I need to get IDs of all leaf-children category IDs, parameter for getLastChildren()
is ID of current category and I need all leafs under it. I tried something like this, but it ended up with infinite loop. $categoryList
is container of CategoryItem
objects, which can return all children categories and also find parent of current category. $category->isLastChild()
will return true/false if current category is leaf. Thanks for help.
/**
* @param int $idCategory
* @return int[]
*/
public function getLastChildren($idCategory)
{
$categoryList = $this->getCategoryList();
$categories = $categoryList->getChildCategories($idCategory);
$leafCats = [];
$nonLeafCats = [];
foreach ($categories as $category) {
$nonLeafCats[] = $category->getId();
}
while (!empty($nonLeafCats)) {
foreach ($nonLeafCats as &$nonLeafCat) {
$categories = $categoryList->getChildCategories($nonLeafCat);
$result = $this->getChildren($categories);
$leafCats = array_merge($leafCats, $result['leafs']);
$nonLeafCats = array_merge($nonLeafCats, $result['nonLeafs']);
unset($nonLeafCat);
}
}
return $leafCats;
}
/**
* @param CategoryItem[] $categories
* @return array
*/
private function getChildren(array $categories)
{
$leafCats = $nonLeafCats = [];
foreach ($categories as $category) {
if ($category->isLastChild()) {
$leafCats[] = $category->getId();
} else {
$nonLeafCats[] = $category->getId();
}
}
return [
'leafs' => $leafCats,
'nonLeafs' => $nonLeafCats
];
}
This is solution:
/**
* @param int $idCategory
* @return int[]
*/
public function getLastChildren($idCategory)
{
if(empty($this->categoryList)) {
$this->categoryList = $this->getCategoryList();
}
$categories = $this->categoryList->getChildCategories($idCategory);
$leafs = [];
foreach ($categories as $category) {
if ($category->isLastChild()) {
$leafs[] = $category->getId();
} else {
$leafs = array_merge($leafs, $this->getLastChildren($category->getId()));
}
}
return $leafs;
}