Programador PHP freelance

13 Jul, 2010

Script para importar productos y categorías en Prestashop

Posted by: admin In: Desarrollo| Internet| Software

Estoy en pleno desarrollo de una tienda virtual con Prestashop para un cliente del sector de la ferretería. El cliente tiene su aplicación de gestión de productos en el servidor de la empresa y la base de datos de estos debe de ser sincronizada con el e-commerce de forma automática de modo que cualquier modificación en la misma se vea actualizada en la base de datos del Prestashop.

Inicialmente había pensado en la posibilidad de hacer un script que sincronizara las dos bases de datos conectando directamente con ellas pero visto que el Prestashop dispone de un módulo de importación a partir de ficheros CSV, he decidido utilizarlo.

En esta arquitectura existen dos partes, la parte del cliente situada en el servidor local de la empresa y la parte de la tienda virtual situada en un alojamiento web, que entre otras cosas requiere dar de alta reglas en el firewall para permitir conectar al Mysql desde una IP externa, cosa que finalmente no necesitaremos.

En la parte del cliente programaré un script que exporte en el formato CSV, esperado por Prestashop, tanto las categorías como los productos -en este caso lo único que necesito exportar- y que suba ambos ficheros al servidor donde está ubicada la tienda.

En la parte de la tienda virtual se requiere un script que sea capaz de lanzar el proceso de importación y es el que describiré a continuación.

Existía la posibilidad, en esta segunda parte, de simular la navegación utilizando CURL, haciendo el login y posterior proceso de importación, pero complica mucho más las cosas cuando lo que necesitamos es simplemente llamar a la clase AdminImport y utilizar su funcionalidad.

Aquí dejo el código del script que, situado en la parte de la tienda, lanza una importación de un fichero CSV productos (pro.csv) o categorías (cat.csv), según se le indique por GET['entity']

Los ficheros CSV a importar deben encontrarse en el directorio /admin/import mientras que nuestro script debe de estar situado en el directorio /admin del Prestashop.

Espero que le pueda (re)servir a alguien.

<?php 
 
define('PS_ADMIN_DIR', getcwd()); 
include(PS_ADMIN_DIR.'/../config/config.inc.php'); 
include(PS_ADMIN_DIR.'/functions.php'); 
include_once './tabs/AdminImport.php'; 
 
if (!isset($_GET['entity'])) die(); 
 
$import = New AdminImport(); 
switch ($_GET['entity']) { 
case 0: 
    loadCategoriesPost(); 
    $import->categoryImport(); 
    break;
 
  case 1:
    loadProductsPost();
    $import->productImport();
    break;
 
  default:
    die();
    break;
}
 
function loadCategoriesPost() {
  $_POST = array (
    'tab' => 'AdminImport',
    'skip' => '0',
    'csv' => 'cat.csv',
    'convert' => '',
    'entity' => '0',
    'separator' => ';',
    'multiple_value_separator' => ',',
    'import' => 'Importar datos CSV',
    'type_value' =>
    array (
      0 => 'id',
      1 => 'active',
      2 => 'name',
      3 => 'parent',
      4 => 'description',
      5 => 'meta_title',
      6 => 'meta_keywords',
      7 => 'meta_description',
      8 => 'link_rewrite',
      9 => 'image',
    ),
  );
}
 
function loadProductsPost() {
  $_POST = array (
    'tab' => 'AdminImport',
    'skip' => '0',
    'csv' => 'pro.csv',
    'convert' => '',
    'entity' => '1',
    'separator' => ';',
    'multiple_value_separator' => ',',
    'import' => 'Importar datos CSV',
    'type_value' =>
    array (
      0 => 'id',
      1 => 'active',
      2 => 'name',
      3 => 'category',
      4 => 'price_tex',
      5 => 'tax_rate',
      6 => 'wholesale_price',
      7 => 'on_sale',
      8 => 'reduction_price',
      9 => 'reduction_percent',
      10 => 'reduction_from',
      11 => 'reduction_to',
      12 => 'reference',
      13 => 'supplier_reference',
      14 => 'supplier',
      15 => 'manufacturer',
      16 => 'ean13',
      17 => 'ecotax',
      18 => 'weight',
      19 => 'quantity',
      20 => 'description_short',
      21 => 'description',
      22 => 'tags',
      23 => 'meta_title',
      24 => 'meta_keywords',
      25 => 'meta_description',
      26 => 'available_now',
      27 => 'available_later',
      28 => 'image',
      29 => 'no',
    ),
  );
}
?>
[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Posts relacionados

36 Responses to "Script para importar productos y categorías en Prestashop"

1 | Claudio

July 14th, 2010 at 3:02 pm

Avatar

Hola,

No probe el script pero desde ya te agradezco que lo compartas!

Una consulta, suponiendo que le llamo al script importardatos.php, como le paso el valor para entity?

Hay manera de saber si la importacion fue correcta? Si se cargaron todos los datos?
Quizas crear algun archivo en donde se deje una variable con un valor, si es 1 salio todo bien, si es 0, hubo un error. Esto como para saber q todo funciona bien, sino estaria vendiendo a precios viejos en el site.

Las fotos hay que subirlas a la carpeta upload, no?

Saludos, Exitos, y Muchas gracias.
Claudio

2 | admin

July 14th, 2010 at 3:50 pm

Avatar

Hola Claudio,

el parámetro entity lo debes pasar por GET llamando a importardatos.php?entity=1, por ejemplo.

Respecto a los errores, la misma clase registra los errores en un array $_errors que posteriormente es lanzado a pantalla con displayErrors(). Esto ocurre sólo cuando importas desde el back-office.

Por otro lado la clase gestiona warnings que también son mostrados, en el back-office, una vez finalizado el proceso de importación , estos últimos en la función displayForm() de AdminImport.php

En el script de importación que aparece en el post puedes lanzar displayErrors(), capturar su salida y lanzarla por pantalla y lo mismo con los warnings aunque en este caso deberías de implementarte tu propio displayWarning(), pero basándose en displayErrors() el desarrollo es inmediato.

Las imágenes de productos en Prestashop se guardan dentro de img/p y las de las categorías dentro de img/c
Ahí es donde deberías de subirlas. Si esto no te funcionara, prueba a pasar la URL completa de un directorio donde las tengas todas por ejemplo http://example.com/imagenes/producto1.jpg

Me alegro de haberte servido de ayuda ;-)
Santi

3 | Claudio

July 14th, 2010 at 4:43 pm

Avatar

Respecto a los errores lo util, como se esta buscando automatizar todo, es que queden en un archivo, mas que salgan por pantalla. Esto sabes como se haria?

Y el tema de las imagenes, viste que prestashop no las copia directamente a p o c, les hace un proceso y te guarda x cada una no recuerdo si 4, small, large, etc.
Me parece q cuando probe de importar imagenes, las subi a upload y me las cargo bien. Es necesarios tener los distintos tamaños de imagenes?

4 | Jose Carlos

August 2nd, 2010 at 1:33 am

Avatar

Prestashop cuenta con una utilidad para regenerar todas las miniaturas, desde el backend en la pestaña Preferencias la opción Imagen. Desde ahí se gestionan los distintos tamaños para las imágenes y está la opción de regenerar miniaturas.

5 | Moises Lazaro

October 11th, 2010 at 5:28 am

Avatar

Excelente , me sirvio de mucho el scrip muchas gracias , mas bien tengo una consulta , que puedo hacer para enviar el parametro para que borre la db de productos pues cada vez que ejecuto la funcion esta me duplica la data y no la actualiza como pensaba
gracias

6 | Rafa

October 21st, 2010 at 11:29 am

Avatar

Hola, muchas gracias por el script, me funciona todo ok pero tengo un problema las fotos no me las sube, le paso la url http://example.com/imagenes/producto1.jpg pero no la pilla, sin embargo si lo hago desde el BO con el mismo cvs si que las sube.

A que puede ser debido? mi prestashop 1.3.2

Un saludo y gracias :-)

7 | Rafa

October 26th, 2010 at 8:51 am

Avatar

Alguna sugerencia?

8 | Rafa

October 27th, 2010 at 10:07 am

Avatar

Problema solucionado!!!

En el php AdminImport.php línea 718 se supone que $product->Image es un array, si ejecutamos la importación desde fuera del bo (no es un array) por lo que modifico el código

/*if (isset($product->image) AND is_array($product->image) and sizeof($product->image))*/
if (isset($product->image) AND sizeof($product->image))
{
$productHasImages = (bool)Image::getImages(3, intval($product->id));
/*$productHasImages = (bool)Image::getImages(intval($cookie->id_lang), intval($product->id));
foreach ($product->image AS $key => $url)*/
$url=$product->image;
if (!empty($url))
{

De esta forma solo podremos importar una foto, no una lista de fotos aunque a mi me basta, supongo que con una lista si que funcionaria.

9 | admin

October 27th, 2010 at 3:25 pm

Avatar

Hola Rafa,

me has pillado en una de las semanas más ocupadas del año. Revisaré el script para buscar la forma de solucionarlo, a poder ser sin tocar el código fuente del AdminImport.php que es código del core del Prestashop.

10 | david

November 20th, 2010 at 12:07 pm

Avatar

Hola,

La verdad es que este script es muy util, pero la mejora con las imagenes es importante. ¿ has podido ver si es viable realizar el cambio en el script en vez del codigo core ?

11 | admin

November 22nd, 2010 at 9:46 am

Avatar

Hola David,

sigo muy ocupado y aún no he tenido tiempo. Esperemos que en breve ;-)

12 | david

November 28th, 2010 at 12:37 am

Avatar

Gracias por la respuesta. Esperaremos

13 | vfenix

January 4th, 2011 at 2:46 am

Avatar

rferrero, has podido terminar el script???

Estoy tratando de utilizarlo, lo subo al ftp dentro del directorio del admin, pero después no sé cual es el siguiente paso.

¿Dónde se configura la dirección de donde tiene que “recoger” los datos del proveedor? ¿Aparece en el bo? ¿No hay que hacer nada más?

Igualmente gracias por tu trabajo, eres de los pocos que lo ha compartido desinteresadamente.

14 | admin

January 4th, 2011 at 10:26 am

Avatar

Hola @verofenix,

el script está preparado para ser llamado en remoto utilizando el path completo, por ejemplo http://example.com/admin/script.php?entity=0 donde en este caso el script lo hubiéramos llamado script.php

El script no tiene configuración en el BO y sólo importa productos y categorías desde ficheros CSV que se encuentren en el servidor.

Espero haberte ayudado ;-)

15 | Xikot5

January 19th, 2011 at 12:15 pm

Avatar

hola a todos!!! Perdonen mi ignorancia pero no se donde meter el fichero csv para q me lo detecte (^_^)’. Lo e puesto en la misma carpeta q el scipt pero al ejecutarlo me dice q no puede leer el fichero. Llevo ya 3 meses intentando hacer un csv en condiciones xq siempre me encuentran algun fallo asi q si alguien me puede decir esto estaria muy agradecido. Un saludo y gracias.

16 | admin

January 19th, 2011 at 12:45 pm

Avatar

Hola Xikot5,

he ampliado el post para indicar el path de los CSV. Te lo pego aquí:

Los ficheros CSV a importar deben encontrarse en el directorio /admin/import mientras que nuestro script debe de estar situado en el directorio /admin del Prestashop.

Un saludo

17 | Xikot5

January 20th, 2011 at 9:27 am

Avatar

hola de nuevo y gracias por tu tiempo. Ahora tengo tu scrip en la carpeta admin y mi csv en la import (todo con permisos 777) y este el path q utilizo para llamarlo -> http://www.xxx.cat/admin49/importardatos.php?entity=1
pero todabia me dice q no puede leer el fichero. Se te ocurre q puedo tar aciendo mal? Utilizo la version 1.3.6.

18 | admin

January 20th, 2011 at 9:50 am

Avatar

Hola,

aún no lo he probado con la rama 1.3.x del Prestashop, así que desconozco si puede venir por ahí el problema. ¿Alguien lo ha probado en la rama 1.3.x?

¿Puedes pegar el error que devuelve? ¿El nombre del CSV es el esperado, pro.csv o cat.csv?

19 | Xikot5

January 20th, 2011 at 10:06 am

Avatar

wenas! pensaba q lo de pro.csv y cat.csv era un ejemplo ^^’ aora no me devuelve el error (era este : Cannot read the csv file) sino q se queda la pagina en blanco pero cuando voi al BO nose me an importado los productos e revisado i tengo los mismos campos q en el scrip, nose si es q soy un pardillo o es q esto es muy dificil, estoy ya desquiciado :(

20 | admin

January 20th, 2011 at 1:58 pm

Avatar

Xikot5,

se ve que editando el post había desaparecido parte del principio del script. Lo he corregido. Revisa que no vayan por ahí los tiros.

Por otro lado, la pantalla en blanco seguramente se produzca por un error en el PHP que tu servidor está escondiendo.

Para obtener más información añade estas dos lineas al principio del script:

error_reporting(E_ALL);
ini_set('display_errors', '1');

21 | Xikot5

January 21st, 2011 at 9:53 am

Avatar

wenos dias! he vuelto a crear el script por lo q me as comentado y le he añadido las dos lineas con lo q ahora me muestra estas dos advertencias:

Warning: key_exists() [function.key-exists]: The second argument should be either an array or an object in /var/www/vhosts/elaborats.cat/httpdocs/classes/AdminTab.php on line 164

Notice: Trying to get property of non-object in /var/www/vhosts/elaborats.cat/httpdocs/classes/AdminTab.php on line 148

Lo he estado mirando pero no se por donde cojerlo.

22 | admin

January 21st, 2011 at 10:39 am

Avatar

El script da ese error en la rama 1.3.x del Prestashop, que supongo que es la que estás probando. Tengo previsto adaptarlo en breve. Lo publicaré aquí.

23 | Xikot5

January 21st, 2011 at 11:01 am

Avatar

Gracias por tu tiempo, viendo tu curriculum no creo q esto te cueste muxo xD. Efectivamente utilizo la 1.3.6. Esparare la actualizaion puesto q en todo el tiempo q llevo liado con prestashop has sido el unico q ha contestado los post. Haces un gran trabajo.

24 | verofenix

February 11th, 2011 at 4:00 am

Avatar

está a puntito de salir la version 1.4 como definitiva, va a tocar actualizar dos veces XD.

Por cierto, gracias por la respuesta, que no te lo dije, pero me salen los mismor errores que a los compañeros, porque estoy usando las últimas versiones del presta, y actualizo en cuanto están disponibles para descargar.

Buen trabajo igualmente ^^.

25 | admin

February 11th, 2011 at 9:22 am

Avatar

Y esperemos que no sean tres.

Estoy a punto de abandonar esa linea de desarrollo. En mi caso en concreto he acabado necesitando un script que ataque directamente a la base de datos ya que la importación por CSV no permite controlar al detalle una actualización de productos existentes.

En cualquier caso este script es una prueba de concepto para automatizar una importación mediante CSV, sin necesidad de pasar por el backoffice. Eso y sólo eso y necesita ser complementado con un desarrollo en la parte de cliente que se encargue de generar los CSV, subirlos al servidor y llamar a este script, para tener un verdadero script de importación.
Con eso se tendría un buen script de sincronización automatizada pero sólo en un sentido: Desde el origen hasta el Prestashop.

Si alguien quiere/puede corregir o completar el script que no dude en hacerlo saber.

26 | Josep

February 22nd, 2011 at 4:25 pm

Avatar

Buenas.
Seguramente deberé realizar lo mismo o algo parecido para el sitio donde trabajo.
Tengo que conectar un MSSQL, con el MySQL.
Pero con la salvedad que también tengo que importar(MySQL –> MSSQL) las orders…
Miraré a ver que puedo hacer con la exportación de categorías y productos, aún así creo que no podré utilizar las funciones nativas.
Bueno si sale algo decente ya lo publicaré. Alguien ha avanzado con las versiones 1.3.X? Creo que me centraré en la 1.4 RC3 o 4
Un saludo.

27 | hostxxi

March 1st, 2011 at 3:52 pm

Avatar

Hola, el script no funciona ni puede funcionar con las nuevas versiones por temas de seguridad.

Al navegar por la administración se hacen comprobaciones con una cadena llamada token. Si no le pasais el token correcto da un fallo. Las funciones que se utilizan en el script requieren este token, por lo que no funciona.

La forma de hacerlo sería mediante la libreria Curl.

Un saludo

28 | admin

March 1st, 2011 at 3:55 pm

Avatar

Hola,

el caso es que el error que yo recuerdo parecía propio del PHP, más relacionado con la definición de clases, que no con el token.

Una alternativa, como bien dices, es cURL.

Suerte

29 | hostxxi

March 1st, 2011 at 5:10 pm

Avatar

Cuando lo probé me daba un fallo que comentas porque no tenia Cookie.

Se ve que la comprobación de seguridad la hace con el token y la cookie que se crea al acceder a la administración.

Un saludo

30 | vancaru

April 28th, 2011 at 10:35 am

Avatar

Buenas,

gracias por el aporte, va perfecto también en la versión 1.4, un par de modificaciones en las variables de la función “loadProductsPost()” y de lujo (las pruebas son en local). Ahora quiero probar como implementar algún tipo de aviso al finalizar. Si consigo algo decente, lo comento.

Saludos

31 | admin

April 28th, 2011 at 10:43 am

Avatar

Hola Vancaru,

gracias por tu aportación. Si finalmente implementas el sistema de avisos y quieres publicarlo, esta es tu casa ;-)
Un saludo

32 | Pau

June 23rd, 2011 at 6:16 am

Avatar

Buenas a todos.
He leido todo el hilo, he implementado el script en una importación automatizada y tengo varias dudas por si podéis ayudarme.

Mi necesidad es que el CSV de productos y categorías me lo da el proveedor de productos, con lo que no puedo manipular el CSV original para añadir las columnas que me exige el prestashop.

La solución es extraer sólo los campos que me interesan y crear un CSV a la medida del prestashop. He creado un script que publicaré aquí cuanto lo tenga terminado para aportar mi experiencia.

Mi script crea un CSV sólo extrayendo los campos que necesito para prestashop, los coloca en el orden necesario y los deja en la carpeta /ADMIN/IMPORT.

El problema:
Cuando uso las opciones del BACKOFFICE de importar, selecciono los campos del desplegable de importar productos y le doy a importar, funciona (si lo hago con pocos productos, entre 10 y 300, mas se cuelga y no termina nunca.) Lo que significa que mi script funciona y prepara correctamente los CSV.

Cuando uso tu script, que he modificado para sólo seleccionar los campos que realmente uso en la importación desde backoffice, no importa nada.

Pregunta:
Como debo preparar el array de campos a importar?
En mi caso son 14 de los 27 campos:
array (
0 => ‘id’,
1 => ‘active’,
2 => ‘name’,
3 => ‘category’,
4 => ‘wholesale_price’,
5 => ‘tax_rate’,
6 => ‘reference’,
7 => ‘manufacturer’,
8 => ’supplier_reference’,
9 => ‘ean13′,
10 => ‘quantity’,
11 => ‘description_short’,
12 => ‘description’,
13 => ‘meta_title’,
14 => ‘image’,
),
Con esta opción no funciona.
Lo que no explica por ningún lado, o que haya encontrado es como preparar este array. Que es importante la etiqueta o el número. Yo creo que la etiqueta.

Segunda pregunta:
Mi script prepara el CSV para ISO-8859-1, debo poner el campo ‘convert’ => ‘1′, para que lo importe en ese formato?

Gracias anticipadas.

33 | pau_curro

June 28th, 2011 at 12:12 pm

Avatar

Hola a todos.

He implementado la funcion en las versión 1.4 y no soy capaz de saber que parámetros hay que añadir en loadProductsPost() para que funcione correctamente y pueda realizar la importación.

El error que me da es: key_exists() [function.key-exists]: The second argument should be either an array …

Podéis ayudarme?

gracias anticipadas.

34 | pau_curro

June 28th, 2011 at 12:52 pm

Avatar

El error completo es:

Warning: key_exists() [function.key-exists]: The second argument should be either an array or an object in /var/www/vhosts/domain/httpdocs/classes/AdminTab.php on line 215

Gracias.

35 | Fox

June 29th, 2011 at 1:47 pm

Avatar

Saludos que interesante tema y de verdad util, por favor si alguien tiene el script ya corriendo en las versiones 1.4 por favor publicarlo se los agradezco, gracias

36 | Jesús

October 28th, 2011 at 11:34 pm

Avatar

Es una buena aportación, habrá que probarla, 1saludo.

Comment Form

About

ProgramadorPHP.es es el blog profesional de Vicent González i Castells, programador freelance especializado en desarrollo de aplicaciones web. vigoncas@programadorphp.es

CURRÍCULUM

Tags