├── .github
├── CODEOWNERS
└── workflows
│ ├── build.yml
│ └── coding_standard.yml
├── .gitignore
├── README.md
├── README_webpack-config.md
├── assets
├── admin
│ ├── entry.js
│ ├── js
│ │ └── index.js
│ └── scss
│ │ └── main.scss
└── shop
│ ├── entry.js
│ ├── js
│ └── index.js
│ └── scss
│ └── main.scss
├── behat.yml.dist
├── composer.json
├── config
├── api_resources
│ ├── admin
│ │ └── ProductBundle.xml
│ └── shop
│ │ ├── Order.xml
│ │ ├── Product.xml
│ │ ├── ProductBundle.xml
│ │ └── ProductBundleItem.xml
├── config.yml
├── doctrine
│ ├── ProductBundle.orm.xml
│ ├── ProductBundleItem.orm.xml
│ └── ProductBundleOrderItem.orm.xml
├── resources.yml
├── resources
│ ├── product_bundle.yml
│ ├── product_bundle_item.yml
│ └── product_bundle_order_item.yml
├── routes.yml
├── routes
│ ├── admin.yml
│ └── shop.yml
├── serialization
│ ├── AddProductBundleToCartCommand.xml
│ ├── AddProductBundleToCartDto.xml
│ ├── OrderItem.xml
│ ├── Product.xml
│ ├── ProductBundle.xml
│ ├── ProductBundleItem.xml
│ ├── ProductBundleOrderItem.xml
│ ├── ProductVariant.xml
│ └── ProductVariantTranslation.xml
├── services.xml
├── services
│ ├── controller.xml
│ ├── event_listener.xml
│ ├── factory.xml
│ ├── form.xml
│ ├── handler.xml
│ ├── menu.xml
│ ├── processor.xml
│ ├── product.xml
│ ├── transformer.xml
│ ├── twig.xml
│ └── validator.xml
├── twig_hooks
│ ├── order
│ │ └── show.yaml
│ ├── product
│ │ ├── admin
│ │ │ ├── create.yaml
│ │ │ └── update.yaml
│ │ └── shop
│ │ │ └── show.yaml
│ └── twig_hooks.yaml
└── validation
│ ├── AddProductBundleToCartCommand.xml
│ ├── AddProductBundleToCartDto.xml
│ ├── ProductBundle.xml
│ └── ProductBundleItem.xml
├── doc
├── bundle.png
├── bundle_cart.png
├── bundle_productpage.png
├── bundle_taxon.png
├── create_bundle.png
└── functionalities.md
├── ecs.php
├── features
├── creating_bundled_product.feature
└── having_bundled_product_in_store.feature
├── node_modules
├── phpspec.yml.dist
├── phpstan.neon.dist
├── phpunit.xml.dist
├── spec
└── EventListener
│ └── AddProductToProductBundleWhenEditNormalProductEventListenerSpec.php
├── src
├── BitBagSyliusProductBundlePlugin.php
├── Command
│ ├── AddProductBundleItemToCartCommand.php
│ ├── AddProductBundleToCartCommand.php
│ ├── OrderIdentityAwareInterface.php
│ └── ProductCodeAwareInterface.php
├── Component
│ └── Product
│ │ └── AddToCartFormComponent.php
├── DataTransformer
│ └── AddProductBundleToCartDtoDataTransformer.php
├── DependencyInjection
│ └── CompilerPass
│ │ └── AuthenticationManagerPolyfillPass.php
├── Dto
│ ├── AddProductBundleToCartDto.php
│ ├── AddProductBundleToCartDtoInterface.php
│ └── Api
│ │ └── AddProductBundleToCartDto.php
├── Entity
│ ├── OrderItemInterface.php
│ ├── ProductBundle.php
│ ├── ProductBundleInterface.php
│ ├── ProductBundleItem.php
│ ├── ProductBundleItemInterface.php
│ ├── ProductBundleOrderItem.php
│ ├── ProductBundleOrderItemInterface.php
│ ├── ProductBundleOrderItemsAwareTrait.php
│ ├── ProductBundlesAwareInterface.php
│ ├── ProductBundlesAwareTrait.php
│ └── ProductInterface.php
├── EventListener
│ ├── AddProductToProductBundleWhenEditNormalProductEventListener.php
│ └── CartItemAddListener.php
├── Factory
│ ├── AddProductBundleItemToCartCommandFactory.php
│ ├── AddProductBundleItemToCartCommandFactoryInterface.php
│ ├── AddProductBundleToCartCommandFactory.php
│ ├── AddProductBundleToCartCommandFactoryInterface.php
│ ├── AddProductBundleToCartDtoFactory.php
│ ├── AddProductBundleToCartDtoFactoryInterface.php
│ ├── OrderItemFactory.php
│ ├── OrderItemFactoryInterface.php
│ ├── ProductBundleOrderItemFactory.php
│ ├── ProductBundleOrderItemFactoryInterface.php
│ ├── ProductFactory.php
│ └── ProductFactoryInterface.php
├── Form
│ ├── Extension
│ │ └── ProductTypeExtension.php
│ └── Type
│ │ ├── AddProductBundleItemToCartType.php
│ │ ├── AddProductBundleToCartType.php
│ │ ├── ProductBundleItemType.php
│ │ └── ProductBundleType.php
├── Handler
│ ├── AddProductBundleToCartHandler.php
│ ├── AddProductBundleToCartHandler
│ │ ├── CartProcessor.php
│ │ └── CartProcessorInterface.php
│ └── Api
│ │ └── AddProductBundleToCartHandler.php
├── Menu
│ └── AdminProductFormMenuListener.php
├── Repository
│ ├── ProductVariantRepository.php
│ └── ProductVariantRepositoryInterface.php
├── Twig
│ └── Extension
│ │ └── ProductBundleOrderItemExtension.php
└── Validator
│ ├── HasAvailableProductBundle.php
│ ├── HasAvailableProductBundleValidator.php
│ ├── HasExistingCart.php
│ ├── HasExistingCartValidator.php
│ ├── HasProductBundle.php
│ ├── HasProductBundleValidator.php
│ ├── Sequentially.php
│ └── SequentiallyValidator.php
├── templates
├── Admin
│ ├── Order
│ │ └── Show
│ │ │ └── _productBundleOrderItems.html.twig
│ └── product
│ │ └── form
│ │ ├── sections
│ │ ├── bundle.html.twig
│ │ └── bundle
│ │ │ └── productBundleItem.html.twig
│ │ └── side_navigation
│ │ └── bundle.html.twig
└── Shop
│ └── product
│ └── show
│ └── page
│ └── info
│ └── summary
│ └── add_to_cart
│ └── addProductBundleToCart.html.twig
├── tests
├── Api
│ ├── Admin
│ │ ├── OrderTest.php
│ │ └── ProductBundleTest.php
│ ├── AdminJsonApiTestCase.php
│ ├── DataFixtures
│ │ └── ORM
│ │ │ ├── general
│ │ │ ├── authentication.yml
│ │ │ └── channels.yml
│ │ │ └── shop
│ │ │ ├── orders.yml
│ │ │ └── product_bundles.yml
│ ├── JsonApiTestCase.php
│ ├── Responses
│ │ ├── admin
│ │ │ ├── get_order_with_bundle_response.json
│ │ │ ├── get_product_bundle_collection_response.json
│ │ │ ├── get_product_bundle_response.json
│ │ │ ├── post_product_bundle_response.json
│ │ │ └── put_product_bundle_response.json
│ │ └── shop
│ │ │ ├── get_bundled_product_response.json
│ │ │ ├── get_not_bundled_product_response.json
│ │ │ ├── get_order_with_bundle_response.json
│ │ │ └── get_product_bundle_response.json
│ ├── Shop
│ │ ├── OrderTest.php
│ │ └── ProductTest.php
│ └── Utils
│ │ └── CartHelperTrait.php
├── Application
│ ├── .babelrc
│ ├── .env
│ ├── .env.test
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── Kernel.php
│ ├── assets
│ │ ├── admin
│ │ │ ├── entry.js
│ │ │ └── product-entry.js
│ │ ├── controllers.json
│ │ └── shop
│ │ │ └── entry.js
│ ├── bin
│ │ └── console
│ ├── composer.json
│ ├── config
│ │ ├── api_platform
│ │ │ └── .gitkeep
│ │ ├── bootstrap.php
│ │ ├── bundles.php
│ │ ├── jwt
│ │ │ ├── private.pem
│ │ │ └── public.pem
│ │ ├── packages
│ │ │ ├── _sylius.yaml
│ │ │ ├── assets.yaml
│ │ │ ├── bitbag_sylius_product_bundle_plugin.yml
│ │ │ ├── dev
│ │ │ │ ├── framework.yaml
│ │ │ │ ├── monolog.yaml
│ │ │ │ ├── routing.yaml
│ │ │ │ └── web_profiler.yaml
│ │ │ ├── doctrine.yaml
│ │ │ ├── doctrine_migrations.yaml
│ │ │ ├── framework.yaml
│ │ │ ├── http_discovery.yaml
│ │ │ ├── lexik_jwt_authentication.yaml
│ │ │ ├── liip_imagine.yaml
│ │ │ ├── mailer.yaml
│ │ │ ├── prod
│ │ │ │ ├── doctrine.yaml
│ │ │ │ └── monolog.yaml
│ │ │ ├── routing.yaml
│ │ │ ├── security.yaml
│ │ │ ├── staging
│ │ │ │ └── monolog.yaml
│ │ │ ├── stof_doctrine_extensions.yaml
│ │ │ ├── test
│ │ │ │ ├── framework.yaml
│ │ │ │ ├── monolog.yaml
│ │ │ │ ├── sylius_theme.yaml
│ │ │ │ ├── sylius_uploader.yaml
│ │ │ │ └── web_profiler.yaml
│ │ │ ├── test_cached
│ │ │ │ ├── framework.yaml
│ │ │ │ ├── monolog.yaml
│ │ │ │ ├── sylius_channel.yaml
│ │ │ │ ├── sylius_theme.yaml
│ │ │ │ ├── sylius_uploader.yaml
│ │ │ │ └── twig.yaml
│ │ │ ├── translation.yaml
│ │ │ ├── twig.yaml
│ │ │ ├── validator.yaml
│ │ │ └── webpack_encore.yaml
│ │ ├── routes.yaml
│ │ ├── routes
│ │ │ ├── api_platform.yaml
│ │ │ ├── dev
│ │ │ │ └── web_profiler.yaml
│ │ │ ├── liip_imagine.yaml
│ │ │ ├── sylius_admin.yaml
│ │ │ ├── sylius_api.yaml
│ │ │ ├── sylius_shop.yaml
│ │ │ ├── test
│ │ │ │ └── sylius_test_plugin.yaml
│ │ │ ├── test_cached
│ │ │ │ ├── routing.yaml
│ │ │ │ └── sylius_test_plugin.yaml
│ │ │ └── ux.yaml
│ │ ├── secrets
│ │ │ ├── dev
│ │ │ │ └── .gitignore
│ │ │ ├── prod
│ │ │ │ └── .gitignore
│ │ │ ├── test
│ │ │ │ └── .gitignore
│ │ │ └── test_cached
│ │ │ │ └── .gitignore
│ │ ├── services.yaml
│ │ ├── services_test.yaml
│ │ └── services_test_cached.yaml
│ ├── gulpfile.babel.js
│ ├── package.json
│ ├── public
│ │ ├── .htaccess
│ │ ├── favicon.ico
│ │ ├── index.php
│ │ └── robots.txt
│ ├── src
│ │ ├── Entity
│ │ │ ├── OrderItem.php
│ │ │ └── Product.php
│ │ └── Resources
│ │ │ └── config
│ │ │ └── doctrine
│ │ │ ├── OrderItem.orm.xml
│ │ │ └── Product.orm.xml
│ ├── templates
│ │ └── bundles
│ │ │ ├── SyliusAdminBundle
│ │ │ ├── Layout
│ │ │ │ └── _logo.html.twig
│ │ │ ├── _scripts.html.twig
│ │ │ ├── _styles.html.twig
│ │ │ └── order
│ │ │ │ └── show
│ │ │ │ └── content
│ │ │ │ └── sections
│ │ │ │ └── items
│ │ │ │ └── body
│ │ │ │ └── item.html.twig
│ │ │ └── SyliusShopBundle
│ │ │ ├── Layout
│ │ │ └── Header
│ │ │ │ └── _logo.html.twig
│ │ │ ├── _scripts.html.twig
│ │ │ └── _styles.html.twig
│ ├── translations
│ │ └── .gitignore
│ └── webpack.config.js
├── Behat
│ ├── Context
│ │ ├── Setup
│ │ │ └── ProductBundleContext.php
│ │ └── Ui
│ │ │ └── ProductBundleContext.php
│ ├── Page
│ │ └── Admin
│ │ │ ├── CreateBundledProductPage.php
│ │ │ └── CreateBundledProductPageInterface.php
│ └── Resources
│ │ ├── services.yml
│ │ └── suites.yml
└── Unit
│ ├── DataTransformer
│ └── AddProductBundleToCartDtoDataTransformerTest.php
│ ├── Factory
│ ├── AddProductBundleItemToCartCommandFactoryTest.php
│ ├── AddProductBundleToCartCommandFactoryTest.php
│ ├── AddProductBundleToCartDtoFactoryTest.php
│ ├── OrderItemFactoryTest.php
│ └── ProductBundleOrderItemFactoryTest.php
│ ├── Handler
│ ├── AddProductBundleToCartHandler
│ │ └── CartProcessorTest.php
│ ├── AddProductBundleToCartHandlerTest.php
│ └── Api
│ │ └── AddProductBundleToCartHandlerTest.php
│ ├── MotherObject
│ ├── AddProductBundleItemToCartCommandMother.php
│ ├── AddProductBundleToCartDtoMother.php
│ ├── Api
│ │ └── AddProductBundleToCartDtoMother.php
│ ├── ChannelMother.php
│ ├── OrderItemMother.php
│ ├── OrderMother.php
│ ├── ProductBundleItemMother.php
│ ├── ProductBundleMother.php
│ ├── ProductMother.php
│ └── ProductVariantMother.php
│ ├── TypeExceptionMessage.php
│ └── Validator
│ ├── HasAvailableProductBundleValidatorTest.php
│ ├── HasExistingCartValidatorTest.php
│ └── HasProductBundleTest.php
├── translations
├── messages.en.yml
├── messages.fr.yml
├── messages.nl.yml
├── validators.en.yml
├── validators.fr.yml
└── validators.nl.yml
└── webpack.config.js
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @Sylius/core-team
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
2 | /node_modules/
3 | /composer.lock
4 |
5 | /etc/build/*
6 | !/etc/build/.gitignore
7 |
8 | /tests/Application/yarn.lock
9 |
10 | /.phpunit.result.cache
11 | /behat.yml
12 | /phpspec.yml
13 | /phpunit.xml
14 | .phpunit.result.cache
15 |
16 | # Symfony CLI https://symfony.com/doc/current/setup/symfony_server.html#different-php-settings-per-project
17 | /.php-version
18 | /php.ini
19 |
--------------------------------------------------------------------------------
/README_webpack-config.md:
--------------------------------------------------------------------------------
1 | # BitBag SyliusProductBundlePlugin
2 |
3 | ## Installation - Import Webpack Config
4 |
5 |
6 |
7 | 1. Import plugin's `webpack.config.js` file
8 |
9 | ```js
10 | // webpack.config.js
11 | const [bitbagproductBundleShop, bitbagproductBundleAdmin] = require('./vendor/bitbag/product-bundle-plugin/webpack.config.js');
12 | ...
13 |
14 | module.exports = [..., bitbagproductBundleShop, bitbagproductBundleAdmin];
15 | ```
16 |
17 | 2. Add new packages in `./config/packages/assets.yaml`
18 |
19 | ```yml
20 | # config/packages/assets.yaml
21 |
22 | framework:
23 | assets:
24 | packages:
25 | # ...
26 | shop:
27 | json_manifest_path: '%kernel.project_dir%/public/build/shop/manifest.json'
28 | product_bundle_shop:
29 | json_manifest_path: '%kernel.project_dir%/public/build/bitbag/productBundle/shop/manifest.json'
30 | product_bundle_admin:
31 | json_manifest_path: '%kernel.project_dir%/public/build/bitbag/productBundle/admin/manifest.json'
32 | ```
33 |
34 | 3. Add new build paths in `./config/packages/webpack_encore.yml`
35 |
36 | ```yml
37 | # config/packages/webpack_encore.yml
38 |
39 | webpack_encore:
40 | builds:
41 | # ...
42 | product_bundle_shop: '%kernel.project_dir%/public/build/bitbag/productBundle/shop'
43 | product_bundle_admin: '%kernel.project_dir%/public/build/bitbag/productBundle/admin'
44 | ```
45 |
46 | 4. Add encore functions to your templates
47 |
48 | ```twig
49 | {# @SyliusShopBundle/_scripts.html.twig #}
50 | {{ encore_entry_script_tags('bitbag-productBundle-shop', null, 'product_bundle_shop') }}
51 |
52 | {# @SyliusShopBundle/_styles.html.twig #}
53 | {{ encore_entry_link_tags('bitbag-productBundle-shop', null, 'product_bundle_shop') }}
54 |
55 | {# @SyliusAdminBundle/_scripts.html.twig #}
56 | {{ encore_entry_script_tags('bitbag-productBundle-admin', null, 'product_bundle_admin') }}
57 |
58 | {# @SyliusAdminBundle/_styles.html.twig #}
59 | {{ encore_entry_link_tags('bitbag-productBundle-admin', null, 'product_bundle_admin') }}
60 | ```
61 |
62 | 5. Run `yarn encore dev` or `yarn encore production`
63 |
--------------------------------------------------------------------------------
/assets/admin/entry.js:
--------------------------------------------------------------------------------
1 | import './js';
2 | import './scss/main.scss';
3 |
--------------------------------------------------------------------------------
/assets/admin/js/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/assets/admin/js/index.js
--------------------------------------------------------------------------------
/assets/admin/scss/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/assets/admin/scss/main.scss
--------------------------------------------------------------------------------
/assets/shop/entry.js:
--------------------------------------------------------------------------------
1 | import './js';
2 | import './scss/main.scss';
3 |
--------------------------------------------------------------------------------
/assets/shop/js/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/assets/shop/js/index.js
--------------------------------------------------------------------------------
/assets/shop/scss/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/assets/shop/scss/main.scss
--------------------------------------------------------------------------------
/config/api_resources/shop/Product.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
29 |
30 |
31 |
32 |
33 | shop:product_bundle:read
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/config/api_resources/shop/ProductBundleItem.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
16 |
21 |
22 |
23 |
24 |
25 | shop:product_bundle_items:read
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/config/config.yml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: resources.yml }
3 | - { resource: services.xml }
4 | - { resource: "@BitBagSyliusProductBundlePlugin/config/twig_hooks/twig_hooks.yaml" }
5 |
6 | framework:
7 | messenger:
8 | buses:
9 | bitbag_sylius_product_bundle.command_bus: ~
10 |
--------------------------------------------------------------------------------
/config/doctrine/ProductBundle.orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/config/doctrine/ProductBundleItem.orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/config/doctrine/ProductBundleOrderItem.orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/config/resources.yml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: resources/product_bundle.yml }
3 | - { resource: resources/product_bundle_item.yml }
4 | - { resource: resources/product_bundle_order_item.yml }
5 |
--------------------------------------------------------------------------------
/config/resources/product_bundle.yml:
--------------------------------------------------------------------------------
1 | sylius_resource:
2 | resources:
3 | bitbag_sylius_product_bundle.product_bundle:
4 | driver: doctrine/orm
5 | classes:
6 | model: BitBag\SyliusProductBundlePlugin\Entity\ProductBundle
7 | interface: BitBag\SyliusProductBundlePlugin\Entity\ProductBundleInterface
8 | form: BitBag\SyliusProductBundlePlugin\Form\Type\ProductBundleType
9 |
--------------------------------------------------------------------------------
/config/resources/product_bundle_item.yml:
--------------------------------------------------------------------------------
1 | sylius_resource:
2 | resources:
3 | bitbag_sylius_product_bundle.product_bundle_item:
4 | driver: doctrine/orm
5 | classes:
6 | model: BitBag\SyliusProductBundlePlugin\Entity\ProductBundleItem
7 | interface: BitBag\SyliusProductBundlePlugin\Entity\ProductBundleItemInterface
8 | form: BitBag\SyliusProductBundlePlugin\Form\Type\ProductBundleItemType
9 |
--------------------------------------------------------------------------------
/config/resources/product_bundle_order_item.yml:
--------------------------------------------------------------------------------
1 | sylius_resource:
2 | resources:
3 | bitbag_sylius_product_bundle.product_bundle_order_item:
4 | driver: doctrine/orm
5 | classes:
6 | model: BitBag\SyliusProductBundlePlugin\Entity\ProductBundleOrderItem
7 | interface: BitBag\SyliusProductBundlePlugin\Entity\ProductBundleOrderItemInterface
8 |
--------------------------------------------------------------------------------
/config/routes.yml:
--------------------------------------------------------------------------------
1 | bitbag_sylius_product_bundle_admin:
2 | resource: routes/admin.yml
3 | prefix: '/%sylius_admin.path_name%'
4 |
5 | bitbag_sylius_product_bundle_shop:
6 | resource: routes/shop.yml
7 | prefix: /{_locale}
8 | requirements:
9 | _locale: ^[a-z]{2}(?:_[A-Z]{2})?$
10 |
11 |
--------------------------------------------------------------------------------
/config/routes/admin.yml:
--------------------------------------------------------------------------------
1 | bitbag_product_bundle_admin_product_create_bundle:
2 | path: /products/new/bundle
3 | methods: [GET, POST]
4 | defaults:
5 | _controller: sylius.controller.product::createAction
6 | _sylius:
7 | section: admin
8 | permission: true
9 | factory:
10 | method: createWithVariantAndBundle
11 | template: "@SyliusAdmin/shared/crud/create.html.twig"
12 | redirect: sylius_admin_product_update
13 | form:
14 | type: Sylius\Bundle\AdminBundle\Form\Type\ProductType
15 | options:
16 | validation_groups:
17 | - sylius
18 | - bitbag_sylius_product_bundle
19 | vars:
20 | subheader: sylius.ui.manage_your_product_catalog
21 | templates:
22 | form: "@SyliusAdmin/product/form.html.twig"
23 | route:
24 | name: bitbag_product_bundle_admin_product_create_bundle
25 |
26 | bitbag_product_bundle_admin_ajax_product_variants_by_phrase:
27 | path: /ajax/product-variants/search-by-phrase
28 | methods: [GET]
29 | defaults:
30 | _controller: sylius.controller.product_variant::indexAction
31 | _format: json
32 | _sylius:
33 | serialization_groups: [Autocomplete]
34 | permission: true
35 | repository:
36 | method: findByPhrase
37 | arguments:
38 | phrase: $phrase
39 | locale: expr:service('sylius.context.locale').getLocaleCode()
40 |
41 | bitbag_product_bundle_admin_ajax_product_variants_by_codes:
42 | path: /ajax/product-variants/by-codes
43 | methods: [GET]
44 | defaults:
45 | _controller: sylius.controller.product_variant::indexAction
46 | _format: json
47 | _sylius:
48 | serialization_groups: [Autocomplete]
49 | permission: true
50 | repository:
51 | method: findByCodes
52 | arguments: [$code]
53 |
--------------------------------------------------------------------------------
/config/routes/shop.yml:
--------------------------------------------------------------------------------
1 | bitbag_sylius_product_bundle_shop_ajax_cart_add_product_bundle:
2 | path: /ajax/cart/product-bundle/add
3 | methods: [POST]
4 | defaults:
5 | _controller: bitbag_sylius_product_bundle.controller.order_item::addProductBundleAction
6 | _format: json
7 | _sylius:
8 | factory:
9 | method: createForProduct
10 | arguments: [expr:notFoundOnNull(service('sylius.repository.product').find($productId))]
11 | form:
12 | type: BitBag\SyliusProductBundlePlugin\Form\Type\AddProductBundleToCartType
13 | options:
14 | product: expr:notFoundOnNull(service('sylius.repository.product').find($productId))
15 | redirect:
16 | route: sylius_shop_cart_summary
17 | parameters: {}
18 | flash: sylius.cart.add_item
19 |
20 | bitbag_sylius_product_bundle_shop_partial_cart_add_product_bundle:
21 | path: /_partial/cart/product-bundle/add
22 | methods: [GET]
23 | defaults:
24 | _controller: bitbag_sylius_product_bundle.controller.order_item::addProductBundleAction
25 | _sylius:
26 | template: $template
27 | factory:
28 | method: createForProduct
29 | arguments: [expr:notFoundOnNull(service('sylius.repository.product').find($productId))]
30 | form:
31 | type: BitBag\SyliusProductBundlePlugin\Form\Type\AddProductBundleToCartType
32 | options:
33 | product: expr:notFoundOnNull(service('sylius.repository.product').find($productId))
34 | redirect:
35 | route: sylius_shop_cart_summary
36 | parameters: {}
37 |
--------------------------------------------------------------------------------
/config/serialization/AddProductBundleToCartCommand.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | shop:product_bundle:add_to_cart
16 |
17 |
18 | shop:product_bundle:add_to_cart
19 |
20 |
21 | shop:product_bundle:add_to_cart
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/config/serialization/AddProductBundleToCartDto.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | shop:cart:add_product_bundle
16 |
17 |
18 | shop:cart:add_product_bundle
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/config/serialization/OrderItem.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | admin:order:read
16 | admin:order_item:read
17 | shop:order_item:read
18 | shop:cart:read
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/config/serialization/Product.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | sylius:admin:product:index
16 | sylius:admin:product:show
17 | sylius:admin:product:create
18 | sylius:admin:product:update
19 | sylius:shop:product:index
20 | sylius:shop:product:show
21 |
22 |
23 | sylius:admin:product:index
24 | sylius:admin:product:show
25 | sylius:admin:product:create
26 | sylius:admin:product:update
27 | sylius:shop:product:index
28 | sylius:shop:product:show
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/config/serialization/ProductBundleItem.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | admin:product_bundle:create
16 | admin:product_bundle:update
17 | shop:product:read
18 | shop:product_bundle:read
19 |
20 |
21 | admin:product_bundle:create
22 | admin:product_bundle:update
23 | shop:product:read
24 | shop:product_bundle:read
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/config/serialization/ProductBundleOrderItem.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | admin:order:read
16 | admin:order_item:read
17 |
18 |
19 | admin:order:read
20 | admin:order_item:read
21 | shop:order_item:read
22 | shop:cart:read
23 |
24 |
25 | admin:order:read
26 | admin:order_item:read
27 | shop:order_item:read
28 | shop:cart:read
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/config/serialization/ProductVariant.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | shop:product:read
16 | shop:product_bundle:read
17 | shop:order_item:read
18 | shop:cart:read
19 |
20 |
21 | shop:product_bundle:read
22 |
23 |
24 | shop:product:read
25 | shop:product_bundle:read
26 |
27 |
28 | shop:product:read
29 | shop:product_bundle:read
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/config/serialization/ProductVariantTranslation.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | shop:product:read
16 | shop:product_bundle:read
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/config/services.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/config/services/controller.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/config/services/event_listener.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/config/services/form.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | bitbag_sylius_product_bundle
7 |
8 |
9 |
10 | bitbag_sylius_product_bundle
11 |
12 |
13 |
14 |
15 |
16 | %bitbag_sylius_product_bundle.model.product_bundle.class%
17 | %bitbag_sylius_product_bundle.form.type.product_bundle.validation_groups%
18 |
19 |
20 |
21 |
22 | %bitbag_sylius_product_bundle.model.product_bundle_item.class%
23 | %bitbag_sylius_product_bundle.form.type.product_bundle_item.validation_groups%
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/config/services/handler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/config/services/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/config/services/processor.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/config/services/product.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | BitBag\SyliusProductBundlePlugin\Form\Type\AddProductBundleToCartType
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/config/services/transformer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/config/services/twig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/config/services/validator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/config/twig_hooks/order/show.yaml:
--------------------------------------------------------------------------------
1 | sylius_twig_hooks:
2 | hooks:
3 | 'sylius_admin.order.show.content.sections.items.body':
4 | item:
5 | template: '@SyliusAdmin/order/show/content/sections/items/body/item.html.twig'
6 | priority: 800
7 |
--------------------------------------------------------------------------------
/config/twig_hooks/product/admin/create.yaml:
--------------------------------------------------------------------------------
1 | sylius_twig_hooks:
2 | hooks:
3 | 'sylius_admin.product.create.content.form.side_navigation':
4 | bundle:
5 | template: '@BitBagSyliusProductBundlePlugin/Admin/product/form/side_navigation/bundle.html.twig'
6 | priority: -10
7 |
8 | 'sylius_admin.product.create.content.form.sections':
9 | bundle:
10 | template: '@BitBagSyliusProductBundlePlugin/Admin/product/form/sections/bundle.html.twig'
11 | priority: -10
12 |
13 | 'sylius_admin.product.create.content.form.sections.bundle':
14 | bundle:
15 | template: '@BitBagSyliusProductBundlePlugin/Admin/product/form/sections/bundle/productBundleItem.html.twig'
16 | priority: 0
17 |
--------------------------------------------------------------------------------
/config/twig_hooks/product/admin/update.yaml:
--------------------------------------------------------------------------------
1 | sylius_twig_hooks:
2 | hooks:
3 | 'sylius_admin.product.update.content.form.side_navigation':
4 | bundle:
5 | template: '@BitBagSyliusProductBundlePlugin/Admin/product/form/side_navigation/bundle.html.twig'
6 | priority: -10
7 |
8 | 'sylius_admin.product.update.content.form.sections':
9 | bundle:
10 | template: '@BitBagSyliusProductBundlePlugin/Admin/product/form/sections/bundle.html.twig'
11 | priority: -10
12 |
13 | 'sylius_admin.product.update.content.form.sections.bundle':
14 | product_bundle:
15 | template: '@BitBagSyliusProductBundlePlugin/Admin/product/form/sections/bundle/productBundleItem.html.twig'
16 | priority: 0
17 |
--------------------------------------------------------------------------------
/config/twig_hooks/product/shop/show.yaml:
--------------------------------------------------------------------------------
1 | sylius_twig_hooks:
2 | hooks:
3 | 'sylius_shop.product.show.content.info.summary.add_to_cart':
4 | bundle:
5 | component: 'sylius_shop:product:add_to_cart_form'
6 | props:
7 | product: '@=_context.product'
8 | template: '@BitBagSyliusProductBundlePlugin/Shop/product/show/page/info/summary/add_to_cart/addProductBundleToCart.html.twig'
9 | priority: 20
10 |
--------------------------------------------------------------------------------
/config/twig_hooks/twig_hooks.yaml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: "@BitBagSyliusProductBundlePlugin/config/twig_hooks/product/**/*.yaml" }
3 | - { resource: "@BitBagSyliusProductBundlePlugin/config/twig_hooks/order/*.yaml" }
4 |
--------------------------------------------------------------------------------
/config/validation/AddProductBundleToCartCommand.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/config/validation/AddProductBundleToCartDto.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/config/validation/ProductBundle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/config/validation/ProductBundleItem.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 |
16 |
17 | bitbag_sylius_product_bundle.product_bundle_item.product_variant.not_blank
18 |
19 | bitbag_sylius_product_bundle
20 |
21 |
22 |
23 |
24 |
25 | bitbag_sylius_product_bundle.product_bundle_item.quantity.not_blank
26 |
27 | bitbag_sylius_product_bundle
28 |
29 |
30 |
31 |
32 | bitbag_sylius_product_bundle
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/doc/bundle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/doc/bundle.png
--------------------------------------------------------------------------------
/doc/bundle_cart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/doc/bundle_cart.png
--------------------------------------------------------------------------------
/doc/bundle_productpage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/doc/bundle_productpage.png
--------------------------------------------------------------------------------
/doc/bundle_taxon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/doc/bundle_taxon.png
--------------------------------------------------------------------------------
/doc/create_bundle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/doc/create_bundle.png
--------------------------------------------------------------------------------
/doc/functionalities.md:
--------------------------------------------------------------------------------
1 | # Functionalities
2 |
3 | ---
4 | **Bundles**
5 |
6 | The plugin gives the user the opportunity to create bundles that contain more than product from the store. Creating a bundle is possible in the admin panel in the Products section.
7 |
8 |
9 |
10 |
11 |
12 | After choosing the right option, the user is taken to the bundle creation page. All the sections are just the same as for the normal products. However, there is a section that is unique for the plugin and it is Bundle section.
13 |
14 |
15 |
16 |
17 |
18 | In there user can add chosen variants of the products to the bundle and decide what should be their quantity per bundle.
19 |
20 | > When the option `is packed product` is `not checked`, the customer, when adding the product bundle to the basket, can change its variants (example in one of the screens below).
21 |
22 | > When the `is packed product` option is `checked`, it is not possible for the customer to change product variants.
23 |
24 | After setting all the other required info, taxonomy and enabling the bundle in the chosen channel, the user can buy the bundle in the shop.
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ecs.php:
--------------------------------------------------------------------------------
1 | import('vendor/bitbag/coding-standard/ecs.php');
12 | $config->paths(['src', 'tests']);
13 | };
14 |
--------------------------------------------------------------------------------
/features/creating_bundled_product.feature:
--------------------------------------------------------------------------------
1 | @bundled_product
2 | Feature: Creating a product in store which is a bundle of other products
3 | I want to be able to add bundled product to cart
4 |
5 | Background:
6 | Given the store operates on a single channel in "United States"
7 | And I am logged in as an administrator
8 | And the store has a product "Jack Daniels Gentleman" priced at "$10.00"
9 | And the store has a product "Johny Walker Black" priced at "$10.00"
10 | And the store has a product "Jim Beam Double Oak" priced at "$10.00"
11 |
12 | @ui
13 | Scenario: Creating a bundled product
14 | When I want to create a new bundled product
15 | And I specify its code as "WHISKEY_PACK"
16 | And I name it "Whiskey double pack" in "English (United States)"
17 | And I set its slug to "whiskey-double-pack" in "English (United States)"
18 | And I set its price to "$10.00" for "United States" channel
19 | And I set its original price to "$20.00" for "United States" channel
20 | And I add product "Johny Walker Black" and "Jack Daniels Gentleman" to the bundle
21 | And I add it
22 | Then I should be notified that it has been successfully created
23 |
24 | @ui
25 | Scenario: Creating a bundled product with more products
26 | When I want to create a new bundled product
27 | And I specify its code as "WHISKEY_BIG_PACK"
28 | And I name it "Whiskey triple pack" in "English (United States)"
29 | And I set its slug to "whiskey-triple-pack" in "English (United States)"
30 | And I set its price to "$10.00" for "United States" channel
31 | And I set its original price to "$20.00" for "United States" channel
32 | And I add product "Johny Walker Black" and "Jack Daniels Gentleman" and "Jim Beam Double Oak" to the bundle
33 | And I add it
34 | Then I should be notified that it has been successfully created
35 |
--------------------------------------------------------------------------------
/node_modules:
--------------------------------------------------------------------------------
1 | tests/Application/node_modules
--------------------------------------------------------------------------------
/phpspec.yml.dist:
--------------------------------------------------------------------------------
1 | suites:
2 | main:
3 | namespace: BitBag\SyliusProductBundlePlugin
4 | psr4_prefix: BitBag\SyliusProductBundlePlugin
5 |
--------------------------------------------------------------------------------
/phpstan.neon.dist:
--------------------------------------------------------------------------------
1 | parameters:
2 | reportUnmatchedIgnoredErrors: false
3 | checkMissingIterableValueType: false
4 |
5 | level: 7
6 | paths:
7 | - src
8 |
9 | excludes_analyse:
10 | # Makes PHPStan crash
11 | - 'src/DependencyInjection/Configuration.php'
12 |
13 | # Test dependencies
14 | - 'tests/Application/app/**.php'
15 | - 'tests/Application/src/**.php'
16 |
17 | ignoreErrors:
18 | - '/Parameter #1 \$productRepository of method BitBag\\SyliusProductBundlePlugin\\Component\\Product\\AddToCartFormComponent::initializeProduct\(\) expects Sylius\\Component\\Core\\Repository\\ProductRepositoryInterface, Sylius\\Component\\Core\\Repository\\ProductRepositoryInterface given\./'
19 | - '/Parameter #10 \$productRepository of method Sylius\\Bundle\\ShopBundle\\Twig\\Component\\Product\\AddToCartFormComponent::__construct\(\) expects Sylius\\Component\\Core\\Repository\\ProductRepositoryInterface\, Sylius\\Component\\Core\\Repository\\ProductRepositoryInterface\ given\./'
20 | - identifier: missingType.iterableValue
21 | - identifier: missingType.generics
22 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 | ./tests/Api
10 |
11 |
12 | ./tests/Api
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/spec/EventListener/AddProductToProductBundleWhenEditNormalProductEventListenerSpec.php:
--------------------------------------------------------------------------------
1 | shouldHaveType(AddProductToProductBundleWhenEditNormalProductEventListener::class);
24 | }
25 |
26 | public function it_should_add_product_to_product_bundle_if_not_exist_on_pre_create_and_update_event(
27 | ResourceControllerEvent $resourceControllerEvent,
28 | ProductInterface $product,
29 | ProductBundleInterface $productBundle
30 | ): void {
31 | $resourceControllerEvent->getSubject()->willReturn($product);
32 |
33 | $product->getProductBundle()->shouldBeCalled();
34 |
35 | $product->getProductBundle()->willReturn($productBundle);
36 |
37 | $this->addProductToProductBundle($resourceControllerEvent);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/BitBagSyliusProductBundlePlugin.php:
--------------------------------------------------------------------------------
1 | addCompilerPass(new AuthenticationManagerPolyfillPass());
31 |
32 | parent::build($container);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Command/AddProductBundleItemToCartCommand.php:
--------------------------------------------------------------------------------
1 | productVariant = $productBundleItem->getProductVariant();
25 | $this->quantity = $productBundleItem->getQuantity();
26 | }
27 |
28 | public function getProductBundleItem(): ProductBundleItemInterface
29 | {
30 | return $this->productBundleItem;
31 | }
32 |
33 | public function getProductVariant(): ?ProductVariantInterface
34 | {
35 | return $this->productVariant;
36 | }
37 |
38 | public function setProductVariant(ProductVariantInterface $productVariant): void
39 | {
40 | $this->productVariant = $productVariant;
41 | }
42 |
43 | public function getQuantity(): ?int
44 | {
45 | return $this->quantity;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Command/AddProductBundleToCartCommand.php:
--------------------------------------------------------------------------------
1 | orderId;
26 | }
27 |
28 | public function getProductCode(): string
29 | {
30 | return $this->productCode;
31 | }
32 |
33 | public function getQuantity(): int
34 | {
35 | return $this->quantity;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Command/OrderIdentityAwareInterface.php:
--------------------------------------------------------------------------------
1 | getProductCode();
38 | $quantity = $object->getQuantity();
39 |
40 | return new AddProductBundleToCartCommand($cart->getId(), $productCode, $quantity);
41 | }
42 |
43 | public function supportsTransformation(
44 | mixed $data,
45 | string $to,
46 | array $context = [],
47 | ): bool {
48 | return isset($context['input']['class']) && AddProductBundleToCartDto::class === $context['input']['class'];
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/DependencyInjection/CompilerPass/AuthenticationManagerPolyfillPass.php:
--------------------------------------------------------------------------------
1 | has('security.authentication_manager') &&
23 | true === $container->has('security.authentication.manager')
24 | ) {
25 | $container->setAlias('security.authentication_manager', 'security.authentication.manager');
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Dto/AddProductBundleToCartDto.php:
--------------------------------------------------------------------------------
1 | productBundleItems = new ArrayCollection($productBundleItems);
31 | }
32 |
33 | public function getCart(): OrderInterface
34 | {
35 | return $this->cart;
36 | }
37 |
38 | public function setCart(OrderInterface $cart): void
39 | {
40 | $this->cart = $cart;
41 | }
42 |
43 | public function getCartItem(): OrderItemInterface
44 | {
45 | return $this->cartItem;
46 | }
47 |
48 | public function setCartItem(OrderItemInterface $cartItem): void
49 | {
50 | $this->cartItem = $cartItem;
51 | }
52 |
53 | public function getProduct(): ProductInterface
54 | {
55 | return $this->product;
56 | }
57 |
58 | public function setProduct(ProductInterface $product): void
59 | {
60 | $this->product = $product;
61 | }
62 |
63 | public function getProductBundleItems(): ArrayCollection
64 | {
65 | return $this->productBundleItems;
66 | }
67 |
68 | public function getProductCode(): string
69 | {
70 | return $this->product->getCode() ?? '';
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Dto/AddProductBundleToCartDtoInterface.php:
--------------------------------------------------------------------------------
1 | orderTokenValue;
30 | }
31 |
32 | public function setOrderTokenValue(string $orderTokenValue): void
33 | {
34 | $this->orderTokenValue = $orderTokenValue;
35 | }
36 |
37 | public function getProductCode(): string
38 | {
39 | return $this->productCode;
40 | }
41 |
42 | public function getQuantity(): int
43 | {
44 | return $this->quantity;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Entity/OrderItemInterface.php:
--------------------------------------------------------------------------------
1 | createdAt = new \DateTime();
36 | }
37 |
38 | public function getId(): ?int
39 | {
40 | return $this->id;
41 | }
42 |
43 | public function getProductVariant(): ?ProductVariantInterface
44 | {
45 | return $this->productVariant;
46 | }
47 |
48 | public function setProductVariant(?ProductVariantInterface $productVariant): void
49 | {
50 | $this->productVariant = $productVariant;
51 | }
52 |
53 | public function getQuantity(): ?int
54 | {
55 | return $this->quantity;
56 | }
57 |
58 | public function setQuantity(?int $quantity): void
59 | {
60 | $this->quantity = $quantity;
61 | }
62 |
63 | public function getProductBundle(): ?ProductBundleInterface
64 | {
65 | return $this->productBundle;
66 | }
67 |
68 | public function setProductBundle(?ProductBundleInterface $productBundle): void
69 | {
70 | $this->productBundle = $productBundle;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Entity/ProductBundleItemInterface.php:
--------------------------------------------------------------------------------
1 | id;
39 | }
40 |
41 | public function getOrderItem(): ?OrderItemInterface
42 | {
43 | return $this->orderItem;
44 | }
45 |
46 | public function setOrderItem(?OrderItemInterface $orderItem): void
47 | {
48 | $this->orderItem = $orderItem;
49 | }
50 |
51 | public function getProductBundleItem(): ?ProductBundleItemInterface
52 | {
53 | return $this->productBundleItem;
54 | }
55 |
56 | public function setProductBundleItem(?ProductBundleItemInterface $productBundleItem): void
57 | {
58 | $this->productBundleItem = $productBundleItem;
59 | }
60 |
61 | public function getProductVariant(): ?ProductVariantInterface
62 | {
63 | return $this->productVariant;
64 | }
65 |
66 | public function setProductVariant(?ProductVariantInterface $productVariant): void
67 | {
68 | $this->productVariant = $productVariant;
69 | }
70 |
71 | public function getQuantity(): ?int
72 | {
73 | return $this->quantity;
74 | }
75 |
76 | public function setQuantity(?int $quantity): void
77 | {
78 | $this->quantity = $quantity;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/Entity/ProductBundleOrderItemInterface.php:
--------------------------------------------------------------------------------
1 | productBundleOrderItems = new ArrayCollection();
24 | }
25 |
26 | /** @return ProductBundleOrderItemInterface[]|ArrayCollection */
27 | public function getProductBundleOrderItems()
28 | {
29 | return $this->productBundleOrderItems;
30 | }
31 |
32 | public function addProductBundleOrderItem(ProductBundleOrderItemInterface $productBundleOrderItem): void
33 | {
34 | $this->productBundleOrderItems->add($productBundleOrderItem);
35 | $productBundleOrderItem->setOrderItem($this);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Entity/ProductBundlesAwareInterface.php:
--------------------------------------------------------------------------------
1 | productBundle;
22 | }
23 |
24 | public function setProductBundle(?ProductBundleInterface $productBundle): void
25 | {
26 | $this->productBundle = $productBundle;
27 | }
28 |
29 | public function isBundle(): bool
30 | {
31 | return null !== $this->getProductBundle();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Entity/ProductInterface.php:
--------------------------------------------------------------------------------
1 | getSubject();
23 | if (null !== $product->getProductBundle() && null === $product->getProductBundle()->getProduct()) {
24 | $product->getProductBundle()->setProduct($product);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/EventListener/CartItemAddListener.php:
--------------------------------------------------------------------------------
1 | getSubject();
29 |
30 | Assert::isInstanceOf($addToCartCommand, AddProductBundleToCartDtoInterface::class);
31 |
32 | $this->orderModifier->addToOrder($addToCartCommand->getCart(), $addToCartCommand->getCartItem());
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Factory/AddProductBundleItemToCartCommandFactory.php:
--------------------------------------------------------------------------------
1 | getCart()->getId();
30 | $productCode = $dto->getProduct()->getCode() ?? '';
31 | $quantity = $dto->getCartItem()->getQuantity();
32 |
33 | return $this->createNew($cartId, $productCode, $quantity);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Factory/AddProductBundleToCartCommandFactoryInterface.php:
--------------------------------------------------------------------------------
1 | decoratedFactory->createNew();
31 |
32 | return $orderItem;
33 | }
34 |
35 | public function createWithVariant(ProductVariantInterface $productVariant): OrderItemInterface
36 | {
37 | $orderItem = $this->createNew();
38 | $orderItem->setVariant($productVariant);
39 |
40 | return $orderItem;
41 | }
42 |
43 | public function createForProduct(ProductInterface $product): \Sylius\Component\Core\Model\OrderItemInterface
44 | {
45 | return $this->decoratedFactory->createForProduct($product);
46 | }
47 |
48 | public function createForCart(OrderInterface $order): \Sylius\Component\Core\Model\OrderItemInterface
49 | {
50 | return $this->decoratedFactory->createForCart($order);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Factory/OrderItemFactoryInterface.php:
--------------------------------------------------------------------------------
1 | decoratedFactory->createNew();
29 |
30 | return $productBundleOrderItem;
31 | }
32 |
33 | public function createFromProductBundleItem(ProductBundleItemInterface $bundleItem): ProductBundleOrderItemInterface
34 | {
35 | /** @var ProductBundleOrderItemInterface $productBundleOrderItem */
36 | $productBundleOrderItem = $this->decoratedFactory->createNew();
37 |
38 | $productBundleOrderItem->setProductBundleItem($bundleItem);
39 | $productBundleOrderItem->setProductVariant($bundleItem->getProductVariant());
40 | $productBundleOrderItem->setQuantity($bundleItem->getQuantity());
41 |
42 | return $productBundleOrderItem;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Factory/ProductBundleOrderItemFactoryInterface.php:
--------------------------------------------------------------------------------
1 | productBundleFactory->createNew();
32 |
33 | /** @var ProductInterface $product */
34 | $product = $this->createWithVariant();
35 |
36 | $productBundle->setProduct($product);
37 |
38 | $product->setProductBundle($productBundle);
39 |
40 | return $product;
41 | }
42 |
43 | public function createNew(): BaseProductInterface
44 | {
45 | /** @var BaseProductInterface $product */
46 | $product = $this->decoratedFactory->createNew();
47 |
48 | return $product;
49 | }
50 |
51 | public function createWithVariant(): BaseProductInterface
52 | {
53 | return $this->decoratedFactory->createWithVariant();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Factory/ProductFactoryInterface.php:
--------------------------------------------------------------------------------
1 | add('productBundle', ProductBundleType::class, [
26 | 'label' => false,
27 | 'constraints' => [new Valid()],
28 | ])
29 | ;
30 | }
31 |
32 | public static function getExtendedTypes(): iterable
33 | {
34 | return [ProductType::class];
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Form/Type/AddProductBundleToCartType.php:
--------------------------------------------------------------------------------
1 | add('cartItem', CartItemType::class, [
28 | 'product' => $options['product'],
29 | ])
30 | ->add('productBundleItems', CollectionType::class, [
31 | 'entry_type' => AddProductBundleItemToCartType::class,
32 | 'entry_options' => [
33 | 'product' => $options['product'],
34 | ],
35 | ])
36 | ;
37 | }
38 |
39 | public function configureOptions(OptionsResolver $resolver): void
40 | {
41 | $resolver
42 | ->setDefined([
43 | 'product',
44 | ])
45 | ->setAllowedTypes('product', ProductInterface::class)
46 | ->setDefaults([
47 | 'data_class' => AddProductBundleToCartDto::class,
48 | ])
49 | ;
50 | }
51 |
52 | public function getBlockPrefix(): string
53 | {
54 | return 'bitbag_sylius_product_bundle_plugin_add_product_bundle_to_cart';
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Form/Type/ProductBundleItemType.php:
--------------------------------------------------------------------------------
1 | add('quantity', IntegerType::class, [
25 | 'label' => false,
26 | 'required' => false,
27 | ])
28 | ->add('productVariant', ProductVariantAutocompleteType::class, [
29 | 'label' => false,
30 | ])
31 | ;
32 | }
33 |
34 | public function getBlockPrefix(): string
35 | {
36 | return 'bitbag_sylius_product_bundle_plugin_product_bundle_item';
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Form/Type/ProductBundleType.php:
--------------------------------------------------------------------------------
1 | add('isPackedProduct', CheckboxType::class, [
26 | 'label' => 'bitbag_sylius_product_bundle.ui.is_packed_product',
27 | ])
28 | ->add('productBundleItems', LiveCollectionType::class, [
29 | 'entry_type' => ProductBundleItemType::class,
30 | 'entry_options' => ['label' => false],
31 | 'allow_add' => true,
32 | 'allow_delete' => true,
33 | 'by_reference' => false,
34 | 'label' => false,
35 | 'button_add_type' => AddButtonType::class,
36 | ])
37 | ;
38 | }
39 |
40 | public function getBlockPrefix(): string
41 | {
42 | return 'bitbag_sylius_product_bundle_plugin_product_bundle';
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Handler/AddProductBundleToCartHandler.php:
--------------------------------------------------------------------------------
1 | orderRepository->findCartById($addProductBundleToCartCommand->getOrderId());
36 | Assert::notNull($cart);
37 |
38 | /** @var ProductInterface|null $product */
39 | $product = $this->productRepository->findOneByCode($addProductBundleToCartCommand->getProductCode());
40 | Assert::notNull($product);
41 | Assert::true($product->isBundle());
42 |
43 | /** @var ProductBundleInterface|null $productBundle */
44 | $productBundle = $product->getProductBundle();
45 | Assert::notNull($productBundle);
46 |
47 | $quantity = $addProductBundleToCartCommand->getQuantity();
48 | Assert::greaterThan($quantity, 0);
49 |
50 | $this->cartProcessor->process($cart, $productBundle, $quantity);
51 | $this->orderRepository->add($cart);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Handler/AddProductBundleToCartHandler/CartProcessorInterface.php:
--------------------------------------------------------------------------------
1 | getMenu();
21 |
22 | $menu
23 | ->addChild('bundle')
24 | ->setAttribute('template', '@BitBagSyliusProductBundlePlugin/Admin/product/form/side_navigation/bundle.html.twig')
25 | ->setLabel('bitbag_sylius_product_bundle.ui.bundle')
26 | ;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Repository/ProductVariantRepository.php:
--------------------------------------------------------------------------------
1 | getEntityManager()->getExpressionBuilder();
24 |
25 | return $this->createQueryBuilder('o')
26 | ->leftJoin('o.translations', 'translation', 'WITH', 'translation.locale = :locale')
27 | ->innerJoin('o.product', 'product')
28 | ->andWhere($expr->orX(
29 | 'translation.name LIKE :phrase',
30 | 'o.code LIKE :phrase',
31 | 'product.code LIKE :phrase',
32 | ))
33 | ->setParameter('phrase', '%' . $phrase . '%')
34 | ->setParameter('locale', $locale)
35 | ->setMaxResults(20)
36 | ->getQuery()
37 | ->getResult()
38 | ;
39 | }
40 |
41 | public function findByCodes(array $codes): array
42 | {
43 | return $this->createQueryBuilder('o')
44 | ->andWhere('o.code IN (:codes)')
45 | ->setParameter('codes', $codes)
46 | ->getQuery()
47 | ->getResult()
48 | ;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Repository/ProductVariantRepositoryInterface.php:
--------------------------------------------------------------------------------
1 | ['html']],
33 | ),
34 | ];
35 | }
36 |
37 | public function renderProductBundleOrderItems(ProductInterface $product): string
38 | {
39 | if (!$product->isBundle()) {
40 | return '';
41 | }
42 |
43 | $productBundle = $product->getProductBundle();
44 |
45 | if (null === $productBundle) {
46 | throw new \RuntimeException('Product does not contain a valid product bundle.');
47 | }
48 |
49 | $items = $productBundle->getProductBundleItems();
50 |
51 | return $this->twig->render('@BitBagSyliusProductBundlePlugin/Admin/Order/Show/_productBundleOrderItems.html.twig', [
52 | 'items' => $items,
53 | ]);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Validator/HasAvailableProductBundle.php:
--------------------------------------------------------------------------------
1 | orderRepository->findCartById($value->getOrderId());
41 |
42 | if (null !== $cart) {
43 | return;
44 | }
45 |
46 | $this->context->addViolation(HasExistingCart::CART_DOESNT_EXIST_MESSAGE);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Validator/HasProductBundle.php:
--------------------------------------------------------------------------------
1 | productRepository->findOneByCode($value->getProductCode());
43 |
44 | if (null === $product) {
45 | $this->context->addViolation(HasProductBundle::PRODUCT_DOESNT_EXIST_MESSAGE);
46 |
47 | return;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Validator/Sequentially.php:
--------------------------------------------------------------------------------
1 | context;
27 |
28 | $validator = $context->getValidator()->inContext($context);
29 |
30 | $originalCount = $validator->getViolations()->count();
31 |
32 | if (is_iterable($constraint->constraints)) {
33 | foreach ($constraint->constraints as $c) {
34 | if ($originalCount !== $validator->validate($value, $c)->getViolations()->count()) {
35 | break;
36 | }
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/templates/Admin/product/form/sections/bundle.html.twig:
--------------------------------------------------------------------------------
1 | {% set form = hookable_metadata.context.form %}
2 | {% set product = hookable_metadata.context.resource %}
3 |
4 | {% if product.isBundle %}
5 |
17 | {% endif %}
18 |
--------------------------------------------------------------------------------
/templates/Admin/product/form/sections/bundle/productBundleItem.html.twig:
--------------------------------------------------------------------------------
1 | {% from '@SyliusResource/Macros/notification.html.twig' import error %}
2 |
3 | {% set form = hookable_metadata.context.form %}
4 | {% set product_bundle_items = hookable_metadata.context.form.productBundle.productBundleItems %}
5 |
6 |
7 | {{ error(form.vars.errors) }}
8 |
9 | {{ form_row(form.productBundle.isPackedProduct) }}
10 |
11 |
12 |
13 | {{ 'bitbag_sylius_product_bundle.ui.product_variant'|trans }}
14 | {{ 'bitbag_sylius_product_bundle.ui.quantity'|trans }}
15 | {{ 'bitbag_sylius_product_bundle.ui.delete'|trans }}
16 |
17 |
18 |
19 | {% for product_bundle_form in product_bundle_items %}
20 |
21 |
22 | {{ form_row(product_bundle_form.children.productVariant) }}
23 |
24 |
25 | {{ form_row(product_bundle_form.children.quantity) }}
26 |
27 |
28 | {{ form_widget(product_bundle_form.vars.button_delete, { label: 'sylius.ui.delete'|trans, attr: { class: 'btn btn-outline-danger w-100','data-test-image-delete': '' }}) }}
29 |
30 |
31 | {% endfor %}
32 |
33 |
34 |
35 | {{ form_widget(product_bundle_items.vars.button_add) }}
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/templates/Admin/product/form/side_navigation/bundle.html.twig:
--------------------------------------------------------------------------------
1 | {% set product = hookable_metadata.context.resource %}
2 |
3 | {% if product.isBundle %}
4 |
12 | {{ 'bitbag_sylius_product_bundle.ui.bundle'|trans }}
13 |
14 | {% endif %}
15 |
--------------------------------------------------------------------------------
/templates/Shop/product/show/page/info/summary/add_to_cart/addProductBundleToCart.html.twig:
--------------------------------------------------------------------------------
1 | {% form_theme form '@SyliusShop/form/theme.html.twig' %}
2 |
3 | {% if product.isBundle %}
4 | {% set product_bundle_items = form.productBundleItems %}
5 |
6 |
{{ 'bitbag_sylius_product_bundle.ui.products_in_bundle'|trans }}
7 | {% for item in product_bundle_items %}
8 | {% set data = item.vars.data %}
9 |
10 |
11 |
12 | {{ data.quantity }} x {{ data.productVariant.product.name }}
13 |
14 | {% if item.productVariant is defined %}
15 | {{ form_row(item.productVariant) }}
16 | {% endif %}
17 |
18 |
19 | {% endfor %}
20 |
21 |
22 | {% endif %}
23 |
--------------------------------------------------------------------------------
/tests/Api/Admin/OrderTest.php:
--------------------------------------------------------------------------------
1 | fixtures = $this->loadFixturesFromFiles([
32 | 'general/channels.yml',
33 | 'general/authentication.yml',
34 | 'shop/product_bundles.yml',
35 | 'shop/orders.yml',
36 | ]);
37 |
38 | $authToken = $this->getAuthToken('api@example.com', 'sylius-api');
39 | $this->authHeaders = $this->getHeaders($authToken);
40 | }
41 |
42 | /** @test */
43 | public function it_gets_order_data_containing_info_about_bundled_items(): void
44 | {
45 | /** @var OrderInterface $order */
46 | $order = $this->fixtures['order_with_bundle'];
47 |
48 | $this->client->request(
49 | Request::METHOD_GET,
50 | sprintf(self::ENDPOINT_ORDERS_ITEM, $order->getTokenValue()),
51 | [],
52 | [],
53 | $this->authHeaders,
54 | );
55 | $response = $this->client->getResponse();
56 |
57 | $this->assertResponse($response, 'admin/get_order_with_bundle_response', Response::HTTP_OK);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/tests/Api/AdminJsonApiTestCase.php:
--------------------------------------------------------------------------------
1 | client->request(
21 | 'POST',
22 | $endpoint,
23 | [],
24 | [],
25 | ['CONTENT_TYPE' => 'application/json', 'HTTP_ACCEPT' => 'application/json'],
26 | json_encode(['email' => $email, 'password' => $password]),
27 | );
28 |
29 | return json_decode($this->client->getResponse()->getContent(), true)['token'];
30 | }
31 |
32 | public function getHeaders($authToken = null): array
33 | {
34 | $headers = ['CONTENT_TYPE' => 'application/ld+json', 'HTTP_ACCEPT' => 'application/ld+json'];
35 |
36 | if (null === $authToken) {
37 | return $headers;
38 | }
39 |
40 | $authorizationHeader = self::getContainer()->getParameter('sylius.api.authorization_header');
41 | $headers['HTTP_' . $authorizationHeader] = 'Bearer ' . $authToken;
42 |
43 | return $headers;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tests/Api/DataFixtures/ORM/general/authentication.yml:
--------------------------------------------------------------------------------
1 | Sylius\Component\Core\Model\AdminUser:
2 | admin:
3 | plainPassword: sylius-api
4 | roles: [ROLE_API_ACCESS]
5 | enabled: true
6 | email: api@example.com
7 | username: sylius
8 | localeCode: en_US
9 |
--------------------------------------------------------------------------------
/tests/Api/DataFixtures/ORM/general/channels.yml:
--------------------------------------------------------------------------------
1 | Sylius\Component\Core\Model\Channel:
2 | channel_web:
3 | code: "WEB"
4 | name: "Web Channel"
5 | hostname: "localhost"
6 | description: "Lorem ipsum"
7 | baseCurrency: "@currency1"
8 | defaultLocale: "@locale"
9 | locales: ["@locale"]
10 | color: "black"
11 | enabled: true
12 | taxCalculationStrategy: "order_items_based"
13 |
14 | Sylius\Component\Currency\Model\Currency:
15 | currency1:
16 | code: "EUR"
17 |
18 | Sylius\Component\Locale\Model\Locale:
19 | locale:
20 | code: "en_US"
21 |
--------------------------------------------------------------------------------
/tests/Api/JsonApiTestCase.php:
--------------------------------------------------------------------------------
1 | 'application/ld+json', 'HTTP_ACCEPT' => 'application/ld+json'];
20 |
21 | public const PATCH_HEADER = ['CONTENT_TYPE' => 'application/merge-patch+json', 'HTTP_ACCEPT' => 'application/ld+json'];
22 |
23 | protected static function getContainer(): Container
24 | {
25 | if (is_callable('parent::getContainer')) {
26 | /* @phpstan-ignore-next-line */
27 | return parent::getContainer();
28 | }
29 |
30 | return self::$container;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/Api/Responses/admin/get_order_with_bundle_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": "\/api\/v2\/contexts\/Order",
3 | "@id": "\/api\/v2\/admin\/orders\/zszRdAaZIx",
4 | "@type": "Order",
5 | "customer": "@string@",
6 | "channel": "\/api\/v2\/admin\/channels\/WEB",
7 | "shippingAddress": "@...@",
8 | "billingAddress": "@...@",
9 | "payments": "@*@",
10 | "shipments": "@*@",
11 | "currencyCode": "EUR",
12 | "localeCode": "en_US",
13 | "checkoutState": "completed",
14 | "paymentState": "awaiting_payment",
15 | "shippingState": "ready",
16 | "tokenValue": "zszRdAaZIx",
17 | "id": "@integer@",
18 | "number": "@string@",
19 | "items": [
20 | {
21 | "@id": "@string@",
22 | "@type": "OrderItem",
23 | "variant": "\/api\/v2\/admin\/product-variants\/WHISKEY_DOUBLE_PACK",
24 | "productName": "Whiskey Double Pack",
25 | "id": "@integer@",
26 | "quantity": 1,
27 | "unitPrice": 1800,
28 | "originalUnitPrice": 0,
29 | "total": 1800,
30 | "productBundleOrderItems": [
31 | {
32 | "@type": "ProductBundleOrderItem",
33 | "@id": "@string@",
34 | "id": "@integer@",
35 | "productVariant": "@string@",
36 | "quantity": 1
37 | },
38 | {
39 | "@type": "ProductBundleOrderItem",
40 | "@id": "@string@",
41 | "id": "@integer@",
42 | "productVariant": "@string@",
43 | "quantity": 1
44 | }
45 | ],
46 | "subtotal": 1800
47 | }
48 | ],
49 | "itemsTotal": 1800,
50 | "total": 1800,
51 | "state": "new",
52 | "taxTotal": 0,
53 | "shippingTotal": 0,
54 | "orderPromotionTotal": 0
55 | }
56 |
--------------------------------------------------------------------------------
/tests/Api/Responses/admin/get_product_bundle_collection_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": "\/api\/v2\/contexts\/ProductBundle",
3 | "@id": "\/api\/v2\/admin\/product-bundles",
4 | "@type": "hydra:Collection",
5 | "hydra:totalItems": 1,
6 | "hydra:member": [
7 | {
8 | "@id": "\/api\/v2\/admin\/product-bundles\/@integer@",
9 | "@type": "ProductBundle",
10 | "id": "@integer@",
11 | "product": "\/api\/v2\/admin\/products\/WHISKEY_DOUBLE_PACK",
12 | "items": [
13 | "\/api\/v2\/shop\/product-bundle-items\/@integer@",
14 | "\/api\/v2\/shop\/product-bundle-items\/@integer@"
15 | ],
16 | "createdAt": "@datetime@",
17 | "updatedAt": "@datetime@",
18 | "isPacked": true
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/tests/Api/Responses/admin/get_product_bundle_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": "\/api\/v2\/contexts\/ProductBundle",
3 | "@id": "\/api\/v2\/admin\/product-bundles\/@integer@",
4 | "@type": "ProductBundle",
5 | "id": "@integer@",
6 | "product": "\/api\/v2\/admin\/products\/WHISKEY_DOUBLE_PACK",
7 | "items": [
8 | "\/api\/v2\/shop\/product-bundle-items\/@integer@",
9 | "\/api\/v2\/shop\/product-bundle-items\/@integer@"
10 | ],
11 | "createdAt": "@datetime@",
12 | "updatedAt": "@datetime@",
13 | "isPacked": true
14 | }
15 |
--------------------------------------------------------------------------------
/tests/Api/Responses/admin/post_product_bundle_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": "\/api\/v2\/contexts\/ProductBundle",
3 | "@id": "\/api\/v2\/admin\/product-bundles\/@integer@",
4 | "@type": "ProductBundle",
5 | "id": "@integer@",
6 | "product": "\/api\/v2\/admin\/products\/JOHNNY_WALKER_BUNDLE",
7 | "items": [
8 | "\/api\/v2\/shop\/product-bundle-items\/@integer@",
9 | "\/api\/v2\/shop\/product-bundle-items\/@integer@"
10 | ],
11 | "createdAt": "@datetime@",
12 | "updatedAt": "@datetime@",
13 | "isPacked": true
14 | }
15 |
--------------------------------------------------------------------------------
/tests/Api/Responses/admin/put_product_bundle_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": "\/api\/v2\/contexts\/ProductBundle",
3 | "@id": "\/api\/v2\/admin\/product-bundles\/@integer@",
4 | "@type": "ProductBundle",
5 | "id": "@integer@",
6 | "product": "\/api\/v2\/admin\/products\/WHISKEY_DOUBLE_PACK",
7 | "items": [
8 | "\/api\/v2\/shop\/product-bundle-items\/@integer@",
9 | "\/api\/v2\/shop\/product-bundle-items\/@integer@"
10 | ],
11 | "createdAt": "@datetime@",
12 | "updatedAt": "@datetime@",
13 | "isPacked": false
14 | }
15 |
--------------------------------------------------------------------------------
/tests/Api/Responses/shop/get_bundled_product_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": "\/api\/v2\/contexts\/Product",
3 | "@id": "\/api\/v2\/shop\/products\/WHISKEY_DOUBLE_PACK",
4 | "@type": "Product",
5 | "productTaxons": [],
6 | "mainTaxon": null,
7 | "averageRating": "@integer@",
8 | "images": [],
9 | "id": "@integer@",
10 | "code": "WHISKEY_DOUBLE_PACK",
11 | "variants": ["/api/v2/shop/product-variants/@string@"],
12 | "options": [],
13 | "associations": [],
14 | "createdAt": "@datetime@",
15 | "updatedAt": "@datetime@",
16 | "isBundle": true,
17 | "shortDescription": null,
18 | "reviews": [],
19 | "name": "@string@",
20 | "description": "@string@",
21 | "slug": "@string@",
22 | "bundle": "/api/v2/admin/product-bundles/@integer@",
23 | "defaultVariant": "@string@"
24 | }
25 |
--------------------------------------------------------------------------------
/tests/Api/Responses/shop/get_not_bundled_product_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": "\/api\/v2\/contexts\/Product",
3 | "@id": "\/api\/v2\/shop\/products\/JOHNNY_WALKER_BLACK",
4 | "@type": "Product",
5 | "productTaxons": "@...@",
6 | "mainTaxon": null,
7 | "reviews": "@...@",
8 | "averageRating": "@integer@",
9 | "images": "@...@",
10 | "id": "@integer@",
11 | "code": "JOHNNY_WALKER_BLACK",
12 | "name": "@string@",
13 | "slug": "@string@",
14 | "variants": "@...@",
15 | "options": "@...@",
16 | "createdAt": "@string@",
17 | "updatedAt": "@string@",
18 | "bundle": null,
19 | "isBundle": false,
20 | "description": "@string@",
21 | "shortDescription": null,
22 | "defaultVariant": "@string@"
23 | }
24 |
--------------------------------------------------------------------------------
/tests/Api/Responses/shop/get_product_bundle_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": "\/api\/v2\/contexts\/ProductBundle",
3 | "@id": "@string@",
4 | "@type": "Product",
5 | "product": "\/api\/v2\/shop\/products\/WHISKEY_DOUBLE_PACK",
6 | "items": [
7 | {
8 | "@type": "ProductBundleItem",
9 | "@id": "@string@",
10 | "productVariant": "@...@",
11 | "quantity": 1
12 | },
13 | {
14 | "@type": "ProductBundleItem",
15 | "@id": "@string@",
16 | "productVariant": "@...@",
17 | "quantity": 1
18 | }
19 | ],
20 | "isPacked": true
21 | }
22 |
--------------------------------------------------------------------------------
/tests/Api/Utils/CartHelperTrait.php:
--------------------------------------------------------------------------------
1 | get('sylius.command_bus');
25 |
26 | $command = new PickupCart('WEB', 'en_US', null, $tokenValue, );
27 |
28 | $commandBus->dispatch($command);
29 | }
30 |
31 | public function findCart(string $tokenValue): ?OrderInterface
32 | {
33 | /** @var OrderRepositoryInterface $orderManager */
34 | $orderManager = self::getContainer()->get('sylius.repository.order');
35 |
36 | return $orderManager->findCartByTokenValue($tokenValue);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/tests/Application/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "targets": {
5 | "node": "6"
6 | },
7 | "useBuiltIns": true
8 | }]
9 | ],
10 | "plugins": [
11 | ["transform-object-rest-spread", {
12 | "useBuiltIns": true
13 | }]
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/tests/Application/.env:
--------------------------------------------------------------------------------
1 | # This file is a "template" of which env vars needs to be defined in your configuration or in an .env file
2 | # Set variables here that may be different on each deployment target of the app, e.g. development, staging, production.
3 | # https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration
4 |
5 | ###> symfony/framework-bundle ###
6 | APP_ENV=dev
7 | APP_DEBUG=1
8 | APP_SECRET=EDITME
9 | ###< symfony/framework-bundle ###
10 |
11 | ###> doctrine/doctrine-bundle ###
12 | # Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
13 | # For a sqlite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
14 | # Set "serverVersion" to your server version to avoid edge-case exceptions and extra database calls
15 | # DATABASE_URL=sqlite:///%kernel.project_dir%/var/data_%kernel.environment%.db
16 | DATABASE_URL=mysql://root@127.0.0.1/bitbag_product_bundle_plugin_%kernel.environment%?serverVersion=8
17 | ###< doctrine/doctrine-bundle ###
18 |
19 | ###> symfony/messenger ###
20 | # Choose one of the transports below
21 | # MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
22 | # MESSENGER_TRANSPORT_DSN=doctrine://default
23 | # MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
24 | MESSENGER_TRANSPORT_DSN=sync://
25 | ###< symfony/messenger ###
26 |
27 | ###> lexik/jwt-authentication-bundle ###
28 | JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
29 | JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
30 | JWT_PASSPHRASE=acme_plugin_development
31 | ###< lexik/jwt-authentication-bundle ###
32 |
33 | ###> symfony/swiftmailer-bundle ###
34 | # For Gmail as a transport, use: "gmail://username:password@localhost"
35 | # For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode="
36 | # Delivery is disabled by default via "null://localhost"
37 | MAILER_URL=smtp://localhost
38 | ###< symfony/swiftmailer-bundle ###
39 |
--------------------------------------------------------------------------------
/tests/Application/.env.test:
--------------------------------------------------------------------------------
1 | APP_SECRET='ch4mb3r0f5ecr3ts'
2 |
3 | KERNEL_CLASS='Tests\BitBag\SyliusProductBundlePlugin\Application\Kernel'
4 |
--------------------------------------------------------------------------------
/tests/Application/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: 'airbnb-base',
3 | env: {
4 | node: true,
5 | },
6 | rules: {
7 | 'object-shorthand': ['error', 'always', {
8 | avoidQuotes: true,
9 | avoidExplicitReturnArrows: true,
10 | }],
11 | 'function-paren-newline': ['error', 'consistent'],
12 | 'max-len': ['warn', 120, 2, {
13 | ignoreUrls: true,
14 | ignoreComments: false,
15 | ignoreRegExpLiterals: true,
16 | ignoreStrings: true,
17 | ignoreTemplateLiterals: true,
18 | }],
19 | },
20 | };
21 |
--------------------------------------------------------------------------------
/tests/Application/.gitignore:
--------------------------------------------------------------------------------
1 | /public/assets
2 | /public/build
3 | /public/css
4 | /public/js
5 | /public/media/*
6 | !/public/media/image/
7 | /public/media/image/*
8 | !/public/media/image/.gitignore
9 |
10 | /node_modules
11 |
12 | /config/encryption
13 |
14 | ###> symfony/framework-bundle ###
15 | /.env.*.local
16 | /.env.local
17 | /.env.local.php
18 | /public/bundles
19 | /var/
20 | /vendor/
21 | ###< symfony/framework-bundle ###
22 |
23 | ###> symfony/web-server-bundle ###
24 | /.web-server-pid
25 | ###< symfony/web-server-bundle ###
26 |
--------------------------------------------------------------------------------
/tests/Application/assets/admin/entry.js:
--------------------------------------------------------------------------------
1 | import 'sylius/bundle/AdminBundle/Resources/assets/entrypoint';
2 |
--------------------------------------------------------------------------------
/tests/Application/assets/admin/product-entry.js:
--------------------------------------------------------------------------------
1 | import 'sylius/bundle/AdminBundle/Resources/assets/scripts/product/attribute-tabs-refresher';
2 |
--------------------------------------------------------------------------------
/tests/Application/assets/controllers.json:
--------------------------------------------------------------------------------
1 | {
2 | "controllers": {
3 | "@symfony/ux-autocomplete": {
4 | "autocomplete": {
5 | "main": "dist/controller.js",
6 | "webpackMode": "eager",
7 | "fetch": "eager",
8 | "enabled": true,
9 | "autoimport": {
10 | "tom-select/dist/css/tom-select.default.css": false,
11 | "tom-select/dist/css/tom-select.bootstrap5.css": false
12 | }
13 | }
14 | }
15 | },
16 | "entrypoints": []
17 | }
18 |
--------------------------------------------------------------------------------
/tests/Application/assets/shop/entry.js:
--------------------------------------------------------------------------------
1 | import 'sylius/bundle/ShopBundle/Resources/assets/entrypoint';
2 |
--------------------------------------------------------------------------------
/tests/Application/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | getParameterOption(['--env', '-e'], null, true)) {
19 | putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env);
20 | }
21 |
22 | if ($input->hasParameterOption('--no-debug', true)) {
23 | putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0');
24 | }
25 |
26 | require dirname(__DIR__).'/config/bootstrap.php';
27 |
28 | if ($_SERVER['APP_DEBUG']) {
29 | umask(0000);
30 |
31 | if (class_exists(Debug::class)) {
32 | Debug::enable();
33 | }
34 | }
35 |
36 | $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
37 | $application = new Application($kernel);
38 | $application->run($input);
39 |
--------------------------------------------------------------------------------
/tests/Application/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sylius/plugin-skeleton-test-application",
3 | "description": "Sylius application for plugin testing purposes (composer.json needed for project dir resolving)",
4 | "license": "MIT"
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Application/config/api_platform/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/tests/Application/config/api_platform/.gitkeep
--------------------------------------------------------------------------------
/tests/Application/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | =1.2)
18 | if (is_array($env = @include dirname(__DIR__) . '/.env.local.php')) {
19 | $_SERVER += $env;
20 | $_ENV += $env;
21 | } elseif (!class_exists(Dotenv::class)) {
22 | throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.');
23 | } else {
24 | // load all the .env files
25 | (new Dotenv())->loadEnv(dirname(__DIR__) . '/.env');
26 | }
27 |
28 | $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?? 'dev';
29 | $_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV'];
30 | $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], \FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
31 |
--------------------------------------------------------------------------------
/tests/Application/config/jwt/public.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6QkmF/Xi5nAYb8Kzr7qC
3 | d63V2K+d/nCXbpDUKKDPJAqOtTlMoQSuJRLNnhhp7z1i/Cp4Bhifr20Pu2dq8JYg
4 | 6pRT4ctqvYb/MXxAaPZc3EcBC0S6AhgKO/fDvR3LcqYqGJmQQOXZvxTsgqongdvV
5 | 4XbqFBMMgngyayoBk0VKTaI/s+LQhIce+1QaxbAI0+/zbR0hZ1hWT73orJi3do+1
6 | TBzQol+V7WGa8LlJfmgM56qO3BmVkeTDMBc27pGp6g3+Oufk/l29jEGJlUT9yu7Q
7 | BRhaQTWNVASa2aD+AKjVBzJh53O2zD8slAbjF1M9U7bbWN28Sv+xC/dUz0q9HnPu
8 | RsY2tnwryqTyYn/Hf2xyP3/KvjJ6oslAwemu5JirdJkO7KVQAthWG42gLuhZg3ks
9 | cSZhCLZH7nO2UDsf+2ZZgdbhpYZwR4gDRfNt7GKWXnWZOz9Uw1yVCPgylyZRZwg8
10 | l0y9aABdj3379I22icrwpMZbAgkyxNSV6UNJuxZksLUoP3i9OvXYgPYU9E4tU/Ul
11 | Dm/T1rGSReGoPkU1YQnI50bq7p1byIoUu2scTflvpTVI5a7zULkS1tg60xk7vBRC
12 | aBc7nr4UEtA235N6uLtcGxH11WBMwsKX69sSU0sQdC4Sk25zXM2gc8R1XV9K3qz2
13 | wQorQRlCwrkG44VRDgbFH+8CAwEAAQ==
14 | -----END PUBLIC KEY-----
15 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/assets.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | assets:
3 | packages:
4 | shop:
5 | json_manifest_path: '%kernel.project_dir%/public/build/shop/manifest.json'
6 | admin:
7 | json_manifest_path: '%kernel.project_dir%/public/build/admin/manifest.json'
8 | product_bundle_shop:
9 | json_manifest_path: '%kernel.project_dir%/public/build/bitbag/productBundle/shop/manifest.json'
10 | product_bundle_admin:
11 | json_manifest_path: '%kernel.project_dir%/public/build/bitbag/productBundle/admin/manifest.json'
12 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/bitbag_sylius_product_bundle_plugin.yml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: "@BitBagSyliusProductBundlePlugin/config/config.yml" }
3 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/dev/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | profiler: { only_exceptions: false }
3 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/dev/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: stream
5 | path: "%kernel.logs_dir%/%kernel.environment%.log"
6 | level: debug
7 | firephp:
8 | type: firephp
9 | level: info
10 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/dev/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: true
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/dev/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler:
2 | toolbar: true
3 | intercept_redirects: false
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/doctrine.yaml:
--------------------------------------------------------------------------------
1 | parameters:
2 | # Adds a fallback DATABASE_URL if the env var is not set.
3 | # This allows you to run cache:warmup even if your
4 | # environment variables are not available yet.
5 | # You should not need to change this value.
6 | env(DATABASE_URL): ''
7 |
8 | doctrine:
9 | dbal:
10 | driver: 'pdo_mysql'
11 | server_version: '5.7'
12 | charset: UTF8
13 |
14 | url: '%env(resolve:DATABASE_URL)%'
15 |
16 | orm:
17 | auto_generate_proxy_classes: '%kernel.debug%'
18 | naming_strategy: doctrine.orm.naming_strategy.underscore
19 | auto_mapping: true
20 | mappings:
21 | App:
22 | is_bundle: false
23 | type: xml
24 | dir: '%kernel.project_dir%/src/Resources/config/doctrine'
25 | prefix: 'Tests\BitBag\SyliusProductBundlePlugin\Entity'
26 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/doctrine_migrations.yaml:
--------------------------------------------------------------------------------
1 | doctrine_migrations:
2 | storage:
3 | table_storage:
4 | table_name: sylius_migrations
5 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | secret: '%env(APP_SECRET)%'
3 | form: true
4 | csrf_protection: true
5 | session:
6 | handler_id: ~
7 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/http_discovery.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | Psr\Http\Message\RequestFactoryInterface: '@http_discovery.psr17_factory'
3 | Psr\Http\Message\ResponseFactoryInterface: '@http_discovery.psr17_factory'
4 | Psr\Http\Message\ServerRequestFactoryInterface: '@http_discovery.psr17_factory'
5 | Psr\Http\Message\StreamFactoryInterface: '@http_discovery.psr17_factory'
6 | Psr\Http\Message\UploadedFileFactoryInterface: '@http_discovery.psr17_factory'
7 | Psr\Http\Message\UriFactoryInterface: '@http_discovery.psr17_factory'
8 |
9 | http_discovery.psr17_factory:
10 | class: Http\Discovery\Psr17Factory
11 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/lexik_jwt_authentication.yaml:
--------------------------------------------------------------------------------
1 | lexik_jwt_authentication:
2 | secret_key: '%env(resolve:JWT_SECRET_KEY)%'
3 | public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
4 | pass_phrase: '%env(JWT_PASSPHRASE)%'
5 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/liip_imagine.yaml:
--------------------------------------------------------------------------------
1 | liip_imagine:
2 | resolvers:
3 | default:
4 | web_path:
5 | web_root: "%kernel.project_dir%/public"
6 | cache_prefix: "media/cache"
7 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/mailer.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | mailer:
3 | dsn: 'null://null'
4 | cache:
5 | pools:
6 | test.mailer_pool:
7 | adapter: cache.adapter.filesystem
8 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/prod/doctrine.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | orm:
3 | metadata_cache_driver:
4 | type: service
5 | id: doctrine.system_cache_provider
6 | query_cache_driver:
7 | type: service
8 | id: doctrine.system_cache_provider
9 | result_cache_driver:
10 | type: service
11 | id: doctrine.result_cache_provider
12 |
13 | services:
14 | doctrine.result_cache_provider:
15 | class: Symfony\Component\Cache\DoctrineProvider
16 | public: false
17 | arguments:
18 | - '@doctrine.result_cache_pool'
19 | doctrine.system_cache_provider:
20 | class: Symfony\Component\Cache\DoctrineProvider
21 | public: false
22 | arguments:
23 | - '@doctrine.system_cache_pool'
24 |
25 | framework:
26 | cache:
27 | pools:
28 | doctrine.result_cache_pool:
29 | adapter: cache.app
30 | doctrine.system_cache_pool:
31 | adapter: cache.system
32 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/prod/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: fingers_crossed
5 | action_level: error
6 | handler: nested
7 | nested:
8 | type: stream
9 | path: "%kernel.logs_dir%/%kernel.environment%.log"
10 | level: debug
11 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: ~
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/staging/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: fingers_crossed
5 | action_level: error
6 | handler: nested
7 | nested:
8 | type: stream
9 | path: "%kernel.logs_dir%/%kernel.environment%.log"
10 | level: debug
11 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/stof_doctrine_extensions.yaml:
--------------------------------------------------------------------------------
1 | # Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html
2 | # See the official DoctrineExtensions documentation for more details: https://github.com/Atlantic18/DoctrineExtensions/tree/master/doc/
3 | stof_doctrine_extensions:
4 | default_locale: '%locale%'
5 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | test: ~
3 | session:
4 | handler_id: ~
5 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: stream
5 | path: "%kernel.logs_dir%/%kernel.environment%.log"
6 | level: error
7 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/sylius_theme.yaml:
--------------------------------------------------------------------------------
1 | sylius_theme:
2 | sources:
3 | test: ~
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/sylius_uploader.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | Sylius\Component\Core\Generator\ImagePathGeneratorInterface:
3 | class: Sylius\Behat\Service\Generator\UploadedImagePathGenerator
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler:
2 | toolbar: false
3 | intercept_redirects: false
4 |
5 | framework:
6 | profiler: { collect: false }
7 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | test: ~
3 | session:
4 | handler_id: ~
5 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: stream
5 | path: "%kernel.logs_dir%/%kernel.environment%.log"
6 | level: error
7 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/sylius_channel.yaml:
--------------------------------------------------------------------------------
1 | sylius_channel:
2 | debug: true
3 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/sylius_theme.yaml:
--------------------------------------------------------------------------------
1 | sylius_theme:
2 | sources:
3 | test: ~
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/sylius_uploader.yaml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: "../test/sylius_uploader.yaml" }
3 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/twig.yaml:
--------------------------------------------------------------------------------
1 | twig:
2 | paths: ['%kernel.project_dir%/templates']
3 | debug: '%kernel.debug%'
4 | strict_variables: true
5 |
6 | services:
7 | _defaults:
8 | public: false
9 | autowire: true
10 | autoconfigure: true
11 |
12 | Twig\Extra\Intl\IntlExtension: ~
13 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/translation.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | default_locale: '%locale%'
3 | translator:
4 | paths:
5 | - '%kernel.project_dir%/translations'
6 | fallbacks:
7 | - '%locale%'
8 | - 'en'
9 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/twig.yaml:
--------------------------------------------------------------------------------
1 | twig:
2 | paths: ['%kernel.project_dir%/templates']
3 | debug: '%kernel.debug%'
4 | strict_variables: '%kernel.debug%'
5 |
6 | services:
7 | _defaults:
8 | public: false
9 | autowire: true
10 | autoconfigure: true
11 |
12 | Twig\Extra\Intl\IntlExtension: ~
13 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/validator.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | validation:
3 | enable_attributes: true
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/webpack_encore.yaml:
--------------------------------------------------------------------------------
1 | webpack_encore:
2 | output_path: '%kernel.project_dir%/public/build/default'
3 | builds:
4 | shop: '%kernel.project_dir%/public/build/shop'
5 | admin: '%kernel.project_dir%/public/build/admin'
6 | product_bundle_shop: '%kernel.project_dir%/public/build/bitbag/productBundle/shop'
7 | product_bundle_admin: '%kernel.project_dir%/public/build/bitbag/productBundle/admin'
8 |
--------------------------------------------------------------------------------
/tests/Application/config/routes.yaml:
--------------------------------------------------------------------------------
1 | bitbag_sylius_product_bundle_plugin:
2 | resource: "@BitBagSyliusProductBundlePlugin/config/routes.yml"
3 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/api_platform.yaml:
--------------------------------------------------------------------------------
1 | api_platform:
2 | resource: .
3 | type: api_platform
4 | prefix: /api
5 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/dev/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | _wdt:
2 | resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml"
3 | prefix: /_wdt
4 |
5 | _profiler:
6 | resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml"
7 | prefix: /_profiler
8 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/liip_imagine.yaml:
--------------------------------------------------------------------------------
1 | _liip_imagine:
2 | resource: "@LiipImagineBundle/Resources/config/routing.yaml"
3 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/sylius_admin.yaml:
--------------------------------------------------------------------------------
1 | sylius_admin:
2 | resource: "@SyliusAdminBundle/Resources/config/routing.yml"
3 | prefix: /admin
4 |
5 | live_component:
6 | resource: "@LiveComponentBundle/config/routes.php"
7 | prefix: /_components
8 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/sylius_api.yaml:
--------------------------------------------------------------------------------
1 | sylius_api:
2 | resource: "@SyliusApiBundle/Resources/config/routing.yml"
3 | prefix: "%sylius.security.api_route%"
4 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/sylius_shop.yaml:
--------------------------------------------------------------------------------
1 | sylius_shop:
2 | resource: "@SyliusShopBundle/Resources/config/routing.yml"
3 | prefix: /{_locale}
4 | requirements:
5 | _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$
6 |
7 | sylius_shop_payum:
8 | resource: "@SyliusPayumBundle/Resources/config/routing/integrations/sylius_shop.yaml"
9 |
10 | sylius_shop_default_locale:
11 | path: /
12 | methods: [GET]
13 | defaults:
14 | _controller: sylius_shop.controller.locale_switch::switchAction
15 |
16 | live_component:
17 | resource: "@LiveComponentBundle/config/routes.php"
18 | prefix: /_components
19 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/test/sylius_test_plugin.yaml:
--------------------------------------------------------------------------------
1 | sylius_test_plugin_main:
2 | path: /test/main
3 | controller: FrameworkBundle:Template:template
4 | defaults:
5 | template: "@SyliusTestPlugin/main.html.twig"
6 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/test_cached/routing.yaml:
--------------------------------------------------------------------------------
1 | sylius_test_plugin_main:
2 | path: /test/main
3 | controller: FrameworkBundle:Template:template
4 | defaults:
5 | template: "@SyliusTestPlugin/main.html.twig"
6 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/test_cached/sylius_test_plugin.yaml:
--------------------------------------------------------------------------------
1 | sylius_test_plugin_main:
2 | path: /test/main
3 | controller: FrameworkBundle:Template:template
4 | defaults:
5 | template: "@SyliusTestPlugin/main.html.twig"
6 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/ux.yaml:
--------------------------------------------------------------------------------
1 | live_component:
2 | resource: "@LiveComponentBundle/config/routes.php"
3 | prefix: /_components
4 |
--------------------------------------------------------------------------------
/tests/Application/config/secrets/dev/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/tests/Application/config/secrets/dev/.gitignore
--------------------------------------------------------------------------------
/tests/Application/config/secrets/prod/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/tests/Application/config/secrets/prod/.gitignore
--------------------------------------------------------------------------------
/tests/Application/config/secrets/test/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/tests/Application/config/secrets/test/.gitignore
--------------------------------------------------------------------------------
/tests/Application/config/secrets/test_cached/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/tests/Application/config/secrets/test_cached/.gitignore
--------------------------------------------------------------------------------
/tests/Application/config/services.yaml:
--------------------------------------------------------------------------------
1 | # Put parameters here that don't need to change on each machine where the app is deployed
2 | # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
3 | parameters:
4 | locale: en_US
5 |
--------------------------------------------------------------------------------
/tests/Application/config/services_test.yaml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: "../../Behat/Resources/services.yml" }
3 | - { resource: "../../../vendor/sylius/sylius/src/Sylius/Behat/Resources/config/services.xml" }
4 |
5 | # workaround needed for strange "test.client.history" problem
6 | # see https://github.com/FriendsOfBehat/SymfonyExtension/issues/88
7 | services:
8 | Symfony\Component\BrowserKit\AbstractBrowser: '@test.client'
9 |
--------------------------------------------------------------------------------
/tests/Application/config/services_test_cached.yaml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: "services_test.yaml" }
3 |
--------------------------------------------------------------------------------
/tests/Application/gulpfile.babel.js:
--------------------------------------------------------------------------------
1 | import chug from 'gulp-chug';
2 | import gulp from 'gulp';
3 | import yargs from 'yargs';
4 |
5 | const { argv } = yargs
6 | .options({
7 | rootPath: {
8 | description: ' path to public assets directory',
9 | type: 'string',
10 | requiresArg: true,
11 | required: false,
12 | },
13 | nodeModulesPath: {
14 | description: ' path to node_modules directory',
15 | type: 'string',
16 | requiresArg: true,
17 | required: false,
18 | },
19 | });
20 |
21 | const config = [
22 | '--rootPath',
23 | argv.rootPath || '../../../../../../../tests/Application/public/assets',
24 | '--nodeModulesPath',
25 | argv.nodeModulesPath || '../../../../../../../tests/Application/node_modules',
26 | ];
27 |
28 | export const buildAdmin = function buildAdmin() {
29 | return gulp.src('../../vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle/gulpfile.babel.js', { read: false })
30 | .pipe(chug({ args: config, tasks: 'build' }));
31 | };
32 | buildAdmin.description = 'Build admin assets.';
33 |
34 | export const watchAdmin = function watchAdmin() {
35 | return gulp.src('../../vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle/gulpfile.babel.js', { read: false })
36 | .pipe(chug({ args: config, tasks: 'watch' }));
37 | };
38 | watchAdmin.description = 'Watch admin asset sources and rebuild on changes.';
39 |
40 | export const buildShop = function buildShop() {
41 | return gulp.src('../../vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/gulpfile.babel.js', { read: false })
42 | .pipe(chug({ args: config, tasks: 'build' }));
43 | };
44 | buildShop.description = 'Build shop assets.';
45 |
46 | export const watchShop = function watchShop() {
47 | return gulp.src('../../vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/gulpfile.babel.js', { read: false })
48 | .pipe(chug({ args: config, tasks: 'watch' }));
49 | };
50 | watchShop.description = 'Watch shop asset sources and rebuild on changes.';
51 |
52 | export const build = gulp.parallel(buildAdmin, buildShop);
53 | build.description = 'Build assets.';
54 |
55 | gulp.task('admin', buildAdmin);
56 | gulp.task('admin-watch', watchAdmin);
57 | gulp.task('shop', buildShop);
58 | gulp.task('shop-watch', watchShop);
59 |
60 | export default build;
61 |
--------------------------------------------------------------------------------
/tests/Application/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "license": "MIT",
3 | "scripts": {
4 | "build": "encore dev",
5 | "build:prod": "encore production",
6 | "watch": "encore dev --watch"
7 | },
8 | "dependencies": {
9 | "@sylius-ui/admin": "file:../../vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle",
10 | "@sylius-ui/shop": "file:../../vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle",
11 | "@symfony/ux-autocomplete": "file:../../vendor/symfony/ux-autocomplete/assets",
12 | "@symfony/ux-live-component": "file:../../vendor/symfony/ux-live-component/assets"
13 | },
14 | "devDependencies": {
15 | "@hotwired/stimulus": "^3.0.0",
16 | "@symfony/stimulus-bridge": "^3.2.0",
17 | "@symfony/webpack-encore": "^5.0.1",
18 | "tom-select": "^2.2.2",
19 | "babel-core": "^6.26.3",
20 | "babel-plugin-external-helpers": "^6.22.0",
21 | "babel-plugin-module-resolver": "^3.1.1",
22 | "babel-plugin-transform-object-rest-spread": "^6.26.0",
23 | "babel-preset-env": "^1.7.0",
24 | "babel-register": "^6.26.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/Application/public/.htaccess:
--------------------------------------------------------------------------------
1 | DirectoryIndex app.php
2 |
3 |
4 | RewriteEngine On
5 |
6 | RewriteCond %{HTTP:Authorization} ^(.*)
7 | RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
8 |
9 | RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
10 | RewriteRule ^(.*) - [E=BASE:%1]
11 |
12 | RewriteCond %{ENV:REDIRECT_STATUS} ^$
13 | RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
14 |
15 | RewriteCond %{REQUEST_FILENAME} -f
16 | RewriteRule .? - [L]
17 |
18 | RewriteRule .? %{ENV:BASE}/index.php [L]
19 |
20 |
21 |
22 |
23 | RedirectMatch 302 ^/$ /index.php/
24 |
25 |
26 |
--------------------------------------------------------------------------------
/tests/Application/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/tests/Application/public/favicon.ico
--------------------------------------------------------------------------------
/tests/Application/public/index.php:
--------------------------------------------------------------------------------
1 | handle($request);
35 | $response->send();
36 | $kernel->terminate($request, $response);
37 |
--------------------------------------------------------------------------------
/tests/Application/public/robots.txt:
--------------------------------------------------------------------------------
1 | # www.robotstxt.org/
2 | # www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449
3 |
4 | User-agent: *
5 |
--------------------------------------------------------------------------------
/tests/Application/src/Entity/OrderItem.php:
--------------------------------------------------------------------------------
1 | init();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/Application/src/Entity/Product.php:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/tests/Application/src/Resources/config/doctrine/Product.orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/tests/Application/templates/bundles/SyliusAdminBundle/Layout/_logo.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/tests/Application/templates/bundles/SyliusAdminBundle/_scripts.html.twig:
--------------------------------------------------------------------------------
1 | {{ encore_entry_script_tags('admin-entry', null, 'admin') }}
2 | {{ encore_entry_script_tags('bitbag-productBundle-admin', null, 'product_bundle_admin') }}
3 |
--------------------------------------------------------------------------------
/tests/Application/templates/bundles/SyliusAdminBundle/_styles.html.twig:
--------------------------------------------------------------------------------
1 | {{ encore_entry_link_tags('admin-entry', null, 'admin') }}
2 | {{ encore_entry_link_tags('bitbag-productBundle-admin', null, 'product_bundle_admin') }}
3 |
--------------------------------------------------------------------------------
/tests/Application/templates/bundles/SyliusAdminBundle/order/show/content/sections/items/body/item.html.twig:
--------------------------------------------------------------------------------
1 | {% from '@SyliusAdmin/shared/helper/product_image.html.twig' import image %}
2 |
3 | {% set product = hookable_metadata.context.product %}
4 | {% set variant = hookable_metadata.context.variant %}
5 |
6 |
7 |
8 |
9 | {{ image(product) }}
10 |
11 |
12 |
17 |
{{ variant.code }}
18 |
{{ variant.name }}
19 |
20 |
21 |
22 | {{ bitbag_render_product_bundle_order_items(product) }}
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/Application/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/tests/Application/templates/bundles/SyliusShopBundle/_scripts.html.twig:
--------------------------------------------------------------------------------
1 | {{ encore_entry_script_tags('shop-entry', null, 'shop') }}
2 | {{ encore_entry_script_tags('bitbag-productBundle-shop', null, 'product_bundle_shop') }}
3 |
--------------------------------------------------------------------------------
/tests/Application/templates/bundles/SyliusShopBundle/_styles.html.twig:
--------------------------------------------------------------------------------
1 | {{ encore_entry_link_tags('shop-entry', null, 'shop') }}
2 | {{ encore_entry_link_tags('bitbag-productBundle-shop', null, 'product_bundle_shop') }}
3 |
--------------------------------------------------------------------------------
/tests/Application/translations/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitBagCommerce/SyliusProductBundlePlugin/2a3819010ccaee087746f8c113fc58d27327628f/tests/Application/translations/.gitignore
--------------------------------------------------------------------------------
/tests/Application/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const Encore = require('@symfony/webpack-encore');
3 |
4 | const [bitbagProductBundleShop, bitbagProductBundleAdmin] = require('../../webpack.config.js');
5 |
6 | const syliusBundles = path.resolve(__dirname, '../../vendor/sylius/sylius/src/Sylius/Bundle/');
7 | const uiBundleScripts = path.resolve(syliusBundles, 'UiBundle/Resources/private/js/');
8 | const uiBundleResources = path.resolve(syliusBundles, 'UiBundle/Resources/private/');
9 |
10 | // Shop config
11 | Encore.setOutputPath('public/build/shop/')
12 | .setPublicPath('/build/shop')
13 | .addEntry('shop-entry', './assets/shop/entry.js')
14 | .enableStimulusBridge('./assets/controllers.json')
15 | .disableSingleRuntimeChunk()
16 | .cleanupOutputBeforeBuild()
17 | .enableSourceMaps(!Encore.isProduction())
18 | .enableVersioning(Encore.isProduction())
19 | .enableSassLoader();
20 |
21 | const shopConfig = Encore.getWebpackConfig();
22 |
23 | shopConfig.resolve.alias['sylius/ui'] = uiBundleScripts;
24 | shopConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources;
25 | shopConfig.resolve.alias['sylius/bundle'] = syliusBundles;
26 | shopConfig.name = 'shop';
27 |
28 | Encore.reset();
29 |
30 | // Admin config
31 | Encore.setOutputPath('public/build/admin/')
32 | .setPublicPath('/build/admin')
33 | .addEntry('admin-entry', './assets/admin/entry.js')
34 | .addEntry('admin-product-entry', './assets/admin/product-entry.js')
35 | .enableStimulusBridge('./assets/controllers.json')
36 | .disableSingleRuntimeChunk()
37 | .cleanupOutputBeforeBuild()
38 | .enableSourceMaps(!Encore.isProduction())
39 | .enableVersioning(Encore.isProduction())
40 | .enableSassLoader();
41 |
42 | const adminConfig = Encore.getWebpackConfig();
43 |
44 | adminConfig.resolve.alias['sylius/ui'] = uiBundleScripts;
45 | adminConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources;
46 | adminConfig.resolve.alias['sylius/bundle'] = syliusBundles;
47 | adminConfig.externals = Object.assign({}, adminConfig.externals, { window: 'window', document: 'document' });
48 | adminConfig.name = 'admin';
49 |
50 | module.exports = [shopConfig, adminConfig, bitbagProductBundleShop, bitbagProductBundleAdmin];
51 |
--------------------------------------------------------------------------------
/tests/Behat/Page/Admin/CreateBundledProductPageInterface.php:
--------------------------------------------------------------------------------
1 | createNew($productBundleItem);
27 |
28 | self::assertInstanceOf(AddProductBundleItemToCartCommand::class, $command);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Unit/Factory/AddProductBundleToCartCommandFactoryTest.php:
--------------------------------------------------------------------------------
1 | createNew(self::ORDER_ID, self::PRODUCT_CODE, self::QUANTITY);
31 |
32 | self::assertInstanceOf(AddProductBundleToCartCommand::class, $command);
33 | self::assertEquals(self::ORDER_ID, $command->getOrderId());
34 | self::assertEquals(self::PRODUCT_CODE, $command->getProductCode());
35 | self::assertEquals(self::QUANTITY, $command->getQuantity());
36 | }
37 |
38 | public function testCreateAddProductBundleToCartCommandObjectFromDto(): void
39 | {
40 | $dto = AddProductBundleToCartDtoMother::createWithOrderIdAndProductCode(self::ORDER_ID, self::PRODUCT_CODE);
41 |
42 | $factory = new AddProductBundleToCartCommandFactory();
43 | $command = $factory->createFromDto($dto);
44 |
45 | self::assertInstanceOf(AddProductBundleToCartCommand::class, $command);
46 | self::assertEquals(self::ORDER_ID, $command->getOrderId());
47 | self::assertEquals(self::PRODUCT_CODE, $command->getProductCode());
48 | self::assertEquals(0, $command->getQuantity());
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/tests/Unit/Factory/OrderItemFactoryTest.php:
--------------------------------------------------------------------------------
1 | createMock(CartItemFactoryInterface::class);
28 | $baseFactory->expects(self::once())
29 | ->method('createNew')
30 | ->willReturn($orderItem)
31 | ;
32 |
33 | $factory = new OrderItemFactory($baseFactory);
34 | $orderItemWithVariant = $factory->createWithVariant($productVariant);
35 |
36 | self::assertSame($productVariant, $orderItemWithVariant->getVariant());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/tests/Unit/MotherObject/AddProductBundleItemToCartCommandMother.php:
--------------------------------------------------------------------------------
1 | setName($name);
29 |
30 | return $channel;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/Unit/MotherObject/OrderItemMother.php:
--------------------------------------------------------------------------------
1 | id = $id;
32 | };
33 | ($setIdClosure->bindTo($order, $order))($id);
34 |
35 | return $order;
36 | }
37 |
38 | public static function createWithChannel(ChannelInterface $channel): OrderInterface
39 | {
40 | $order = self::create();
41 |
42 | $order->setChannel($channel);
43 |
44 | return $order;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/tests/Unit/MotherObject/ProductBundleItemMother.php:
--------------------------------------------------------------------------------
1 | addProductBundleItem($bundleItem);
34 | }
35 |
36 | return $productBundle;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/tests/Unit/MotherObject/ProductVariantMother.php:
--------------------------------------------------------------------------------
1 | setCode($code);
29 |
30 | return $productVariant;
31 | }
32 |
33 | public static function createDisabledWithCode(string $code): ProductVariantInterface
34 | {
35 | $productVariant = self::createWithCode($code);
36 |
37 | $productVariant->disable();
38 |
39 | return $productVariant;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/tests/Unit/TypeExceptionMessage.php:
--------------------------------------------------------------------------------
1 | {
6 | Encore.reset();
7 |
8 | Encore
9 | .setOutputPath(`public/build/bitbag/${pluginName}/${type}/`)
10 | .setPublicPath(`/build/bitbag/${pluginName}/${type}/`)
11 | .addEntry(`bitbag-${pluginName}-${type}`, path.resolve(__dirname, `./assets/${type}/entry.js`))
12 | .disableSingleRuntimeChunk()
13 | .cleanupOutputBeforeBuild()
14 | .enableSourceMaps(!Encore.isProduction())
15 | .enableSassLoader();
16 |
17 | const config = Encore.getWebpackConfig();
18 | config.name = `bitbag-${pluginName}-${type}`;
19 |
20 | return config;
21 | }
22 |
23 | Encore
24 | .setOutputPath(`src/Resources/public/`)
25 | .setPublicPath(`/public/`)
26 | .addEntry(`bitbag-${pluginName}-shop`, path.resolve(__dirname, `./assets/shop/entry.js`))
27 | .addEntry(`bitbag-${pluginName}-admin`, path.resolve(__dirname, `./assets/admin/entry.js`))
28 | .cleanupOutputBeforeBuild()
29 | .disableSingleRuntimeChunk()
30 | .enableSassLoader();
31 |
32 | const distConfig = Encore.getWebpackConfig();
33 | distConfig.name = `bitbag-plugin-dist`;
34 |
35 | Encore.reset();
36 |
37 | const shopConfig = getConfig(pluginName, 'shop')
38 | const adminConfig = getConfig(pluginName, 'admin')
39 |
40 | module.exports = [shopConfig, adminConfig, distConfig];
41 |
--------------------------------------------------------------------------------