From aec9e0e9047e395efa1686bd589fd447059098b2 Mon Sep 17 00:00:00 2001 From: Yousef Chanan Date: Wed, 11 Jul 2018 09:59:51 +0200 Subject: [PATCH 1/5] Update for Sylius ^1.1 --- .gitignore | 14 +- .gitlab-ci.yml | 11 - .travis.yml | 75 ++++- Command/CreateInitialCommand.php | 58 ---- Controller/Account/WishlistController.php | 190 ------------- Controller/Frontend/WishlistController.php | 179 ------------ .../Frontend/WishlistItemController.php | 241 ---------------- .../WebburzaSyliusWishlistExtension.php | 27 -- EventListener/MenuBuilderListener.php | 26 -- EventListener/UserListener.php | 68 ----- Factory/WishlistFactoryInterface.php | 17 -- Form/Type/AdminWishlistType.php | 26 -- Form/Type/UserChoiceType.php | 67 ----- Model/WishlistInterface.php | 92 ------ Provider/WishlistProviderInterface.php | 18 -- README.md | 107 ++++--- Repository/WishlistRepositoryInterface.php | 32 --- .../ProductVariantCartResolverInterface.php | 13 - Resources/config/config.yml | 42 --- Resources/config/grids.yml | 63 ----- Resources/config/parameters.yml | 36 --- Resources/config/routing.yml | 20 -- Resources/config/routingAccount.yml | 33 --- Resources/config/routingFront.yml | 41 --- Resources/config/services.yml | 82 ------ Resources/views/Backend/_form.html.twig | 44 --- Resources/views/Backend/grid/_title.html.twig | 5 - Resources/views/Backend/grid/_user.html.twig | 1 - .../views/Frontend/Shop/_badge.html.twig | 10 - WebburzaSyliusWishlistBundle.php | 9 - behat.yml.dist | 21 ++ bin/.gitkeep | 0 composer.json | 55 +++- easy-coding-standard.neon | 2 + etc/build/.gitkeep | 0 ...ccesing_wishlists_via_sidebar_link.feature | 21 ++ .../admin/viewing_a_single_wishlist.feature | 18 ++ .../wishlist/admin/viewing_wishlists.feature | 23 ++ .../shop/accessing_the_wishlist_page.feature | 35 +++ .../wishlist/shop/adding_to_wishlist.feature | 29 ++ .../navigating_via_the_wishlist_badge.feature | 19 ++ .../shop/viewing_the_wishlist_badge.feature | 31 ++ node_modules | 1 + phpspec.yml.dist | 4 + phpstan.neon | 11 + phpunit.xml.dist | 31 +- src/Controller/Account/WishlistController.php | 223 +++++++++++++++ src/Controller/Shop/WishlistController.php | 243 ++++++++++++++++ .../Shop/WishlistItemController.php | 267 ++++++++++++++++++ .../DependencyInjection}/Configuration.php | 12 +- .../WebburzaSyliusWishlistExtension.php | 30 ++ .../Doctrine}/ORM/WishlistRepository.php | 25 +- .../EventListener/AccountMenuListener.php | 61 ++-- src/EventListener/AdminMenuListener.php | 29 ++ {Factory => src/Factory}/WishlistFactory.php | 16 +- src/Factory/WishlistFactoryInterface.php | 19 ++ {Form => src/Form}/Type/WishlistType.php | 12 +- {Model => src/Model}/Wishlist.php | 101 +++++-- src/Model/WishlistInterface.php | 118 ++++++++ {Model => src/Model}/WishlistItem.php | 23 +- .../Model}/WishlistItemInterface.php | 21 +- src/Provider/LoggedInUserProvider.php | 38 +++ .../LoggedInUserProviderInterface.php | 15 + .../Provider}/WishlistProvider.php | 46 ++- src/Provider/WishlistProviderInterface.php | 20 ++ .../WishlistRepositoryInterface.php | 34 +++ .../ProductVariantFromRequestResolver.php | 49 +++- ...uctVariantFromRequestResolverInterface.php | 18 ++ src/Resolver/WishlistFromRequestResolver.php | 88 ++++++ .../WishlistFromRequestResolverInterface.php | 18 ++ src/Resources/config/app/grids.yml | 63 +++++ src/Resources/config/app/misc.yml | 17 ++ src/Resources/config/app/resources.yml | 12 + src/Resources/config/app/serializer.yml | 6 + src/Resources/config/config.yml | 5 + .../config/doctrine/Wishlist.orm.xml | 27 +- .../config/doctrine/WishlistItem.orm.xml | 18 +- src/Resources/config/routing.yml | 10 + src/Resources/config/routing/account.yml | 29 ++ src/Resources/config/routing/admin.yml | 14 + src/Resources/config/routing/shop.yml | 38 +++ .../config/serializer/Model.Wishlist.yml | 23 ++ src/Resources/config/services.yml | 6 + src/Resources/config/services/controllers.yml | 34 +++ src/Resources/config/services/listeners.yml | 15 + src/Resources/config/services/misc.yml | 15 + src/Resources/config/services/providers.yml | 11 + src/Resources/config/services/resolvers.yml | 17 ++ .../Resources}/translations/messages.en.yml | 26 +- .../Resources/views/Account}/create.html.twig | 12 +- .../Resources/views/Account}/index.html.twig | 21 +- .../Resources/views/Account}/update.html.twig | 12 +- .../views/Admin/Grid/_count.html.twig | 1 + .../views/Admin/Grid/_customer.html.twig | 1 + .../views/Admin/Show/_breadcrumb.html.twig | 10 + .../views/Admin/Show/_details.html.twig | 38 +++ .../views/Admin/Show/_header.html.twig | 15 + .../views/Admin/Show/_items.html.twig | 40 +++ src/Resources/views/Admin/index.html.twig | 1 + src/Resources/views/Admin/show.html.twig | 18 ++ .../views/Shop/Misc}/_addToWishlist.html.twig | 6 +- .../views/Shop/Misc/_badge.html.twig | 10 + .../views/Shop/Wishlist/_cartForm.html.twig | 23 ++ .../views/Shop}/Wishlist/_header.html.twig | 9 +- .../views/Shop}/Wishlist/_info.html.twig | 2 +- .../views/Shop}/Wishlist/_items.html.twig | 14 +- .../views/Shop}/Wishlist/_mainImage.html.twig | 4 +- .../views/Shop}/Wishlist/show.html.twig | 7 +- src/WebburzaSyliusWishlistPlugin.php | 13 + tests/Application/.gitignore | 9 + tests/Application/Gulpfile.js | 24 ++ tests/Application/app/AppKernel.php | 33 +++ .../views/Cart/_widget.html.twig | 34 +++ .../views/Product/Show/_addToCart.html.twig | 28 ++ tests/Application/app/config/config.yml | 67 +++++ tests/Application/app/config/config_dev.yml | 6 + tests/Application/app/config/config_prod.yml | 13 + tests/Application/app/config/config_test.yml | 6 + tests/Application/app/config/routing.yml | 7 + tests/Application/bin/console | 27 ++ tests/Application/package.json | 32 +++ tests/Application/var/.gitkeep | 0 tests/Application/web/app.php | 16 ++ tests/Application/web/app_dev.php | 19 ++ tests/Application/web/app_test.php | 19 ++ tests/Behat/Context/AdminContext.php | 156 ++++++++++ tests/Behat/Context/ShopContext.php | 105 +++++++ tests/Behat/Context/WishlistContext.php | 98 +++++++ tests/Behat/Resources/services.yml | 27 ++ tests/Behat/Resources/suites.yml | 24 ++ 130 files changed, 3096 insertions(+), 1771 deletions(-) delete mode 100644 .gitlab-ci.yml delete mode 100644 Command/CreateInitialCommand.php delete mode 100644 Controller/Account/WishlistController.php delete mode 100644 Controller/Frontend/WishlistController.php delete mode 100644 Controller/Frontend/WishlistItemController.php delete mode 100644 DependencyInjection/WebburzaSyliusWishlistExtension.php delete mode 100644 EventListener/MenuBuilderListener.php delete mode 100644 EventListener/UserListener.php delete mode 100644 Factory/WishlistFactoryInterface.php delete mode 100644 Form/Type/AdminWishlistType.php delete mode 100644 Form/Type/UserChoiceType.php delete mode 100644 Model/WishlistInterface.php delete mode 100644 Provider/WishlistProviderInterface.php delete mode 100644 Repository/WishlistRepositoryInterface.php delete mode 100644 Resolver/ProductVariantCartResolverInterface.php delete mode 100644 Resources/config/config.yml delete mode 100644 Resources/config/grids.yml delete mode 100644 Resources/config/parameters.yml delete mode 100644 Resources/config/routing.yml delete mode 100644 Resources/config/routingAccount.yml delete mode 100644 Resources/config/routingFront.yml delete mode 100644 Resources/config/services.yml delete mode 100644 Resources/views/Backend/_form.html.twig delete mode 100644 Resources/views/Backend/grid/_title.html.twig delete mode 100644 Resources/views/Backend/grid/_user.html.twig delete mode 100644 Resources/views/Frontend/Shop/_badge.html.twig delete mode 100644 WebburzaSyliusWishlistBundle.php create mode 100644 behat.yml.dist create mode 100644 bin/.gitkeep create mode 100644 easy-coding-standard.neon create mode 100644 etc/build/.gitkeep create mode 100644 features/wishlist/admin/accesing_wishlists_via_sidebar_link.feature create mode 100644 features/wishlist/admin/viewing_a_single_wishlist.feature create mode 100644 features/wishlist/admin/viewing_wishlists.feature create mode 100644 features/wishlist/shop/accessing_the_wishlist_page.feature create mode 100644 features/wishlist/shop/adding_to_wishlist.feature create mode 100644 features/wishlist/shop/navigating_via_the_wishlist_badge.feature create mode 100644 features/wishlist/shop/viewing_the_wishlist_badge.feature create mode 120000 node_modules create mode 100644 phpspec.yml.dist create mode 100644 phpstan.neon create mode 100644 src/Controller/Account/WishlistController.php create mode 100644 src/Controller/Shop/WishlistController.php create mode 100644 src/Controller/Shop/WishlistItemController.php rename {DependencyInjection => src/DependencyInjection}/Configuration.php (53%) create mode 100644 src/DependencyInjection/WebburzaSyliusWishlistExtension.php rename {Doctrine => src/Doctrine}/ORM/WishlistRepository.php (62%) rename EventListener/AccountMenuBuilderListener.php => src/EventListener/AccountMenuListener.php (57%) create mode 100644 src/EventListener/AdminMenuListener.php rename {Factory => src/Factory}/WishlistFactory.php (73%) create mode 100644 src/Factory/WishlistFactoryInterface.php rename {Form => src/Form}/Type/WishlistType.php (74%) rename {Model => src/Model}/Wishlist.php (50%) create mode 100644 src/Model/WishlistInterface.php rename {Model => src/Model}/WishlistItem.php (65%) rename {Model => src/Model}/WishlistItemInterface.php (53%) create mode 100644 src/Provider/LoggedInUserProvider.php create mode 100644 src/Provider/LoggedInUserProviderInterface.php rename {Provider => src/Provider}/WishlistProvider.php (50%) create mode 100644 src/Provider/WishlistProviderInterface.php create mode 100644 src/Repository/WishlistRepositoryInterface.php rename Resolver/ProductVariantCartResolver.php => src/Resolver/ProductVariantFromRequestResolver.php (63%) create mode 100644 src/Resolver/ProductVariantFromRequestResolverInterface.php create mode 100644 src/Resolver/WishlistFromRequestResolver.php create mode 100644 src/Resolver/WishlistFromRequestResolverInterface.php create mode 100644 src/Resources/config/app/grids.yml create mode 100644 src/Resources/config/app/misc.yml create mode 100644 src/Resources/config/app/resources.yml create mode 100644 src/Resources/config/app/serializer.yml create mode 100644 src/Resources/config/config.yml rename {Resources => src/Resources}/config/doctrine/Wishlist.orm.xml (71%) rename {Resources => src/Resources}/config/doctrine/WishlistItem.orm.xml (88%) create mode 100644 src/Resources/config/routing.yml create mode 100644 src/Resources/config/routing/account.yml create mode 100644 src/Resources/config/routing/admin.yml create mode 100644 src/Resources/config/routing/shop.yml create mode 100644 src/Resources/config/serializer/Model.Wishlist.yml create mode 100644 src/Resources/config/services.yml create mode 100644 src/Resources/config/services/controllers.yml create mode 100644 src/Resources/config/services/listeners.yml create mode 100644 src/Resources/config/services/misc.yml create mode 100644 src/Resources/config/services/providers.yml create mode 100644 src/Resources/config/services/resolvers.yml rename {Resources => src/Resources}/translations/messages.en.yml (70%) rename {Resources/views/Frontend/Account/Wishlist => src/Resources/views/Account}/create.html.twig (58%) rename {Resources/views/Frontend/Account/Wishlist => src/Resources/views/Account}/index.html.twig (69%) rename {Resources/views/Frontend/Account/Wishlist => src/Resources/views/Account}/update.html.twig (56%) create mode 100644 src/Resources/views/Admin/Grid/_count.html.twig create mode 100644 src/Resources/views/Admin/Grid/_customer.html.twig create mode 100644 src/Resources/views/Admin/Show/_breadcrumb.html.twig create mode 100644 src/Resources/views/Admin/Show/_details.html.twig create mode 100644 src/Resources/views/Admin/Show/_header.html.twig create mode 100644 src/Resources/views/Admin/Show/_items.html.twig create mode 100644 src/Resources/views/Admin/index.html.twig create mode 100644 src/Resources/views/Admin/show.html.twig rename {Resources/views/Frontend/Shop => src/Resources/views/Shop/Misc}/_addToWishlist.html.twig (75%) create mode 100644 src/Resources/views/Shop/Misc/_badge.html.twig create mode 100644 src/Resources/views/Shop/Wishlist/_cartForm.html.twig rename {Resources/views/Frontend => src/Resources/views/Shop}/Wishlist/_header.html.twig (64%) rename {Resources/views/Frontend => src/Resources/views/Shop}/Wishlist/_info.html.twig (83%) rename {Resources/views/Frontend => src/Resources/views/Shop}/Wishlist/_items.html.twig (66%) rename {Resources/views/Frontend => src/Resources/views/Shop}/Wishlist/_mainImage.html.twig (59%) rename {Resources/views/Frontend => src/Resources/views/Shop}/Wishlist/show.html.twig (58%) create mode 100644 src/WebburzaSyliusWishlistPlugin.php create mode 100644 tests/Application/.gitignore create mode 100644 tests/Application/Gulpfile.js create mode 100644 tests/Application/app/AppKernel.php create mode 100644 tests/Application/app/Resources/SyliusShopBundle/views/Cart/_widget.html.twig create mode 100644 tests/Application/app/Resources/SyliusShopBundle/views/Product/Show/_addToCart.html.twig create mode 100644 tests/Application/app/config/config.yml create mode 100644 tests/Application/app/config/config_dev.yml create mode 100644 tests/Application/app/config/config_prod.yml create mode 100644 tests/Application/app/config/config_test.yml create mode 100644 tests/Application/app/config/routing.yml create mode 100755 tests/Application/bin/console create mode 100644 tests/Application/package.json create mode 100644 tests/Application/var/.gitkeep create mode 100644 tests/Application/web/app.php create mode 100644 tests/Application/web/app_dev.php create mode 100644 tests/Application/web/app_test.php create mode 100644 tests/Behat/Context/AdminContext.php create mode 100644 tests/Behat/Context/ShopContext.php create mode 100644 tests/Behat/Context/WishlistContext.php create mode 100644 tests/Behat/Resources/services.yml create mode 100644 tests/Behat/Resources/suites.yml diff --git a/.gitignore b/.gitignore index f7f8ac3..7ea2c86 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,14 @@ -/.idea/ +/bin/* +!/bin/.gitkeep + /vendor/ +/node_modules/ +/composer.lock + +/etc/build/* +!/etc/build/.gitkeep + +/tests/Application/yarn.lock + +/.idea/ +/tests/Application/.web-server-pid diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 189333c..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,11 +0,0 @@ -before_script: - - composer install --no-interaction --prefer-dist --no-scripts - -build: - script: - - composer validate - - vendor/bin/phpunit - cache: - paths: - - bin - - vendor diff --git a/.travis.yml b/.travis.yml index dcd85a7..7576d82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,24 +1,75 @@ language: php +dist: trusty + +sudo: false + +php: + - 7.1 + - 7.2 + cache: + yarn: true directories: - - bin - - vendor + - ~/.composer/cache/files + - $SYLIUS_CACHE_DIR -php: - - 7.0 - - 5.6 - - 5.5 +env: + global: + - SYLIUS_CACHE_DIR=$HOME/.sylius-cache + - SYLIUS_BUILD_DIR=etc/build before_install: - phpenv config-rm xdebug.ini - - composer self-update - - if [[ -z "$GITHUB_OAUTH_TOKEN" ]]; then export GITHUB_OAUTH_TOKEN="66736022ed66ebbb2be87027ed45a24554cc8344"; fi - - composer config -g github-oauth.github.com "$GITHUB_OAUTH_TOKEN" >/dev/null 2>&1 + - echo "memory_limit=4096M" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini + - mkdir -p "${SYLIUS_CACHE_DIR}" install: - - composer install --no-interaction --prefer-dist --no-scripts + - composer install --no-interaction --prefer-dist + - (cd tests/Application && yarn install) + +before_script: + - (cd tests/Application && bin/console doctrine:database:create --env=test -vvv) + - (cd tests/Application && bin/console doctrine:schema:create --env=test -vvv) + - (cd tests/Application && bin/console assets:install web --env=test -vvv) + - (cd tests/Application && yarn run gulp) + + # Configure display + - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1680x1050x16 + - export DISPLAY=:99 + + # Download and configure ChromeDriver + - | + if [ ! -f $SYLIUS_CACHE_DIR/chromedriver ] || [ "$($SYLIUS_CACHE_DIR/chromedriver --version | grep -c 2.34)" = "0" ]; then + curl http://chromedriver.storage.googleapis.com/2.34/chromedriver_linux64.zip > chromedriver.zip + unzip chromedriver.zip + chmod +x chromedriver + mv chromedriver $SYLIUS_CACHE_DIR + fi + + # Run ChromeDriver + - $SYLIUS_CACHE_DIR/chromedriver > /dev/null 2>&1 & + + # Download and configure Selenium + - | + if [ ! -f $SYLIUS_CACHE_DIR/selenium.jar ] || [ "$(java -jar $SYLIUS_CACHE_DIR/selenium.jar --version | grep -c 3.4.0)" = "0" ]; then + curl http://selenium-release.storage.googleapis.com/3.4/selenium-server-standalone-3.4.0.jar > selenium.jar + mv selenium.jar $SYLIUS_CACHE_DIR + fi + + # Run Selenium + - java -Dwebdriver.chrome.driver=$SYLIUS_CACHE_DIR/chromedriver -jar $SYLIUS_CACHE_DIR/selenium.jar > /dev/null 2>&1 & + + # Run webserver + - (cd tests/Application && bin/console server:run 127.0.0.1:8080 -d web --env=test --quiet > /dev/null 2>&1 &) script: - - composer validate - - vendor/bin/phpunit + - composer validate --strict + - bin/phpstan.phar analyse -c phpstan.neon -l max src/ + + - bin/phpunit + - bin/phpspec run + - bin/behat --strict -vvv --no-interaction || bin/behat --strict -vvv --no-interaction --rerun + +after_failure: + - vendor/lakion/mink-debug-extension/travis/tools/upload-textfiles "${SYLIUS_BUILD_DIR}/*.log" diff --git a/Command/CreateInitialCommand.php b/Command/CreateInitialCommand.php deleted file mode 100644 index 5e159d0..0000000 --- a/Command/CreateInitialCommand.php +++ /dev/null @@ -1,58 +0,0 @@ -setName('webburza:sylius-wishlist-bundle:create-initial') - ->setDescription("Create initial wishlists for existing users.") - ; - } - - /** - * @param InputInterface $input - * @param OutputInterface $output - * - * @return void - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $output->writeln('Creating wishlists for existing users...'); - - /** @var UserRepositoryInterface $userRepository */ - $userRepository = $this->getContainer()->get('sylius.repository.shop_user'); - - /** @var WishlistRepositoryInterface $wishlistRepository */ - $wishlistRepository = $this->getContainer()->get('webburza_wishlist.repository.wishlist'); - - /** @var WishlistFactoryInterface $wishlistFactory */ - $wishlistFactory = $this->getContainer()->get('webburza_wishlist.factory.wishlist'); - - // Get all users - $users = $userRepository->findAll(); - - // Keep track of created wishlists - $createdCount = 0; - - // For each user, check if a wishlist exists and create it if not - foreach ($users as $user) { - if ($wishlistRepository->getCountForUser($user) == 0) { - $wishlist = $wishlistFactory->createDefault($user); - $wishlistRepository->add($wishlist); - $createdCount++; - } - } - - $output->writeln('Created '. $createdCount .' wishlists.'); - } -} diff --git a/Controller/Account/WishlistController.php b/Controller/Account/WishlistController.php deleted file mode 100644 index c4a089e..0000000 --- a/Controller/Account/WishlistController.php +++ /dev/null @@ -1,190 +0,0 @@ -setContainer($container); - } - - /** - * @param Request $request - * - * @return Response - */ - public function indexAction(Request $request) - { - // Throw 404 if not in multiple wishlist mode - if (!$this->getParameter('webburza_sylius_wishlist.multiple')) { - return $this->redirectToRoute('sylius_shop_account_dashboard'); - } - - // Get all wishlists for the current user - $wishlists = $this->get('webburza_wishlist.repository.wishlist')->findBy([ - 'user' => $this->getUser() - ], [ - 'createdAt' => 'asc' - ]); - - $view = View::create([ - 'wishlists' => $wishlists - ]); - - $view->setTemplate('WebburzaSyliusWishlistBundle:Frontend/Account/Wishlist:index.html.twig'); - - return $this->handleView($view); - } - - /** - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - // Throw 404 if not in multiple wishlist mode - if (!$this->getParameter('webburza_sylius_wishlist.multiple')) { - throw new NotFoundHttpException(); - } - - // Get wishlist form and handle request - $form = $this->get('form.factory')->create(WishlistType::class); - $form->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - /** @var WishlistInterface $wishlist */ - $wishlist = $form->getData(); - - // Set wishlist user - $wishlist->setUser($this->getUser()); - - // Persist changes - $this->get('webburza_wishlist.repository.wishlist')->add($wishlist); - - // If this was an AJAX request, return appropriate response - if ($request->getRequestFormat() != 'html') { - return new JsonResponse(null, Response::HTTP_CREATED); - } - - // Set success message - $this->addFlash( - 'success', - $this->get('translator')->trans('webburza_wishlist.flash.updated') - ); - - return $this->redirectToRoute('webburza_account_wishlist_edit', [ - 'id' => $wishlist->getId() - ]); - } - - $view = View::create([ - 'form' => $form->createView() - ]); - - $view->setTemplate('WebburzaSyliusWishlistBundle:Frontend/Account/Wishlist:create.html.twig'); - - return $this->handleView($view); - } - - /** - * @param Request $request - * - * @return Response - */ - public function updateAction(Request $request) - { - // Get the wishlist - $wishlist = $this->get('webburza_wishlist.repository.wishlist')->findOneBy([ - 'id' => $request->get('id'), - 'user' => $this->getUser() - ]); - - if (!$wishlist) { - throw new NotFoundHttpException(); - } - - // Get wishlist form - $form = $this->get('form.factory')->create(WishlistType::class, $wishlist); - - if (in_array($request->getMethod(), ['PUT', 'POST'])) { - if ($form->handleRequest($request)->isValid()) { - - // Persist changes - $this->get('webburza_wishlist.repository.wishlist')->add($form->getData()); - - // If this was an AJAX request, return appropriate response - if ($request->getRequestFormat() != 'html') { - return new JsonResponse(null, Response::HTTP_OK); - } - - // Set success message - $this->addFlash( - 'success', - $this->get('translator')->trans('webburza_wishlist.flash.updated') - ); - - return $this->redirectToRoute('webburza_account_wishlist_edit', [ - 'id' => $wishlist->getId() - ]); - } - } - - $view = View::create([ - 'form' => $form->createView(), - 'wishlist' => $wishlist - ]); - - $view->setTemplate('WebburzaSyliusWishlistBundle:Frontend/Account/Wishlist:update.html.twig'); - - return $this->handleView($view); - } - - /** - * @param Request $request - * - * @return Response - */ - public function deleteAction(Request $request) - { - $wishlist = $this->get('webburza_wishlist.repository.wishlist')->findOneBy([ - 'id' => $request->get('id'), - 'user' => $this->getUser() - ]); - - // Throw exception if not found - if (!$wishlist) { - throw new NotFoundHttpException(); - } - - // Remove the wishlist - $this->get('webburza_wishlist.repository.wishlist')->remove($wishlist); - - // If this was an AJAX request, return appropriate response - if ($request->getRequestFormat() != 'html') { - return new JsonResponse(null, Response::HTTP_NO_CONTENT); - } - - // Set success message - $this->addFlash( - 'success', - $this->get('translator')->trans('webburza_wishlist.ui.deleted') - ); - - return $this->redirectToRoute('webburza_account_wishlist_index'); - } -} diff --git a/Controller/Frontend/WishlistController.php b/Controller/Frontend/WishlistController.php deleted file mode 100644 index 5103180..0000000 --- a/Controller/Frontend/WishlistController.php +++ /dev/null @@ -1,179 +0,0 @@ -setContainer($container); - } - - /** - * Get a publicly visible wishlist by slug. - * - * @param Request $request - * - * @return Response - */ - public function showAction(Request $request) - { - /** @var WishlistInterface $wishlist */ - $wishlist = $this->get('webburza_wishlist.repository.wishlist')->findOneBy([ - 'slug' => $request->get('slug') - ]); - - // Check if wishlist exists, and it can be accessed - if (!($wishlist && $this->userCanAccessWishlist($this->getUser(), $wishlist))) { - throw new NotFoundHttpException(); - } - - $view = View::create($wishlist); - - if ($request->getRequestFormat() == 'html') { - $view->setTemplate('WebburzaSyliusWishlistBundle:Frontend/Wishlist:show.html.twig'); - - $view->setData([ - 'wishlist' => $wishlist - ]); - } - - return $this->handleView($view); - } - - /** - * Get the first publicly visible wishlist for the current user. - * - * @param Request $request - * - * @return Response - */ - public function firstAction(Request $request) - { - if (!$this->getUser()) { - throw new NotFoundHttpException(); - } - - // Get the first wishlist for the user - $wishlist = - $this->get('webburza_wishlist.repository.wishlist')->getFirstForUser($this->getUser()); - - // Create a wishlist if none exist - if (!$wishlist) { - $wishlist = $this->get('webburza_wishlist.factory.wishlist')->createDefault($this->getUser()); - $this->get('webburza_wishlist.repository.wishlist')->add($wishlist); - } - - // If the bundle is configured to work with multiple wishlists - // Redirect to the current wishlist to update URI - if ($this->getParameter('webburza_sylius_wishlist.multiple')) { - return $this->redirectToRoute('webburza_frontend_wishlist_show', [ - 'slug' => $wishlist->getSlug() - ]); - } - - // If this was an AJAX request, return appropriate response - if ($request->getRequestFormat() != 'html') { - return new JsonResponse(['wishlist' => $wishlist], 200); - } - - // Create the view for the wishlist - $view = View::create([ - 'wishlist' => $wishlist - ]); - - // Set view template - $view->setTemplate('WebburzaSyliusWishlistBundle:Frontend/Wishlist:show.html.twig'); - - // Handle the view - return $this->handleView($view); - } - - /** - * @param Request $request - * - * @return Response - */ - public function clearAction(Request $request) - { - /** @var WishlistInterface $wishlist */ - $wishlist = $this->get('webburza_wishlist.repository.wishlist')->findOneBy([ - 'id' => $request->get('id'), - 'user' => $this->getUser() - ]); - - // Check if wishlist found - if (!$wishlist) { - $this->createNotFoundException(); - } - - // Remove each wishlist item - foreach ($wishlist->getItems() as $wishlistItem) { - $this->get('webburza_wishlist.repository.wishlist_item')->remove($wishlistItem); - } - - // If this was an AJAX request, return appropriate response - if ($request->getRequestFormat() != 'html') { - return new JsonResponse(null, 200); - } - - // Set success message - $this->addFlash( - 'success', - $this->get('translator')->trans('webburza_wishlist.flash.cleared') - ); - - return $this->redirectToWishlist($wishlist); - } - - /** - * Check if a wishlist is publicly available, or the - * user has special privileges to access it. - * - * @param $user - * @param $wishlist - * - * @return bool - */ - protected function userCanAccessWishlist( - UserInterface $user = null, - WishlistInterface $wishlist - ) { - return $wishlist->isPublic() || ($user && $user->getId() == $wishlist->getUser()->getId()); - } - - /** - * @param WishlistInterface $wishlist - * - * @return RedirectResponse - */ - protected function redirectToWishlist(WishlistInterface $wishlist) - { - // If the bundle is configured to work with a single wishlist, - // Redirect to the the general route (without a slug) - if (false == $this->getParameter('webburza_sylius_wishlist.multiple')) { - return $this->redirectToRoute('webburza_frontend_wishlist_first'); - } - - // Redirect back to the wishlist - return $this->redirectToRoute('webburza_frontend_wishlist_show', [ - 'slug' => $wishlist->getSlug() - ]); - } - -} diff --git a/Controller/Frontend/WishlistItemController.php b/Controller/Frontend/WishlistItemController.php deleted file mode 100644 index e6cf789..0000000 --- a/Controller/Frontend/WishlistItemController.php +++ /dev/null @@ -1,241 +0,0 @@ -setContainer($container); - } - - /** - * This action renders a partial template to be submitted to - * the default add-to-cart endpoint, as used on product page. - * - * @param Request $request - * - * @return Response - */ - public function addToCartAction(Request $request) - { - $cart = $this->get('sylius.context.cart')->getCart(); - - $variant = - $this->get('sylius.repository.product_variant')->find($request->get('variantId')); - - /** @var OrderItemInterface $orderItem */ - $orderItem = $this->get('sylius.factory.order_item') - ->createForProduct($variant->getProduct()); - - $addToCartCommand = - $this->get('sylius.factory.add_to_cart_command') - ->createWithCartAndCartItem($cart, $orderItem); - - $form = $this->get('form.factory')->create(AddToCartType::class, $addToCartCommand, [ - 'product' => $variant->getProduct() - ]); - - $form->get('cartItem')->get('quantity')->setData(1); - - if ($form->get('cartItem')->has('variant')) { - $form->get('cartItem')->get('variant')->setData($variant); - } - - $view = View::create([ - 'product' => $variant->getProduct(), - 'form' => $form->createView() - ]); - - $view->setTemplate('@WebburzaSyliusWishlist/Frontend/Wishlist/_cartForm.html.twig'); - - return $this->handleView($view); - } - - /** - * @param Request $request - * - * @return Response - */ - public function removeAction(Request $request) - { - /** @var WishlistItemInterface $wishlistItem */ - $wishlistItem = - $this->get('webburza_wishlist.repository.wishlist_item')->find($request->get('id')); - - // Check if this item belongs to the current customer trying to remove it - if ($wishlistItem->getWishlist()->getUser() != $this->getUser()) { - throw $this->createAccessDeniedException(); - } - - // Remove the item from the repository - $this->get('webburza_wishlist.repository.wishlist_item')->remove($wishlistItem); - - // If this was an AJAX request, return appropriate response - if ($request->getRequestFormat() != 'html') { - return new JsonResponse(null, Response::HTTP_NO_CONTENT); - } - - // Set success message - $this->addFlash( - 'success', - $this->get('translator')->trans('webburza_wishlist.flash.item_removed') - ); - - return $this->redirectToWishlist($wishlistItem->getWishlist()); - } - - /** - * Add a wishlist item to a wishlist (create it). - * - * @param Request $request - * - * @return Response - */ - public function addAction(Request $request) - { - // Get the current user - if (!($user = $this->getUser())) { - throw new BadRequestHttpException(); - } - - // Get (or create) the wishlist to which the item should be added - $wishlist = $this->resolveWishlist($request, $user); - - // Get the product variant to be added to wishlist - $productVariant = $this->resolveProductVariant($request); - - // Prevent duplicates - if ($wishlist->contains($productVariant)) { - // Set flash message - $this->addFlash( - 'info', - $this->get('translator')->trans('webburza_wishlist.flash.already_on_wishlist') - ); - - // Redirect back to the wishlist - return $this->redirectToWishlist($wishlist); - } - - /** @var WishlistItemInterface $wishlistItem */ - $wishlistItem = $this->get('webburza_wishlist.factory.wishlist_item')->createNew(); - $wishlistItem->setProductVariant($productVariant); - - $wishlist->addItem($wishlistItem); - - // Persist the wishlist item - $this->get('webburza_wishlist.repository.wishlist_item')->add($wishlistItem); - - if ($request->getRequestFormat() != 'html') { - return new JsonResponse(null, Response::HTTP_CREATED); - } - - // Set success message - $this->addFlash( - 'success', - $this->get('translator')->trans('webburza_wishlist.flash.item_added') - ); - - return $this->redirectToWishlist($wishlist); - } - - /** - * Get the requested wishlist, if any, - * or the first one for the customer. - * - * @param Request $request - * @param UserInterface $user - * - * @return null|WishlistInterface - */ - protected function resolveWishlist(Request $request, UserInterface $user) - { - // Check if a specific wishlist was requested - if ($wishlistId = $request->get('wishlistId')) { - $wishlist = $this->get('webburza_wishlist.repository.wishlist') - ->findOneBy([ - 'id' => $wishlistId, - 'user' => $user - ]); - - if (!$wishlist) { - throw new BadRequestHttpException(); - } - - return $wishlist; - } - - // If not, get the first wishlist for the customer - $wishlist = $this->get('webburza_wishlist.repository.wishlist')->getFirstForUser($user); - - // If no wishlist found, create a new one - if (!$wishlist) { - $wishlist = $this->get('webburza_wishlist.factory.wishlist')->createDefault($user); - $this->get('webburza_wishlist.repository.wishlist')->add($wishlist); - } - - return $wishlist; - } - - /** - * @param Request $request - * - * @return mixed - * @throws BadRequestHttpException - */ - protected function resolveProductVariant(Request $request) - { - if ($productVariantId = $request->get('productVariantId')) { - $productVariant = $this->get('sylius.repository.product_variant') - ->find($productVariantId); - } else { - $productVariant = - $this->container->get('webburza_wishlist.resolver.product_variant_cart') - ->resolve($request); - } - - if (!$productVariant) { - throw new BadRequestHttpException(); - } - - return $productVariant; - } - - /** - * @param WishlistInterface $wishlist - * - * @return RedirectResponse - */ - protected function redirectToWishlist(WishlistInterface $wishlist) - { - // If the bundle is configured to work with a single wishlist, - // Redirect to the the general route (without a slug) - if (false == $this->getParameter('webburza_sylius_wishlist.multiple')) { - return $this->redirectToRoute('webburza_frontend_wishlist_first'); - } - - // Redirect back to the wishlist - return $this->redirectToRoute('webburza_frontend_wishlist_show', [ - 'slug' => $wishlist->getSlug() - ]); - } -} diff --git a/DependencyInjection/WebburzaSyliusWishlistExtension.php b/DependencyInjection/WebburzaSyliusWishlistExtension.php deleted file mode 100644 index 0d91084..0000000 --- a/DependencyInjection/WebburzaSyliusWishlistExtension.php +++ /dev/null @@ -1,27 +0,0 @@ -processConfiguration($configuration, $configs); - - // Set config parameters - $container->setParameter('webburza_sylius_wishlist.multiple', $config['multiple']); - $container->setParameter('webburza_sylius_wishlist.default_public', $config['default_public']); - - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - $loader->load('services.yml'); - } -} diff --git a/EventListener/MenuBuilderListener.php b/EventListener/MenuBuilderListener.php deleted file mode 100644 index d3702d3..0000000 --- a/EventListener/MenuBuilderListener.php +++ /dev/null @@ -1,26 +0,0 @@ -getMenu(); - - // Get or create the parent group - if (null == ($contentMenu = $menu->getChild('customers'))) { - $contentMenu = $menu->addChild('customers')->setLabel('webburza_wishlist.ui.customer'); - } - - // Add 'Wishlists' menu item - $contentMenu->addChild('webburza_wishlists', ['route' => 'webburza_wishlist_admin_wishlist_index']) - ->setLabel('webburza_wishlist.ui.wishlists') - ->setLabelAttribute('icon', 'star'); - } -} diff --git a/EventListener/UserListener.php b/EventListener/UserListener.php deleted file mode 100644 index 9df7ac1..0000000 --- a/EventListener/UserListener.php +++ /dev/null @@ -1,68 +0,0 @@ -container = $container; - $this->wishlistQueue = new ArrayCollection(); - } - - /** - * @param OnFlushEventArgs $event - */ - public function onFlush(OnFlushEventArgs $event) - { - $entities = $event->getEntityManager()->getUnitOfWork()->getScheduledEntityInsertions(); - - foreach ($entities as $entity) { - if ($entity instanceof ShopUserInterface) { - $this->wishlistQueue->add( - $this->container->get('webburza_wishlist.factory.wishlist')->createDefault($entity) - ); - } - } - } - - /** - * @param PostFlushEventArgs $event - */ - public function postFlush(PostFlushEventArgs $event) - { - if ($this->wishlistQueue->count()) { - foreach ($this->wishlistQueue as $wishlist) { - $this->container->get('doctrine.orm.entity_manager')->persist($wishlist); - } - $this->wishlistQueue->clear(); - - $event->getEntityManager()->flush(); - } - } -} diff --git a/Factory/WishlistFactoryInterface.php b/Factory/WishlistFactoryInterface.php deleted file mode 100644 index e59d3ae..0000000 --- a/Factory/WishlistFactoryInterface.php +++ /dev/null @@ -1,17 +0,0 @@ -add('user', UserChoiceType::class, [ - 'label' => 'webburza_wishlist.wishlist.label.user', - 'required' => true, - 'constraints' => [ - new NotBlank() - ] - ]); - } -} diff --git a/Form/Type/UserChoiceType.php b/Form/Type/UserChoiceType.php deleted file mode 100644 index 69ba935..0000000 --- a/Form/Type/UserChoiceType.php +++ /dev/null @@ -1,67 +0,0 @@ -repository = $repository; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - if ($options['multiple']) { - $builder->addModelTransformer(new CollectionToArrayTransformer()); - } - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'choices' => function (Options $options) { - return $this->repository->findAll(); - }, - 'choice_value' => 'id', - 'choice_label' => 'email' - ]); - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return ChoiceType::class; - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'webburza_wishlist_user_choice'; - } -} diff --git a/Model/WishlistInterface.php b/Model/WishlistInterface.php deleted file mode 100644 index 4e62921..0000000 --- a/Model/WishlistInterface.php +++ /dev/null @@ -1,92 +0,0 @@ - - {{ form_errors(form) }} - -
-
- {{ form_rest(form) }} -
- - {% if form.vars.data.items | length %} -
- - - - - - - - {% for item in form.vars.data.items %} - - - - {% endfor %} - -
{{ 'webburza_wishlist.ui.wishlist_items' | trans }}
- - {{ item.productVariant.product.name }} - - - {% if item.productVariant.optionValues %} -
- - {{ item.productVariant.optionValues | join(', ') }} - - {% endif %} -
-
- {% endif %} -
- diff --git a/Resources/views/Backend/grid/_title.html.twig b/Resources/views/Backend/grid/_title.html.twig deleted file mode 100644 index 03d8f29..0000000 --- a/Resources/views/Backend/grid/_title.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -{% if data.public %} - {{ data.title }} -{% else %} - {{ data.title }} -{% endif %} diff --git a/Resources/views/Backend/grid/_user.html.twig b/Resources/views/Backend/grid/_user.html.twig deleted file mode 100644 index 15d4ac4..0000000 --- a/Resources/views/Backend/grid/_user.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ data.user.customer.email }} diff --git a/Resources/views/Frontend/Shop/_badge.html.twig b/Resources/views/Frontend/Shop/_badge.html.twig deleted file mode 100644 index 8c9f61c..0000000 --- a/Resources/views/Frontend/Shop/_badge.html.twig +++ /dev/null @@ -1,10 +0,0 @@ -{% if is_granted('ROLE_USER') %} - - - {{ wishlist_provider.itemCount }} - -{% endif %} diff --git a/WebburzaSyliusWishlistBundle.php b/WebburzaSyliusWishlistBundle.php deleted file mode 100644 index be4f75b..0000000 --- a/WebburzaSyliusWishlistBundle.php +++ /dev/null @@ -1,9 +0,0 @@ - + - + bootstrap="vendor/autoload.php"> - - ./Tests + + tests - - - ./ - - ./Tests - ./vendor - - - + + + + diff --git a/src/Controller/Account/WishlistController.php b/src/Controller/Account/WishlistController.php new file mode 100644 index 0000000..bd77bb5 --- /dev/null +++ b/src/Controller/Account/WishlistController.php @@ -0,0 +1,223 @@ +wishlistRepository = $wishlistRepository; + $this->loggedInUserProvider = $loggedInUserProvider; + $this->translator = $translator; + $this->formFactory = $formFactory; + $this->multipleWishlistMode = $multipleWishlistMode; + } + + /** + * @param Request $request + * + * @return Response + */ + public function indexAction(Request $request) : Response + { + // Throw 404 if not in multiple wishlist mode + if (!$this->multipleWishlistMode) { + return $this->redirectToRoute('sylius_shop_account_dashboard'); + } + + // Get all wishlists for the current user + $wishlists = $this->wishlistRepository->findBy([ + 'user' => $this->loggedInUserProvider->getUser() + ], [ + 'createdAt' => 'asc' + ]); + + // Render view + return $this->render('@WebburzaSyliusWishlistPlugin/Resources/views/Account/index.html.twig', [ + 'wishlists' => $wishlists + ]); + } + + /** + * @param Request $request + * + * @return Response + */ + public function createAction(Request $request) : Response + { + // Throw 404 if not in multiple wishlist mode + if (!$this->multipleWishlistMode) { + throw $this->createNotFoundException(); + } + + // Get wishlist form and handle request + $form = $this->formFactory->create(WishlistType::class); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + /** @var WishlistInterface $wishlist */ + $wishlist = $form->getData(); + + // Set wishlist user + $wishlist->setUser($this->loggedInUserProvider->getUser()); + + // Persist changes + $this->wishlistRepository->add($wishlist); + + // If this was an AJAX request, return appropriate response + if ($request->getRequestFormat() != 'html') { + return new JsonResponse(null, Response::HTTP_CREATED); + } + + // Set success message + $this->addFlash( + 'success', $this->translator->trans('webburza_sylius_wishlist.flash.updated') + ); + + return $this->redirectToRoute('webburza_sylius_wishlist_account_wishlist_edit', [ + 'id' => $wishlist->getId() + ]); + } + + return $this->render('@WebburzaSyliusWishlistPlugin/Resources/views/Account/create.html.twig', [ + 'form' => $form->createView() + ]); + } + + /** + * @param Request $request + * + * @return Response + */ + public function updateAction(Request $request) : Response + { + // Get the wishlist + $wishlist = $this->wishlistRepository->findOneBy([ + 'id' => $request->get('id'), + 'user' => $this->loggedInUserProvider->getUser() + ]); + + if (!$wishlist) { + throw $this->createNotFoundException(); + } + + // Get wishlist form + $form = $this->formFactory->create(WishlistType::class, $wishlist); + + if (in_array($request->getMethod(), ['PUT', 'POST'])) { + if ($form->handleRequest($request)->isValid()) { + /** @var WishlistInterface $wishlist */ + $wishlist = $form->getData(); + + // Set wishlist user + $wishlist->setUser($this->loggedInUserProvider->getUser()); + + // Persist changes + $this->wishlistRepository->add($wishlist); + + // If this was an AJAX request, return appropriate response + if ($request->getRequestFormat() != 'html') { + return new JsonResponse(null, Response::HTTP_OK); + } + + // Set success message + $this->addFlash( + 'success', $this->translator->trans('webburza_sylius_wishlist.flash.updated') + ); + + return $this->redirectToRoute('webburza_sylius_wishlist_account_wishlist_edit', [ + 'id' => $wishlist->getId() + ]); + } + } + + return $this->render('@WebburzaSyliusWishlistPlugin/Resources/views/Account/update.html.twig', [ + 'form' => $form->createView(), + 'wishlist' => $wishlist + ]); + } + + /** + * @param Request $request + * + * @return Response + */ + public function deleteAction(Request $request) : Response + { + /** @var WishlistInterface $wishlist */ + $wishlist = $this->wishlistRepository->findOneBy([ + 'id' => $request->get('id'), + 'user' => $this->loggedInUserProvider->getUser() + ]); + + // Throw exception if not found + if (!$wishlist) { + throw $this->createNotFoundException(); + } + + // Remove the wishlist + $this->wishlistRepository->remove($wishlist); + + // If this was an AJAX request, return appropriate response + if ($request->getRequestFormat() != 'html') { + return new JsonResponse(null, Response::HTTP_NO_CONTENT); + } + + // Set success message + $this->addFlash( + 'success', $this->translator->trans('webburza_sylius_wishlist.ui.deleted') + ); + + return $this->redirectToRoute('webburza_sylius_wishlist_account_wishlist_index'); + } +} diff --git a/src/Controller/Shop/WishlistController.php b/src/Controller/Shop/WishlistController.php new file mode 100644 index 0000000..061e307 --- /dev/null +++ b/src/Controller/Shop/WishlistController.php @@ -0,0 +1,243 @@ +loggedInUserProvider = $loggedInUserProvider; + $this->wishlistRepository = $wishlistRepository; + $this->wishlistFactory = $wishlistFactory; + $this->translator = $translator; + $this->restViewHandler = $restViewHandler; + $this->multipleWishlistMode = $multipleWishlistMode; + } + + /** + * @param Request $request + * + * @return Response + */ + public function firstAction(Request $request) : Response + { + // Abort if no logged-in user + if (!($loggedInUser = $this->loggedInUserProvider->getUser())) { + throw $this->createNotFoundException(); + } + + // Get the first wishlist for the user + $wishlist = $this->wishlistRepository->getFirstForUser($loggedInUser); + + // Create a wishlist if none exists + if (!$wishlist) { + $wishlist = $this->wishlistFactory->createDefault($loggedInUser); + $this->wishlistRepository->add($wishlist); + } + + // If the bundle is configured to work with multiple wishlists + // Redirect to the current wishlist to update URI + if ($this->multipleWishlistMode) { + return $this->redirectToRoute('webburza_sylius_wishlist_shop_wishlist_show', [ + 'id' => $wishlist->getId(), + 'slug' => $wishlist->getSlug() + ]); + } + + return $this->handleView( + '@WebburzaSyliusWishlistPlugin/Resources/views/Shop/Wishlist/show.html.twig', [ + 'wishlist' => $wishlist + ], $request + ); + } + + /** + * @param Request $request + * + * @return Response $response + */ + public function clearAction(Request $request) : Response + { + /** @var WishlistInterface $wishlist */ + $wishlist = $this->wishlistRepository->findOneBy([ + 'id' => $request->get('id'), + 'user' => $this->getUser() + ]); + + // Check if wishlist found + if (!$wishlist) { + throw $this->createNotFoundException(); + } + + // Clear items from wishlist + $wishlist->clearItems(); + + // Persist changes + $this->wishlistRepository->add($wishlist); + + // If this was an AJAX request, return appropriate response + if ($request->isXmlHttpRequest()) { + return new JsonResponse(null, 200); + } + + // Set success message + $this->addFlash( + 'success', $this->translator->trans('webburza_sylius_wishlist.flash.cleared') + ); + + return $this->redirectToWishlist($wishlist); + } + + /** + * Get a publicly visible wishlist by id. + * + * @param Request $request + * + * @return Response + */ + public function showAction(Request $request): Response + { + /** @var WishlistInterface $wishlist */ + $wishlist = $this->wishlistRepository->findOneBy([ + 'id' => $request->get('id'), + 'slug' => $request->get('slug') + ]); + + // Check if wishlist exists, and it can be accessed + if (!($wishlist && $this->userCanAccessWishlist( + $this->loggedInUserProvider->getUser(), $wishlist) + )) { + throw $this->createNotFoundException(); + } + + return $this->handleView( + '@WebburzaSyliusWishlistPlugin/Resources/views/Shop/Wishlist/show.html.twig', [ + 'wishlist' => $wishlist + ], $request + ); + } + + /** + * Check if a wishlist is publicly available, or the + * user has special privileges to access it. + * + * @param ShopUserInterface $user + * @param WishlistInterface $wishlist + * + * @return bool + */ + protected function userCanAccessWishlist( + ShopUserInterface $user = null, + WishlistInterface $wishlist + ) : bool { + return $wishlist->isPublic() || ($user && $user->getId() === $wishlist->getUser()->getId()); + } + + /** + * @param WishlistInterface $wishlist + * + * @return RedirectResponse + */ + protected function redirectToWishlist(WishlistInterface $wishlist) : RedirectResponse + { + // If the bundle is configured to work with a single wishlist, + // Redirect to the the general route (without an id) + if (false == $this->multipleWishlistMode) { + return $this->redirectToRoute('webburza_sylius_wishlist_shop_wishlist_first'); + } + + // Redirect back to the same wishlist + return $this->redirectToRoute('webburza_sylius_wishlist_shop_wishlist_show', [ + 'id' => $wishlist->getId(), + 'slug' => $wishlist->getSlug() + ]); + } + + /** + * @param string $template + * @param array $data + * @param Request $request + * + * @return Response + */ + protected function handleView(string $template, array $data = [], Request $request) : Response + { + // Consider first item in $data as main resource + $resource = !empty($data) ? array_values($data)[0] : null; + + // Create the view + $view = View::create($resource); + + // Set template if HTML request, or serialization data and format if Ajax + if (!$request->isXmlHttpRequest()) { + $view->setTemplate($template) + ->setData($data); + } else { + $view->getContext()->enableMaxDepth(); + $view->setFormat('json'); + } + + // Handle the view and return response + return $this->restViewHandler->handle($view); + } +} diff --git a/src/Controller/Shop/WishlistItemController.php b/src/Controller/Shop/WishlistItemController.php new file mode 100644 index 0000000..7867b32 --- /dev/null +++ b/src/Controller/Shop/WishlistItemController.php @@ -0,0 +1,267 @@ +loggedInUserProvider = $loggedInUserProvider; + $this->wishlistItemRepository = $wishlistItemRepository; + $this->translator = $translator; + $this->cartContext = $cartContext; + $this->productVariantRepository = $productVariantRepository; + $this->cartItemFactory = $cartItemFactory; + $this->addToCartCommandFactory = $addToCartCommandFactory; + $this->wishlistFromRequestResolver = $wishlistFromRequestResolver; + $this->productVariantFromRequestResolver = $productVariantFromRequestResolver; + $this->wishlistItemFactory = $wishlistItemFactory; + $this->multipleWishlistMode = $multipleWishlistMode; + } + + /** + * @param Request $request + * + * @return Response + */ + public function addAction(Request $request) : Response + { + // Get (or create) the wishlist to which the item should be added + $wishlist = $this->wishlistFromRequestResolver->resolve($request); + + // Get the product variant to be added to wishlist + $productVariant = $this->productVariantFromRequestResolver->resolve($request); + + // Prevent duplicates + if ($wishlist->containsVariant($productVariant)) { + if ($request->isXmlHttpRequest()) { + return new JsonResponse(null, Response::HTTP_CONFLICT); + } + + // Set flash message + $this->addFlash( + 'info', + $this->translator->trans('webburza_sylius_wishlist.flash.already_on_wishlist') + ); + + // Redirect back to the wishlist + return $this->redirectToWishlist($wishlist); + } + + /** @var WishlistItemInterface $wishlistItem */ + $wishlistItem = $this->wishlistItemFactory->createNew(); + $wishlistItem->setProductVariant($productVariant); + + $wishlist->addItem($wishlistItem); + + // Persist the wishlist item + $this->wishlistItemRepository->add($wishlistItem); + + if ($request->isXmlHttpRequest()) { + return new JsonResponse(null, Response::HTTP_CREATED); + } + + // Set success message + $this->addFlash( + 'success', $this->translator->trans('webburza_sylius_wishlist.flash.item_added') + ); + + // Redirect back to the wishlist + return $this->redirectToWishlist($wishlist); + } + + /** + * @param Request $request + * + * @return Response + */ + public function addToCartAction(Request $request) : Response + { + // Get product variant + $variant = $this->productVariantRepository->find($request->get('variantId')); + + // Check if product variant found + if (!$variant) { + throw $this->createNotFoundException(); + } + + // Create an add-to-cart command + $addToCartCommand = $this->addToCartCommandFactory->createWithCartAndCartItem( + $this->cartContext->getCart(), + $this->cartItemFactory->createForProduct($variant->getProduct()) + ); + + // Prepare the form to be rendered for the add-to-cart command + $form = $this->get('form.factory')->create(AddToCartType::class, $addToCartCommand, [ + 'product' => $variant->getProduct() + ]); + + $form->get('cartItem')->get('quantity')->setData(1); + + if ($form->get('cartItem')->has('variant')) { + $form->get('cartItem')->get('variant')->setData($variant); + } + + // Render the view + return $this->render('@WebburzaSyliusWishlistPlugin/Resources/views/Shop/Wishlist/_cartForm.html.twig', [ + 'product' => $variant->getProduct(), + 'form' => $form->createView() + ]); + } + + /** + * @param Request $request + * + * @return Response + */ + public function removeAction(Request $request) : Response + { + /** @var WishlistItemInterface $wishlistItem */ + $wishlistItem = $this->wishlistItemRepository->find($request->get('id')); + + // Check if wishlist item found + if (!$wishlistItem) { + throw $this->createNotFoundException(); + } + + // Check if this item belongs to the current customer trying to remove it + if ($wishlistItem->getWishlist()->getUser() != $this->getUser()) { + throw $this->createAccessDeniedException(); + } + + // Remove the item from the repository + $this->wishlistItemRepository->remove($wishlistItem); + + // If this was an AJAX request, return appropriate response + if ($request->isXmlHttpRequest()) { + return new JsonResponse(null, Response::HTTP_NO_CONTENT); + } + + // Set success message + $this->addFlash( + 'success', $this->translator->trans('webburza_sylius_wishlist.flash.item_removed') + ); + + return $this->redirectToWishlist($wishlistItem->getWishlist()); + } + + /** + * @param WishlistInterface $wishlist + * + * @return RedirectResponse + */ + protected function redirectToWishlist(WishlistInterface $wishlist) : RedirectResponse + { + // If the bundle is configured to work with a single wishlist, + // Redirect to the the general route (without an id) + if (false == $this->multipleWishlistMode) { + return $this->redirectToRoute('webburza_sylius_wishlist_shop_wishlist_first'); + } + + // Redirect back to the same wishlist + return $this->redirectToRoute('webburza_sylius_wishlist_shop_wishlist_show', [ + 'id' => $wishlist->getId(), + 'slug' => $wishlist->getSlug() + ]); + } +} diff --git a/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php similarity index 53% rename from DependencyInjection/Configuration.php rename to src/DependencyInjection/Configuration.php index 9d5b624..3f09dc8 100644 --- a/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -1,24 +1,26 @@ root('webburza_sylius_wishlist'); $rootNode ->children() - ->booleanNode('multiple')->end() - ->booleanNode('default_public')->end() + ->booleanNode('multiple')->defaultFalse()->end() + ->booleanNode('default_public')->defaultFalse()->end() ->end(); return $treeBuilder; diff --git a/src/DependencyInjection/WebburzaSyliusWishlistExtension.php b/src/DependencyInjection/WebburzaSyliusWishlistExtension.php new file mode 100644 index 0000000..3ffdfbc --- /dev/null +++ b/src/DependencyInjection/WebburzaSyliusWishlistExtension.php @@ -0,0 +1,30 @@ +processConfiguration($this->getConfiguration([], $container), $config); + + // Set configuration as a parameters in the container + $container->setParameter('webburza_sylius_wishlist.config.multiple', $config['multiple']); + $container->setParameter('webburza_sylius_wishlist.config.default_public', $config['default_public']); + + $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); + + $loader->load('services.yml'); + } +} diff --git a/Doctrine/ORM/WishlistRepository.php b/src/Doctrine/ORM/WishlistRepository.php similarity index 62% rename from Doctrine/ORM/WishlistRepository.php rename to src/Doctrine/ORM/WishlistRepository.php index a08120a..52c0548 100644 --- a/Doctrine/ORM/WishlistRepository.php +++ b/src/Doctrine/ORM/WishlistRepository.php @@ -1,33 +1,36 @@ createQueryBuilder('o'); $queryBuilder->innerJoin('o.user', 'user'); + $queryBuilder->innerJoin('user.customer', 'customer'); return $queryBuilder; } /** - * @param UserInterface $user + * @param ShopUserInterface $user * - * @return integer + * @return int */ - public function getCountForUser(UserInterface $user) + public function getCountForUser(ShopUserInterface $user): int { // Get query builder $queryBuilder = $this->createQueryBuilder('o'); @@ -44,11 +47,11 @@ public function getCountForUser(UserInterface $user) /** * Get the first wishlist for the user, if any. * - * @param UserInterface $user + * @param ShopUserInterface $user * * @return WishlistInterface|object|null */ - public function getFirstForUser(UserInterface $user) + public function getFirstForUser(ShopUserInterface $user): ?WishlistInterface { return $this->findOneBy([ 'user' => $user diff --git a/EventListener/AccountMenuBuilderListener.php b/src/EventListener/AccountMenuListener.php similarity index 57% rename from EventListener/AccountMenuBuilderListener.php rename to src/EventListener/AccountMenuListener.php index eb14ca8..40c4c83 100644 --- a/EventListener/AccountMenuBuilderListener.php +++ b/src/EventListener/AccountMenuListener.php @@ -1,13 +1,15 @@ translator = $translator; - $this->tokenStorage = $tokenStorage; + $this->loggedInUserProvider = $loggedInUserProvider; $this->wishlistRepository = $wishlistRepository; $this->multipleWishlistMode = $multipleWishlistMode; } @@ -55,29 +57,31 @@ public function __construct( * * @param MenuBuilderEvent $event */ - public function addAccountMenuItems(MenuBuilderEvent $event) + public function addMenuItems(MenuBuilderEvent $event) : void { // Get the menu $menu = $event->getMenu(); // Set route and label, depending on multiple wishlist mode if ($this->multipleWishlistMode) { - $route = 'webburza_account_wishlist_index'; + $route = 'webburza_sylius_wishlist_account_wishlist_index'; $routeParameters = []; - $label = $this->translate('webburza_wishlist.ui.my_wishlists'); + $label = $this->translator->trans('webburza_sylius_wishlist.ui.account_wishlists'); } else { // Get the first wishlist for the user - $wishlist = $this->wishlistRepository->getFirstForUser($this->getUser()); + $wishlist = $this->wishlistRepository->getFirstForUser( + $this->loggedInUserProvider->getUser() + ); if (!$wishlist) { return; } - $route = 'webburza_account_wishlist_edit'; + $route = 'webburza_sylius_wishlist_account_wishlist_edit'; $routeParameters = [ 'id' => $wishlist->getId() ]; - $label = $this->translate('webburza_wishlist.ui.my_wishlist'); + $label = $this->translator->trans('webburza_sylius_wishlist.ui.account_wishlist'); } // Add menu item to the menu @@ -88,29 +92,4 @@ public function addAccountMenuItems(MenuBuilderEvent $event) 'labelAttributes' => ['icon' => 'star', 'iconOnly' => false], ])->setLabel($label); } - - /** - * Translate a string using the translator. - * - * @param $string - * @return string - */ - protected function translate($string) - { - return $this->translator->trans($string); - } - - /** - * @return UserInterface - */ - protected function getUser() - { - if ($securityToken = $this->tokenStorage->getToken()) { - if (($user = $securityToken->getUser()) instanceof UserInterface) { - return $user; - } - } - - return null; - } } diff --git a/src/EventListener/AdminMenuListener.php b/src/EventListener/AdminMenuListener.php new file mode 100644 index 0000000..3c548d5 --- /dev/null +++ b/src/EventListener/AdminMenuListener.php @@ -0,0 +1,29 @@ +getMenu(); + + // Get or create the parent group + if (null === ($customerMenu = $menu->getChild('customers'))) { + $customerMenu = $menu->addChild('customers')->setLabel('sylius.ui.customer'); + } + + // Add 'Wishlists' menu item + $customerMenu + ->addChild('webburza_sylius_wishlist.wishlists', ['route' => 'webburza_sylius_wishlist_admin_wishlist_index']) + ->setLabel('webburza_sylius_wishlist.ui.wishlists') + ->setLabelAttribute('icon', 'star'); + } +} diff --git a/Factory/WishlistFactory.php b/src/Factory/WishlistFactory.php similarity index 73% rename from Factory/WishlistFactory.php rename to src/Factory/WishlistFactory.php index eb19265..4826980 100644 --- a/Factory/WishlistFactory.php +++ b/src/Factory/WishlistFactory.php @@ -1,11 +1,13 @@ factory->createNew(); } /** - * @param UserInterface $user + * @param ShopUserInterface $user * * @return WishlistInterface */ - public function createDefault(UserInterface $user) + public function createDefault(ShopUserInterface $user) : WishlistInterface { // Create a new wishlist $wishlist = $this->createNew(); // Set default title - $wishlist->setTitle($this->translator->trans('webburza_wishlist.wishlist.default_title')); + $wishlist->setTitle($this->translator->trans('webburza_sylius_wishlist.ui.default_title')); // Set default public state $wishlist->setPublic($this->defaultPublic); diff --git a/src/Factory/WishlistFactoryInterface.php b/src/Factory/WishlistFactoryInterface.php new file mode 100644 index 0000000..b00f9c4 --- /dev/null +++ b/src/Factory/WishlistFactoryInterface.php @@ -0,0 +1,19 @@ +add('title', Type\TextType::class, [ - 'label' => 'webburza_wishlist.wishlist.label.title', + 'label' => 'sylius.ui.title', 'required' => true, 'constraints' => [ new NotBlank() @@ -24,12 +26,12 @@ public function buildForm(FormBuilderInterface $builder, array $options) ]); $builder->add('description', Type\TextareaType::class, [ - 'label' => 'webburza_wishlist.wishlist.label.description', + 'label' => 'sylius.ui.description', 'required' => false ]); $builder->add('public', Type\CheckboxType::class, [ - 'label' => 'webburza_wishlist.wishlist.label.public', + 'label' => 'webburza_sylius_wishlist.ui.public', 'required' => false ]); } diff --git a/Model/Wishlist.php b/src/Model/Wishlist.php similarity index 50% rename from Model/Wishlist.php rename to src/Model/Wishlist.php index 138c259..9dcad3a 100644 --- a/Model/Wishlist.php +++ b/src/Model/Wishlist.php @@ -1,16 +1,19 @@ id; } @@ -66,7 +69,7 @@ public function getId() /** * @return string */ - public function getTitle() + public function getTitle() : ?string { return $this->title; } @@ -76,7 +79,7 @@ public function getTitle() * * @return WishlistInterface */ - public function setTitle($title) + public function setTitle(?string $title) : WishlistInterface { $this->title = $title; @@ -86,7 +89,7 @@ public function setTitle($title) /** * @return string */ - public function getSlug() + public function getSlug() : string { return $this->slug; } @@ -94,9 +97,9 @@ public function getSlug() /** * @param string $slug * - * @return Wishlist + * @return WishlistInterface */ - public function setSlug($slug) + public function setSlug(string $slug) : WishlistInterface { $this->slug = $slug; @@ -106,7 +109,7 @@ public function setSlug($slug) /** * @return string */ - public function getDescription() + public function getDescription() : ?string { return $this->description; } @@ -114,9 +117,9 @@ public function getDescription() /** * @param string $description * - * @return Wishlist + * @return WishlistInterface */ - public function setDescription($description) + public function setDescription(?string $description) : WishlistInterface { $this->description = $description; @@ -124,19 +127,19 @@ public function setDescription($description) } /** - * @return boolean + * @return bool */ - public function isPublic() + public function isPublic() : bool { return $this->public; } /** - * @param boolean $public + * @param bool $public * * @return WishlistInterface */ - public function setPublic($public) + public function setPublic(bool $public) : WishlistInterface { $this->public = $public; @@ -146,17 +149,17 @@ public function setPublic($public) /** * @return ShopUserInterface */ - public function getUser() + public function getUser() : ShopUserInterface { return $this->user; } /** - * @param UserInterface $user + * @param ShopUserInterface $user * - * @return Wishlist + * @return WishlistInterface */ - public function setUser(UserInterface $user = null) + public function setUser(ShopUserInterface $user) : WishlistInterface { $this->user = $user; @@ -164,9 +167,9 @@ public function setUser(UserInterface $user = null) } /** - * @return ArrayCollection|WishlistItemInterface[] + * @return Collection|WishlistItemInterface[] */ - public function getItems() + public function getItems() : Collection { return $this->items; } @@ -174,7 +177,7 @@ public function getItems() /** * @return bool */ - public function hasItems() + public function hasItems() : bool { return !$this->items->isEmpty(); } @@ -184,7 +187,7 @@ public function hasItems() * * @return WishlistInterface */ - public function addItem(WishlistItemInterface $item) + public function addItem(WishlistItemInterface $item) : WishlistInterface { $this->items->add($item); $item->setWishlist($this); @@ -192,15 +195,55 @@ public function addItem(WishlistItemInterface $item) return $this; } + /** + * @param WishlistItemInterface $item + * + * @return WishlistInterface + */ + public function removeItem(WishlistItemInterface $item) : WishlistInterface + { + $this->items->removeElement($item); + + return $this; + } + + /** + * @return WishlistInterface + */ + public function clearItems() : WishlistInterface + { + foreach ($this->getItems() as $item) { + $this->removeItem($item); + } + + return $this; + } + /** * @param ProductVariantInterface $productVariant * * @return bool */ - public function contains(ProductVariantInterface $productVariant) + public function containsVariant(ProductVariantInterface $productVariant) : bool + { + foreach ($this->items as $wishlistItem) { + if ($wishlistItem->getProductVariant() === $productVariant) { + return true; + } + } + + return false; + } + + /** + * @param ProductInterface $product + * + * @return bool + */ + public function containsProduct(ProductInterface $product) : bool { foreach ($this->items as $wishlistItem) { - if ($wishlistItem->getProductVariant() == $productVariant) { + if ($wishlistItem->getProductVariant()->getProduct() === $product) { return true; } } diff --git a/src/Model/WishlistInterface.php b/src/Model/WishlistInterface.php new file mode 100644 index 0000000..cb46fb7 --- /dev/null +++ b/src/Model/WishlistInterface.php @@ -0,0 +1,118 @@ +id; } @@ -38,7 +37,7 @@ public function getId() /** * @return WishlistInterface */ - public function getWishlist() + public function getWishlist() : WishlistInterface { return $this->wishlist; } @@ -48,7 +47,7 @@ public function getWishlist() * * @return WishlistItemInterface */ - public function setWishlist(WishlistInterface $wishlist) + public function setWishlist(WishlistInterface $wishlist) : WishlistItemInterface { $this->wishlist = $wishlist; @@ -58,7 +57,7 @@ public function setWishlist(WishlistInterface $wishlist) /** * @return ProductVariantInterface */ - public function getProductVariant() + public function getProductVariant() : ProductVariantInterface { return $this->productVariant; } @@ -68,7 +67,7 @@ public function getProductVariant() * * @return WishlistItemInterface */ - public function setProductVariant(ProductVariantInterface $productVariant) + public function setProductVariant(ProductVariantInterface $productVariant) : WishlistItemInterface { $this->productVariant = $productVariant; diff --git a/Model/WishlistItemInterface.php b/src/Model/WishlistItemInterface.php similarity index 53% rename from Model/WishlistItemInterface.php rename to src/Model/WishlistItemInterface.php index 6a98caa..39cb912 100644 --- a/Model/WishlistItemInterface.php +++ b/src/Model/WishlistItemInterface.php @@ -1,37 +1,36 @@ tokenStorage = $tokenStorage; + } + + /** + * @return ShopUserInterface|null + */ + public function getUser() : ?ShopUserInterface + { + if ($securityToken = $this->tokenStorage->getToken()) { + if (($user = $securityToken->getUser()) instanceof ShopUserInterface) { + return $user; + } + } + + return null; + } +} diff --git a/src/Provider/LoggedInUserProviderInterface.php b/src/Provider/LoggedInUserProviderInterface.php new file mode 100644 index 0000000..ee041a5 --- /dev/null +++ b/src/Provider/LoggedInUserProviderInterface.php @@ -0,0 +1,15 @@ +repository = $repository; - $this->tokenStorage = $tokenStorage; + $this->loggedInUserProvider = $loggedInUserProvider; } /** * @return WishlistInterface[] */ - public function getWishlists() + public function getWishlists() : array { if (null === $this->wishlists) { - if ($user = $this->getUser()) { + if ($user = $this->loggedInUserProvider->getUser()) { $this->wishlists = $this->repository->findBy(['user' => $user]); } } - return $this->wishlists; + return $this->wishlists ?: []; } /** * @return int */ - public function getItemCount() + public function getItemCount() : int { $itemCount = 0; @@ -65,18 +65,4 @@ public function getItemCount() return $itemCount; } - - /** - * @return UserInterface - */ - protected function getUser() - { - if ($securityToken = $this->tokenStorage->getToken()) { - if (($user = $securityToken->getUser()) instanceof UserInterface) { - return $user; - } - } - - return null; - } } diff --git a/src/Provider/WishlistProviderInterface.php b/src/Provider/WishlistProviderInterface.php new file mode 100644 index 0000000..9c89fa4 --- /dev/null +++ b/src/Provider/WishlistProviderInterface.php @@ -0,0 +1,20 @@ +productVariantRepository = $productVariantRepository; $this->productRepository = $productRepository; $this->addToCartCommandFactory = $addToCartCommandFactory; $this->cartContext = $cartContext; @@ -69,7 +78,27 @@ public function __construct( * * @return ProductVariantInterface */ - public function resolve(Request $request) + public function resolve(Request $request) : ProductVariantInterface + { + if ($productVariantId = $request->get('productVariantId')) { + $productVariant = $this->productVariantRepository->find($productVariantId); + } else { + $productVariant = $this->resolveViaCartForm($request); + } + + if (!$productVariant) { + throw new BadRequestHttpException(); + } + + return $productVariant; + } + + /** + * @param Request $request + * + * @return ProductVariantInterface + */ + protected function resolveViaCartForm(Request $request) : ?ProductVariantInterface { /** @var ProductInterface $product */ if (!($product = $this->productRepository->find($request->get('productId')))) { diff --git a/src/Resolver/ProductVariantFromRequestResolverInterface.php b/src/Resolver/ProductVariantFromRequestResolverInterface.php new file mode 100644 index 0000000..0bf6939 --- /dev/null +++ b/src/Resolver/ProductVariantFromRequestResolverInterface.php @@ -0,0 +1,18 @@ +loggedInUserProvider = $loggedInUserProvider; + $this->wishlistRepository = $wishlistRepository; + $this->wishlistFactory = $wishlistFactory; + } + + /** + * Get the requested wishlist, if any, or the first one for the logged-in user. + * If none exists for the user, create a new one. + * + * @param Request $request + * + * @return WishlistInterface + */ + public function resolve(Request $request) : WishlistInterface + { + // Abort if no logged-in user + if (!($user = $this->loggedInUserProvider->getUser())) { + throw new BadRequestHttpException(); + } + + // Check if a specific wishlist was requested + if ($wishlistId = $request->get('wishlistId')) { + /** @var WishlistInterface $wishlist */ + $wishlist = $this->wishlistRepository->findOneBy([ + 'id' => $wishlistId, + 'user' => $user + ]); + + if (!$wishlist) { + throw new NotFoundHttpException(); + } + + return $wishlist; + } + + // If not, get the first wishlist for the user + $wishlist = $this->wishlistRepository->getFirstForUser($user); + + // If no wishlist found, create a new one + if (!$wishlist) { + $wishlist = $this->wishlistFactory->createDefault($user); + $this->wishlistRepository->add($wishlist); + } + + return $wishlist; + } +} diff --git a/src/Resolver/WishlistFromRequestResolverInterface.php b/src/Resolver/WishlistFromRequestResolverInterface.php new file mode 100644 index 0000000..6250cc5 --- /dev/null +++ b/src/Resolver/WishlistFromRequestResolverInterface.php @@ -0,0 +1,18 @@ + - + - - + + + + + + + + + + + + + - + - - - - - - diff --git a/Resources/config/doctrine/WishlistItem.orm.xml b/src/Resources/config/doctrine/WishlistItem.orm.xml similarity index 88% rename from Resources/config/doctrine/WishlistItem.orm.xml rename to src/Resources/config/doctrine/WishlistItem.orm.xml index 3ff277e..aefb441 100644 --- a/Resources/config/doctrine/WishlistItem.orm.xml +++ b/src/Resources/config/doctrine/WishlistItem.orm.xml @@ -6,11 +6,19 @@ xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> - + + + + + + + + + @@ -19,14 +27,6 @@ - - - - - - - - diff --git a/src/Resources/config/routing.yml b/src/Resources/config/routing.yml new file mode 100644 index 0000000..60c1557 --- /dev/null +++ b/src/Resources/config/routing.yml @@ -0,0 +1,10 @@ +webburza_sylius_wishlist_admin: + resource: routing/admin.yml + +webburza_sylius_wishlist_shop: + resource: routing/shop.yml + prefix: /wishlist + +webburza_sylius_wishlist_account: + resource: routing/account.yml + prefix: /account/wishlists diff --git a/src/Resources/config/routing/account.yml b/src/Resources/config/routing/account.yml new file mode 100644 index 0000000..9e35c2c --- /dev/null +++ b/src/Resources/config/routing/account.yml @@ -0,0 +1,29 @@ +webburza_sylius_wishlist_account_wishlist_create: + path: /new + methods: [GET, POST] + defaults: + _controller: webburza_sylius_wishlist.controller.account.wishlist:createAction + +webburza_sylius_wishlist_account_wishlist_edit: + path: /{id}/edit + methods: [GET] + defaults: + _controller: webburza_sylius_wishlist.controller.account.wishlist:updateAction + +webburza_sylius_wishlist_account_wishlist_update: + path: /{id} + methods: [PUT] + defaults: + _controller: webburza_sylius_wishlist.controller.account.wishlist:updateAction + +webburza_sylius_wishlist_account_wishlist_index: + path: / + methods: [GET] + defaults: + _controller: webburza_sylius_wishlist.controller.account.wishlist:indexAction + +webburza_sylius_wishlist_account_wishlist_delete: + path: /{id} + methods: [DELETE] + defaults: + _controller: webburza_sylius_wishlist.controller.account.wishlist:deleteAction diff --git a/src/Resources/config/routing/admin.yml b/src/Resources/config/routing/admin.yml new file mode 100644 index 0000000..c0da06a --- /dev/null +++ b/src/Resources/config/routing/admin.yml @@ -0,0 +1,14 @@ +webburza_sylius_wishlist_admin_wishlist: + resource: | + alias: webburza_sylius_wishlist.wishlist + section: admin + templates: WebburzaSyliusWishlistPlugin:Admin + except: ['create', 'update'] + grid: webburza_sylius_wishlist_admin_wishlist + vars: + all: + subheader: webburza_sylius_wishlist.ui.manage_wishlists + index: + icon: 'file star' + type: sylius.resource + prefix: /admin diff --git a/src/Resources/config/routing/shop.yml b/src/Resources/config/routing/shop.yml new file mode 100644 index 0000000..3f5b44a --- /dev/null +++ b/src/Resources/config/routing/shop.yml @@ -0,0 +1,38 @@ +# Show the first wishlist for the current user, only if the bundle +# is configured for a single wishlist per user, otherwise redirect + +webburza_sylius_wishlist_shop_wishlist_first: + path: / + methods: [GET] + defaults: + _controller: webburza_sylius_wishlist.controller.shop.wishlist:firstAction + +webburza_sylius_wishlist_shop_wishlist_clear: + path: /{id}/clear + methods: [POST] + defaults: + _controller: webburza_sylius_wishlist.controller.shop.wishlist:clearAction + +webburza_sylius_wishlist_shop_wishlist_add_item: + path: /item + methods: [POST] + defaults: + _controller: webburza_sylius_wishlist.controller.shop.wishlist_item:addAction + +webburza_sylius_wishlist_shop_wishlist_remove_item: + path: /item/{id} + methods: [DELETE] + defaults: + _controller: webburza_sylius_wishlist.controller.shop.wishlist_item:removeAction + +webburza_sylius_wishlist_shop_add_to_cart: + path: /item/add-to-cart + methods: [GET] + defaults: + _controller: webburza_sylius_wishlist.controller.shop.wishlist_item:addToCartAction + +webburza_sylius_wishlist_shop_wishlist_show: + path: /{id}/{slug} + methods: [GET] + defaults: + _controller: webburza_sylius_wishlist.controller.shop.wishlist:showAction diff --git a/src/Resources/config/serializer/Model.Wishlist.yml b/src/Resources/config/serializer/Model.Wishlist.yml new file mode 100644 index 0000000..79a15e8 --- /dev/null +++ b/src/Resources/config/serializer/Model.Wishlist.yml @@ -0,0 +1,23 @@ +Webburza\SyliusWishlistPlugin\Model\Wishlist: + exclusion_policy: ALL + xml_root_name: webburza-wishlist + properties: + id: + expose: true + type: integer + xml_attribute: true + title: + expose: true + type: string + slug: + expose: true + type: string + description: + expose: true + type: string + public: + expose: true + type: bool + items: + expose: true + type: array diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml new file mode 100644 index 0000000..80b8f53 --- /dev/null +++ b/src/Resources/config/services.yml @@ -0,0 +1,6 @@ +imports: + - { resource: services/providers.yml } + - { resource: services/controllers.yml } + - { resource: services/resolvers.yml } + - { resource: services/listeners.yml } + - { resource: services/misc.yml } diff --git a/src/Resources/config/services/controllers.yml b/src/Resources/config/services/controllers.yml new file mode 100644 index 0000000..381f956 --- /dev/null +++ b/src/Resources/config/services/controllers.yml @@ -0,0 +1,34 @@ +services: + webburza_sylius_wishlist.controller.shop.wishlist: + class: Webburza\SyliusWishlistPlugin\Controller\Shop\WishlistController + arguments: + - '@webburza_sylius_wishlist.provider.logged_in_user' + - '@webburza_sylius_wishlist.repository.wishlist' + - '@webburza_sylius_wishlist.factory.wishlist' + - '@translator' + - '@fos_rest.view_handler.default' + - '%webburza_sylius_wishlist.config.multiple%' + + webburza_sylius_wishlist.controller.shop.wishlist_item: + class: Webburza\SyliusWishlistPlugin\Controller\Shop\WishlistItemController + arguments: + - '@webburza_sylius_wishlist.provider.logged_in_user' + - '@webburza_sylius_wishlist.repository.wishlist_item' + - '@translator' + - '@sylius.context.cart' + - '@sylius.repository.product_variant' + - '@sylius.custom_factory.order_item' + - '@sylius.factory.add_to_cart_command' + - '@webburza_sylius_wishlist.resolver.wishlist_from_request' + - '@webburza_sylius_wishlist.resolver.product_variant_from_request' + - '@webburza_sylius_wishlist.factory.wishlist_item' + - '%webburza_sylius_wishlist.config.multiple%' + + webburza_sylius_wishlist.controller.account.wishlist: + class: Webburza\SyliusWishlistPlugin\Controller\Account\WishlistController + arguments: + - '@webburza_sylius_wishlist.repository.wishlist' + - '@webburza_sylius_wishlist.provider.logged_in_user' + - '@translator' + - '@form.factory' + - '%webburza_sylius_wishlist.config.multiple%' diff --git a/src/Resources/config/services/listeners.yml b/src/Resources/config/services/listeners.yml new file mode 100644 index 0000000..7336b18 --- /dev/null +++ b/src/Resources/config/services/listeners.yml @@ -0,0 +1,15 @@ +services: + webburza_sylius_wishlist.event_listener.admin_menu: + class: Webburza\SyliusWishlistPlugin\EventListener\AdminMenuListener + tags: + - { name: kernel.event_listener, event: sylius.menu.admin.main, method: addMenuItems } + + webburza_sylius_wishlist.event_listener.account_menu: + class: Webburza\SyliusWishlistPlugin\EventListener\AccountMenuListener + arguments: + - '@translator' + - '@webburza_sylius_wishlist.provider.logged_in_user' + - '@webburza_sylius_wishlist.repository.wishlist' + - '%webburza_sylius_wishlist.config.multiple%' + tags: + - { name: kernel.event_listener, event: sylius.menu.shop.account, method: addMenuItems } diff --git a/src/Resources/config/services/misc.yml b/src/Resources/config/services/misc.yml new file mode 100644 index 0000000..c78d7d7 --- /dev/null +++ b/src/Resources/config/services/misc.yml @@ -0,0 +1,15 @@ +services: + webburza_sylius_wishlist.factory.decorated.wishlist: + class: Webburza\SyliusWishlistPlugin\Factory\WishlistFactory + decorates: webburza_sylius_wishlist.factory.wishlist + arguments: + - '@webburza_sylius_wishlist.factory.decorated.wishlist.inner' + - '@translator' + - '%webburza_sylius_wishlist.config.default_public%' + + webburza_sylius_wishlist.form.type.wishlist_type: + class: Webburza\SyliusWishlistPlugin\Form\Type\WishlistType + arguments: + - '%webburza_sylius_wishlist.model.wishlist.class%' + tags: + - { name: form.type } diff --git a/src/Resources/config/services/providers.yml b/src/Resources/config/services/providers.yml new file mode 100644 index 0000000..2e61e3b --- /dev/null +++ b/src/Resources/config/services/providers.yml @@ -0,0 +1,11 @@ +services: + webburza_sylius_wishlist.provider.logged_in_user: + class: Webburza\SyliusWishlistPlugin\Provider\LoggedInUserProvider + arguments: + - '@security.token_storage' + + webburza_sylius_wishlist.provider.wishlist: + class: Webburza\SyliusWishlistPlugin\Provider\WishlistProvider + arguments: + - '@webburza_sylius_wishlist.repository.wishlist' + - '@webburza_sylius_wishlist.provider.logged_in_user' diff --git a/src/Resources/config/services/resolvers.yml b/src/Resources/config/services/resolvers.yml new file mode 100644 index 0000000..bd6a1a7 --- /dev/null +++ b/src/Resources/config/services/resolvers.yml @@ -0,0 +1,17 @@ +services: + webburza_sylius_wishlist.resolver.wishlist_from_request: + class: Webburza\SyliusWishlistPlugin\Resolver\WishlistFromRequestResolver + arguments: + - '@webburza_sylius_wishlist.provider.logged_in_user' + - '@webburza_sylius_wishlist.repository.wishlist' + - '@webburza_sylius_wishlist.factory.decorated.wishlist' + + webburza_sylius_wishlist.resolver.product_variant_from_request: + class: Webburza\SyliusWishlistPlugin\Resolver\ProductVariantFromRequestResolver + arguments: + - '@sylius.repository.product_variant' + - '@sylius.repository.product' + - '@sylius.factory.add_to_cart_command' + - '@sylius.context.cart' + - '@sylius.custom_factory.order_item' + - '@form.factory' diff --git a/Resources/translations/messages.en.yml b/src/Resources/translations/messages.en.yml similarity index 70% rename from Resources/translations/messages.en.yml rename to src/Resources/translations/messages.en.yml index d387dbb..da6154f 100644 --- a/Resources/translations/messages.en.yml +++ b/src/Resources/translations/messages.en.yml @@ -1,4 +1,4 @@ -webburza_wishlist: +webburza_sylius_wishlist: ui: wishlist: Wishlist wishlists: Wishlists @@ -7,14 +7,17 @@ webburza_wishlist: wishlist_is_empty: This wishlist has no items. not_public: This wishlist is private. clear_wishlist: Clear all items - customer: Customer - add_to_cart: Add to cart add_to_wishlist: Add to wishlist - remove_from_wishlist: Remove controls: Controls - my_wishlist: Wishlist - my_wishlists: My wishlists + account_wishlist: Wishlist + account_wishlists: Wishlists + account_manage_wishlists: Manage your wishlists deleted: Wishlist deleted successfully. + default_title: Wishlist + item_count: Item count + description: Description + public: Public? + updated_at: Updated At account: update: @@ -33,14 +36,3 @@ webburza_wishlist: updated: Wishlist updated successfully. item_added: Item added to wishlist. item_removed: Item removed successfully. - - wishlist: - default_title: Wishlist - label: - id: Id - title: Title - description: Description - public: Public? - created_at: Created At - updated_at: Updated At - user: User diff --git a/Resources/views/Frontend/Account/Wishlist/create.html.twig b/src/Resources/views/Account/create.html.twig similarity index 58% rename from Resources/views/Frontend/Account/Wishlist/create.html.twig rename to src/Resources/views/Account/create.html.twig index 59131e1..0b58934 100644 --- a/Resources/views/Frontend/Account/Wishlist/create.html.twig +++ b/src/Resources/views/Account/create.html.twig @@ -8,19 +8,21 @@
/
{{ 'sylius.ui.my_account'|trans }}
/
- {{ 'webburza_wishlist.account.index.header'|trans }} + + {{ 'webburza_sylius_wishlist.account.index.header'|trans }} +
/
-
{{ 'webburza_wishlist.account.create.header'|trans }}
+
{{ 'webburza_sylius_wishlist.account.create.header'|trans }}
{% endblock %} {% block subcontent %}
- {{ form_start(form, {'action': path('webburza_account_wishlist_create'), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} + {{ form_start(form, {'action': path('webburza_sylius_wishlist_account_wishlist_create'), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }}

- {{ 'webburza_wishlist.account.create.header'|trans }} -
{{ 'webburza_wishlist.account.create.subheader'|trans }}
+ {{ 'webburza_sylius_wishlist.account.create.header'|trans }} +
{{ 'webburza_sylius_wishlist.account.create.subheader'|trans }}

{{ form_errors(form) }} diff --git a/Resources/views/Frontend/Account/Wishlist/index.html.twig b/src/Resources/views/Account/index.html.twig similarity index 69% rename from Resources/views/Frontend/Account/Wishlist/index.html.twig rename to src/Resources/views/Account/index.html.twig index b923e80..37369fe 100644 --- a/Resources/views/Frontend/Account/Wishlist/index.html.twig +++ b/src/Resources/views/Account/index.html.twig @@ -9,7 +9,7 @@
/
{{ 'sylius.ui.my_account'|trans }}
/
-
{{ 'webburza_wishlist.account.index.header'|trans }}
+
{{ 'webburza_sylius_wishlist.account.index.header'|trans }}
{% endblock %} @@ -17,12 +17,12 @@

- {{ 'webburza_wishlist.account.index.header'|trans }} -
{{ 'webburza_wishlist.account.index.subheader'|trans }}
+ {{ 'webburza_sylius_wishlist.account.index.header'|trans }} +
{{ 'webburza_sylius_wishlist.account.index.subheader'|trans }}

- {{ buttons.create(path('webburza_account_wishlist_create')) }} + {{ buttons.create(path('webburza_sylius_wishlist_account_wishlist_create')) }}
@@ -31,8 +31,8 @@ - - + + @@ -40,7 +40,10 @@ {% for wishlist in wishlists %} @@ -49,8 +52,8 @@ diff --git a/Resources/views/Frontend/Account/Wishlist/update.html.twig b/src/Resources/views/Account/update.html.twig similarity index 56% rename from Resources/views/Frontend/Account/Wishlist/update.html.twig rename to src/Resources/views/Account/update.html.twig index 1eb3639..de2519c 100644 --- a/Resources/views/Frontend/Account/Wishlist/update.html.twig +++ b/src/Resources/views/Account/update.html.twig @@ -8,21 +8,23 @@
/
{{ 'sylius.ui.my_account'|trans }}
/
- {{ 'webburza_wishlist.account.index.header'|trans }} + {{ 'webburza_sylius_wishlist.account.index.header'|trans }}
/
-
{{ 'webburza_wishlist.account.update.header'|trans }}
+
{{ 'webburza_sylius_wishlist.account.update.header'|trans }}
{% endblock %} {% block subcontent %}
- {{ form_start(form, {'action': path('webburza_account_wishlist_update', {id: wishlist.id}), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} + {{ form_start(form, {'action': path('webburza_sylius_wishlist_account_wishlist_update', {id: wishlist.id}), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }}

- {{ 'webburza_wishlist.account.update.header'|trans }} -
{{ 'webburza_wishlist.account.update.subheader'|trans }}
+ {{ 'webburza_sylius_wishlist.account.update.header'|trans }} +
{{ 'webburza_sylius_wishlist.account.update.subheader'|trans }}

+ + {{ form_errors(form) }} {{ form_rest(form) }} diff --git a/src/Resources/views/Admin/Grid/_count.html.twig b/src/Resources/views/Admin/Grid/_count.html.twig new file mode 100644 index 0000000..93a1412 --- /dev/null +++ b/src/Resources/views/Admin/Grid/_count.html.twig @@ -0,0 +1 @@ +{{ data.items.count }} diff --git a/src/Resources/views/Admin/Grid/_customer.html.twig b/src/Resources/views/Admin/Grid/_customer.html.twig new file mode 100644 index 0000000..4ae5d87 --- /dev/null +++ b/src/Resources/views/Admin/Grid/_customer.html.twig @@ -0,0 +1 @@ +{{ data.customer.email }} diff --git a/src/Resources/views/Admin/Show/_breadcrumb.html.twig b/src/Resources/views/Admin/Show/_breadcrumb.html.twig new file mode 100644 index 0000000..effaa93 --- /dev/null +++ b/src/Resources/views/Admin/Show/_breadcrumb.html.twig @@ -0,0 +1,10 @@ +{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} + +{% set breadcrumbs = [ + { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, + { label: (metadata.applicationName~'.ui.'~metadata.pluralName)|trans, url: path(configuration.getRouteName('index'), configuration.vars.route.parameters|default({})) }, + { label: resource.title|default(resource.id)} + ] +%} + +{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Resources/views/Admin/Show/_details.html.twig b/src/Resources/views/Admin/Show/_details.html.twig new file mode 100644 index 0000000..19910a7 --- /dev/null +++ b/src/Resources/views/Admin/Show/_details.html.twig @@ -0,0 +1,38 @@ +
+
{{ 'webburza_wishlist.wishlist.label.title' | trans }}{{ 'webburza_wishlist.wishlist.label.public' | trans }}{{ 'sylius.ui.title' | trans }}{{ 'webburza_sylius_wishlist.ui.public' | trans }} {{ 'sylius.ui.actions' | trans }}
- + {{ wishlist.title }}
- {{ buttons.edit(path('webburza_account_wishlist_edit', { id: wishlist.id })) }} - {{ buttons.delete(path('webburza_account_wishlist_delete', { id: wishlist.id })) }} + {{ buttons.edit(path('webburza_sylius_wishlist_account_wishlist_edit', { id: wishlist.id })) }} + {{ buttons.delete(path('webburza_sylius_wishlist_account_wishlist_delete', { id: wishlist.id })) }}
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'sylius.ui.details'|trans }}
{{ 'sylius.ui.title'|trans }}{{ wishlist.title }}
{{ 'sylius.ui.description'|trans }}{{ wishlist.description }}
{{ 'sylius.ui.customer'|trans }} + {{ wishlist.user.customer.email }} +
{{ 'webburza_sylius_wishlist.ui.public'|trans }}{% include '@SyliusUi/Grid/Field/yesNo.html.twig' with {data: wishlist.public} %}
{{ 'sylius.ui.created_at' | trans }}{{ wishlist.createdAt | format_date }}
{{ 'webburza_sylius_wishlist.ui.updated_at' | trans }}{{ wishlist.updatedAt ? (wishlist.updatedAt | format_date) : '' }}
+ diff --git a/src/Resources/views/Admin/Show/_header.html.twig b/src/Resources/views/Admin/Show/_header.html.twig new file mode 100644 index 0000000..1774269 --- /dev/null +++ b/src/Resources/views/Admin/Show/_header.html.twig @@ -0,0 +1,15 @@ +
+

+ +
+ {{ wishlist.title }} +
+
+
+ {{ wishlist.user.customer.email }} +
+
+
+
+

+
diff --git a/src/Resources/views/Admin/Show/_items.html.twig b/src/Resources/views/Admin/Show/_items.html.twig new file mode 100644 index 0000000..45bf5e7 --- /dev/null +++ b/src/Resources/views/Admin/Show/_items.html.twig @@ -0,0 +1,40 @@ +{% import '@SyliusUi/Macro/messages.html.twig' as messages %} + +
+ + + + + + + + + {% if wishlist.hasItems %} + {% for item in wishlist.items %} + + + + {% endfor %} + {% else %} + + + + {% endif %} + +
{{ 'webburza_sylius_wishlist.ui.wishlist_items'|trans }}
+ + {{ item.productVariant.product.name }} + +
+ + {% if item.productVariant.optionValues is not empty %} + {% for optionValue in item.productVariant.optionValues %} + {{ optionValue.value }}{{ not loop.last ? ', ' : '' }} + {% endfor %} + {% elseif item.productVariant.name is not empty %} + {{ item.productVariant.name }} + {% endif %} + +
{{ messages.info('webburza_sylius_wishlist.ui.wishlist_is_empty') }}
+
+ diff --git a/src/Resources/views/Admin/index.html.twig b/src/Resources/views/Admin/index.html.twig new file mode 100644 index 0000000..2442b25 --- /dev/null +++ b/src/Resources/views/Admin/index.html.twig @@ -0,0 +1 @@ +{% extends 'SyliusAdminBundle:Crud:index.html.twig' %} diff --git a/src/Resources/views/Admin/show.html.twig b/src/Resources/views/Admin/show.html.twig new file mode 100644 index 0000000..61e97dd --- /dev/null +++ b/src/Resources/views/Admin/show.html.twig @@ -0,0 +1,18 @@ +{% extends 'SyliusAdminBundle::layout.html.twig' %} + +{% block title %}{{ wishlist.title ~ ' (' ~ wishlist.user.customer.email ~ ')' }} {{ parent() }}{% endblock %} + +{% block content %} +
+ {% include '@WebburzaSyliusWishlistPlugin/Resources/views/Admin/Show/_header.html.twig' %} +
+ +
+ + {% include '@WebburzaSyliusWishlistPlugin/Resources/views/Admin/Show/_breadcrumb.html.twig' %} + +
+ {% include '@WebburzaSyliusWishlistPlugin/Resources/views/Admin/Show/_details.html.twig' %} + {% include '@WebburzaSyliusWishlistPlugin/Resources/views/Admin/Show/_items.html.twig' %} +
+{% endblock %} diff --git a/Resources/views/Frontend/Shop/_addToWishlist.html.twig b/src/Resources/views/Shop/Misc/_addToWishlist.html.twig similarity index 75% rename from Resources/views/Frontend/Shop/_addToWishlist.html.twig rename to src/Resources/views/Shop/Misc/_addToWishlist.html.twig index 981e938..c588752 100644 --- a/Resources/views/Frontend/Shop/_addToWishlist.html.twig +++ b/src/Resources/views/Shop/Misc/_addToWishlist.html.twig @@ -2,7 +2,7 @@ {% if wishlist_provider.wishlists | length > 1 %}
- +