Cómo crear un Admin-administrable Magento Entidad Para las marcas


Además, vamos a asociar la entidad de nuestra nueva marca con otras entidades de Magento, como productos. El proceso en sí es bastante largo porque voy a explicar cada paso en detalle, pero realmente es fácil una vez que sabes cómo, y es un gran ejemplo de lo poderoso que la plataforma Magento puede ser con un mínimo de esfuerzo.

Vamos a cubrir los siguientes temas:

  • Crear una nueva entidad marca en Magento.
  • Explorar, filtrar y ordenar las marcas en el panel de administración de Magento.
  • Crear, actualizar y eliminar marcas en el panel de administración.
  • Crear una lista de marca, y ver las páginas en el front-end.
  • Marcas asociadas a los productos.
  • Mostrar una asociación producto-marca en el front-end.
  • Incluir imágenes en todas partes.

Este tutorial esta basado en Magento Community Edition 1.8.0.0, la última versión disponible en el momento de la escritura. Pero el código y principios se aplican a todas las versiones recientes de Magento, tanto a Community como Enterprise.

Aunque he tratado de ser lo más preciso posible en mis explicaciones, documentando el código a veces es la mejor manera de explicar ciertas cosas, por lo que encontrarás un montón de comentarios en los fragmentos de código que podrás descargar. El fragmento de código vinculado al final de la página contiene más usos y elementos de los que se tratan en este tutorial, para mostrarte cómo extender las cosas que aprenderás aquí.

Creando Nuestro módulo

Comienza por crear la siguiente estructura de carpetas y archivos. Por el momento, todos los archivos estarán vacíos. Normalmente, estos archivos y carpetas se crearían uno a la vez, según sea necesario, pero por el bien de este tutorial, vamos a poner todo en su lugar desde el principio.

Como de costumbre, supongo que ya sabes lo básico de la creación de un módulo de Magento y te sientes cómodo con este paso, asumo que no requiere ninguna explicación adicional.

Estructura de carpetas y archivos:

  • app

    • code

      • community

        • MisModulos

          • GranMarca

            • Block

              • Adminhtml

                • Marca

                  • Edit

                    • Form.php
                  • Edit.php
                  • Grid.php
                  • Marca.php
            • Helper

              • Data.php
            • Model

              • Resource

                • Marca

                  • Collection.php
                • Marca.php
              • Marca.php
            • controllers

              • Adminhtml

                • MarcaController.php
            • etc

              • adminhtml.xml
              • config.xml
            • sql

              • mismodulos_granmarca_setup

                • install-0.0.1.php
    • etc

      • modules

        • MisModulos_GranMarca.xml

Los scripts de configuración del módulo

Para que nuestro módulo sea de alguna utilidad, necesitamos un lugar para almacenar nuestros datos. Por lo tanto, tenemos que escribir un script para la configuración del módulo que creará una tabla en base de datos para almacenar la información sobre nuestra entidad marca. Los scripts de configuración se almacenan en dos lugares dentro del módulo, /sql y /datos. El primero es para los cambios físicos en la instancia de Magento, tales como actualizaciones del esquema de base de datos, y el segundo es para poblar o eliminar entradas del esquema existente.

En nuestro caso, estamos agregando una nueva tabla. Así, edita el archivo en sql/mismodulos_granmarca_setup/install-0.0.1.php con el siguiente código:

$this->startSetup();

/**
 * Nota: En Magento hay muchas maneras de lograr el mismo resultado en
 * la creación de una tabla de base de datos. En este tutorial, utilizamos el
 * Método Varien_Db_Ddl_Table, pero no dude en explorar lo que Magento
 * hace en la CE 1.8.0.0 y versiones anteriores.
 */
$table = new Varien_Db_Ddl_Table();

/**
 * Este es un alias del nombre real de nuestra tabla de base de datos, que es
 * configurado en config.xml. Mediante el uso de un alias, podemos hacer referencia a la misma
 * tabla a través de nuestro código si lo deseamos, y si el nombre de la tabla tiende a cambiar
 * podemos simplemente actualizarlo desde una única ubicación del config.xml
 * - mismodulos_granmarca es el alias del modelo 'marca' que es la 
 * - referencia de la tabla
 */
$table->setName($this->getTable('mismodulos_granmarca/marca'));

/**
 * Agregamos las columnas que necesitamos por ahora. Si más tarde necesitas más,
 * Siempre puedes crear un nuevo script de configuración como una actualización. 
 * Que más adelante introduciremos en este tutorial.
 */
$table->addColumn(
    'entity_id',
    Varien_Db_Ddl_Table::TYPE_INTEGER,
    10,
    array(
        'auto_increment' => true,
        'unsigned' => true,
        'nullable'=> false,
        'primary' => true
    )
);
$table->addColumn(
    'created_at',
    Varien_Db_Ddl_Table::TYPE_DATETIME,
    null,
    array(
        'nullable' => false,
    )
);
$table->addColumn(
    'updated_at',
    Varien_Db_Ddl_Table::TYPE_DATETIME,
    null,
    array(
        'nullable' => false,
    )
);
$table->addColumn(
    'name',
    Varien_Db_Ddl_Table::TYPE_VARCHAR,
    255,
    array(
        'nullable' => false,
    )
);
$table->addColumn(
    'url_key',
    Varien_Db_Ddl_Table::TYPE_VARCHAR,
    255,
    array(
        'nullable' => false,
    )
);
$table->addColumn(
    'description',
    Varien_Db_Ddl_Table::TYPE_TEXT,
    null,
    array(
        'nullable' => false,
    )
);
$table->addColumn(
    'visibility',
    Varien_Db_Ddl_Table::TYPE_BOOLEAN,
    null,
    array(
        'nullable' => false,
    )
);

/**
 * Estas dos líneas importantes a menudo se pierden..
 */
$table->setOption('type', 'InnoDB');
$table->setOption('charset', 'utf8');

/**
 * Create the table!
 */
$this->getConnection()->createTable($table);

$this->endSetup();

Inicializando nuestro módulo

En este punto, todavía no tenemos un módulo de Magento activo; sólo tenemos una serie de carpetas y archivos vacíos y una secuencia de comandos de configuración de instalación que no hace nada. Esto es a propósito. En los próximos pasos, vamos a poblar el archivo app/etc/modules XML y configurar config.xml para que Magento sepa dónde buscar nuestro script de instalación, tras lo cual la próxima visita a la página web se disparará el contenido de nuestro script de configuración y correrá.

Si hubiésemos realizado estas tareas al revés (es decir, configurado el módulo primero y luego poblado el script de configuración), entonces existiría la posibilidad de que Magento pensara que nuestro módulo estaba en la versión 0.0.1 y que nuestro script de instalación estaba todavía vacío y, como resultado, la secuencia de comandos tendería efectivamente a ser omitida. Así que, para evitar poner cara de face-palm, he tratado de mantener el orden de los pasos lo más seguro posible.

Configuración de Nuestro módulo

Edita el archivo app/etc/modules/MisModulos_GranMarca.xml y añade lo siguiente para activar nuestro módulo:


    
        
            true
            community
        
    

Te darás cuenta de que estamos utilizando el codepool de la comunidad. El módulo GrandesMarcas no contendrá ningún código específico de cliente o personalizaciones. En lugar de esto, contendrá bloques de construcción para nuestra nueva entidad, que puede ser utilizado en otros módulos, dependiendo del caso de uso. Por lo tanto, este módulo community puede caer en cualquier instancia de Magento y se utiliza tal cual, sin ningún código que necesite ser cambiado. Si se necesitan cambios en el código para un determinado caso de uso, entonces sería más apropiado dejar el código en el pool local.

Ahora, le diremos a Magento que tenemos un módulo con un número de versión, que en realidad va a determinar las secuencias de comandos de configuración de ejecución y dónde encontrar el scripts de configuración. Editar etc/config.xml con lo siguiente:


    
        
            
            0.0.1
        
    
    
        

            
            

                
      mismodulos_grandesmarcas_resource

            

            
            

                

                    
                    

                        
                        mismodulos_grandesmarcas_marcas
MisMarcas_GrandesMarcas Mage_Core_Model_Resource_Setup core_setup

¿Funciona todo hasta el momento?

Adelante y accede a cualquier página de tu sitio web - iremos a la página principal. Magento encontrará que tiene un módulo nuevo en la versión 0.0.1, sin embargo, no tiene registro de este módulo en la tabla de base de datos core_resource. Esta entrada faltante disparará una busqueda en Magento en una secuencia de comandos de configuración de instalación y ejecutará su contenido.

Si todo sale bien ...

Si todo sale bien, entonces te parecerá como si nada hubiera pasado. La página de Magento puede tardar unos momentos más en cargar, mientras que el contenido de nuestro script de instalación se esta ejecutando (es decir, mientras se crea la nueva tabla de base de datos), y luego la página seguirá cargando de forma normal. Ahora tiene dos tareas que debes realizar para comprobar que todo ha ido como se esperaba:

  • Asegúrate de que Magento ya conoce tu módulo y que el módulo está activado, ve a System→Configuration→Advanced→Advanced.
  • Accede a tu base de datos a través de cualquier terminal o algo así como el PHPMyAdmin para ver si Magento ha creado una nueva tabla, mismodulos_grandesmarcas_marcas.

Si nada ha ido bien ...

Si las cosas no van bien, entonces también puede parecer no ha pasado nada, sólo que esta vez nada realmente ha sucedido! La razón de esto podría ser errores en el archivo config.xml, carpetas o archivos mal nombradas (ten cuidado con mayúsculas y minúsculas) o algo más. Ve a través de los pasos anteriores y comprueba que todo esta como debe ser. Por otro lado, es posible que veas un mensaje de error - tal vez un "PHP Fatal Error" o una página de informe, dependiendo de la gravedad del error. Usa tus habilidades de depuración para identificar el problema y corregirlo, nuevamente comprueba todos los pasos anteriores de este tutorial.

"Esto salió mal. ¿Cómo puedo intentarlo de nuevo? "

Para intentar nuevamente desde cero, puedes realizar las siguientes acciones - no todas serán requeridas dependiendo de que tan lejos Magento llegó antes de que las cosas comenzaran mal. Tendrá que acceder a tu base de datos de forma directa, porque esto no se puede realizar a través de Magento:

  1. En la tabla core_resource, elimina unicamente la fila mismodulos_grandesmarcas_setup.
  2. Eliminar la tabla mismodulos_grandesmarcas_marcas.

Creando Nuestro Helper

En realidad no necesitamos definir cualquier funcionalidad personalizada en un helper para este tutorial. Pero estaremos añadiendo elementos de menú al panel de administración que utilizan un ayudante para la traducción, por lo que simplemente podemos crear uno en Helper/Data.php y por ahora olvidarnos de él.

< ?php
class MisModulos_GrandesMarcas_Helper_Data
    extends Mage_Core_Helper_Abstract
{

}

Creando Nuestros Modelos

A continuación, necesitamos crear modelos y los modelos de recurso para que podamos persistir datos de la marca a la base de datos al crear y guardar, mostrar información sobre nuestras marcas en las redes del panel de administración de Magento, y mostramos nuestras marcas al cliente desde el front-end.

El Modelo de Marca

Tenemos que definir un modelo para permitir a los desarrolladores interactuar con nuestra marca. No voy a entrar en más detalles porque la gente más inteligente que yo sin duda ya han explicado lo que es un modelo, así que no dudes en busca algunos artículos. Por ahora, me limitaré en conseguir que nuestro modelo haga el trabajo que necesitamos para continuar nuestro tutorial. Por lo tanto, editamos  Model/Marcas.php con esto:

< ?php
class MisModelos_GrandesMarcas_Model_Marcas
    extends Mage_Core_Model_Abstract
{
    const VISIBILITY_HIDDEN = '0';
    const VISIBILITY_DIRECTORY = '1';

    protected function _construct()
    {
        /**
         * Esto le dice a Magento donde puede encontrar el modelo de recursos relacionados.
         * Para un modelo de recurso, Magento utilizará el alias del modelo estándar -
         * en este caso 'mismodulos_grandesmarcas' - y buscar en el archivo
         * config.xml de un nodo hijo. Esta será la ubicación en la que Magento
         * buscará el modelo cuando Mage::getResourceModel() es llamado - en nuestro caso,
         * MisModulos_GrandesMarcas_Model_Resource.
         */
        $this->_init('mismodulos_grandesmarcas/marcas');
    }

    /**
     * Este método es utilizado en la cuadricula y el formulario para poblrar la lista desplegable.
     */
    public function getAvailableVisibilies()
    {
        return array(
            self::VISIBILITY_HIDDEN
                => Mage::helper('smashingmagazine_branddirectory')
                       ->__('Hidden'),
            self::VISIBILITY_DIRECTORY
                => Mage::helper('smashingmagazine_branddirectory')
                       ->__('Visible in Directory'),
        );
    }

    protected function _beforeSave()
    {
        parent::_beforeSave();

        /**
         * Realiza algunas acciones antes de que la marca es guardada.
         */
        $this->_updateTimestamps();
        $this->_prepareUrlKey();

        return $this;
    }

    protected function _updateTimestamps()
    {
        $timestamp = now();

        /**
         * Establece el timestamp de la última actualización.
         */
        $this->setUpdatedAt($timestamp);

        /**
         * Si tenemos un nuevo objeto marca, establece el timestamp al crearlo.
         */
        if ($this->isObjectNew()) {
            $this->setCreatedAt($timestamp);
        }

        return $this;
    }

    protected function _prepareUrlKey()
    {
        /**
         * En este método, usted podría considerar asegurar
         * que la clave de URL introducida es única y
         * contiene sólo caracteres alfanuméricos.
         */

        return $this;
    }
}

El Modelo del Recurso Marca

Al igual que en la introducción al modelo anterior, no voy a entrar en más detalles que decir que el trabajo del modelo de recursos es persistir y recuperar datos de la base de datos. Así que vamos a editar Model/Resource/Marcas.php con esto:fafefa

< ?php
class SmashingMagazine_BrandDirectory_Model_Resource_Brand
    extends Mage_Core_Model_Resource_Db_Abstract
{
    protected function _construct()
    {
        /**
         * Le decimos a Magento el nombre de la base de datos y
         * el campo de la clave principal para persistir los datos.
         * Similar al _construct () de nuestro modelo, Magento 
         * encuentra estos datos en config.xml para encontrar el nodo
         * y la localización de los hijos.
         *
         * En este ejemplo:
         * - mismodulos_grandesmarcas es el alias del modelo
         * - marcas la referencia de la entidad en config.xml
         * - entity_id es el nombre de la columna de la llave primaria
         *
         * Como resultado, Magento escribirá los datos en la tabla
         * 'mismodulos_grandesmarcas_marcas' y cualquier llamado a
         * $model->getId() recuperará los datos desde la columna
         * llamada 'entity_id'.
         */
        $this->_init('mismodulos_grandesmarcas/marcas', 'entity_id');
    }
}

La Colección del Recurso Marca

Por último, necesitamos una colección de recursos para permitir la iteración a través de nuestras marcas para cosas como las grillas del panel de administración y el listado de páginas del front-end. Para esto editamos Model/Resource/Marcas/Collection.php con esto:

< ?php
class SmashingMagazine_BrandDirectory_Model_Resource_Brand_Collection
    extends Mage_Core_Model_Resource_Db_Collection_Abstract
{
    protected function _construct()
    {
        parent::_construct();

        /**
         * Le decimos a Magento del modelo y los modelos de recursos para utilizar con
         * la colección. Puesto a que ambos alias son los mismos,
         * podemos omitir el segundo parámetro si lo deseamos.
         */
        $this->_init(
            'mismodulos_grandesmarcas/marca',
            'mismodulos_grandesmarcas/marca'
        );
    }
}

Creando Nuestros Bloques Admin

La mayor parte de la trabajo pesado se hace ahora. Una base de datos está lista para ser poblada, modelos y los modelos de recurso están listos para poblarla a ella. Sólo tenemos que crear la interfaz para hacerlo. Vamos a empezar con la creación y configuración de los bloques del administrador para mostrar nuestras marcas en cuadriculas desde el panel del admin y que permita crearlas y actualizarlas.

Bloque Contenedor de la Cuadricula

El trabajo del contenedor de cuadrícula es para albergar a las filas individuales de las entradas de la marca que se mostrarán en el panel de administración de Magento. El contenedor de cuadrícula es como un envoltorio e incluye los botones en la parte superior derecha (por ejemplo, "Añadir"). Edita Block/Adminhtml/Marca.php con esto:

< ?php
class SmashingMagazine_BrandDirectory_Block_Adminhtml_Brand
    extends Mage_Adminhtml_Block_Widget_Grid_Container
{
    protected function _construct()
    {
        parent::_construct();

        /**
         * La propiedad $_blockGroup le dice a Magento que alias utilizar para
         * localizar los bloques que se mostrarán en el contenedor de la cuadrícula.
         * En nuestro ejemplo, esto corresponde a GrandesMarcas/Block/Adminhtml.
         */
        $this->_blockGroup = 'smashingmagazine_branddirectory_adminhtml';

        /**
         * $_controller es un nombre un poco confuso para esta propiedad.
         * Este valor, de hecho, se refiere a la carpeta que contiene nuestro
         * Grid.php y Edit.php - de nuestro ejemplo,
         * GrandesMarcas/Block/Adminhtml/Marca. Por lo tanto, vamos a utilizar "marca".
         */
        $this->_controller = 'brand';

        /**
         * El título de la página en el panel admin.
         */
        $this->_headerText = Mage::helper('mismodulos_grandesmarcas')
            ->__('Grandes Marcas');
    }

    public function getCreateUrl()
    {
        /**
         * Cuando se hace clic en el botón "Agregar", aquí es donde el usuario debe
         * ser redirigido a - en nuestro ejemplo, el método editAction
         * MarcasController.php en el módulo GrandesMarcas.
         */
        return $this->getUrl(
            'mismodulos_grandesmarcas_admin/marcas/edit'
        );
    }
}

Bloque de Cuadricula

Cuando renderizamos una cuadricula, Magento espera encontrar un bloque de cuadricula en la ubicación _controller definida en el contenedor de la cuadrícula anterior, por lo que la vamos a crear ahora. Aquí, podemos definir que campos se van a recuperar desde la base de datos y se mostrarán en la cuadrícula del panel de admin, y Magento permitirá automáticamente la busqueda y el filtrado deestas columnas. Editamos Block/Adminhtml/Marcas/Grid.php con esto:

< ?php
class SmashingMagazine_BrandDirectory_Block_Adminhtml_Brand_Grid
    extends Mage_Adminhtml_Block_Widget_Grid
{
    protected function _prepareCollection()
    {
        /**
         * Le dice a Magento que colección utilizar para mostrar esta cuadrícula.
         */
        $collection = Mage::getResourceModel(
            'mismodulos_grandesmarcas/marcas_collection'
        );
        $this->setCollection($collection);

        return parent::_prepareCollection();
    }

    public function getRowUrl($row)
    {
        /**
         * Cuando se le da clic a una cuadrícula, aquí es donde el usuario será
         * redireccionado a - en nuestro ejemplo, el método editAction del
         * MarcasController.php en el módulo GrandesMarcas.
         */
        return $this->getUrl(
            'mismodulos_grandesmarcas_admin/marcas/edit',
            array(
                'id' => $row->getId()
            )
        );
    }

    protected function _prepareColumns()
    {
        /**
         * Aquí, definimos que columnas se mostrarán en la cuadrícula.
         */
        $this->addColumn('entity_id', array(
            'header' => $this->_getHelper()->__('ID'),
            'type' => 'number',
            'index' => 'entity_id',
        ));

        $this->addColumn('created_at', array(
            'header' => $this->_getHelper()->__('Created'),
            'type' => 'datetime',
            'index' => 'created_at',
        ));

        $this->addColumn('updated_at', array(
            'header' => $this->_getHelper()->__('Updated'),
            'type' => 'datetime',
            'index' => 'updated_at',
        ));

        $this->addColumn('name', array(
            'header' => $this->_getHelper()->__('Name'),
            'type' => 'text',
            'index' => 'name',
        ));

        $this->addColumn('lastname', array(
            'header' => $this->_getHelper()->__('Url Key'),
            'type' => 'text',
            'index' => 'url_key',
        ));

        $brandSingleton = Mage::getSingleton(
            'mismodulos_grandesmarcas/marcas'
        );
        $this->addColumn('visibility', array(
            'header' => $this->_getHelper()->__('Visibility'),
            'type' => 'options',
            'index' => 'visibility',
            'options' => $brandSingleton->getAvailableVisibilies()
        ));

        /**
         * Finalmente, agregaremos una columna de acción con el enlace edit.
         */
        $this->addColumn('action', array(
            'header' => $this->_getHelper()->__('Action'),
            'width' => '50px',
            'type' => 'action',
            'actions' => array(
                array(
                    'caption' => $this->_getHelper()->__('Edit'),
                    'url' => array(
                        'base' => 'mismodulos_grandesmarcas_admin'
                                  . '/marcas/edit',
                    ),
                    'field' => 'id'
                ),
            ),
            'filter' => false,
            'sortable' => false,
            'index' => 'entity_id',
        ));

        return parent::_prepareColumns();
    }

    protected function _getHelper()
    {
        return Mage::helper('mismodulos_grandesmarcas');
    }
}

Bloque contenedor del formulario

El bloque contenedor del formulario tiene una función similar al del contenedor de cuadrícula pero es utilizado para crear o editar una entidad. Editamos Block/Adminhtml/Marcas/Edit.php  con esto:

< ?php
class MisModulos_GrandesMarcas_Block_Adminhtml_Marca_Editar
    extends Mage_Adminhtml_Block_Widget_Form_Container
{
    protected function _construct()
    {
        $this->_blockGroup = 'mismodulos_grandesmarcas_adminhtml';
        $this->_controller = 'marca';

        /**
         * La propiedad $_mode le dice a Magento qué carpeta usar
         * para localizar los bloques de formularios relacionados para ser mostradas en
         * este contenedor formulario. En nuestro ejemplo, esto corresponde
         * a GrandesMarcas/Block/Adminhtml/Marca/Editar/.
         */
        $this->_mode = 'editar';

        $newOrEdit = $this->getRequest()->getParam('id')
            ? $this->__('Edit')
            : $this->__('New');
        $this->_headerText =  $newOrEdit . ' ' . $this->__('Marca');
    }
}

Bloque del formulario

En el bloque del formulario, definimos que campos pueden ser gestionados al crear o editar una entidad. Para esto editamos Block/Adminhtml/Marca/Editar/Form.php con esto:

< ?php
class SmashingMagazine_BrandDirectory_Block_Adminhtml_Brand_Edit_Form
    extends Mage_Adminhtml_Block_Widget_Form
{
    protected function _prepareForm()
    {
        // Instancia un nuevo formulario para mostrar nuestra marca para su edición.
        $form = new Varien_Data_Form(array(
            'id' => 'edit_form',
            'action' => $this->getUrl(
                'mismodulos_grandesmarcas_admin/marca/editar',
                array(
                    '_current' => true,
                    'continue' => 0,
                )
            ),
            'method' => 'post',
        ));
        $form->setUseContainer(true);
        $this->setForm($form);

        // Definimos un nuevo conjunto de campos. Necesitamos solo uno para nuestra entidad simple..
        $fieldset = $form->addFieldset(
            'general',
            array(
                'legend' => $this->__('Detalle de Marca')
            )
        );

        $brandSingleton = Mage::getSingleton(
            'mismodulos_grandesmarcas/marca'
        );

        // Agregamos los campos que queremos que sean editables.
        $this->_addFieldsToFieldset($fieldset, array(
            'name' => array(
                'label' => $this->__('Name'),
                'input' => 'text',
                'required' => true,
            ),
            'url_key' => array(
                'label' => $this->__('URL Key'),
                'input' => 'text',
                'required' => true,
            ),
            'description' => array(
                'label' => $this->__('Description'),
                'input' => 'textarea',
                'required' => true,
            ),
            'visibility' => array(
                'label' => $this->__('Visibility'),
                'input' => 'select',
                'required' => true,
                'options' => $brandSingleton->getAvailableVisibilies(),
            ),

            /**
             * Nota: no hemos incluido created_at o updated_at.
             * Nos encargaremos de esos campos nosotros mismos en el modelo
             * antes de guardar.
             */
        ));

        return $this;
    }

    /**
     * Este método hace la vida un poco más fácil para nosotros por que pre-pueblan los
     * campos con los datos $_POST donde aplica y envuelven nuestros datos post
     * en 'marcasData' para que podamos separar fácilmente toda la información pertinente
     * en el controlador. Se podría, por supuesto, omita este método completamente
     * y llamar directamente al método $fieldset->addField().
     */
    protected function _addFieldsToFieldset(
        Varien_Data_Form_Element_Fieldset $fieldset, $fields)
    {
        $requestData = new Varien_Object($this->getRequest()
            ->getPost('brandData'));

        foreach ($fields as $name => $_data) {
            if ($requestValue = $requestData->getData($name)) {
                $_data['value'] = $requestValue;
            }

            // Wrap all fields with brandData group.
            $_data['name'] = "brandData[$name]";

            // Generally, label and title are always the same.
            $_data['title'] = $_data['label'];

            // If no new value exists, use the existing brand data.
            if (!array_key_exists('value', $_data)) {
                $_data['value'] = $this->_getBrand()->getData($name);
            }

            // Finalmente, llama a la funcionalidad vanilla para agregar el campo.
            $fieldset->addField($name, $_data['input'], $_data);
        }

        return $this;
    }

    /**
     * Recuperar la marca existente para pre-rellenar los campos del formulario.
     * Para una entrada nueva marca, este devolverá un objeto marca vacía.
     */
    protected function _getBrand()
    {
        if (!$this->hasData('brand')) {
            // Esto se habrá fijado en el controlador.
            $brand = Mage::registry('current_brand');

            // Sólo en caso de que el controlador no registra la marca.
            if (!$brand instanceof
                    SmashingMagazine_BrandDirectory_Model_Brand) {
                $brand = Mage::getModel(
                    'smashingmagazine_branddirectory/brand'
                );
            }

            $this->setData('brand', $brand);
        }

        return $this->getData('brand');
    }
}

Creando nuestro controlador de Admin

Ahora, necesitamos un controlador para aceptar las solicitudes y presentar los bloques de contenedores desde arriba. El controlador también se encargará de las peticiones POST para crear, actualizar y eliminar las marcas que sean necesarias. Editamos controllers/Adminhtml/BrandController.php con esto:

< ?php
class SmashingMagazine_BrandDirectory_Adminhtml_BrandController
    extends Mage_Adminhtml_Controller_Action
{
    /**
     * Instanciar nuestro bloque contenedor de cuadrícula y añadir al
     * contenido de la página. Cuando acceda a esta página en index admin,
     * verá una cuadrícula de todas las marcas actualmente disponibles en
     * nuestra instancia de Magento, junto con un botón para agregar una nueva
     * si así lo deseamos.
     */
    public function indexAction()
    {
        // una instancia del contenedor de cuadrícula
        $brandBlock = $this->getLayout()
            ->createBlock('smashingmagazine_branddirectory_adminhtml/brand');

        // Agrega el contenedor de cuadrícula como el único elemento en esta página
        $this->loadLayout()
            ->_addContent($brandBlock)
            ->renderLayout();
    }

    /**
     * Esta acción se ocupa de ambas visualización y edición marcas existentes.
     */
    public function editAction()
    {
        /**
         * Recuperar datos de marcas existentes si se ha especificado un ID.
         * Si no, vamos a tener una entidad marca vacía lista para ser poblada.
         */
        $brand = Mage::getModel('smashingmagazine_branddirectory/brand');
        if ($brandId = $this->getRequest()->getParam('id', false)) {
            $brand->load($brandId);

            if ($brand->getId() _getSession()->addError(
                    $this->__('This brand no longer exists.')
                );
                return $this->_redirect(
                    'smashingmagazine_branddirectory_admin/brand/index'
                );
            }
        }

        // procesa los datos de $_POST si se envía el formulario
        if ($postData = $this->getRequest()->getPost('brandData')) {
            try {
                $brand->addData($postData);
                $brand->save();

                $this->_getSession()->addSuccess(
                    $this->__('The brand has been saved.')
                );

                // redirecciona para eliminar datos $_POST desde una solicitud
                return $this->_redirect(
                    'smashingmagazine_branddirectory_admin/brand/edit',
                    array('id' => $brand->getId())
                );
            } catch (Exception $e) {
                Mage::logException($e);
                $this->_getSession()->addError($e->getMessage());
            }

            /**
             * Si llegamos hasta aquí, entonces algo salió mal. Continua
             * mostrando la página como antes, la diferencia esta vez es,
             * los datos enviados por $_POST estan disponibles.
             */
        }

        // Hace que el objeto marca actual este disponible en los bloques.
        Mage::register('current_brand', $brand);

        // Una instancia del contenedor del formulario.
        $brandEditBlock = $this->getLayout()->createBlock(
            'smashingmagazine_branddirectory_adminhtml/brand_edit'
        );

        // Agregar el contenedor del formulario como el único elemento en esta página.
        $this->loadLayout()
            ->_addContent($brandEditBlock)
            ->renderLayout();
    }

    public function deleteAction()
    {
        $brand = Mage::getModel('smashingmagazine_branddirectory/brand');

        if ($brandId = $this->getRequest()->getParam('id', false)) {
            $brand->load($brandId);
        }

        if ($brand->getId() _getSession()->addError(
                $this->__('This brand no longer exists.')
            );
            return $this->_redirect(
                'smashingmagazine_branddirectory_admin/brand/index'
            );
        }

        try {
            $brand->delete();

            $this->_getSession()->addSuccess(
                $this->__('The brand has been deleted.')
            );
        } catch (Exception $e) {
            Mage::logException($e);
            $this->_getSession()->addError($e->getMessage());
        }

        return $this->_redirect(
            'smashingmagazine_branddirectory_admin/brand/index'
        );
    }

    /**
     * Con este método se implementan las reglas ACL configuradas en adminhtml.xml.
     */
    protected function _isAllowed()
    {
        /**
         * Incluimos este interruptor para demostrar que se puede agregar
         * restricciones a nivel de acción con las reglas de ACL. El método
         * isAllowed() utilizará la regla ACL que hemos configurado en nuestro
         * fichero adminhtml.xml:


we include this switch to demonstrate that you can add action
         * level restrictions in your ACL rules. The isAllowed() method will
         * use the ACL rule we have configured in our adminhtml.xml file:
         * - acl
         * - - resources
         * - - - admin
         * - - - - children
         * - - - - - smashingmagazine_branddirectory
         * - - - - - - children
         * - - - - - - - brand
         *
         * por ejemplo. podrías agregar más reglas dentro de la marca para editar y borrar.
         */
        $actionName = $this->getRequest()->getActionName();
        switch ($actionName) {
            case 'index':
            case 'edit':
            case 'delete':
                // intentionally no break
            default:
                $adminSession = Mage::getSingleton('admin/session');
                $isAllowed = $adminSession
                    ->isAllowed('smashingmagazine_branddirectory/brand');
                break;
        }

        return $isAllowed;
    }
}

Finalizando La Configuración

Eso es todo el código que necesitamos para el back-end. Sólo tenemos que hacer algunos cambios en el config.xml para decirle a Magento dónde encontrar nuestro controlador, bloques, modelos y helper. También tenemos que agregar un elemento al menú del panel de administración para un fácil acceso al administrar nuestra entidad marca.

config.xml

Necesitamos agreagar el bloque, helper y la definición del modelo para nuestra configuración del módulo para que Magento sapa dónde ubicar estos archivos, así como un router de admin para que Magento conozca dónde ubicar nuestro controlador de elementos de menú que estamos a punto de añadir en el siguiente paso. La versión final de nuestro archivo etc/config.xml se verá de la siguiente manera:

 

adminhtml.xml

Agregar elementos de menú al panel de administración de Magento es sencillo. Simplemente tenemos que crear un archivo adminhtml.xml, definir qué elementos deben aparecer y dónde deberíamos direccionar cuando se hace clic. Editar etc/adminhtml.xml con esto:

Mostrar marcas en el Front-End

Hemos llegado al final de este tutorial sobre cómo crear una entidad que es manejable desde el panel de administración. Por ahora, usted debería ser capaz de crear, actualizar y borrar las marcas y tener esos cambios reflejados en la base de datos. Usted tiene una entidad de marca en pleno funcionamiento, pero no hace nada. El siguiente paso es integrar esta nueva entidad en el resto del código de Magento.

En vez de continuar a divagar acerca de cómo hacer esto, he incluido en el código fuente adjunto un módulo local adicional, llamado «BrandExample", que contiene ejemplos de cómo lograrlo.

Si inspeccionas el archivo adjunto, te darás cuenta de que he mantenido este ejemplo del front-end suplementario como un módulo local e independiente, con la intención de que no sea confundido con las secciones de manejo del panel de administración cubiertas anteriormente. Una vez que estes más familiarizado, entonces por todos los medios, agrupa los dos módulos en uno si lo deseas.

El tutorial completo desarrolado contiene:

  • Un nuevo atributo de producto para asociar los productos con las marcas.
  • Inclusión de marcas en la página de vista del producto, una vez que es asociado.
  • Un listado marcas y página de aterrizaje de marca, incluyendo productos relacionados.
  • Scripts de configuración de datos para crear productos y marcas ficticias.

Añadir nuevo comentario

CAPTCHA
Esta pregunta es para comprobar si usted es un visitante humano y prevenir envíos de spam automatizado.
20 + 0 =
Resuelva este simple problema matemático y escriba la solución; por ejemplo: Para 1+3, escriba 4.