app/Plugin/CustomGMC/Controller/Admin/ProductController.php line 314

Open in your IDE?
  1. <?php
  2. namespace Plugin\CustomGMC\Controller\Admin;
  3. use Eccube\Controller\AbstractController;
  4. use Eccube\Event\EccubeEvents;
  5. use Eccube\Event\EventArgs;
  6. use Eccube\Repository\CategoryRepository;
  7. use Eccube\Repository\Master\PageMaxRepository;
  8. use Eccube\Repository\ProductRepository;
  9. use Eccube\Repository\TaxRuleRepository;
  10. use Eccube\Util\CacheUtil;
  11. use Eccube\Util\FormUtil;
  12. use Knp\Component\Pager\Paginator;
  13. use Knp\Component\Pager\PaginatorInterface;
  14. use PharIo\Manifest\Url;
  15. use Plugin\CustomGMC\Form\Type\Admin\SearchProductType;
  16. use Plugin\CustomGMC\Repository\ConfigRepository;
  17. use Plugin\CustomGMC\Utils\Constants;
  18. use Plugin\CustomGMC\Repository\ProductRepository as CustomGMCProductRepository;
  19. use Plugin\CustomGMC\Services\HandleTokenExpiredService;
  20. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  21. use Symfony\Component\HttpFoundation\Request;
  22. use Symfony\Component\Routing\Annotation\Route;
  23. class ProductController extends AbstractController
  24. {
  25.     /**
  26.      * @var ConfigRepository
  27.      */
  28.     protected $configRepository;
  29.     /**
  30.      * @var TaxRuleRepository
  31.      */
  32.     protected $taxRuleRepository;
  33.     /**
  34.      * @var ProductRepository
  35.      */
  36.     protected $productRepository;
  37.     /**
  38.      * @var PageMaxRepository
  39.      */
  40.     protected $pageMaxRepository;
  41.     /**
  42.      * @var HandleTokenExpiredService
  43.      */
  44.     protected $handleTokenExpiredService;
  45.     protected $customGMCProductRepository;
  46.     /**
  47.      * ConfigController constructor.
  48.      *
  49.      * @param ConfigRepository $configRepository
  50.      * @param CategoryRepository $categoryRepository
  51.      * @param ProductRepository $productRepository
  52.      * @param PageMaxRepository $pageMaxRepository
  53.      * @param HandleTokenExpiredService $handleTokenExpiredService
  54.      */
  55.     public function __construct(
  56.         ConfigRepository $configRepository,
  57.         TaxRuleRepository $taxRuleRepository,
  58.         ProductRepository $productRepository,
  59.         PageMaxRepository $pageMaxRepository,
  60.         HandleTokenExpiredService $handleTokenExpiredService,
  61.         CustomGMCProductRepository $customGMCProductRepository
  62.     ){
  63.         $this->taxRuleRepository $taxRuleRepository;
  64.         $this->productRepository $productRepository;
  65.         $this->pageMaxRepository $pageMaxRepository;
  66.         $this->configRepository $configRepository->get();
  67.         $this->handleTokenExpiredService $handleTokenExpiredService;
  68.         $this->customGMCProductRepository $customGMCProductRepository;
  69.     }
  70.     /**
  71.      * @Route("/%eccube_admin_route%/custom_gmc/product", name="custom_gmc_admin_product")
  72.      * @Route("/%eccube_admin_route%/custom_gmc/product/page/{page_no}", requirements={"page_no" = "\d+"}, name="custom_gmc_admin_product_page")
  73.      * @Template("@CustomGMC/admin/Product/list.twig")
  74.      */
  75.     public function index(Request $request$page_no nullPaginatorInterface $paginator)
  76.     {
  77.         if (!$this->handleTokenExpiredService->tokenIsValid()) {
  78.             $this->addError('admin.gmc.token_expired''admin');
  79.             return $this->redirectToRoute('custom_gmc_admin_auth');
  80.         }
  81.         $builder $this->formFactory
  82.             ->createBuilder(SearchProductType::class);
  83.         $event = new EventArgs(
  84.             [
  85.                 'builder' => $builder,
  86.             ],
  87.             $request
  88.         );
  89.         $this->eventDispatcher->dispatch($eventEccubeEvents::ADMIN_PRODUCT_INDEX_INITIALIZE);
  90.         $searchForm $builder->getForm();
  91.         /**
  92.          * ページの表示件数は, 以下の順に優先される.
  93.          * - リクエストパラメータ
  94.          * - セッション
  95.          * - デフォルト値
  96.          * また, セッションに保存する際は mtb_page_maxと照合し, 一致した場合のみ保存する.
  97.          **/
  98.         $page_count $this->session->get(
  99.             'eccube.admin.product.search.page_count',
  100.             $this->eccubeConfig->get('eccube_default_page_count')
  101.         );
  102.         $page_count_param = (int) $request->get('page_count');
  103.         $pageMaxis $this->pageMaxRepository->findAll();
  104.         if ($page_count_param) {
  105.             foreach ($pageMaxis as $pageMax) {
  106.                 if ($page_count_param == $pageMax->getName()) {
  107.                     $page_count $pageMax->getName();
  108.                     $this->session->set('eccube.admin.product.search.page_count'$page_count);
  109.                     break;
  110.                 }
  111.             }
  112.         }
  113.         if ('POST' === $request->getMethod()) {
  114.             $searchForm->handleRequest($request);
  115.             if ($searchForm->isValid()) {
  116.                 /**
  117.                  * 検索が実行された場合は, セッションに検索条件を保存する.
  118.                  * ページ番号は最初のページ番号に初期化する.
  119.                  */
  120.                 $page_no 1;
  121.                 $searchData $searchForm->getData();
  122.                 // 検索条件, ページ番号をセッションに保持.
  123.                 $this->session->set('eccube.admin.product.search'FormUtil::getViewData($searchForm));
  124.                 $this->session->set('eccube.admin.product.search.page_no'$page_no);
  125.             } else {
  126.                 // 検索エラーの際は, 詳細検索枠を開いてエラー表示する.
  127.                 return [
  128.                     'searchForm' => $searchForm->createView(),
  129.                     'pagination' => [],
  130.                     'pageMaxis' => $pageMaxis,
  131.                     'page_no' => $page_no,
  132.                     'page_count' => $page_count,
  133.                     'has_errors' => true,
  134.                 ];
  135.             }
  136.         } else {
  137.             if (null !== $page_no || $request->get('resume')) {
  138.                 /*
  139.                  * ページ送りの場合または、他画面から戻ってきた場合は, セッションから検索条件を復旧する.
  140.                  */
  141.                 if ($page_no) {
  142.                     // ページ送りで遷移した場合.
  143.                     $this->session->set('eccube.admin.product.search.page_no', (int) $page_no);
  144.                 } else {
  145.                     // 他画面から遷移した場合.
  146.                     $page_no $this->session->get('eccube.admin.product.search.page_no'1);
  147.                 }
  148.                 $viewData $this->session->get('eccube.admin.product.search', []);
  149.                 $searchData FormUtil::submitAndGetData($searchForm$viewData);
  150.             } else {
  151.                 /**
  152.                  * 初期表示の場合.
  153.                  */
  154.                 $page_no 1;
  155.                 // submit default value
  156.                 $viewData FormUtil::getViewData($searchForm);
  157.                 $searchData FormUtil::submitAndGetData($searchForm$viewData);
  158.                 // セッション中の検索条件, ページ番号を初期化.
  159.                 $this->session->set('eccube.admin.product.search'$viewData);
  160.                 $this->session->set('eccube.admin.product.search.page_no'$page_no);
  161.             }
  162.         }
  163.         $qb $this->customGMCProductRepository->getQueryBuilderBySearchDataForAdmin($searchData);
  164.         $event = new EventArgs(
  165.             [
  166.                 'qb' => $qb,
  167.                 'searchData' => $searchData,
  168.             ],
  169.             $request
  170.         );
  171.         $this->eventDispatcher->dispatch($eventEccubeEvents::ADMIN_PRODUCT_INDEX_SEARCH);
  172.         $pagination $paginator->paginate(
  173.             $qb,
  174.             $page_no,
  175.             $page_count
  176.         );
  177.         return [
  178.             'searchForm' => $searchForm->createView(),
  179.             'pagination' => $pagination,
  180.             'pageMaxis' => $pageMaxis,
  181.             'page_no' => $page_no,
  182.             'page_count' => $page_count,
  183.             'has_errors' => false,
  184.         ];
  185.     }
  186.    
  187.     /**
  188.      * Bulk public action
  189.      *
  190.      * @Route("/%eccube_admin_route%/product/bulk/gmc", name="admin_product_bulk_to_gmc", methods={"POST"})
  191.      *
  192.      * @param Request $request
  193.      * @param ProductStatus $ProductStatus
  194.      *
  195.      * @return RedirectResponse
  196.      */
  197.     public function sendProductsToGMC(Request $requestCacheUtil $cacheUtil)
  198.     {
  199.         $this->isTokenValid();
  200.         if (!$this->handleTokenExpiredService->tokenIsValid()) {
  201.             $this->addError('admin.gmc.token_expired''admin');
  202.             return $this->redirectToRoute('custom_gmc_admin_auth');
  203.         }
  204.         try {
  205.             $url Constants::GOOGLE_SHOPPING_API_URL.$this->configRepository->getMerchantId().'/products';
  206.             // CURL
  207.             $ch curl_init();
  208.             curl_setopt($chCURLOPT_URL,            $url);
  209.             curl_setopt($chCURLOPT_RETURNTRANSFER1);
  210.             curl_setopt($chCURLOPT_HTTPHEADER,     array(
  211.                 'Content-Type: application/json',
  212.                 'Accept: application/json',
  213.                 'Authorization: Bearer ' $this->session->get('gmc_access_token')
  214.             ));
  215.             /** @var Product[] $Products */
  216.             $Products $this->productRepository->findBy(['id' => $request->get('ids')]);            
  217.             foreach ($Products as $key => $Product) {
  218.                 // Update product status to GMC
  219.                 if ($Product->getGMCProductId()) {
  220.                     $url $url.'/'.$Product->getGMCProductId();
  221.                     curl_setopt($chCURLOPT_URL,            $url);
  222.                     $data = array(
  223.                         'title' => $Product->getName(),
  224.                         'description' => $Product->getDescriptionDetail(),
  225.                         'imageLink' => $request->getUriForPath('/html/upload/save_image/'.$Product->getMainFileName()),
  226.                         'price' => array(
  227.                             'value' => $Product->getPrice02Max(),
  228.                             'currency' => 'JPY',
  229.                         ),
  230.                     );
  231.                     curl_setopt($chCURLOPT_CUSTOMREQUEST'PATCH');
  232.                 } else {
  233.                     // Insert product to GMC
  234.                     $data = array(
  235.                         'kind' => "content#product",
  236.                         'title' => $Product->getName(),
  237.                         'description' => $Product->getDescriptionDetail(),
  238.                         "link" => $request->getUriForPath($this->generateUrl('product_detail', ['id' => $Product->getId()])),
  239.                         'offerId' => $Product->getId(),
  240.                         'imageLink' => $request->getUriForPath('/html/upload/save_image/'.$Product->getMainFileName()),
  241.                         'contentLanguage' => 'JA',
  242.                         'targetCountry' => 'JP',
  243.                         'channel' => "online",
  244.                         'availability' => "in stock",
  245.                         'condition' => 'new',
  246.                         'price' => array(
  247.                             'value' => $Product->getPrice02Max(),
  248.                             'currency' => 'JPY',
  249.                         ),
  250.                     );
  251.                     curl_setopt($chCURLOPT_POST,           true);
  252.                 }
  253.                 curl_setopt($chCURLOPT_POSTFIELDS,     json_encode($data)); 
  254.                
  255.                 $result json_decode(curl_exec ($ch));
  256.                
  257.                 if (isset($result->error)) { /* Handle error */
  258.                     $this->addError($result->error->message'admin');
  259.                 } else {
  260.                     if ($result && isset($result->id)) {
  261.                         $Product->setGMCProductId($result->id);
  262.                         $this->productRepository->save($Product);
  263.                         $this->entityManager->flush();
  264.                         $this->addSuccess('admin.gmc.send_product.success''admin');
  265.                     }
  266.                     $cacheUtil->clearDoctrineCache();
  267.                 }
  268.             }
  269.         } catch (\Exception $e) {
  270.             $this->addError($e->getMessage(), 'admin');
  271.         }
  272.         return $this->redirectToRoute('custom_gmc_admin_product');
  273.     }
  274.    
  275.     /**
  276.      * Bulk public action
  277.      *
  278.      * @Route("/%eccube_admin_route%/product/bulk/gmc/{id}/delete", name="admin_product_bulk_delete_to_gmc", methods={"DELETE"})
  279.      *
  280.      * @param Request $request
  281.      * @param ProductStatus $ProductStatus
  282.      *
  283.      * @return RedirectResponse
  284.      */
  285.     public function bulkDeleteProducts(Request $request$id nullCacheUtil $cacheUtil)
  286.     {
  287.         $this->isTokenValid();
  288.         if (!$this->handleTokenExpiredService->tokenIsValid()) {
  289.             $this->addError('admin.gmc.token_expired''admin');
  290.             return $this->redirectToRoute('custom_gmc_admin_auth');
  291.         }
  292.         try {
  293.             $url Constants::GOOGLE_SHOPPING_API_URL.$this->configRepository->getMerchantId().'/products';
  294.             // CURL
  295.             $ch curl_init();
  296.             curl_setopt($chCURLOPT_RETURNTRANSFER1);
  297.             curl_setopt($chCURLOPT_HTTPHEADER,     array(
  298.                 'Content-Type: application/json',
  299.                 'Accept: application/json',
  300.                 'Authorization: Bearer ' $this->session->get('gmc_access_token')
  301.             ));
  302.             /** @var Product[] $Products */
  303.             $Product $this->productRepository->find($id);            
  304.             // Update product status to GMC
  305.             $result null;                        
  306.             $success true;
  307.             $message '';
  308.             if ($Product->getGMCProductId()) {
  309.                 $url $url.'/'.$Product->getGMCProductId();
  310.                 curl_setopt($chCURLOPT_URL,            $url);
  311.                 curl_setopt($chCURLOPT_CUSTOMREQUEST'DELETE');
  312.                 $result json_decode(curl_exec ($ch));
  313.                 
  314.                 if (isset($result->error)) { /* Handle error */
  315.                     $message $result->error->message;
  316.                     $success false;
  317.                     $this->addError($result->error->message'admin');
  318.                 } else {
  319.                     $Product->setGMCProductId('');
  320.                     $this->productRepository->save($Product);
  321.                     $this->entityManager->flush();
  322.                     $this->addSuccess('admin.gmc.delete_product.success''admin');
  323.                     $cacheUtil->clearDoctrineCache();
  324.                 }
  325.             } else {
  326.                 $success false;
  327.                 $message trans('admin.gmc.delete_product.not_found');
  328.                 $this->addError('admin.gmc.delete_product.not_found''admin');
  329.             }
  330.         } catch (\Exception $e) {
  331.             $success false;
  332.             $message $e->getMessage();
  333.         }
  334.         return $this->json(['success' => $success'message' => $message]);
  335.     }
  336. }