From c5d431df2b53e987289ebd8cc26e71731f77800e Mon Sep 17 00:00:00 2001 From: "ivan.hrytsai" Date: Mon, 10 Nov 2025 17:33:21 +0200 Subject: [PATCH 1/5] 14254-Magefan-extensions-review-popup-in-Magento-admin [in progress] --- Block/Adminhtml/ReviewPopup.php | 67 +++++++++++++ Model/GetModuleInfo.php | 6 +- view/adminhtml/layout/default.xml | 3 + view/adminhtml/templates/review-popup.phtml | 106 ++++++++++++++++++++ 4 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 Block/Adminhtml/ReviewPopup.php create mode 100644 view/adminhtml/templates/review-popup.phtml diff --git a/Block/Adminhtml/ReviewPopup.php b/Block/Adminhtml/ReviewPopup.php new file mode 100644 index 0000000..7260c04 --- /dev/null +++ b/Block/Adminhtml/ReviewPopup.php @@ -0,0 +1,67 @@ +getModuleInfo = $getModuleInfo; + parent::__construct($context, $data, $jsonHelper, $directoryHelper); + } + + public function getModuleName() { + return ucfirst($this->_request->getModuleName()); + } + + public function getModuleReviewUrl() + { + if ($this->reviewUrl === null) { + $info = $this->getModuleInfo->execute($this->getModuleName()); + + if (!empty($info['review_url'])) { + $this->reviewUrl = $info['review_url']; + } + } + + return $this->reviewUrl; + } + + private function canDisplay() { + return $this->getModuleReviewUrl(); // && перевірити чи є + } + + /** + * Prepare html output + * + * @return string + */ + protected function _toHtml() + { + if (!$this->canDisplay()) { + return ''; + } + return parent::_toHtml(); + } +} \ No newline at end of file diff --git a/Model/GetModuleInfo.php b/Model/GetModuleInfo.php index 87c68da..33b6535 100644 --- a/Model/GetModuleInfo.php +++ b/Model/GetModuleInfo.php @@ -57,7 +57,10 @@ public function execute($moduleName = null) return $modulesInfo; } - $moduleKey = explode('_', $moduleName)[1]; + $moduleKey = $moduleName; + if (strpos($moduleName, '_') !== false) { + $moduleKey = explode('_', $moduleName)[1]; + } if (!isset($modulesInfo[$moduleKey])) { $modulesInfo[$moduleKey] = new DataObject(); @@ -94,6 +97,7 @@ private function load(): array $data = []; try { $url = 'https://mage' . 'fan.com/media/product-versions-extended.json'; + $url = 'http://mage' . 'fan.loc/media/product-versions-extended.json'; // Make the request $this->curl->get($url); diff --git a/view/adminhtml/layout/default.xml b/view/adminhtml/layout/default.xml index 0d2e6ed..a7801e2 100644 --- a/view/adminhtml/layout/default.xml +++ b/view/adminhtml/layout/default.xml @@ -15,5 +15,8 @@ + + + diff --git a/view/adminhtml/templates/review-popup.phtml b/view/adminhtml/templates/review-popup.phtml new file mode 100644 index 0000000..d71b5f4 --- /dev/null +++ b/view/adminhtml/templates/review-popup.phtml @@ -0,0 +1,106 @@ + + + + + +renderTag('script', [], $script, false) ?> + From 40dcfb8614d1a73aed082ed0c35e32b0503b7d29 Mon Sep 17 00:00:00 2001 From: "ivan.hrytsai" Date: Fri, 14 Nov 2025 15:30:42 +0200 Subject: [PATCH 2/5] 14254-Magefan-extensions-review-popup-in-Magento-admin --- Block/Adminhtml/ReviewPopup.php | 115 +++++- Controller/Adminhtml/Review/Index.php | 122 ++++++ Model/Config.php | 15 + etc/adminhtml/system.xml | 4 + etc/config.xml | 1 + view/adminhtml/layout/default.xml | 2 +- view/adminhtml/templates/review-popup.phtml | 392 +++++++++++++++----- 7 files changed, 553 insertions(+), 98 deletions(-) create mode 100644 Controller/Adminhtml/Review/Index.php diff --git a/Block/Adminhtml/ReviewPopup.php b/Block/Adminhtml/ReviewPopup.php index 7260c04..bcc90f3 100644 --- a/Block/Adminhtml/ReviewPopup.php +++ b/Block/Adminhtml/ReviewPopup.php @@ -10,35 +10,78 @@ use Magento\Directory\Helper\Data as DirectoryHelper; use Magento\Framework\Json\Helper\Data as JsonHelper; - +use Magento\Framework\App\Route\Config as RouteConfig; +use Magefan\Community\Model\Config; class ReviewPopup extends \Magento\Backend\Block\Template { + private $reviewUrl = null; + private $moduleInfo = null; + /** * @var \Magefan\Community\Model\GetModuleInfo */ private $getModuleInfo; - private $reviewUrl = null; + /** + * @var RouteConfig + */ + private $routeConfig; + /** + * @var Config + */ + private $config; + + /** + * @param \Magento\Backend\Block\Template\Context $context + * @param \Magefan\Community\Model\GetModuleInfo $getModuleInfo + * @param RouteConfig $routeConfig + * @param Config $config + * @param \Magento\Backend\Model\Auth\Session $authSession + * @param array $data + * @param JsonHelper|null $jsonHelper + * @param DirectoryHelper|null $directoryHelper + */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magefan\Community\Model\GetModuleInfo $getModuleInfo, + RouteConfig $routeConfig, + Config $config, + \Magento\Backend\Model\Auth\Session $authSession, array $data = [], ?JsonHelper $jsonHelper = null, ?DirectoryHelper $directoryHelper = null) { $this->getModuleInfo = $getModuleInfo; + $this->routeConfig = $routeConfig; + $this->config = $config; + $this->_authSession = $authSession; parent::__construct($context, $data, $jsonHelper, $directoryHelper); } + /** + * Get module name + * + * @return string|null + */ public function getModuleName() { - return ucfirst($this->_request->getModuleName()); + $frontModule = $this->routeConfig->getModulesByFrontName($this->getRequest()->getModuleName()); + + if (!empty($frontModule[0]) && strpos($frontModule[0], 'Magefan_') !== false) { + return $frontModule[0]; + } + return null; } + /** + * Get module review url + * + * @return mixed|null + */ public function getModuleReviewUrl() { if ($this->reviewUrl === null) { - $info = $this->getModuleInfo->execute($this->getModuleName()); + $info = $this->getModuleInfo(); if (!empty($info['review_url'])) { $this->reviewUrl = $info['review_url']; @@ -48,8 +91,66 @@ public function getModuleReviewUrl() return $this->reviewUrl; } - private function canDisplay() { - return $this->getModuleReviewUrl(); // && перевірити чи є + /** + * Get the product name + * + * @return string + */ + public function getProductName(): string + { + $info = $this->getModuleInfo();; + if (!empty($info['product_name'])) { + return str_replace('Magento 2', 'Magefan' , $info['product_name']); + } + return ''; + } + + /** + * Get module info + * + * @return array|\Magento\Framework\DataObject|mixed + */ + private function getModuleInfo() { + if ($this->reviewUrl === null) { + $this->moduleInfo = $this->getModuleInfo->execute($this->getModuleName()); + } + return $this->moduleInfo; + } + + + /** + * Check if we can display block + * + * @return bool + */ + private function canDisplay() : bool + { + $display = true; + $moduleName = $this->getModuleName(); + if ($moduleName && strpos($moduleName, '_') !== false) { + $moduleName = explode('_', $moduleName)[1]; + $extra = $this->_authSession->getUser()->getExtra(); + if (!empty($extra)) { + $extra = json_decode($extra, true); + $rev = $extra['mf_review'][$moduleName] ?? null; + if ($rev && $rev['leave_review'] === false) { + if (!empty($rev['updated_at'])) { + try { + $given = new \DateTime($rev['updated_at']); + $threeDaysAgo = new \DateTime('-3 days'); + if ($given > $threeDaysAgo) { + $display = false; + } + + } catch (\Exception $e) { + } + } + } else { + $display = false; + } + } + } + return $this->config->receiveReview() && $this->getModuleReviewUrl() && $this->getProductName() && $display; } /** @@ -57,7 +158,7 @@ private function canDisplay() { * * @return string */ - protected function _toHtml() + protected function _toHtml(): string { if (!$this->canDisplay()) { return ''; diff --git a/Controller/Adminhtml/Review/Index.php b/Controller/Adminhtml/Review/Index.php new file mode 100644 index 0000000..5b1bba1 --- /dev/null +++ b/Controller/Adminhtml/Review/Index.php @@ -0,0 +1,122 @@ +_authSession = $authSession; + $this->resultJsonFactory = $resultJsonFactory; + $this->curl = $curl; + parent::__construct($context); + } + + public function execute() + { + $reviewData = []; + $result = $this->resultJsonFactory->create(); + $moduleName = $this->_request->getParam('module'); + if (!$moduleName) { + return $result->setData(['success' => false, 'message' => __('Module name is not specified.')]); + } + $reviewAction = $this->_request->getParam('action'); + if (!$reviewAction) { + return $result->setData(['success' => false, 'message' => __('Action is not specified.')]); + } + if ($reviewAction == 'cancel') { + return $this->remindLater($moduleName); + } + + foreach (self::REQUIRED_FIELDS as $field) { + if (!$this->_request->getParam($field)) { + return $result->setData(['success' => false,'message' => __('Please fill all required fields.')]); + } + $reviewData[$field] = $this->_request->getParam($field); + } + try { + $url = $reviewAction; + $postData = $reviewData; + + $this->curl->post($url, $postData); + + $response = $this->curl->getBody(); + + $this->setReviewStatus($moduleName); + return $result->setData([ + 'success' => true, + 'response' => $response + ]); + } catch (\Exception $e) { + return $result->setData([ + 'success' => false, + 'message' => $e->getMessage() + ]); + } + } + + private function remindLater($moduleName) + { + $result = $this->resultJsonFactory->create(); + try { + $this->setReviewStatus($moduleName, false); + return $result->setData(['success' => true]); + } catch (\Exception $e) { + return $result->setData(['success' => false]); + } + } + + private function setReviewStatus($moduleName, $status = true) + { + $user = $this->_authSession->getUser(); + $extra = $user->getExtra(); + $extraArray = !empty($extra) ? json_decode($extra,true) : []; + $extraArray['mf_review'][$moduleName] = [ + 'updated_at' => (new \DateTime())->format('Y-m-d H:i:s'), + 'leave_review' => $status + ]; + $user->setExtra(json_encode($extraArray)); + $user->save(); + } +} \ No newline at end of file diff --git a/Model/Config.php b/Model/Config.php index de27ce2..0225175 100644 --- a/Model/Config.php +++ b/Model/Config.php @@ -19,6 +19,7 @@ class Config const XML_PATH_RECEIVE_NEWS = 'mfextension/notification/news'; const XML_PATH_RECEIVE_TIPS_AND_TRICKS = 'mfextension/notification/tip_trick'; const XML_PATH_RECEIVE_GENERAL_INFORMATION = 'mfextension/notification/general'; + const XML_PATH_RECEIVE_REVIEW = 'mfextension/notification/review'; /** * Display Menu @@ -110,6 +111,20 @@ public function receiveGeneralInformation($storeId = null) ); } + /** + * Receive Review + * + * @param null $storeId + * @return bool + */ + public function receiveReview($storeId = null): bool + { + return (bool)$this->getConfig( + self::XML_PATH_RECEIVE_REVIEW, + $storeId + ); + } + /** * Receive Notifications * diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 85e0db2..82c17f6 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -46,6 +46,10 @@ Magento\Config\Model\Config\Source\Yesno + + + Magento\Config\Model\Config\Source\Yesno + diff --git a/etc/config.xml b/etc/config.xml index 3800058..4e842a8 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -15,6 +15,7 @@ 1 1 1 + 1 1 diff --git a/view/adminhtml/layout/default.xml b/view/adminhtml/layout/default.xml index a7801e2..9efdb66 100644 --- a/view/adminhtml/layout/default.xml +++ b/view/adminhtml/layout/default.xml @@ -16,7 +16,7 @@ - + diff --git a/view/adminhtml/templates/review-popup.phtml b/view/adminhtml/templates/review-popup.phtml index d71b5f4..5989591 100644 --- a/view/adminhtml/templates/review-popup.phtml +++ b/view/adminhtml/templates/review-popup.phtml @@ -1,106 +1,318 @@ -