Cómo crear una clase para el Shell en Magento

Cuando pensamos en módulos para Magento nos quedamos, normalmente, con agregar funcionalidad para el frontend o para el backend.

Creo que cuando pensamos en un módulo debemos imaginarnos los cuatro posibles entornos para su aplicación. Por los cuatro entornos me refiero:

  • Frontend o tienda propiamente dicha.
  • Backend o administración.
  • API.
  • Consola.

Si bien ésta división puede parecer arbitraria, éstas serán las posibles puertas de entrada que normalmente utilicemos (dependiendo sobre si nos toca ser usuario, administrador, desarrollador o el encargado del mantenimiento; o todo).

Claro está que no todos los módulos requieren funcionalidad en los cuatro entornos, pero en muchos casos deberíamos cuidar las formas y proveer de herramientas para cada caso.

En mi caso, desde hace ya un buen tiempo, me ha tocado desarrollar unas cuantas integraciones que importan o exportan información. Normalmente, con procesos manejados a través del Cron de Magento.

Uno de las situaciones con las que nos vamos a encontrar cuando trabajemos con módulos que funcionan con un cronjob, es la de la prueba de ejecución. Está claro que podemos programar la tarea para que se ejecute y esperar a que suceda. Luego de la quinta prueba es muy probable que empecemos a perder un poco la paciencia.

Lo que vamos a ver hoy es cómo crear una clase para el shell respetando el estilo de la plataforma. Si bien podemos hacerlo por fuera de éstos lineamientos, vamos a tratar de ser lo más respetuosos posible. La idea es lograr tener siempre extensiones prolijas para que puedan ser reutilizadas y no nos generen conflictos con otras extensiones (o al menos que esos casos sean los menos posibles).

Continue reading

Magento 1.5.1.0-rc1 (extrañando el 2008)

El 31 de marzo se hizo pública la versión 1.5.1.0-rc1 de Magento. Al igual que su predecesora, sin mucho bombo ni platillo.

En éste caso, el changelog es significativamente menor. (Parecería que la versión beta fue la alpha y la primer rc la beta).

Sólo dos cambios vamos a encontrar (mencionados):

  • Actualización de Magento Mobile a la versión 19.
  • Se remplaza el uso de Varien_File_Uploader por Mage_Core_Model_File_Uploader (sigue avanzando la restauración de la funcionalidad de almacenamiento alternativo).

Ahora bien, de los cambios no mencionados, además de todas las correcciones, podremos encontrar: un nuevo modelo para filtrar contenido HTML malicioso y la asignación de permiso para la opción de Cache externo.

Por lo pronto todo parece indicar que nos estaríamos encontrando con la versión real de la 1.5.0.1, no más.

Ya tenemos claro que el foco está puesto en la plataforma mobile y en MagentoGo. Pensar en que la plataforma va a seguir creciendo funcionalmente como lo hizo en años anteriores es de ingenuo.

Lo de siempre: ni siquiera se les debe cruzar por la cabeza la posibilidad de probar ésta versión en producción.

Un detalle menor. Al ingresar al backend, ya no se te notifica que existe una última versión que es la misma que estás ejecutando.

Magento 1.5.1.0-beta1 (una versión casi anónima)

A diferencia de otros lanzamientos, éste pasó casi desapercibido. (Eso no tiene nada que ver con la demora del review, ha sido sólo trabajo el motivo).

El 17 de marzo se publicó la versión 1.5.1.0-beta1 de Magento, casi un mes después de haberse publicado la última (y fallida) versión estable. Lo llamativo es que no se escuchó demasiado al respecto de ésta nueva versión.

Según el changelog oficial, además de una buenas cantidad de errores corregidos, las mejoras y novedades son:

  • Actualización de Magento Mobile a las versión 18.
  • Se agregan excepciones para los Mensajes de Regalo en la API.
  • Implementada compatibilidad WS-I para la API.

Revisando el código, además, puede verse que se vuelve a al carga con la implementación de almacenamiento alternativo para media. En el backend aparece un nuevo Model, llamado LayoutUpdate, que se encargaría de controlar los updates custom de layout y proteger ciertas acciones (aún no lo he intentado probarlo).

Los módulos Sales y Tax siguen recibiendo cambios y correcciones a diestra y siniestra.

Vamos a encontrar un nuevo modelo para los precios de los productos de tipo Grouped y se nota que la energía está puesta en la ampliación de funcionalidad para la solución mobile.

De más está decir, y menos aún luego del último lanzamiento, que bajo ningún punto de vista ésta versión debe ser puesta en producción.

Collabtive-CI 0.6.5.2

Al comienzo es fácil mantener el ritmo, así que vamos a aprovechar la inercia.

Versión 0.6.5.2 de Collabtive-CI con otro cambio referente a las tareas. En ésta oportunidad, agregué la posibilidad, opcional, de cargar para una tarea la cantidad de tiempo estimado que va a llevar.

La idea será avanzar sobre el control de tiempo para luego poder medir la estimación contra el tiempo real demandado.

A diferencia de las prioridades, éste campo no es obligatorio al momento de crear la tarea.

Como ya he dicho, ante cualquier error o comentario, éste es el link del Gestor de Incidencias de Collabtive-CI.

Collabtive-CI 0.6.5.1

El primer set de cambios ya se encuentra publicados bajo la versión 0.6.5.1 de Collabtive-CI.

Los cambios implementado son:

  • Cambios en las plantillas de mail, enviando ahora mayor información al agregar o editar una tarea.
  • Correcciones de traducciones.
  • Se agregó la constante CL_BRANCH_VERSION y se implementó su uso junto a CL_VERSION en el footer.
  • Creación automática de las carpetas files y templates_c al momento de la instalación.
  • Se quitó el indicador de usuarios online y el chat de la barra lateral.
  • Se restauró el calendario en la barra lateral.
  • Se muestran todos los proyectos a los cuales el usuario está asociado, para dar la posibilidad de cambiar de proyecto si tener que pasar por el Escritorio.
  • Se implementaron prioridades para las tareas.

Continue reading

Collabtive y Collabtive-CI

Desde hace ya un buen tiempo utilizo Collabtive para intentar gestionar proyectos, tareas, ideas, etc. Es una herramienta bastante cómoda y sencilla (tanto para trabajar de forma individual como grupal).

Básicamente, la aplicación presenta una pantalla general en la que veremos los proyectos en los que estamos involucrados y todas las tareas que tenemos asignadas.

Continue reading

Extendiendo la configuración gráfica del cron en Magento

Para evitar tener que lidiar con la configuración por xml, en Magento podemos crear la configuración gráfica para los cron jobs de nuestros módulos, de manera que estamos dando mayor flexibilidad al usuario y nos evitamos riesgos que podrían ocasionarse por una mala edición de los archivos.

Normalmente las opciones que nos ofrece la configuración suelen ser suficiente.

En otros casos, es posible que no nos alcance con sólo poder configurar una ejecución diaria, semanal o mensual. En éste esquema, nos estamos perdiendo la posibilidad de configurar la ejecución con repetición por horas o por minutos.

Para poder obtener esas opciones vamos a necesitar crear dos modelos para nuestro módulo, que serán los encargados de brindarnos esas nuevas posibilidades (y de paso vamos a arreglar otras que no funcionan desde la implementación original).

Continue reading

Cómo modificar los botones de la grilla en un módulo de Magento

Cuando utilizamos el generador automático de modulos, nuestra grilla viene un botón para agregar nuevos registros.

En algunas oportunidades, posiblemente necesitemos hacer algunos cambios, ya sea agregando acciones o quitando las que obtenemos por defecto.

Para comenzar, tenemos que identificar la clase que se encarga de definir dicha sección. Suponiendo que el módulo se llama Dc_Test, tenemos que buscar el siguiente archivo: /app/code/local/Dc/Test/Block/Adminhtml/Test.php.

Lo que vamos a ver en el archivo es lo siguiente:

class Dc_Test_Block_Adminhtml_Test extends Mage_Adminhtml_Block_Widget_Grid_Container {
 
    public function __construct()     {
        $this->_controller = 'adminhtml_test';
        $this->_blockGroup = 'test';
        $this->_headerText = Mage::helper('test')->__('Item Manager');
        $this->_addButtonLabel = Mage::helper('test')->__('Add Item');
        parent::__construct();
    }
 
}

Continue reading

Magento 1.5.0.1 (problemas resueltos)

Varias horas después de haberse publicado la versión 1.5.0.0, debido a un problema de seguridad en dicha versión, se hizo pública la versión 1.5.0.1 de Magento.

La versión estable ha quedado con las siguientes funcionalidades destacadas:

  • Mejoras en el importador y exportador de Productos y Clientes.
  • Actualización de Zend Framework a la 1.11.1.
  • Inclusión de la extensión Mobile como funcionalidad por defecto.
  • Gestión de los estados de la Orden.
  • Se agrega Payflow Link como opción de pago.
  • Manejo del Carrito a través de la API.
  • Se agrega el módulo PageCache.
  • Inclusión de MagentoConnect Manager 2.
  • Mejoras al módulo Wishlist.
  • Mejoras al Carrito, soportando ahora la edición de configuraciones de productos.

En el changelog pueden verse la cantidad de cambios, mejoras y correcciones que se han hecho.

Continue reading

Magento 1.5.0.0 (shame on all of us)

En medio del Magento Imagine se hizo pública la versión 1.5.0.0 de Magento.

Ya se sabía que no habría grandes novedades entre lo que se vio desde la segunda versión alpha. El único cambio significativo fue la inclusión de MagentoConnect Manager 2.

El resúmen de mejoras quedó de la siguiente forma:

  • Mejoras en el importador y exportador de Productos y Clientes.
  • Actualización de Zend Framework a la 1.11.1.
  • Inclusión de la extensión Mobile como funcionalidad por defecto.
  • Gestión de los estados de la Orden.
  • Posibilidad de configurar el almacenamiento para el contenido de media.
  • Se agrega Payflow Link como opción de pago.
  • Manejo del Carrito a través de la API.
  • Se agrega el módulo PageCache.
  • Inclusión de MagentoConnect Manager 2.
  • Mejoras al módulo Wishlist.
  • Mejoras al Carrito, soportando ahora la edición de configuraciones de productos.

Hasta acá todo muy lindo, pero con gusto a poco para mi gusto.

Lo que destaca realmente a ésta versión y a su lanzamiento, fue el problema de seguridad originado por la inclusión de un archivo llamado get.php en la raíz de la plataforma.

Dicho archivo permite obtener el contenido de cualquier archivo de la plataforma. Por ejemplo, si usáramos la url http://www.dominio.com/get.php/app/etc/local.xml, obtendríamos algo como esto.

<!--
 
/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE_AFL.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category   Mage
 * @package    Mage_Core
 * @copyright  Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
 * @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */
-->
<config>
    <global>
        <install>
            <date>Tue, 15 Feb 2011 19:12:14 +0000</date>
        </install>
        <crypt>
            <key>a3a94d4d2bdffaba9b0a9ef9942a6760</key>
        </crypt>
        <disable_local_modules>false</disable_local_modules>
        <resources>
            <db>
                <table_prefix></table_prefix>
            </db>
            <default_setup>
                <connection>
                    <host>localhost</host>
                    <username>user</username>
                    <password>password</password>
                    <dbname>database</dbname>
                    <active>1</active>
                </connection>
            </default_setup>
        </resources>
        <session_save>files</session_save>
    </global>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <frontname>admin</frontname>
                </args>
            </adminhtml>
        </routers>
    </admin>
</config>

O, sabiendo qué clases tenemos disponibles, probando con ésta otra http://www.dominio.com/get.php/app/code/core/Mage/Admin/Model/Acl.php, se puede ver la clase completa.

< ?php
/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category    Mage
 * @package     Mage_Admin
 * @copyright   Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
 
 
/**
 * Acl model
 * 
 * @category   Mage
 * @package    Mage_Admin
 * @author      Magento Core Team <core@magentocommerce.com>
 */
class Mage_Admin_Model_Acl extends Zend_Acl
{
    /**
     * All the group roles are prepended by G
     *
     */
    const ROLE_TYPE_GROUP = 'G';
 
    /**
     * All the user roles are prepended by U
     *
     */
    const ROLE_TYPE_USER = 'U';
 
    /**
     * Permission level to deny access
     *
     */
    const RULE_PERM_DENY = 0;
 
    /**
     * Permission level to inheric access from parent role
     *
     */
    const RULE_PERM_INHERIT = 1;
 
    /**
     * Permission level to allow access
     *
     */
    const RULE_PERM_ALLOW = 2;
 
    /**
     * Get role registry object or create one
     *
     * @return Mage_Admin_Model_Acl_Role_Registry
     */
    protected function _getRoleRegistry()
    {
        if (null === $this->_roleRegistry) {
            $this->_roleRegistry = Mage::getModel('admin/acl_role_registry');
        }
        return $this->_roleRegistry;
    }
 
    /**
     * Add parent to role object
     *
     * @param Zend_Acl_Role $role
     * @param Zend_Acl_Role $parent
     * @return Mage_Admin_Model_Acl
     */
    public function addRoleParent($role, $parent)
    {
        $this->_getRoleRegistry()->addParent($role, $parent);
        return $this;
    }
}

Semejante error podría tener consecuencias bastante serias si esto se combinara con otros elementos poco fortuitos. No deja de ser, bajo ningún punto de vista, una demostración de cómo se lleva adelante el desarrollo de la plataforma.

Continue reading