0

Having issues overriding Magento\MediaGalleryUi\Model\Directories\GetDirectoryTree.php.

It is related to a current Media Gallery bug that causes Folders not to display (https://github.com/magento/magento2/issues/30596)

Here is my setup:

di.xml

<preference for="Magento\MediaGalleryUi\Model\Directories\GetDirectoryTree"
type="Vendor\General\Plugin\MediaGalleryUi\GetDirectoryTree"/>

GetDirectoryTree.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace Vendor\General\Plugin\MediaGalleryUi;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\ValidatorException;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\ReadInterface;
use Magento\Framework\Filesystem\Glob;
use Magento\MediaGalleryApi\Api\IsPathExcludedInterface;

/**
 * Build media gallery folder tree structure
 */
class GetDirectoryTree
{
    /**
     * @var Filesystem
     */
    private $filesystem;

    /**
     * @var IsPathExcludedInterface
     */
    private $isPathExcluded;

    /**
     * @var Glob
     */
    private $glob;

    /**
     * @param Filesystem $filesystem
     * @param Glob $glob
     * @param IsPathExcludedInterface $isPathExcluded
     */
    public function __construct(
        Filesystem $filesystem,
        Glob $glob,
        IsPathExcludedInterface $isPathExcluded
    ) {
        $this->filesystem = $filesystem;
        $this->glob = $glob;
        $this->isPathExcluded = $isPathExcluded;
    }

    /**
     * Return directory folder structure in array
     *
     * @return array
     * @throws ValidatorException
     */
    public function execute(): array
    {
        return $this->getDirectories();
    }

    /**
     * Read media directories recursively and build directory tree array in the jstree format
     *
     * @param string $path
     * @return array
     * @throws ValidatorException
     */
    private function getDirectories(string $path = ''): array
    {
        $directories = [];

        $absolutePath = $this->getMediaDirectory()->getAbsolutePath($path);
        foreach ($this->glob->glob(rtrim($absolutePath, '/') . '/*', Glob::GLOB_ONLYDIR) as $childPath) {
            $relativePath = $this->getMediaDirectory()->getRelativePath($childPath);
            if (!$this->isPathExcluded->execute($relativePath)) {
                $directories[] = $this->getTreeNode($relativePath);
            }
        }

        return $directories;
    }

    /**
     * Format tree node based on path (relative to media directory)
     *
     * @param string $path
     * @return array
     * @throws ValidatorException
     */
    private function getTreeNode(string $path): array
    {
        $pathArray = explode('/', $path);
        return [
            'data' => count($pathArray) > 0 ? end($pathArray) : $path,
            'attr' => [
                'id' => $path
            ],
            'metadata' => [
                'path' => $path
            ],
            'path_array' => $pathArray,
            'children' => $this->getDirectories($path)
        ];
    }

    /**
     * Retrieve media directory with read access
     *
     * @return ReadInterface
     */
    private function getMediaDirectory(): ReadInterface
    {
        return $this->filesystem->getDirectoryRead(DirectoryList::MEDIA);
    }
}

module.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_General" setup_version="0.0.1">
        <sequence>            
            <module name="Magento_MediaGalleryUi"/>
        </sequence>
    </module>
</config>

Any ideas?

I have tried the plugin method too and it also did not work. I think I'm missing something that's preventing me from pulling this class up.

UPDATE:

I looked into debug.log and saw this:

main.ERROR: Type Error occurred when creating object: Magento\MediaGalleryUi\Controller\Adminhtml\Directories\GetTree\Interceptor, Argument 3 passed to Magento\MediaGalleryUi\Controller\Adminhtml\Directories\GetTree\Interceptor::__construct() must be an instance of Magento\MediaGalleryUi\Model\Directories\GetDirectoryTree, instance of Vendor\General\Plugin\MediaGalleryUi\GetDirectoryTree given, called in /var/www/php/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 121 [] []

I did go through the code generation steps and did remove generation folders:

php -dmemory_limit=6G bin/magento setup:upgrade
rm -rf var/generation/ var/view_preprocessed/ pub/static/frontend
php -dmemory_limit=6G bin/magento setup:di:compile
php -dmemory_limit=6G bin/magento setup:static-content:deploy -f
php -dmemory_limit=6G bin/magento cache:flush
2
  • 1
    Does module is register and enable into the system? – Dhiren Vasoya Jul 21 at 5:27
  • @DhirenVasoya yes, I have put this within an older plugin that is already registered, should I put it into a new plugin completely? – Kalvin Klien Jul 21 at 15:54
0

I was able to get it done. It required also adding a preference for GetTree.php file.

Here is the whole plugin:

src\app\code\Vendor\OverrideMediaGalleryUi\Controller\Adminhtml\Directories\GetTree.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace Vendor\OverrideMediaGalleryUi\Controller\Adminhtml\Directories;

use Magento\Backend\App\Action;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\Result\Json;
use Magento\Framework\Controller\ResultFactory;
use Vendor\OverrideMediaGalleryUi\Model\Directories\GetDirectoryTree;
use Psr\Log\LoggerInterface;

/**
 * Returns all available directories
 */
class GetTree extends Action implements HttpGetActionInterface
{
    private const HTTP_OK = 200;
    private const HTTP_INTERNAL_ERROR = 500;

    /**
     * @see _isAllowed()
     */
    public const ADMIN_RESOURCE = 'Magento_Cms::media_gallery';

    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @var GetDirectoryTree
     */
    private $getDirectoryTree;

    /**
     * Constructor
     *
     * @param Action\Context $context
     * @param LoggerInterface $logger
     * @param GetDirectoryTree $getDirectoryTree
     */
    public function __construct(
        Action\Context $context,
        LoggerInterface $logger,
        GetDirectoryTree $getDirectoryTree
    ) {
        parent::__construct($context);
        $this->logger = $logger;
        $this->getDirectoryTree = $getDirectoryTree;
    }
    /**
     * @inheritdoc
     */
    public function execute()
    {
        try {
            $responseContent = [
                $this->getDirectoryTree->execute()
            ];
            $responseCode = self::HTTP_OK;
        } catch (\Exception $exception) {
            $this->logger->critical($exception);
            $responseCode = self::HTTP_INTERNAL_ERROR;
            $responseContent = [
                'success' => false,
                'message' => __('Retrieving directories list failed.'),
            ];
        }

        /** @var Json $resultJson */
        $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
        $resultJson->setHttpResponseCode($responseCode);
        $resultJson->setData($responseContent);

        return $resultJson;
    }
}

src\app\code\Vendor\OverrideMediaGalleryUi\etc\di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\MediaGalleryUi\Model\Directories\GetDirectoryTree" type="Vendor\OverrideMediaGalleryUi\Model\Directories\GetDirectoryTree"/>
    <preference for="Magento\MediaGalleryUi\Controller\Adminhtml\Directories\GetTree" type="Vendor\OverrideMediaGalleryUi\Controller\Adminhtml\Directories\GetTree"/>
</config>

src\app\code\Vendor\OverrideMediaGalleryUi\etc\module.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">  
    <module name="Vendor_OverrideMediaGalleryUi">
        <sequence>
            <module name="Magento_MediaGalleryUi"/>
        </sequence>
    </module>
</config>

src\app\code\Vendor\OverrideMediaGalleryUi\Model\Directories\GetDirectoryTree.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace Vendor\OverrideMediaGalleryUi\Model\Directories;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\ValidatorException;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\ReadInterface;
use Magento\Framework\Filesystem\Glob;
use Magento\MediaGalleryApi\Api\IsPathExcludedInterface;

/**
 * Build media gallery folder tree structure
 */
class GetDirectoryTree
{
    /**
     * @var Filesystem
     */
    private $filesystem;

    /**
     * @var IsPathExcludedInterface
     */
    private $isPathExcluded;

    /**
     * @var Glob
     */
    private $glob;

    /**
     * @param Filesystem $filesystem
     * @param Glob $glob
     * @param IsPathExcludedInterface $isPathExcluded
     */
    public function __construct(
        Filesystem $filesystem,
        Glob $glob,
        IsPathExcludedInterface $isPathExcluded
    ) {
        $this->filesystem = $filesystem;
        $this->glob = $glob;
        $this->isPathExcluded = $isPathExcluded;
    }

    /**
     * Return directory folder structure in array
     *
     * @return array
     * @throws ValidatorException
     */
    public function execute(): array
    {
        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/test.log');
        $logger = new \Zend\Log\Logger();
        $logger->addWriter($writer);
        $logger->info("==============DIRECTORIES===============");

        return $this->getDirectories();
    }

    /**
     * Read media directories recursively and build directory tree array in the jstree format
     *
     * @param string $path
     * @return array
     * @throws ValidatorException
     */
    private function getDirectories(string $path = ''): array
    {
        $directories = [];

        $absolutePath = $this->getMediaDirectory()->getAbsolutePath($path);
        foreach ($this->glob->glob(rtrim($absolutePath, '/') . '/*', Glob::GLOB_ONLYDIR) as $childPath) {
            $relativePath = $this->getMediaDirectory()->getRelativePath($childPath);
            if (!$this->isPathExcluded->execute($relativePath)) {
                $directories[] = $this->getTreeNode($relativePath);
            }
        }

        return $directories;
    }

    /**
     * Format tree node based on path (relative to media directory)
     *
     * @param string $path
     * @return array
     * @throws ValidatorException
     */
    private function getTreeNode(string $path): array
    {
        $pathArray = explode('/', $path);
        return [
            'data' => count($pathArray) > 0 ? end($pathArray) : $path,
            'attr' => [
                'id' => $path
            ],
            'metadata' => [
                'path' => $path
            ],
            'path_array' => $pathArray,
            'children' => $this->getDirectories($path)
        ];
    }

    /**
     * Retrieve media directory with read access
     *
     * @return ReadInterface
     */
    private function getMediaDirectory(): ReadInterface
    {
        return $this->filesystem->getDirectoryRead(DirectoryList::MEDIA);
    }
}

src\app\code\Vendor\OverrideMediaGalleryUi\composer.json

{
    "name": "vendor/module-overridemediagalleryui",
    "description": "Overrides Broken MediaGalleryUi",
    "type": "magento2-module",
    "license": "GPL-3.0",
    "authors": [
        {
            "name": "Vendor",
            "email": "vendor@vendor.com"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Vendor\\OverrideMediaGalleryUi\\": ""
        }
    }
}

src\app\code\Vendor\OverrideMediaGalleryUi\registration.php

<?php
/**
 * Copyright ©  All rights reserved.
 * See COPYING.txt for license details.
 */
use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Vendor_OverrideMediaGalleryUi', __DIR__);

This is quick and dirty way of doing it, I will probably rewrite it using a Plugin later as it will be an easier implementation.

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.