From 35125b4026113e813123c8d7fd3708ae4613c6d2 Mon Sep 17 00:00:00 2001 From: leemyong pakvn <3759923+leemyongpakvn@users.noreply.github.com> Date: Sat, 9 Dec 2023 16:36:02 +0700 Subject: [PATCH 1/4] partial migration to Symfony FormData Provider n Handler --- config/admin/services.yml | 16 +++ ...ProductCommentCriterionFormDataHandler.php | 121 ++++++++++++++++++ ...roductCommentCriterionFormDataProvider.php | 89 +++++++++++++ src/Form/index.php | 34 +++++ 4 files changed, 260 insertions(+) create mode 100644 src/Form/ProductCommentCriterionFormDataHandler.php create mode 100644 src/Form/ProductCommentCriterionFormDataProvider.php create mode 100644 src/Form/index.php diff --git a/config/admin/services.yml b/config/admin/services.yml index 6e16e432..02ce511d 100644 --- a/config/admin/services.yml +++ b/config/admin/services.yml @@ -1,2 +1,18 @@ imports: - { resource: ../common.yml } + +services: + product_comment_criterion_form_data_provider: + class: 'PrestaShop\Module\ProductComment\Form\ProductCommentCriterionFormDataProvider' + public: true + arguments: + - '@product_comment_criterion_repository' + - '@prestashop.core.admin.lang.repository' + + product_comment_criterion_form_data_handler: + class: 'PrestaShop\Module\ProductComment\Form\ProductCommentCriterionFormDataHandler' + public: true + arguments: + - '@product_comment_criterion_repository' + - '@prestashop.core.admin.lang.repository' + - '@doctrine.orm.default_entity_manager' \ No newline at end of file diff --git a/src/Form/ProductCommentCriterionFormDataHandler.php b/src/Form/ProductCommentCriterionFormDataHandler.php new file mode 100644 index 00000000..8e0437d9 --- /dev/null +++ b/src/Form/ProductCommentCriterionFormDataHandler.php @@ -0,0 +1,121 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +declare(strict_types=1); + +namespace PrestaShop\Module\ProductComment\Form; + +use Doctrine\ORM\EntityManagerInterface; +use PrestaShop\Module\ProductComment\Entity\ProductCommentCriterion; +use PrestaShop\Module\ProductComment\Entity\ProductCommentCriterionLang; +use PrestaShop\Module\ProductComment\Repository\ProductCommentCriterionRepository; +use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\FormDataHandlerInterface; +use PrestaShopBundle\Entity\Repository\LangRepository; + +class ProductCommentCriterionFormDataHandler implements FormDataHandlerInterface +{ + /** + * @var ProductCommentCriterionRepository + */ + private $pccriterionRepository; + + /** + * @var LangRepository + */ + private $langRepository; + + /** + * @var EntityManagerInterface + */ + private $entityManager; + + /** + * @param ProductCommentCriterionRepository $pccriterionRepository + * @param LangRepository $langRepository + * @param EntityManagerInterface $entityManager + */ + public function __construct( + ProductCommentCriterionRepository $pccriterionRepository, + LangRepository $langRepository, + EntityManagerInterface $entityManager + ) { + $this->pccriterionRepository = $pccriterionRepository; + $this->langRepository = $langRepository; + $this->entityManager = $entityManager; + } + + /** + * {@inheritdoc} + */ + public function create(array $data) + { + } + + /** + * {@inheritdoc} + */ + public function update($id, array $data) + { + } + + /** + * @param ProductCommentCriterion $pccriterion + * @param array $pcc_languages + * + * @todo migrate this temporary function to above standard function create + */ + public function createLangs($pccriterion, $pcc_languages): void + { + foreach ($pcc_languages as $langId => $langContent) { + $lang = $this->langRepository->find($langId); + $pccriterionLang = new ProductCommentCriterionLang(); + $pccriterionLang + ->setLang($lang) + ->setName($langContent) + ; + $pccriterion->addCriterionLang($pccriterionLang); + } + + $this->entityManager->persist($pccriterion); + $this->entityManager->flush(); + } + + /** + * @param ProductCommentCriterion $pccriterion + * @param array $pcc_languages + * + * @todo migrate this temporary function to above standard function update + */ + public function updateLangs($pccriterion, $pcc_languages): void + { + foreach ($pcc_languages as $langId => $langContent) { + $lang = $this->langRepository->find($langId); + $pccriterionLang = $pccriterion->getCriterionLangByLangId($langId); + if (null === $pccriterionLang) { + continue; + } + $pccriterionLang + ->setName($langContent) + ; + } + + $this->entityManager->persist($pccriterion); + $this->entityManager->flush(); + } +} diff --git a/src/Form/ProductCommentCriterionFormDataProvider.php b/src/Form/ProductCommentCriterionFormDataProvider.php new file mode 100644 index 00000000..a02cb840 --- /dev/null +++ b/src/Form/ProductCommentCriterionFormDataProvider.php @@ -0,0 +1,89 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +declare(strict_types=1); + +namespace PrestaShop\Module\ProductComment\Form; + +use PrestaShop\Module\ProductComment\Repository\ProductCommentCriterionRepository; +use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\FormDataProviderInterface; +use PrestaShopBundle\Entity\Repository\LangRepository; + +class ProductCommentCriterionFormDataProvider implements FormDataProviderInterface +{ + /** + * @var ProductCommentCriterionRepository + */ + private $pccriterionRepository; + + /** + * @var LangRepository + */ + private $langRepository; + + /** + * @param ProductCommentCriterionRepository $pccriterionRepository + * @param LangRepository $langRepository + */ + public function __construct( + ProductCommentCriterionRepository $pccriterionRepository, + LangRepository $langRepository + ) { + $this->pccriterionRepository = $pccriterionRepository; + $this->langRepository = $langRepository; + } + + /** + * {@inheritdoc} + */ + public function getData($criterionId) + { + $criterion = $this->pccriterionRepository->find($criterionId); + + $criterionData = [ + 'type' => $criterion->getType(), + 'active' => $criterion->isActive(), + ]; + foreach ($criterion->getCriterionLangs() as $criterionLang) { + $criterionData['name'][$criterionLang->getLang()->getId()] = $criterionLang->getName(); + } + + return $criterionData; + } + + /** + * {@inheritdoc} + */ + public function getDefaultData() + { + $default_name = []; + + //$langIsoIds = Language::getIsoIds(); + $langEntities = $this->langRepository->findBy(['active' => 1]); + foreach ($langEntities as $langEntity) { + $default_name[$langEntity->getId()] = $langEntity->getIsoCode(); + } + + return [ + 'type' => '', + 'active' => false, + 'name' => $default_name, + ]; + } +} diff --git a/src/Form/index.php b/src/Form/index.php new file mode 100644 index 00000000..45df26c5 --- /dev/null +++ b/src/Form/index.php @@ -0,0 +1,34 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; From d7a89ad098fd66f459cd725ff3c265a0d8cd7722 Mon Sep 17 00:00:00 2001 From: leemyong pakvn <3759923+leemyongpakvn@users.noreply.github.com> Date: Sat, 9 Dec 2023 16:38:56 +0700 Subject: [PATCH 2/4] replace Manual lang field process by Doctrine Entity Relation --- src/Entity/ProductCommentCriterion.php | 107 ++++++++++++--------- src/Entity/ProductCommentCriterionLang.php | 97 +++++++++++++++++++ 2 files changed, 161 insertions(+), 43 deletions(-) create mode 100644 src/Entity/ProductCommentCriterionLang.php diff --git a/src/Entity/ProductCommentCriterion.php b/src/Entity/ProductCommentCriterion.php index b2421472..de610006 100644 --- a/src/Entity/ProductCommentCriterion.php +++ b/src/Entity/ProductCommentCriterion.php @@ -26,8 +26,8 @@ namespace PrestaShop\Module\ProductComment\Entity; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; -use Language; use Validate; /** @@ -67,34 +67,79 @@ class ProductCommentCriterion /** * @var array * - * Need to be implemented as ORM\OneToMany in the future + * @deprecated 6.0.3 - use criterionLangs instead */ private $names; + /** + * @ORM\OneToMany(targetEntity="PrestaShop\Module\ProductComment\Entity\ProductCommentCriterionLang", cascade={"persist", "remove"}, mappedBy="productcommentcriterion") + */ + private $criterionLangs; + /** * @var array * - * Need to be implemented as ORM\OneToMany in the future + * @todo implement as ORM\OneToMany in the future */ private $categories; /** * @var array * - * Need to be implemented as ORM\OneToMany in the future + * @todo implement as ORM\OneToMany in the future */ private $products; public function __construct() { - $langIsoIds = Language::getIsoIds(); - foreach ($langIsoIds as $langIsoId) { - $this->names[$langIsoId['id_lang']] = $langIsoId['iso_code']; + $this->criterionLangs = new ArrayCollection(); + } + + /** + * @return ArrayCollection + */ + public function getCriterionLangs() + { + return $this->criterionLangs; + } + + /** + * @return ProductCommentCriterionLang|null + */ + public function getCriterionLangByLangId(int $langId) + { + foreach ($this->criterionLangs as $criterionLang) { + if ($langId === $criterionLang->getLang()->getId()) { + return $criterionLang; + } + } + + return null; + } + + public function addCriterionLang(ProductCommentCriterionLang $criterionLang): self + { + $criterionLang->setProductCommentCriterion($this); + $this->criterionLangs->add($criterionLang); + + return $this; + } + + public function getCriterionName(): string + { + if ($this->criterionLangs->count() <= 0) { + return ''; } + + $criterionLang = $this->criterionLangs->first(); + + return $criterionLang->getName(); } /** * @return array + * + * @deprecated 6.0.3 - migrated to Form\ProductCommentCriterionFormDataProvider */ public function getNames() { @@ -105,6 +150,8 @@ public function getNames() * @param array $langNames * * @return ProductCommentCriterion + * + * @deprecated 6.0.3 */ public function setNames($langNames) { @@ -123,10 +170,8 @@ public function getCategories() /** * @param array $selectedCategories - * - * @return ProductCommentCriterion */ - public function setCategories($selectedCategories) + public function setCategories($selectedCategories): self { $this->categories = $selectedCategories; @@ -143,71 +188,47 @@ public function getProducts() /** * @param array $selectedProducts - * - * @return ProductCommentCriterion */ - public function setProducts($selectedProducts) + public function setProducts($selectedProducts): self { $this->products = $selectedProducts; return $this; } - /** - * @return int - */ - public function getId() + public function getId(): int { return $this->id; } - /** - * @return int - */ - public function getType() + public function getType(): int { return $this->type; } - /** - * @param int $type - * - * @return ProductCommentCriterion - */ - public function setType($type) + public function setType(int $type): self { $this->type = $type; return $this; } - /** - * @return bool - */ - public function isActive() + public function isActive(): bool { return $this->active; } - /** - * @param bool $active - * - * @return ProductCommentCriterion - */ - public function setActive($active) + public function setActive(bool $active): self { $this->active = $active; return $this; } - /** - * @return bool - */ - public function isValid() + public function isValid(): bool { - foreach ($this->names as $value) { - if (!Validate::isGenericName($value)) { + foreach ($this->criterionLangs as $criterionLang) { + if (!Validate::isGenericName($criterionLang->getName())) { return false; } } diff --git a/src/Entity/ProductCommentCriterionLang.php b/src/Entity/ProductCommentCriterionLang.php new file mode 100644 index 00000000..19373f7f --- /dev/null +++ b/src/Entity/ProductCommentCriterionLang.php @@ -0,0 +1,97 @@ +productcommentcriterion; + } + + public function setProductCommentCriterion(ProductCommentCriterion $productcommentcriterion): self + { + $this->productcommentcriterion = $productcommentcriterion; + + return $this; + } + + /** + * @return Lang + */ + public function getLang() + { + return $this->lang; + } + + /** + * @param Lang $lang + */ + public function setLang(Lang $lang): self + { + $this->lang = $lang; + + return $this; + } + + public function getName(): string + { + return $this->name; + } + + public function setName(string $name): self + { + $this->name = $name; + + return $this; + } +} From a99f0172df3aef331efc9484fb717e6d9b0ee363 Mon Sep 17 00:00:00 2001 From: leemyong pakvn <3759923+leemyongpakvn@users.noreply.github.com> Date: Sat, 9 Dec 2023 16:41:06 +0700 Subject: [PATCH 3/4] mark deprcated functions, replace migrated functions call by new one --- productcomments.php | 48 +++++++++++---- .../ProductCommentCriterionRepository.php | 61 ++++++++----------- 2 files changed, 62 insertions(+), 47 deletions(-) diff --git a/productcomments.php b/productcomments.php index 473f5ed5..75745ac5 100644 --- a/productcomments.php +++ b/productcomments.php @@ -169,8 +169,10 @@ public function getCacheId($id_product = null) protected function _postProcess() { $id_product_comment = (int) Tools::getValue('id_product_comment'); + $id_product_comment_criterion = (int) Tools::getValue('id_product_comment_criterion'); $commentRepository = $this->get('product_comment_repository'); $criterionRepository = $this->get('product_comment_criterion_repository'); + $criterionFormHandler = $this->get('product_comment_criterion_form_data_handler'); if (Tools::isSubmit('submitModerate')) { $errors = []; @@ -215,7 +217,12 @@ protected function _postProcess() Tools::redirectAdmin($this->context->link->getAdminLink('AdminModules', true, [], ['configure' => $this->name])); } } elseif (Tools::isSubmit('submitEditCriterion')) { - $criterion = $criterionRepository->findRelation((int) Tools::getValue('id_product_comment_criterion')); + if ($id_product_comment_criterion > 0) { + $criterion = $criterionRepository->find($id_product_comment_criterion); + } else { + $criterion = new ProductCommentCriterion(); + } + $criterion->setType((int) Tools::getValue('id_product_comment_criterion_type')); $criterion->setActive(Tools::getValue('active')); @@ -224,7 +231,12 @@ protected function _postProcess() foreach ($languages as $key => $value) { $name[$value['id_lang']] = Tools::getValue('name_' . $value['id_lang']); } - $criterion->setNames($name); + + if ($id_product_comment_criterion > 0) { + $criterionFormHandler->updateLangs($criterion, $name); + } else { + $criterionFormHandler->createLangs($criterion, $name); + } if (!$criterion->isValid()) { $this->_html .= $this->displayError($this->trans('The criterion cannot be saved', [], 'Modules.Productcomments.Admin')); @@ -238,14 +250,18 @@ protected function _postProcess() } } } elseif (Tools::isSubmit('deleteproductcommentscriterion')) { - $criterion = $criterionRepository->findRelation((int) Tools::getValue('id_product_comment_criterion')); + $criterion = $criterionRepository->find($id_product_comment_criterion); if ($criterionRepository->delete($criterion)) { - $this->_html .= $this->displayConfirmation($this->trans('Criterion deleted', [], 'Modules.Productcomments.Admin')); + Tools::redirectAdmin($this->context->link->getAdminLink('AdminModules', true, [], ['configure' => $this->name])); + } else { + $this->_html .= $this->displayError($this->trans('Criterion cannot be deleted', [], 'Modules.Productcomments.Admin')); } } elseif (Tools::isSubmit('statusproductcommentscriterion')) { - $criterion = $criterionRepository->findRelation((int) Tools::getValue('id_product_comment_criterion')); + $criterion = $criterionRepository->find($id_product_comment_criterion); $criterion->setActive(!$criterion->isActive()); - Tools::redirectAdmin($this->context->link->getAdminLink('AdminModules', true, [], ['configure' => $this->name, 'tab_module' => $this->tab, 'conf' => 4, 'module_name' => $this->name])); + $criterionRepository->updateGeneral($criterion); + + Tools::redirectAdmin($this->context->link->getAdminLink('AdminModules', true, [], ['configure' => $this->name])); } elseif ($id_product_comment = (int) Tools::getValue('approveComment')) { $comment = $commentRepository->find($id_product_comment); $commentRepository->validate($comment, 1); @@ -602,16 +618,22 @@ public function getConfigFieldsValues() ]; } - public function getCriterionFieldsValues($id = 0) + public function getCriterionFieldsValues(int $id = 0) { $criterionRepos = $this->get('product_comment_criterion_repository'); - $criterion = $criterionRepos->findRelation($id); + $criterionFormProvider = $this->get('product_comment_criterion_form_data_provider'); + + if ($id > 0) { + $criterionData = $criterionFormProvider->getData($id); + } else { + $criterionData = $criterionFormProvider->getDefaultData(); + } return [ - 'name' => $criterion->getNames(), - 'id_product_comment_criterion_type' => $criterion->getType(), - 'active' => $criterion->isActive(), - 'id_product_comment_criterion' => $criterion->getId(), + 'name' => $criterionData['name'], + 'id_product_comment_criterion_type' => $criterionData['type'], + 'active' => $criterionData['active'], + 'id_product_comment_criterion' => $id, ]; } @@ -702,7 +724,7 @@ public function renderCriterionForm($id_criterion = 0) $criterionRepository = $this->get('product_comment_criterion_repository'); - $criterion = $criterionRepository->findRelation($id_criterion); + $criterion = $criterionRepository->find($id_criterion); $selected_categories = $criterionRepository->getCategories($id_criterion); $product_table_values = Product::getSimpleProducts($this->langId); diff --git a/src/Repository/ProductCommentCriterionRepository.php b/src/Repository/ProductCommentCriterionRepository.php index 7446f671..c978e5b4 100644 --- a/src/Repository/ProductCommentCriterionRepository.php +++ b/src/Repository/ProductCommentCriterionRepository.php @@ -88,6 +88,9 @@ public function remove(ProductCommentCriterion $entity, bool $flush = false): vo } } + /** + * @deprecated 6.0.3 - cascade remove by Entity setting instead + */ private function deleteLangs($criterion): int { return $this->connection->executeUpdate(' @@ -112,33 +115,34 @@ private function deleteProducts($criterion): int private function deleteGrades($criterion): int { return $this->connection->executeUpdate(' - DELETE FROM `' . _DB_PREFIX_ . 'product_comment_criterion_grade` + DELETE FROM `' . _DB_PREFIX_ . 'product_comment_grade` WHERE `id_product_comment_criterion` = ' . $criterion->getId()); } - /* Remove a criterion and Delete its manual relation _lang, _category, _product, _grade */ + /* Remove a criterion and Delete its manual relation _category, _product, _grade */ public function delete(ProductCommentCriterion $criterion): int { $res = 0; $criterionType = $criterion->getType(); - $this->remove($criterion, true); - - $res += $this->deleteLangs($criterion); - if ($criterionType == ProductCommentCriterion::CATEGORIES_TYPE) { $res += $this->deleteCategories($criterion); } elseif ($criterionType == ProductCommentCriterion::PRODUCTS_TYPE) { $res += $this->deleteProducts($criterion); + } else { + $res = 1; } $res += $this->deleteGrades($criterion); + $this->remove($criterion, true); + + // todo: return void, and use try catch Exception instead return $res; } - /* Update a criterion and Update its manual relation _lang, _category, _product, _grade */ + /* Update a criterion and Update its manual relation _category, _product */ public function update(ProductCommentCriterion $criterion): int { $res = 0; @@ -148,20 +152,23 @@ public function update(ProductCommentCriterion $criterion): int $this->getEntityManager()->persist($criterion); $this->getEntityManager()->flush(); - $res += $this->deleteLangs($criterion); - $res += $this->updateLangs($criterion); - if ($criterionType == ProductCommentCriterion::CATEGORIES_TYPE) { $res += $this->deleteCategories($criterion); $res += $this->updateCategories($criterion); } elseif ($criterionType == ProductCommentCriterion::PRODUCTS_TYPE) { $res += $this->deleteProducts($criterion); $res += $this->updateProducts($criterion); + } else { + $res = 1; } + // todo: return void, and use try catch Exception instead return $res; } + /** + * @deprecated 6.0.3 - migrated to Form\ProductCommentCriterionFormDataHandler + */ private function updateLangs($criterion): int { $res = 0; @@ -217,15 +224,18 @@ private function updateProducts($criterion): int return $res; } + public function updateGeneral(ProductCommentCriterion $criterion): void + { + $this->getEntityManager()->persist($criterion); + $this->getEntityManager()->flush(); + } + /** - * @param int $idProduct - * @param int $idLang - * * @return array * * @throws \PrestaShopException */ - public function getByProduct($idProduct, $idLang) + public function getByProduct(int $idProduct, int $idLang) { /** @var QueryBuilder $qb */ $qb = $this->connection->createQueryBuilder(); @@ -255,11 +265,9 @@ public function getByProduct($idProduct, $idLang) } /** - * Get Criterions - * * @return array Criterions */ - public function getCriterions($id_lang, $type = false, $active = false) + public function getCriterions(int $id_lang, $type = false, $active = false) { $sql = ' SELECT pcc.`id_product_comment_criterion`, pcc.id_product_comment_criterion_type, pccl.`name`, pcc.active @@ -278,8 +286,6 @@ public function getCriterions($id_lang, $type = false, $active = false) } /** - * @param int $id_criterion - * * @return array */ public function getProducts(int $id_criterion) @@ -302,8 +308,6 @@ public function getProducts(int $id_criterion) } /** - * @param int $id_criterion - * * @return array */ public function getCategories(int $id_criterion) @@ -340,25 +344,14 @@ public function getTypes() } /** - * Get Criterion with names in active languages - * * @return ProductCommentCriterion + * + * @deprecated 6.0.3 - use standard find() instead */ public function findRelation($id_criterion) { if ($id_criterion > 0) { $criterion = $this->find($id_criterion); - $sql = ' - SELECT `id_lang`, `name` - FROM `' . _DB_PREFIX_ . 'product_comment_criterion_lang` pccl - WHERE pccl.id_product_comment_criterion = ' . $id_criterion . ' - ORDER BY pccl.`id_lang` ASC'; - $langNames = $this->connection->executeQuery($sql)->fetchAll(); - $langArray = []; - foreach ($langNames as $langName) { - $langArray[$langName['id_lang']] = $langName['name']; - } - $criterion->setNames($langArray); } else { $criterion = new ProductCommentCriterion(); } From 28fb21410a28fd05b1f37ac17a3608a2eebd220b Mon Sep 17 00:00:00 2001 From: leemyong pakvn <3759923+leemyongpakvn@users.noreply.github.com> Date: Thu, 14 Dec 2023 09:38:20 +0700 Subject: [PATCH 4/4] redundant comment --- src/Form/ProductCommentCriterionFormDataProvider.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Form/ProductCommentCriterionFormDataProvider.php b/src/Form/ProductCommentCriterionFormDataProvider.php index a02cb840..9b8397d9 100644 --- a/src/Form/ProductCommentCriterionFormDataProvider.php +++ b/src/Form/ProductCommentCriterionFormDataProvider.php @@ -74,7 +74,6 @@ public function getDefaultData() { $default_name = []; - //$langIsoIds = Language::getIsoIds(); $langEntities = $this->langRepository->findBy(['active' => 1]); foreach ($langEntities as $langEntity) { $default_name[$langEntity->getId()] = $langEntity->getIsoCode();