Magento – Run a profile from command line

dataflowimportexportmagento-1.9

I have created an advanced data profile with the below actions xml. It takes a csv of order ids and my adapter marks the orders as complete. When run through the admin panel, this works fine. However, I am wanting to automate the procedure (as the csv will be updated on a semi-regular basis) so have followed the instructions on Magento Export/Import from the command line (see below for my code).

When I run this code from the command line I am getting the output "Order status update complete. BatchID: nn", however the orders that I am specifying are not being updated. When I put var_dumps and dies into my adapter nothing happens. When I do var_dumps into the below code I can see that it has loaded the correct profile, and that the actions xml is being read correctly.

How do I get the below code to run my adapter when it is run from the command line?

Actions XML

<action type="dataflow/convert_adapter_io" method="load">
    <var name="type">file</var>
    <var name="path">var/import</var>
    <var name="filename"><![CDATA[filename.csv]]></var>
    <var name="format"><![CDATA[csv]]></var>
</action>
<action type="dataflow/convert_parser_csv" method="parse">
    <var name="delimiter"><![CDATA[,]]></var>
    <var name="enclose"><![CDATA["]]></var>
    <var name="fieldnames">true</var>
    <var name="store"><![CDATA[0]]></var>
    <var name="number_of_records">1</var>
    <var name="decimal_separator"><![CDATA[.]]></var>
    <var name="adapter">mynamespace_mymodule/convert_adapter_store</var>
    <var name="method">saveRow</var>
</action>

Run Profile Code

<?php
//THIS SCRIPT JUST INITIALS THE PROFILE TO BE RUN VIA MAGENTO ADMIN "RUN PROFILE IN POPUP".
//Its the same thing as click just via this file that you can run via cron

// SYSTEM - IMPORT/EXPORT - ADVANCED PROFILES <-- you need to go into your magento admin and grab the exact profile ID
$profileId = 9; 

require_once 'public_html/app/Mage.php';
umask(0);
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

$profile = Mage::getModel('dataflow/profile');
$userModel = Mage::getModel('admin/user');
$userModel->setUserId(0);
Mage::getSingleton('admin/session')->setUser($userModel);
$profile->load($profileId);
if (!$profile->getId()) {
    Mage::getSingleton('adminhtml/session')->addError('ERROR: Incorrect profile id');
}

Mage::register('current_convert_profile', $profile);
$profile->run();
$batchModel = Mage::getSingleton('dataflow/batch');
echo "ORDER STATUS UPDATE COMPLETE. BATCHID: " . $batchModel->getId();

Best Answer

When run from the command line, the mynamespace_mymodule/convert_adapter_store::saveRow method is never called I'm afraid. Usually, during dataflow imports, the save action is triggered via the profile popup. That means you need to mimic the controller's batchRunAction when executing import profiles from shell. Just append another action to your Advanced Dataflow Profile XML:

<action type="mynamespace_mymodule/convert_parser_shell" method="save"/>

The save method basically contains the code from the controller action, but needs a little tweaking to replace the POST parameters.

class MyNamespace_MyModule_Model_Dataflow_Convert_Parser_Shell
    extends Mage_Dataflow_Model_Convert_Adapter_Abstract
{
    public function save()
    {
        $profile = Mage::registry('current_convert_profile');
        $batchId = $profile->getBatchId();

        /** @var Mage_Dataflow_Model_Batch $batchModel */
        $batchModel = Mage::getModel('dataflow/batch')->load($batchId);

        if (!$batchModel->getId()) {
            return;
        }
        if (!$batchModel->getAdapter()) {
            return;
        }

        /** @var Mage_Dataflow_Model_Batch_Import $batchImportModel */
        $batchImportModel = $batchModel->getBatchImportModel();
        $importIds = $batchImportModel->getIdCollection();

        /** @var MyNamespace_MyModule_Model_Convert_Adapter_Store $adapter */
        $adapter = Mage::getModel($batchModel->getAdapter());
        $adapter->setBatchParams($batchModel->getParams());

        // […]
        foreach ($importIds as $importId) {
            // […]
            // THIS actually persists an entity:
            $adapter->saveRow($importData);
            // […]
        }

        // […]
    }

    public function load()
    {
        // not implemented, only import needed.
    }
}

I skipped a few lines to focus on the main aspects. See batchRunAction for reference.

The data juggling depends on the individual entities and adapters anyway.

Related Topic