1

so I'm trying to create a widget that will show my subcategories. I've implemented the code and it works but the problem is that it shows the categories even that are not active. I need some help or recommendation with trying to fix the logic because I've tried a lot of stuff but can't make it work. Below you can find the code for the logic and the template. Logic:

class SubcategoriesWidget extends Template implements BlockInterface
{
    protected $_template = 'widget/subcategories-widget.phtml';

    private CategoryRepository $categoryRepository;
    private Http $request;

    public function __construct(
        Template\Context $context,
        Http $request,
        CategoryRepository $categoryRepository,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->categoryRepository = $categoryRepository;
        $this->request = $request;
    }

    /**
     * @throws NoSuchEntityException
     */
    public function getSubcategories()
    {
        $categoryId = $this->request->getParam('id');
        $category = $this->categoryRepository->get($categoryId);
        $subCategories = $category->getChildrenCategories();
        foreach ($subCategories as $subCategory) {
            if ($subCategory->hasChildren()) {
                $this->getChildNames();
            }
        }
        return $subCategories;
    }


}

And this is the code for the template:

<?php if ($subcategories = $block->getSubcategories()): ?>
<?php $lastCategory = end($subcategories)  ?>

<div class="mt-[16px]">
    <?php foreach ($subcategories as $subcategory): ?>
    <?php if ($subcategory->getIsActive()): ?>
    <a href="<?= $subcategory->getUrl()?>">
            <?php echo $subcategory->getName() ?>
            <?php if ($subcategory->getId() != $lastCategory->getId()) {
                echo " | " ; } ?>
        </a>
    <?php endif; ?>
    <?php endforeach; ?>
</div>

<?php endif; ?>

Any help would be appreciated

1 Answer 1

1

Could you confirm the following code is redundant?

foreach ($subCategories as $subCategory) {
    if ($subCategory->hasChildren()) {
        $this->getChildNames();
    }
}

I've tested your code without the above code, and it works as expected. But due to Magento\Catalog\Model\Category::getChildrenCategories() method can return object (Collection) or an array, your code has to modify to make it compatible with PHP 8:

Change <?php $lastCategory = end($subcategories) ?>

to <?php $lastCategory = is_object($subcategories) ? $subcategories->getLastItem() : end($subcategories); ?>

Finally, your SubcategoriesWidget class should looks like the following:

class SubcategoriesWidget extends Template implements BlockInterface
{
    protected $_template = 'widget/subcategories-widget.phtml';

    private CategoryRepository $categoryRepository;
    private Http $request;

    public function __construct(
        Template\Context $context,
        Http $request,
        CategoryRepository $categoryRepository,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->categoryRepository = $categoryRepository;
        $this->request = $request;
    }

    /**
     * @throws NoSuchEntityException
     */
    public function getSubcategories()
    {
        $categoryId = $this->request->getParam('id');
        $category = $this->categoryRepository->get($categoryId);
        return $category->getChildrenCategories();
    }
}

Your code in the template should looks like the following:

<?php if ($subcategories = $block->getSubcategories()): ?>
<?php $lastCategory = is_object($subcategories) ? $subcategories->getLastItem() : end($subcategories); ?>

<div class="mt-[16px]">
    <?php foreach ($subcategories as $subcategory): ?>
    <?php if ($subcategory->getIsActive()): ?>
    <a href="<?= $subcategory->getUrl()?>">
            <?php echo $subcategory->getName() ?>
            <?php if ($subcategory->getId() != $lastCategory->getId()) {
                echo " | " ; } ?>
        </a>
    <?php endif; ?>
    <?php endforeach; ?>
</div>

<?php endif; ?>
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.