TransWikia.com

How to run php function directly after a specific Magento 2 CLI command?

Magento Asked on October 2, 2021

For the sake of simplicity, let’s say I want to echo out "Hello World" (in reality i want to do a lot more) directly after anyone runs php bin/magento setup:di:compile. In the latest version of Magento what is the correct way to do this without going directly in to vendor folders and modifying files? Observers are on their way out, interceptors seem to be the way forward but I cannot get an interceptor to run when basing it on the classes that perform the setup:di:compile action. Anyone know how to do this?

3 Answers

Trying with overrides, plugins etc will not work, but there is a workaround.

You can create a shell script and do not use the php bin/magento setup:di:compile command directly.

EX: compile.sh

php bin/magento setup:di:compile
php yourscript.php

And you can execute ./compile.sh every time you need to run setup:di:compile

Another not way (not a good way though) is to directly bin/magento file.

After $application->run() you can execute your script by using exec php function and the content of the file would be somethign like this:

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

if (PHP_SAPI !== 'cli') {
    echo 'bin/magento must be run as a CLI application';
    exit(1);
}

try {
    require __DIR__ . '/../app/bootstrap.php';
} catch (Exception $e) {
    echo 'Autoload error: ' . $e->getMessage();
    exit(1);
}
try {
    $handler = new MagentoFrameworkAppErrorHandler();
    set_error_handler([$handler, 'handler']);
    $application = new MagentoFrameworkConsoleCli('Magento CLI');
    $application->run();
    if ($argv[1] == 'setup:di:compile' || $argv[1] == 'setup:upgrade') {
        // your code here
    }
} catch (Exception $e) {
    while ($e) {
        echo $e->getMessage();
        echo $e->getTraceAsString();
        echo "nn";
        $e = $e->getPrevious();
    }
    exit(MagentoFrameworkConsoleCli::RETURN_FAILURE);
}

Correct answer by Zenel Rrushi on October 2, 2021

The bottom line is that it isn't possible. Your best bet would be (as @Herve Tribouilloy @Zenel Rrushi have said) to either create a shell script that runs the command and then runs your custom code after or just to create an entire new Magento 2 command and have that run the code you want.

It seemingly isn't possible to setup an interceptor for the CLI commands because as Herve notes in his answer and i quote "the command-line system is not bootstrapped the same way as the magento framework is" resulting in the command-line environment not triggering the magento interception system.

Maybe it'll be possible one day to create an interceptor/plugin to run code after particular Magento 2 commands have been ran. But for now, in 2.3 it just can't be done.

Answered by John on October 2, 2021

You may have seen the command bin/magento hits a Magento model MagentoFrameworkConsoleCli from within magento script. However, this model is not instantiated with the objectmanager but rather using the raw php command new

then, following the code, you will find the function SymfonyComponentConsoleApplication::doRunCommand. This function does not appear to have any interceptor (there is no plugins)

After you have run the command, this class is nowhere to be seen in generated folder with an interceptor. I have attempted to see why the class is not getting any interceptor and this is yet something to work out for me..

However, I don't how technical the above is to you, I'd say I am inclined to say the command-line system is not bootstrapped the same way as the magento framework is. Or more simply, the command-line environment is not triggering all the magento interception system.

As a conclusion, the best bet is indeed to trigger a script after the magento script or you may want to write a patch that would override the core function.

--> using a patch does not have the same problem as overriding the code directly. Next time you update the vendor folder, it gets updated and your patch will just need to be running again after each update.

Answered by Herve Tribouilloy on October 2, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP