diff --git a/Block/Adminhtml/ReviewPopup.php b/Block/Adminhtml/ReviewPopup.php new file mode 100644 index 0000000..df7b765 --- /dev/null +++ b/Block/Adminhtml/ReviewPopup.php @@ -0,0 +1,182 @@ +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() { + $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(); + + if (!empty($info['review_url'])) { + $this->reviewUrl = $info['review_url']; + } + } + + return $this->reviewUrl; + } + + /** + * 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 + { + $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); + $resourceConnection = $objectManager->get('Magento\Framework\App\ResourceConnection'); + $display = true; + $moduleName = $this->getModuleName(); + if ($moduleName && strpos($moduleName, '_') !== false) { + $moduleName = explode('_', $moduleName)[1]; + $userId = $this->_authSession->getUser()->getId(); + $connection = $resourceConnection->getConnection(); + $tableName = $resourceConnection->getTableName('mf_review'); + $select = $connection->select() + ->from($tableName) + ->where('user_id = ?', $userId) + ->where('module_name = ?', $moduleName) + ->limit(1); + + $review = $connection->fetchRow($select); + + if ($review) { + if ((int)$review['is_reviewed'] === 0) { + $updatedAt = $review['updated_at'] ?? null; + if ($updatedAt) { + try { + $given = new \DateTime($updatedAt); + $threeDaysAgo = new \DateTime('-3 days'); + if ($given > $threeDaysAgo) { + $display = false; + } + } catch (\Exception $e) { + // ignore + } + } + } else { + $display = false; + } + } + } + return $this->config->receiveReview() + && $this->getModuleReviewUrl() + && $this->getProductName() + && $display; + } + + /** + * Prepare html output + * + * @return string + */ + protected function _toHtml(): string + { + if (!$this->canDisplay()) { + return ''; + } + return parent::_toHtml(); + } +} \ No newline at end of file diff --git a/Controller/Adminhtml/Review/Index.php b/Controller/Adminhtml/Review/Index.php new file mode 100644 index 0000000..e1bdf02 --- /dev/null +++ b/Controller/Adminhtml/Review/Index.php @@ -0,0 +1,173 @@ + [0 => 16], + 2 => [1 => 17], + 3 => [2 => 18], + 4 => [3 => 19], + 5 => [4 => 20] + ]; + + /** + * @var \Magento\Backend\Model\Auth\Session + */ + private $_authSession; + + /** + * @var JsonFactory + */ + private $resultJsonFactory; + + /** + * @var Curl + */ + private $curl; + + /** + * @param Context $context + * @param \Magento\Backend\Model\Auth\Session $authSession + * @param JsonFactory $resultJsonFactory + * @param Curl $curl + */ + public function __construct( + Context $context, + \Magento\Backend\Model\Auth\Session $authSession, + JsonFactory $resultJsonFactory, + Curl $curl + ) + { + $this->_authSession = $authSession; + $this->resultJsonFactory = $resultJsonFactory; + $this->curl = $curl; + parent::__construct($context); + } + + /** + * Executes the main review processing logic based on request parameters. + * + * @return \Magento\Framework\Controller\Result\Json + */ + 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); + + if ($field == 'ratings') { + $reviewData[$field] = self::RATINGS_OPTION[$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() + ]); + } + } + + /** + * Handle a reminder to delay review prompt for a specific module. + * + * @param string $moduleName + * @return \Magento\Framework\Controller\Result\Json + */ + 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]); + } + } + + /** + * Updates or inserts the review status for a given module and user. + * + * @param string $moduleName + * @param bool $status + * + * @return void + */ + private function setReviewStatus($moduleName, $status = true) + { + $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); + $resourceConnection = $objectManager->get('Magento\Framework\App\ResourceConnection'); + $connection = $resourceConnection->getConnection(); + $tableName = $resourceConnection->getTableName('mf_review'); + $userId = $this->_authSession->getUser()->getId(); + + $select = $connection->select() + ->from($tableName) + ->where('user_id = ?', $userId) + ->where('module_name = ?', $moduleName); + $existing = $connection->fetchRow($select); + + $data = [ + 'module_name' => $moduleName, + 'user_id' => $userId, + 'is_reviewed' => $status ? 1 : 0, + 'updated_at' => (new \DateTime())->format('Y-m-d H:i:s'), + ]; + + if ($existing) { + $connection->update( + $tableName, + $data, + ['id = ?' => $existing['id']] + ); + } else { + $data['created_at'] = (new \DateTime())->format('Y-m-d H:i:s'); + $connection->insert($tableName, $data); + } + } +} \ 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/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/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/etc/db_schema.xml b/etc/db_schema.xml new file mode 100644 index 0000000..2cc6ba3 --- /dev/null +++ b/etc/db_schema.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + +
+
diff --git a/view/adminhtml/layout/default.xml b/view/adminhtml/layout/default.xml index 0d2e6ed..9efdb66 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..ec1b5fb --- /dev/null +++ b/view/adminhtml/templates/review-popup.phtml @@ -0,0 +1,319 @@ + + + +getModuleName(); +if (strpos($moduleName, '_') !== false) { + $moduleName = explode('_', $moduleName)[1]; +} +?> + + +getProductName()) . "', + content: formClone, + buttons: [{ + text: '" . __('Submit Review') . "', + class: 'action primary accept', + click: function () { + if (formClone.validation() && formClone.valid()) { + formClone.submit(); + this.closeModal(true); + } + } + }] + }); + } + }, 5000) + }); + }); + +"; ?> +renderTag('script', [], $script, false) ?> +