Category: Magento

Magento: Como borrar todos los productos de prueba en Magento

En ocasiones, es necesario eliminar todo nuestro catálogo de producos, ya sea por mótivo de pruebas o por otras razones, desafortunadamente no es tan sencillo como parece, es necesario eliminar muchas tablas para mantener la integridad de nuestra base de datos. Así que para borrar TODOS los productos en Magento en una versión Enterprise 1.13, ejecutamos los siguientes querys.

SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE TABLE `catalog_product_bundle_option`;
TRUNCATE TABLE `catalog_product_bundle_option_value`;
TRUNCATE TABLE `catalog_product_bundle_selection`;
TRUNCATE TABLE `catalog_product_entity_datetime`;
TRUNCATE TABLE `catalog_product_entity_decimal`;
TRUNCATE TABLE `catalog_product_entity_gallery`;
TRUNCATE TABLE `catalog_product_entity_int`;
TRUNCATE TABLE `catalog_product_entity_media_gallery`;
TRUNCATE TABLE `catalog_product_entity_media_gallery_value`;
TRUNCATE TABLE `catalog_product_entity_text`;
TRUNCATE TABLE `catalog_product_entity_tier_price`;
TRUNCATE TABLE `catalog_product_entity_varchar`;
TRUNCATE TABLE `catalog_product_link`;
TRUNCATE TABLE `catalog_product_link_attribute`;
TRUNCATE TABLE `catalog_product_link_attribute_decimal`;
TRUNCATE TABLE `catalog_product_link_attribute_int`;
TRUNCATE TABLE `catalog_product_link_attribute_varchar`;
TRUNCATE TABLE `catalog_product_link_type`;
TRUNCATE TABLE `catalog_product_option`;
TRUNCATE TABLE `catalog_product_option_price`;
TRUNCATE TABLE `catalog_product_option_title`;
TRUNCATE TABLE `catalog_product_option_type_price`;
TRUNCATE TABLE `catalog_product_option_type_title`;
TRUNCATE TABLE `catalog_product_option_type_value`;
TRUNCATE TABLE `catalog_product_super_attribute`;
TRUNCATE TABLE `catalog_product_super_attribute_label`;
TRUNCATE TABLE `catalog_product_super_attribute_pricing`;
TRUNCATE TABLE `catalog_product_super_link`;
TRUNCATE TABLE `catalog_product_enabled_index`;
TRUNCATE TABLE `catalog_product_website`;
TRUNCATE TABLE `catalog_product_entity`;
TRUNCATE TABLE `cataloginventory_stock`;
TRUNCATE TABLE `cataloginventory_stock_item`;
TRUNCATE TABLE `cataloginventory_stock_status`;
INSERT  INTO `catalog_product_link_type`(`link_type_id`,`code`)
 VALUES (1,'relation'),(2,'bundle'),(3,'super'),(4,'up_sell'),
(5,'cross_sell');
INSERT  INTO `catalog_product_link_attribute`(`product_link_attribute_id`,
`link_type_id`,`product_link_attribute_code`,`data_type`) 
VALUES (1,2,'qty','decimal')
,(2,1,'position','int'),(3,4,'position','int')
,(4,5,'position','int'),(6,1,'qty','decimal')
,(7,3,'position','int'),(8,3,'qty','decimal');
INSERT  INTO `cataloginventory_stock`(`stock_id`,`stock_name`) VALUES (1,'Default');
TRUNCATE TABLE `enterprise_url_rewrite_redirect_rewrite`;
TRUNCATE TABLE `enterprise_url_rewrite_redirect_cl`;
TRUNCATE TABLE `enterprise_url_rewrite_redirect`;
TRUNCATE TABLE `enterprise_url_rewrite_product_cl`;
TRUNCATE TABLE `enterprise_url_rewrite_category_cl`;
TRUNCATE TABLE `enterprise_catalog_product_rewrite`;
TRUNCATE TABLE `enterprise_catalog_category_rewrite`;
TRUNCATE TABLE `core_url_rewrite`;
DELETE FROM `enterprise_url_rewrite`;
TRUNCATE TABLE `catalog_product_entity_url_key`;
SET FOREIGN_KEY_CHECKS = 0;

Y por último corremos un reindex total, nos ubicamos en nuestro sitio y ejecutamos la siguiente sentencia:

php shell/indexer.php --reindexall

Saludos.

Aprendiendo magento crear un modulo II: Hola Mundo

Continuando con el post anterior Crear un módulo Parte 1, veremos a continuación como crear un módulo desde 0 y como meta final conseguir nuestro ya famosísimo “Hola Mundo”.

Primer paso es:

Crear el activador de nuestro módulo

Nos ubicamos dentro del directorio raíz de nuestra instalación y a continuación accedemos a app/etc/modules. Ya dentro de ese directorio crearemos un archivo .xml,  con el nombre de “Machakando_Holamundo” (Namespace_Modulo), y le agregaremos el siguiente contenido:

<?xml version="1.0" ?>
<config>
    <modules>
        <Machakando_Holamundo>
           <active>true</active>
           <codePool>local</codePool>
        </Machakando_Holamundo>
     </modules>
</config>

Una vez creado esto, necesitamos limpiar la cache de Magento y preferiblemente desactivarla para notar este tipo de cambios, ya que los cambios que se realizan sobre los .xml siempre se almacenan en cache. Para esto accedemos a nuestro backend y “System”->”Cache Management”, Seleccionamos todos los tipos de cache, cambiamos la acción a “refresh” y posteriormente seleccionamos todos los tipos de cache nuevamente y cambiamos el action por “disable” y “submit”.

Una vez realizado esto, nos aseguramos que Magento este reconociendo la activación de nuestro módulo, para esto accedemos a “System”-> “Configuration” -> “Advanced” -> “Advanced”,  y veremos una lista con todos los módulos activados hasta el momento. Si localizamos el nuestro en la lista, entonces todo habrá salido bien.

– Crear nuestro módulo

Como siguiente paso, crearemos un directorio “local” dentro de la carpeta “app” (en caso de que no exista) y siguiendole el nombre de nuestro Namespace (Por lo regular, se coloca la empresa de quien lo está desarrollando). Quedando de la siguiente manera

/magento/app/code/local/Machakando

Dentro de nuestra carpeta local, crearemos otro directorio con el nombre de nuestro módulo, en este caso, el directorio es “Holamundo”

/magento/app/code/local/Machakando/Holamundo

Dentro de este directorio crearemos un directorio etc, y dentro un xml llamado, config.xml. Quedando la estructura de directorios de esta manera:

/magento/app/code/local/Machakando/Holamundo/etc/config.xml

Abrimos el archivo config.xml y colocamos lo siguiente:

<config>
    <modules>
        <Machakando_Holamundo>
            <version>0.1.0</version>
        </Machakando_Holamundo>
    </modules>
    <frontend>
        <routers>
            <holamundo>
                <use>standard</use>
                <args>
                    <module>Machakando_Holamundo</module>
                    <frontName>holamundo</frontName>
                </args>
            </holamundo>
        </routers>
    </frontend>
</config>

Donde el nodo Define información básica de nuestro módulo, así como la versión actual del mismo (Más adelante veremos como manejar la versión), posteriormente, dentro del nodo definimos a el controller que despachará a este módulo, donde el valor de es el valor que se accesará desde la url. Quedando el acceso a nuestro módulo de la siguiente manera:

http://misitio/holamundo/

Si tratamos de accesar nos arrojará un error 404 o algo similar. Lo que nos falta entonces, es declarar la clase controller. Para esto creamos el siguiente directorio en nuestro módulo /Holamundo/controllers/ y Agregamos la clase IndexController.php, quedando los directorios de la siguiente manera:

/Holamundo/controllers/IndexController.php

Y a continuación el contenido de esta clase será:

class Machakando_Holamundo_IndexController extends Mage_Core_Controller_Front_Action
{
    public function indexAction()
    {
        echo "hola mundo";
    }
}

Si vemos con cuidado, la manera en que formamos el nombre de nuestra clase, es tal cual, la ruta donde esta almacenado nuestro controller, es decir:

Machakando_Holamundo_IndexController es muy similar a Machakando/Holamundo/controllers/IndexController solamente con la diferencia que estamos omitiendo la palabra “controllers”. Todos los controllers del frontend, extienden de Mage_Core_Controller_Front_Action.

La manera en que comprobaremos es la siguiente:

http://misitio/holamundo/index/index

Y con esto obtendremos nuestro primer módulo funcionando y el mensaje de Hola Mundo mostrandose correctamente.

Que se traduciría a http://misitio/modulo/controller/action si observamos esta analogía, nos damos cuenta que la palabra Controller y Action se omitén al escribirla en la barra de direcciones.

En caso de no funcionar, no está de mas revisar los logs, Como activar logs en Magento

Magento: Como habilitar las rutas de phtmls y bloques en el backend

detective
Cuando realizamos desarrollos para backend, en ocasiones es necesario realizar un debug cuando necesitemos saber que template o que bloque esta conteniendo cierta información, Para esto es necesario habilitar las rutas de templates y bloques en el backend de Magento, para hacerlo, simplemente insertamos dos registros en nuestra tabla de core_config_data:

INSERT INTO core_config_data (scope, scope_id, path, value)
VALUES ('default', 0, 'dev/debug/template_hints', 1),
('default', 0, 'dev/debug/template_hints_blocks', 1);

Probamos nuestro backend, y listo.

Para deshabilitarlo, cambiamos el valor de 1 por 0.

Saludos.

Obtener el texto de multiselects en Magento

A quien no le ha pasado que queremos obtener los valores de un atributo con valores multiselects.

Para obtenerlos lo hacemos de la siguiente manera:

  $attributeMultiSelect = $_product->getAttributeText('attribute_to_display'); 
  foreach ($attributeMultiSelect as $option) {
    echo $option;
  }

Magento: Cargar Modelo por distintos campos

Cuantas veces nos hemos topado con la necesidad de cargar un modelo de datos sin conocer el id en un módulo creado por nosotros. Y nativamente no encontramos la manera de hacerlo, ya que el ORM de Magento, con un modelo recién creado, solo permite la carga de modelos a través del id. Como por ejemplo:

$model = Mage::getModel('minamespace_mimodulo/modelo')->load(5);
$model->getData();

Sí necesitamos cargar un modelo por medio de otro campo, necesitamos agregar un par de métodos en nuestras clases modelos y resources models.
Supongamos que necesitamos hacer una carga del modelo a través de un campo propio, en este caso “Teléfono”. Para esto necesitamos modificar nuestra clase ubicada en:
Minamespace_Mimodulo_Model_Modelo

public function loadByTelephone($telephone){
$this->_getResource()->loadByTelephone($this, $telephone);
return $this;
}

Con esto, indicamos que necesitamos obtener datos por medio de un método del Resource Model. Posteriormente agregamos otro método a nuestro Resource Model, ubicado en:
Minamespace_Mimodulo_Model_Mysql4_Modelo

public function loadByTelephone(Entrepids_Product_Model_Enhancement_Item     $custommoduleobj, $telephone)
{
$select = $this->_getReadAdapter()->select()
->from($this->getMainTable())
->where($this->getMainTable() . '.' . 'telephone' . '=?', $telephone);
$custommodule_id = $this->_getReadAdapter()->fetchOne($select);
if ($custommodule_id)
$this->load($custommoduleobj, $custommodule_id);
return $this;
}

Con esto estamos logrando la carga de nuestro modelo de datos especificando el query que se encargará de retornar estos datos.

Ya por último, para poder hacer uso de estos datos, lo haremos de la siguiente manera:

$model= Mage::getModel('minamespace_mimodulo/modelo')->loadByTelephone($telephone);
$model->getData();

Magento: crear Credito en Tienda manualmente

store-credit

Magento Enterprise cuenta con una característica muy particular, los store credits o creditos en tienda.

Desafortunadamente el modelo del store credit solo funciona para crearlos a través del backend.

Aquí les pongo un método desarrollado por mí para poder crearlos manualmente:


public function manuallyStoreCredit($customer, $amount)
{
    $customerId = $customer->getId();
    $websiteId = $customer->getWebsiteId();
    try{
        $products = Mage::getSingleton('core/resource');
        $writeConnection = $products->getConnection('core_write');
        $readConnection = $products->getConnection('core_write');
        $writeConnection->beginTransaction();
        //Validamos que no exista una nota de credito
        $queryValidate = "SELECT COUNT(*) FROM enterprise_customerbalance WHERE         customer_id = '{$customerId}'";
        $cant = $readConnection->fetchOne($queryValidate);

        if ($cant > 0) {
            $updateBalance = "UPDATE enterprise_customerbalance SET amount = '{$amount}'  WHERE customer_id = '{$customerId}'";
            $writeConnection->query($updateBalance);
            $queryBalanceId = "SELECT balance_id FROM enterprise_customerbalance WHERE customer_id = '{$customerId}'";
            $balanceId = $readConnection->fetchOne($queryBalanceId);
            $queryHistory = "INSERT INTO enterprise_customerbalance_history (balance_id, updated_at, action, balance_amount, balance_delta, additional_info, is_customer_notified)";
            $queryHistory .= " VALUES ('{$balanceId}', CURRENT_TIMESTAMP, 1, '{$amount}', '{$amount}', 'SE ACTUALIZA NOTA DE CREDITO POR WS', '0')";
            $writeConnection->query($queryHistory);
        } else {
            $query = "INSERT INTO enterprise_customerbalance (customer_id, website_id, amount ) VALUES ('{$customerId}', '{$websiteId}', '{$amount}')";
            $writeConnection->query($query);
            $balanceId = $writeConnection->lastInsertId();
            $queryHistory = "INSERT INTO enterprise_customerbalance_history (balance_id, updated_at, action, balance_amount, balance_delta, additional_info, is_customer_notified)";
            $queryHistory .= " VALUES ('{$balanceId}', CURRENT_TIMESTAMP, 2, '{$amount}', '{$amount}', 'SE CREA NOTA DE CREDITO MANUALMENTE', '0')";
            $writeConnection->query($queryHistory);
        }
        $writeConnection->commit();
    }
    catch(Exception $e) {
        Mage::log($e);
    }
}

Magento 2

 

m2-project

La expansión en uso y popularidad de Magento en los últimos años ha ido a un ritmo bastante rápido. Gracias a eso, el equipo de desarrollo de esta plataforma se ha visto en la necesidad de acelerar el desarrollo de la siguiente versión
MAGENTO 2.
Se está trabajando en mejorar varios puntos, entre los que destacan:

  • Procesos limpios y transparentes
  • Calidad mejorada en el catalogo de productos
  • Mejoras en escalabilidad y rendimiento
  • Mejoras en cuestiones de seguridad
  • Mejoras en las Web Api’s
  • Soporte multilenguaje
  • Mejoras en la arquitectura modular
Y lo mejor de todo, Magento nos promete una curva de aprendizaje mucho menor, y mas material de referencia para los desarrolladores 😀
Otros temas muchos mas específicos de los que se nos ha hecho saber son:
Magento con Github
Ahora los desarrolladores podrán contribuir de una manera mas cercana, descargando un branch del código de Magento 2, encontrando bugs y agregando cosas nuevas. Como todos sabemos en el mundo del software libre, la clave está en la contribución.
Nueva estructura de archivos
Ha llegado el momento de olvidarnos de la estrutura app/design/frontend/base/tema . De ahora en adelante Magento2 no buscará las plantillas que no se encuentren en nuestro tema activo en base, si no que ahora Magento buscará en otro lugar, ya no existirá el tema base. En lugar de eso, la estructura de las vistas ( templates y layouts) será movida a la estructura modular. Por ejemplo:
La vista del catálogo ahora se encontrará en:
app/code/core/Mage/Catalog/view/frontend/product/view.phtml y en lugar de tener catalog.xml dentro de la carpeta /layout, ahora tendremos un archivo layout.xml dentro de cada carpeta vista del módulo.
  Esto es para tener una estructura de archivo mucho mas limpia y sencilla de comprender
Nuevos elementos en el layout

Magento2 agrega el nuevos concepto de containers:

  • Containers pueden contener bloques
  • Containers pueden contener otros containers
  • Containers pueden renderizar todos los childrens

La idea detrás de este nuevo concepto es tener una estructura lógica nueva y clara para organizar los bloques y definir secciones del layout. Los containers serán usados en su gran mayoría por el editor de diseño para poder manipular de una manera más sencilla los bloques

jQuery finalmente reemplaza a prototype

Cuando Magento comenzó, jQuery no era la libreria tan robusta que es ahora, es por esto que en aquellos años se opto por utilizar a prototype como la libreria javascript nativa para el framework. Después de mucho pedirlo por la comunidad de Magento, finalmente tendremos a jQuery como el framework nativo de javascript. Cabe mencionar, que aun contará con soporte con prototype.

Adiós a los nombres de métodos factoriales
Si te costo mucho tiempo aprenderte la manera de nombrar o hacer uso de los nombres de los métodos factoriales, te tengo una mala noticia, esto desaparecerá, a partir de Magento2, la manera en que hacemos:
Mage::getModel(‘catalog/product’) ya no funcionará, a partir de Magento2 tendremos que utilizar el nombre de la clase por completo haciéndolo de está manera:
 Mage::getModel(‘Mage_Catalog_Model_Product’) Al igual que todas las class names de las tablas eav.* Afortunadamente Magento no se olvida de su comunidad de programadores, y se han desarrollado varios métodos para realizar las migraciones sin problemas, creando una serie de herramientas ubicadas en /dev/tools/migration Las cuales buscarán todas las llamadas con el nombre factorial anterior y reemplazandolas por las nueva manera de invocarlas con el nombre de la clase completa incluyendo el namespace.
Y estos, son solo algunas de las características que nos esperan. Sigamos esperando con ansias la salida de Magento2.

Magento: Obtener las subcategorias

La manera en que podemos cargar las subcategorias en base a la id de una categoría que conozcamos, lo hacemos de la siguiente manera.

$children = Mage::getModel('catalog/category')->getCategories($_category->getId()); 
foreach ($children as $category){
    $cat = Mage::getModel('catalog/category')->load($category->getId()); ?>
    // En caso de que queramos imprimir la imagen thumbnail
    // echo Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA) . 'catalog' . '/' . 'category/' .$cat->getThumbnail();
    echo $cat->getName();
}

Saludos