services:
    oro_visibility.event_listener.product_visibility_cache:
        class: Oro\Bundle\VisibilityBundle\EventListener\ProductVisibilityCacheListener
        arguments:
            - '@oro_visibility.provider.resolved_product_visibility_provider'
        tags:
            - { name: doctrine.event_listener, event: onFlush }

    oro_visibility.acl.voter.customer:
        class: Oro\Bundle\VisibilityBundle\Acl\Voter\ProductVisibilityVoter
        arguments:
            - '@oro_entity.doctrine_helper'
            - '@oro_frontend.request.frontend_helper'
            - '@Psr\Container\ContainerInterface'
        calls:
            - [setClassName, ['Oro\Bundle\ProductBundle\Entity\Product']]
        tags:
            - { name: security.voter }
            - { name: container.service_subscriber, id: oro_visibility.provider.resolved_product_visibility_provider }

    oro_visibility.event_listener.visibility_grid_listener:
        class: 'Oro\Bundle\VisibilityBundle\EventListener\VisibilityGridListener'
        abstract: true
        arguments:
            - "@doctrine"
            - "@oro_visibility.provider.visibility_choices"
            - "@oro_scope.scope_manager"

    oro_visibility.event_listener.visibility_grid_listener.product.customer:
        parent: oro_visibility.event_listener.visibility_grid_listener
        tags:
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.pre.customer-product-visibility-grid, method: onPreBuild }
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.after.customer-product-visibility-grid, method: onDatagridBuildAfter }

    oro_visibility.event_listener.visibility_grid_listener.product.customer_group:
        parent: oro_visibility.event_listener.visibility_grid_listener
        tags:
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.pre.customer-group-product-visibility-grid, method: onPreBuild }
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.after.customer-group-product-visibility-grid, method: onDatagridBuildAfter }

    oro_visibility.event_listener.visibility_grid_listener.category.customer:
        parent: oro_visibility.event_listener.visibility_grid_listener
        tags:
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.pre.customer-category-visibility-grid, method: onPreBuild }
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.after.customer-category-visibility-grid, method: onDatagridBuildAfter }

    oro_visibility.event_listener.visibility_grid_listener.category.customer_group:
        parent: oro_visibility.event_listener.visibility_grid_listener
        tags:
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.pre.customer-group-category-visibility-grid, method: onPreBuild }
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.after.customer-group-category-visibility-grid, method: onDatagridBuildAfter }

    oro_visibility.filter.visibility_type_choice:
        class: 'Oro\Bundle\VisibilityBundle\Filter\VisibilityChoiceFilter'
        public: false
        arguments:
            - '@form.factory'
            - '@oro_filter.filter_utility'
            - '@doctrine'
        tags:
            - { name: oro_filter.extension.orm_filter.filter, type: visibility_choice }

    oro_visibility.event_listener.product_duplicate_listener:
        class: 'Oro\Bundle\VisibilityBundle\EventListener\ProductDuplicateListener'
        arguments:
            - "@doctrine"
        tags:
            - { name: kernel.event_listener, event: oro_product.product.duplicate.after, method: onDuplicateProduct }
        calls:
            - [ setVisibilityToAllClassName, ['Oro\Bundle\VisibilityBundle\Entity\Visibility\ProductVisibility'] ]
            - [ setVisibilityCustomerGroupClassName, ['Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerGroupProductVisibility'] ]
            - [ setVisibilityCustomerClassName, ['Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerProductVisibility'] ]
            - [ setFieldName, ['product'] ]

    oro_visibility.event_listener.default_visibility:
        class: 'Oro\Bundle\VisibilityBundle\EventListener\DefaultVisibilityListener'
        public: false
        tags:
            - { name: doctrine.event_listener, event: onFlush }

    oro_visibility.event_listener.default_visibility_changed:
        class: Oro\Bundle\VisibilityBundle\EventListener\DefaultVisibilityChangedListener
        arguments:
            - '@event_dispatcher'
        tags:
            - { name: kernel.event_listener, event: oro_config.update_after, method: onConfigUpdate }

    oro_visibility.provider.visibility_choices:
        class: 'Oro\Bundle\VisibilityBundle\Provider\VisibilityChoicesProvider'
        public: false
        arguments:
            - "@translator"

    oro_visibility.visibility.provider.category_visibility_provider:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Provider\CategoryVisibilityProvider'
        public: false
        arguments:
            - "@oro_visibility.visibility.resolver.category_visibility_resolver"
            - "@oro_customer.provider.customer_user_relations_provider"

    oro_visibility.visibility.resolver.category_visibility_resolver:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Resolver\CategoryVisibilityResolver'
        public: true
        arguments:
            - "@doctrine"
            - "@oro_config.manager"
            - "@oro_scope.scope_manager"

    oro_visibility.event_listener.category_tree_handler_listener:
        class: 'Oro\Bundle\VisibilityBundle\EventListener\CategoryTreeHandlerListener'
        arguments:
            - '@oro_visibility.visibility.provider.category_visibility_provider'
        tags:
            - {name: kernel.event_listener, event: oro_catalog.category.tree.create_after, method: onCreateAfter }

    oro_visibility.model.product_visibility_query_builder_modifier:
        class: 'Oro\Bundle\VisibilityBundle\Model\ProductVisibilityQueryBuilderModifier'
        public: false
        arguments:
            - "@oro_config.global"
            - "@oro_scope.scope_manager"
            - "@oro_entity.doctrine_helper"
        calls:
            - [setProductVisibilitySystemConfigurationPath, ['oro_visibility.product_visibility']]
            - [setCategoryVisibilitySystemConfigurationPath, ['oro_visibility.category_visibility']]
            - [setVisibilityScopeProvider, ['@oro_visibility.provider.visibility_scope_provider']]

    oro_visibility.visibility.cache.product.customer_group_product_resolved_cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\CustomerGroupProductResolvedCacheBuilder'
        arguments:
            - '@doctrine'
            - '@oro_product.search.product_reindex_manager'
            - '@oro_scope.scope_manager'
            - '@oro_entity.orm.insert_from_select_query_executor'

    oro_visibility.visibility.cache.product.customer_product_resolved_cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\CustomerProductResolvedCacheBuilder'
        arguments:
            - '@doctrine'
            - '@oro_product.search.product_reindex_manager'
            - '@oro_scope.scope_manager'
            - '@oro_entity.orm.insert_from_select_query_executor'

    oro_visibility.visibility.cache.product.product_resolved_cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\ProductResolvedCacheBuilder'
        arguments:
            - '@doctrine'
            - '@oro_product.search.product_reindex_manager'
            - '@oro_scope.scope_manager'
            - '@oro_entity.orm.insert_from_select_query_executor'

    oro_visibility.visibility.cache.product.cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\CacheBuilder'
        calls:
            - [addBuilder, ["@oro_visibility.visibility.cache.product.product_resolved_cache_builder"]]
            - [addBuilder, ["@oro_visibility.visibility.cache.product.customer_group_product_resolved_cache_builder"]]
            - [addBuilder, ["@oro_visibility.visibility.cache.product.customer_product_resolved_cache_builder"]]

    oro_visibility.visibility.cache.product.category.customer_group_category_resolved_cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\Category\CustomerGroupCategoryResolvedCacheBuilder'
        arguments:
            - '@doctrine'
            - '@oro_catalog.manager.product_index_scheduler'
            - '@oro_entity.orm.insert_from_select_query_executor'
            - '@oro_visibility.visibility.cache.product.category.subtree.visibility_change_group_subtree_cache_builder'

    oro_visibility.visibility.cache.product.category.customer_category_resolved_cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\Category\CustomerCategoryResolvedCacheBuilder'
        arguments:
            - '@doctrine'
            - '@oro_catalog.manager.product_index_scheduler'
            - '@oro_scope.scope_manager'
            - '@oro_entity.orm.insert_from_select_query_executor'
            - '@oro_visibility.visibility.cache.product.category.subtree.visibility_change_customer_subtree_cache_builder'

    oro_visibility.visibility.cache.product.category.category_resolved_cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\Category\CategoryResolvedCacheBuilder'
        arguments:
            - '@doctrine'
            - '@oro_catalog.manager.product_index_scheduler'
            - '@oro_scope.scope_manager'
            - '@oro_entity.orm.insert_from_select_no_conflict_query_executor'
            - '@oro_visibility.visibility.cache.product.category.subtree.visibility_change_category_subtree_cache_builder'
            - '@oro_visibility.visibility.cache.product.category.subtree.position_change_category_subtree_cache_builder'

    oro_visibility.visibility.cache.product.category.cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\Category\CacheBuilder'
        calls:
            - [addBuilder, ["@oro_visibility.visibility.cache.product.category.category_resolved_cache_builder"]]
            - [addBuilder, ["@oro_visibility.visibility.cache.product.category.customer_group_category_resolved_cache_builder"]]
            - [addBuilder, ["@oro_visibility.visibility.cache.product.category.customer_category_resolved_cache_builder"]]

    oro_visibility.visibility.cache.cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\CompositeCacheBuilder'
        calls:
            - [addBuilder, ["@oro_visibility.visibility.cache.product.category.cache_builder"]]
            - [addBuilder, ["@oro_visibility.visibility.cache.product.cache_builder"]]

    oro_visibility.visibility.cache.product.category.subtree.category_subtree_cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\Category\Subtree\AbstractSubtreeCacheBuilder'
        abstract: true
        arguments:
            - "@doctrine"
            - "@oro_visibility.visibility.resolver.category_visibility_resolver"
            - "@oro_config.manager"
            - "@oro_scope.scope_manager"

    oro_visibility.visibility.cache.product.category.subtree.visibility_change_category_subtree_cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\Category\Subtree\VisibilityChangeCategorySubtreeCacheBuilder'
        public: false
        parent: oro_visibility.visibility.cache.product.category.subtree.category_subtree_cache_builder

    oro_visibility.visibility.cache.product.category.subtree.position_change_category_subtree_cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\Category\Subtree\PositionChangeCategorySubtreeCacheBuilder'
        public: false
        parent: oro_visibility.visibility.cache.product.category.subtree.category_subtree_cache_builder
        calls:
            - [setCustomerCategoryRepository, ['@oro_visibility.customer_category_repository']]
            - [setCustomerGroupCategoryRepository, ['@oro_visibility.customer_group_category_repository']]

    oro_visibility.visibility.cache.product.category.subtree.visibility_change_customer_subtree_cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\Category\Subtree\VisibilityChangeCustomerSubtreeCacheBuilder'
        public: false
        parent: oro_visibility.visibility.cache.product.category.subtree.category_subtree_cache_builder

    oro_visibility.visibility.cache.product.category.subtree.visibility_change_group_subtree_cache_builder:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Cache\Product\Category\Subtree\VisibilityChangeGroupSubtreeCacheBuilder'
        public: false
        parent: oro_visibility.visibility.cache.product.category.subtree.category_subtree_cache_builder

    oro_visibility.async.message_filter.visibility.change_category_visibility:
        class: 'Oro\Bundle\VisibilityBundle\Async\Visibility\VisibilityMessageFilter'
        arguments:
            - !php/const Oro\Bundle\VisibilityBundle\Async\Topic\ResolveCategoryVisibilityTopic::NAME
        tags:
            - { name: oro_message_queue.message_filter, topic: !php/const Oro\Bundle\VisibilityBundle\Async\Topic\ResolveCategoryVisibilityTopic::NAME }

    oro_visibility.async.message_filter.visibility.resolve_product_visibility:
        class: 'Oro\Bundle\VisibilityBundle\Async\Visibility\VisibilityMessageFilter'
        arguments:
            - !php/const Oro\Bundle\VisibilityBundle\Async\Topic\ResolveProductVisibilityTopic::NAME
        tags:
            - { name: oro_message_queue.message_filter, topic: !php/const Oro\Bundle\VisibilityBundle\Async\Topic\ResolveProductVisibilityTopic::NAME }

    oro_visibility.entity_listener.product_visibility_change:
        class: 'Oro\Bundle\VisibilityBundle\Entity\EntityListener\ProductVisibilityListener'
        public: false
        arguments:
            - '@oro_message_queue.client.message_producer'
        tags:
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\ProductVisibility', event: preUpdate }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\ProductVisibility', event: preRemove }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\ProductVisibility', event: postPersist }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerProductVisibility', event: preUpdate }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerProductVisibility', event: preRemove }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerProductVisibility', event: postPersist }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerGroupProductVisibility', event: preUpdate }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerGroupProductVisibility', event: preRemove }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerGroupProductVisibility', event: postPersist }

    oro_visibility.entity_listener.category_visibility_change:
        class: 'Oro\Bundle\VisibilityBundle\Entity\EntityListener\CategoryVisibilityListener'
        public: false
        arguments:
            - '@oro_message_queue.client.message_producer'
        tags:
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CategoryVisibility', event: preUpdate }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CategoryVisibility', event: preRemove }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CategoryVisibility', event: postPersist }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerGroupCategoryVisibility', event: preUpdate }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerGroupCategoryVisibility', event: preRemove }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerGroupCategoryVisibility', event: postPersist }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerCategoryVisibility', event: preUpdate }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerCategoryVisibility', event: preRemove }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerCategoryVisibility', event: postPersist }

    oro_visibility.entity_listener.change_product_category:
        class: 'Oro\Bundle\VisibilityBundle\Entity\EntityListener\ProductListener'
        public: false
        arguments:
            - '@oro_message_queue.client.message_producer'
        tags:
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\ProductBundle\Entity\Product', event: postPersist }

    oro_visibility.event_listener.form_view:
        class: 'Oro\Bundle\VisibilityBundle\Form\EventListener\FormViewListener'
        arguments:
            - "@translator"
            - "@oro_entity.doctrine_helper"
            - "@request_stack"
        tags:
            - { name: kernel.event_listener, event: oro_ui.scroll_data.before.category-edit, method: onCategoryEdit }

    oro_visibility.entity.entity_listener.category_listener:
        class: 'Oro\Bundle\VisibilityBundle\Entity\EntityListener\CategoryListener'
        public: false
        arguments:
            - '@oro_message_queue.client.message_producer'
        tags:
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\CatalogBundle\Entity\Category', event: preUpdate }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\CatalogBundle\Entity\Category', event: preRemove }

    Oro\Bundle\VisibilityBundle\Provider\VisibilityRootScopesProvider:
        alias: oro_visibility.root_scopes_provider

    oro_visibility.root_scopes_provider:
        class: 'Oro\Bundle\VisibilityBundle\Provider\VisibilityRootScopesProvider'
        public: true
        arguments:
            - '@oro_scope.scope_manager'

    oro_visibility.event_listener.category_listener:
        class: 'Oro\Bundle\VisibilityBundle\EventListener\CategoryListener'
        arguments:
            - '@oro_message_queue.client.message_producer'
        tags:
            - { name: kernel.event_listener, event: oro_catalog.event.products_change_relation, method: onProductsChangeRelation, priority: 100 }

    oro_visibility.event_listener.restrict_product_variant_event:
        class: 'Oro\Bundle\VisibilityBundle\EventListener\RestrictProductVariantEventVisibilityListener'
        arguments:
            - '@oro_visibility.model.product_visibility_query_builder_modifier'
        tags:
            - { name: kernel.event_listener, event: oro_product.event.restrict_product_variant_event, method: onRestrictProductVariantEvent }

    oro_visibility.product_raw_repository:
        alias: Oro\Bundle\VisibilityBundle\Entity\Visibility\Repository\ProductVisibilityRepository

    Oro\Bundle\VisibilityBundle\Entity\Visibility\Repository\ProductVisibilityRepository:
        parent: oro_entity.abstract_repository
        arguments:
            - Oro\Bundle\VisibilityBundle\Entity\Visibility\ProductVisibility
        tags:
            - { name: doctrine.repository_service }

    oro_visibility.product_repository:
        alias: Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\ProductRepository

    Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\ProductRepository:
        parent: oro_entity.abstract_repository
        arguments:
            - Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\ProductVisibilityResolved
        tags:
            - { name: doctrine.repository_service }

    oro_visibility.customer_product_repository:
        alias: Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\CustomerProductRepository

    Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\CustomerProductRepository:
        parent: oro_entity.abstract_repository
        arguments:
            - Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\CustomerProductVisibilityResolved
        tags:
            - { name: doctrine.repository_service }

    oro_visibility.customer_group_product_repository:
        alias: Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\CustomerGroupProductRepository

    Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\CustomerGroupProductRepository:
        parent: oro_entity.abstract_repository
        arguments:
            - Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\CustomerGroupProductVisibilityResolved
        tags:
            - { name: doctrine.repository_service }

    oro_visibility.customer_category_repository:
        alias: Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\CustomerCategoryRepository

    Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\CustomerCategoryRepository:
        parent: oro_entity.abstract_repository
        arguments:
            - Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\CustomerCategoryVisibilityResolved
        tags:
            - { name: doctrine.repository_service }

    oro_visibility.category_repository:
        alias: Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\CategoryRepository

    Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\CategoryRepository:
        parent: oro_entity.abstract_repository
        arguments:
            - Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\CategoryVisibilityResolved
        tags:
            - { name: doctrine.repository_service }

    oro_visibility.customer_group_category_repository:
        alias: Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\CustomerGroupCategoryRepository

    Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\Repository\CustomerGroupCategoryRepository:
        parent: oro_entity.abstract_repository
        arguments:
            - Oro\Bundle\VisibilityBundle\Entity\VisibilityResolved\CustomerGroupCategoryVisibilityResolved
        tags:
            - { name: doctrine.repository_service }

    Oro\Bundle\VisibilityBundle\Entity\Visibility\Repository\CustomerGroupProductVisibilityRepository:
        parent: oro_entity.abstract_repository
        arguments:
            - Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerGroupProductVisibility
        tags:
            - { name: doctrine.repository_service }

    Oro\Bundle\VisibilityBundle\Entity\Visibility\Repository\CustomerProductVisibilityRepository:
        parent: oro_entity.abstract_repository
        arguments:
            - Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerProductVisibility
        tags:
            - { name: doctrine.repository_service }

    oro_visibility.migration.demo_data_fixtures_listener.change_visibility:
        parent: oro_platform.event_listener.demo_data_fixtures_listener.abstract
        class: Oro\Bundle\VisibilityBundle\EventListener\ChangeVisibilityDemoDataFixturesListener
        arguments:
            - '@oro_website_search.driver.customer_partial_update_driver'
        calls:
            - [disableListener, ['oro_visibility.entity.entity_listener.customer_listener']]
            - [disableListener, ['oro_visibility.entity_listener.change_product_category']]
            - [disableListener, ['oro_visibility.entity_listener.product_visibility_change']]
            - [disableListener, ['oro_visibility.entity_listener.category_visibility_change']]
            - [disableListener, ['oro_visibility.event_listener.category_listener']]
        tags:
            - { name: kernel.event_listener, event: oro_migration.data_fixtures.pre_load, method: onPreLoad }
            - { name: kernel.event_listener, event: oro_migration.data_fixtures.post_load, method: onPostLoad }

    oro_visibility.entity.entity_listener.customer_listener:
        class: 'Oro\Bundle\VisibilityBundle\Entity\EntityListener\CustomerListener'
        arguments:
            - '@oro_message_queue.client.message_producer'
            - '@oro_website_search.driver.customer_partial_update_driver'
        tags:
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\CustomerBundle\Entity\Customer', event: postPersist }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\CustomerBundle\Entity\Customer', event: preRemove }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\CustomerBundle\Entity\Customer', event: preUpdate }

    oro_visibility.event_listener.restrict_products_index:
        class: 'Oro\Bundle\VisibilityBundle\EventListener\RestrictProductsIndexEventListener'
        arguments:
            - '@oro_entity.doctrine_helper'
            - '@oro_config.global'
            - 'oro_visibility.product_visibility'
            - 'oro_visibility.category_visibility'
            - '@oro_website_search.manager.website_context_manager'
        calls:
            - [setVisibilityScopeProvider, ['@oro_visibility.provider.visibility_scope_provider']]
        tags:
            - { name: kernel.event_listener, event: oro_website_search.event.restrict_index_entity.product, method: onRestrictIndexEntityEvent }

    oro_visibility.visibility.provider.product_visibility_provider:
        class: 'Oro\Bundle\VisibilityBundle\Visibility\Provider\ProductVisibilityProvider'
        public: false
        arguments:
            - '@oro_entity.doctrine_helper'
            - '@oro_config.global'
        calls:
            - [setProductVisibilitySystemConfigurationPath, ['oro_visibility.product_visibility']]
            - [setCategoryVisibilitySystemConfigurationPath, ['oro_visibility.category_visibility']]
            - [setVisibilityScopeProvider, ['@oro_visibility.provider.visibility_scope_provider']]

    oro_visibility.model.product_visibility_search_query_modifier:
        class: 'Oro\Bundle\VisibilityBundle\Model\ProductVisibilitySearchQueryModifier'
        arguments:
            - '@security.token_storage'
            - '@oro_website_search.provider.placeholder_provider'

    oro_visibility.event_listener.product_db_query_restriction:
        class: 'Oro\Bundle\VisibilityBundle\EventListener\ProductDBQueryRestrictionEventListener'
        arguments:
            - "@oro_frontend.request.frontend_helper"
            - "@oro_visibility.model.product_visibility_query_builder_modifier"
        tags:
            - { name: kernel.event_listener, event: oro_product.product_db_query.restriction, method: onDBQuery }

    oro_visibility.event_listener.product_search_query_restriction:
        class: 'Oro\Bundle\VisibilityBundle\EventListener\ProductSearchQueryRestrictionEventListener'
        arguments:
            - "@oro_frontend.request.frontend_helper"
            - "@oro_visibility.model.product_visibility_search_query_modifier"
        tags:
            - { name: kernel.event_listener, event: oro_product.product_search_query.restriction, method: onSearchQuery }

    oro_visibility.indexer.product_visibility_indexer:
        class: 'Oro\Bundle\VisibilityBundle\Indexer\ProductVisibilityIndexer'
        arguments:
            - '@oro_visibility.visibility.provider.product_visibility_provider'

    oro_visibility.event_listener.website_search_product_visibility_indexer_listener:
        class: 'Oro\Bundle\VisibilityBundle\EventListener\WebsiteSearchProductVisibilityIndexerListener'
        arguments:
            - '@oro_visibility.indexer.product_visibility_indexer'
            - '@oro_website_search.manager.website_context_manager'
        tags:
            - { name: kernel.event_listener, event: oro_website_search.event.index_entity.product, method: onWebsiteSearchIndex }

    oro_visibility.provider.visibility_scope_provider:
        class: 'Oro\Bundle\VisibilityBundle\Provider\VisibilityScopeProvider'
        arguments:
            - '@oro_scope.scope_manager'

    oro_visibility.event_listener.category_visible_listener:
        class: Oro\Bundle\VisibilityBundle\EventListener\CategoryVisibleListener
        arguments:
            - '@doctrine'
            - '@oro_visibility.visibility.resolver.category_visibility_resolver'
            - '@oro_customer.provider.customer_user_relations_provider'
            - '@security.token_storage'
        tags:
            - { name: kernel.event_listener, event: kernel.controller }

    oro_visibility.async.message_filter.visibility.change_product_category:
        class: 'Oro\Bundle\VisibilityBundle\Async\Visibility\ProductMessageFilter'
        arguments:
            - !php/const Oro\Bundle\VisibilityBundle\Async\Topic\VisibilityOnChangeProductCategoryTopic::NAME
        tags:
            - { name: oro_message_queue.message_filter, topic: !php/const Oro\Bundle\VisibilityBundle\Async\Topic\VisibilityOnChangeProductCategoryTopic::NAME }

    oro_visibility.async.message_filter.visibility.category_position_change:
        class: 'Oro\Bundle\VisibilityBundle\Async\Visibility\CategoryMessageFilter'
        arguments:
            - !php/const Oro\Bundle\VisibilityBundle\Async\Topic\VisibilityOnChangeCategoryPositionTopic::NAME
        tags:
            - { name: oro_message_queue.message_filter, topic: !php/const Oro\Bundle\VisibilityBundle\Async\Topic\VisibilityOnChangeCategoryPositionTopic::NAME }

    oro_visibility.category_message_filter.category_remove:
        class: 'Oro\Bundle\VisibilityBundle\Async\Visibility\CategoryMessageFilter'
        arguments:
            - !php/const Oro\Bundle\VisibilityBundle\Async\Topic\VisibilityOnRemoveCategoryTopic::NAME
        tags:
            - { name: oro_message_queue.message_filter, topic: !php/const Oro\Bundle\VisibilityBundle\Async\Topic\VisibilityOnRemoveCategoryTopic::NAME }

    oro_visibility.model.category_visibility_query_builder_modifier:
        class: 'Oro\Bundle\VisibilityBundle\Model\CategoryVisibilityQueryBuilderModifier'
        public: false
        arguments:
            - '@oro_entity.doctrine_helper'
            - '@oro_config.manager'
            - '@oro_scope.scope_manager'

    oro_visibility.product_visibility.widget_provider.actions:
        parent: oro_ui.widget_provider.action_button.abstract
        arguments:
            - oro_product_visibility_button
            - oro_product_visibility_link
        tags:
            - { name: oro_ui.view_action_provider, group: activity, priority: -200 }

    oro_visibility.provider.resolved_product_visibility_provider:
        class: Oro\Bundle\VisibilityBundle\Provider\ResolvedProductVisibilityProvider
        arguments:
            - '@doctrine'
            - '@oro_visibility.model.product_visibility_query_builder_modifier'

    Oro\Bundle\VisibilityBundle\Provider\ResolvedProductVisibilityProvider:
        alias: oro_visibility.provider.resolved_product_visibility_provider

    oro_visibility.entity_listener.category_default_visibility:
        class: 'Oro\Bundle\VisibilityBundle\Entity\EntityListener\CategoryDefaultVisibilityListener'
        public: false
        arguments:
            - '@oro_scope.scope_manager'
            - '@oro_entity.orm.insert_from_select_query_executor'
        tags:
            - { name: doctrine.event_listener, event: onFlush }
            - { name: doctrine.event_listener, event: postFlush }

    oro_visibility.event_listener.datagrid_line_items_data.visibility_prefetch:
        class: Oro\Bundle\VisibilityBundle\EventListener\DatagridLineItemsDataVisibilityPrefetchListener
        arguments:
            - '@oro_visibility.provider.resolved_product_visibility_provider'
        tags:
            # This listener must be called early as it prefetches visibility for the products line items which might be needed by others, but not before "oro_shopping_list.event_listener.datagrid_line_items_data.preload".
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-customer-user-shopping-list-grid, method: onLineItemData, priority: 1014 }
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-customer-user-shopping-list-edit-grid, method: onLineItemData, priority: 1014 }
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-checkout-line-items-grid, method: onLineItemData, priority: 1014 }
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-single-page-checkout-line-items-grid, method: onLineItemData, priority: 1014 }

    oro_visibility.event_listener.datagrid_line_items_data.visibility:
        class: Oro\Bundle\VisibilityBundle\EventListener\DatagridLineItemsDataVisibilityListener
        arguments:
            - '@oro_visibility.provider.resolved_product_visibility_provider'
        tags:
            # This listener must be called early as it sets visibility for the products line items which might be needed by others, but not before "oro_shopping_list.event_listener.datagrid_line_items_data.visibility_prefetch".
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-customer-user-shopping-list-grid, method: onLineItemData, priority: 1004 }
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-customer-user-shopping-list-edit-grid, method: onLineItemData, priority: 1004 }
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-checkout-line-items-grid, method: onLineItemData, priority: 1004 }
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-single-page-checkout-line-items-grid, method: onLineItemData, priority: 1004 }

    oro_visibility.event_listener.datagrid_kit_item_line_items_data.visibility:
        class: Oro\Bundle\VisibilityBundle\EventListener\DatagridLineItemsDataVisibilityListener
        arguments:
            - '@oro_visibility.provider.resolved_product_visibility_provider'
        tags:
            # This listener must be called early as it sets visibility for the products line items which might be needed by others, but not before "oro_shopping_list.event_listener.datagrid_line_items_data.visibility_prefetch".
            - { name: kernel.event_listener, event: oro_product.datagrid_kit_item_line_items_data.frontend-customer-user-shopping-list-grid, method: onLineItemData, priority: 1004 }
            - { name: kernel.event_listener, event: oro_product.datagrid_kit_item_line_items_data.frontend-customer-user-shopping-list-edit-grid, method: onLineItemData, priority: 1004 }
            - { name: kernel.event_listener, event: oro_product.datagrid_kit_item_line_items_data.frontend-checkout-line-items-grid, method: onLineItemData, priority: 1004 }
            - { name: kernel.event_listener, event: oro_product.datagrid_kit_item_line_items_data.frontend-single-page-checkout-line-items-grid, method: onLineItemData, priority: 1004 }

    oro_visibility.twig.visibility_extension:
        class: Oro\Bundle\VisibilityBundle\Twig\VisibilityExtension
        arguments:
            - '@oro_platform.twig.service_locator'
        tags:
            - { name: twig.extension }

    oro_visibility.strategy_processor.product_visibility_audit_strategy:
        class: 'Oro\Bundle\DataAuditBundle\Strategy\Processor\DefaultUnidirectionalFieldAuditStrategyProcessor'
        arguments:
            - '@doctrine'
        tags:
            - { name: oro_dataaudit.entity_strategy_processor, entityName: Oro\Bundle\VisibilityBundle\Entity\Visibility\ProductVisibility }
            - { name: oro_dataaudit.entity_strategy_processor, entityName: Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerProductVisibility }
            - { name: oro_dataaudit.entity_strategy_processor, entityName: Oro\Bundle\VisibilityBundle\Entity\Visibility\CustomerGroupProductVisibility }
