Skip to content

Commit 5236e4a

Browse files
committed
AC-13363::Category tree in admin is not expanded to show all selected nested categories from level 3
1 parent 43a5442 commit 5236e4a

File tree

2 files changed

+551
-0
lines changed
  • app/code/Magento/Catalog
    • Block/Adminhtml/Category/Checkboxes
    • Test/Unit/Block/Adminhtml/Category/Checkboxes

2 files changed

+551
-0
lines changed

app/code/Magento/Catalog/Block/Adminhtml/Category/Checkboxes/Tree.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ public function setCategoryIds($ids)
5858
$ids = [(int)$ids];
5959
}
6060
$this->_selectedIds = $ids;
61+
62+
// Pre-compute expanded paths for all selected categories so that
63+
// ancestors are marked as expanded before the JSON is generated.
64+
$this->_expandedPath = [];
65+
if (!empty($ids)) {
66+
$collection = $this->_categoryFactory->create()->getCollection();
67+
$collection->addAttributeToSelect('path')
68+
->addAttributeToFilter('entity_id', ['in' => $ids]);
69+
foreach ($collection as $category) {
70+
$this->setExpandedPath($category->getPath());
71+
}
72+
}
6173
return $this;
6274
}
6375

@@ -122,4 +134,74 @@ protected function _getNodeJson($node, $level = 1)
122134
$item['expanded'] = in_array($node->getId(), $this->getExpandedPath());
123135
return $item;
124136
}
137+
138+
/**
139+
* Get tree structure
140+
*
141+
* Ensure that deeply selected categories are present by building the tree
142+
* around selected IDs rather than the default 3-level root-only tree.
143+
*
144+
* @param mixed|null $parenNodeCategory
145+
* @return array
146+
*/
147+
public function getTree($parenNodeCategory = null)
148+
{
149+
// For AJAX child loads, respect the requested parent node
150+
if ($parenNodeCategory !== null) {
151+
$root = $this->getRoot($parenNodeCategory);
152+
} else {
153+
$root = empty($this->_selectedIds)
154+
? $this->getRoot($parenNodeCategory)
155+
: $this->getRootByIds($this->_selectedIds);
156+
}
157+
158+
$rootArray = $this->_getNodeJson($root);
159+
return $rootArray['children'] ?? [];
160+
}
161+
162+
/**
163+
* Get tree json
164+
*
165+
* Ensure that deeply selected categories are present in the JSON output.
166+
*
167+
* @param mixed|null $parenNodeCategory
168+
* @return string
169+
*/
170+
public function getTreeJson($parenNodeCategory = null)
171+
{
172+
// For AJAX child loads, respect the requested parent node
173+
if ($parenNodeCategory !== null) {
174+
$root = $this->getRoot($parenNodeCategory);
175+
} else {
176+
$root = empty($this->_selectedIds)
177+
? $this->getRoot($parenNodeCategory)
178+
: $this->getRootByIds($this->_selectedIds);
179+
}
180+
181+
$rootArray = $this->_getNodeJson($root);
182+
return $this->_jsonEncoder->encode($rootArray['children'] ?? []);
183+
}
184+
185+
/**
186+
* Override parent's implementation to avoid using cached registry root
187+
* which might have been built with limited recursion and miss deep nodes.
188+
*
189+
* @param array $ids
190+
* @return \Magento\Framework\Data\Tree\Node|array|null
191+
*/
192+
public function getRootByIds($ids)
193+
{
194+
$ids = $this->_categoryTree->getExistingCategoryIdsBySpecifiedIds($ids);
195+
$tree = $this->_categoryTree->loadByIds($ids);
196+
$rootId = \Magento\Catalog\Model\Category::TREE_ROOT_ID;
197+
$root = $tree->getNodeById($rootId);
198+
if ($root) {
199+
$root->setIsVisible(true);
200+
if ($root->getId() == \Magento\Catalog\Model\Category::TREE_ROOT_ID) {
201+
$root->setName(__('Root'));
202+
}
203+
}
204+
$tree->addCollectionData($this->getCategoryCollection());
205+
return $root;
206+
}
125207
}

0 commit comments

Comments
 (0)