1

I would like to call the publishing-method I defined in my item's controller from a CLI-script or a helper (which is included in the CLI).

The best case would be to call it like this:

$itemcontroller->publish($task);

But I am not sure if this is possible.

The modified publishing-method in my controller looks like this:

/**
 * publish function.
 * 
 * @access public
 * @return void
 */
public function publish()
{
    $app                                    =   JFactory::getApplication();
    $jinput                                 =   JFactory::getApplication()->input;
    $ids                                    =   $jinput->get('cid', '', 'array');
    $task                                   =   $this->getTask();
    $date                                   =   JFactory::getDate();            

    $modelitem                              =   $this->getModel('Item');        

    foreach($ids as $id)
    {
        switch($task)
        {
            case 'publish'  :                   // do something
                                                break;          
            case 'unpublish':                   // do something
                                                break;      
            case 'archive'  :                   // do something
                                                break;      
            case 'trash'    :                   // do something
                                                break;      
        }

    $publish                                =   $modelitem->publish($id, $state);       
    $this->setRedirect('index.php?option=com_bestia&view=items', false);

    return true;
}   

How can I do that?

1

Here is a CLI script I made that allows you to call controllers just as you would via http. Just add it to the cli folder named something like kewlcomponent.php.

<?php
/**
 * This is a CRON script which should be called from the command-line,
 * not the web. For example something like:
 * env php /path/to/joomla/cli/app.php
 */

// Make sure we're being called from the command line, not a web interface
if (PHP_SAPI !== 'cli') die('This is a command line only application.');

// Set flag that this is a valid Joomla entry point
define('_JEXEC', 1);

// Configure error reporting to maximum for CLI output.
error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
ini_set('display_errors', 1);

// Load system defines
if (!defined('_JDEFINES')) {
    define('JPATH_BASE', dirname(dirname(__FILE__)));
    require_once JPATH_BASE . '/includes/defines.php';
}
require_once JPATH_BASE . '/includes/framework.php';

// Fool Joomla into thinking we're in the administrator with com_kewlcomponent as active component
$app = JFactory::getApplication('site');
$_SERVER['HTTP_HOST'] = 'domain.com';
$_SERVER['REQUEST_METHOD'] = 'GET';
define('JPATH_COMPONENT', JPATH_BASE . '/components/com_kewlcomponent');
define('JPATH_COMPONENT_SITE', JPATH_BASE . '/components/com_kewlcomponent');
define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_BASE . '/administrator/components/com_kewlcomponent');

/* add loaders as necessary */
JLoader::discover('CH',JPATH_COMPONENT_ADMINISTRATOR.'/helpers');
JHtml::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.'/helpers/html');
JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.'/tables');
JFormHelper::addRulePath(JPATH_COMPONENT_ADMINISTRATOR.'/helpers/rule');

$app->loadLanguage();
$lang = JFactory::getLanguage();
$lang->load('com_kewlcomponent',JPATH_ADMINISTRATOR,'en-GB',true);
$lang->load('com_kewlcomponent',JPATH_ADMINISTRATOR,null,true);
/* end loaders */

class CliKewlcomponent extends JApplicationCli
{
    protected $timestamp = null;

    public function __construct(JInputCli $input = null, JRegistry $config = null, JDispatcher $dispatcher = null) {

        $this->timestamp = time();

        parent::__construct($input, $config, $dispatcher);
    }

    public function doExecute() {

        $live_site = $this->input->get('live_site',null,'string');
        if (!empty($live_site)) {
            $liveSiteUri = new Juri($live_site);
            $_SERVER['HTTP_HOST'] = $liveSiteUri->getHost();
            JFactory::getConfig()->set('live_site',$live_site);
        }

        $this->input->set('option','com_kewlcomponent');
        $task = $this->input->get('task');

        if (empty($task)){
            $this->out('No task given');
            $this->out('============================');
            $this->out();
            return;
        }

        $app = JFactory::getApplication();

        // set the form tokens
        $token = JSession::getFormToken();
        $this->input->set($token,1); 
        $this->input->post->set($token,1); 
        $this->input->get->set($token,1);

        // copy the input we are given
        $app->input = $this->input; 

        // run the task
        $controller = JControllerLegacy::getInstance('Kewlcomponent');
        if (!$controller->execute($app->input->get('task'))) { // controller breaks up task, need to check new value
            $this->out('=============Error=============');
            $this->out("\n\t".implode("\n\t",$controller->getErrors())."\n\t");
            $this->out('============================');
            $this->out();
        }
    }
}

JApplicationCli::getInstance('CliKewlcomponent')->execute();

Then you can call your controller like:

php5 public_html/cli/kewlcomponent.php --task=kewlcontroller.publish --live_site="http://example.com" --anothervariable="something cool"

You cannot currently pass lists via CLI in Joomla. So you may have to add a little preprocessing before:

$app->input = $this->input; 
  • Sounds good. I tried that for triggering a task inside my controller in the frontend, but i get all the time: JLIB_APPLICATION_ERROR_VIEW_NOT_FOUND – Mike May 19 '17 at 14:16
  • It may not know the path to the views since we are going through the regular flow. I think you can set the view path when initializing the CLI controller and it will propagate through. Glancing at the source, It should be automatically set though. This is worth a try though. $controller = JControllerLegacy::getInstance('Kewlcomponent',[ 'view_path' => JPATH_COMPONENT .'/views', ]); – David Hayes May 19 '17 at 19:05
  • *** we aren't going through the regular flow. – David Hayes May 19 '17 at 19:50
0

You can use the ComponentHelper class for this:

class MyCliApp extends JApplicationCli
{

    public function doExecute()
    {    
        // Fool Joomla factory into loading CMS application
        $app = JFactory::getApplication('site');

        // Transfer arguments into the CMS application's input
        $app->input->set('task', 'controllername.taskname');
        $app->input->set('arg1', $this->input->getInt('arg1'));

        // Invoke the component
        $component = Joomla\CMS\Component\ComponentHelper::renderComponent('com_mycomponent');

        $this->out('Finished');
    }
}

JApplicationCli::getInstance('MyCliApp')->execute();

I've not done much experimentation with this yet, so not certain what pitfalls you may hit with it yet, but it is meeting my own needs for now at least (allowing me to invoke a task in my component from a cron job).

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.