From 9a81e5e8ce190352ca68fa865526ae9be73d5f61 Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Tue, 20 Aug 2019 16:55:28 +0300 Subject: [PATCH 1/6] Implemented custom-widgets support --- src/Model/Template/FilterEmulate.php | 102 +++++++++++++++++++++++++++ src/etc/di.xml | 1 + 2 files changed, 103 insertions(+) create mode 100644 src/Model/Template/FilterEmulate.php diff --git a/src/Model/Template/FilterEmulate.php b/src/Model/Template/FilterEmulate.php new file mode 100644 index 0000000..2d17857 --- /dev/null +++ b/src/Model/Template/FilterEmulate.php @@ -0,0 +1,102 @@ + + * @copyright Copyright (c) 2018 Scandiweb, Ltd (https://scandiweb.com) + */ + +namespace ScandiPWA\CmsGraphQl\Model\Template; + +/** + * Class FilterEmulate + * @package ScandiPWA\CmsGraphQl\Model\Template + */ +class FilterEmulate extends \Magento\Widget\Model\Template\FilterEmulate +{ + + /** + * Array of keys that will not be escaped + * in custom widget html output + * + * @var string[] + */ + public static $widgetParamsWhitelist = ['type']; + + /** + * General method for generate widget + * + * @param string[] $construction + * @return string + */ + public function generateWidget($construction) + { + $params = $this->getParameters($construction[2]); + + // Determine what name block should have in layout + $name = null; + if (isset($params['name'])) { + $name = $params['name']; + } + + if (isset($this->_storeId) && !isset($params['store_id'])) { + $params['store_id'] = $this->_storeId; + } + + // validate required parameter type or id + if (!empty($params['type'])) { + $type = $params['type']; + } elseif (!empty($params['id'])) { + $preConfigured = $this->_widgetResource->loadPreconfiguredWidget($params['id']); + $type = $preConfigured['widget_type']; + $params = $preConfigured['parameters']; + } else { + return ''; + } + + // we have no other way to avoid fatal errors for type like 'cms/widget__link', '_cms/widget_link' etc. + $xml = $this->_widget->getWidgetByClassType($type); + if ($xml === null) { + return ''; + } + + // If widget is not CmsBlock let frontend handle it + if ($params['type'] !== 'Magento\Cms\Block\Widget\Block') { + return $this->widgetToHtml($params); + } + + // define widget block and check the type is instance of Widget Interface + $widget = $this->_layout->createBlock($type, $name, ['data' => $params]); + if (!$widget instanceof \Magento\Widget\Block\BlockInterface) { + return ''; + } + + return $widget->toHtml(); + } + + /** + * Generates widget html-like instructions + * + * @param string[] $params + * @return string + */ + public function widgetToHtml($params) + { + unset($params['template']); + + $paramsList = []; + foreach ($params as $key => $value) { + if (!in_array($key, FilterEmulate::$widgetParamsWhitelist)) { + $value = $this->_escaper->escapeHtmlAttr($value); + } + + $paramsList[] = "$key='$value'"; + } + + $attributes = implode(' ', $paramsList); + + return ""; + } +} diff --git a/src/etc/di.xml b/src/etc/di.xml index afeb709..d03ddb6 100644 --- a/src/etc/di.xml +++ b/src/etc/di.xml @@ -1,4 +1,5 @@ + From 480de79564a33b8e70ea06765772c8972ed08a9a Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Thu, 22 Aug 2019 13:23:01 +0300 Subject: [PATCH 2/6] Changed logic to use DI --- src/Model/Template/FilterEmulate.php | 62 ++++++++++++++++++++++++---- src/etc/di.xml | 13 +++++- src/etc/module.xml | 1 + 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/Model/Template/FilterEmulate.php b/src/Model/Template/FilterEmulate.php index 2d17857..d4b350b 100644 --- a/src/Model/Template/FilterEmulate.php +++ b/src/Model/Template/FilterEmulate.php @@ -10,6 +10,22 @@ namespace ScandiPWA\CmsGraphQl\Model\Template; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\State; +use Magento\Framework\Escaper; +use Magento\Framework\Stdlib\StringUtils; +use Magento\Framework\UrlInterface; +use Magento\Framework\View\Asset\Repository; +use Magento\Framework\View\LayoutFactory; +use Magento\Framework\View\LayoutInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Variable\Model\Source\Variables; +use Magento\Variable\Model\VariableFactory; +use Magento\Widget\Block\BlockInterface; +use Magento\Widget\Model\Widget; +use Pelago\Emogrifier; +use Psr\Log\LoggerInterface; + /** * Class FilterEmulate * @package ScandiPWA\CmsGraphQl\Model\Template @@ -23,7 +39,38 @@ class FilterEmulate extends \Magento\Widget\Model\Template\FilterEmulate * * @var string[] */ - public static $widgetParamsWhitelist = ['type']; + public $widgetParamsWhitelist; + /** + * Array of objects that will parsed to custom widget syntax + * + * @var object[] + */ + public $availableFilters; + + public function __construct( + StringUtils $string, + LoggerInterface $logger, + Escaper $escaper, + Repository $assetRepo, + ScopeConfigInterface $scopeConfig, + VariableFactory $coreVariableFactory, + StoreManagerInterface $storeManager, + LayoutInterface $layout, + LayoutFactory $layoutFactory, + State $appState, + UrlInterface $urlModel, + Emogrifier $emogrifier, + Variables $configVariables, + \Magento\Widget\Model\ResourceModel\Widget $widgetResource, + Widget $widget, + array $availableFilters, + array $widgetParamsWhitelist + ) + { + parent::__construct($string, $logger, $escaper, $assetRepo, $scopeConfig, $coreVariableFactory, $storeManager, $layout, $layoutFactory, $appState, $urlModel, $emogrifier, $configVariables, $widgetResource, $widget); + $this->availableFilters = $availableFilters; + $this->widgetParamsWhitelist = $widgetParamsWhitelist; + } /** * General method for generate widget @@ -62,14 +109,13 @@ public function generateWidget($construction) return ''; } - // If widget is not CmsBlock let frontend handle it - if ($params['type'] !== 'Magento\Cms\Block\Widget\Block') { - return $this->widgetToHtml($params); + if ($widgetName = array_search($params['type'], $this->availableFilters)) { + return $this->widgetToHtml($params, $widgetName); } // define widget block and check the type is instance of Widget Interface $widget = $this->_layout->createBlock($type, $name, ['data' => $params]); - if (!$widget instanceof \Magento\Widget\Block\BlockInterface) { + if (!$widget instanceof BlockInterface) { return ''; } @@ -80,15 +126,17 @@ public function generateWidget($construction) * Generates widget html-like instructions * * @param string[] $params + * @param string $widgetName * @return string */ - public function widgetToHtml($params) + public function widgetToHtml($params, $widgetName) { unset($params['template']); + $params['type'] = $widgetName; $paramsList = []; foreach ($params as $key => $value) { - if (!in_array($key, FilterEmulate::$widgetParamsWhitelist)) { + if (!in_array($key, $this->widgetParamsWhitelist)) { $value = $this->_escaper->escapeHtmlAttr($value); } diff --git a/src/etc/di.xml b/src/etc/di.xml index d03ddb6..020c151 100644 --- a/src/etc/di.xml +++ b/src/etc/di.xml @@ -1,5 +1,16 @@ + + + + Magento\Cms\Block\Widget\Page\Link + + + type + + + + - + diff --git a/src/etc/module.xml b/src/etc/module.xml index bcd4d1b..f3571d9 100644 --- a/src/etc/module.xml +++ b/src/etc/module.xml @@ -4,6 +4,7 @@ + \ No newline at end of file From 384f1d162b85c0231feceb2361e4436c0ad7163f Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Fri, 23 Aug 2019 11:05:13 +0300 Subject: [PATCH 3/6] Added slider support --- src/etc/di.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/etc/di.xml b/src/etc/di.xml index 020c151..6ce136c 100644 --- a/src/etc/di.xml +++ b/src/etc/di.xml @@ -3,7 +3,8 @@ - Magento\Cms\Block\Widget\Page\Link + Scandiweb\Slider\Block\Widget\Slider + Magento\Catalog\Block\Product\Widget\NewWidget type From eceeb3eb8165497855a9db3c2ea3c87e180c1a3e Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Mon, 2 Sep 2019 16:28:48 +0300 Subject: [PATCH 4/6] Added new Catalog Product List filter --- src/Api/AttributeHandlerInterface.php | 7 +++++++ src/Model/Template/FilterEmulate.php | 15 +++++++++++---- src/etc/di.xml | 4 +++- 3 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 src/Api/AttributeHandlerInterface.php diff --git a/src/Api/AttributeHandlerInterface.php b/src/Api/AttributeHandlerInterface.php new file mode 100644 index 0000000..e3e6177 --- /dev/null +++ b/src/Api/AttributeHandlerInterface.php @@ -0,0 +1,7 @@ +availableFilters = $availableFilters; - $this->widgetParamsWhitelist = $widgetParamsWhitelist; + $this->widgetParamsWhitelist = $widgetUnescapedParams; + $this->widgetCustomParamsHandlers = $widgetCustomParamsHandlers; } /** @@ -136,7 +141,9 @@ public function widgetToHtml($params, $widgetName) $paramsList = []; foreach ($params as $key => $value) { - if (!in_array($key, $this->widgetParamsWhitelist)) { + if (key_exists($key, $this->widgetCustomParamsHandlers)) { + $value = $this->widgetCustomParamsHandlers[$key]->resolve($value); + } else if (!in_array($key, $this->widgetParamsWhitelist)) { $value = $this->_escaper->escapeHtmlAttr($value); } diff --git a/src/etc/di.xml b/src/etc/di.xml index 6ce136c..349fe9a 100644 --- a/src/etc/di.xml +++ b/src/etc/di.xml @@ -5,10 +5,12 @@ Scandiweb\Slider\Block\Widget\Slider Magento\Catalog\Block\Product\Widget\NewWidget + Magento\CatalogWidget\Block\Product\ProductsList - + type + From d3a88def2f14b612f50ea3c7a839bfa9ab58a381 Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Thu, 5 Sep 2019 18:13:29 +0300 Subject: [PATCH 5/6] Added Base64 encoding for Conditions --- .../Resolver/Attribute/ConditionsEncoded.php | 22 +++++++++++++++++++ src/Model/Template/FilterEmulate.php | 5 ++--- src/etc/di.xml | 4 +++- 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 src/Model/Resolver/Attribute/ConditionsEncoded.php diff --git a/src/Model/Resolver/Attribute/ConditionsEncoded.php b/src/Model/Resolver/Attribute/ConditionsEncoded.php new file mode 100644 index 0000000..3668bf8 --- /dev/null +++ b/src/Model/Resolver/Attribute/ConditionsEncoded.php @@ -0,0 +1,22 @@ + + * @copyright Copyright (c) 2018 Scandiweb, Ltd (https://scandiweb.com) + */ + +namespace ScandiPWA\CmsGraphQl\Model\Resolver\Attribute; + +use ScandiPWA\CmsGraphQl\Api\AttributeHandlerInterface; + +class ConditionsEncoded implements AttributeHandlerInterface +{ + + public function resolve(string $value): string + { + return base64_encode($value); + } +} diff --git a/src/Model/Template/FilterEmulate.php b/src/Model/Template/FilterEmulate.php index 08c4973..cb9465d 100644 --- a/src/Model/Template/FilterEmulate.php +++ b/src/Model/Template/FilterEmulate.php @@ -69,8 +69,7 @@ public function __construct( array $availableFilters, array $widgetUnescapedParams, array $widgetCustomParamsHandlers - ) - { + ) { parent::__construct($string, $logger, $escaper, $assetRepo, $scopeConfig, $coreVariableFactory, $storeManager, $layout, $layoutFactory, $appState, $urlModel, $emogrifier, $configVariables, $widgetResource, $widget); $this->availableFilters = $availableFilters; $this->widgetParamsWhitelist = $widgetUnescapedParams; @@ -143,7 +142,7 @@ public function widgetToHtml($params, $widgetName) foreach ($params as $key => $value) { if (key_exists($key, $this->widgetCustomParamsHandlers)) { $value = $this->widgetCustomParamsHandlers[$key]->resolve($value); - } else if (!in_array($key, $this->widgetParamsWhitelist)) { + } elseif (!in_array($key, $this->widgetParamsWhitelist)) { $value = $this->_escaper->escapeHtmlAttr($value); } diff --git a/src/etc/di.xml b/src/etc/di.xml index 349fe9a..429a7a0 100644 --- a/src/etc/di.xml +++ b/src/etc/di.xml @@ -10,7 +10,9 @@ type - + + ScandiPWA\CmsGraphQl\Model\Resolver\Attribute\ConditionsEncoded + From be165e2f54f870abafad232dd17f04f71bb7bdde Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Thu, 5 Sep 2019 18:15:53 +0300 Subject: [PATCH 6/6] Removed empty line --- src/Model/Resolver/Attribute/ConditionsEncoded.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Model/Resolver/Attribute/ConditionsEncoded.php b/src/Model/Resolver/Attribute/ConditionsEncoded.php index 3668bf8..ec67dac 100644 --- a/src/Model/Resolver/Attribute/ConditionsEncoded.php +++ b/src/Model/Resolver/Attribute/ConditionsEncoded.php @@ -14,7 +14,6 @@ class ConditionsEncoded implements AttributeHandlerInterface { - public function resolve(string $value): string { return base64_encode($value);