From 0e892c059cd690bec58a526d42d5772ce826fb78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sammy=20Nordstr=C3=B6m?= Date: Mon, 17 Jun 2019 16:10:35 +0200 Subject: [PATCH] Adds config validation --- Helper/Config.php | 205 +++++++++++++++++++++++------- Observer/ConfigChangeObserver.php | 137 ++++++++++++++++++++ etc/adminhtml/events.xml | 6 + 3 files changed, 304 insertions(+), 44 deletions(-) create mode 100644 Observer/ConfigChangeObserver.php create mode 100644 etc/adminhtml/events.xml diff --git a/Helper/Config.php b/Helper/Config.php index 073bd4a..abaf33a 100644 --- a/Helper/Config.php +++ b/Helper/Config.php @@ -2,19 +2,26 @@ namespace PayEx\Core\Helper; +use Magento\Config\Model\Config\PathValidator; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Config\Storage\WriterInterface; use Magento\Framework\App\Helper\AbstractHelper; +use Magento\Framework\App\Helper\Context; +use Magento\Framework\Exception\ValidatorException; use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\App\Helper\Context; use Magento\Store\Model\ScopeInterface; -use Magento\Framework\App\Config\ScopeConfigInterface; + +use PayEx\Core\Logger\Logger; class Config extends AbstractHelper { protected $storeManager; - protected $objectManager; protected $scopeConfig; + protected $pathValidator; + protected $configWriter; + + protected $logger; protected $moduleDependencies = []; @@ -23,42 +30,90 @@ class Config extends AbstractHelper /** * Config constructor. * @param Context $context - * @param ObjectManagerInterface $objectManager * @param StoreManagerInterface $storeManager * @param ScopeConfigInterface $scopeConfig + * @param PathValidator $pathValidator + * @param WriterInterface $configWriter + * @param Logger $logger */ public function __construct( Context $context, - ObjectManagerInterface $objectManager, StoreManagerInterface $storeManager, - ScopeConfigInterface $scopeConfig + ScopeConfigInterface $scopeConfig, + PathValidator $pathValidator, + WriterInterface $configWriter, + Logger $logger ) { - $this->objectManager = $objectManager; $this->storeManager = $storeManager; $this->scopeConfig = $scopeConfig; + $this->pathValidator = $pathValidator; + $this->configWriter = $configWriter; + $this->logger = $logger; parent::__construct($context); } /** + * @param string $module + * @return mixed|string + */ + protected function getConfigSection($module = '') + { + $configSectionConst = "\\" . get_called_class() . "::XML_CONFIG_SECTION"; + + if ($module != '') { + $moduleConfigHelper = '\\' . str_replace('_', '\\', $module) . '\\Helper\\Config'; + if (defined($moduleConfigHelper . '::XML_CONFIG_SECTION')) { + $configSectionConst = $moduleConfigHelper . '::XML_CONFIG_SECTION'; + } + } + + return (defined($configSectionConst)) ? constant($configSectionConst) : self::XML_CONFIG_SECTION; + } + + /** + * @param string $module * @return string */ - protected function getConfigGroup() + protected function getConfigGroup($module = '') { - $constant = "\\" . get_called_class() . "::XML_CONFIG_GROUP"; - return (defined($constant)) ? constant($constant) : 'core'; + $configGroupConst = "\\" . get_called_class() . "::XML_CONFIG_GROUP"; + + if ($module != '') { + $moduleConfigHelper = '\\' . str_replace('_', '\\', $module) . '\\Helper\\Config'; + if (defined($moduleConfigHelper . '::XML_CONFIG_GROUP')) { + $configGroupConst = $moduleConfigHelper . '::XML_CONFIG_GROUP'; + } + } + + return (defined($configGroupConst)) ? constant($configGroupConst) : 'core'; } /** - * @param $code + * @param string $code + * @param string $module * @return string */ - public function getConfigPath($code = '') + public function getConfigPath($code = '', $module = '') { if ($code != '') { - return self::XML_CONFIG_SECTION . '/' . $this->getConfigGroup() . '/' . $code; + return $this->getConfigSection($module) . '/' . $this->getConfigGroup($module) . '/' . $code; } - return self::XML_CONFIG_SECTION . '/' . $this->getConfigGroup(); + return $this->getConfigSection($module) . '/' . $this->getConfigGroup($module); + } + + /** + * @param string $code + * @param string $module + * @return string + */ + public function getPaymentConfigPath($code = '', $module = '') + { + if ($code != '') { + return 'payment/' . $this->getConfigSection($module) . '_' . $this->getConfigGroup($module) . '/' . $code; + } + + return 'payment/' . $this->getConfigSection($module) . '_' . $this->getConfigGroup($module); } /** @@ -74,7 +129,7 @@ public function getValue($code, $store = null) return $this->scopeConfig->getValue( $this->getConfigPath($code), - ScopeInterface::SCOPE_STORE, + $this->getScope($store), $store ); } @@ -99,59 +154,121 @@ public function getPaymentValue($code, $paymentMethod, $store = null) } return $this->scopeConfig->getValue( - sprintf('payment/' . $paymentMethod . '/%s', $code), - ScopeInterface::SCOPE_STORE, + $this->getPaymentConfigPath($code, $paymentMethod), + $this->getScope($store), $store ); } + /** + * @param string $module + * @return bool + */ + public function isPayment($module = '') + { + $isPayment = false; + + try { + $paymentConfigPath = $this->getPaymentConfigPath('active', $module); + if ($this->pathValidator->validate($paymentConfigPath)) { + $isPayment = true; + } + } catch (ValidatorException $e) { + } + + return $isPayment; + } + /** * @param Store|int|string|null $store + * @param string $module * @return bool */ - public function isActive($store = null) + public function isActive($store = null, $module = '') { - if (!in_array($this->_getModuleName(), $this->moduleDependencies)) { - $this->moduleDependencies[] = $this->_getModuleName(); + $isActive = false; + + if ($isPayment = $this->isPayment($module)) { + $isActive = $this->scopeConfig->isSetFlag($this->getPaymentConfigPath('active', $module)); + } + + if (!$isPayment) { + $isActive = $this->scopeConfig->isSetFlag($this->getConfigPath('active', $module)); } - foreach($this->moduleDependencies as $dependency) { + if (!$isActive || $module != '') { + return $isActive; + } + + if (in_array($this->_getModuleName(), $this->moduleDependencies)) { + $key = array_search($this->_getModuleName(), $this->moduleDependencies); + unset($this->moduleDependencies[$key]); + } + + foreach ($this->moduleDependencies as $dependency) { if ($dependency == 'PayEx_Core') { continue; } - $moduleConfigHelper = '\\' . str_replace('_' , '\\', $dependency) . '\\Helper\\Config'; - - if (defined($moduleConfigHelper . '::XML_CONFIG_SECTION') - && defined($moduleConfigHelper . '::XML_CONFIG_GROUP')) { + $isActive = $this->isActive($store, $dependency); - $configPath = constant($moduleConfigHelper . '::XML_CONFIG_SECTION') . '/' . - constant($moduleConfigHelper . '::XML_CONFIG_GROUP') . '/' . 'active'; + if (!$isActive) { + break; + } - $isActive = $this->scopeConfig->getValue( - $configPath, - ScopeInterface::SCOPE_STORE, + if ($isActive && $dependency == 'PayEx_Client') { + $merchantToken = $this->scopeConfig->getValue( + $this->getConfigPath('merchant_token', $dependency), + $this->getScope($store), $store ); - if (!$isActive) { - - $paymentConfigPath = 'payment/' . constant($moduleConfigHelper . '::XML_CONFIG_SECTION') . '_' . - constant($moduleConfigHelper . '::XML_CONFIG_GROUP') . '/' . 'active'; + if (trim($merchantToken) == '') { + $isActive = false; + break; + } - $isPaymentActive = $this->scopeConfig->getValue( - $paymentConfigPath, - ScopeInterface::SCOPE_STORE, - $store - ); + $payeeId = $this->scopeConfig->getValue( + $this->getConfigPath('payee_id', $dependency), + $this->getScope($store), + $store + ); - if (!$isPaymentActive) { - return false; - } + if (trim($payeeId) == '') { + $isActive = false; + break; } } } - return true; + return $isActive; + } + + public function deactivateModule($scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $store = null, $module = '') + { + if ($this->isPayment($module)) { + $configPath = $this->getPaymentConfigPath('active', $module); + } + + if (!isset($configPath)) { + $configPath = $this->getConfigPath('active', $module); + } + + $this->configWriter->save($configPath, 0, $scope, $store); + } + + /** + * Get the scope value of the store + * + * @param Store $store + * @return string + */ + private function getScope($store = null) + { + if ($store === null) { + return ScopeConfigInterface::SCOPE_TYPE_DEFAULT; + } + + return ScopeInterface::SCOPE_STORES; } } diff --git a/Observer/ConfigChangeObserver.php b/Observer/ConfigChangeObserver.php new file mode 100644 index 0000000..a08406d --- /dev/null +++ b/Observer/ConfigChangeObserver.php @@ -0,0 +1,137 @@ +scopeConfig = $scopeConfig; + $this->storeManager = $storeManager; + $this->coreConfig = $coreConfig; + $this->logger = $logger; + } + + /** + * @param Observer $observer + * @throws ValidatorException + */ + public function execute(Observer $observer) + { + if (self::$isRunning) { + return; + } + + self::$isRunning = true; + + $store = (int)$observer->getData('store'); + $website = (int)$observer->getData('website'); + + $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT; + $scopeId = 0; + + if ($website) { + $scope = ScopeInterface::SCOPE_WEBSITES; + $scopeId = $website; + } + + if ($store) { + $scope = ScopeInterface::SCOPE_STORES; + $scopeId = $store; + } + + $changedPaths = $observer->getData('changed_paths'); + + $payexActiveChangePaths = array_filter($changedPaths, function ($var) { + return ( + preg_match('|payex/[^/]+/active|', $var) || + preg_match('|payment/payex_[^/]+/active|', $var) + ); + }); + + if (count($payexActiveChangePaths) == 0) { + return; + } + + $deactivated = []; + + foreach ($payexActiveChangePaths as $changePath) { + $isActivated = $this->scopeConfig->getValue( + $changePath, + $scope, + $scopeId + ); + + $moduleConfigGroup = ''; + + if (strpos($changePath, 'payment/payex_') !== false) { + $moduleConfigGroup = substr( + $changePath, + strlen('payment/payex_'), + 0 - strlen('/active') + ); + } + + if ($moduleConfigGroup == '') { + $moduleConfigGroup = substr( + $changePath, + strlen('payex/'), + 0 - strlen('/active') + ); + } + + $moduleNameParts = explode('_', $moduleConfigGroup); + $moduleNameParts = array_map('ucfirst', $moduleNameParts); + $moduleName = implode('', $moduleNameParts); + + $objectManager = ObjectManager::getInstance(); + $moduleConfigHelper = $objectManager->get('PayEx\\' . $moduleName . '\\Helper\\Config'); + + $isValid = $moduleConfigHelper->isActive($store); + + if ($isActivated && !$isValid) { + $moduleConfigHelper->deactivateModule($scope, $scopeId); + $deactivated[$changePath] = implode(' ', $moduleNameParts); + } + } + + self::$isRunning = false; + + if (count($deactivated) > 0) { + throw new ValidatorException( + __('Unable to activate PayEx module(s): ' . implode(', ', $deactivated) . '. ' . + 'Please make sure the PayEx Client and any other required settings are correct.') + ); + } + } +} diff --git a/etc/adminhtml/events.xml b/etc/adminhtml/events.xml new file mode 100644 index 0000000..b52f207 --- /dev/null +++ b/etc/adminhtml/events.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file