Configuración gráfica para un cron job en Magento

Siempre que se habla de crear cron jobs para un módulo en Magento, se explica cómo configurar el crontab y el xml del módulo.

Si bien vamos a lograr el objetivo, esto siempre obliga a quien administra el proceso a estar editando un archivo y corrigiendo los tiempos de ejecución.

De ésta forma no sólo estamos ante una situación incómoda sino que, además, podríamos estar comprometiendo la integridad del módulo.

Voy a dar por sentado que ya nuestro cron job funciona como queremos y que hemos creado la configuración de otros parámetros del módulo. Sólo nos vamos a concentrar en agregar la configuración gráfica para la ejecución.

Ahora bien, el primer paso es crear un nuevo modelo que será el encargado de transformar los valores que ingresemos en la configuración a valores que el Cron Manager de Magento entienda.

Si bien no hay por qué seguir ningún estándar en particular, para éste tipo de modelos suele usarse la siguiente nomenclatura.

/app/code/local/Dc/Modulo/Model/Config/Cron/Proceso.php

Ahora bien, vamos a crear la clase.

class Dc_Modulo_Model_Config_Cron_Proceso extends Mage_Core_Model_Config_Data
{
 
    const CRON_STRING_PATH = 'crontab/jobs/mi_modulo_mi_cron_job/schedule/cron_expr';
    const CRON_MODEL_PATH = 'crontab/jobs/mi_modulo_mi_cron_job/run/model';
 
    protected function _afterSave()
    {
 
        $time = $this->getData('groups/cronjob/fields/time/value');
        $frequency = $this->getData('groups/cronjob/fields/frequency/value');
 
        $frequencyDaily = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_DAILY;
        $frequencyWeekly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_WEEKLY;
        $frequencyMonthly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_MONTHLY;
 
        $cronDayOfWeek = date('N');
 
        $cronExprArray = array(
            intval($time[1]),
            intval($time[0]),
            ($frequency == $frequencyMonthly) ? '1' : '*',
            '*',
            ($frequency == $frequencyWeekly) ? '1' : '*',
        );
 
        $cronExprString = join(' ', $cronExprArray);
 
        try {
            Mage::getModel('core/config_data')
                ->load(self::CRON_STRING_PATH, 'path')
                ->setValue($cronExprString)
                ->setPath(self::CRON_STRING_PATH)
                ->save();
            Mage::getModel('core/config_data')
                ->load(self::CRON_MODEL_PATH, 'path')
                ->setValue((string) Mage::getConfig()->getNode(self::CRON_MODEL_PATH))
                ->setPath(self::CRON_MODEL_PATH)
                ->save();
        } catch (Exception $e) {
            throw new Exception(Mage::helper('cron')->__('Unable to save Cron expression'));
        }
    }
}

El siguiente paso es indicarle al valor de configuración que para manejar los datos, aplique éste modelo.

Para esto, vamos a abrir el archivo /etc/system.xml de nuestro módulo y vamos a agregar un nuevo parámetro dentro del nodo fields que será el de la configuración específica del cron job.

<time translate="label">
    <label>Start Time</label>
    <frontend_type>time</frontend_type>
    <sort_order>1</sort_order>
    <show_in_default>1</show_in_default>
    <show_in_website>0</show_in_website>
    <show_in_store>0</show_in_store>
</time>
<frequency translate="label">
    <label>Frequency</label>
    <frontend_type>select</frontend_type>
    <source_model>adminhtml/system_config_source_cron_frequency</source_model>
    <backend_model>modulo/config_cron_proceso</backend_model>
    <sort_order>2</sort_order>
    <show_in_default>1</show_in_default>
    <show_in_website>0</show_in_website>
    <show_in_store>0</show_in_store>
</frequency>

Ahora guardamos y accedemos a la configuración.

El resultado debería ser similar (el mismo en realidad) a lo que vemos a continuación.

Configuración gráfica de un cron job en Magento

Ahora ya podemos configurar nuestro cron job desde el backend sin tocar los archivos de la plataforma.