1

I want to sort the categories in a Magento 2.3.1 install in alphabetical order (on the frontend!). I'm aware of the fact that you can sort it by dragging it in the Magento admin panel. But since the store I'm working on has more than 3000 categories, that's not an option. The categories also update from time to time, so it has to be a "future proof" solution.

Does anyone have an idea how to solve this? The only things I can find are for M1.

4

In your module di.xml (app\code\vender\module\etc\di.xml) place this line

<preference for="Magento\Catalog\Model\ResourceModel\Category" type="Vendor\Module\Model\Category"/>    

Create the file Vendor\Module\Model\Category.php and place this code in it:

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * Catalog category model
 *
 * @author      Magento Core Team <core@magentocommerce.com>
 */
declare(strict_types=1);

namespace elastron\elcustom\Model;

/**
 * Resource model for category entity
 *
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class Category extends \Magento\Catalog\Model\ResourceModel\Category
{

    /**
     * Return child categories
     *
     * @param \Magento\Catalog\Model\Category $category
     * @return \Magento\Catalog\Model\ResourceModel\Category\Collection
     */
    public function getChildrenCategories($category)
    {
        $collection = $category->getCollection();
        /* @var $collection \Magento\Catalog\Model\ResourceModel\Category\Collection */
        $collection->addAttributeToSelect(
            'url_key'
        )->addAttributeToSelect(
            'name'
        )->addAttributeToSelect(
            'all_children'
        )->addAttributeToSelect(
            'is_anchor'
        )->addAttributeToFilter(
            'is_active',
            1
        )->addIdFilter(
            $category->getChildren()
        )->setOrder(
            'name',
            \Magento\Framework\DB\Select::SQL_ASC
        )->joinUrlRewrite();

        return $collection;
    }
}
?>

let me know if you need any assistance !

Don't forget to run upgrade, compile an clean/flush cache

5
  • 1
    before applying a preference on a model, you might want to verify this function is not called anywhere else? I'd say using preference on a resource model is likely very intrusive / meaning likely to override the class behaviour in more places than you intend to.. – Herve Tribouilloy Jul 8 '20 at 18:09
  • Yes but I'm only overriding this specific method. I understand you're concern but this is not a "dangerous" method. – Joao71 Jul 8 '20 at 18:14
  • to be fair, the advantage of your solution is that is will do what the question asks. In terms of best practice, it is not ideal, but it is quite practical to offer, thanks for challenging – Herve Tribouilloy Jul 8 '20 at 18:26
  • I'm not taking it personally ;) I surely don't know everything, I'm still learning and I'm only working with Magento since January :): I would appreciate if you could guide me towards some documentation that supports your opinion.What would be the safest way to solve this problem? – Joao71 Jul 8 '20 at 18:26
  • Upvoted yours.. no solution is perfect, only relevant to your context. Simplicity sometimes outperforms perfection. Great attitude you have – Herve Tribouilloy Jul 9 '20 at 8:15
3

There are many solutions to this problem, Joao71's solution is simple to write and should do the trick.

In terms of best practice, preference are to be used if plugin is not possible. The reason is because if 2 modules do use the same preference, only one in the system will be eventually be used (we call this a conflict) and that is what plugin resolves.

plugin will allow you to take over any public function and yet, any further plugin on the same function will not be compromised. In your case, getChildrenCategories is a public function and that is therefore working

Finally, the solution I would offer in this instance would be to write a script / command-line that reorders the categories. This way solves the problem to do it manually but more importantly does not touch an inch on the integrity of the Magento system

1
  • Thank you for your explanation, never thaught from the perspective of code maintenance *maybe because I don-t have many preferences on my module :)) . Up voted ! – Joao71 Jul 9 '20 at 8:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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