Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Categories.php
Go to the documentation of this file.
1 <?php
7 
9 use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
17 
27 {
31  const CATEGORY_TREE_ID = 'CATALOG_PRODUCT_CATEGORY_TREE';
39 
44  protected $dbHelper;
45 
51  protected $categoriesTrees = [];
52 
57  protected $locator;
58 
63  protected $urlBuilder;
64 
69  protected $arrayManager;
70 
74  private $cacheManager;
75 
79  private $serializer;
80 
89  public function __construct(
91  CategoryCollectionFactory $categoryCollectionFactory,
95  SerializerInterface $serializer = null
96  ) {
97  $this->locator = $locator;
98  $this->categoryCollectionFactory = $categoryCollectionFactory;
99  $this->dbHelper = $dbHelper;
100  $this->urlBuilder = $urlBuilder;
101  $this->arrayManager = $arrayManager;
102  $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
103  }
104 
111  private function getCacheManager()
112  {
113  if (!$this->cacheManager) {
114  $this->cacheManager = ObjectManager::getInstance()
115  ->get(CacheInterface::class);
116  }
117  return $this->cacheManager;
118  }
119 
124  public function modifyMeta(array $meta)
125  {
126  $meta = $this->createNewCategoryModal($meta);
127  $meta = $this->customizeCategoriesField($meta);
128 
129  return $meta;
130  }
131 
136  public function modifyData(array $data)
137  {
138  return $data;
139  }
140 
148  protected function createNewCategoryModal(array $meta)
149  {
150  return $this->arrayManager->set(
151  'create_category_modal',
152  $meta,
153  [
154  'arguments' => [
155  'data' => [
156  'config' => [
157  'isTemplate' => false,
158  'componentType' => 'modal',
159  'options' => [
160  'title' => __('New Category'),
161  ],
162  'imports' => [
163  'state' => '!index=create_category:responseStatus'
164  ],
165  ],
166  ],
167  ],
168  'children' => [
169  'create_category' => [
170  'arguments' => [
171  'data' => [
172  'config' => [
173  'label' => '',
174  'componentType' => 'container',
175  'component' => 'Magento_Ui/js/form/components/insert-form',
176  'dataScope' => '',
177  'update_url' => $this->urlBuilder->getUrl('mui/index/render'),
178  'render_url' => $this->urlBuilder->getUrl(
179  'mui/index/render_handle',
180  [
181  'handle' => 'catalog_category_create',
182  'store' => $this->locator->getStore()->getId(),
183  'buttons' => 1
184  ]
185  ),
186  'autoRender' => false,
187  'ns' => 'new_category_form',
188  'externalProvider' => 'new_category_form.new_category_form_data_source',
189  'toolbarContainer' => '${ $.parentName }',
190  'formSubmitType' => 'ajax',
191  ],
192  ],
193  ]
194  ]
195  ]
196  ]
197  );
198  }
199 
207  protected function customizeCategoriesField(array $meta)
208  {
209  $fieldCode = 'category_ids';
210  $elementPath = $this->arrayManager->findPath($fieldCode, $meta, null, 'children');
211  $containerPath = $this->arrayManager->findPath(static::CONTAINER_PREFIX . $fieldCode, $meta, null, 'children');
212 
213  if (!$elementPath) {
214  return $meta;
215  }
216 
217  $meta = $this->arrayManager->merge(
218  $containerPath,
219  $meta,
220  [
221  'arguments' => [
222  'data' => [
223  'config' => [
224  'label' => __('Categories'),
225  'dataScope' => '',
226  'breakLine' => false,
227  'formElement' => 'container',
228  'componentType' => 'container',
229  'component' => 'Magento_Ui/js/form/components/group',
230  'scopeLabel' => __('[GLOBAL]'),
231  'disabled' => $this->locator->getProduct()->isLockedAttribute($fieldCode),
232  ],
233  ],
234  ],
235  'children' => [
236  $fieldCode => [
237  'arguments' => [
238  'data' => [
239  'config' => [
240  'formElement' => 'select',
241  'componentType' => 'field',
242  'component' => 'Magento_Catalog/js/components/new-category',
243  'filterOptions' => true,
244  'chipsEnabled' => true,
245  'disableLabel' => true,
246  'levelsVisibility' => '1',
247  'elementTmpl' => 'ui/grid/filters/elements/ui-select',
248  'options' => $this->getCategoriesTree(),
249  'listens' => [
250  'index=create_category:responseData' => 'setParsed',
251  'newOption' => 'toggleOptionSelected'
252  ],
253  'config' => [
254  'dataScope' => $fieldCode,
255  'sortOrder' => 10,
256  ],
257  ],
258  ],
259  ],
260  ],
261  'create_category_button' => [
262  'arguments' => [
263  'data' => [
264  'config' => [
265  'title' => __('New Category'),
266  'formElement' => 'container',
267  'additionalClasses' => 'admin__field-small',
268  'componentType' => 'container',
269  'component' => 'Magento_Ui/js/form/components/button',
270  'template' => 'ui/form/components/button/container',
271  'actions' => [
272  [
273  'targetName' => 'product_form.product_form.create_category_modal',
274  'actionName' => 'toggleModal',
275  ],
276  [
277  'targetName' =>
278  'product_form.product_form.create_category_modal.create_category',
279  'actionName' => 'render'
280  ],
281  [
282  'targetName' =>
283  'product_form.product_form.create_category_modal.create_category',
284  'actionName' => 'resetForm'
285  ]
286  ],
287  'additionalForGroup' => true,
288  'provider' => false,
289  'source' => 'product_details',
290  'displayArea' => 'insideGroup',
291  'sortOrder' => 20,
292  ],
293  ],
294  ]
295  ]
296  ]
297  ]
298  );
299 
300  return $meta;
301  }
302 
310  protected function getCategoriesTree($filter = null)
311  {
312  $categoryTree = $this->getCacheManager()->load(self::CATEGORY_TREE_ID . '_' . $filter);
313  if ($categoryTree) {
314  return $this->serializer->unserialize($categoryTree);
315  }
316 
317  $storeId = $this->locator->getStore()->getId();
318  /* @var $matchingNamesCollection \Magento\Catalog\Model\ResourceModel\Category\Collection */
319  $matchingNamesCollection = $this->categoryCollectionFactory->create();
320 
321  if ($filter !== null) {
322  $matchingNamesCollection->addAttributeToFilter(
323  'name',
324  ['like' => $this->dbHelper->addLikeEscape($filter, ['position' => 'any'])]
325  );
326  }
327 
328  $matchingNamesCollection->addAttributeToSelect('path')
329  ->addAttributeToFilter('entity_id', ['neq' => CategoryModel::TREE_ROOT_ID])
330  ->setStoreId($storeId);
331 
332  $shownCategoriesIds = [];
333 
335  foreach ($matchingNamesCollection as $category) {
336  foreach (explode('/', $category->getPath()) as $parentId) {
337  $shownCategoriesIds[$parentId] = 1;
338  }
339  }
340 
341  /* @var $collection \Magento\Catalog\Model\ResourceModel\Category\Collection */
342  $collection = $this->categoryCollectionFactory->create();
343 
344  $collection->addAttributeToFilter('entity_id', ['in' => array_keys($shownCategoriesIds)])
345  ->addAttributeToSelect(['name', 'is_active', 'parent_id'])
346  ->setStoreId($storeId);
347 
348  $categoryById = [
349  CategoryModel::TREE_ROOT_ID => [
350  'value' => CategoryModel::TREE_ROOT_ID,
351  'optgroup' => null,
352  ],
353  ];
354 
355  foreach ($collection as $category) {
356  foreach ([$category->getId(), $category->getParentId()] as $categoryId) {
357  if (!isset($categoryById[$categoryId])) {
358  $categoryById[$categoryId] = ['value' => $categoryId];
359  }
360  }
361 
362  $categoryById[$category->getId()]['is_active'] = $category->getIsActive();
363  $categoryById[$category->getId()]['label'] = $category->getName();
364  $categoryById[$category->getParentId()]['optgroup'][] = &$categoryById[$category->getId()];
365  }
366 
367  $this->getCacheManager()->save(
368  $this->serializer->serialize($categoryById[CategoryModel::TREE_ROOT_ID]['optgroup']),
369  self::CATEGORY_TREE_ID . '_' . $filter,
370  [
373  ]
374  );
375 
376  return $categoryById[CategoryModel::TREE_ROOT_ID]['optgroup'];
377  }
378 }
__()
Definition: __.php:13
__construct(LocatorInterface $locator, CategoryCollectionFactory $categoryCollectionFactory, DbHelper $dbHelper, UrlInterface $urlBuilder, ArrayManager $arrayManager, SerializerInterface $serializer=null)
Definition: Categories.php:89