public function testValidateNoRecursiveReference() { $fieldConfig = ['path' => 'no/reference', 'fieldset' => 'no/reference', 'field' => 'no_reference']; $designConfigMock = $this->getMockBuilder(\Magento\Theme\Api\Data\DesignConfigInterface::class)->getMock(); $designConfigExtensionMock = $this->getMockBuilder(\Magento\Theme\Api\Data\DesignConfigExtensionInterface::class)->setMethods(['getDesignConfigData'])->getMock(); $designElementMock = $this->getMockBuilder(\Magento\Theme\Model\Data\Design\Config\Data::class)->disableOriginalConstructor()->getMock(); $designConfigMock->expects($this->once())->method('getExtensionAttributes')->willReturn($designConfigExtensionMock); $designConfigExtensionMock->expects($this->once())->method('getDesignConfigData')->willReturn([$designElementMock]); $designElementMock->expects($this->any())->method('getFieldConfig')->willReturn($fieldConfig); $designElementMock->expects($this->once())->method('getPath')->willReturn($fieldConfig['path']); $designElementMock->expects($this->once())->method('getValue')->willReturn($fieldConfig['field']); $templateMock = $this->getMockBuilder(\Magento\Email\Model\TemplateInterface::class)->setMethods(['getTemplateText', 'emulateDesign', 'loadDefault', 'revertDesign'])->getMock(); $this->templateFactoryMock->expects($this->once())->method('create')->willReturn($templateMock); $templateMock->expects($this->once())->method('getTemplateText')->willReturn(file_get_contents(__DIR__ . '/_files/template_fixture.html')); $this->model->validate($designConfigMock); }
/** * 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) { // Load template object by configured template id $template = $this->templateFactory->create(); $template->emulateDesign($designConfig->getScopeId()); $templateId = $data['value']; if (is_numeric($templateId)) { $template->load($templateId); } else { $template->loadDefault($templateId); } $text = $template->getTemplateText(); $template->revertDesign(); // 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])); } } } } }