News:

Looking for documentation? Take a look on our wiki

Main Menu

Use vm classes from joomla cli app?

Started by vmfyelloq19, March 31, 2025, 17:02:36 PM

Previous topic - Next topic

vmfyelloq19

Hello friends,

I'd like to update some products automatically via a custom joomla cli application.
Unfortunalety I did not manage to initialize VM's classes from there.

For testing I added a system plugin triggerd by onAfterInitialise() and used VmModel::getModel('product')->store(). This works as expected as long as I satisfy VMs security checks with a valid admins session and make sure $_REQUEST is populated manually with the VM form token. But CLI applications neither have a session nor $_REQUEST.

Could anywone elaborate on the proper way of initialising VM's classes via a CLI app?

TIA!

Ghost

VM models aren't written to be used outside of Joomla web environment. Because they perform tasks that are really responsibilities of controllers (reading request data, checking authorization). That reminds me of this old post https://x.com/virtuemart/status/661263708346257408.

vmfyelloq19

Hello ghost, well yes, I know vm classes won't work outside joomla's environment, that's why it's a joomla application. And no, I'm not going to put raw SQL statements anywhere as long as there is any proper way around it.

Anyway, after digging through vmrequest etc., it's working now just fine.

In case anyone else is interested or has some suggestions, here's the code stub, tested on VirtueMart 4.4.4 11101. (Put it anywhere, it does not have to reside in htdocs/cli/)


<?php
use Joomla\CMS\Factory;

if(
'cli' !== php_sapi_name()) die('Go away.');

error_reporting(E_ALL);
ini_set('display_errors'1);

// Adjust to your environment
define('WEBROOT''/var/www/webspace/htdocs');

// Init Joomla
const _JEXEC 1;
if(
file_exists(WEBROOT '/defines.php')) require_once WEBROOT '/defines.php';
if( ! 
defined('_JDEFINES')) {
    
define('JPATH_BASE'WEBROOT);
    require_once 
JPATH_BASE '/includes/defines.php';
}
require_once 
JPATH_LIBRARIES '/import.legacy.php';
require_once 
JPATH_LIBRARIES '/cms.php';
require_once 
JPATH_CONFIGURATION '/configuration.php';
$config = new JConfig;
define('JDEBUG'$config->debug);
$lang JFactory::getLanguage();

global 
$_SERVER;
$_SERVER['HTTP_HOST'] = 'example.com';
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['DOCUMENT_ROOT'] = WEBROOT;
$_SERVER['SCRIPT_NAME'] = basename(__FILE__);
$_SERVER['REMOTE_ADDR'] = getHostByName(getHostName());

class 
MyFancyStuffCli extends JApplicationCli {
    public function 
doExecute() {
$app Factory::getApplication('site');

        
$this->out('My Fancy Stuff CLI application');
        
$this->out('------------------------------');

        
// Log in so we have a valid session
        
if( ! $app->login([
             
'username' => 'username'
            
,'password' => 'so-super-secret'
        
])) {
            
$this->out('Login failed. Abort.');
            die();
        }
        
$user Factory::getUser();
        
$this->out('Logged in successfully as ' $user->name '' $user->id ' [' $user->username ']');

        
// Init virtuemart
        
if( ! class_exists'VmConfig' )) require_once(JPATH_ADMINISTRATOR '/components/com_virtuemart/helpers/config.php');
        
VmConfig::loadConfig();
        if( ! 
class_exists('VmModel')) require_once(JPATH_ADMINISTRATOR '/components/com_virtuemart/helpers/vmmodel.php');

        
// Init virtuemart security
        
$vmtoken vRequest::getFormToken();
        
$app->input->set($vmtoken1);
        
$app->input->set('token'$vmtoken); // propably redundant

        
$productdata = [
            
// ...
        
];
        try{
            
$product_id = (int) VmModel::getModel('product')->store($productdata);
        } catch (
Exception $e) {
            
$this->out('Error storing product, caught exception:');
            
$this->out($e->getMessage());
        }
        if(
$product_id 0) {
            
$this->out('Stored product with id #' $product_id);
        } else {
            
$this->out('Did not receive new product id. Hu?.');
        }
    } 
// doExecute();
// class

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


(Tested with J3 as I'm working on an older intranet system)