-
Notifications
You must be signed in to change notification settings - Fork 9.3k
/
Validator.php
137 lines (128 loc) · 4.4 KB
/
Validator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Theme\Model\Design\Config;
use \Magento\Framework\Exception\LocalizedException;
use \Magento\Theme\Api\Data\DesignConfigInterface;
use \Magento\Theme\Api\Data\DesignConfigDataInterface;
use \Magento\Framework\Mail\TemplateInterfaceFactory as TemplateFactory;
use \Magento\Framework\Filter\Template;
use \Magento\Framework\Filter\Template\Tokenizer\Parameter as ParameterTokenizer;
/**
* Design configuration validator
*/
class Validator
{
/**
* @var string[]
*/
private $fields = [];
/**
* @var TemplateFactory
*/
private $templateFactory;
/**
* Initialize dependencies.
*
* @param TemplateFactory $templateFactory
* @param string[] $fields
*/
public function __construct(TemplateFactory $templateFactory, $fields = [])
{
$this->templateFactory = $templateFactory;
$this->fields = $fields;
}
/**
* Validate if design configuration has recursive references
*
* @param DesignConfigInterface $designConfig
*
* @throws LocalizedException
* @return void
*/
public function validate(DesignConfigInterface $designConfig)
{
/** @var DesignConfigDataInterface[] $designConfigData */
$designConfigData = $designConfig->getExtensionAttributes()->getDesignConfigData();
$elements = [];
foreach ($designConfigData as $designElement) {
if (!in_array($designElement->getFieldConfig()['field'], $this->fields)) {
continue;
}
/* Save mapping between field names and config paths */
$elements[$designElement->getFieldConfig()['field']] = [
'config_path' => $designElement->getPath(),
'value' => $designElement->getValue()
];
}
foreach ($elements as $name => $data) {
$templateId = $data['value'];
$text = $this->getTemplateText($templateId, $designConfig);
// Check if template body has a reference to the same config path
if (preg_match_all(Template::CONSTRUCTION_TEMPLATE_PATTERN, $text, $constructions, PREG_SET_ORDER)) {
foreach ($constructions as $construction) {
$configPath = isset($construction[2]) ? $construction[2] : '';
$params = $this->getParameters($configPath);
if (isset($params['config_path']) && $params['config_path'] == $data['config_path']) {
throw new LocalizedException(
__(
"The %templateName contains an incorrect configuration. The template has " .
"a reference to itself. Either remove or change the reference.",
["templateName" => $name]
)
);
};
}
}
}
}
/**
* Returns store identifier if is store scope
*
* @param DesignConfigInterface $designConfig
* @return string|bool
*/
private function getScopeId(DesignConfigInterface $designConfig)
{
if ($designConfig->getScope() == 'stores') {
return $designConfig->getScopeId();
}
return false;
}
/**
* Load template text in configured scope
*
* @param integer|string $templateId
* @param DesignConfigInterface $designConfig
* @return string
*/
private function getTemplateText($templateId, DesignConfigInterface $designConfig)
{
// Load template object by configured template id
$template = $this->templateFactory->create();
$template->emulateDesign($this->getScopeId($designConfig));
if (is_numeric($templateId)) {
$template->load($templateId);
} else {
$template->loadDefault($templateId);
}
$text = $template->getTemplateText();
$template->revertDesign();
return $text;
}
/**
* Return associative array of parameters.
*
* @param string $value raw parameters
* @return array
*/
private function getParameters($value)
{
$tokenizer = new ParameterTokenizer();
$tokenizer->setString($value);
$params = $tokenizer->tokenize();
return $params;
}
}