From 386bf175d570773101ccb82e4df2cc1123f6ae82 Mon Sep 17 00:00:00 2001 From: lammn Date: Wed, 19 Oct 2016 17:21:34 +0700 Subject: [PATCH 01/63] commit for renew this plugin --- .travis.yml | 89 +++++++ Controller/Admin/RelatedProductController.php | 80 +++--- Event.php | 227 +++++------------ EventLegacy.php | 239 ++++++++++++++++++ Form/Type/Admin/RelatedProductType.php | 46 +++- LICENSE.txt => LICENSE | 0 Migration/Version20150808173000.php | 42 --- PluginManager.php | 84 +++++- Repository/RelatedProductRepository.php | 6 +- Resource/assets/css/relatedproduct.css | 1 + Resource/config/constant.yml | 1 + Resource/config/path.yml | 4 + .../migration/Version20150808173000.php | 133 ++++++++++ Resource/locale/message.ja.yml | 1 + Resource/template/Admin/modal_result.twig | 42 --- Resource/template/Admin/related_product.twig | 63 ----- Resource/template/{Admin => admin}/modal.twig | 25 +- Resource/template/admin/modal_result.twig | 75 ++++++ Resource/template/admin/related_product.twig | 86 +++++++ .../{Front => front}/related_product.twig | 2 +- Service/RelatedProductService.php | 49 ++++ .../RelatedProductServiceProvider.php | 79 +++++- appveyor.yml | 78 ++++++ config.yml | 4 +- event.yml | 13 +- 25 files changed, 1088 insertions(+), 381 deletions(-) create mode 100644 .travis.yml create mode 100644 EventLegacy.php rename LICENSE.txt => LICENSE (100%) delete mode 100644 Migration/Version20150808173000.php create mode 100644 Resource/assets/css/relatedproduct.css create mode 100644 Resource/config/constant.yml create mode 100644 Resource/config/path.yml create mode 100644 Resource/doctrine/migration/Version20150808173000.php create mode 100644 Resource/locale/message.ja.yml delete mode 100644 Resource/template/Admin/modal_result.twig delete mode 100644 Resource/template/Admin/related_product.twig rename Resource/template/{Admin => admin}/modal.twig (77%) create mode 100644 Resource/template/admin/modal_result.twig create mode 100644 Resource/template/admin/related_product.twig rename Resource/template/{Front => front}/related_product.twig (92%) create mode 100644 appveyor.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..90a26fb --- /dev/null +++ b/.travis.yml @@ -0,0 +1,89 @@ +language: php + +sudo: false + +cache: + directories: + - $HOME/.composer/cache + +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - 7.0 + +env: + # plugin code + global: + PLUGIN_CODE=RelatedProduct + matrix: + # ec-cube master + - ECCUBE_VERSION=master DB=mysql USER=root DBNAME=myapp_test DBPASS=' ' DBUSER=root + - ECCUBE_VERSION=master DB=pgsql USER=postgres DBNAME=myapp_test DBPASS=password DBUSER=postgres + - ECCUBE_VERSION=master DB=sqlite + # ec-cube 3.0.9 + - ECCUBE_VERSION=3.0.9 DB=mysql USER=root DBNAME=myapp_test DBPASS=' ' DBUSER=root + - ECCUBE_VERSION=3.0.9 DB=pgsql USER=postgres DBNAME=myapp_test DBPASS=password DBUSER=postgres + # ec-cube 3.0.10 + - ECCUBE_VERSION=3.0.10 DB=mysql USER=root DBNAME=myapp_test DBPASS=' ' DBUSER=root + - ECCUBE_VERSION=3.0.10 DB=pgsql USER=postgres DBNAME=myapp_test DBPASS=password DBUSER=postgres +matrix: + fast_finish: true + include: + exclude: + allow_failures: + - php: 5.3 + env: ECCUBE_VERSION=master DB=sqlite + - php: 5.4 + env: ECCUBE_VERSION=master DB=sqlite + - php: 5.5 + env: ECCUBE_VERSION=master DB=sqlite + - php: 5.6 + env: ECCUBE_VERSION=master DB=sqlite + - php: 7.0 + env: ECCUBE_VERSION=master DB=sqlite + - php: 7.0 + env: ECCUBE_VERSION=3.0.9 DB=mysql USER=root DBNAME=myapp_test DBPASS=' ' DBUSER=root + - php: 7.0 + env: ECCUBE_VERSION=3.0.9 DB=pgsql USER=postgres DBNAME=myapp_test DBPASS=password DBUSER=postgres + - php: 7.0 + env: ECCUBE_VERSION=3.0.10 DB=mysql USER=root DBNAME=myapp_test DBPASS=' ' DBUSER=root + - php: 7.0 + env: ECCUBE_VERSION=3.0.10 DB=pgsql USER=postgres DBNAME=myapp_test DBPASS=password DBUSER=postgres + +install: + - gem install mime-types -v 2.99.1 + - gem install mailcatcher + +before_script: + # archive plugin + - tar cvzf ${HOME}/${PLUGIN_CODE}.tar.gz ./* + # clone ec-cube + - git clone https://github.com/EC-CUBE/ec-cube.git + - cd ec-cube + # checkout version + - sh -c "if [ ! '${ECCUBE_VERSION}' = 'master' ]; then git checkout -b ${ECCUBE_VERSION} refs/tags/${ECCUBE_VERSION}; fi" + # update composer + - composer selfupdate + - composer install --dev --no-interaction -o + # install ec-cube + - sh -c "if [ '$DB' = 'mysql' ]; then sh ./eccube_install.sh mysql none; fi" + - sh -c "if [ '$DB' = 'pgsql' ]; then sh ./eccube_install.sh pgsql none; fi" + - sh -c "if [ '$DB' = 'sqlite' ]; then sh ./eccube_install.sh sqlite3 none; fi" + # install plugin + - php app/console plugin:develop install --path=${HOME}/${PLUGIN_CODE}.tar.gz + # enable plugin + - php app/console plugin:develop enable --code=${PLUGIN_CODE} + # mail catcher + - mailcatcher + +script: + # exec phpunit on ec-cube + - phpunit app/Plugin/${PLUGIN_CODE}/Tests + +after_script: + # disable plugin + - php app/console plugin:develop disable --code=${PLUGIN_CODE} + # uninstall plugin + - php app/console plugin:develop uninstall --code=${PLUGIN_CODE} --uninstall-force=true \ No newline at end of file diff --git a/Controller/Admin/RelatedProductController.php b/Controller/Admin/RelatedProductController.php index 31c262f..f1c00bc 100644 --- a/Controller/Admin/RelatedProductController.php +++ b/Controller/Admin/RelatedProductController.php @@ -11,14 +11,30 @@ namespace Plugin\RelatedProduct\Controller\Admin; +use Doctrine\Common\Collections\ArrayCollection; use Eccube\Application; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception as HttpException; class RelatedProductController { - public function searchProduct(Application $app, Request $request) + /** + * @param Application $app + * @param Request $request + * @param integer $page_no + * @return \Symfony\Component\HttpFoundation\Response + */ + public function searchProduct(Application $app, Request $request, $page_no = null) { - if ($request->isXmlHttpRequest()) { + if (!$request->isXmlHttpRequest()) { + return null; + } + + $app['monolog']->addDebug('search product start.'); + $pageCount = $app['config']['default_page_count']; + $session = $app['session']; + if ('POST' === $request->getMethod()) { + $page_no = 1; $searchData = array( 'id' => $request->get('id'), ); @@ -26,41 +42,39 @@ public function searchProduct(Application $app, Request $request) $Category = $app['eccube.repository.category']->find($categoryId); $searchData['category_id'] = $Category; } - - /** @var $Products \Eccube\Entity\Product[] */ - $Products = $app['eccube.repository.product'] - ->getQueryBuilderBySearchDataForAdmin($searchData) - ->getQuery() - ->getResult(); - - // 表示されている商品は検索結果に含めない - $productId = $request->get('product_id'); - $ProductsData = array(); - $count = count($Products); - $i = 0; - for($i = 0; $i < $count; $i++) { - $Product = $Products[$i]; - if ($Product->getId() != $productId) { - $ProductsData[] = $Product; - } - if ($i >= 10) { - break; - } + $session->set('eccube.plugin.related_product.product.search', $searchData); + $session->set('eccube.plugin.related_product.product.search.page_no', $page_no); + } else { + $searchData = (array)$session->get('eccube.plugin.related_product.product.search'); + if (is_null($page_no)) { + $page_no = intval($session->get('eccube.plugin.related_product.product.search.page_no')); + } else { + $session->set('eccube.plugin.related_product.product.search.page_no', $page_no); } + } - $message = ''; - if ($count > $i) { - $message = '検索結果の上限を超えています。検索条件を設定してください。'; - } + $qb = $app['eccube.repository.product']->getQueryBuilderBySearchDataForAdmin($searchData); - return $app->renderView( - 'RelatedProduct/Resource/template/Admin/modal_result.twig', - array( - 'Products' => $ProductsData, - 'message' => $message, - ) - ); + /** @var \Knp\Component\Pager\Pagination\SlidingPagination $pagination */ + $pagination = $app['paginator']()->paginate( + $qb, + $page_no, + $pageCount, + array('wrap-queries' => true) + ); + /** @var ArrayCollection */ + $arrProduct = $pagination->getItems(); + if (count($arrProduct) == 0) { + $app['monolog']->addDebug('search product not found.'); } + + $paths = array(); + $paths[] = $app['config']['template_admin_realdir']; + $app['twig.loader']->addLoader(new \Twig_Loader_Filesystem($paths)); + + return $app->render('RelatedProduct/Resource/template/admin/modal_result.twig', array( + 'pagination' => $pagination + )); } } \ No newline at end of file diff --git a/Event.php b/Event.php index e33ed74..bc553be 100644 --- a/Event.php +++ b/Event.php @@ -8,208 +8,103 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace Plugin\RelatedProduct; - -use Symfony\Component\DomCrawler\Crawler; +use Eccube\Common\Constant; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; -use Symfony\Component\HttpFoundation\RedirectResponse; class Event { + /** + * @var $app + */ private $app; + /** + * @var $legacyEvent + */ + private $legacyEvent; + + /** + * Event constructor. + * @param $app + */ public function __construct($app) { $this->app = $app; + $this->legacyEvent = new EventLegacy($app); } // フロント:商品詳細画面に関連商品を表示 + /** + * @param FilterResponseEvent $event + */ public function showRelatedProduct(FilterResponseEvent $event) { - $app = $this->app; - - $id = $app['request']->attributes->get('id'); - $Product = $app['eccube.repository.product']->find($id); - $RelatedProducts = $app['eccube.plugin.repository.related_product']->findBy(array('Product' => $Product)); - - if (count($RelatedProducts) > 0) { - $twig = $app->renderView( - 'RelatedProduct/Resource/template/Front/related_product.twig', - array( - 'RelatedProducts' => $RelatedProducts, - ) - ); - - $response = $event->getResponse(); - - if ($response instanceof RedirectResponse) { - return; - } - - $html = $response->getContent(); - $crawler = new Crawler($html); - - $oldHtml = $crawler->filter('#main')->html(); - $oldHtml = html_entity_decode($oldHtml, ENT_NOQUOTES, 'UTF-8'); - $newHtml = $oldHtml.$twig; - - $html = $this->getHtml($crawler); - $html = str_replace($oldHtml, $newHtml, $html); - - $response->setContent($html); - $event->setResponse($response); + if ($this->supportNewHookPoint()) { + return; } + $this->legacyEvent->showRelatedProduct($event); } + /** + * new hookpoint for save related product + * @param FilterResponseEvent $event + */ public function registerRelatedProduct(FilterResponseEvent $event) { - $app = $this->app; - if (!$app->isGranted('ROLE_ADMIN')) { + if ($this->supportNewHookPoint()) { return; } - - if ('POST' === $app['request']->getMethod()) { - // ProductControllerの登録成功時のみ処理を通す - // RedirectResponseかどうかで判定する. - $response = $event->getResponse(); - if (!$response instanceof RedirectResponse) { - return; - } - /* @var $Product \Eccube\Entity\Product */ - $Product = $this->getTargetProduct($event); - $builder = $app['form.factory']->createBuilder('admin_product'); - - if ($Product->hasProductClass()) { - $builder->remove('class'); - } - - $form = $builder->getForm(); - $form->handleRequest($app['request']); - - if ($form->isValid()) { - $app['eccube.plugin.repository.related_product']->removeChildProduct($Product); - $app['orm.em']->flush(); - - $RelatedProducts = $form->get('related_collection')->getData(); - foreach ($RelatedProducts as $RelatedProduct) { - /* @var $RelatedProduct \Plugin\RelatedProduct\Entity\RelatedProduct */ - if ($RelatedProduct->getChildProduct() instanceof \Eccube\Entity\Product) { - $RelatedProduct->setProduct($Product); - $app['orm.em']->persist($RelatedProduct); - } - } - $app['orm.em']->flush(); - } - } - } - - private function getTargetProduct($event) - { - $request = $event->getRequest(); - $response = $event->getResponse(); - if ($request->attributes->get('id')) { - $id = $request->attributes->get('id'); - } else { - $location = explode('/', $response->headers->get('location')); - $url = explode('/', $this->app->url('admin_product_product_edit', array('id' => '0'))); - $diffs = array_values(array_diff($location, $url)); - $id = $diffs[0]; - } - - $Product = $this->app['eccube.repository.product']->find($id); - - return $Product; + $this->legacyEvent->registerRelatedProduct($event); } + /** + * new hookpoint for add RelatedProduct to product edit + * @param FilterResponseEvent $event + */ public function addContentOnProductEdit(FilterResponseEvent $event) { - $app = $this->app; - if (!$app->isGranted('ROLE_ADMIN')) { + if ($this->supportNewHookPoint()) { return; } - $request = $event->getRequest(); - $response = $event->getResponse(); - $id = $request->attributes->get('id'); - - $html = $response->getContent(); - $crawler = new Crawler($html); - - $form = $app['form.factory'] - ->createBuilder('admin_product') - ->getForm(); - - if ($id) { - $Product = $app['eccube.repository.product']->find($id); - } else { - $Product = new \Eccube\Entity\Product(); - } - - $RelatedProducts = $app['eccube.plugin.repository.related_product']->findBy( - array( - 'Product' => $Product, - )); - - $loop = 5 - count($RelatedProducts); - for ($i = 0; $i < $loop; $i++) { - $RelatedProduct = new \Plugin\RelatedProduct\Entity\RelatedProduct(); - $RelatedProduct - ->setProductId($id) - ->setProduct($Product); - $RelatedProducts[] = $RelatedProduct; - } - $form->get('related_collection')->setData($RelatedProducts); - - $form->handleRequest($request); - - // 商品検索フォーム - $searchForm = $app['form.factory'] - ->createBuilder('admin_search_product') - ->getForm(); + $this->legacyEvent->addContentOnProductEdit($event); + } - $twig = $app->renderView( - 'RelatedProduct/Resource/template/Admin/related_product.twig', - array( - 'form' => $form->createView(), - ) - ); - $modal = $app->renderView( - 'RelatedProduct/Resource/template/Admin/modal.twig', - array( - 'searchForm' => $searchForm->createView(), - 'Product' => $Product, - ) - ); - $oldElement = $crawler - ->filter('.accordion') - ->last(); - if ($oldElement->count() > 0) { - $oldHtml = $oldElement->html(); - $newHtml = $oldHtml.$twig; + // フロント:商品詳細画面に関連商品を表示 + /** + * @param FilterResponseEvent $event + */ + public function onProductDetailRender(FilterResponseEvent $event) + { + $this->legacyEvent->showRelatedProduct($event); + } - $html = $this->getHtml($crawler); - $html = $html.$modal; - $html = str_replace($oldHtml, $newHtml, $html); + /** + * new hookpoint for add RelatedProduct to product edit + * @param FilterResponseEvent $event + */ + public function onProductEditRender(FilterResponseEvent $event) + { + $this->legacyEvent->addContentOnProductEdit($event); + } - $response->setContent($html); - $event->setResponse($response); - } + /** + * new hookpoint for save related product + * @param FilterResponseEvent $event + */ + public function onProductEditRegister(FilterResponseEvent $event) + { + $this->legacyEvent->registerRelatedProduct($event); } /** - * 解析用HTMLを取得 + * v3.0.9以降のフックポイントに対応しているのか * - * @param Crawler $crawler - * @return string + * @return bool */ - private function getHtml(Crawler $crawler) + private function supportNewHookPoint() { - $html = ''; - foreach ($crawler as $domElement) { - $domElement->ownerDocument->formatOutput = true; - $html .= $domElement->ownerDocument->saveHTML(); - } - return html_entity_decode($html, ENT_NOQUOTES, 'UTF-8'); + return version_compare('3.0.9', Constant::VERSION, '<='); } -} +} \ No newline at end of file diff --git a/EventLegacy.php b/EventLegacy.php new file mode 100644 index 0000000..41fa17d --- /dev/null +++ b/EventLegacy.php @@ -0,0 +1,239 @@ +app = $app; + } + + /** + * フロント:商品詳細画面に関連商品を表示 + * @param FilterResponseEvent $event + */ + public function showRelatedProduct(FilterResponseEvent $event) + { + $app = $this->app; + + $id = $app['request']->attributes->get('id'); + $Product = $app['eccube.repository.product']->find($id); + $RelatedProducts = $app['eccube.plugin.repository.related_product']->findBy(array('Product' => $Product)); + + if (count($RelatedProducts) > 0) { + $twig = $app->renderView( + 'RelatedProduct/Resource/template/Front/related_product.twig', + array( + 'RelatedProducts' => $RelatedProducts, + ) + ); + + $response = $event->getResponse(); + + if ($response instanceof RedirectResponse) { + return; + } + + $html = $response->getContent(); + $crawler = new Crawler($html); + + $oldHtml = $crawler->filter('#main')->html(); + $oldHtml = html_entity_decode($oldHtml, ENT_NOQUOTES, 'UTF-8'); + $newHtml = $oldHtml.$twig; + + $html = $this->getHtml($crawler); + $html = str_replace($oldHtml, $newHtml, $html); + + $response->setContent($html); + $event->setResponse($response); + } + } + + /** + * save related product + * @param FilterResponseEvent $event + */ + public function registerRelatedProduct(FilterResponseEvent $event) + { + $app = $this->app; + if (!$app->isGranted('ROLE_ADMIN')) { + return; + } + + if ('POST' === $app['request']->getMethod()) { + // ProductControllerの登録成功時のみ処理を通す + // RedirectResponseかどうかで判定する. + $response = $event->getResponse(); + if (!$response instanceof RedirectResponse) { + return; + } + /* @var $Product \Eccube\Entity\Product */ + $Product = $this->getTargetProduct($event); + $builder = $app['form.factory']->createBuilder('admin_product'); + + if ($Product->hasProductClass()) { + $builder->remove('class'); + } + + $form = $builder->getForm(); + $form->handleRequest($app['request']); + + if ($form->isValid()) { + $app['eccube.plugin.repository.related_product']->removeChildProduct($Product); + $app['orm.em']->flush(); + + $RelatedProducts = $form->get('related_collection')->getData(); + foreach ($RelatedProducts as $RelatedProduct) { + /* @var $RelatedProduct \Plugin\RelatedProduct\Entity\RelatedProduct */ + if ($RelatedProduct->getChildProduct() instanceof Product) { + $RelatedProduct->setProduct($Product); + $app['orm.em']->persist($RelatedProduct); + } + } + $app['orm.em']->flush(); + } + } + } + + /** + * getTargetProduct + * @param $event + * @return $Product + */ + private function getTargetProduct($event) + { + $request = $event->getRequest(); + $response = $event->getResponse(); + if ($request->attributes->get('id')) { + $id = $request->attributes->get('id'); + } else { + $location = explode('/', $response->headers->get('location')); + $url = explode('/', $this->app->url('admin_product_product_edit', array('id' => '0'))); + $diffs = array_values(array_diff($location, $url)); + $id = $diffs[0]; + } + + $Product = $this->app['eccube.repository.product']->find($id); + + return $Product; + } + + /** + * add RelatedProduct to product edit + * @param FilterResponseEvent $event + */ + public function addContentOnProductEdit(FilterResponseEvent $event) + { + $app = $this->app; + if (!$app->isGranted('ROLE_ADMIN')) { + return; + } + $request = $event->getRequest(); + $response = $event->getResponse(); + $id = $request->attributes->get('id'); + + $html = $response->getContent(); + $crawler = new Crawler($html); + + $form = $app['form.factory'] + ->createBuilder('admin_product') + ->getForm(); + + if ($id) { + $Product = $app['eccube.repository.product']->find($id); + } else { + $Product = new Product(); + } + + $RelatedProducts = $app['eccube.plugin.repository.related_product']->findBy( + array( + 'Product' => $Product, + )); + + $loop = 5 - count($RelatedProducts); + for ($i = 0; $i < $loop; $i++) { + $RelatedProduct = new RelatedProduct(); + $RelatedProduct + ->setProductId($id) + ->setProduct($Product); + $RelatedProducts[] = $RelatedProduct; + } + $form->get('related_collection')->setData($RelatedProducts); + + $form->handleRequest($request); + + // 商品検索フォーム + $searchForm = $app['form.factory'] + ->createBuilder('admin_search_product') + ->getForm(); + + $twig = $app->renderView( + 'RelatedProduct/Resource/template/Admin/related_product.twig', + array( + 'form' => $form->createView(), + 'RelatedProducts' => $RelatedProducts + ) + ); + $modal = $app->renderView( + 'RelatedProduct/Resource/template/Admin/modal.twig', + array( + 'searchForm' => $searchForm->createView(), + 'Product' => $Product, + ) + ); + $oldElement = $crawler + ->filter('.accordion') + ->last(); + if ($oldElement->count() > 0) { + //fix bug input html tag or special character code + $oldHtml = html_entity_decode($oldElement->html(), ENT_NOQUOTES, 'UTF-8'); + $newHtml = $oldHtml.$twig; + + $html = $this->getHtml($crawler); + $html = $html.$modal; + $html = str_replace($oldHtml, $newHtml, $html); + + $response->setContent($html); + $event->setResponse($response); + } + } + + /** + * 解析用HTMLを取得 + * + * @param Crawler $crawler + * @return string html + */ + private function getHtml(Crawler $crawler) + { + $html = ''; + foreach ($crawler as $domElement) { + $domElement->ownerDocument->formatOutput = true; + $html .= $domElement->ownerDocument->saveHTML(); + } + return html_entity_decode($html, ENT_NOQUOTES, 'UTF-8'); + } + +} diff --git a/Form/Type/Admin/RelatedProductType.php b/Form/Type/Admin/RelatedProductType.php index 78f1192..f27baef 100644 --- a/Form/Type/Admin/RelatedProductType.php +++ b/Form/Type/Admin/RelatedProductType.php @@ -11,16 +11,36 @@ namespace Plugin\RelatedProduct\Form\Type\Admin; -use \Symfony\Component\Form\AbstractType; -use \Symfony\Component\Form\Extension\Core\Type; -use \Symfony\Component\Form\FormBuilderInterface; -use \Symfony\Component\Validator\Constraints as Assert; -use \Symfony\Component\OptionsResolver\OptionsResolverInterface; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Validator\Constraints as Assert; + class RelatedProductType extends AbstractType { + /** + * @var \Eccube\Application + */ + private $app; + + /** + * RelatedProductType constructor. + * @param $app + */ + public function __construct($app) + { + $this->app = $app; + } + + /** + * RelatedProduct form builder + * @param FormBuilderInterface $builder + * @param array $options + */ public function buildForm(FormBuilderInterface $builder, array $options) { + $app = $this->app; $builder ->add('Product', 'entity', array( 'class' => 'Eccube\Entity\Product', @@ -35,14 +55,24 @@ public function buildForm(FormBuilderInterface $builder, array $options) ->add('content', 'textarea', array( 'label' => '説明文', 'required' => false, + 'trim' => true, + 'constraints' => array( + new Assert\Length(array( + 'max' => $app['config']['text_area_len'], + )), + ), + 'attr' => array( + 'maxlength' => $app['config']['text_area_len'], + 'placeholder' => $app->trans('plugin.related_product.type.comment.placeholder')), )) ; } /** * {@inheritdoc} + * @param OptionsResolver $resolver */ - public function setDefaultOptions(OptionsResolverInterface $resolver) + public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Plugin\RelatedProduct\Entity\RelatedProduct', @@ -50,6 +80,10 @@ public function setDefaultOptions(OptionsResolverInterface $resolver) } + /** + * form name + * @return string + */ public function getName() { return 'admin_related_product'; diff --git a/LICENSE.txt b/LICENSE similarity index 100% rename from LICENSE.txt rename to LICENSE diff --git a/Migration/Version20150808173000.php b/Migration/Version20150808173000.php deleted file mode 100644 index 245601e..0000000 --- a/Migration/Version20150808173000.php +++ /dev/null @@ -1,42 +0,0 @@ -createRelatedProductTable($schema); - } - - public function down(Schema $schema) - { - $schema->dropTable('plg_related_product'); - } - - protected function createRelatedProductTable(Schema $schema) - { - $table = $schema->createTable("plg_related_product"); - $table->addColumn('id', 'integer', array('autoincrement' => true)); - $table->addColumn('product_id', 'integer'); - $table->addColumn('child_product_id', 'integer'); - $table->addColumn('content', 'text', array( - 'notnull' => false, - )) - ; - $table->setPrimaryKey(array('id')); - } -} diff --git a/PluginManager.php b/PluginManager.php index 52b5065..4b97dd4 100644 --- a/PluginManager.php +++ b/PluginManager.php @@ -12,29 +12,109 @@ namespace Plugin\RelatedProduct; use Eccube\Plugin\AbstractPluginManager; +use Symfony\Component\Filesystem\Filesystem; class PluginManager extends AbstractPluginManager { + /** + * @var string コピー元リソースディレクトリ + */ + private $origin; + + /** + * @var string コピー先リソースディレクトリ + */ + private $target; + + /** + * PluginManager constructor. + */ + public function __construct() + { + // コピー元のディレクトリ + $this->origin = __DIR__.'/Resource/assets'; + // コピー先のディレクトリ + $this->target = __DIR__ . '/../../../html/plugin/relatedproduct'; + } + + /** + * プラグインインストール時の処理 + * + * @param $config + * @param $app + * @throws \Exception + */ public function install($config, $app) { - $this->migrationSchema($app, __DIR__ . '/Migration', $config['code']); + // リソースファイルのコピー + $this->copyAssets($app); } + /** + * プラグイン削除時の処理 + * + * @param $config + * @param $app + */ public function uninstall($config, $app) { - $this->migrationSchema($app, __DIR__ . '/Migration', $config['code'], 0); + $this->migrationSchema($app, __DIR__.'/Resource/doctrine/migration', $config['code'], 0); + // リソースファイルの削除 + $this->removeAssets($app); } + /** + * プラグイン有効時の処理 + * + * @param $config + * @param $app + * @throws \Exception + */ public function enable($config, $app) { + $this->migrationSchema($app, __DIR__.'/Resource/doctrine/migration', $config['code']); } + /** + * プラグイン無効時の処理 + * + * @param $config + * @param $app + */ public function disable($config, $app) { } + /** + * プラグイン更新時の処理 + * @param $config + * @param $app + */ public function update($config, $app) { + $this->migrationSchema($app, __DIR__.'/Resource/doctrine/migration', $config['code'], 0); + } + + /** + * リソースファイル等をコピー + * + * @param $app + */ + private function copyAssets($app) + { + $file = new Filesystem(); + $file->mirror($this->origin, $this->target.'/assets'); + } + + /** + * コピーしたリソースファイルなどを削除 + * + * @param $app + */ + private function removeAssets($app) + { + $file = new Filesystem(); + $file->remove($this->target); } } \ No newline at end of file diff --git a/Repository/RelatedProductRepository.php b/Repository/RelatedProductRepository.php index 45364ae..478972e 100644 --- a/Repository/RelatedProductRepository.php +++ b/Repository/RelatedProductRepository.php @@ -14,13 +14,17 @@ use Doctrine\ORM\EntityRepository; /** - * CategoryTotalCountRepository + * RelatedProductRepository * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. */ class RelatedProductRepository extends EntityRepository { + /** + * 子商品の削除 + * @param $Product + */ public function removeChildProduct($Product) { $em = $this->getEntityManager(); diff --git a/Resource/assets/css/relatedproduct.css b/Resource/assets/css/relatedproduct.css new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Resource/assets/css/relatedproduct.css @@ -0,0 +1 @@ + diff --git a/Resource/config/constant.yml b/Resource/config/constant.yml new file mode 100644 index 0000000..626adb7 --- /dev/null +++ b/Resource/config/constant.yml @@ -0,0 +1 @@ +text_area_len: 4000 diff --git a/Resource/config/path.yml b/Resource/config/path.yml new file mode 100644 index 0000000..3621596 --- /dev/null +++ b/Resource/config/path.yml @@ -0,0 +1,4 @@ +# urlpath +relatedproduct_path: /relatedproduct +relatedproduct_assetspath: /relatedproduct/assets +relatedproduct_img_urlpath: /relatedproduct/assets/img diff --git a/Resource/doctrine/migration/Version20150808173000.php b/Resource/doctrine/migration/Version20150808173000.php new file mode 100644 index 0000000..d9bdac8 --- /dev/null +++ b/Resource/doctrine/migration/Version20150808173000.php @@ -0,0 +1,133 @@ +=')) { + $this->createRelatedProductTable($schema); + } else { + $this->createRelatedProductTableForOldVersion($schema); + } + } + + /** + * remove table + * + * @param Schema $schema + */ + public function down(Schema $schema) + { + if (version_compare(Constant::VERSION, '3.0.9', '>=')) { + $app = Application::getInstance(); + $meta = $this->getMetadata($app['orm.em']); + $tool = new SchemaTool($app['orm.em']); + $schemaFromMetadata = $tool->getSchemaFromMetadata($meta); + // テーブル削除 + foreach ($schemaFromMetadata->getTables() as $table) { + if ($schema->hasTable($table->getName())) { + $schema->dropTable($table->getName()); + } + } + // シーケンス削除 + foreach ($schemaFromMetadata->getSequences() as $sequence) { + if ($schema->hasSequence($sequence->getName())) { + $schema->dropSequence($sequence->getName()); + } + } + } else { + // this down() migration is auto-generated, please modify it to your needs + $schema->dropTable(self::NAME); + $schema->dropSequence('plg_related_product_related_product_id_seq'); + } + } + + /** + * create related product table for version < 3.0.9 + * + * @param Schema $schema + */ + protected function createRelatedProductTableForOldVersion(Schema $schema) + { + $table = $schema->createTable("plg_related_product"); + $table->addColumn('id', 'integer', array('autoincrement' => true)); + $table->addColumn('product_id', 'integer'); + $table->addColumn('child_product_id', 'integer'); + $table->addColumn('content', 'text', array( + 'notnull' => false, + )) + ; + $table->setPrimaryKey(array('id')); + } + + /** + * create related product table for version > 3.0.9 + * + * @param Schema $schema + * @return true + */ + protected function createRelatedProductTable(Schema $schema) + { + if ($schema->hasTable(self::NAME)) { + return true; + } + + $app = Application::getInstance(); + $em = $app['orm.em']; + $classes = array( + $em->getClassMetadata('Plugin\RelatedProduct\Entity\RelatedProduct'), + ); + $tool = new SchemaTool($em); + $tool->createSchema($classes); + + return true; + } + + /** + * Get metadata + * + * @param EntityManager $em + * @return array + */ + protected function getMetadata(EntityManager $em) + { + $meta = array(); + foreach ($this->entities as $entity) { + $meta[] = $em->getMetadataFactory()->getMetadataFor($entity); + } + + return $meta; + } +} diff --git a/Resource/locale/message.ja.yml b/Resource/locale/message.ja.yml new file mode 100644 index 0000000..9829d94 --- /dev/null +++ b/Resource/locale/message.ja.yml @@ -0,0 +1 @@ +plugin.related_product.type.comment.placeholder: 説明文を入力してください(HTMLタグ使用可)。 \ No newline at end of file diff --git a/Resource/template/Admin/modal_result.twig b/Resource/template/Admin/modal_result.twig deleted file mode 100644 index 340305f..0000000 --- a/Resource/template/Admin/modal_result.twig +++ /dev/null @@ -1,42 +0,0 @@ -{# - This file is part of EC-CUBE - - Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved. - http://www.lockon.co.jp/ - - For the full copyright and license information, please view the LICENSE - file that was distributed with this source code. -#} - -{% if message is not empty %} -

{{ message }}

-{% endif %} -
- - - - {% for Product in Products %} - - - - - - - {% endfor %} - - -
- {{ Product.name }} - {% if Product.hasProductClass %} -
{{ Product.code_min }}~{{ Product.code_max }}
- {% else %} -
{{ Product.code_min }}
- {% endif %} -
- -
-
diff --git a/Resource/template/Admin/related_product.twig b/Resource/template/Admin/related_product.twig deleted file mode 100644 index 3bf930f..0000000 --- a/Resource/template/Admin/related_product.twig +++ /dev/null @@ -1,63 +0,0 @@ -{# - This file is part of EC-CUBE - - Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved. - http://www.lockon.co.jp/ - - For the full copyright and license information, please view the LICENSE - file that was distributed with this source code. -#} - -{% block javascript %} - -{% endblock javascript %} - - -
- - -
-
-

- {{ form.related_collection.vars.label }} - -

-
-
- - {% for child in form.related_collection %} -
- {{ form_label(child.ChildProduct) }} - - - {{ form_widget(child.ChildProduct, { attr: { style: 'display: none' } }) }} - {% if child.vars.value.id is not null %} - - {% endif %} -
-
- {{ form_label(child.content) }} -
- {{ form_widget(child.content) }} -
-
- {% endfor %} - -
-
diff --git a/Resource/template/Admin/modal.twig b/Resource/template/admin/modal.twig similarity index 77% rename from Resource/template/Admin/modal.twig rename to Resource/template/admin/modal.twig index d9a00a9..4578f10 100644 --- a/Resource/template/Admin/modal.twig +++ b/Resource/template/admin/modal.twig @@ -11,17 +11,13 @@ {% form_theme searchForm 'Form/bootstrap_3_horizontal_layout.html.twig' %} \ No newline at end of file +
diff --git a/appveyor.yml b/appveyor.yml index 5cd97b7..8cc0981 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -76,3 +76,6 @@ before_test: test_script: - vendor\bin\phpunit.bat app/Plugin/%PLUGIN_CODE%/Tests + + + From fe823b5d01d623bac72211cff35777407dbff808 Mon Sep 17 00:00:00 2001 From: lammn Date: Thu, 27 Oct 2016 17:05:16 +0700 Subject: [PATCH 19/63] fix end of file --- .travis.yml | 2 +- appveyor.yml | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 90a26fb..73bc4ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -86,4 +86,4 @@ after_script: # disable plugin - php app/console plugin:develop disable --code=${PLUGIN_CODE} # uninstall plugin - - php app/console plugin:develop uninstall --code=${PLUGIN_CODE} --uninstall-force=true \ No newline at end of file + - php app/console plugin:develop uninstall --code=${PLUGIN_CODE} --uninstall-force=true diff --git a/appveyor.yml b/appveyor.yml index 8cc0981..5cd97b7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -76,6 +76,3 @@ before_test: test_script: - vendor\bin\phpunit.bat app/Plugin/%PLUGIN_CODE%/Tests - - - From 00c37f3cb160704b94a193a618368f11edf7e5d2 Mon Sep 17 00:00:00 2001 From: lammn Date: Thu, 27 Oct 2016 17:11:54 +0700 Subject: [PATCH 20/63] fix bug --- Event.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Event.php b/Event.php index 3125c40..7b0e8d2 100644 --- a/Event.php +++ b/Event.php @@ -91,13 +91,14 @@ public function onRenderProductDetail(TemplateEvent $event) //find related product mark if (strpos($source, self::RELATED_PRODUCT_TAG)) { $search = self::RELATED_PRODUCT_TAG; + $replace = $search.$snipet; } else { //regular expression for get free area div $pattern = '/({% if Product.freearea %})(.*?(\n))+.*?({% endif %})/'; preg_match($pattern, $source, $matches); $search = $matches[0]; + $replace = $search.$snipet; } - $replace = $snipet.$search; $source = str_replace($search, $replace, $source); $event->setSource($source); From 1d96262a95243d26322d9f24a370b019e2d0c587 Mon Sep 17 00:00:00 2001 From: lammn Date: Fri, 28 Oct 2016 09:12:03 +0700 Subject: [PATCH 21/63] fix variable name --- Entity/RelatedProduct.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Entity/RelatedProduct.php b/Entity/RelatedProduct.php index f75eb72..a9e2013 100644 --- a/Entity/RelatedProduct.php +++ b/Entity/RelatedProduct.php @@ -45,7 +45,7 @@ class RelatedProduct /** * @var int */ - private $childProdcutId; + private $childProductId; /** * @return int @@ -158,7 +158,7 @@ public function setChildProduct(Product $Product = null) */ public function getChildProductId() { - return $this->childProdcutId; + return $this->childProductId; } /** @@ -170,7 +170,7 @@ public function getChildProductId() */ public function setChildProductId($productId) { - $this->childProdcutId = $productId; + $this->childProductId = $productId; return $this; } From b0f2261411df030d408c36b0bd48b130c52ca393 Mon Sep 17 00:00:00 2001 From: lammn Date: Fri, 28 Oct 2016 10:48:37 +0700 Subject: [PATCH 22/63] fix old version --- EventLegacy.php | 5 +++-- Resource/template/admin/related_product.twig | 10 +++------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/EventLegacy.php b/EventLegacy.php index b441229..ddba149 100644 --- a/EventLegacy.php +++ b/EventLegacy.php @@ -139,8 +139,10 @@ public function onRenderAdminProductEditBefore(FilterResponseEvent $event) if ($Product->hasProductClass()) { $builder->remove('class'); + //get new form from builder. + $form = $builder->getForm(); + $form->handleRequest($request); } - if ($form->isValid()) { $app['eccube.plugin.repository.related_product']->removeChildProduct($Product); $RelatedProducts = $form->get('related_collection')->getData(); @@ -178,7 +180,6 @@ public function onRenderAdminProductEditBefore(FilterResponseEvent $event) $RelatedProducts[] = $RelatedProduct; } $form->get('related_collection')->setData($RelatedProducts); - $form->handleRequest($request); // 商品検索フォーム diff --git a/Resource/template/admin/related_product.twig b/Resource/template/admin/related_product.twig index 366f567..ffe0ed6 100644 --- a/Resource/template/admin/related_product.twig +++ b/Resource/template/admin/related_product.twig @@ -54,19 +54,16 @@ $(function() { }); -
-
+

{{ form.related_collection.vars.label }}

-
+
{% for child in form.related_collection %}
{% endfor %} -
-
+ From 5bef801ca5f0b803a1347e21c44ec671988caaaa Mon Sep 17 00:00:00 2001 From: lammn Date: Fri, 28 Oct 2016 11:01:30 +0700 Subject: [PATCH 23/63] fix display --- EventLegacy.php | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/EventLegacy.php b/EventLegacy.php index ddba149..e018961 100644 --- a/EventLegacy.php +++ b/EventLegacy.php @@ -203,21 +203,14 @@ public function onRenderAdminProductEditBefore(FilterResponseEvent $event) 'Product' => $Product, ) ); - $oldElement = $crawler - ->filter('.accordion') - ->last(); - if ($oldElement->count() > 0) { - //fix bug input html tag or special character code - $oldHtml = html_entity_decode($oldElement->html(), ENT_NOQUOTES, 'UTF-8'); - $newHtml = $oldHtml.$twig; - - $html = $this->getHtml($crawler); - $html = $html.$modal; - $html = str_replace($oldHtml, $newHtml, $html); - - $response->setContent($html); - $event->setResponse($response); - } + $html = $response->getContent(); + $html = $html.$modal; + // For old and new version + $search = '/( diff --git a/ServiceProvider/RelatedProductServiceProvider.php b/ServiceProvider/RelatedProductServiceProvider.php index 518f5d4..79a9032 100644 --- a/ServiceProvider/RelatedProductServiceProvider.php +++ b/ServiceProvider/RelatedProductServiceProvider.php @@ -19,7 +19,7 @@ use Plugin\RelatedProduct\Util\Util; // include log functions (for 3.0.0 - 3.0.11) -require_once(__DIR__.'/../log.php'); +require_once __DIR__.'/../log.php'; /** * Class RelatedProductServiceProvider. @@ -36,6 +36,9 @@ public function register(BaseApplication $app) $app->post('/related_product/search_product', '\Plugin\RelatedProduct\Controller\Admin\RelatedProductController::searchProduct') ->bind('admin_related_product_search'); + $app->post('/related_product/get_product', '\Plugin\RelatedProduct\Controller\Admin\RelatedProductController::getProduct') + ->bind('admin_related_product_get_product'); + $app->match('/'.$app['config']['admin_route'].'/related_product/search/product/page/{page_no}', '\Plugin\RelatedProduct\Controller\Admin\RelatedProductController::searchProduct') ->assert('page_no', '\d+') ->bind('admin_related_product_search_product_page'); diff --git a/log.php b/log.php index c6b3e90..1c1e54f 100644 --- a/log.php +++ b/log.php @@ -13,95 +13,78 @@ } if (function_exists('log_emergency') === false) { - function log_emergency($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { $GLOBALS['eccube_logger']->emergency($message, $context); } } - } if (function_exists('log_alert') === false) { - function log_alert($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { $GLOBALS['eccube_logger']->alert($message, $context); } } - } if (function_exists('log_critical') === false) { - function log_critical($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { $GLOBALS['eccube_logger']->critical($message, $context); } } - } if (function_exists('log_error') === false) { - function log_error($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { $GLOBALS['eccube_logger']->error($message, $context); } } - } if (function_exists('log_warning') === false) { - function log_warning($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { $GLOBALS['eccube_logger']->warning($message, $context); } } - } if (function_exists('log_notice') === false) { - function log_notice($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { $GLOBALS['eccube_logger']->notice($message, $context); } } - } if (function_exists('log_info') === false) { - function log_info($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { $GLOBALS['eccube_logger']->info($message, $context); } } - } if (function_exists('log_debug') === false) { - function log_debug($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { $GLOBALS['eccube_logger']->debug($message, $context); } } - } if (function_exists('eccube_log_init') === false) { - function eccube_log_init($app) { if (isset($GLOBALS['eccube_logger'])) { @@ -114,7 +97,6 @@ function eccube_log_init($app) return $app['monolog']; }); } - } // 3.0.9以上の場合は初期化処理を行う. From 729535caf04858b8a0de697ce7db5074dbcef1d2 Mon Sep 17 00:00:00 2001 From: lammn Date: Wed, 9 Nov 2016 17:25:36 +0700 Subject: [PATCH 33/63] remove log in plugin manager --- PluginManager.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/PluginManager.php b/PluginManager.php index de39186..c7db8cf 100644 --- a/PluginManager.php +++ b/PluginManager.php @@ -28,7 +28,6 @@ class PluginManager extends AbstractPluginManager */ public function install($config, $app) { - log_info('install related product plugin'); } /** @@ -40,7 +39,6 @@ public function install($config, $app) public function uninstall($config, $app) { $this->migrationSchema($app, __DIR__.'/Resource/doctrine/migration', $config['code'], 0); - log_info('uninstall related product plugin'); } /** @@ -54,7 +52,6 @@ public function uninstall($config, $app) public function enable($config, $app) { $this->migrationSchema($app, __DIR__.'/Resource/doctrine/migration', $config['code']); - log_info('enable related product plugin'); } /** @@ -65,7 +62,6 @@ public function enable($config, $app) */ public function disable($config, $app) { - log_info('disable related product plugin'); } /** @@ -77,6 +73,5 @@ public function disable($config, $app) public function update($config, $app) { $this->migrationSchema($app, __DIR__.'/Resource/doctrine/migration', $config['code']); - log_info('update related product plugin'); } } From c5de76d5b24cbb524f7027cb9dee63b13598c496 Mon Sep 17 00:00:00 2001 From: lammn Date: Mon, 14 Nov 2016 10:20:51 +0700 Subject: [PATCH 34/63] fix new log --- EventLegacy.php | 2 +- Resource/template/admin/modal_result.twig | 2 +- Resource/template/admin/related_product.twig | 51 ++++++++++---------- phpunit.xml.dist | 1 + 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/EventLegacy.php b/EventLegacy.php index 3ae4c89..e06e75c 100644 --- a/EventLegacy.php +++ b/EventLegacy.php @@ -87,8 +87,8 @@ public function onRenderProductDetailBefore(FilterResponseEvent $event) $response->setContent($html); $event->setResponse($response); - log_info('RelatedProduct trigger onRenderProductDetailBefore finish'); } + log_info('RelatedProduct trigger onRenderProductDetailBefore finish'); } /** diff --git a/Resource/template/admin/modal_result.twig b/Resource/template/admin/modal_result.twig index e007d53..9794ed0 100644 --- a/Resource/template/admin/modal_result.twig +++ b/Resource/template/admin/modal_result.twig @@ -59,7 +59,7 @@ - diff --git a/Resource/template/admin/related_product.twig b/Resource/template/admin/related_product.twig index 48d22ce..ec9f560 100644 --- a/Resource/template/admin/related_product.twig +++ b/Resource/template/admin/related_product.twig @@ -20,34 +20,35 @@ $(function() { $('#searchResult').children().remove(); }); - $("select.child-product").each(function () { - var html = $(this).clone(); - var productId = $(this).val(); - var index = $(this).parent().find('button').attr('data-id'); - var productCode = $('#product-code' + index).text(); - var parentDiv = $('#related-div-' + index); - if (productId && !productCode) { - $.ajax({ - type: "POST", - url: "{{ url('admin_related_product_get_product') }}", - data: { - product_id : productId, - index : index - }, - success: function(data){ - parentDiv.empty().append(data); - parentDiv.append(html); - }, - error: function() { - alert('get product info failed.'); - } - }); - } - }); + window.onload = function () { + $("select.child-product").each(function () { + var html = $(this).clone(); + var productId = $(this).val(); + var index = $(this).parent().find('button').attr('data-id'); + var productCode = $('#product-code' + index).text(); + var parentDiv = $('#related-div-' + index); + if (productId && !productCode) { + $.ajax({ + type: "POST", + url: "{{ url('admin_related_product_get_product') }}", + data: { + product_id : productId, + index : index + }, + success: function(data){ + parentDiv.empty().append(data); + parentDiv.append(html); + }, + error: function() { + alert('get product info failed.'); + } + }); + } + }); + }; $(document).on("click", 'a[id^="search_"]', function () { dataId = $(this).attr("data-id"); - console.log('aaa'); $("#relatedDataId").val(dataId); $("#searchResult").children().remove(); $('div.box-footer a').remove(); diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8a9be3f..4608d40 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -26,6 +26,7 @@ ./Resource ./Tests ./PluginManager.php + ./log.php From 496be013b23c6d07b8c376194f2b9b2454975a08 Mon Sep 17 00:00:00 2001 From: lammn Date: Tue, 15 Nov 2016 08:28:53 +0700 Subject: [PATCH 35/63] fix new log --- Util/Util.php | 10 ++++++ log.php | 89 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 86 insertions(+), 13 deletions(-) diff --git a/Util/Util.php b/Util/Util.php index 789efd8..992abab 100644 --- a/Util/Util.php +++ b/Util/Util.php @@ -31,4 +31,14 @@ public static function isSupportNewHookpoint() return false; } } + + /** + * Check version to support new log function. + * + * @return bool|int|mixed|void + */ + public static function isSupportLogFunction() + { + return version_compare(Constant::VERSION, '3.0.12', '>='); + } } diff --git a/log.php b/log.php index 1c1e54f..2fe5962 100644 --- a/log.php +++ b/log.php @@ -7,12 +7,19 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ +use Plugin\RelatedProduct\Util\Util; -if (version_compare(\Eccube\Common\Constant::VERSION, '3.0.12', '>=')) { +if (Util::isSupportLogFunction()) { return; } - if (function_exists('log_emergency') === false) { + /** + * Log emergency. + * Urgent alert. System is unusable. + * + * @param string $message + * @param array $context + */ function log_emergency($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { @@ -20,8 +27,16 @@ function log_emergency($message, array $context = array()) } } } - if (function_exists('log_alert') === false) { + /** + * Log alert. + * Action must be taken immediately. + * + * Entire website down, database unavailable, etc. This should trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + */ function log_alert($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { @@ -29,8 +44,16 @@ function log_alert($message, array $context = array()) } } } - if (function_exists('log_critical') === false) { + /** + * Log critical. + * Critical conditions. + * + * Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + */ function log_critical($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { @@ -38,8 +61,16 @@ function log_critical($message, array $context = array()) } } } - if (function_exists('log_error') === false) { + /** + * Log error. + * Runtime errors that do not require immediate action but should typically be logged and monitored. + * + * Error content at the time of occurrence Exception. + * + * @param string $message + * @param array $context + */ function log_error($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { @@ -47,8 +78,16 @@ function log_error($message, array $context = array()) } } } - if (function_exists('log_warning') === false) { + /** + * Log warning. + * Exceptional occurrences that are not errors. + * + * Use of deprecated APIs, poor use of an API, undesirable things that are not necessarily wrong. + * + * @param string $message + * @param array $context + */ function log_warning($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { @@ -56,8 +95,14 @@ function log_warning($message, array $context = array()) } } } - if (function_exists('log_notice') === false) { + /** + * Log notice. + * Normal but significant events. + * + * @param string $message + * @param array $context + */ function log_notice($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { @@ -65,8 +110,16 @@ function log_notice($message, array $context = array()) } } } - if (function_exists('log_info') === false) { + /** + * Log info. + * Interesting events. + * + * Logging to confirm the operation was performed. + * + * @param string $message + * @param array $context + */ function log_info($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { @@ -74,8 +127,17 @@ function log_info($message, array $context = array()) } } } - if (function_exists('log_debug') === false) { + /** + * Log debug. + * Detailed debug information. + * + * HTTP communication log. + * Log you want to output at the time of development + * + * @param string $message + * @param array $context + */ function log_debug($message, array $context = array()) { if (isset($GLOBALS['eccube_logger'])) { @@ -83,22 +145,23 @@ function log_debug($message, array $context = array()) } } } - if (function_exists('eccube_log_init') === false) { + /** + * Init log function for ec-cube <= 3.0.8. + * + * @param object $app + */ function eccube_log_init($app) { if (isset($GLOBALS['eccube_logger'])) { return; } - $GLOBALS['eccube_logger'] = $app['monolog']; - $app['eccube.monolog.factory'] = $app->protect(function ($config) use ($app) { return $app['monolog']; }); } } - // 3.0.9以上の場合は初期化処理を行う. if (method_exists('Eccube\Application', 'getInstance') === true) { $app = \Eccube\Application::getInstance(); From 94007b3b0efc28b903f204a3d80983fa70d0d8af Mon Sep 17 00:00:00 2001 From: ryo-endo Date: Tue, 15 Nov 2016 15:04:24 +0900 Subject: [PATCH 36/63] =?UTF-8?q?Event=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AE?= =?UTF-8?q?=E5=88=86=E9=9B=A2=E3=81=AESample=E5=AE=9F=E8=A3=85=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Event.php | 49 +--- Event/Event.php | 213 ++++++++++++++++++ EventLegacy.php => Event/EventLegacy.php | 2 +- .../RelatedProductServiceProvider.php | 8 + 4 files changed, 224 insertions(+), 48 deletions(-) create mode 100644 Event/Event.php rename EventLegacy.php => Event/EventLegacy.php (99%) diff --git a/Event.php b/Event.php index e8557b6..7585921 100644 --- a/Event.php +++ b/Event.php @@ -30,13 +30,6 @@ class Event */ private $app; - /** - * v3.0.0 - 3.0.8 向けのイベントを処理するインスタンス. - * - * @var EventLegacy - */ - private $legacyEvent; - /** * position for insert in twig file. * @@ -59,7 +52,6 @@ class Event public function __construct($app) { $this->app = $app; - $this->legacyEvent = new EventLegacy($app); } /** @@ -69,44 +61,7 @@ public function __construct($app) */ public function onRenderProductDetail(TemplateEvent $event) { - log_info('RelatedProduct trigger onRenderProductDetail start'); - $app = $this->app; - $parameters = $event->getParameters(); - // ProductIDがない場合、レンダリングしない - if (is_null($parameters['Product'])) { - return; - } - - // 登録がない、レンダリングをしない - $Product = $parameters['Product']; - $Disp = $app['eccube.repository.master.disp']->find(Disp::DISPLAY_SHOW); - $RelatedProducts = $app['eccube.plugin.repository.related_product']->showRelatedProduct($Product, $Disp); - if (count($RelatedProducts) == 0) { - return; - } - - // twigコードを挿入 - $snipet = $app['twig']->getLoader()->getSource('RelatedProduct/Resource/template/front/related_product.twig'); - $source = $event->getSource(); - //find related product mark - if (strpos($source, self::RELATED_PRODUCT_TAG)) { - log_info('Render related product with ', array('RELATED_PRODUCT_TAG' => self::RELATED_PRODUCT_TAG)); - $search = self::RELATED_PRODUCT_TAG; - $replace = $search.$snipet; - } else { - //regular expression for get free area div - $pattern = '/({% if Product.freearea %})(.*?(\n))+.*?({% endif %})/'; - preg_match($pattern, $source, $matches); - $search = $matches[0]; - $replace = $search.$snipet; - } - $source = str_replace($search, $replace, $source); - $event->setSource($source); - - //set parameter for twig files - $parameters['RelatedProducts'] = $RelatedProducts; - $event->setParameters($parameters); - log_info('RelatedProduct trigger onRenderProductDetail finish'); + $this->app['eccube.plugin.relatedproduct.event']->onRenderProductDetail($event); } /** @@ -205,7 +160,7 @@ public function onRenderProductDetailBefore(FilterResponseEvent $event) if (Util::isSupportNewHookpoint()) { return; } - $this->legacyEvent->onRenderProductDetailBefore($event); + $this->app['eccube.plugin.relatedproduct.event.legacy']->onRenderProductDetail($event); } /** diff --git a/Event/Event.php b/Event/Event.php new file mode 100644 index 0000000..73c00fa --- /dev/null +++ b/Event/Event.php @@ -0,0 +1,213 @@ += 3.0.9. + */ +class Event +{ + /** + * @var Application + */ + private $app; + + /** + * position for insert in twig file. + * + * @var string + */ + const RELATED_PRODUCT_TAG = ''; + + /** + * maximum product related. + * + * @var int + */ + const MAXIMUM_PRODUCT_RELATED = 5; + + /** + * Event constructor. + * + * @param Application $app + */ + public function __construct($app) + { + $this->app = $app; + } + + /** + * フロント:商品詳細画面に関連商品を表示. + * + * @param TemplateEvent $event + */ + public function onRenderProductDetail(TemplateEvent $event) + { + log_info('RelatedProduct trigger onRenderProductDetail start'); + $app = $this->app; + $parameters = $event->getParameters(); + // ProductIDがない場合、レンダリングしない + if (is_null($parameters['Product'])) { + return; + } + + // 登録がない、レンダリングをしない + $Product = $parameters['Product']; + $Disp = $app['eccube.repository.master.disp']->find(Disp::DISPLAY_SHOW); + $RelatedProducts = $app['eccube.plugin.repository.related_product']->showRelatedProduct($Product, $Disp); + if (count($RelatedProducts) == 0) { + return; + } + + // twigコードを挿入 + $snipet = $app['twig']->getLoader()->getSource('RelatedProduct/Resource/template/front/related_product.twig'); + $source = $event->getSource(); + //find related product mark + if (strpos($source, self::RELATED_PRODUCT_TAG)) { + log_info('Render related product with ', array('RELATED_PRODUCT_TAG' => self::RELATED_PRODUCT_TAG)); + $search = self::RELATED_PRODUCT_TAG; + $replace = $search.$snipet; + } else { + //regular expression for get free area div + $pattern = '/({% if Product.freearea %})(.*?(\n))+.*?({% endif %})/'; + preg_match($pattern, $source, $matches); + $search = $matches[0]; + $replace = $search.$snipet; + } + $source = str_replace($search, $replace, $source); + $event->setSource($source); + + //set parameter for twig files + $parameters['RelatedProducts'] = $RelatedProducts; + $event->setParameters($parameters); + log_info('RelatedProduct trigger onRenderProductDetail finish'); + } + + /** + * new hookpoint for init product edit. + * + * @param EventArgs $event + */ + public function onRenderAdminProductInit(EventArgs $event) + { + log_info('RelatedProduct trigger onRenderAdminProductInit start'); + $Product = $event->getArgument('Product'); + $RelatedProducts = $this->createRelatedProductData($Product); + // フォームの追加 + /** @var FormBuilder $builder */ + $builder = $event->getArgument('builder'); + $builder + ->add('related_collection', 'collection', array( + 'label' => '関連商品', + 'type' => 'admin_related_product', + 'allow_add' => true, + 'allow_delete' => true, + 'prototype' => true, + 'mapped' => false, + )) + ; + $builder->get('related_collection')->setData($RelatedProducts); + log_info('RelatedProduct trigger onRenderAdminProductInit finish'); + } + + /** + * new hookpoint for render RelatedProduct form. + * + * @param TemplateEvent $event + */ + public function onRenderAdminProduct(TemplateEvent $event) + { + log_info('RelatedProduct trigger onRenderAdminProduct start'); + $app = $this->app; + $parameters = $event->getParameters(); + $Product = $parameters['Product']; + $RelatedProducts = $this->createRelatedProductData($Product); + + // twigコードを挿入 + $snipet = $app['twig']->getLoader()->getSource('RelatedProduct/Resource/template/admin/related_product.twig'); + $modal = $app['twig']->getLoader()->getSource('RelatedProduct/Resource/template/admin/modal.twig'); + + //add related product to product edit + $search = '