{"id":331273,"date":"2022-03-30T15:00:52","date_gmt":"2022-03-30T15:00:52","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=331273"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=331273","title":{"rendered":"<span>Magento 2. \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e \u0432\u0430\u0441, \u0445\u0430\u0431\u0440\u0430\u0432\u0447\u0430\u043d\u0435! \u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u0440\u0430\u0432\u0448\u0438\u0441\u044c \u0441\u043c\u0435\u043b\u043e\u0441\u0442\u0438 \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u043f\u0435\u0440\u0432\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e, \u0442\u043e\u0447\u043d\u0435\u0435 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c, \u0432 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439, \u043a\u0430\u043a \u043c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0442\u0435\u043c\u0435, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u043a\u0430\u043a \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a \u0444\u0430\u0439\u043b\u043e\u0432.<\/p>\n<p>\u0418\u0442\u0430\u043a \u043d\u0430\u0447\u043d\u0435\u043c.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c, \u0438 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043c\u043e\u0434\u0443\u043b\u044f<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/registration.php<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php  \\Magento\\Framework\\Component\\ComponentRegistrar::register(     \\Magento\\Framework\\Component\\ComponentRegistrar::MODULE,     'Mr_ImageDynamicConfig',     __DIR__ );<\/code><\/pre>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/etc\/module.xml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\"?> &lt;config xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:magento:framework:Module\/etc\/module.xsd\">     &lt;module name=\"Mr_ImageDynamicConfig\" setup_version=\"1.0.0\"\/> &lt;\/config> <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u0447\u043d\u0435\u043c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u0448\u0430\u0433 \u0437\u0430 \u0448\u0430\u0433\u043e\u043c:<\/p>\n<p>\u0418 \u043f\u0435\u0440\u0432\u044b\u043c \u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0430\u043c \u043a\u043e\u043d\u0444\u0438\u0433:<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/etc\/adminhtml\/system.xml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\"?>  &lt;config xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"         xsi:noNamespaceSchemaLocation=\"urn:magento:module:Magento_Config:etc\/system_file.xsd\">     &lt;system>         &lt;tab id=\"mr\" translate=\"label\" sortOrder=\"400\">             &lt;label>Mr&lt;\/label>         &lt;\/tab>         &lt;section id=\"swatch\" translate=\"label\" type=\"text\" sortOrder=\"300\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"1\">             &lt;class>separator-top&lt;\/class>             &lt;label>Image Array Swatch&lt;\/label>             &lt;tab>mr&lt;\/tab>             &lt;resource>Mr_ImageDynamicConfig::config&lt;\/resource>             &lt;group id=\"image_serializer\" translate=\"label\" type=\"text\" sortOrder=\"140\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"1\">                 &lt;field id=\"image\" translate=\"label\" type=\"text\" sortOrder=\"20\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\">                     &lt;label>Image&lt;\/label>                     &lt;frontend_model>Mr\\ImageDynamicConfig\\Block\\Adminhtml\\System\\Config\\ImageFields&lt;\/frontend_model>                     &lt;backend_model>Mr\\ImageDynamicConfig\\Model\\Config\\Backend\\Serialized\\ArraySerialized&lt;\/backend_model>                     &lt;upload_dir>var\/uploads\/swatch\/image_serializer&lt;\/upload_dir>                 &lt;\/field>             &lt;\/group>         &lt;\/section>     &lt;\/system> &lt;\/config> <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441\u0442\u0440\u043e\u043a\u0430 &lt;frontend_model>Mr\\ImageDynamicConfig\\Block\\Adminhtml\\System\\Config\\ImageFields&lt;\/frontend_model> \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u043d\u043e\u0432\u0430, \u0438 \u043a\u043b\u0430\u0441\u0441 ImageFields \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442 \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u043a \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/Block\/Adminhtml\/System\/Config\/ImageFields.php<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php declare(strict_types=1);  namespace Mr\\ImageDynamicConfig\\Block\\Adminhtml\\System\\Config;  use Magento\\Config\\Block\\System\\Config\\Form\\Field\\FieldArray\\AbstractFieldArray;  class ImageFields extends AbstractFieldArray {     const IMAGE_FIELD = 'image';     const NAME_FIELD = 'name';     private $imageRenderer;      protected function _prepareToRender()     {         $this->addColumn(             self::IMAGE_FIELD,             [                 'label' => __('Image'),                 'renderer' => $this->getImageRenderer()             ]         );          $this->addColumn(             self::NAME_FIELD,             [                 'label' => __('Name'),             ]         );          $this->_addAfter       = false;         $this->_addButtonLabel = __('Add');     }      private function getImageRenderer()     {         if (!$this->imageRenderer) {             $this->imageRenderer = $this->getLayout()->createBlock(                 \\Mr\\ImageDynamicConfig\\Block\\Adminhtml\\Form\\Field\\ImageColumn::class,                 '',                 ['data' => ['is_render_to_js_template' => true]]             );         }         return $this->imageRenderer;     } }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0442\u0443\u0442 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 _prepareToRender \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435, \u0438 \u0435\u0441\u043b\u0438 \u0432 \u043a\u043e\u043b\u043e\u043d\u043a\u0435 \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0435 \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0435 \u043e\u0442 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0438\u043d\u043f\u0443\u0442\u0430, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0435\u0440 (\u043c\u0435\u0442\u043e\u0434 getImageRenderer). \u041d\u0430 \u0441\u0442\u0440\u043e\u043a\u0435 38 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u0431\u043b\u043e\u043a \\Mr\\ImageDynamicConfig\\Block\\Adminhtml\\Form\\Field\\ImageColumn, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u043c \u0432\u043c\u0435\u0441\u0442\u043e \u0438\u043d\u043f\u0443\u0442\u0430 html &#8212; \u043a\u043e\u0434 \u0441 \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0444\u0430\u0439\u043b\u0430<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/Block\/Adminhtml\/Form\/Field\/ImageColumn.php<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php declare(strict_types=1);  namespace Mr\\ImageDynamicConfig\\Block\\Adminhtml\\Form\\Field;  use Mr\\ImageDynamicConfig\\Block\\Adminhtml\\ImageButton;  class ImageColumn extends \\Magento\\Framework\\View\\Element\\AbstractBlock {     public function setInputName(string $value)     {         return $this->setName($value);     }      public function setInputId(string $value)     {         return $this->setId($value);     }      protected function _toHtml(): string     {         $imageButton = $this->getLayout()             ->createBlock(ImageButton::class)             ->setData('id', $this->getId())             ->setData('name', $this->getName());         return $imageButton->toHtml();     } } <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 _toHtml \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u0431\u043b\u043e\u043a Mr\\ImageDynamicConfig\\Block\\Adminhtml\\ImageButton, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u043c \u0442\u0435\u043c\u043f\u043b\u0435\u0439\u0442 \u0441 html &#8212; \u043a\u043e\u0434\u043e\u043c<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/Block\/Adminhtml\/\/ImageButton.php<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php declare(strict_types=1);  namespace Mr\\ImageDynamicConfig\\Block\\Adminhtml;  class ImageButton extends \\Magento\\Backend\\Block\\Template {     protected $_template = 'Mr_ImageDynamicConfig::config\/array_serialize\/swatch_image.phtml';      private $assetRepository;      public function __construct(         \\Magento\\Backend\\Block\\Template\\Context $context,         \\Magento\\Framework\\View\\Asset\\Repository $assetRepository,         array $data = []     ) {         $this->assetRepository = $assetRepository;         parent::__construct($context, $data);     }      public function getAssertRepository(): \\Magento\\Framework\\View\\Asset\\Repository     {         return $this->assetRepository;     } }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 getAssertRepository \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u043b\u043d\u044b\u0439 url \u043d\u0430 css \u0444\u0430\u0439\u043b \u0432 \u0442\u0435\u043c\u043f\u043b\u0435\u0439\u0442\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/view\/adminhtml\/templates\/config\/array_serialize\/swatch_image.phtml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php \/*** @var \\Mr\\ImageDynamicConfig\\Block\\Adminhtml\\ImageButton $block *\/ $css = $block->getAssertRepository()->createAsset(\"Mr_ImageDynamicConfig::css\/image_button.css\"); ?> &lt;link rel=\"stylesheet\" type=\"text\/css\" media=\"all\" href=\"&lt;?php \/* @escapeNotVerified *\/echo $css->getUrl() ?>\"\/>  &lt;div class=\"upload-file\" data-id=\"&lt;?=$block->getId()?>\">     &lt;div class=\"upload-file__block upload-file__block_first\">         &lt;img class=\"upload-file__block__img\" id=\"swatch_image_image_&lt;?= $block->getId() ?>\" src=\"\">     &lt;\/div>     &lt;div class=\"upload-file__block\">         &lt;input class=\"upload-file__input\" hidden type=\"file\" name=\"&lt;?= $block->getName() ?>\" id=\"swatch_image_input_&lt;?= $block->getId() ?>\" value=\"\"\/>         &lt;label class=\"upload-file__label\" for=\"swatch_image_input_&lt;?= $block->getId() ?>\">             &lt;?= __(\"File\") ?>         &lt;\/label>     &lt;\/div>     &lt;input class=\"upload-file__input\" type=\"hidden\" id=\"&lt;?=$block->getId()?>\"> &lt;\/div>   &lt;script type=\"text\/javascript\">     require([\"jquery\"], function (jq) {         jq(function () {             const id = \"&lt;?=$block->getId()?>\"             const imageId = \"swatch_image_image_&lt;?=$block->getId()?>\"             const data = jq(\"#\" + id).val();             if (data) {                 jq(\"#\" + imageId).attr(\"src\", data)                 jq(\"#\" + imageId).attr(\"value\", data)             }         });     }); &lt;\/script><\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0442\u0435\u043c\u043f\u043b\u0435\u0439\u0442\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0438\u043d\u043f\u0443\u0442 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u0438 \u0432\u044b\u0432\u043e\u0434\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438. \u0421 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043e\u0447\u0435\u043d\u044c \u0441\u0442\u0440\u0430\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043a\u0440\u044b\u0442\u044b\u0439 \u0438\u043d\u043f\u0443\u0442:<\/p>\n<pre><code class=\"php\">&lt;input class=\"upload-file__input\" type=\"hidden\" id=\"&lt;?=$block->getId()?>\"><\/code><\/pre>\n<p>\u0430 \u043f\u043e\u0441\u043b\u0435 \u0438\u0437 \u043d\u0435\u0433\u043e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0432 img \u0442\u0435\u0433 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"javascript\">jq(function () {             const id = \"&lt;?=$block->getId()?>\"             const imageId = \"swatch_image_image_&lt;?=$block->getId()?>\"             const data = jq(\"#\" + id).val();             if (data) {                 jq(\"#\" + imageId).attr(\"src\", data)                 jq(\"#\" + imageId).attr(\"value\", data)             }         });<\/code><\/pre>\n<p>\u041d\u043e, \u043a\u043e\u0433\u0434\u0430 Magento \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442 \u0444\u043e\u0440\u043c\u0443 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0443\u0434\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043e\u043d\u0430 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0439\u0442\u0438 input \u0441 id \u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 value \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041f\u043e-\u044d\u0442\u043e\u043c\u0443 \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0441\u043a\u0440\u044b\u0442\u044b\u0439 \u0438\u043d\u043f\u0443\u0442 \u0438 \u0447\u0435\u0440\u0435\u0437 jquery \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u043b \u0432 source img \u043f\u0443\u0442\u044c \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438 frontend_model \u0438 \u043a\u0430\u043a \u0432\u044b\u0432\u0435\u0441\u0442\u0438 image input \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c  \u044d\u0442\u0430\u043f &#8212; \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a.<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f backend_model, \u0438 \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433, \u0442\u043e \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u0432 backend_model Magento\\Config\\Model\\Config\\Backend\\Serialized\\ArraySerialized \u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0440\u0435\u0448\u0435\u043d\u044b, \u043d\u043e ArraySerialized \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a, \u0438 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043d\u0430 \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0432\u043e\u0439 array serializer<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/Model\/Config\/Backend\/Serialized\/ArraySerialized<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php declare(strict_types=1);  namespace Mr\\ImageDynamicConfig\\Model\\Config\\Backend\\Serialized;  use Magento\\Framework\\Serialize\\Serializer\\Json; use Mr\\ImageDynamicConfig\\Block\\Adminhtml\\System\\Config\\ImageFields;  class ArraySerialized extends \\Magento\\Config\\Model\\Config\\Backend\\Serialized\\ArraySerialized {     private $imageUploaderFactory;     private $imageConfig;      public function __construct(         \\Magento\\Framework\\Model\\Context $context,         \\Magento\\Framework\\Registry $registry,         \\Magento\\Framework\\App\\Config\\ScopeConfigInterface $config,         \\Magento\\Framework\\App\\Cache\\TypeListInterface $cacheTypeList,         \\Mr\\ImageDynamicConfig\\Model\\Config\\ImageConfig $imageConfig,         \\Mr\\ImageDynamicConfig\\Model\\ImageUploaderFactory $imageUploaderFactory,         \\Magento\\Framework\\Model\\ResourceModel\\AbstractResource $resource = null,         \\Magento\\Framework\\Data\\Collection\\AbstractDb $resourceCollection = null,         array $data = [],         Json $serializer = null     ) {         $this->imageUploaderFactory = $imageUploaderFactory;         $this->imageConfig = $imageConfig;         parent::__construct(             $context,             $registry,             $config,             $cacheTypeList,             $resource,             $resourceCollection,             $data,             $serializer         );     }      public function beforeSave(): ArraySerialized     {         $value = $this->getValue();         $value = $this->mapRows($value);         $this->setValue($value);         return parent::beforeSave();     }      private function mapRows(array $rows): array     {         $iconUploader = $this->imageUploaderFactory->create([             'path' => $this->getPath(),             'uploadDir' => $this->getUploadDir(),         ]);         $uploadedFiles = $iconUploader->upload();         $swatches = $this->imageConfig->getSwatches();         foreach ($rows as $id => $data) {             if (isset($uploadedFiles[$id])) {                 $rows[$id][ImageFields::IMAGE_FIELD] = $uploadedFiles[$id];                 continue;             }             if (!isset($swatches[$id])) {                 unset($swatches[$id]);             } else {                 $rows[$id] = $this->matchRow($data, $swatches[$id]);             }         }         return $rows;     }      private function matchRow(array $row, array $configTabIcon): array     {         foreach ($row as $fieldName => $value) {             if (is_array($value) &amp;&amp; $fieldName == ImageFields::IMAGE_FIELD) {                 $row[ImageFields::IMAGE_FIELD] = $configTabIcon[ImageFields::IMAGE_FIELD];             }         }         return $row;     }      private function getUploadDir(): string     {         $fieldConfig = $this->getFieldConfig();          if (!array_key_exists('upload_dir', $fieldConfig)) {             throw new \\Magento\\Framework\\Exception\\LocalizedException(                 __('The base directory to upload file is not specified.')             );         }          if (is_array($fieldConfig['upload_dir'])) {             $uploadDir = $fieldConfig['upload_dir']['value'];             if (array_key_exists('scope_info', $fieldConfig['upload_dir'])                 &amp;&amp; $fieldConfig['upload_dir']['scope_info']             ) {                 $uploadDir = $this->_appendScopeInfo($uploadDir);             }              if (array_key_exists('config', $fieldConfig['upload_dir'])) {                 $uploadDir = $this->getUploadDirPath($uploadDir);             }         } else {             $uploadDir = (string)$fieldConfig['upload_dir'];         }          return $uploadDir;     } }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0422\u0443\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u0430\u043e\u0441\u0442\u0440\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043c\u0435\u0442\u043e\u0434\u0435 mapRows, \u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0430\u0445 50-54 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443, \u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0430\u0445 56-66 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0430, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c\/\u0437\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0430 \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u0442\u043e\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c<\/p>\n<p>\u043a\u043b\u0430\u0441\u0441 ImageUploader:<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/Model\/ImageUploader.php<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php declare(strict_types=1);  namespace Mr\\ImageDynamicConfig\\Model;  use Magento\\MediaStorage\\Model\\File\\Uploader;  class ImageUploader {     private $arrayFileModifier;     private $uploaderFactory;     private $uploadDir;     private $allowExtensions;      public function __construct(         \\Mr\\ImageDynamicConfig\\Model\\ArrayFileModifier $arrayFileModifier,         \\Magento\\MediaStorage\\Model\\File\\UploaderFactory $uploaderFactory,         string $uploadDir,         array $allowExtensions     ) {         $this->arrayFileModifier = $arrayFileModifier;         $this->uploaderFactory = $uploaderFactory;         $this->uploadDir = $uploadDir;         $this->allowExtensions = $allowExtensions;     }      public function upload(): array     {         $result = [];         $files = $this->arrayFileModifier->modify();         if (!$files) {             return $result;         }          foreach ($files as $id => $file) {             try {                 $uploader = $this->uploaderFactory->create(['fileId' => $id]);                 $uploader->setAllowedExtensions($this->allowExtensions);                 $uploader->setAllowRenameFiles(true);                 $uploader->addValidateCallback('size', $this, 'validateMaxSize');                 $newFileName = $this->getNewFileName($uploader);                 $uploader->save($this->uploadDir, $newFileName);                 $result[$id] = $this->getFullFilPath($newFileName);             } catch (\\Exception $e) {                 throw new \\Magento\\Framework\\Exception\\LocalizedException(__('%1', $e->getMessage()));             }         }         return $result;     }      private function getNewFileName(Uploader $uploader): string     {         return sprintf(             '%s.%s',             uniqid(),             $uploader->getFileExtension()         );     }      private function getFullFilPath(string $filename): string     {         return sprintf(             '\/%s\/%s',             $this->uploadDir,             $filename         );     } }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 \u0435\u0441\u0442\u044c \u0441\u0442\u0440\u043e\u0447\u043a\u0430 $files = $this->arrayFileModifier->modify(); \u042d\u0442\u043e\u0442 modifier \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043c\u0430\u0441\u0441\u0438\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a \u043d\u0430\u043c \u043f\u0440\u0438\u0448\u0435\u043b, \u0438\u0437 \u0444\u043e\u0440\u043c\u044b \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6f0\/b5e\/5a3\/6f0b5e5a3ea70069ff357de97869e8e8.png\" width=\"1054\" height=\"526\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6f0\/b5e\/5a3\/6f0b5e5a3ea70069ff357de97869e8e8.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0432 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u0434\u043b\u044f \u0430\u043f\u043b\u043e\u0443\u0434\u0435\u0440\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/db4\/26a\/e3d\/db426ae3dce5e30ae1e6aaaf4af9d0fc.png\" width=\"902\" height=\"372\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/db4\/26a\/e3d\/db426ae3dce5e30ae1e6aaaf4af9d0fc.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c id $uploader = $this->uploaderFactory->create([&#8216;fileId&#8217; => $id]);<\/p>\n<p>\u0438 \u0430\u043f\u043b\u043e\u0443\u0434\u0435\u0440 \u0437\u043d\u0430\u043b \u0441 \u0447\u0435\u043c \u0435\u043c\u0443 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043f\u0430\u0437\u043b\u0438\u043a &#8212; \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u043c<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/Model\/Config\/ImageConfig<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php declare(strict_types=1);  namespace Mr\\ImageDynamicConfig\\Model\\Config;  use Magento\\Framework\\App\\Config\\ScopeConfigInterface; use Magento\\Framework\\Serialize\\SerializerInterface;  class ImageConfig {     const XML_PATH_IMAGE_SERIALIZER = 'swatch\/image_serializer\/';      private $scopeConfig;     private $serializer;      public function __construct(         SerializerInterface $serializer,         ScopeConfigInterface $scopeConfig     ) {         $this->scopeConfig = $scopeConfig;         $this->serializer = $serializer;     }          public function getSwatches(): array     {         $data = $this->scopeConfig->getValue(self::XML_PATH_IMAGE_SERIALIZER . 'image');         if (!$data) {             return [];         }         return $this->serializer->unserialize($data);     } }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0418 \u0441\u0430\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/12d\/643\/0dd\/12d6430ddd35eac5fb8077403f53f484.png\" width=\"1162\" height=\"342\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/12d\/643\/0dd\/12d6430ddd35eac5fb8077403f53f484.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/541\/b95\/0eb\/541b950eb2d042500b5072d6742f29cb.png\" width=\"1162\" height=\"346\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/541\/b95\/0eb\/541b950eb2d042500b5072d6742f29cb.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u042d\u043f\u0438\u043b\u043e\u0433<\/p>\n<p><a href=\"https:\/\/github.com\/mavlikhanov\/image_dymanic_config\/tree\/main\" rel=\"noopener noreferrer nofollow\">\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043c\u043e\u0434\u0443\u043b\u044f \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435<\/a><\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0438\/\u0438\u043b\u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439. \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f\/\u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\/\u0432\u043e\u043f\u0440\u043e\u0441\u044b \u0434\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438. <\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/658167\/\"> https:\/\/habr.com\/ru\/post\/658167\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e \u0432\u0430\u0441, \u0445\u0430\u0431\u0440\u0430\u0432\u0447\u0430\u043d\u0435! \u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u0440\u0430\u0432\u0448\u0438\u0441\u044c \u0441\u043c\u0435\u043b\u043e\u0441\u0442\u0438 \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u043f\u0435\u0440\u0432\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e, \u0442\u043e\u0447\u043d\u0435\u0435 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c, \u0432 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439, \u043a\u0430\u043a \u043c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0442\u0435\u043c\u0435, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u043a\u0430\u043a \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a \u0444\u0430\u0439\u043b\u043e\u0432.<\/p>\n<p>\u0418\u0442\u0430\u043a \u043d\u0430\u0447\u043d\u0435\u043c.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c, \u0438 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043c\u043e\u0434\u0443\u043b\u044f<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/registration.php<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php  \\Magento\\Framework\\Component\\ComponentRegistrar::register(     \\Magento\\Framework\\Component\\ComponentRegistrar::MODULE,     'Mr_ImageDynamicConfig',     __DIR__ );<\/code><\/pre>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/etc\/module.xml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\"?> &lt;config xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:magento:framework:Module\/etc\/module.xsd\">     &lt;module name=\"Mr_ImageDynamicConfig\" setup_version=\"1.0.0\"\/> &lt;\/config> <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u0447\u043d\u0435\u043c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u0448\u0430\u0433 \u0437\u0430 \u0448\u0430\u0433\u043e\u043c:<\/p>\n<p>\u0418 \u043f\u0435\u0440\u0432\u044b\u043c \u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0430\u043c \u043a\u043e\u043d\u0444\u0438\u0433:<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/etc\/adminhtml\/system.xml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\"?>  &lt;config xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"         xsi:noNamespaceSchemaLocation=\"urn:magento:module:Magento_Config:etc\/system_file.xsd\">     &lt;system>         &lt;tab id=\"mr\" translate=\"label\" sortOrder=\"400\">             &lt;label>Mr&lt;\/label>         &lt;\/tab>         &lt;section id=\"swatch\" translate=\"label\" type=\"text\" sortOrder=\"300\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"1\">             &lt;class>separator-top&lt;\/class>             &lt;label>Image Array Swatch&lt;\/label>             &lt;tab>mr&lt;\/tab>             &lt;resource>Mr_ImageDynamicConfig::config&lt;\/resource>             &lt;group id=\"image_serializer\" translate=\"label\" type=\"text\" sortOrder=\"140\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"1\">                 &lt;field id=\"image\" translate=\"label\" type=\"text\" sortOrder=\"20\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\">                     &lt;label>Image&lt;\/label>                     &lt;frontend_model>Mr\\ImageDynamicConfig\\Block\\Adminhtml\\System\\Config\\ImageFields&lt;\/frontend_model>                     &lt;backend_model>Mr\\ImageDynamicConfig\\Model\\Config\\Backend\\Serialized\\ArraySerialized&lt;\/backend_model>                     &lt;upload_dir>var\/uploads\/swatch\/image_serializer&lt;\/upload_dir>                 &lt;\/field>             &lt;\/group>         &lt;\/section>     &lt;\/system> &lt;\/config> <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441\u0442\u0440\u043e\u043a\u0430 &lt;frontend_model>Mr\\ImageDynamicConfig\\Block\\Adminhtml\\System\\Config\\ImageFields&lt;\/frontend_model> \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u043d\u043e\u0432\u0430, \u0438 \u043a\u043b\u0430\u0441\u0441 ImageFields \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442 \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u043a \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/Block\/Adminhtml\/System\/Config\/ImageFields.php<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php declare(strict_types=1);  namespace Mr\\ImageDynamicConfig\\Block\\Adminhtml\\System\\Config;  use Magento\\Config\\Block\\System\\Config\\Form\\Field\\FieldArray\\AbstractFieldArray;  class ImageFields extends AbstractFieldArray {     const IMAGE_FIELD = 'image';     const NAME_FIELD = 'name';     private $imageRenderer;      protected function _prepareToRender()     {         $this->addColumn(             self::IMAGE_FIELD,             [                 'label' => __('Image'),                 'renderer' => $this->getImageRenderer()             ]         );          $this->addColumn(             self::NAME_FIELD,             [                 'label' => __('Name'),             ]         );          $this->_addAfter       = false;         $this->_addButtonLabel = __('Add');     }      private function getImageRenderer()     {         if (!$this->imageRenderer) {             $this->imageRenderer = $this->getLayout()->createBlock(                 \\Mr\\ImageDynamicConfig\\Block\\Adminhtml\\Form\\Field\\ImageColumn::class,                 '',                 ['data' => ['is_render_to_js_template' => true]]             );         }         return $this->imageRenderer;     } }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0442\u0443\u0442 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 _prepareToRender \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435, \u0438 \u0435\u0441\u043b\u0438 \u0432 \u043a\u043e\u043b\u043e\u043d\u043a\u0435 \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0435 \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0435 \u043e\u0442 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0438\u043d\u043f\u0443\u0442\u0430, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0435\u0440 (\u043c\u0435\u0442\u043e\u0434 getImageRenderer). \u041d\u0430 \u0441\u0442\u0440\u043e\u043a\u0435 38 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u0431\u043b\u043e\u043a \\Mr\\ImageDynamicConfig\\Block\\Adminhtml\\Form\\Field\\ImageColumn, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u043c \u0432\u043c\u0435\u0441\u0442\u043e \u0438\u043d\u043f\u0443\u0442\u0430 html &#8212; \u043a\u043e\u0434 \u0441 \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0444\u0430\u0439\u043b\u0430<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/Block\/Adminhtml\/Form\/Field\/ImageColumn.php<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php declare(strict_types=1);  namespace Mr\\ImageDynamicConfig\\Block\\Adminhtml\\Form\\Field;  use Mr\\ImageDynamicConfig\\Block\\Adminhtml\\ImageButton;  class ImageColumn extends \\Magento\\Framework\\View\\Element\\AbstractBlock {     public function setInputName(string $value)     {         return $this->setName($value);     }      public function setInputId(string $value)     {         return $this->setId($value);     }      protected function _toHtml(): string     {         $imageButton = $this->getLayout()             ->createBlock(ImageButton::class)             ->setData('id', $this->getId())             ->setData('name', $this->getName());         return $imageButton->toHtml();     } } <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 _toHtml \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u0431\u043b\u043e\u043a Mr\\ImageDynamicConfig\\Block\\Adminhtml\\ImageButton, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u043c \u0442\u0435\u043c\u043f\u043b\u0435\u0439\u0442 \u0441 html &#8212; \u043a\u043e\u0434\u043e\u043c<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/Block\/Adminhtml\/\/ImageButton.php<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php declare(strict_types=1);  namespace Mr\\ImageDynamicConfig\\Block\\Adminhtml;  class ImageButton extends \\Magento\\Backend\\Block\\Template {     protected $_template = 'Mr_ImageDynamicConfig::config\/array_serialize\/swatch_image.phtml';      private $assetRepository;      public function __construct(         \\Magento\\Backend\\Block\\Template\\Context $context,         \\Magento\\Framework\\View\\Asset\\Repository $assetRepository,         array $data = []     ) {         $this->assetRepository = $assetRepository;         parent::__construct($context, $data);     }      public function getAssertRepository(): \\Magento\\Framework\\View\\Asset\\Repository     {         return $this->assetRepository;     } }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 getAssertRepository \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u043b\u043d\u044b\u0439 url \u043d\u0430 css \u0444\u0430\u0439\u043b \u0432 \u0442\u0435\u043c\u043f\u043b\u0435\u0439\u0442\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/view\/adminhtml\/templates\/config\/array_serialize\/swatch_image.phtml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php \/*** @var \\Mr\\ImageDynamicConfig\\Block\\Adminhtml\\ImageButton $block *\/ $css = $block->getAssertRepository()->createAsset(\"Mr_ImageDynamicConfig::css\/image_button.css\"); ?> &lt;link rel=\"stylesheet\" type=\"text\/css\" media=\"all\" href=\"&lt;?php \/* @escapeNotVerified *\/echo $css->getUrl() ?>\"\/>  &lt;div class=\"upload-file\" data-id=\"&lt;?=$block->getId()?>\">     &lt;div class=\"upload-file__block upload-file__block_first\">         &lt;img class=\"upload-file__block__img\" id=\"swatch_image_image_&lt;?= $block->getId() ?>\" src=\"\">     &lt;\/div>     &lt;div class=\"upload-file__block\">         &lt;input class=\"upload-file__input\" hidden type=\"file\" name=\"&lt;?= $block->getName() ?>\" id=\"swatch_image_input_&lt;?= $block->getId() ?>\" value=\"\"\/>         &lt;label class=\"upload-file__label\" for=\"swatch_image_input_&lt;?= $block->getId() ?>\">             &lt;?= __(\"File\") ?>         &lt;\/label>     &lt;\/div>     &lt;input class=\"upload-file__input\" type=\"hidden\" id=\"&lt;?=$block->getId()?>\"> &lt;\/div>   &lt;script type=\"text\/javascript\">     require([\"jquery\"], function (jq) {         jq(function () {             const id = \"&lt;?=$block->getId()?>\"             const imageId = \"swatch_image_image_&lt;?=$block->getId()?>\"             const data = jq(\"#\" + id).val();             if (data) {                 jq(\"#\" + imageId).attr(\"src\", data)                 jq(\"#\" + imageId).attr(\"value\", data)             }         });     }); &lt;\/script><\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0442\u0435\u043c\u043f\u043b\u0435\u0439\u0442\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0438\u043d\u043f\u0443\u0442 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u0438 \u0432\u044b\u0432\u043e\u0434\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438. \u0421 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043e\u0447\u0435\u043d\u044c \u0441\u0442\u0440\u0430\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043a\u0440\u044b\u0442\u044b\u0439 \u0438\u043d\u043f\u0443\u0442:<\/p>\n<pre><code class=\"php\">&lt;input class=\"upload-file__input\" type=\"hidden\" id=\"&lt;?=$block->getId()?>\"><\/code><\/pre>\n<p>\u0430 \u043f\u043e\u0441\u043b\u0435 \u0438\u0437 \u043d\u0435\u0433\u043e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0432 img \u0442\u0435\u0433 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"javascript\">jq(function () {             const id = \"&lt;?=$block->getId()?>\"             const imageId = \"swatch_image_image_&lt;?=$block->getId()?>\"             const data = jq(\"#\" + id).val();             if (data) {                 jq(\"#\" + imageId).attr(\"src\", data)                 jq(\"#\" + imageId).attr(\"value\", data)             }         });<\/code><\/pre>\n<p>\u041d\u043e, \u043a\u043e\u0433\u0434\u0430 Magento \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442 \u0444\u043e\u0440\u043c\u0443 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0443\u0434\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043e\u043d\u0430 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0439\u0442\u0438 input \u0441 id \u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 value \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041f\u043e-\u044d\u0442\u043e\u043c\u0443 \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0441\u043a\u0440\u044b\u0442\u044b\u0439 \u0438\u043d\u043f\u0443\u0442 \u0438 \u0447\u0435\u0440\u0435\u0437 jquery \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u043b \u0432 source img \u043f\u0443\u0442\u044c \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438 frontend_model \u0438 \u043a\u0430\u043a \u0432\u044b\u0432\u0435\u0441\u0442\u0438 image input \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c  \u044d\u0442\u0430\u043f &#8212; \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a.<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f backend_model, \u0438 \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433, \u0442\u043e \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u0432 backend_model Magento\\Config\\Model\\Config\\Backend\\Serialized\\ArraySerialized \u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0440\u0435\u0448\u0435\u043d\u044b, \u043d\u043e ArraySerialized \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a, \u0438 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043d\u0430 \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0432\u043e\u0439 array serializer<\/p>\n<details class=\"spoiler\">\n<summary>Mr\/ImageDynamicConfig\/Model\/Config\/Backend\/Serialized\/ArraySerialized<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php declare(strict_types=1);  namespace Mr\\ImageDynamicConfig\\Model\\Config\\Backend\\Serialized;  use Magento\\Framework\\Serialize\\Serializer\\Json; use Mr\\ImageDynamicConfig\\Block\\Adminhtml\\System\\Config\\ImageFields;  class ArraySerialized extends \\Magento\\Config\\Model\\Config\\Backend\\Serialized\\ArraySerialized {     private $imageUploaderFactory;     private $imageConfig;      public function __construct(         \\Magento\\Framework\\Model\\Context $context,         \\Magento\\Framework\\Registry $registry,         \\Magento\\Framework\\App\\Config\\ScopeConfigInterface $config,         \\Magento\\Framework\\App\\Cache\\TypeListInterface $cacheTypeList,         \\Mr\\ImageDynamicConfig\\Model\\Config\\ImageConfig $imageConfig,         \\Mr\\ImageDynamicConfig\\Model\\ImageUploaderFactory $imageUploaderFactory,         \\Magento\\Framework\\Model\\ResourceModel\\AbstractResource $resource = null,         \\Magento\\Framework\\Data\\Collection\\AbstractDb $resourceCollection = null,         array $data = [],         Json $serializer = null     ) {         $this->imageUploaderFactory = $imageUploaderFactory;         $this->imageConfig = $imageConfig;         parent::__construct(             $context,             $registry,             $config,             $cacheTypeList,             $resource,  <\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-331273","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/331273","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=331273"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/331273\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=331273"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=331273"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=331273"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}