20

To make a long story short xdebug will not reliably stop on the breakpoints in my cron files when using the typical:

php bin/magento cron:run

Xdebug is all setup properly and sometimes it will work but 85% of the time it will not and just hang in CLI until I turn off listen for connections in phpstorm.

Is there a way to run just one cron file somehow? I had to actually copy and paste the contents of my cron file to a separate console command to test it properly in xdebug which is not ideal.

In Magento 1.x I used to use the AOE Scheduler for testing cron jobs with Xdebug by going to the admin, checkboxing the one I wanted, and choosing run from the dropdown and it worked fine.

I'm looking to use something like:

php bin/magento modulename:cronjob

which should always run the cron even if it is not scheduled.

7 Answers 7

20

Think simple! The Cron class is a "normal" class. We can use a Playground to test our Cron: How can I bootstrap Magento 2 in a test.php script?. The Object Manager will create our Cron Object. And then, we can test our Cron by calling the url directly on Browser.

** Note if using Nginx you can put these files in the pub/ folder and adjust the require path for the Test.php file to require '../app/bootstrap.php';

Test.php

<?php
require __DIR__ . '/app/bootstrap.php';
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication('TestApp');
$bootstrap->run($app);

TestApp.php

 public function launch()
 {
        /** @var \Vendor\Module\Cron\Test $cron */
        $cron = \Magento\Framework\App\ObjectManager::getInstance()
            ->create('Vendor\Module\Cron\Test');

        $cron->execute();

        return $this->_response;

 }

enter image description here

2
  • 1
    Thank you, this worked for me but with a little tweaking. Since I'm using Nginx it does not check the root directory, so I had to put the Test.php and TestApp.php in the pub directory. After that I adjusted the path on Test.php require to: require '../app/bootstrap.php'; also on the TestApp.php there needs to be the: return $this->_response; or it will throw an error which you have on your phpstorm screenshot but not the actual code. I will try and edit your answer with this. Commented Jan 3, 2017 at 14:38
  • @KevinJavitz you're welcome! Commented Jan 3, 2017 at 14:42
30

On option to save in the development time would be to use N98MageRun for Magento 2.

This has the wonderful commands sys:cron:list and sys:cron:run.

Using these commands you will be able to find the specific job code for your cron and then trigger just that cron from the command line.

It can easily be installed via composer require --dev n98/magerun2 and I would recommend it should be a go to for a dev installation when working with Magento 2

2
  • 1
    OMG Wao best way to run cronjob by just a command
    – Learner
    Commented Mar 14, 2018 at 8:53
  • This is best way and quickly than above
    – madagaskar
    Commented Jun 27 at 3:22
6

You can achieve using two files:

create folder and class in root of project like:

crons/CronprocessApp.php

    <?php
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
use phpseclib\Net\SFTP;
use phpseclib\Crypt\RSA;

class CronprocessApp
    extends \Magento\Framework\App\Http
    implements \Magento\Framework\AppInterface{

    public function __construct(
    \Magento\Framework\App\State $state,\Magento\Framework\App\Response\Http $response)
    {
        $this->_response = $response;
        //$state->setAreaCode('any area'); // or 'adminhtml', depending on your needs
        $state->setAreaCode('adminhtml'); // or 'adminhtml', depending on your needs
    }
    public function launch()
    {
        /** @var \Vendor\Module\Cron\Test $cron */
        $cron = \Magento\Framework\App\ObjectManager::getInstance()
            ->create('Custom\Preorder\Cron\ChangeVisiblityNonPreorderProduct'); //pass the name of your cron class path 
        $cron->execute();       


        return $this->_response;

    }
    public function catchException(\Magento\Framework\App\Bootstrap $bootstrap, \Exception $exception)
    {
        return false;
    }
}
?>

Create another class file:

crons/Cronprocess.php

 <?php
require __DIR__ . '/../app/bootstrap.php';
require __DIR__ . '/../crons/cronprocessApp.php';

$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication('CronprocessApp');
$bootstrap->run($app);

To Run cron go to cli with project root path and run below command:

php crons/cronprocess.php
1
  • Hi, if some one get issue, and you are using ubuntu, please remember to correct the file name, ubuntu don't allow to use CronprocessApp as cronprocessapp, i mean uppercase and lowercase are need to be correct.
    – fudu
    Commented Jan 7, 2021 at 4:11
2

It's very simple and easy to achive..

In Magento root I created PHP script file as below. If you are in magento 2.4.2 or newer version then change require 'app/bootstrap.php'; to require '../app/bootstrap.php'; because now pub is a root directory in latest magento

cron_run_direct_script.php

<?php

ini_set('memory_limit','2048M');

require 'app/bootstrap.php';

use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\Response\Http\FileFactory;
use Magento\Framework\Filesystem;


class CronRunManually
    extends \Magento\Framework\App\Http
    implements \Magento\Framework\AppInterface
{
    public function launch()
    { 
      
       $this->_state->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML);
       $myClass = $this->_objectManager->create('Namespace\Module\Cron\YourCronFileName');
       $myClass->execute(); 
       return $this->_response;
    }

}

$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication('CronRunManually');
$bootstrap->run($app);
6
  • any idea to run this cron on button click from an admin
    – Pramod
    Commented Mar 3, 2022 at 9:42
  • Yes, ask separate question and add question link in here comment Commented Mar 3, 2022 at 11:33
  • yeah am doing this
    – Pramod
    Commented Mar 3, 2022 at 11:44
  • please share if you have any idea over this magento.stackexchange.com/questions/353648/…
    – Pramod
    Commented Mar 3, 2022 at 11:58
  • Page not found - on above link Commented Mar 4, 2022 at 10:01
1

You can use this module: https://github.com/Ethan3600/magento2-CronjobManager

bin/magento cronmanager:killjob - Kill cron jobs by code

bin/magento cronmanager:runjob - Run a specific cron job by its job_code

bin/magento cronmanager:showjobs - Show all cron job codes in Magento

1
  • Best answer currently IMO. This is easy to install: $ composer require ethanyehuda/magento2-cronjobmanager Commented Aug 29 at 17:30
0

Can't comment because of low reputation. IMO, the necessity to create 2 separate php files is not "easy". Easy would be bin/magento cron:jobname run.

Also, Magento doesn't by default allow arbitrary php code execution so wouldn't you have to whitelist it?

Answer should default by saying no, it is not possible "out of box", but it could be done if you create a script followed by the accepted answer.

1
0

Create this cronLaunch.php file in your magento root directory

<?php
use Magento\Framework\App\Bootstrap;

require __DIR__ . '/app/bootstrap.php';

//require '../../app/bootstrap.php';
if (php_sapi_name() !== 'cli' && isset($_GET['job'])) {
    define('CRONJOBCLASS', $_GET['job']);
} elseif (php_sapi_name() !== 'cli') {
    die('Please add the class of the cron job you want to execute as a job parameter (?job=Vendor\Module\Class)');
} elseif (!isset($argv[1])) {
    die('Please add the class of the cron job you want to execute enclosed IN DOUBLE QUOTES as a parameter.' . PHP_EOL);
} else {
    define('CRONJOBCLASS', $argv[1]);
}

class CronRunner extends \Magento\Framework\App\Http
    implements \Magento\Framework\AppInterface
{

    public function __construct(
        \Magento\Framework\App\State $state,\Magento\Framework\App\Response\Http $response)
    {
        $this->_response = $response;
        $state->setAreaCode('adminhtml');
    }

    function launch()
    {
        $cron = \Magento\Framework\App\ObjectManager::getInstance()
            ->create(CRONJOBCLASS);

        $cron->execute();
        return $this->_response;
    }
}

$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
$app = $bootstrap->createApplication('CronRunner');
$bootstrap->run($app);

and then you can run any specific cron job using 'job' parameter

http://your-website-url/cronLaunch.php?job=YourModule\SubfolderNamespace\Cron\YourClassFile

refer below picture for your cron class file placement

enter image description here

Note : Once you finished debuging remove this file from production and never keep this file on production/live servers !!

Happy Coding :)

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.