Jump to content

Importar productos desde csv en subcategorias utilizando NOMBRE de la misma


Recommended Posts

Buenas tardes,

 

Yo utilizo la version 1.5.3 y en categorias los ejemplos muestran el Nombre de la categoria.

Supongamos yo creo un .csv con las categorias pero sin usar un ID (dejando que se autoincremente), entonces luego mi idea era crear los productos y colocarlos bajo estos nombres de categorias, sin pensar en los ID ya que no los "conozco" (se que puedo encontrarlos en el back-office una vez importado el fichero .csv y ver que numero de ID se le ha asignado), ya que la idea y lo mas facil e intuitivo seria colocar nombres y no tener que andar con numeros.

 

Hay una forma? yo lo intento y no me los coge, me crea siempre todos los productos en "Inicio" y unicamente si lo hago a mano desde el back-office puedo colocar estos en la subcategoria o categoria que deseo.

Tener en cuenta que tengo unos 5000 articulos o mas, y hacer esto uno por uno seria una locura.

 

Gracias de antemano y escribo en este apartado ya que he mirado muchisimos post referentes a este tema pero todos tienen el ejemplo "del amor" como tu bien mencionas pero no es lo que a mi me hace falta.

 

Saludos =)

Link to comment
Share on other sites

Hola, debe ser un error de la version 1.5.3 lo mismo me pasa a mi, todos los productos me los importa a la categoría de inicio, pero en la 1.4 no me pasaba esto, siempre importaba los productos solo con el nombre de la subcategoría y los importaba bien, espero que lo arreglen para la 1.5.4

 

pero soy novato en prestashop, por eso tambien espero el comentario de algien mas experimentado.

 

Saludos.

Link to comment
Share on other sites

Skree99,

 

Yo de momento he intentado lo que voy a detallarte y me ha funcionado! Espero no traiga algun defecto secundario pero me parece que no.

 

Path: controllers/admin/AdminImportController.php

 

en ese fichero, alrededor de la linea 640 encontraras:

 

do $uniqid = uniqid(); while (file_exists(PS_UPLOAD_DIR.$uniqid));

$tmp_file = file_put_contents(PS_UPLOAD_DIR.$uniqid, $field);

$fd = fopen($temp, 'r');

 

----- Borralo, previamente salvando una copia del fichero, y reemplaza por esto:

 

//MODIFICADO

do $uniqid_path = PS_UPLOAD_DIR.uniqid(); while (file_exists($uniqid_path));

file_put_contents($uniqid_path, $field);

$fd = fopen($uniqid_path, 'r');

$tab = fgetcsv($fd, MAX_LINE_SIZE, $separator);

fclose($fd);

unlink($uniqid_path); // MODIFICADO

 

if (empty($tab) || (!is_array($tab)))

return array();

return $tab;

}

 

Espero te sirva, a mi la verdad de momento me funciona sin problemas.

He quitado este codigo luego de leer mil paginas, por lo que si tu llegas a encontrar algo mejor ya sabes =)

 

Exitos!

Link to comment
Share on other sites

Skree99,

 

Yo de momento he intentado lo que voy a detallarte y me ha funcionado! Espero no traiga algun defecto secundario pero me parece que no.

 

Path: controllers/admin/AdminImportController.php

 

en ese fichero, alrededor de la linea 640 encontraras:

 

do $uniqid = uniqid(); while (file_exists(PS_UPLOAD_DIR.$uniqid));

$tmp_file = file_put_contents(PS_UPLOAD_DIR.$uniqid, $field);

$fd = fopen($temp, 'r');

 

----- Borralo, previamente salvando una copia del fichero, y reemplaza por esto:

 

//MODIFICADO

do $uniqid_path = PS_UPLOAD_DIR.uniqid(); while (file_exists($uniqid_path));

file_put_contents($uniqid_path, $field);

$fd = fopen($uniqid_path, 'r');

$tab = fgetcsv($fd, MAX_LINE_SIZE, $separator);

fclose($fd);

unlink($uniqid_path); // MODIFICADO

 

if (empty($tab) || (!is_array($tab)))

return array();

return $tab;

}

 

Espero te sirva, a mi la verdad de momento me funciona sin problemas.

He quitado este codigo luego de leer mil paginas, por lo que si tu llegas a encontrar algo mejor ya sabes =)

 

Exitos!

 

Eso se te ha ocurrido a ti, o lo has copiado simplemente de aquí: https://github.com/PrestaShop/PrestaShop/commit/8d7196daf3b39d280c631882f0e3ebe473233d07

 

¿?

Link to comment
Share on other sites

Hola, ya avía visto la pagina que menciona rubalcaba, pero como mi ingles es muy malo no entendía como como cambiar el código, gracias por la explicación, lo voy a probar, aunque también encontré otra solución aquí.

 

http://www.prestashop.com/forums/topic/215671-probleme-import-produit-csv/page__p__1067176__hl__import%20csv__fromsearch__1#entry1067176

 

solo hay que cambiar esta linea:

$fd = fopen($temp, 'r');

 

 

por

 

 

$fd = fopen(_PS_UPLOAD_DIR_.$uniqid, 'r');

 

En el archivo controllers/admin/AdminImportController.php

 

con ese cambio me a funcionado bien, pone los productos en sus categorías y también agarra las imágenes.

 

Saludos.

Edited by skree99 (see edit history)
  • Like 2
Link to comment
Share on other sites

Rubalcaba no dije nunca que se me ha ocurrido a mi, es mas quiza no he sido muy claro pero he escrito "He quitado este codigo luego de leer mil paginas, por lo que si tu llegas a encontrar algo mejor ya sabes =)" en referencia a que consegui este codigo dando vueltas por la red =).

 

Simplemente yo entendi lo que decian y lo probe y funciono.

Skree99 dice que su ingles no es muy bueno y tal vez por ese motivo no habia probado dicho codigo. Vamos, que estamos para ayudarnos, no me tomo el credito de alguien que ha puesto la solucion, simplemente comparto lo que yo he probado y ha funcionado.

 

Saludos y buen Jueves!

Link to comment
Share on other sites

  • 2 weeks later...
  • 4 weeks later...
  • 3 weeks later...

buenos dias, trate de actualizar con el click upgrade, desde el 1.5.3 a v1.5.4, y me da el siguiente error:

Download complete but md5sum does not match (bbb96ed727dc4d692fb177c1ad2f3852).

Por favor si pueden ayudarme. Gracias.

Link to comment
Share on other sites

  • 3 weeks later...

Chicos, os funcionó ese invento? a mi me sucede lo mismo. Me importa todo a la categoría inicio, no sé qué hacer! :_(

 

GRacias!

 

a mi no me funciona, ni este, ni otros, sigo probando cosas.. A mi el prblema es que no me importa los productos a ningun sitio se queda trabajando el navegador pero como si nada.

Link to comment
Share on other sites

Chicos,

 

Este fix si funciona, yo lo he probado ya en varias tiendas de test que he realizado y antes de importar productos aplicaba esto.

Funciona perfectamente, al menos en la version 1.5.3 que es la he utilizado desde siempre.

 

DavOfe:

 

1. Quiza haya alguna columna mal en el fichero csv.

2. Intentas importar muchos productos a la vez y su servidor no lo "soporta".

 

Yo que tu (yo lo he hecho y no solo carga MUCHISIMO mas rapido, sino que evitas largos tiempos de espera en los cuales el servidor termina mostrando un error por tiempos de espera) quitaria para realizar la importacion la opcion de indexacion que encuentras en: Preferencias => Búsqueda. Intenta cargar cantidades menores de productos (yo máximo 1200) si es que tienes la suerte de tener ficheros csv separados por categoría.

 

Importante:

 

No olvides luego de hacer las importaciones necesarias de seleccionar tambien en Preferencias => Búsquedas la opción "Re-construir el índice completo." y ya luego activar la indexación nuevamente.

 

Si no haces esto, en el front-office, campo de búsqueda, no te encontrará los productos que has agregado.

Si decides dejar la opcion de indexación desactivada, recuerda que puedes elegir en este caso la opción "Añadir los productos que faltan al índice", pero te tocará hacerlo cada vez que agregues/modifiques productos.

 

Resumiendo:

Para importar desactiva la indexación sino tardarás muchisimo tiempo al importar grandes cantidades de productos, con sus respectivas imágenes y demás. Yo utilizo Loading, cual recomiendo al 100% ya que antes estaba en 1and1 y realmente casi abandono prestashop por los 1000 dolores de cabeza ocasionados y que no sabia como solucionar, ademas de la diferencia en el rendimiento, parámetros, etc

 

Exito y ya nos cuentas

Edited by hellagood9 (see edit history)
Link to comment
Share on other sites

Chicos,

 

Este fix si funciona, yo lo he probado ya en varias tiendas de test que he realizado y antes de importar productos aplicaba esto.

Funciona perfectamente, al menos en la version 1.5.3 que es la he utilizado desde siempre.

 

 

 

Pero el csv lo he subido anteriormente en la misma version pero al quitar la tienda y volver a subirla (porque la lie parda y no habia solucion) me pasa esto. He aprendido a no hacer ningun cambio de ninguna linea, archivo, o cualquier cosa sin hacer copia de seguridad.

 

He quitado lo de indexar segun actualiza lo productos a ver si va. Ahora estoy subiendo el csv y he modificado otra vez esa linea, voy a ver si hay novedades.,.........

 

EDITO :::: No me funciona.

Edited by DavOfe (see edit history)
Link to comment
Share on other sites

El problema que yo tenia es que los productos se subian a la categoría Home y no me copiaba las imágenes, lo he solucionado así, por si sirve de ayuda (aunque ya se haya comentado mas arriba).

 

En el archivo controllers/admin/AdminImportController.php

 

mas o menos por la linea 645 he dejado el código así (comentado lo que está mal, por si acaso):

 

do $uniqid_path = _PS_UPLOAD_DIR_.uniqid(); while (file_exists($uniqid_path));
file_put_contents($uniqid_path, $field);
$fd = fopen($uniqid_path, 'r');
/*do $uniqid = uniqid(); while (file_exists(_PS_UPLOAD_DIR_.$uniqid));
$tmp_file = file_put_contents(_PS_UPLOAD_DIR_.$uniqid, $field); 
$fd = fopen(_PS_UPLOAD_DIR_.$uniqid, 'r');*/
$tab = fgetcsv($fd, MAX_LINE_SIZE, $separator);
fclose($fd);
//unlink($tmp_file);
unlink($uniqid_path);

 

Las imágenes las tienes que subir a un sitio conocido de tu servidor (por ejemplo: http://www.tudominio.com/imagenes), de tal forma que en la columna URL images del csv tienes que poner la ruta entera de las imágenes, por ejemplo: http://www.tudominio.com/imagenes/image_01.jpg (y así con todas).

 

Una vez hayas subido todos los productos puedes borrar la carpeta imagenes de tu servidor ya que prestashop habrá copiado las imágenes donde las tenga que copiar.

 

Si esto te falla revisa los permisos de la carpeta img de prestashop.

 

Explico todo esto, porque el tema de las imágenes me ha dado muchos quebraderos de cabeza, y despues de mucho buscar en foros (este también) :) encontré la solución, y ahora me funciona correctamente.

 

Saludos

 

PD.- Ahora voy a probar la subida masiva de combinaciones :blink:

Link to comment
Share on other sites

do $uniqid_path = _PS_UPLOAD_DIR_.uniqid(); while (file_exists($uniqid_path));
file_put_contents($uniqid_path, $field);
$fd = fopen($uniqid_path, 'r');
/*do $uniqid = uniqid(); while (file_exists(_PS_UPLOAD_DIR_.$uniqid));
$tmp_file = file_put_contents(_PS_UPLOAD_DIR_.$uniqid, $field);
$fd = fopen(_PS_UPLOAD_DIR_.$uniqid, 'r');*/
$tab = fgetcsv($fd, MAX_LINE_SIZE, $separator);
fclose($fd);
//unlink($tmp_file);
unlink($uniqid_path);

 

 

 

Eso ya esta comentado aqui: https://github.com/P...0e3ebe473233d07 y en miles de post del foro.

 

Gracias de todos modos.

Edited by Rubalcaba (see edit history)
Link to comment
Share on other sites

Pero el csv lo he subido anteriormente en la misma version pero al quitar la tienda y volver a subirla (porque la lie parda y no habia solucion) me pasa esto. He aprendido a no hacer ningun cambio de ninguna linea, archivo, o cualquier cosa sin hacer copia de seguridad.

 

He quitado lo de indexar segun actualiza lo productos a ver si va. Ahora estoy subiendo el csv y he modificado otra vez esa linea, voy a ver si hay novedades.,.........

 

EDITO :::: No me funciona.

 

¿Pero has aplicado el parche?

Link to comment
Share on other sites

Yo en esos dias he utilizado el enlace que menciona Rubalcaba, y efectivamente es algo ya muy mencionado. Se trata de un bug de esta version y aplicado lo de ese enlace se soluciona. Lo de las imagenes hice lo mismo que Fco y tambien sin problemas. Ten en cuenta que si tienes una instalacion limpia de esta version, el parche debes realizarlo ANTES de intentar importar cualquier producto.

Por mi parte no se como mas poder ayudar, ya que no tengo experiencia en ninguna otra version diferente a la 3.5.1 y he instalado a forma de prueba unas 6 tiendas y en todas he seguido el mismo procedimiento y me ha funcionado.

 

Por si te sirve... te dejo las lineas del fichero que yo tengo colocado en mi tienda. Aviso, he realizado muchos otros cambios pero creo, no estoy 100% seguro, en este file solo he modicado lo mencionado en el enlace que posteo Rubalcaba.

No se como adjuntarlo, por eso lo copio, lo siento.

 

Path: controllers/admin

File: AdminImportController.php

 

Suerte y comentanos que tal te ha ido

 

<?php

/*

* 2007-2013 PrestaShop

*

* 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 [email protected] so we can send you a copy immediately.

*

* DISCLAIMER

*

* Do not edit or add to this file if you wish to upgrade PrestaShop to newer

* versions in the future. If you wish to customize PrestaShop for your

* needs please refer to http://www.prestashop.com for more information.

*

* @author PrestaShop SA <[email protected]>

* @copyright 2007-2013 PrestaShop SA

* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)

* International Registered Trademark & Property of PrestaShop SA

*/

 

@ini_set('max_execution_time', 0);

/** No max line limit since the lines can be more than 4096. Performance impact is not significant. */

define('MAX_LINE_SIZE', 0);

 

/** Used for validatefields diying without user friendly error or not */

define('UNFRIENDLY_ERROR', false);

 

/** this value set the number of columns visible on each page */

define('MAX_COLUMNS', 6);

 

/** correct Mac error on eof */

@ini_set('auto_detect_line_endings', '1');

 

class AdminImportControllerCore extends AdminController

{

public static $column_mask;

 

public $entities = array();

 

public $available_fields = array();

 

public $required_fields = array('name');

 

public $cache_image_deleted = array();

 

public static $default_values = array();

 

public static $validators = array(

'active' => array('AdminImportController', 'getBoolean'),

'tax_rate' => array('AdminImportController', 'getPrice'),

/** Tax excluded */

'price_tex' => array('AdminImportController', 'getPrice'),

/** Tax included */

'price_tin' => array('AdminImportController', 'getPrice'),

'reduction_price' => array('AdminImportController', 'getPrice'),

'reduction_percent' => array('AdminImportController', 'getPrice'),

'wholesale_price' => array('AdminImportController', 'getPrice'),

'ecotax' => array('AdminImportController', 'getPrice'),

'name' => array('AdminImportController', 'createMultiLangField'),

'description' => array('AdminImportController', 'createMultiLangField'),

'description_short' => array('AdminImportController', 'createMultiLangField'),

'meta_title' => array('AdminImportController', 'createMultiLangField'),

'meta_keywords' => array('AdminImportController', 'createMultiLangField'),

'meta_description' => array('AdminImportController', 'createMultiLangField'),

'link_rewrite' => array('AdminImportController', 'createMultiLangField'),

'available_now' => array('AdminImportController', 'createMultiLangField'),

'available_later' => array('AdminImportController', 'createMultiLangField'),

'category' => array('AdminImportController', 'split'),

'online_only' => array('AdminImportController', 'getBoolean')

);

 

public $separator;

public $multiple_value_separator;

 

public function __construct()

{

$this->entities = array(

$this->l('Categories:'),

$this->l('Products:'),

$this->l('Combinations'),

$this->l('Customers'),

$this->l('Addresses'),

$this->l('Manufacturers:'),

$this->l('Suppliers:'),

);

 

// @since 1.5.0

if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))

{

$this->entities = array_merge(

$this->entities,

array(

$this->l('SupplyOrders'),

$this->l('SupplyOrdersDetails'),

)

);

}

 

$this->entities = array_flip($this->entities);

 

switch ((int)Tools::getValue('entity'))

{

case $this->entities[$this->l('Combinations')]:

$this->required_fields = array(

'id_product',

'group',

'attribute'

);

 

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id_product' => array('label' => $this->l('Product ID').'*'),

'group' => array(

'label' => $this->l('Attribute (Name:Type:Position)').'*'

),

'attribute' => array(

'label' => $this->l('Value (Value:Position)').'*'

),

'supplier_reference' => array('label' => $this->l('Supplier reference')),

'reference' => array('label' => $this->l('Reference')),

'ean13' => array('label' => $this->l('EAN13')),

'upc' => array('label' => $this->l('UPC')),

'wholesale_price' => array('label' => $this->l('Wholesale price')),

'price' => array('label' => $this->l('Impact on price')),

'ecotax' => array('label' => $this->l('Ecotax')),

'quantity' => array('label' => $this->l('Quantity')),

'minimal_quantity' => array('label' => $this->l('Minimal quantity')),

'weight' => array('label' => $this->l('Impact on weight')),

'default_on' => array('label' => $this->l('Default (0 = No, 1 = Yes)')),

'image_position' => array(

'label' => $this->l('Image position')

),

'image_url' => array('label' => $this->l('Image URL')),

'delete_existing_images' => array(

'label' => $this->l('Delete existing images (0 = No, 1 = Yes)')

),

'shop' => array(

'label' => $this->l('ID / Name of shop'),

'help' => $this->l('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.'),

)

);

 

self::$default_values = array(

'reference' => '',

'supplier_reference' => '',

'ean13' => '',

'upc' => '',

'wholesale_price' => 0,

'price' => 0,

'ecotax' => 0,

'quantity' => 0,

'minimal_quantity' => 1,

'weight' => 0,

'default_on' => 0,

);

break;

 

case $this->entities[$this->l('Categories:')]:

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'active' => array('label' => $this->l('Active (0/1)')),

'name' => array('label' => $this->l('Name *')),

'parent' => array('label' => $this->l('Parent category')),

'is_root_category' => array(

'label' => $this->l('Root category (0/1)'),

'help' => $this->l('A category root is where a category tree can begin. This is used with multistore.')

),

'description' => array('label' => $this->l('Description')),

'meta_title' => array('label' => $this->l('Meta-title')),

'meta_keywords' => array('label' => $this->l('Meta-keywords')),

'meta_description' => array('label' => $this->l('Meta-description')),

'link_rewrite' => array('label' => $this->l('URL rewritten')),

'image' => array('label' => $this->l('Image URL')),

'shop' => array(

'label' => $this->l('ID / Name of shop'),

'help' => $this->l('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.'),

),

);

 

self::$default_values = array(

'active' => '1',

'parent' => Configuration::get('PS_HOME_CATEGORY'),

'link_rewrite' => ''

);

break;

 

case $this->entities[$this->l('Products:')]:

self::$validators['image'] = array(

'AdminImportController',

'split'

);

 

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'active' => array('label' => $this->l('Active (0/1)')),

'name' => array('label' => $this->l('Name *')),

'category' => array('label' => $this->l('Categories (x,y,z...)')),

'price_tex' => array('label' => $this->l('Price tax excluded')),

'price_tin' => array('label' => $this->l('Price tax included')),

'id_tax_rules_group' => array('label' => $this->l('Tax rules ID')),

'wholesale_price' => array('label' => $this->l('Wholesale price')),

'on_sale' => array('label' => $this->l('On sale (0/1)')),

'reduction_price' => array('label' => $this->l('Discount amount')),

'reduction_percent' => array('label' => $this->l('Discount percent')),

'reduction_from' => array('label' => $this->l('Discount from (yyyy-mm-dd)')),

'reduction_to' => array('label' => $this->l('Discount to (yyyy-mm-dd)')),

'reference' => array('label' => $this->l('Reference #')),

'supplier_reference' => array('label' => $this->l('Supplier reference #')),

'supplier' => array('label' => $this->l('Supplier')),

'manufacturer' => array('label' => $this->l('Manufacturer')),

'ean13' => array('label' => $this->l('EAN13')),

'upc' => array('label' => $this->l('UPC')),

'ecotax' => array('label' => $this->l('Ecotax')),

'weight' => array('label' => $this->l('Weight')),

'quantity' => array('label' => $this->l('Quantity')),

'description_short' => array('label' => $this->l('Short description')),

'description' => array('label' => $this->l('Description')),

'tags' => array('label' => $this->l('Tags (x,y,z...)')),

'meta_title' => array('label' => $this->l('Meta-title')),

'meta_keywords' => array('label' => $this->l('Meta-keywords')),

'meta_description' => array('label' => $this->l('Meta-description')),

'link_rewrite' => array('label' => $this->l('URL rewritten')),

'available_now' => array('label' => $this->l('Text when in stock')),

'available_later' => array('label' => $this->l('Text when backorder allowed')),

'available_for_order' => array('label' => $this->l('Available for order (0 = No, 1 = Yes)')),

'date_add' => array('label' => $this->l('Product creation date')),

'show_price' => array('label' => $this->l('Show price (0 = No, 1 = Yes)')),

'image' => array('label' => $this->l('Image URLs (x,y,z...)')),

'delete_existing_images' => array(

'label' => $this->l('Delete existing images (0 = No, 1 = Yes)')

),

'features' => array('label' => $this->l('Feature(Name:Value:Position)')),

'online_only' => array('label' => $this->l('Available online only (0 = No, 1 = Yes)')),

'condition' => array('label' => $this->l('Condition')),

'shop' => array(

'label' => $this->l('ID / Name of shop'),

'help' => $this->l('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.'),

)

);

 

self::$default_values = array(

'id_category' => array((int)Configuration::get('PS_HOME_CATEGORY')),

'id_category_default' => (int)Configuration::get('PS_HOME_CATEGORY'),

'active' => '1',

'quantity' => 0,

'price' => 0,

'id_tax_rules_group' => 0,

'description_short' => array((int)Configuration::get('PS_LANG_DEFAULT') => ''),

'link_rewrite' => array((int)Configuration::get('PS_LANG_DEFAULT') => ''),

'online_only' => 0,

'condition' => 'new',

'date_add' => date('Y-m-d H:i:s'),

'condition' => 'new',

);

break;

 

case $this->entities[$this->l('Customers')]:

//Overwrite required_fields AS only email is required whereas other entities

$this->required_fields = array('email', 'passwd', 'lastname', 'firstname');

 

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'active' => array('label' => $this->l('Active (0/1)')),

'id_gender' => array('label' => $this->l('Titles ID (Mr = 1, Ms = 2, else 0)')),

'email' => array('label' => $this->l('Email *')),

'passwd' => array('label' => $this->l('Password *')),

'birthday' => array('label' => $this->l('Birthday (yyyy-mm-dd)')),

'lastname' => array('label' => $this->l('Last Name *')),

'firstname' => array('label' => $this->l('First Name *')),

'newsletter' => array('label' => $this->l('Newsletter (0/1)')),

'optin' => array('label' => $this->l('Opt-in (0/1)')),

'id_shop' => array(

'label' => $this->l('ID / Name of shop'),

'help' => $this->l('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.'),

),

);

 

self::$default_values = array(

'active' => '1',

'id_shop' => Configuration::get('PS_SHOP_DEFAULT'),

);

break;

 

case $this->entities[$this->l('Addresses')]:

//Overwrite required_fields

$this->required_fields = array(

'lastname',

'firstname',

'address1',

'postcode',

'country',

'customer_email',

'city'

);

 

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'alias' => array('label' => $this->l('Alias *')),

'active' => array('label' => $this->l('Active (0/1)')),

'customer_email' => array('label' => $this->l('Customer email')),

'id_customer' => array('label' => $this->l('Customer ID:')),

'manufacturer' => array('label' => $this->l('Manufacturer')),

'supplier' => array('label' => $this->l('Supplier')),

'company' => array('label' => $this->l('Company')),

'lastname' => array('label' => $this->l('Last Name *')),

'firstname' => array('label' => $this->l('First Name *')),

'address1' => array('label' => $this->l('Address 1 *')),

'address2' => array('label' => $this->l('Address 2')),

'postcode' => array('label' => $this->l('Postcode*/ Zipcode*')),

'city' => array('label' => $this->l('City *')),

'country' => array('label' => $this->l('Country *')),

'state' => array('label' => $this->l('State')),

'other' => array('label' => $this->l('Other')),

'phone' => array('label' => $this->l('Phone')),

'phone_mobile' => array('label' => $this->l('Mobile Phone')),

'vat_number' => array('label' => $this->l('VAT number')),

);

 

self::$default_values = array(

'alias' => 'Alias',

'postcode' => 'X'

);

break;

 

case $this->entities[$this->l('Manufacturers:')]:

case $this->entities[$this->l('Suppliers:')]:

//Overwrite validators AS name is not MultiLangField

self::$validators = array(

'description' => array('AdminImportController', 'createMultiLangField'),

'short_description' => array('AdminImportController', 'createMultiLangField'),

'meta_title' => array('AdminImportController', 'createMultiLangField'),

'meta_keywords' => array('AdminImportController', 'createMultiLangField'),

'meta_description' => array('AdminImportController', 'createMultiLangField'),

);

 

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'active' => array('label' => $this->l('Active (0/1)')),

'name' => array('label' => $this->l('Name *')),

'description' => array('label' => $this->l('Description')),

'short_description' => array('label' => $this->l('Short description')),

'meta_title' => array('label' => $this->l('Meta-title')),

'meta_keywords' => array('label' => $this->l('Meta-keywords')),

'meta_description' => array('label' => $this->l('Meta-description')),

'shop' => array(

'label' => $this->l('ID / Name of group shop'),

'help' => $this->l('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.'),

),

);

 

self::$default_values = array(

'shop' => Shop::getGroupFromShop(Configuration::get('PS_SHOP_DEFAULT')),

);

break;

// @since 1.5.0

case $this->entities[$this->l('SupplyOrders')]:

if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))

{

// required fields

$this->required_fields = array(

'id_supplier',

'id_warehouse',

'reference',

'date_delivery_expected',

);

// available fields

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'id_supplier' => array('label' => $this->l('Supplier ID *')),

'id_lang' => array('label' => $this->l('Lang ID')),

'id_warehouse' => array('label' => $this->l('Warehouse ID *')),

'id_currency' => array('label' => $this->l('Currency ID *')),

'reference' => array('label' => $this->l('Supply Order Reference *')),

'date_delivery_expected' => array('label' => $this->l('Delivery Date (Y-M-D)*')),

'discount_rate' => array('label' => $this->l('Discount Rate')),

'is_template' => array('label' => $this->l('Template')),

);

// default values

self::$default_values = array(

'id_lang' => (int)Configuration::get('PS_LANG_DEFAULT'),

'id_currency' => Currency::getDefaultCurrency()->id,

'discount_rate' => '0',

'is_template' => '0',

);

}

break;

// @since 1.5.0

case $this->entities[$this->l('SupplyOrdersDetails')]:

if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))

{

// required fields

$this->required_fields = array(

'supply_order_reference',

'id_product',

'unit_price_te',

'quantity_expected',

);

// available fields

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'supply_order_reference' => array('label' => $this->l('Supply Order Reference *')),

'id_product' => array('label' => $this->l('Product ID *')),

'id_product_attribute' => array('label' => $this->l('Product Attribute ID')),

'unit_price_te' => array('label' => $this->l('Unit Price (tax excl.)*')),

'quantity_expected' => array('label' => $this->l('Quantity Expected *')),

'discount_rate' => array('label' => $this->l('Discount Rate')),

'tax_rate' => array('label' => $this->l('Tax Rate')),

);

// default values

self::$default_values = array(

'discount_rate' => '0',

'tax_rate' => '0',

);

}

}

 

$this->separator = strval(trim(Tools::getValue('separator', ';')));

 

if (is_null(Tools::getValue('multiple_value_separator')) || trim(Tools::getValue('multiple_value_separator')) == '')

$this->multiple_value_separator = ',';

else

$this->multiple_value_separator = Tools::getValue('multiple_value_separator');

 

parent::__construct();

}

 

public function renderForm()

{

if (!is_writable(_PS_ADMIN_DIR_.'/import/'))

$this->displayWarning($this->l('Directory import on admin directory must be writable (CHMOD 755 / 777)'));

 

if (isset($this->warnings) && count($this->warnings))

{

$warnings = array();

foreach ($this->warnings as $warning)

$warnings[] = $warning;

}

 

$files_to_import = scandir(_PS_ADMIN_DIR_.'/import/');

uasort($files_to_import, array('AdminImportController', 'usortFiles'));

foreach ($files_to_import as $k => &$filename)

//exclude . .. .svn and index.php and all hidden files

if (preg_match('/^\..*|index\.php/i', $filename))

unset($files_to_import[$k]);

unset($filename);

 

$this->fields_form = array('');

 

$this->toolbar_scroll = false;

$this->toolbar_btn = array();

 

// adds fancybox

$this->addCSS(_PS_CSS_DIR_.'jquery.fancybox-1.3.4.css', 'screen');

$this->addJqueryPlugin(array('fancybox'));

 

$this->tpl_form_vars = array(

'module_confirmation' => (Tools::getValue('import')) && (isset($this->warnings) && !count($this->warnings)),

'path_import' => _PS_ADMIN_DIR_.'/import/',

'entities' => $this->entities,

'entity' => Tools::getValue('entity'),

'files_to_import' => $files_to_import,

'languages' => Language::getLanguages(false),

'id_language' => $this->context->language->id,

'available_fields' => $this->getAvailableFields(),

'truncateAuthorized' => (Shop::isFeatureActive() && $this->context->employee->isSuperAdmin()) || !Shop::isFeatureActive(),

'PS_ADVANCED_STOCK_MANAGEMENT' => Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'),

);

 

return parent::renderForm();

}

 

public function renderView()

{

$this->addJS(_PS_JS_DIR_.'adminImport.js');

 

$handle = $this->openCsvFile();

$nb_column = $this->getNbrColumn($handle, $this->separator);

$nb_table = ceil($nb_column / MAX_COLUMNS);

 

$res = array();

foreach ($this->required_fields as $elem)

$res[] = '\''.$elem.'\'';

 

$data = array();

for ($i = 0; $i < $nb_table; $i++)

$data[$i] = $this->generateContentTable($i, $nb_column, $handle, $this->separator);

 

$this->tpl_view_vars = array(

'import_matchs' => Db::getInstance()->executeS('SELECT * FROM '._DB_PREFIX_.'import_match'),

'fields_value' => array(

'csv' => Tools::getValue('csv'),

'convert' => Tools::getValue('convert'),

'entity' => (int)Tools::getValue('entity'),

'iso_lang' => Tools::getValue('iso_lang'),

'truncate' => Tools::getValue('truncate'),

'forceIDs' => Tools::getValue('forceIDs'),

'match_ref' => Tools::getValue('match_ref'),

'separator' => $this->separator,

'multiple_value_separator' => $this->multiple_value_separator

),

'nb_table' => $nb_table,

'nb_column' => $nb_column,

'res' => implode(',', $res),

'max_columns' => MAX_COLUMNS,

'no_pre_select' => array('price_tin', 'feature'),

'available_fields' => $this->available_fields,

'data' => $data

);

 

return parent::renderView();

}

 

public function initToolbar()

{

switch ($this->display)

{

case 'import':

// Default cancel button - like old back link

$back = Tools::safeOutput(Tools::getValue('back', ''));

if (empty($back))

$back = self::$currentIndex.'&token='.$this->token;

 

$this->toolbar_btn['cancel'] = array(

'href' => $back,

'desc' => $this->l('Cancel')

);

// Default save button - action dynamically handled in javascript

$this->toolbar_btn['save-import'] = array(

'href' => '#',

'desc' => $this->l('Import .CSV data')

);

break;

}

}

 

protected function generateContentTable($current_table, $nb_column, $handle, $glue)

{

$html = '<table id="table'.$current_table.'" style="display: none;" class="table" cellspacing="0" cellpadding="0">

<tr>';

 

// Header

for ($i = 0; $i < $nb_column; $i++)

if (MAX_COLUMNS * (int)$current_table <= $i && (int)$i < MAX_COLUMNS * ((int)$current_table + 1))

$html .= '<th style="width: '.(900 / MAX_COLUMNS).'px; vertical-align: top; padding: 4px">

<select onchange="askFeatureName(this, '.$i.');"

style="width: '.(900 / MAX_COLUMNS).'px;"

id="type_value['.$i.']"

name="type_value['.$i.']"

class="type_value">

'.$this->getTypeValuesOptions($i).'

</select>

<div id="features_'.$i.'" style="display: none;">

<input style="width: 90px" type="text" name="" id="feature_name_'.$i.'">

<input type="button" value="ok" onclick="replaceFeature($(\'#feature_name_'.$i.'\').attr(\'name\'), '.$i.');">

</div>

</th>';

$html .= '</tr>';

 

AdminImportController::setLocale();

for ($current_line = 0; $current_line < 10 && $line = fgetcsv($handle, MAX_LINE_SIZE, $glue); $current_line++)

{

/* UTF-8 conversion */

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$html .= '<tr id="table_'.$current_table.'_line_'.$current_line.'" style="padding: 4px">';

foreach ($line as $nb_c => $column)

if ((MAX_COLUMNS * (int)$current_table <= $nb_c) && ((int)$nb_c < MAX_COLUMNS * ((int)$current_table + 1)))

$html .= '<td>'.htmlentities(substr($column, 0, 200), ENT_QUOTES, 'UTF-8').'</td>';

$html .= '</tr>';

}

$html .= '</table>';

AdminImportController::rewindBomAware($handle);

return $html;

}

 

public function init()

{

parent::init();

if (Tools::isSubmit('submitImportFile'))

$this->display = 'import';

}

 

public function initContent()

{

// toolbar (save, cancel, new, ..)

$this->initToolbar();

if ($this->display == 'import')

if (Tools::getValue('csv'))

$this->content .= $this->renderView();

else

{

$this->errors[] = $this->l('You must upload a file for go to the next step');

$this->content .= $this->renderForm();

}

else

$this->content .= $this->renderForm();

 

$this->context->smarty->assign(array(

'content' => $this->content,

'url_post' => self::$currentIndex.'&token='.$this->token,

));

}

 

protected static function rewindBomAware($handle)

{

// A rewind wrapper that skip BOM signature wrongly

rewind($handle);

if (($bom = fread($handle, 3)) != "\xEF\xBB\xBF")

rewind($handle);

}

 

protected static function getBoolean($field)

{

return (boolean)$field;

}

 

protected static function getPrice($field)

{

$field = ((float)str_replace(',', '.', $field));

$field = ((float)str_replace('%', '', $field));

return $field;

}

 

protected static function split($field)

{

if (empty($field))

return array();

 

$separator = Tools::getValue('multiple_value_separator');

if (is_null($separator) || trim($separator) == '')

$separator = ',';

 

do $uniqid_path = _PS_UPLOAD_DIR_.uniqid(); while (file_exists($uniqid_path));

file_put_contents($uniqid_path, $field);

$tab = '';

if(!empty($uniqid_path))

{

$fd = fopen($uniqid_path, 'r');

$tab = fgetcsv($fd, MAX_LINE_SIZE, $separator);

fclose($fd);

unlink($uniqid_path);

}

 

if (empty($tab) || (!is_array($tab)))

return array();

return $tab;

}

 

protected static function createMultiLangField($field)

{

$languages = Language::getLanguages(false);

$res = array();

foreach ($languages as $lang)

$res[$lang['id_lang']] = $field;

return $res;

}

 

protected function getTypeValuesOptions($nb_c)

{

$i = 0;

$no_pre_select = array('price_tin', 'feature');

 

$options = '';

foreach ($this->available_fields as $k => $field)

{

$options .= '<option value="'.$k.'"';

if ($k === 'price_tin')

++$nb_c;

if ($i === ($nb_c + 1) && (!in_array($k, $no_pre_select)))

$options .= ' selected="selected"';

$options .= '>'.$field['label'].'</option>';

++$i;

}

return $options;

}

 

/*

* Return fields to be display AS piece of advise

*

* @param $in_array boolean

* @return string or return array

*/

public function getAvailableFields($in_array = false)

{

$i = 0;

$fields = array();

$keys = array_keys($this->available_fields);

array_shift($keys);

foreach ($this->available_fields as $k => $field)

{

if ($k === 'no')

continue;

if ($k === 'price_tin')

$fields[$i - 1] = '<div>'.$this->available_fields[$keys[$i - 1]]['label'].' '.$this->l('or').' '.$field['label'].'<span style="margin-left:16px"></span></div>';

else

{

if (isset($field['help']))

$html = ' <a href="#" class="info_import" title="'.$this->l('Info').'|'.$field['help'].'"><img src="'._PS_ADMIN_IMG_.'information.png"></a>';

else

$html = '<span style="margin-left:16px"></span>';

$fields[] = '<div>'.$field['label'].$html.'</div>';

}

++$i;

}

if ($in_array)

return $fields;

else

return implode("\n\r", $fields);

}

 

protected function receiveTab()

{

$type_value = Tools::getValue('type_value') ? Tools::getValue('type_value') : array();

foreach ($type_value as $nb => $type)

if ($type != 'no')

self::$column_mask[$type] = $nb;

}

 

public static function getMaskedRow($row)

{

$res = array();

if (is_array(self::$column_mask))

foreach (self::$column_mask as $type => $nb)

$res[$type] = isset($row[$nb]) ? $row[$nb] : null;

 

if (Tools::getValue('forceIds')) // if you choose to force table before import the column id is remove from the CSV file.

unset($res['id']);

 

return $res;

}

 

protected static function setDefaultValues(&$info)

{

foreach (self::$default_values as $k => $v)

if (!isset($info[$k]) || $info[$k] == '')

$info[$k] = $v;

}

 

protected static function setEntityDefaultValues(&$entity)

{

$members = get_object_vars($entity);

foreach (self::$default_values as $k => $v)

if ((array_key_exists($k, $members) && $entity->$k === null) || !array_key_exists($k, $members))

$entity->$k = $v;

}

 

protected static function fillInfo($infos, $key, &$entity)

{

$infos = trim($infos);

if (isset(self::$validators[$key][1]) && self::$validators[$key][1] == 'createMultiLangField' && Tools::getValue('iso_lang'))

{

$id_lang = Language::getIdByIso(Tools::getValue('iso_lang'));

$tmp = call_user_func(self::$validators[$key], $infos);

foreach ($tmp as $id_lang_tmp => $value)

if (empty($entity->{$key}[$id_lang_tmp]) || $id_lang_tmp == $id_lang)

$entity->{$key}[$id_lang_tmp] = $value;

}

else

if (!empty($infos) || $infos == '0') // ($infos == '0') => if you want to disable a product by using "0" in active because empty('0') return true

$entity->{$key} = isset(self::$validators[$key]) ? call_user_func(self::$validators[$key], $infos) : $infos;

 

return true;

}

 

public static function arrayWalk(&$array, $funcname, &$user_data = false)

{

if (!is_callable($funcname)) return false;

 

foreach ($array as $k => $row)

if (!call_user_func_array($funcname, array($row, $k, $user_data)))

return false;

return true;

}

 

/**

* copyImg copy an image located in $url and save it in a path

* according to $entity->$id_entity .

* $id_image is used if we need to add a watermark

*

* @param int $id_entity id of product or category (set in entity)

* @param int $id_image (default null) id of the image if watermark enabled.

* @param string $url path or url to use

* @param string entity 'products' or 'categories'

* @return void

*/

protected static function copyImg($id_entity, $id_image = null, $url, $entity = 'products')

{

$tmpfile = tempnam(_PS_TMP_IMG_DIR_, 'ps_import');

$watermark_types = explode(',', Configuration::get('WATERMARK_TYPES'));

 

switch ($entity)

{

default:

case 'products':

$image_obj = new Image($id_image);

$path = $image_obj->getPathForCreation();

break;

case 'categories':

$path = _PS_CAT_IMG_DIR_.(int)$id_entity;

break;

}

$url = str_replace(' ', '%20', trim($url));

 

// Evaluate the memory required to resize the image: if it's too much, you can't resize it.

if (!ImageManager::checkImageMemoryLimit($url))

return false;

 

// 'file_exists' doesn't work on distant file, and getimagesize make the import slower.

// Just hide the warning, the traitment will be the same.

if (@copy($url, $tmpfile))

{

ImageManager::resize($tmpfile, $path.'.jpg');

$images_types = ImageType::getImagesTypes($entity);

foreach ($images_types as $image_type)

ImageManager::resize($tmpfile, $path.'-'.stripslashes($image_type['name']).'.jpg', $image_type['width'], $image_type['height']);

 

if (in_array($image_type['id_image_type'], $watermark_types))

Hook::exec('actionWatermark', array('id_image' => $id_image, 'id_product' => $id_entity));

}

else

{

unlink($tmpfile);

return false;

}

unlink($tmpfile);

return true;

}

 

public function categoryImport()

{

$cat_moved = array();

 

$this->receiveTab();

$handle = $this->openCsvFile();

$default_language_id = (int)Configuration::get('PS_LANG_DEFAULT');

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

$tab_categ = array(Configuration::get('PS_HOME_CATEGORY'), Configuration::get('PS_ROOT_CATEGORY'));

if (isset($info['id']) && in_array((int)$info['id'], $tab_categ))

{

$this->errors[] = Tools::displayError('The ID category cannot be the same as the ID Root category, nor the ID Home category');

continue;

}

AdminImportController::setDefaultValues($info);

 

if (Tools::getValue('forceIDs') && isset($info['id']) && (int)$info['id'])

$category = new Category((int)$info['id']);

else

{

if (isset($info['id']) && (int)$info['id'] && Category::existsInDatabase((int)$info['id'], 'category'))

$category = new Category((int)$info['id']);

else

$category = new Category();

}

 

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $category);

 

if (isset($category->parent) && is_numeric($category->parent))

{

if (isset($cat_moved[$category->parent]))

$category->parent = $cat_moved[$category->parent];

$category->id_parent = $category->parent;

}

elseif (isset($category->parent) && is_string($category->parent))

{

$category_parent = Category::searchByName($default_language_id, $category->parent, true);

if ($category_parent['id_category'])

{

$category->id_parent = (int)$category_parent['id_category'];

$category->level_depth = (int)$category_parent['level_depth'] + 1;

}

else

{

$category_to_create = new Category();

$category_to_create->name = AdminImportController::createMultiLangField($category->parent);

$category_to_create->active = 1;

$category_link_rewrite = Tools::link_rewrite($category_to_create->name[$default_language_id]);

$category_to_create->link_rewrite = $category_link_rewrite;

$category_to_create->id_parent = Configuration::get('PS_HOME_CATEGORY'); // Default parent is home for unknown category to create

if (($field_error = $category_to_create->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $category_to_create->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $category_to_create->add())

$category->id_parent = $category_to_create->id;

else

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$category_to_create->name[$default_language_id],

(isset($category_to_create->id) ? $category_to_create->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

if (isset($category->link_rewrite) && !empty($category->link_rewrite[$default_language_id]))

$valid_link = Validate::isLinkRewrite($category->link_rewrite[$default_language_id]);

else

$valid_link = false;

 

if (!Shop::isFeatureActive())

$category->id_shop_default = 1;

else

$category->id_shop_default = (int)Context::getContext()->shop->id;

 

$bak = $category->link_rewrite[$default_language_id];

if ((isset($category->link_rewrite) && empty($category->link_rewrite[$default_language_id])) || !$valid_link)

{

$category->link_rewrite = Tools::link_rewrite($category->name[$default_language_id]);

if ($category->link_rewrite == '')

{

$category->link_rewrite = 'friendly-url-autogeneration-failed';

$this->warnings[] = sprintf(Tools::displayError('URL rewriting failed to auto-generate a friendly URL for: %s'), $category->name[$default_language_id]);

}

$category->link_rewrite = AdminImportController::createMultiLangField($category->link_rewrite);

}

 

if (!$valid_link)

$this->warnings[] = sprintf(

Tools::displayError('Rewrite link for %1$s (ID: %2$s) was re-written as %3$s.'),

$bak,

(isset($info['id']) ? $info['id'] : 'null'),

$category->link_rewrite[$default_language_id]

);

$res = false;

if (($field_error = $category->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $category->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && empty($this->errors))

{

$category_already_created = Category::searchByNameAndParentCategoryId(

$default_language_id,

$category->name[$default_language_id],

$category->id_parent

);

 

// If category already in base, get id category back

if ($category_already_created['id_category'])

{

$cat_moved[$category->id] = (int)$category_already_created['id_category'];

$category->id = (int)$category_already_created['id_category'];

}

 

/* No automatic nTree regeneration for import */

$category->doNotRegenerateNTree = true;

 

// If id category AND id category already in base, trying to update

$categories_home_root = array(Configuration::get('PS_ROOT_CATEGORY'), Configuration::get('PS_HOME_CATEGORY'));

if ($category->id && $category->categoryExists($category->id) && !in_array($category->id, $categories_home_root))

$res = $category->update();

if ($category->id == Configuration::get('PS_ROOT_CATEGORY'))

$this->errors[] = Tools::displayError('Root category cannot be modified');

// If no id_category or update failed

if (!$res)

$res = $category->add();

}

//copying images of categories

if (isset($category->image) && !empty($category->image))

if (!(AdminImportController::copyImg($category->id, null, $category->image, 'categories')))

$this->warnings[] = $category->image.' '.Tools::displayError('cannot be copied');

// If both failed, mysql error

if (!$res)

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

(isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'),

(isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID')

);

$error_tmp = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').Db::getInstance()->getMsgError();

if ($error_tmp != '')

$this->errors[] = $error_tmp;

}

else

{

// Associate category to shop

if (Shop::isFeatureActive())

{

Db::getInstance()->execute('

DELETE FROM '._DB_PREFIX_.'category_shop

WHERE id_category = '.(int)$category->id

);

 

if (!Shop::isFeatureActive())

$info['shop'] = 1;

elseif (!isset($info['shop']) || empty($info['shop']))

$info['shop'] = implode($this->multiple_value_separator, Shop::getContextListShopID());

 

// Get shops for each attributes

$info['shop'] = explode($this->multiple_value_separator, $info['shop']);

 

foreach ($info['shop'] as $shop)

if (!is_numeric($shop))

$category->addShop(Shop::getIdByName($shop));

else

$category->addShop($shop);

}

}

}

 

/* Import has finished, we can regenerate the categories nested tree */

Category::regenerateEntireNtree();

 

$this->closeCsvFile($handle);

}

 

public function productImport()

{

$this->receiveTab();

$handle = $this->openCsvFile();

$default_language_id = (int)Configuration::get('PS_LANG_DEFAULT');

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

if (Tools::getValue('forceIDs') && isset($info['id']) && (int)$info['id'])

$product = new Product((int)$info['id']);

else

{

if (array_key_exists('id', $info) && (int)$info['id'] && Product::existsInDatabase((int)$info['id'], 'product'))

$product = new Product((int)$info['id']);

else

$product = new Product();

}

 

if (array_key_exists('id', $info) && (int)$info['id'] && Product::existsInDatabase((int)$info['id'], 'product'))

{

$product->loadStockData();

$category_data = Product::getProductCategories((int)$product->id);

foreach ($category_data as $tmp)

$product->category[] = $tmp;

}

 

AdminImportController::setEntityDefaultValues($product);

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $product);

 

if (!Shop::isFeatureActive())

$product->shop = 1;

elseif (!isset($product->shop) || empty($product->shop))

$product->shop = implode($this->multiple_value_separator, Shop::getContextListShopID());

 

if (!Shop::isFeatureActive())

$product->id_shop_default = 1;

else

$product->id_shop_default = (int)Context::getContext()->shop->id;

 

// link product to shops

$product->id_shop_list = array();

foreach (explode($this->multiple_value_separator, $product->shop) as $shop)

if (!is_numeric($shop))

$product->id_shop_list[] = Shop::getIdByName($shop);

else

$product->id_shop_list[] = $shop;

 

if ((int)$product->id_tax_rules_group != 0)

{

if (Validate::isLoadedObject(new TaxRulesGroup($product->id_tax_rules_group)))

{

$address = $this->context->shop->getAddress();

$tax_manager = TaxManagerFactory::getManager($address, $product->id_tax_rules_group);

$product_tax_calculator = $tax_manager->getTaxCalculator();

$product->tax_rate = $product_tax_calculator->getTotalRate();

}

else

$this->addProductWarning(

'id_tax_rules_group',

$product->id_tax_rules_group,

Tools::displayError('Invalid tax rule group ID, you first need a group with this ID.')

);

}

if (isset($product->manufacturer) && is_numeric($product->manufacturer) && Manufacturer::manufacturerExists((int)$product->manufacturer))

$product->id_manufacturer = (int)$product->manufacturer;

else if (isset($product->manufacturer) && is_string($product->manufacturer) && !empty($product->manufacturer))

{

if ($manufacturer = Manufacturer::getIdByName($product->manufacturer))

$product->id_manufacturer = (int)$manufacturer;

else

{

$manufacturer = new Manufacturer();

$manufacturer->name = $product->manufacturer;

if (($field_error = $manufacturer->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $manufacturer->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $manufacturer->add())

$product->id_manufacturer = (int)$manufacturer->id;

else

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$manufacturer->name,

(isset($manufacturer->id) ? $manufacturer->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

 

if (isset($product->supplier) && is_numeric($product->supplier) && Supplier::supplierExists((int)$product->supplier))

$product->id_supplier = (int)$product->supplier;

else if (isset($product->supplier) && is_string($product->supplier) && !empty($product->supplier))

{

if ($supplier = Supplier::getIdByName($product->supplier))

$product->id_supplier = (int)$supplier;

else

{

$supplier = new Supplier();

$supplier->name = $product->supplier;

$supplier->active = true;

 

if (($field_error = $supplier->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $supplier->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $supplier->add())

{

$product->id_supplier = (int)$supplier->id;

$supplier->associateTo($product->id_shop_list);

}

else

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$supplier->name,

(isset($supplier->id) ? $supplier->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

 

if (isset($product->price_tex) && !isset($product->price_tin))

$product->price = $product->price_tex;

else if (isset($product->price_tin) && !isset($product->price_tex))

{

$product->price = $product->price_tin;

// If a tax is already included in price, withdraw it from price

if ($product->tax_rate)

$product->price = (float)number_format($product->price / (1 + $product->tax_rate / 100), 6, '.', '');

}

else if (isset($product->price_tin) && isset($product->price_tex))

$product->price = $product->price_tex;

 

if (isset($product->category) && is_array($product->category) && count($product->category))

{

$product->id_category = array(); // Reset default values array

foreach ($product->category as $value)

{

if (is_numeric($value))

{

if (Category::categoryExists((int)$value))

$product->id_category[] = (int)$value;

else

{

$category_to_create = new Category();

$category_to_create->id = (int)$value;

$category_to_create->name = AdminImportController::createMultiLangField($value);

$category_to_create->active = 1;

$category_to_create->id_parent = Configuration::get('PS_HOME_CATEGORY'); // Default parent is home for unknown category to create

$category_link_rewrite = Tools::link_rewrite($category_to_create->name[$default_language_id]);

$category_to_create->link_rewrite = AdminImportController::createMultiLangField($category_link_rewrite);

if (($field_error = $category_to_create->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $category_to_create->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $category_to_create->add())

$product->id_category[] = (int)$category_to_create->id;

else

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$category_to_create->name[$default_language_id],

(isset($category_to_create->id) ? $category_to_create->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

else if (is_string($value) && !empty($value))

{

$category = Category::searchByName($default_language_id, trim($value), true);

if ($category['id_category'])

$product->id_category[] = (int)$category['id_category'];

else

{

$category_to_create = new Category();

if (!Shop::isFeatureActive())

$category_to_create->id_shop_default = 1;

else

$category_to_create->id_shop_default = (int)Context::getContext()->shop->id;

$category_to_create->name = AdminImportController::createMultiLangField(trim($value));

$category_to_create->active = 1;

$category_to_create->id_parent = (int)Configuration::get('PS_HOME_CATEGORY'); // Default parent is home for unknown category to create

$category_link_rewrite = Tools::link_rewrite($category_to_create->name[$default_language_id]);

$category_to_create->link_rewrite = AdminImportController::createMultiLangField($category_link_rewrite);

if (($field_error = $category_to_create->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $category_to_create->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $category_to_create->add())

$product->id_category[] = (int)$category_to_create->id;

else

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$category_to_create->name[$default_language_id],

(isset($category_to_create->id) ? $category_to_create->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

}

}

 

$product->id_category_default = isset($product->id_category[0]) ? (int)$product->id_category[0] : '';

 

$link_rewrite = (is_array($product->link_rewrite) && count($product->link_rewrite)) ? trim($product->link_rewrite[$default_language_id]) : '';

 

$valid_link = Validate::isLinkRewrite($link_rewrite);

 

if ((isset($product->link_rewrite[$default_language_id]) && empty($product->link_rewrite[$default_language_id])) || !$valid_link)

{

$link_rewrite = Tools::link_rewrite($product->name[$default_language_id]);

if ($link_rewrite == '')

$link_rewrite = 'friendly-url-autogeneration-failed';

}

 

if (!$valid_link)

$this->warnings[] = sprintf(

Tools::displayError('Rewrite link for %1$s (ID: %2$s) was re-written as %3$s.'),

$link_rewrite,

(isset($info['id']) ? $info['id'] : 'null'),

$link_rewrite

);

 

$product->link_rewrite = AdminImportController::createMultiLangField($link_rewrite);

 

// replace the value of separator by coma

if ($this->multiple_value_separator != ',')

foreach ($product->meta_keywords as &$meta_keyword)

if (!empty($meta_keyword))

$meta_keyword = str_replace($this->multiple_value_separator, ',', $meta_keyword);

 

$res = false;

$field_error = $product->validateFields(UNFRIENDLY_ERROR, true);

$lang_field_error = $product->validateFieldsLang(UNFRIENDLY_ERROR, true);

if ($field_error === true && $lang_field_error === true)

{

// check quantity

if ($product->quantity == null)

$product->quantity = 0;

 

// If match ref is specified && ref product && ref product already in base, trying to update

if (Tools::getValue('match_ref') == 1 && $product->reference && $product->existsRefInDatabase($product->reference))

{

$datas = Db::getInstance()->getRow('

SELECT product_shop.`date_add`, p.`id_product`

FROM `'._DB_PREFIX_.'product` p

'.Shop::addSqlAssociation('product', 'p').'

WHERE p.`reference` = "'.$product->reference.'"

');

$product->id = (int)$datas['id_product'];

$product->date_add = pSQL($datas['date_add']);

$res = $product->update();

} // Else If id product && id product already in base, trying to update

else if ($product->id && Product::existsInDatabase((int)$product->id, 'product'))

{

$datas = Db::getInstance()->getRow('

SELECT product_shop.`date_add`

FROM `'._DB_PREFIX_.'product` p

'.Shop::addSqlAssociation('product', 'p').'

WHERE p.`id_product` = '.(int)$product->id);

$product->date_add = pSQL($datas['date_add']);

$res = $product->update();

}

// If no id_product or update failed

if (!$res)

{

if (isset($product->date_add) && $product->date_add != '')

$res = $product->add(false);

else

$res = $product->add();

}

}

 

$shops = array();

$product_shop = explode($this->multiple_value_separator, $product->shop);

foreach ($product_shop as $shop)

{

$shop = trim($shop);

if (!is_numeric($shop))

$shop = ShopGroup::getIdByName($shop);

$shops[] = $shop;

}

if (empty($shops))

$shops = Shop::getContextListShopID();

// If both failed, mysql error

if (!$res)

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

(isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'),

(isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

 

}

else

{

// Product supplier

if (isset($product->id_supplier) && isset($product->supplier_reference))

{

$id_product_supplier = ProductSupplier::getIdByProductAndSupplier((int)$product->id, 0, (int)$product->id_supplier);

if ($id_product_supplier)

$product_supplier = new ProductSupplier((int)$id_product_supplier);

else

$product_supplier = new ProductSupplier();

 

$product_supplier->id_product = $product->id;

$product_supplier->id_product_attribute = 0;

$product_supplier->id_supplier = $product->id_supplier;

$product_supplier->product_supplier_price_te = $product->wholesale_price;

$product_supplier->product_supplier_reference = $product->supplier_reference;

$product_supplier->save();

}

 

// SpecificPrice (only the basic reduction feature is supported by the import)

if ((isset($info['reduction_price']) && $info['reduction_price'] > 0) || (isset($info['reduction_percent']) && $info['reduction_percent'] > 0))

{

$specific_price = new SpecificPrice();

$specific_price->id_product = (int)$product->id;

// @todo multishop specific price import

$specific_price->id_shop = $this->context->shop->id;

$specific_price->id_currency = 0;

$specific_price->id_country = 0;

$specific_price->id_group = 0;

$specific_price->price = -1;

$specific_price->id_customer = 0;

$specific_price->from_quantity = 1;

$specific_price->reduction = (isset($info['reduction_price']) && $info['reduction_price']) ? $info['reduction_price'] : $info['reduction_percent'] / 100;

$specific_price->reduction_type = (isset($info['reduction_price']) && $info['reduction_price']) ? 'amount' : 'percentage';

$specific_price->from = (isset($info['reduction_from']) && Validate::isDate($info['reduction_from'])) ? $info['reduction_from'] : '0000-00-00 00:00:00';

$specific_price->to = (isset($info['reduction_to']) && Validate::isDate($info['reduction_to'])) ? $info['reduction_to'] : '0000-00-00 00:00:00';

if (!$specific_price->add())

$this->addProductWarning(Tools::safeOutput($info['name']), $product->id, $this->l('Discount is invalid'));

}

 

if (isset($product->tags) && !empty($product->tags))

{

// Delete tags for this id product, for no duplicating error

Tag::deleteTagsForProduct($product->id);

 

if (!is_array($product->tags))

{

$product->tags = AdminImportController::createMultiLangField($product->tags);

foreach ($product->tags as $key => $tags)

{

$is_tag_added = Tag::addTags($key, $product->id, $tags, $this->multiple_value_separator);

if (!$is_tag_added)

{

$this->addProductWarning(Tools::safeOutput($info['name']), $product->id, $this->l('Tags list is invalid'));

break;

}

}

}

else

{

foreach ($product->tags as $key => $tags)

{

$str = '';

foreach ($tags as $one_tag)

$str .= $one_tag.$this->multiple_value_separator;

$str = rtrim($str, $this->multiple_value_separator);

 

$is_tag_added = Tag::addTags($key, $product->id, $str, $this->multiple_value_separator);

if (!$is_tag_added)

{

$this->addProductWarning(Tools::safeOutput($info['name']), (int)$product->id, 'Invalid tag(s) ('.$str.')');

break;

}

}

}

}

//delete existing images if "delete_existing_images" is set to 1

if (isset($product->delete_existing_images))

if ((bool)$product->delete_existing_images)

$product->deleteImages();

else if (isset($product->image) && is_array($product->image) && count($product->image))

$product->deleteImages();

 

if (isset($product->image) && is_array($product->image) && count($product->image))

{

$product_has_images = (bool)Image::getImages($this->context->language->id, (int)$product->id);

foreach ($product->image as $key => $url)

{

$url = trim($url);

$error = false;

if (!empty($url))

{

$url = str_replace(' ', '%20', $url);

 

$image = new Image();

$image->id_product = (int)$product->id;

$image->position = Image::getHighestPosition($product->id) + 1;

$image->cover = (!$key && !$product_has_images) ? true : false;

// file_exists doesn't work with HTTP protocol

if (@fopen($url, 'r') == false)

$error = true;

else if (($field_error = $image->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $image->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $image->add())

{

// associate image to selected shops

$image->associateTo($shops);

if (!AdminImportController::copyImg($product->id, $image->id, $url))

{

$image->delete();

$this->warnings[] = sprintf(Tools::displayError('Error copying image: %s'), $url);

}

}

else

$error = true;

}

else

$error = true;

 

if ($error)

$this->warnings[] = sprintf(Tools::displayError('Product n°%1$d: the picture cannot be saved: %2$s'), $image->id_product, $url);

}

}

if (isset($product->id_category))

$product->updateCategories(array_map('intval', $product->id_category));

 

// Features import

$features = get_object_vars($product);

 

if (isset($features['features']) && !empty($features['features']))

foreach (explode($this->multiple_value_separator, $features['features']) as $single_feature)

{

$tab_feature = explode(':', $single_feature);

$feature_name = trim($tab_feature[0]);

$feature_value = trim($tab_feature[1]);

$position = isset($tab_feature[2]) ? $tab_feature[2]: false;

if(!empty($feature_name) && !empty($feature_value))

{

$id_feature = Feature::addFeatureImport($feature_name, $position);

$id_feature_value = FeatureValue::addFeatureValueImport($id_feature, $feature_value);

Product::addFeatureProductImport($product->id, $id_feature, $id_feature_value);

}

}

// clean feature positions to avoid conflict

Feature::cleanPositions();

}

 

// stock available

if (Shop::isFeatureActive())

{

foreach ($shops as $shop)

StockAvailable::setQuantity((int)$product->id, 0, $product->quantity, (int)$shop);

}

else

StockAvailable::setQuantity((int)$product->id, 0, $product->quantity, $this->context->shop->id);

 

}

 

if (Configuration::get('PS_SEARCH_INDEXATION'))

Search::indexation(true);

 

$this->closeCsvFile($handle);

}

 

public function attributeImport()

{

$default_language = Configuration::get('PS_LANG_DEFAULT');

 

$groups = array();

foreach (AttributeGroup::getAttributesGroups($default_language) as $group)

$groups[$group['name']] = (int)$group['id_attribute_group'];

 

$attributes = array();

foreach (Attribute::getAttributes($default_language) as $attribute)

$attributes[$attribute['attribute_group'].'_'.$attribute['name']] = (int)$attribute['id_attribute'];

 

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (count($line) == 1 && empty($line[0]))

continue;

 

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

$info = array_map('trim', $info);

 

AdminImportController::setDefaultValues($info);

 

if (!Shop::isFeatureActive())

$info['shop'] = 1;

elseif (!isset($info['shop']) || empty($info['shop']))

$info['shop'] = implode($this->multiple_value_separator, Shop::getContextListShopID());

 

// Get shops for each attributes

$info['shop'] = explode($this->multiple_value_separator, $info['shop']);

 

$id_shop_list = array();

foreach ($info['shop'] as $shop)

if (!is_numeric($shop))

$id_shop_list[] = Shop::getIdByName($shop);

else

$id_shop_list[] = $shop;

 

if(isset($info['id_product']))

$product = new Product((int)$info['id_product'], false, $default_language);

else

continue;

 

$id_image = null;

 

//delete existing images if "delete_existing_images" is set to 1

if (array_key_exists('delete_existing_images', $info) && $info['delete_existing_images'] && !isset($this->cache_image_deleted[(int)$product->id]))

{

$product->deleteImages();

$this->cache_image_deleted[(int)$product->id] = true;

}

 

if (isset($info['image_url']) && $info['image_url'])

{

$product_has_images = (bool)Image::getImages($this->context->language->id, $product->id);

 

$url = $info['image_url'];

$image = new Image();

$image->id_product = (int)$product->id;

$image->position = Image::getHighestPosition($product->id) + 1;

$image->cover = (!$product_has_images) ? true : false;

 

$field_error = $image->validateFields(UNFRIENDLY_ERROR, true);

$lang_field_error = $image->validateFieldsLang(UNFRIENDLY_ERROR, true);

 

if ($field_error === true && $lang_field_error === true && $image->add())

{

$image->associateTo($id_shop_list);

if (!AdminImportController::copyImg($product->id, $image->id, $url))

{

$this->warnings[] = sprintf(Tools::displayError('Error copying image: %s'), $url);

$image->delete();

}

else

$id_image = array($image->id);

}

else

{

$this->warnings[] = sprintf(

Tools::displayError('%s cannot be saved'),

(isset($image->id_product) ? ' ('.$image->id_product.')' : '')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').mysql_error();

}

}

elseif (isset($info['image_position']) && $info['image_position'])

{

$images = $product->getImages($default_language);

 

if ($images)

foreach ($images as $row)

if ($row['position'] == (int)$info['image_position'])

{

$id_image = array($row['id_image']);

break;

}

if (!$id_image)

$this->warnings[] = sprintf(

Tools::displayError('No image found for combination with id_product = %s and image position = %s.'),

$product->id,

(int)$info['image_position']

);

}

 

$id_attribute_group = 0;

// groups

$groups_attributes = array();

if(isset($info['group']))

foreach (explode($this->multiple_value_separator, $info['group']) as $key => $group)

{

$tab_group = explode(':', $group);

$group = trim($tab_group[0]);

if (!isset($tab_group[1]))

$type = 'select';

else

$type = trim($tab_group[1]);

 

// sets group

$groups_attributes[$key]['group'] = $group;

 

// if position is filled

if (isset($tab_group[2]))

$position = trim($tab_group[2]);

else

$position = false;

 

if (!isset($groups[$group]))

{

$obj = new AttributeGroup();

$obj->is_color_group = false;

$obj->group_type = pSQL($type);

$obj->name[$default_language] = $group;

$obj->public_name[$default_language] = $group;

$obj->position = (!$position) ? AttributeGroup::getHigherPosition() + 1 : $position;

 

if (($field_error = $obj->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $obj->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

$obj->add();

$obj->associateTo($id_shop_list);

$groups[$group] = $obj->id;

}

else

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '');

 

// fils groups attributes

$id_attribute_group = $obj->id;

$groups_attributes[$key]['id'] = $id_attribute_group;

}

else // alreay exists

{

$id_attribute_group = $groups[$group];

$groups_attributes[$key]['id'] = $id_attribute_group;

}

}

 

// inits attribute

$id_product_attribute = 0;

$id_product_attribute_update = false;

$attributes_to_add = array();

 

// for each attribute

if(isset($info['attribute']))

foreach (explode($this->multiple_value_separator, $info['attribute']) as $key => $attribute)

{

$tab_attribute = explode(':', $attribute);

$attribute = trim($tab_attribute[0]);

// if position is filled

if (isset($tab_attribute[1]))

$position = trim($tab_attribute[1]);

else

$position = false;

 

if (isset($groups_attributes[$key]))

{

$group = $groups_attributes[$key]['group'];

if (!isset($attributes[$group.'_'.$attribute]) && count($groups_attributes[$key]) == 2)

{

$id_attribute_group = $groups_attributes[$key]['id'];

$obj = new Attribute();

// sets the proper id (corresponding to the right key)

$obj->id_attribute_group = $groups_attributes[$key]['id'];

$obj->name[$default_language] = str_replace('\n', '', str_replace('\r', '', $attribute));

$obj->position = (!$position && isset($groups[$group])) ? Attribute::getHigherPosition($groups[$group]) + 1 : $position;

 

if (($field_error = $obj->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $obj->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

$obj->add();

$obj->associateTo($id_shop_list);

$attributes[$group.'_'.$attribute] = $obj->id;

}

else

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '');

}

 

$info['minimal_quantity'] = isset($info['minimal_quantity']) && $info['minimal_quantity'] ? (int)$info['minimal_quantity'] : 1;

 

$info['wholesale_price'] = str_replace(',', '.', $info['wholesale_price']);

$info['price'] = str_replace(',', '.', $info['price']);

$info['ecotax'] = str_replace(',', '.', $info['ecotax']);

$info['weight'] = str_replace(',', '.', $info['weight']);

 

// if a reference is specified for this product, get the associate id_product_attribute to UPDATE

if (isset($info['reference']) && !empty($info['reference']))

{

$id_product_attribute = Combination::getIdByReference($product->id, strval($info['reference']));

 

// updates the attribute

if ($id_product_attribute)

{

// gets all the combinations of this product

$attribute_combinations = $product->getAttributeCombinations($default_language);

foreach ($attribute_combinations as $attribute_combination)

{

if ($id_product_attribute && in_array($id_product_attribute, $attribute_combination))

{

$product->updateAttribute(

$id_product_attribute,

(float)$info['wholesale_price'],

(float)$info['price'],

(float)$info['weight'],

0,

(float)$info['ecotax'],

$id_image,

strval($info['reference']),

strval($info['ean13']),

(int)$info['default_on'],

0,

strval($info['upc']),

(int)$info['minimal_quantity'],

0,

null,

$id_shop_list

);

 

$id_product_attribute_update = true;

}

}

}

}

 

// if no attribute reference is specified, creates a new one

if (!$id_product_attribute)

{

$id_product_attribute = $product->addCombinationEntity(

(float)$info['wholesale_price'],

(float)$info['price'],

(float)$info['weight'],

0,

(float)$info['ecotax'],

(int)$info['quantity'],

$id_image,

strval($info['reference']),

0,

strval($info['ean13']),

(int)$info['default_on'],

0,

strval($info['upc']),

(int)$info['minimal_quantity'],

$id_shop_list

);

}

 

// fills our attributes array, in order to add the attributes to the product_attribute afterwards

if(isset($attributes[$group.'_'.$attribute]))

$attributes_to_add[] = (int)$attributes[$group.'_'.$attribute];

 

// after insertion, we clean attribute position and group attribute position

$obj = new Attribute();

$obj->cleanPositions((int)$id_attribute_group, false);

AttributeGroup::cleanPositions();

}

}

 

$product->checkDefaultAttributes();

if (!$product->cache_default_attribute)

Product::updateDefaultAttribute($product->id);

if ($id_product_attribute)

{

// now adds the attributes in the attribute_combination table

if ($id_product_attribute_update)

{

Db::getInstance()->execute('

DELETE FROM '._DB_PREFIX_.'product_attribute_combination

WHERE id_product_attribute = '.(int)$id_product_attribute);

}

 

foreach ($attributes_to_add as $attribute_to_add)

{

Db::getInstance()->execute('

INSERT IGNORE INTO '._DB_PREFIX_.'product_attribute_combination (id_attribute, id_product_attribute)

VALUES ('.(int)$attribute_to_add.','.(int)$id_product_attribute.')');

}

 

StockAvailable::setQuantity($product->id, $id_product_attribute, (int)$info['quantity']);

}

}

 

$this->closeCsvFile($handle);

}

 

public function customerImport()

{

$customer_exist = false;

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

AdminImportController::setDefaultValues($info);

 

if (Tools::getValue('forceIDs') && isset($info['id']) && (int)$info['id'])

$customer = new Customer((int)$info['id']);

else

{

if (array_key_exists('id', $info) && (int)$info['id'] && Customer::customerIdExistsStatic((int)$info['id']))

$customer = new Customer((int)$info['id']);

else

$customer = new Customer();

}

 

if (array_key_exists('id', $info) && (int)$info['id'] && Customer::customerIdExistsStatic((int)$info['id']))

{

$current_id_customer = $customer->id;

$current_id_shop = $customer->id_shop;

$current_id_shop_group = $customer->id_shop_group;

$customer_exist = true;

$customer_groups = $customer->getGroups();

$addresses = $customer->getAddresses((int)Configuration::get('PS_LANG_DEFAULT'));

foreach ($customer_groups as $key => $group)

if ($group == $customer->id_default_group)

unset($customer_groups[$key]);

}

 

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $customer);

 

if ($customer->passwd)

$customer->passwd = Tools::encrypt($customer->passwd);

 

$id_shop_list = explode($this->multiple_value_separator, $customer->id_shop);

$customers_shop = array();

$customers_shop['shared'] = array();

$default_shop = new Shop((int)Configuration::get('PS_SHOP_DEFAULT'));

if (Shop::isFeatureActive() && $id_shop_list)

{

foreach ($id_shop_list as $id_shop)

{

$shop = new Shop((int)$id_shop);

$group_shop = $shop->getGroup();

if ($group_shop->share_customer)

{

if (!in_array($group_shop->id, $customers_shop['shared']))

$customers_shop['shared'][(int)$id_shop] = $group_shop->id;

}

else

$customers_shop[(int)$id_shop] = $group_shop->id;

}

}

else

{

$default_shop = new Shop((int)Configuration::get('PS_SHOP_DEFAULT'));

$default_shop->getGroup();

$customers_shop[$default_shop->id] = $default_shop->getGroup()->id;

}

 

//set temporally for validate field

$customer->id_shop = $default_shop->id;

$customer->id_shop_group = $default_shop->getGroup()->id;

 

$res = true;

if (($field_error = $customer->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $customer->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

foreach ($customers_shop as $id_shop => $id_group)

{

if ($id_shop == 'shared')

{

foreach ($id_group as $key => $id)

{

$customer->id_shop = (int)$key;

$customer->id_shop_group = (int)$id;

if ($customer_exist && ($current_id_shop_group == $id || in_array($current_id_shop, ShopGroup::getShopsFromGroup($id))))

{

$customer->id = $current_id_customer;

$res &= $customer->update();

}

 

else

{

$res &= $customer->add();

if (isset($customer_groups))

$customer->addGroups($customer_groups);

if (isset($addresses))

foreach ($addresses as $address)

{

$address['id_customer'] = $customer->id;

unset($address['country'], $address['state'], $address['state_iso'], $address['id_address'] );

Db::getInstance()->insert('address', $address);

}

}

}

}

else

{

$customer->id_shop = $id_shop;

$customer->id_shop_group = $id_group;

if ($customer_exist && $id_shop == $current_id_shop)

{

$customer->id = $current_id_customer;

$res &= $customer->update();

}

else

{

$res &= $customer->add();

if (isset($customer_groups))

$customer->addGroups($customer_groups);

if (isset($addresses))

foreach ($addresses as $address)

{

$address['id_customer'] = $customer->id;

unset($address['country'], $address['state'], $address['state_iso'], $address['id_address']);

Db::getInstance()->insert('address', $address);

}

}

}

}

}

$customer_exist = false;

if (!$res)

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$info['email'],

(isset($info['id']) ? $info['id'] : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

$this->closeCsvFile($handle);

}

 

public function addressImport()

{

$this->receiveTab();

$default_language_id = (int)Configuration::get('PS_LANG_DEFAULT');

$handle = $this->openCsvFile();

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

AdminImportController::setDefaultValues($info);

$address = new Address();

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $address);

 

if (isset($address->country) && is_numeric($address->country))

{

if (Country::getNameById(Configuration::get('PS_LANG_DEFAULT'), (int)$address->country))

$address->id_country = (int)$address->country;

}

else if (isset($address->country) && is_string($address->country) && !empty($address->country))

{

if ($id_country = Country::getIdByName(null, $address->country))

$address->id_country = (int)$id_country;

else

{

$country = new Country();

$country->active = 1;

$country->name = AdminImportController::createMultiLangField($address->country);

$country->id_zone = 0; // Default zone for country to create

$country->iso_code = strtoupper(substr($address->country, 0, 2)); // Default iso for country to create

$country->contains_states = 0; // Default value for country to create

$lang_field_error = $country->validateFieldsLang(UNFRIENDLY_ERROR, true);

if (($field_error = $country->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $country->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $country->add())

$address->id_country = (int)$country->id;

else

{

$this->errors[] = sprintf(Tools::displayError('%s cannot be saved'), $country->name[$default_language_id]);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

 

if (isset($address->state) && is_numeric($address->state))

{

if (State::getNameById((int)$address->state))

$address->id_state = (int)$address->state;

}

else if (isset($address->state) && is_string($address->state) && !empty($address->state))

{

if ($id_state = State::getIdByName($address->state))

$address->id_state = (int)$id_state;

else

{

$state = new State();

$state->active = 1;

$state->name = $address->state;

$state->id_country = isset($country->id) ? (int)$country->id : 0;

$state->id_zone = 0; // Default zone for state to create

$state->iso_code = strtoupper(substr($address->state, 0, 2)); // Default iso for state to create

$state->tax_behavior = 0;

if (($field_error = $state->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $state->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $state->add())

$address->id_state = (int)$state->id;

else

{

$this->errors[] = sprintf(Tools::displayError('%s cannot be saved'), $state->name);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

 

if (isset($address->customer_email) && !empty($address->customer_email))

{

if (Validate::isEmail($address->customer_email))

{

// a customer could exists in different shop

$customer_list = Customer::getCustomersByEmail($address->customer_email);

 

if (count($customer_list) == 0)

$this->errors[] = sprintf(

Tools::displayError('%1$s does not exist in database %2$s (ID: %3$s) cannot be saved'),

Db::getInstance()->getMsgError(),

$address->customer_email,

(isset($info['id']) ? $info['id'] : 'null')

);

}

else

{

$this->errors[] = sprintf(Tools::displayError('"%s": Is not a valid e-mail address'), $address->customer_email);

continue;

}

}

elseif (isset($address->id_customer) && !empty($address->id_customer))

{

if (Customer::customerIdExistsStatic((int)$address->id_customer))

{

$customer = new Customer((int)$address->id_customer);

 

// a customer could exists in different shop

$customer_list = Customer::getCustomersByEmail($customer->email);

 

if (count($customer_list) == 0)

$this->errors[] = sprintf(

Tools::displayError('%1$s does not exist in database %2$s (ID: %3$s) cannot be saved'),

Db::getInstance()->getMsgError(),

$customer->email,

(int)$address->customer_id

);

}

else

$this->errors[] = sprintf(Tools::displayError('The customer ID n.%d does not exist in database (ID: %d) cannot be saved'), $address->customer_id);

}

else

{

$customer_list = array();

$address->id_customer = 0;

}

 

if (isset($address->manufacturer) && is_numeric($address->manufacturer) && Manufacturer::manufacturerExists((int)$address->manufacturer))

$address->id_manufacturer = (int)$address->manufacturer;

else if (isset($address->manufacturer) && is_string($address->manufacturer) && !empty($address->manufacturer))

{

$manufacturer = new Manufacturer();

$manufacturer->name = $address->manufacturer;

if (($field_error = $manufacturer->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $manufacturer->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $manufacturer->add())

$address->id_manufacturer = (int)$manufacturer->id;

else

{

$this->errors[] = Db::getInstance()->getMsgError().' '.sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$manufacturer->name,

(isset($manufacturer->id) ? $manufacturer->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

 

if (isset($address->supplier) && is_numeric($address->supplier) && Supplier::supplierExists((int)$address->supplier))

$address->id_supplier = (int)$address->supplier;

else if (isset($address->supplier) && is_string($address->supplier) && !empty($address->supplier))

{

$supplier = new Supplier();

$supplier->name = $address->supplier;

if (($field_error = $supplier->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $supplier->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $supplier->add())

$address->id_supplier = (int)$supplier->id;

else

{

$this->errors[] = Db::getInstance()->getMsgError().' '.sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$supplier->name,

(isset($supplier->id) ? $supplier->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

 

$res = false;

if (($field_error = $address->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $address->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

if (isset($customer_list) && count($customer_list) > 0)

{

$filter_list = array();

foreach ($customer_list as $customer)

{

if (in_array($customer['id_customer'], $filter_list))

continue;

 

$filter_list[] = $customer['id_customer'];

 

unset($address->id);

$address->id_customer = $customer['id_customer'];

$res = $address->add();

 

if (!$res)

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$info['alias'],

(isset($info['id']) ? $info['id'] : 'null')

);

}

}

else

{

if ($address->id && $address->addressExists($address->id))

$res = $address->update();

if (!$res)

$res = $address->add();

}

}

if (!$res)

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$info['alias'],

(isset($info['id']) ? $info['id'] : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

$this->closeCsvFile($handle);

}

 

public function manufacturerImport()

{

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

AdminImportController::setDefaultValues($info);

 

if (Tools::getValue('forceIDs') && isset($info['id']) && (int)$info['id'])

$manufacturer = new Manufacturer((int)$info['id']);

else

{

if (array_key_exists('id', $info) && (int)$info['id'] && Manufacturer::existsInDatabase((int)$info['id'], 'manufacturer'))

$manufacturer = new Manufacturer((int)$info['id']);

else

$manufacturer = new Manufacturer();

}

 

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $manufacturer);

 

$res = false;

if (($field_error = $manufacturer->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $manufacturer->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

if ($manufacturer->id && $manufacturer->manufacturerExists($manufacturer->id))

$res = $manufacturer->update();

if (!$res)

$res = $manufacturer->add();

 

if ($res)

{

// Associate supplier to group shop

if (Shop::isFeatureActive() && $manufacturer->shop)

{

Db::getInstance()->execute('

DELETE FROM '._DB_PREFIX_.'manufacturer_shop

WHERE id_manufacturer = '.(int)$manufacturer->id

);

$manufacturer->shop = explode($this->multiple_value_separator, $manufacturer->shop);

$shops = array();

foreach ($manufacturer->shop as $shop)

{

$shop = trim($shop);

if (!is_numeric($shop))

$shop = ShopGroup::getIdByName($shop);

$shops[] = $shop;

}

$manufacturer->associateTo($shops);

}

}

}

 

if (!$res)

{

$this->errors[] = Db::getInstance()->getMsgError().' '.sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

(isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'),

(isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID')

);

$this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

$this->closeCsvFile($handle);

}

 

public function supplierImport()

{

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

AdminImportController::setDefaultValues($info);

 

if (Tools::getValue('forceIDs') && isset($info['id']) && (int)$info['id'])

$supplier = new Supplier((int)$info['id']);

else

{

if (array_key_exists('id', $info) && (int)$info['id'] && Supplier::existsInDatabase((int)$info['id'], 'supplier'))

$supplier = new Supplier((int)$info['id']);

else

$supplier = new Supplier();

}

 

 

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $supplier);

if (($field_error = $supplier->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $supplier->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

$res = false;

if ($supplier->id && $supplier->supplierExists($supplier->id))

$res = $supplier->update();

if (!$res)

$res = $supplier->add();

 

if (!$res)

$this->errors[] = Db::getInstance()->getMsgError().' '.sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

(isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'),

(isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID')

);

else

{

// Associate supplier to group shop

if (Shop::isFeatureActive() && $supplier->shop)

{

Db::getInstance()->execute('

DELETE FROM '._DB_PREFIX_.'supplier_shop

WHERE id_supplier = '.(int)$supplier->id

);

$supplier->shop = explode($this->multiple_value_separator, $supplier->shop);

$shops = array();

foreach ($supplier->shop as $shop)

{

$shop = trim($shop);

if (!is_numeric($shop))

$shop = ShopGroup::getIdByName($shop);

$shops[] = $shop;

}

$supplier->associateTo($shops);

}

}

}

else

{

$this->errors[] = $this->l('Supplier is invalid').' ('.$supplier->name.')';

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '');

}

}

$this->closeCsvFile($handle);

}

 

/**

* @since 1.5.0

*/

public function supplyOrdersImport()

{

// opens CSV & sets locale

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

 

// main loop, for each supply orders to import

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); ++$current_line)

{

// if convert requested

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

// sets default values if needed

AdminImportController::setDefaultValues($info);

 

// if an id is set, instanciates a supply order with this id if possible

if (array_key_exists('id', $info) && (int)$info['id'] && SupplyOrder::exists((int)$info['id']))

$supply_order = new SupplyOrder((int)$info['id']);

// if a reference is set, instanciates a supply order with this reference if possible

else if (array_key_exists('reference', $info) && $info['reference'] && SupplyOrder::exists(pSQL($info['reference'])))

$supply_order = SupplyOrder::getSupplyOrderByReference(pSQL($info['reference']));

else // new supply order

$supply_order = new SupplyOrder();

 

// gets parameters

$id_supplier = (int)$info['id_supplier'];

$id_lang = (int)$info['id_lang'];

$id_warehouse = (int)$info['id_warehouse'];

$id_currency = (int)$info['id_currency'];

$reference = pSQL($info['reference']);

$date_delivery_expected = pSQL($info['date_delivery_expected']);

$discount_rate = (float)$info['discount_rate'];

$is_template = (bool)$info['is_template'];

 

// checks parameters

if (!Supplier::supplierExists($id_supplier))

$this->errors[] = sprintf($this->l('Supplier ID (%d) is not valid (at line %d).'), $id_supplier, $current_line + 1);

if (!Language::getLanguage($id_lang))

$this->errors[] = sprintf($this->l('Lang ID (%d) is not valid (at line %d).'), $id_lang, $current_line + 1);

if (!Warehouse::exists($id_warehouse))

$this->errors[] = sprintf($this->l('Warehouse ID (%d) is not valid (at line %d).'), $id_warehouse, $current_line + 1);

if (!Currency::getCurrency($id_currency))

$this->errors[] = sprintf($this->l('Currency ID (%d) is not valid (at line %d).'), $id_currency, $current_line + 1);

if (empty($supply_order->reference) && SupplyOrder::exists($reference))

$this->errors[] = sprintf($this->l('Reference (%s) already exists (at line %d).'), $reference, $current_line + 1);

if (!empty($supply_order->reference) && ($supply_order->reference != $reference && SupplyOrder::exists($reference)))

$this->errors[] = sprintf($this->l('Reference (%s) already exists (at line %d).'), $reference, $current_line + 1);

if (!Validate::isDateFormat($date_delivery_expected))

$this->errors[] = sprintf($this->l('Date (%s) is not valid (at line %d). Format: %s.'), $date_delivery_expected,

$current_line + 1, $this->l('YYYY-MM-DD'));

else if (new DateTime($date_delivery_expected) <= new DateTime('yesterday'))

$this->errors[] = sprintf($this->l('Date (%s) cannot be in the past (at line %d). Format: %s.'), $date_delivery_expected,

$current_line + 1, $this->l('YYYY-MM-DD'));

if ($discount_rate < 0 || $discount_rate > 100)

$this->errors[] = sprintf($this->l('Discount rate (%d) is not valid (at line %d). %s.'), $discount_rate,

$current_line + 1, $this->l('Format: between 0 and 100'));

if ($supply_order->id > 0 && !$supply_order->isEditable())

$this->errors[] = sprintf($this->l('Supply Order (%d) is not editable (at line %d).'), $supply_order->id, $current_line + 1);

 

// if no errors, sets supply order

if (empty($this->errors))

{

// adds parameters

$info['id_ref_currency'] = (int)Currency::getDefaultCurrency()->id;

$info['supplier_name'] = pSQL(Supplier::getNameById($id_supplier));

if ($supply_order->id > 0)

{

$info['id_supply_order_state'] = (int)$supply_order->id_supply_order_state;

$info['id'] = (int)$supply_order->id;

}

else

$info['id_supply_order_state'] = 1;

 

// sets parameters

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $supply_order);

 

// updatesd($supply_order);

$res = true;

if ($supply_order->id > 0)

$res &= $supply_order->update();

else

$res &= $supply_order->add();

 

// errors

if (!$res)

$this->errors[] = sprintf($this->l('Supply Order could not be saved (at line %d).'), $current_line + 1);

}

}

 

// closes

$this->closeCsvFile($handle);

}

 

public function supplyOrdersDetailsImport()

{

// opens CSV & sets locale

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

 

$products = array();

$reset = true;

// main loop, for each supply orders details to import

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); ++$current_line)

{

// if convert requested

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

// sets default values if needed

AdminImportController::setDefaultValues($info);

 

// gets the supply order

if (array_key_exists('supply_order_reference', $info) && pSQL($info['supply_order_reference']) && SupplyOrder::exists(pSQL($info['supply_order_reference'])))

$supply_order = SupplyOrder::getSupplyOrderByReference(pSQL($info['supply_order_reference']));

else

$this->errors[] = sprintf($this->l('Supply Order (%s) could not be loaded (at line %d).'), (int)$info['supply_order_reference'], $current_line + 1);

 

if (empty($this->errors))

{

// sets parameters

$id_product = (int)$info['id_product'];

if (!$info['id_product_attribute'])

$info['id_product_attribute'] = 0;

$id_product_attribute = (int)$info['id_product_attribute'];

$unit_price_te = (float)$info['unit_price_te'];

$quantity_expected = (int)$info['quantity_expected'];

$discount_rate = (float)$info['discount_rate'];

$tax_rate = (float)$info['tax_rate'];

 

// checks if one product is there only once

if (isset($product['id_product']))

{

if ($product['id_product'] == $id_product_attribute)

$this->errors[] = sprintf($this->l('Product (%d/%D) cannot be added twice (at line %d).'), $id_product,

$id_product_attribute, $current_line + 1);

else

$product['id_product'] = $id_product_attribute;

}

else

$product['id_product'] = 0;

 

// checks parameters

if (false === ($supplier_reference = ProductSupplier::getProductSupplierReference($id_product, $id_product_attribute, $supply_order->id_supplier)))

$this->errors[] = sprintf($this->l('Product (%d/%d) is not available for this order (at line %d).'), $id_product,

$id_product_attribute, $current_line + 1);

if ($unit_price_te < 0)

$this->errors[] = sprintf($this->l('Unit Price (tax excl.) (%d) is not valid (at line %d).'), $unit_price_te, $current_line + 1);

if ($quantity_expected < 0)

$this->errors[] = sprintf($this->l('Quantity Expected (%d) is not valid (at line %d).'), $quantity_expected, $current_line + 1);

if ($discount_rate < 0 || $discount_rate > 100)

$this->errors[] = sprintf($this->l('Discount rate (%d) is not valid (at line %d). %s.'), $discount_rate,

$current_line + 1, $this->l('Format: between 0 and 100'));

if ($tax_rate < 0 || $tax_rate > 100)

$this->errors[] = sprintf($this->l('Quantity Expected (%d) is not valid (at line %d).'), $tax_rate,

$current_line + 1, $this->l('Format: between 0 and 100'));

 

// if no errors, sets supply order details

if (empty($this->errors))

{

// resets order if needed

if ($reset)

{

$supply_order->resetProducts();

$reset = false;

}

 

// creates new product

$supply_order_detail = new SupplyOrderDetail();

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $supply_order_detail);

 

// sets parameters

$supply_order_detail->id_supply_order = $supply_order->id;

$currency = new Currency($supply_order->id_ref_currency);

$supply_order_detail->id_currency = $currency->id;

$supply_order_detail->exchange_rate = $currency->conversion_rate;

$supply_order_detail->supplier_reference = $supplier_reference;

$supply_order_detail->name = Product::getProductName($id_product, $id_product_attribute, $supply_order->id_lang);

 

// gets ean13 / ref / upc

$query = new DbQuery();

$query->select('

IFNULL(pa.reference, IFNULL(p.reference, \'\')) as reference,

IFNULL(pa.ean13, IFNULL(p.ean13, \'\')) as ean13,

IFNULL(pa.upc, IFNULL(p.upc, \'\')) as upc

');

$query->from('product', 'p');

$query->leftJoin('product_attribute', 'pa', 'pa.id_product = p.id_product AND id_product_attribute = '.(int)$id_product_attribute);

$query->where('p.id_product = '.(int)$id_product);

$query->where('p.is_virtual = 0 AND p.cache_is_pack = 0');

$res = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query);

$product_infos = $res['0'];

 

$supply_order_detail->reference = $product_infos['reference'];

$supply_order_detail->ean13 = $product_infos['ean13'];

$supply_order_detail->upc = $product_infos['upc'];

 

$supply_order_detail->add();

$supply_order->update();

unset($supply_order_detail);

 

}

}

}

 

// closes

$this->closeCsvFile($handle);

}

 

public function utf8EncodeArray($array)

{

if (is_array($array))

foreach ($array as $key => $value)

$array[$key] = utf8_encode($value);

else

$array = utf8_encode($array);

 

return $array;

}

 

protected function getNbrColumn($handle, $glue)

{

$tmp = fgetcsv($handle, MAX_LINE_SIZE, $glue);

AdminImportController::rewindBomAware($handle);

return count($tmp);

}

 

protected static function usortFiles($a, $B)

{

$a = strrev(substr(strrev($a), 0, 14));

$b = strrev(substr(strrev($B), 0, 14));

 

if ($a == $B)

return 0;

 

return ($a < $B) ? 1 : -1;

}

 

protected function openCsvFile()

{

$handle = fopen(_PS_ADMIN_DIR_.'/import/'.strval(preg_replace('/\.{2,}/', '.', Tools::getValue('csv'))), 'r');

 

if (!$handle)

$this->errors[] = Tools::displayError('Cannot read the .CSV file');

 

AdminImportController::rewindBomAware($handle);

 

for ($i = 0; $i < (int)Tools::getValue('skip'); ++$i)

$line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator);

return $handle;

}

 

protected function closeCsvFile($handle)

{

fclose($handle);

}

 

protected function truncateTables($case)

{

switch ((int)$case)

{

case $this->entities[$this->l('Categories:')]:

Db::getInstance()->execute('

DELETE FROM `'._DB_PREFIX_.'category`

WHERE id_category NOT IN ('.(int)Configuration::get('PS_HOME_CATEGORY').

', '.(int)Configuration::get('PS_ROOT_CATEGORY').')');

Db::getInstance()->execute('

DELETE FROM `'._DB_PREFIX_.'category_lang`

WHERE id_category NOT IN ('.(int)Configuration::get('PS_HOME_CATEGORY').

', '.(int)Configuration::get('PS_ROOT_CATEGORY').')');

Db::getInstance()->execute('

DELETE FROM `'._DB_PREFIX_.'category_shop`

WHERE `id_category` NOT IN ('.(int)Configuration::get('PS_HOME_CATEGORY').

', '.(int)Configuration::get('PS_ROOT_CATEGORY').')');

Db::getInstance()->execute('ALTER TABLE `'._DB_PREFIX_.'category` AUTO_INCREMENT = 3');

foreach (scandir(_PS_CAT_IMG_DIR_) as $d)

if (preg_match('/^[0-9]+(\-(.*))?\.jpg$/', $d))

unlink(_PS_CAT_IMG_DIR_.$d);

break;

case $this->entities[$this->l('Products:')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_shop');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'feature_product');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_lang');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'category_product');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_tag');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'image');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'image_lang');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'image_shop');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'specific_price');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'specific_price_priority');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_carrier');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'cart_product');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'compare_product');

if (count(Db::getInstance()->executeS('SHOW TABLES LIKE \''._DB_PREFIX_.'favorite_product\' '))) //check if table exist

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'favorite_product');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attachment');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_country_tax');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_download');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_group_reduction_cache');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_sale');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_supplier');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'scene_products');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'warehouse_product_location');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'stock');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'stock_available');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'stock_mvt');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'customization');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'customization_field');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'supply_order_detail');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_impact');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_shop`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_combination`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_image`');

Image::deleteAllImages(_PS_PROD_IMG_DIR_);

if (!file_exists(_PS_PROD_IMG_DIR_))

mkdir(_PS_PROD_IMG_DIR_);

break;

case $this->entities[$this->l('Combinations')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_impact');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_lang`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_group`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_group_lang`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_group_shop`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_shop`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_shop`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_combination`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_image`');

Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'stock_available` WHERE id_product_attribute !=0');

break;

case $this->entities[$this->l('Customers')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'customer');

break;

case $this->entities[$this->l('Addresses')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'address');

break;

case $this->entities[$this->l('Manufacturers:')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'manufacturer');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'manufacturer_lang');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'manufacturer_shop');

foreach (scandir(_PS_MANU_IMG_DIR_) as $d)

if (preg_match('/^[0-9]+(\-(.*))?\.jpg$/', $d))

unlink(_PS_MANU_IMG_DIR_.$d);

break;

case $this->entities[$this->l('Suppliers:')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'supplier');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'supplier_lang');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'supplier_shop');

foreach (scandir(_PS_SUPP_IMG_DIR_) as $d)

if (preg_match('/^[0-9]+(\-(.*))?\.jpg$/', $d))

unlink(_PS_SUPP_IMG_DIR_.$d);

break;

}

Image::clearTmpDir();

return true;

}

 

public function postProcess()

{

/* PrestaShop demo mode */

if (_PS_MODE_DEMO_)

{

$this->errors[] = Tools::displayError('This functionality has been disabled.');

return;

}

/* PrestaShop demo mode*/

 

if (Tools::isSubmit('submitFileUpload'))

{

if (isset($_FILES['file']) && !empty($_FILES['file']['error']))

{

switch ($_FILES['file']['error'])

{

case UPLOAD_ERR_INI_SIZE:

$this->errors[] = Tools::displayError('The uploaded file exceeds the upload_max_filesize directive in php.ini. If your server configuration allows it, you may add a directive in your .htaccess.');

break;

case UPLOAD_ERR_FORM_SIZE:

$this->errors[] = Tools::displayError('The uploaded file exceeds the post_max_size directive in php.ini.

If your server configuration allows it, you may add a directive in your .htaccess, for example:')

.'<br/><a href="'.$this->context->link->getAdminLink('AdminMeta').'" >

<code>php_value post_max_size 20M</code> '.

Tools::displayError('(click to open "Generators" page)').'</a>';

break;

break;

case UPLOAD_ERR_PARTIAL:

$this->errors[] = Tools::displayError('The uploaded file was only partially uploaded.');

break;

break;

case UPLOAD_ERR_NO_FILE:

$this->errors[] = Tools::displayError('No file was uploaded');

break;

break;

}

}

else if (!file_exists($_FILES['file']['tmp_name']) ||

!@move_uploaded_file($_FILES['file']['tmp_name'], _PS_ADMIN_DIR_.'/import/'.date('Ymdhis').'-'.$_FILES['file']['name']))

$this->errors[] = $this->l('an error occurred while uploading and copying file');

else

Tools::redirectAdmin(self::$currentIndex.'&token='.Tools::getValue('token').'&conf=18');

}

else if (Tools::getValue('import'))

{

// Check if the CSV file exist

if (Tools::getValue('csv'))

{

// If i am a superadmin, i can truncate table

if (((Shop::isFeatureActive() && $this->context->employee->isSuperAdmin()) || !Shop::isFeatureActive()) && Tools::getValue('truncate'))

$this->truncateTables((int)Tools::getValue('entity'));

 

switch ((int)Tools::getValue('entity'))

{

case $this->entities[$this->l('Categories:')]:

$this->categoryImport();

break;

case $this->entities[$this->l('Products:')]:

$this->productImport();

break;

case $this->entities[$this->l('Customers')]:

$this->customerImport();

break;

case $this->entities[$this->l('Addresses')]:

$this->addressImport();

break;

case $this->entities[$this->l('Combinations')]:

$this->attributeImport();

break;

case $this->entities[$this->l('Manufacturers:')]:

$this->manufacturerImport();

break;

case $this->entities[$this->l('Suppliers:')]:

$this->supplierImport();

break;

// @since 1.5.0

case $this->entities[$this->l('SupplyOrders')]:

if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))

$this->supplyOrdersImport();

break;

// @since 1.5.0

case $this->entities[$this->l('SupplyOrdersDetails')]:

if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))

$this->supplyOrdersDetailsImport();

break;

default:

$this->errors[] = $this->l('Please select what you would like to import');

}

}

else

$this->errors[] = $this->l('You must upload a file for go to the next step');

}

 

parent::postProcess();

}

 

public static function setLocale()

{

$iso_lang = trim(Tools::getValue('iso_lang'));

setlocale(LC_COLLATE, strtolower($iso_lang).'_'.strtoupper($iso_lang).'.UTF-8');

setlocale(LC_CTYPE, strtolower($iso_lang).'_'.strtoupper($iso_lang).'.UTF-8');

}

 

protected function addProductWarning($product_name, $product_id = null, $message = '')

{

$this->warnings[] = $product_name.(isset($product_id) ? ' (ID '.$product_id.')' : '').' '.Tools::displayError($message);

}

 

public function ajaxProcessSaveImportMatchs()

{

if ($this->tabAccess['edit'] === '1')

{

$match = implode('|', Tools::getValue('type_value'));

Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'import_match` (

`id_import_match` ,

`name` ,

`match`,

`skip`

)

VALUES (

NULL ,

\''.pSQL(Tools::getValue('newImportMatchs')).'\',

\''.pSQL($match).'\',

\''.pSQL(Tools::getValue('skip')).'\'

)');

 

die('{"id" : "'.Db::getInstance()->Insert_ID().'"}');

}

}

 

public function ajaxProcessLoadImportMatchs()

{

if ($this->tabAccess['edit'] === '1')

{

$return = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'import_match` WHERE `id_import_match` = '.(int)Tools::getValue('idImportMatchs'));

die('{"id" : "'.$return[0]['id_import_match'].'", "matchs" : "'.$return[0]['match'].'", "skip" : "'.$return[0]['skip'].'"}');

}

}

 

public function ajaxProcessDeleteImportMatchs()

{

if ($this->tabAccess['edit'] === '1')

{

Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'import_match` WHERE `id_import_match` = '.(int)Tools::getValue('idImportMatchs'));

die;

}

}

}

Link to comment
Share on other sites

Eso ya esta comentado aqui: https://github.com/P...0e3ebe473233d07 y en miles de post del foro.

 

Gracias de todos modos.

 

Sí, está explicado en muchos foros, pero quería hacer un poco de incapié en el tema de las imagenes, que me volví loco hasta averiguar que había que subirlas a un servidor.

 

Ya que aclaraba lo de las imágenes, puse el proceso completo, para que no hubiera ninguna duda :)

 

Un saludo

Link to comment
Share on other sites

Yo en esos dias he utilizado el enlace que menciona Rubalcaba, y efectivamente es algo ya muy mencionado. Se trata de un bug de esta version y aplicado lo de ese enlace se soluciona. Lo de las imagenes hice lo mismo que Fco y tambien sin problemas. Ten en cuenta que si tienes una instalacion limpia de esta version, el parche debes realizarlo ANTES de intentar importar cualquier producto.

Por mi parte no se como mas poder ayudar, ya que no tengo experiencia en ninguna otra version diferente a la 3.5.1 y he instalado a forma de prueba unas 6 tiendas y en todas he seguido el mismo procedimiento y me ha funcionado.

 

Por si te sirve... te dejo las lineas del fichero que yo tengo colocado en mi tienda. Aviso, he realizado muchos otros cambios pero creo, no estoy 100% seguro, en este file solo he modicado lo mencionado en el enlace que posteo Rubalcaba.

No se como adjuntarlo, por eso lo copio, lo siento.

 

Path: controllers/admin

File: AdminImportController.php

 

Suerte y comentanos que tal te ha ido

 

<?php

/*

* 2007-2013 PrestaShop

*

* 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.or...ses/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 [email protected] so we can send you a copy immediately.

*

* DISCLAIMER

*

* Do not edit or add to this file if you wish to upgrade PrestaShop to newer

* versions in the future. If you wish to customize PrestaShop for your

* needs please refer to http://www.prestashop.com for more information.

*

* @author PrestaShop SA <[email protected]>

* @copyright 2007-2013 PrestaShop SA

* @license http://opensource.or...ses/osl-3.0.php Open Software License (OSL 3.0)

* International Registered Trademark & Property of PrestaShop SA

*/

 

@ini_set('max_execution_time', 0);

/** No max line limit since the lines can be more than 4096. Performance impact is not significant. */

define('MAX_LINE_SIZE', 0);

 

/** Used for validatefields diying without user friendly error or not */

define('UNFRIENDLY_ERROR', false);

 

/** this value set the number of columns visible on each page */

define('MAX_COLUMNS', 6);

 

/** correct Mac error on eof */

@ini_set('auto_detect_line_endings', '1');

 

class AdminImportControllerCore extends AdminController

{

public static $column_mask;

 

public $entities = array();

 

public $available_fields = array();

 

public $required_fields = array('name');

 

public $cache_image_deleted = array();

 

public static $default_values = array();

 

public static $validators = array(

'active' => array('AdminImportController', 'getBoolean'),

'tax_rate' => array('AdminImportController', 'getPrice'),

/** Tax excluded */

'price_tex' => array('AdminImportController', 'getPrice'),

/** Tax included */

'price_tin' => array('AdminImportController', 'getPrice'),

'reduction_price' => array('AdminImportController', 'getPrice'),

'reduction_percent' => array('AdminImportController', 'getPrice'),

'wholesale_price' => array('AdminImportController', 'getPrice'),

'ecotax' => array('AdminImportController', 'getPrice'),

'name' => array('AdminImportController', 'createMultiLangField'),

'description' => array('AdminImportController', 'createMultiLangField'),

'description_short' => array('AdminImportController', 'createMultiLangField'),

'meta_title' => array('AdminImportController', 'createMultiLangField'),

'meta_keywords' => array('AdminImportController', 'createMultiLangField'),

'meta_description' => array('AdminImportController', 'createMultiLangField'),

'link_rewrite' => array('AdminImportController', 'createMultiLangField'),

'available_now' => array('AdminImportController', 'createMultiLangField'),

'available_later' => array('AdminImportController', 'createMultiLangField'),

'category' => array('AdminImportController', 'split'),

'online_only' => array('AdminImportController', 'getBoolean')

);

 

public $separator;

public $multiple_value_separator;

 

public function __construct()

{

$this->entities = array(

$this->l('Categories:'),

$this->l('Products:'),

$this->l('Combinations'),

$this->l('Customers'),

$this->l('Addresses'),

$this->l('Manufacturers:'),

$this->l('Suppliers:'),

);

 

// @since 1.5.0

if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))

{

$this->entities = array_merge(

$this->entities,

array(

$this->l('SupplyOrders'),

$this->l('SupplyOrdersDetails'),

)

);

}

 

$this->entities = array_flip($this->entities);

 

switch ((int)Tools::getValue('entity'))

{

case $this->entities[$this->l('Combinations')]:

$this->required_fields = array(

'id_product',

'group',

'attribute'

);

 

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id_product' => array('label' => $this->l('Product ID').'*'),

'group' => array(

'label' => $this->l('Attribute (Name:Type:Position)').'*'

),

'attribute' => array(

'label' => $this->l('Value (Value:Position)').'*'

),

'supplier_reference' => array('label' => $this->l('Supplier reference')),

'reference' => array('label' => $this->l('Reference')),

'ean13' => array('label' => $this->l('EAN13')),

'upc' => array('label' => $this->l('UPC')),

'wholesale_price' => array('label' => $this->l('Wholesale price')),

'price' => array('label' => $this->l('Impact on price')),

'ecotax' => array('label' => $this->l('Ecotax')),

'quantity' => array('label' => $this->l('Quantity')),

'minimal_quantity' => array('label' => $this->l('Minimal quantity')),

'weight' => array('label' => $this->l('Impact on weight')),

'default_on' => array('label' => $this->l('Default (0 = No, 1 = Yes)')),

'image_position' => array(

'label' => $this->l('Image position')

),

'image_url' => array('label' => $this->l('Image URL')),

'delete_existing_images' => array(

'label' => $this->l('Delete existing images (0 = No, 1 = Yes)')

),

'shop' => array(

'label' => $this->l('ID / Name of shop'),

'help' => $this->l('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.'),

)

);

 

self::$default_values = array(

'reference' => '',

'supplier_reference' => '',

'ean13' => '',

'upc' => '',

'wholesale_price' => 0,

'price' => 0,

'ecotax' => 0,

'quantity' => 0,

'minimal_quantity' => 1,

'weight' => 0,

'default_on' => 0,

);

break;

 

case $this->entities[$this->l('Categories:')]:

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'active' => array('label' => $this->l('Active (0/1)')),

'name' => array('label' => $this->l('Name *')),

'parent' => array('label' => $this->l('Parent category')),

'is_root_category' => array(

'label' => $this->l('Root category (0/1)'),

'help' => $this->l('A category root is where a category tree can begin. This is used with multistore.')

),

'description' => array('label' => $this->l('Description')),

'meta_title' => array('label' => $this->l('Meta-title')),

'meta_keywords' => array('label' => $this->l('Meta-keywords')),

'meta_description' => array('label' => $this->l('Meta-description')),

'link_rewrite' => array('label' => $this->l('URL rewritten')),

'image' => array('label' => $this->l('Image URL')),

'shop' => array(

'label' => $this->l('ID / Name of shop'),

'help' => $this->l('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.'),

),

);

 

self::$default_values = array(

'active' => '1',

'parent' => Configuration::get('PS_HOME_CATEGORY'),

'link_rewrite' => ''

);

break;

 

case $this->entities[$this->l('Products:')]:

self::$validators['image'] = array(

'AdminImportController',

'split'

);

 

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'active' => array('label' => $this->l('Active (0/1)')),

'name' => array('label' => $this->l('Name *')),

'category' => array('label' => $this->l('Categories (x,y,z...)')),

'price_tex' => array('label' => $this->l('Price tax excluded')),

'price_tin' => array('label' => $this->l('Price tax included')),

'id_tax_rules_group' => array('label' => $this->l('Tax rules ID')),

'wholesale_price' => array('label' => $this->l('Wholesale price')),

'on_sale' => array('label' => $this->l('On sale (0/1)')),

'reduction_price' => array('label' => $this->l('Discount amount')),

'reduction_percent' => array('label' => $this->l('Discount percent')),

'reduction_from' => array('label' => $this->l('Discount from (yyyy-mm-dd)')),

'reduction_to' => array('label' => $this->l('Discount to (yyyy-mm-dd)')),

'reference' => array('label' => $this->l('Reference #')),

'supplier_reference' => array('label' => $this->l('Supplier reference #')),

'supplier' => array('label' => $this->l('Supplier')),

'manufacturer' => array('label' => $this->l('Manufacturer')),

'ean13' => array('label' => $this->l('EAN13')),

'upc' => array('label' => $this->l('UPC')),

'ecotax' => array('label' => $this->l('Ecotax')),

'weight' => array('label' => $this->l('Weight')),

'quantity' => array('label' => $this->l('Quantity')),

'description_short' => array('label' => $this->l('Short description')),

'description' => array('label' => $this->l('Description')),

'tags' => array('label' => $this->l('Tags (x,y,z...)')),

'meta_title' => array('label' => $this->l('Meta-title')),

'meta_keywords' => array('label' => $this->l('Meta-keywords')),

'meta_description' => array('label' => $this->l('Meta-description')),

'link_rewrite' => array('label' => $this->l('URL rewritten')),

'available_now' => array('label' => $this->l('Text when in stock')),

'available_later' => array('label' => $this->l('Text when backorder allowed')),

'available_for_order' => array('label' => $this->l('Available for order (0 = No, 1 = Yes)')),

'date_add' => array('label' => $this->l('Product creation date')),

'show_price' => array('label' => $this->l('Show price (0 = No, 1 = Yes)')),

'image' => array('label' => $this->l('Image URLs (x,y,z...)')),

'delete_existing_images' => array(

'label' => $this->l('Delete existing images (0 = No, 1 = Yes)')

),

'features' => array('label' => $this->l('Feature(Name:Value:Position)')),

'online_only' => array('label' => $this->l('Available online only (0 = No, 1 = Yes)')),

'condition' => array('label' => $this->l('Condition')),

'shop' => array(

'label' => $this->l('ID / Name of shop'),

'help' => $this->l('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.'),

)

);

 

self::$default_values = array(

'id_category' => array((int)Configuration::get('PS_HOME_CATEGORY')),

'id_category_default' => (int)Configuration::get('PS_HOME_CATEGORY'),

'active' => '1',

'quantity' => 0,

'price' => 0,

'id_tax_rules_group' => 0,

'description_short' => array((int)Configuration::get('PS_LANG_DEFAULT') => ''),

'link_rewrite' => array((int)Configuration::get('PS_LANG_DEFAULT') => ''),

'online_only' => 0,

'condition' => 'new',

'date_add' => date('Y-m-d H:i:s'),

'condition' => 'new',

);

break;

 

case $this->entities[$this->l('Customers')]:

//Overwrite required_fields AS only email is required whereas other entities

$this->required_fields = array('email', 'passwd', 'lastname', 'firstname');

 

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'active' => array('label' => $this->l('Active (0/1)')),

'id_gender' => array('label' => $this->l('Titles ID (Mr = 1, Ms = 2, else 0)')),

'email' => array('label' => $this->l('Email *')),

'passwd' => array('label' => $this->l('Password *')),

'birthday' => array('label' => $this->l('Birthday (yyyy-mm-dd)')),

'lastname' => array('label' => $this->l('Last Name *')),

'firstname' => array('label' => $this->l('First Name *')),

'newsletter' => array('label' => $this->l('Newsletter (0/1)')),

'optin' => array('label' => $this->l('Opt-in (0/1)')),

'id_shop' => array(

'label' => $this->l('ID / Name of shop'),

'help' => $this->l('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.'),

),

);

 

self::$default_values = array(

'active' => '1',

'id_shop' => Configuration::get('PS_SHOP_DEFAULT'),

);

break;

 

case $this->entities[$this->l('Addresses')]:

//Overwrite required_fields

$this->required_fields = array(

'lastname',

'firstname',

'address1',

'postcode',

'country',

'customer_email',

'city'

);

 

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'alias' => array('label' => $this->l('Alias *')),

'active' => array('label' => $this->l('Active (0/1)')),

'customer_email' => array('label' => $this->l('Customer email')),

'id_customer' => array('label' => $this->l('Customer ID:')),

'manufacturer' => array('label' => $this->l('Manufacturer')),

'supplier' => array('label' => $this->l('Supplier')),

'company' => array('label' => $this->l('Company')),

'lastname' => array('label' => $this->l('Last Name *')),

'firstname' => array('label' => $this->l('First Name *')),

'address1' => array('label' => $this->l('Address 1 *')),

'address2' => array('label' => $this->l('Address 2')),

'postcode' => array('label' => $this->l('Postcode*/ Zipcode*')),

'city' => array('label' => $this->l('City *')),

'country' => array('label' => $this->l('Country *')),

'state' => array('label' => $this->l('State')),

'other' => array('label' => $this->l('Other')),

'phone' => array('label' => $this->l('Phone')),

'phone_mobile' => array('label' => $this->l('Mobile Phone')),

'vat_number' => array('label' => $this->l('VAT number')),

);

 

self::$default_values = array(

'alias' => 'Alias',

'postcode' => 'X'

);

break;

 

case $this->entities[$this->l('Manufacturers:')]:

case $this->entities[$this->l('Suppliers:')]:

//Overwrite validators AS name is not MultiLangField

self::$validators = array(

'description' => array('AdminImportController', 'createMultiLangField'),

'short_description' => array('AdminImportController', 'createMultiLangField'),

'meta_title' => array('AdminImportController', 'createMultiLangField'),

'meta_keywords' => array('AdminImportController', 'createMultiLangField'),

'meta_description' => array('AdminImportController', 'createMultiLangField'),

);

 

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'active' => array('label' => $this->l('Active (0/1)')),

'name' => array('label' => $this->l('Name *')),

'description' => array('label' => $this->l('Description')),

'short_description' => array('label' => $this->l('Short description')),

'meta_title' => array('label' => $this->l('Meta-title')),

'meta_keywords' => array('label' => $this->l('Meta-keywords')),

'meta_description' => array('label' => $this->l('Meta-description')),

'shop' => array(

'label' => $this->l('ID / Name of group shop'),

'help' => $this->l('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.'),

),

);

 

self::$default_values = array(

'shop' => Shop::getGroupFromShop(Configuration::get('PS_SHOP_DEFAULT')),

);

break;

// @since 1.5.0

case $this->entities[$this->l('SupplyOrders')]:

if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))

{

// required fields

$this->required_fields = array(

'id_supplier',

'id_warehouse',

'reference',

'date_delivery_expected',

);

// available fields

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'id' => array('label' => $this->l('ID')),

'id_supplier' => array('label' => $this->l('Supplier ID *')),

'id_lang' => array('label' => $this->l('Lang ID')),

'id_warehouse' => array('label' => $this->l('Warehouse ID *')),

'id_currency' => array('label' => $this->l('Currency ID *')),

'reference' => array('label' => $this->l('Supply Order Reference *')),

'date_delivery_expected' => array('label' => $this->l('Delivery Date (Y-M-D)*')),

'discount_rate' => array('label' => $this->l('Discount Rate')),

'is_template' => array('label' => $this->l('Template')),

);

// default values

self::$default_values = array(

'id_lang' => (int)Configuration::get('PS_LANG_DEFAULT'),

'id_currency' => Currency::getDefaultCurrency()->id,

'discount_rate' => '0',

'is_template' => '0',

);

}

break;

// @since 1.5.0

case $this->entities[$this->l('SupplyOrdersDetails')]:

if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))

{

// required fields

$this->required_fields = array(

'supply_order_reference',

'id_product',

'unit_price_te',

'quantity_expected',

);

// available fields

$this->available_fields = array(

'no' => array('label' => $this->l('Ignore this column')),

'supply_order_reference' => array('label' => $this->l('Supply Order Reference *')),

'id_product' => array('label' => $this->l('Product ID *')),

'id_product_attribute' => array('label' => $this->l('Product Attribute ID')),

'unit_price_te' => array('label' => $this->l('Unit Price (tax excl.)*')),

'quantity_expected' => array('label' => $this->l('Quantity Expected *')),

'discount_rate' => array('label' => $this->l('Discount Rate')),

'tax_rate' => array('label' => $this->l('Tax Rate')),

);

// default values

self::$default_values = array(

'discount_rate' => '0',

'tax_rate' => '0',

);

}

}

 

$this->separator = strval(trim(Tools::getValue('separator', ';')));

 

if (is_null(Tools::getValue('multiple_value_separator')) || trim(Tools::getValue('multiple_value_separator')) == '')

$this->multiple_value_separator = ',';

else

$this->multiple_value_separator = Tools::getValue('multiple_value_separator');

 

parent::__construct();

}

 

public function renderForm()

{

if (!is_writable(_PS_ADMIN_DIR_.'/import/'))

$this->displayWarning($this->l('Directory import on admin directory must be writable (CHMOD 755 / 777)'));

 

if (isset($this->warnings) && count($this->warnings))

{

$warnings = array();

foreach ($this->warnings as $warning)

$warnings[] = $warning;

}

 

$files_to_import = scandir(_PS_ADMIN_DIR_.'/import/');

uasort($files_to_import, array('AdminImportController', 'usortFiles'));

foreach ($files_to_import as $k => &$filename)

//exclude . .. .svn and index.php and all hidden files

if (preg_match('/^\..*|index\.php/i', $filename))

unset($files_to_import[$k]);

unset($filename);

 

$this->fields_form = array('');

 

$this->toolbar_scroll = false;

$this->toolbar_btn = array();

 

// adds fancybox

$this->addCSS(_PS_CSS_DIR_.'jquery.fancybox-1.3.4.css', 'screen');

$this->addJqueryPlugin(array('fancybox'));

 

$this->tpl_form_vars = array(

'module_confirmation' => (Tools::getValue('import')) && (isset($this->warnings) && !count($this->warnings)),

'path_import' => _PS_ADMIN_DIR_.'/import/',

'entities' => $this->entities,

'entity' => Tools::getValue('entity'),

'files_to_import' => $files_to_import,

'languages' => Language::getLanguages(false),

'id_language' => $this->context->language->id,

'available_fields' => $this->getAvailableFields(),

'truncateAuthorized' => (Shop::isFeatureActive() && $this->context->employee->isSuperAdmin()) || !Shop::isFeatureActive(),

'PS_ADVANCED_STOCK_MANAGEMENT' => Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'),

);

 

return parent::renderForm();

}

 

public function renderView()

{

$this->addJS(_PS_JS_DIR_.'adminImport.js');

 

$handle = $this->openCsvFile();

$nb_column = $this->getNbrColumn($handle, $this->separator);

$nb_table = ceil($nb_column / MAX_COLUMNS);

 

$res = array();

foreach ($this->required_fields as $elem)

$res[] = '\''.$elem.'\'';

 

$data = array();

for ($i = 0; $i < $nb_table; $i++)

$data[$i] = $this->generateContentTable($i, $nb_column, $handle, $this->separator);

 

$this->tpl_view_vars = array(

'import_matchs' => Db::getInstance()->executeS('SELECT * FROM '._DB_PREFIX_.'import_match'),

'fields_value' => array(

'csv' => Tools::getValue('csv'),

'convert' => Tools::getValue('convert'),

'entity' => (int)Tools::getValue('entity'),

'iso_lang' => Tools::getValue('iso_lang'),

'truncate' => Tools::getValue('truncate'),

'forceIDs' => Tools::getValue('forceIDs'),

'match_ref' => Tools::getValue('match_ref'),

'separator' => $this->separator,

'multiple_value_separator' => $this->multiple_value_separator

),

'nb_table' => $nb_table,

'nb_column' => $nb_column,

'res' => implode(',', $res),

'max_columns' => MAX_COLUMNS,

'no_pre_select' => array('price_tin', 'feature'),

'available_fields' => $this->available_fields,

'data' => $data

);

 

return parent::renderView();

}

 

public function initToolbar()

{

switch ($this->display)

{

case 'import':

// Default cancel button - like old back link

$back = Tools::safeOutput(Tools::getValue('back', ''));

if (empty($back))

$back = self::$currentIndex.'&token='.$this->token;

 

$this->toolbar_btn['cancel'] = array(

'href' => $back,

'desc' => $this->l('Cancel')

);

// Default save button - action dynamically handled in javascript

$this->toolbar_btn['save-import'] = array(

'href' => '#',

'desc' => $this->l('Import .CSV data')

);

break;

}

}

 

protected function generateContentTable($current_table, $nb_column, $handle, $glue)

{

$html = '<table id="table'.$current_table.'" style="display: none;" class="table" cellspacing="0" cellpadding="0">

<tr>';

 

// Header

for ($i = 0; $i < $nb_column; $i++)

if (MAX_COLUMNS * (int)$current_table <= $i && (int)$i < MAX_COLUMNS * ((int)$current_table + 1))

$html .= '<th style="width: '.(900 / MAX_COLUMNS).'px; vertical-align: top; padding: 4px">

<select onchange="askFeatureName(this, '.$i.');"

style="width: '.(900 / MAX_COLUMNS).'px;"

id="type_value['.$i.']"

name="type_value['.$i.']"

class="type_value">

'.$this->getTypeValuesOptions($i).'

</select>

<div id="features_'.$i.'" style="display: none;">

<input style="width: 90px" type="text" name="" id="feature_name_'.$i.'">

<input type="button" value="ok" onclick="replaceFeature($(\'#feature_name_'.$i.'\').attr(\'name\'), '.$i.');">

</div>

</th>';

$html .= '</tr>';

 

AdminImportController::setLocale();

for ($current_line = 0; $current_line < 10 && $line = fgetcsv($handle, MAX_LINE_SIZE, $glue); $current_line++)

{

/* UTF-8 conversion */

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$html .= '<tr id="table_'.$current_table.'_line_'.$current_line.'" style="padding: 4px">';

foreach ($line as $nb_c => $column)

if ((MAX_COLUMNS * (int)$current_table <= $nb_c) && ((int)$nb_c < MAX_COLUMNS * ((int)$current_table + 1)))

$html .= '<td>'.htmlentities(substr($column, 0, 200), ENT_QUOTES, 'UTF-8').'</td>';

$html .= '</tr>';

}

$html .= '</table>';

AdminImportController::rewindBomAware($handle);

return $html;

}

 

public function init()

{

parent::init();

if (Tools::isSubmit('submitImportFile'))

$this->display = 'import';

}

 

public function initContent()

{

// toolbar (save, cancel, new, ..)

$this->initToolbar();

if ($this->display == 'import')

if (Tools::getValue('csv'))

$this->content .= $this->renderView();

else

{

$this->errors[] = $this->l('You must upload a file for go to the next step');

$this->content .= $this->renderForm();

}

else

$this->content .= $this->renderForm();

 

$this->context->smarty->assign(array(

'content' => $this->content,

'url_post' => self::$currentIndex.'&token='.$this->token,

));

}

 

protected static function rewindBomAware($handle)

{

// A rewind wrapper that skip BOM signature wrongly

rewind($handle);

if (($bom = fread($handle, 3)) != "\xEF\xBB\xBF")

rewind($handle);

}

 

protected static function getBoolean($field)

{

return (boolean)$field;

}

 

protected static function getPrice($field)

{

$field = ((float)str_replace(',', '.', $field));

$field = ((float)str_replace('%', '', $field));

return $field;

}

 

protected static function split($field)

{

if (empty($field))

return array();

 

$separator = Tools::getValue('multiple_value_separator');

if (is_null($separator) || trim($separator) == '')

$separator = ',';

 

do $uniqid_path = _PS_UPLOAD_DIR_.uniqid(); while (file_exists($uniqid_path));

file_put_contents($uniqid_path, $field);

$tab = '';

if(!empty($uniqid_path))

{

$fd = fopen($uniqid_path, 'r');

$tab = fgetcsv($fd, MAX_LINE_SIZE, $separator);

fclose($fd);

unlink($uniqid_path);

}

 

if (empty($tab) || (!is_array($tab)))

return array();

return $tab;

}

 

protected static function createMultiLangField($field)

{

$languages = Language::getLanguages(false);

$res = array();

foreach ($languages as $lang)

$res[$lang['id_lang']] = $field;

return $res;

}

 

protected function getTypeValuesOptions($nb_c)

{

$i = 0;

$no_pre_select = array('price_tin', 'feature');

 

$options = '';

foreach ($this->available_fields as $k => $field)

{

$options .= '<option value="'.$k.'"';

if ($k === 'price_tin')

++$nb_c;

if ($i === ($nb_c + 1) && (!in_array($k, $no_pre_select)))

$options .= ' selected="selected"';

$options .= '>'.$field['label'].'</option>';

++$i;

}

return $options;

}

 

/*

* Return fields to be display AS piece of advise

*

* @param $in_array boolean

* @return string or return array

*/

public function getAvailableFields($in_array = false)

{

$i = 0;

$fields = array();

$keys = array_keys($this->available_fields);

array_shift($keys);

foreach ($this->available_fields as $k => $field)

{

if ($k === 'no')

continue;

if ($k === 'price_tin')

$fields[$i - 1] = '<div>'.$this->available_fields[$keys[$i - 1]]['label'].' '.$this->l('or').' '.$field['label'].'<span style="margin-left:16px"></span></div>';

else

{

if (isset($field['help']))

$html = ' <a href="#" class="info_import" title="'.$this->l('Info').'|'.$field['help'].'"><img src="'._PS_ADMIN_IMG_.'information.png"></a>';

else

$html = '<span style="margin-left:16px"></span>';

$fields[] = '<div>'.$field['label'].$html.'</div>';

}

++$i;

}

if ($in_array)

return $fields;

else

return implode("\n\r", $fields);

}

 

protected function receiveTab()

{

$type_value = Tools::getValue('type_value') ? Tools::getValue('type_value') : array();

foreach ($type_value as $nb => $type)

if ($type != 'no')

self::$column_mask[$type] = $nb;

}

 

public static function getMaskedRow($row)

{

$res = array();

if (is_array(self::$column_mask))

foreach (self::$column_mask as $type => $nb)

$res[$type] = isset($row[$nb]) ? $row[$nb] : null;

 

if (Tools::getValue('forceIds')) // if you choose to force table before import the column id is remove from the CSV file.

unset($res['id']);

 

return $res;

}

 

protected static function setDefaultValues(&$info)

{

foreach (self::$default_values as $k => $v)

if (!isset($info[$k]) || $info[$k] == '')

$info[$k] = $v;

}

 

protected static function setEntityDefaultValues(&$entity)

{

$members = get_object_vars($entity);

foreach (self::$default_values as $k => $v)

if ((array_key_exists($k, $members) && $entity->$k === null) || !array_key_exists($k, $members))

$entity->$k = $v;

}

 

protected static function fillInfo($infos, $key, &$entity)

{

$infos = trim($infos);

if (isset(self::$validators[$key][1]) && self::$validators[$key][1] == 'createMultiLangField' && Tools::getValue('iso_lang'))

{

$id_lang = Language::getIdByIso(Tools::getValue('iso_lang'));

$tmp = call_user_func(self::$validators[$key], $infos);

foreach ($tmp as $id_lang_tmp => $value)

if (empty($entity->{$key}[$id_lang_tmp]) || $id_lang_tmp == $id_lang)

$entity->{$key}[$id_lang_tmp] = $value;

}

else

if (!empty($infos) || $infos == '0') // ($infos == '0') => if you want to disable a product by using "0" in active because empty('0') return true

$entity->{$key} = isset(self::$validators[$key]) ? call_user_func(self::$validators[$key], $infos) : $infos;

 

return true;

}

 

public static function arrayWalk(&$array, $funcname, &$user_data = false)

{

if (!is_callable($funcname)) return false;

 

foreach ($array as $k => $row)

if (!call_user_func_array($funcname, array($row, $k, $user_data)))

return false;

return true;

}

 

/**

* copyImg copy an image located in $url and save it in a path

* according to $entity->$id_entity .

* $id_image is used if we need to add a watermark

*

* @param int $id_entity id of product or category (set in entity)

* @param int $id_image (default null) id of the image if watermark enabled.

* @param string $url path or url to use

* @param string entity 'products' or 'categories'

* @return void

*/

protected static function copyImg($id_entity, $id_image = null, $url, $entity = 'products')

{

$tmpfile = tempnam(_PS_TMP_IMG_DIR_, 'ps_import');

$watermark_types = explode(',', Configuration::get('WATERMARK_TYPES'));

 

switch ($entity)

{

default:

case 'products':

$image_obj = new Image($id_image);

$path = $image_obj->getPathForCreation();

break;

case 'categories':

$path = _PS_CAT_IMG_DIR_.(int)$id_entity;

break;

}

$url = str_replace(' ', '%20', trim($url));

 

// Evaluate the memory required to resize the image: if it's too much, you can't resize it.

if (!ImageManager::checkImageMemoryLimit($url))

return false;

 

// 'file_exists' doesn't work on distant file, and getimagesize make the import slower.

// Just hide the warning, the traitment will be the same.

if (@copy($url, $tmpfile))

{

ImageManager::resize($tmpfile, $path.'.jpg');

$images_types = ImageType::getImagesTypes($entity);

foreach ($images_types as $image_type)

ImageManager::resize($tmpfile, $path.'-'.stripslashes($image_type['name']).'.jpg', $image_type['width'], $image_type['height']);

 

if (in_array($image_type['id_image_type'], $watermark_types))

Hook::exec('actionWatermark', array('id_image' => $id_image, 'id_product' => $id_entity));

}

else

{

unlink($tmpfile);

return false;

}

unlink($tmpfile);

return true;

}

 

public function categoryImport()

{

$cat_moved = array();

 

$this->receiveTab();

$handle = $this->openCsvFile();

$default_language_id = (int)Configuration::get('PS_LANG_DEFAULT');

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

$tab_categ = array(Configuration::get('PS_HOME_CATEGORY'), Configuration::get('PS_ROOT_CATEGORY'));

if (isset($info['id']) && in_array((int)$info['id'], $tab_categ))

{

$this->errors[] = Tools::displayError('The ID category cannot be the same as the ID Root category, nor the ID Home category');

continue;

}

AdminImportController::setDefaultValues($info);

 

if (Tools::getValue('forceIDs') && isset($info['id']) && (int)$info['id'])

$category = new Category((int)$info['id']);

else

{

if (isset($info['id']) && (int)$info['id'] && Category::existsInDatabase((int)$info['id'], 'category'))

$category = new Category((int)$info['id']);

else

$category = new Category();

}

 

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $category);

 

if (isset($category->parent) && is_numeric($category->parent))

{

if (isset($cat_moved[$category->parent]))

$category->parent = $cat_moved[$category->parent];

$category->id_parent = $category->parent;

}

elseif (isset($category->parent) && is_string($category->parent))

{

$category_parent = Category::searchByName($default_language_id, $category->parent, true);

if ($category_parent['id_category'])

{

$category->id_parent = (int)$category_parent['id_category'];

$category->level_depth = (int)$category_parent['level_depth'] + 1;

}

else

{

$category_to_create = new Category();

$category_to_create->name = AdminImportController::createMultiLangField($category->parent);

$category_to_create->active = 1;

$category_link_rewrite = Tools::link_rewrite($category_to_create->name[$default_language_id]);

$category_to_create->link_rewrite = $category_link_rewrite;

$category_to_create->id_parent = Configuration::get('PS_HOME_CATEGORY'); // Default parent is home for unknown category to create

if (($field_error = $category_to_create->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $category_to_create->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $category_to_create->add())

$category->id_parent = $category_to_create->id;

else

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$category_to_create->name[$default_language_id],

(isset($category_to_create->id) ? $category_to_create->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

if (isset($category->link_rewrite) && !empty($category->link_rewrite[$default_language_id]))

$valid_link = Validate::isLinkRewrite($category->link_rewrite[$default_language_id]);

else

$valid_link = false;

 

if (!Shop::isFeatureActive())

$category->id_shop_default = 1;

else

$category->id_shop_default = (int)Context::getContext()->shop->id;

 

$bak = $category->link_rewrite[$default_language_id];

if ((isset($category->link_rewrite) && empty($category->link_rewrite[$default_language_id])) || !$valid_link)

{

$category->link_rewrite = Tools::link_rewrite($category->name[$default_language_id]);

if ($category->link_rewrite == '')

{

$category->link_rewrite = 'friendly-url-autogeneration-failed';

$this->warnings[] = sprintf(Tools::displayError('URL rewriting failed to auto-generate a friendly URL for: %s'), $category->name[$default_language_id]);

}

$category->link_rewrite = AdminImportController::createMultiLangField($category->link_rewrite);

}

 

if (!$valid_link)

$this->warnings[] = sprintf(

Tools::displayError('Rewrite link for %1$s (ID: %2$s) was re-written as %3$s.'),

$bak,

(isset($info['id']) ? $info['id'] : 'null'),

$category->link_rewrite[$default_language_id]

);

$res = false;

if (($field_error = $category->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $category->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && empty($this->errors))

{

$category_already_created = Category::searchByNameAndParentCategoryId(

$default_language_id,

$category->name[$default_language_id],

$category->id_parent

);

 

// If category already in base, get id category back

if ($category_already_created['id_category'])

{

$cat_moved[$category->id] = (int)$category_already_created['id_category'];

$category->id = (int)$category_already_created['id_category'];

}

 

/* No automatic nTree regeneration for import */

$category->doNotRegenerateNTree = true;

 

// If id category AND id category already in base, trying to update

$categories_home_root = array(Configuration::get('PS_ROOT_CATEGORY'), Configuration::get('PS_HOME_CATEGORY'));

if ($category->id && $category->categoryExists($category->id) && !in_array($category->id, $categories_home_root))

$res = $category->update();

if ($category->id == Configuration::get('PS_ROOT_CATEGORY'))

$this->errors[] = Tools::displayError('Root category cannot be modified');

// If no id_category or update failed

if (!$res)

$res = $category->add();

}

//copying images of categories

if (isset($category->image) && !empty($category->image))

if (!(AdminImportController::copyImg($category->id, null, $category->image, 'categories')))

$this->warnings[] = $category->image.' '.Tools::displayError('cannot be copied');

// If both failed, mysql error

if (!$res)

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

(isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'),

(isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID')

);

$error_tmp = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').Db::getInstance()->getMsgError();

if ($error_tmp != '')

$this->errors[] = $error_tmp;

}

else

{

// Associate category to shop

if (Shop::isFeatureActive())

{

Db::getInstance()->execute('

DELETE FROM '._DB_PREFIX_.'category_shop

WHERE id_category = '.(int)$category->id

);

 

if (!Shop::isFeatureActive())

$info['shop'] = 1;

elseif (!isset($info['shop']) || empty($info['shop']))

$info['shop'] = implode($this->multiple_value_separator, Shop::getContextListShopID());

 

// Get shops for each attributes

$info['shop'] = explode($this->multiple_value_separator, $info['shop']);

 

foreach ($info['shop'] as $shop)

if (!is_numeric($shop))

$category->addShop(Shop::getIdByName($shop));

else

$category->addShop($shop);

}

}

}

 

/* Import has finished, we can regenerate the categories nested tree */

Category::regenerateEntireNtree();

 

$this->closeCsvFile($handle);

}

 

public function productImport()

{

$this->receiveTab();

$handle = $this->openCsvFile();

$default_language_id = (int)Configuration::get('PS_LANG_DEFAULT');

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

if (Tools::getValue('forceIDs') && isset($info['id']) && (int)$info['id'])

$product = new Product((int)$info['id']);

else

{

if (array_key_exists('id', $info) && (int)$info['id'] && Product::existsInDatabase((int)$info['id'], 'product'))

$product = new Product((int)$info['id']);

else

$product = new Product();

}

 

if (array_key_exists('id', $info) && (int)$info['id'] && Product::existsInDatabase((int)$info['id'], 'product'))

{

$product->loadStockData();

$category_data = Product::getProductCategories((int)$product->id);

foreach ($category_data as $tmp)

$product->category[] = $tmp;

}

 

AdminImportController::setEntityDefaultValues($product);

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $product);

 

if (!Shop::isFeatureActive())

$product->shop = 1;

elseif (!isset($product->shop) || empty($product->shop))

$product->shop = implode($this->multiple_value_separator, Shop::getContextListShopID());

 

if (!Shop::isFeatureActive())

$product->id_shop_default = 1;

else

$product->id_shop_default = (int)Context::getContext()->shop->id;

 

// link product to shops

$product->id_shop_list = array();

foreach (explode($this->multiple_value_separator, $product->shop) as $shop)

if (!is_numeric($shop))

$product->id_shop_list[] = Shop::getIdByName($shop);

else

$product->id_shop_list[] = $shop;

 

if ((int)$product->id_tax_rules_group != 0)

{

if (Validate::isLoadedObject(new TaxRulesGroup($product->id_tax_rules_group)))

{

$address = $this->context->shop->getAddress();

$tax_manager = TaxManagerFactory::getManager($address, $product->id_tax_rules_group);

$product_tax_calculator = $tax_manager->getTaxCalculator();

$product->tax_rate = $product_tax_calculator->getTotalRate();

}

else

$this->addProductWarning(

'id_tax_rules_group',

$product->id_tax_rules_group,

Tools::displayError('Invalid tax rule group ID, you first need a group with this ID.')

);

}

if (isset($product->manufacturer) && is_numeric($product->manufacturer) && Manufacturer::manufacturerExists((int)$product->manufacturer))

$product->id_manufacturer = (int)$product->manufacturer;

else if (isset($product->manufacturer) && is_string($product->manufacturer) && !empty($product->manufacturer))

{

if ($manufacturer = Manufacturer::getIdByName($product->manufacturer))

$product->id_manufacturer = (int)$manufacturer;

else

{

$manufacturer = new Manufacturer();

$manufacturer->name = $product->manufacturer;

if (($field_error = $manufacturer->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $manufacturer->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $manufacturer->add())

$product->id_manufacturer = (int)$manufacturer->id;

else

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$manufacturer->name,

(isset($manufacturer->id) ? $manufacturer->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

 

if (isset($product->supplier) && is_numeric($product->supplier) && Supplier::supplierExists((int)$product->supplier))

$product->id_supplier = (int)$product->supplier;

else if (isset($product->supplier) && is_string($product->supplier) && !empty($product->supplier))

{

if ($supplier = Supplier::getIdByName($product->supplier))

$product->id_supplier = (int)$supplier;

else

{

$supplier = new Supplier();

$supplier->name = $product->supplier;

$supplier->active = true;

 

if (($field_error = $supplier->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $supplier->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $supplier->add())

{

$product->id_supplier = (int)$supplier->id;

$supplier->associateTo($product->id_shop_list);

}

else

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$supplier->name,

(isset($supplier->id) ? $supplier->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

 

if (isset($product->price_tex) && !isset($product->price_tin))

$product->price = $product->price_tex;

else if (isset($product->price_tin) && !isset($product->price_tex))

{

$product->price = $product->price_tin;

// If a tax is already included in price, withdraw it from price

if ($product->tax_rate)

$product->price = (float)number_format($product->price / (1 + $product->tax_rate / 100), 6, '.', '');

}

else if (isset($product->price_tin) && isset($product->price_tex))

$product->price = $product->price_tex;

 

if (isset($product->category) && is_array($product->category) && count($product->category))

{

$product->id_category = array(); // Reset default values array

foreach ($product->category as $value)

{

if (is_numeric($value))

{

if (Category::categoryExists((int)$value))

$product->id_category[] = (int)$value;

else

{

$category_to_create = new Category();

$category_to_create->id = (int)$value;

$category_to_create->name = AdminImportController::createMultiLangField($value);

$category_to_create->active = 1;

$category_to_create->id_parent = Configuration::get('PS_HOME_CATEGORY'); // Default parent is home for unknown category to create

$category_link_rewrite = Tools::link_rewrite($category_to_create->name[$default_language_id]);

$category_to_create->link_rewrite = AdminImportController::createMultiLangField($category_link_rewrite);

if (($field_error = $category_to_create->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $category_to_create->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $category_to_create->add())

$product->id_category[] = (int)$category_to_create->id;

else

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$category_to_create->name[$default_language_id],

(isset($category_to_create->id) ? $category_to_create->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

else if (is_string($value) && !empty($value))

{

$category = Category::searchByName($default_language_id, trim($value), true);

if ($category['id_category'])

$product->id_category[] = (int)$category['id_category'];

else

{

$category_to_create = new Category();

if (!Shop::isFeatureActive())

$category_to_create->id_shop_default = 1;

else

$category_to_create->id_shop_default = (int)Context::getContext()->shop->id;

$category_to_create->name = AdminImportController::createMultiLangField(trim($value));

$category_to_create->active = 1;

$category_to_create->id_parent = (int)Configuration::get('PS_HOME_CATEGORY'); // Default parent is home for unknown category to create

$category_link_rewrite = Tools::link_rewrite($category_to_create->name[$default_language_id]);

$category_to_create->link_rewrite = AdminImportController::createMultiLangField($category_link_rewrite);

if (($field_error = $category_to_create->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $category_to_create->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $category_to_create->add())

$product->id_category[] = (int)$category_to_create->id;

else

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$category_to_create->name[$default_language_id],

(isset($category_to_create->id) ? $category_to_create->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

}

}

 

$product->id_category_default = isset($product->id_category[0]) ? (int)$product->id_category[0] : '';

 

$link_rewrite = (is_array($product->link_rewrite) && count($product->link_rewrite)) ? trim($product->link_rewrite[$default_language_id]) : '';

 

$valid_link = Validate::isLinkRewrite($link_rewrite);

 

if ((isset($product->link_rewrite[$default_language_id]) && empty($product->link_rewrite[$default_language_id])) || !$valid_link)

{

$link_rewrite = Tools::link_rewrite($product->name[$default_language_id]);

if ($link_rewrite == '')

$link_rewrite = 'friendly-url-autogeneration-failed';

}

 

if (!$valid_link)

$this->warnings[] = sprintf(

Tools::displayError('Rewrite link for %1$s (ID: %2$s) was re-written as %3$s.'),

$link_rewrite,

(isset($info['id']) ? $info['id'] : 'null'),

$link_rewrite

);

 

$product->link_rewrite = AdminImportController::createMultiLangField($link_rewrite);

 

// replace the value of separator by coma

if ($this->multiple_value_separator != ',')

foreach ($product->meta_keywords as &$meta_keyword)

if (!empty($meta_keyword))

$meta_keyword = str_replace($this->multiple_value_separator, ',', $meta_keyword);

 

$res = false;

$field_error = $product->validateFields(UNFRIENDLY_ERROR, true);

$lang_field_error = $product->validateFieldsLang(UNFRIENDLY_ERROR, true);

if ($field_error === true && $lang_field_error === true)

{

// check quantity

if ($product->quantity == null)

$product->quantity = 0;

 

// If match ref is specified && ref product && ref product already in base, trying to update

if (Tools::getValue('match_ref') == 1 && $product->reference && $product->existsRefInDatabase($product->reference))

{

$datas = Db::getInstance()->getRow('

SELECT product_shop.`date_add`, p.`id_product`

FROM `'._DB_PREFIX_.'product` p

'.Shop::addSqlAssociation('product', 'p').'

WHERE p.`reference` = "'.$product->reference.'"

');

$product->id = (int)$datas['id_product'];

$product->date_add = pSQL($datas['date_add']);

$res = $product->update();

} // Else If id product && id product already in base, trying to update

else if ($product->id && Product::existsInDatabase((int)$product->id, 'product'))

{

$datas = Db::getInstance()->getRow('

SELECT product_shop.`date_add`

FROM `'._DB_PREFIX_.'product` p

'.Shop::addSqlAssociation('product', 'p').'

WHERE p.`id_product` = '.(int)$product->id);

$product->date_add = pSQL($datas['date_add']);

$res = $product->update();

}

// If no id_product or update failed

if (!$res)

{

if (isset($product->date_add) && $product->date_add != '')

$res = $product->add(false);

else

$res = $product->add();

}

}

 

$shops = array();

$product_shop = explode($this->multiple_value_separator, $product->shop);

foreach ($product_shop as $shop)

{

$shop = trim($shop);

if (!is_numeric($shop))

$shop = ShopGroup::getIdByName($shop);

$shops[] = $shop;

}

if (empty($shops))

$shops = Shop::getContextListShopID();

// If both failed, mysql error

if (!$res)

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

(isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'),

(isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

 

}

else

{

// Product supplier

if (isset($product->id_supplier) && isset($product->supplier_reference))

{

$id_product_supplier = ProductSupplier::getIdByProductAndSupplier((int)$product->id, 0, (int)$product->id_supplier);

if ($id_product_supplier)

$product_supplier = new ProductSupplier((int)$id_product_supplier);

else

$product_supplier = new ProductSupplier();

 

$product_supplier->id_product = $product->id;

$product_supplier->id_product_attribute = 0;

$product_supplier->id_supplier = $product->id_supplier;

$product_supplier->product_supplier_price_te = $product->wholesale_price;

$product_supplier->product_supplier_reference = $product->supplier_reference;

$product_supplier->save();

}

 

// SpecificPrice (only the basic reduction feature is supported by the import)

if ((isset($info['reduction_price']) && $info['reduction_price'] > 0) || (isset($info['reduction_percent']) && $info['reduction_percent'] > 0))

{

$specific_price = new SpecificPrice();

$specific_price->id_product = (int)$product->id;

// @todo multishop specific price import

$specific_price->id_shop = $this->context->shop->id;

$specific_price->id_currency = 0;

$specific_price->id_country = 0;

$specific_price->id_group = 0;

$specific_price->price = -1;

$specific_price->id_customer = 0;

$specific_price->from_quantity = 1;

$specific_price->reduction = (isset($info['reduction_price']) && $info['reduction_price']) ? $info['reduction_price'] : $info['reduction_percent'] / 100;

$specific_price->reduction_type = (isset($info['reduction_price']) && $info['reduction_price']) ? 'amount' : 'percentage';

$specific_price->from = (isset($info['reduction_from']) && Validate::isDate($info['reduction_from'])) ? $info['reduction_from'] : '0000-00-00 00:00:00';

$specific_price->to = (isset($info['reduction_to']) && Validate::isDate($info['reduction_to'])) ? $info['reduction_to'] : '0000-00-00 00:00:00';

if (!$specific_price->add())

$this->addProductWarning(Tools::safeOutput($info['name']), $product->id, $this->l('Discount is invalid'));

}

 

if (isset($product->tags) && !empty($product->tags))

{

// Delete tags for this id product, for no duplicating error

Tag::deleteTagsForProduct($product->id);

 

if (!is_array($product->tags))

{

$product->tags = AdminImportController::createMultiLangField($product->tags);

foreach ($product->tags as $key => $tags)

{

$is_tag_added = Tag::addTags($key, $product->id, $tags, $this->multiple_value_separator);

if (!$is_tag_added)

{

$this->addProductWarning(Tools::safeOutput($info['name']), $product->id, $this->l('Tags list is invalid'));

break;

}

}

}

else

{

foreach ($product->tags as $key => $tags)

{

$str = '';

foreach ($tags as $one_tag)

$str .= $one_tag.$this->multiple_value_separator;

$str = rtrim($str, $this->multiple_value_separator);

 

$is_tag_added = Tag::addTags($key, $product->id, $str, $this->multiple_value_separator);

if (!$is_tag_added)

{

$this->addProductWarning(Tools::safeOutput($info['name']), (int)$product->id, 'Invalid tag(s) ('.$str.')');

break;

}

}

}

}

//delete existing images if "delete_existing_images" is set to 1

if (isset($product->delete_existing_images))

if ((bool)$product->delete_existing_images)

$product->deleteImages();

else if (isset($product->image) && is_array($product->image) && count($product->image))

$product->deleteImages();

 

if (isset($product->image) && is_array($product->image) && count($product->image))

{

$product_has_images = (bool)Image::getImages($this->context->language->id, (int)$product->id);

foreach ($product->image as $key => $url)

{

$url = trim($url);

$error = false;

if (!empty($url))

{

$url = str_replace(' ', '%20', $url);

 

$image = new Image();

$image->id_product = (int)$product->id;

$image->position = Image::getHighestPosition($product->id) + 1;

$image->cover = (!$key && !$product_has_images) ? true : false;

// file_exists doesn't work with HTTP protocol

if (@fopen($url, 'r') == false)

$error = true;

else if (($field_error = $image->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $image->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $image->add())

{

// associate image to selected shops

$image->associateTo($shops);

if (!AdminImportController::copyImg($product->id, $image->id, $url))

{

$image->delete();

$this->warnings[] = sprintf(Tools::displayError('Error copying image: %s'), $url);

}

}

else

$error = true;

}

else

$error = true;

 

if ($error)

$this->warnings[] = sprintf(Tools::displayError('Product n°%1$d: the picture cannot be saved: %2$s'), $image->id_product, $url);

}

}

if (isset($product->id_category))

$product->updateCategories(array_map('intval', $product->id_category));

 

// Features import

$features = get_object_vars($product);

 

if (isset($features['features']) && !empty($features['features']))

foreach (explode($this->multiple_value_separator, $features['features']) as $single_feature)

{

$tab_feature = explode(':', $single_feature);

$feature_name = trim($tab_feature[0]);

$feature_value = trim($tab_feature[1]);

$position = isset($tab_feature[2]) ? $tab_feature[2]: false;

if(!empty($feature_name) && !empty($feature_value))

{

$id_feature = Feature::addFeatureImport($feature_name, $position);

$id_feature_value = FeatureValue::addFeatureValueImport($id_feature, $feature_value);

Product::addFeatureProductImport($product->id, $id_feature, $id_feature_value);

}

}

// clean feature positions to avoid conflict

Feature::cleanPositions();

}

 

// stock available

if (Shop::isFeatureActive())

{

foreach ($shops as $shop)

StockAvailable::setQuantity((int)$product->id, 0, $product->quantity, (int)$shop);

}

else

StockAvailable::setQuantity((int)$product->id, 0, $product->quantity, $this->context->shop->id);

 

}

 

if (Configuration::get('PS_SEARCH_INDEXATION'))

Search::indexation(true);

 

$this->closeCsvFile($handle);

}

 

public function attributeImport()

{

$default_language = Configuration::get('PS_LANG_DEFAULT');

 

$groups = array();

foreach (AttributeGroup::getAttributesGroups($default_language) as $group)

$groups[$group['name']] = (int)$group['id_attribute_group'];

 

$attributes = array();

foreach (Attribute::getAttributes($default_language) as $attribute)

$attributes[$attribute['attribute_group'].'_'.$attribute['name']] = (int)$attribute['id_attribute'];

 

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (count($line) == 1 && empty($line[0]))

continue;

 

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

$info = array_map('trim', $info);

 

AdminImportController::setDefaultValues($info);

 

if (!Shop::isFeatureActive())

$info['shop'] = 1;

elseif (!isset($info['shop']) || empty($info['shop']))

$info['shop'] = implode($this->multiple_value_separator, Shop::getContextListShopID());

 

// Get shops for each attributes

$info['shop'] = explode($this->multiple_value_separator, $info['shop']);

 

$id_shop_list = array();

foreach ($info['shop'] as $shop)

if (!is_numeric($shop))

$id_shop_list[] = Shop::getIdByName($shop);

else

$id_shop_list[] = $shop;

 

if(isset($info['id_product']))

$product = new Product((int)$info['id_product'], false, $default_language);

else

continue;

 

$id_image = null;

 

//delete existing images if "delete_existing_images" is set to 1

if (array_key_exists('delete_existing_images', $info) && $info['delete_existing_images'] && !isset($this->cache_image_deleted[(int)$product->id]))

{

$product->deleteImages();

$this->cache_image_deleted[(int)$product->id] = true;

}

 

if (isset($info['image_url']) && $info['image_url'])

{

$product_has_images = (bool)Image::getImages($this->context->language->id, $product->id);

 

$url = $info['image_url'];

$image = new Image();

$image->id_product = (int)$product->id;

$image->position = Image::getHighestPosition($product->id) + 1;

$image->cover = (!$product_has_images) ? true : false;

 

$field_error = $image->validateFields(UNFRIENDLY_ERROR, true);

$lang_field_error = $image->validateFieldsLang(UNFRIENDLY_ERROR, true);

 

if ($field_error === true && $lang_field_error === true && $image->add())

{

$image->associateTo($id_shop_list);

if (!AdminImportController::copyImg($product->id, $image->id, $url))

{

$this->warnings[] = sprintf(Tools::displayError('Error copying image: %s'), $url);

$image->delete();

}

else

$id_image = array($image->id);

}

else

{

$this->warnings[] = sprintf(

Tools::displayError('%s cannot be saved'),

(isset($image->id_product) ? ' ('.$image->id_product.')' : '')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').mysql_error();

}

}

elseif (isset($info['image_position']) && $info['image_position'])

{

$images = $product->getImages($default_language);

 

if ($images)

foreach ($images as $row)

if ($row['position'] == (int)$info['image_position'])

{

$id_image = array($row['id_image']);

break;

}

if (!$id_image)

$this->warnings[] = sprintf(

Tools::displayError('No image found for combination with id_product = %s and image position = %s.'),

$product->id,

(int)$info['image_position']

);

}

 

$id_attribute_group = 0;

// groups

$groups_attributes = array();

if(isset($info['group']))

foreach (explode($this->multiple_value_separator, $info['group']) as $key => $group)

{

$tab_group = explode(':', $group);

$group = trim($tab_group[0]);

if (!isset($tab_group[1]))

$type = 'select';

else

$type = trim($tab_group[1]);

 

// sets group

$groups_attributes[$key]['group'] = $group;

 

// if position is filled

if (isset($tab_group[2]))

$position = trim($tab_group[2]);

else

$position = false;

 

if (!isset($groups[$group]))

{

$obj = new AttributeGroup();

$obj->is_color_group = false;

$obj->group_type = pSQL($type);

$obj->name[$default_language] = $group;

$obj->public_name[$default_language] = $group;

$obj->position = (!$position) ? AttributeGroup::getHigherPosition() + 1 : $position;

 

if (($field_error = $obj->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $obj->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

$obj->add();

$obj->associateTo($id_shop_list);

$groups[$group] = $obj->id;

}

else

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '');

 

// fils groups attributes

$id_attribute_group = $obj->id;

$groups_attributes[$key]['id'] = $id_attribute_group;

}

else // alreay exists

{

$id_attribute_group = $groups[$group];

$groups_attributes[$key]['id'] = $id_attribute_group;

}

}

 

// inits attribute

$id_product_attribute = 0;

$id_product_attribute_update = false;

$attributes_to_add = array();

 

// for each attribute

if(isset($info['attribute']))

foreach (explode($this->multiple_value_separator, $info['attribute']) as $key => $attribute)

{

$tab_attribute = explode(':', $attribute);

$attribute = trim($tab_attribute[0]);

// if position is filled

if (isset($tab_attribute[1]))

$position = trim($tab_attribute[1]);

else

$position = false;

 

if (isset($groups_attributes[$key]))

{

$group = $groups_attributes[$key]['group'];

if (!isset($attributes[$group.'_'.$attribute]) && count($groups_attributes[$key]) == 2)

{

$id_attribute_group = $groups_attributes[$key]['id'];

$obj = new Attribute();

// sets the proper id (corresponding to the right key)

$obj->id_attribute_group = $groups_attributes[$key]['id'];

$obj->name[$default_language] = str_replace('\n', '', str_replace('\r', '', $attribute));

$obj->position = (!$position && isset($groups[$group])) ? Attribute::getHigherPosition($groups[$group]) + 1 : $position;

 

if (($field_error = $obj->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $obj->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

$obj->add();

$obj->associateTo($id_shop_list);

$attributes[$group.'_'.$attribute] = $obj->id;

}

else

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '');

}

 

$info['minimal_quantity'] = isset($info['minimal_quantity']) && $info['minimal_quantity'] ? (int)$info['minimal_quantity'] : 1;

 

$info['wholesale_price'] = str_replace(',', '.', $info['wholesale_price']);

$info['price'] = str_replace(',', '.', $info['price']);

$info['ecotax'] = str_replace(',', '.', $info['ecotax']);

$info['weight'] = str_replace(',', '.', $info['weight']);

 

// if a reference is specified for this product, get the associate id_product_attribute to UPDATE

if (isset($info['reference']) && !empty($info['reference']))

{

$id_product_attribute = Combination::getIdByReference($product->id, strval($info['reference']));

 

// updates the attribute

if ($id_product_attribute)

{

// gets all the combinations of this product

$attribute_combinations = $product->getAttributeCombinations($default_language);

foreach ($attribute_combinations as $attribute_combination)

{

if ($id_product_attribute && in_array($id_product_attribute, $attribute_combination))

{

$product->updateAttribute(

$id_product_attribute,

(float)$info['wholesale_price'],

(float)$info['price'],

(float)$info['weight'],

0,

(float)$info['ecotax'],

$id_image,

strval($info['reference']),

strval($info['ean13']),

(int)$info['default_on'],

0,

strval($info['upc']),

(int)$info['minimal_quantity'],

0,

null,

$id_shop_list

);

 

$id_product_attribute_update = true;

}

}

}

}

 

// if no attribute reference is specified, creates a new one

if (!$id_product_attribute)

{

$id_product_attribute = $product->addCombinationEntity(

(float)$info['wholesale_price'],

(float)$info['price'],

(float)$info['weight'],

0,

(float)$info['ecotax'],

(int)$info['quantity'],

$id_image,

strval($info['reference']),

0,

strval($info['ean13']),

(int)$info['default_on'],

0,

strval($info['upc']),

(int)$info['minimal_quantity'],

$id_shop_list

);

}

 

// fills our attributes array, in order to add the attributes to the product_attribute afterwards

if(isset($attributes[$group.'_'.$attribute]))

$attributes_to_add[] = (int)$attributes[$group.'_'.$attribute];

 

// after insertion, we clean attribute position and group attribute position

$obj = new Attribute();

$obj->cleanPositions((int)$id_attribute_group, false);

AttributeGroup::cleanPositions();

}

}

 

$product->checkDefaultAttributes();

if (!$product->cache_default_attribute)

Product::updateDefaultAttribute($product->id);

if ($id_product_attribute)

{

// now adds the attributes in the attribute_combination table

if ($id_product_attribute_update)

{

Db::getInstance()->execute('

DELETE FROM '._DB_PREFIX_.'product_attribute_combination

WHERE id_product_attribute = '.(int)$id_product_attribute);

}

 

foreach ($attributes_to_add as $attribute_to_add)

{

Db::getInstance()->execute('

INSERT IGNORE INTO '._DB_PREFIX_.'product_attribute_combination (id_attribute, id_product_attribute)

VALUES ('.(int)$attribute_to_add.','.(int)$id_product_attribute.')');

}

 

StockAvailable::setQuantity($product->id, $id_product_attribute, (int)$info['quantity']);

}

}

 

$this->closeCsvFile($handle);

}

 

public function customerImport()

{

$customer_exist = false;

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

AdminImportController::setDefaultValues($info);

 

if (Tools::getValue('forceIDs') && isset($info['id']) && (int)$info['id'])

$customer = new Customer((int)$info['id']);

else

{

if (array_key_exists('id', $info) && (int)$info['id'] && Customer::customerIdExistsStatic((int)$info['id']))

$customer = new Customer((int)$info['id']);

else

$customer = new Customer();

}

 

if (array_key_exists('id', $info) && (int)$info['id'] && Customer::customerIdExistsStatic((int)$info['id']))

{

$current_id_customer = $customer->id;

$current_id_shop = $customer->id_shop;

$current_id_shop_group = $customer->id_shop_group;

$customer_exist = true;

$customer_groups = $customer->getGroups();

$addresses = $customer->getAddresses((int)Configuration::get('PS_LANG_DEFAULT'));

foreach ($customer_groups as $key => $group)

if ($group == $customer->id_default_group)

unset($customer_groups[$key]);

}

 

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $customer);

 

if ($customer->passwd)

$customer->passwd = Tools::encrypt($customer->passwd);

 

$id_shop_list = explode($this->multiple_value_separator, $customer->id_shop);

$customers_shop = array();

$customers_shop['shared'] = array();

$default_shop = new Shop((int)Configuration::get('PS_SHOP_DEFAULT'));

if (Shop::isFeatureActive() && $id_shop_list)

{

foreach ($id_shop_list as $id_shop)

{

$shop = new Shop((int)$id_shop);

$group_shop = $shop->getGroup();

if ($group_shop->share_customer)

{

if (!in_array($group_shop->id, $customers_shop['shared']))

$customers_shop['shared'][(int)$id_shop] = $group_shop->id;

}

else

$customers_shop[(int)$id_shop] = $group_shop->id;

}

}

else

{

$default_shop = new Shop((int)Configuration::get('PS_SHOP_DEFAULT'));

$default_shop->getGroup();

$customers_shop[$default_shop->id] = $default_shop->getGroup()->id;

}

 

//set temporally for validate field

$customer->id_shop = $default_shop->id;

$customer->id_shop_group = $default_shop->getGroup()->id;

 

$res = true;

if (($field_error = $customer->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $customer->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

foreach ($customers_shop as $id_shop => $id_group)

{

if ($id_shop == 'shared')

{

foreach ($id_group as $key => $id)

{

$customer->id_shop = (int)$key;

$customer->id_shop_group = (int)$id;

if ($customer_exist && ($current_id_shop_group == $id || in_array($current_id_shop, ShopGroup::getShopsFromGroup($id))))

{

$customer->id = $current_id_customer;

$res &= $customer->update();

}

 

else

{

$res &= $customer->add();

if (isset($customer_groups))

$customer->addGroups($customer_groups);

if (isset($addresses))

foreach ($addresses as $address)

{

$address['id_customer'] = $customer->id;

unset($address['country'], $address['state'], $address['state_iso'], $address['id_address'] );

Db::getInstance()->insert('address', $address);

}

}

}

}

else

{

$customer->id_shop = $id_shop;

$customer->id_shop_group = $id_group;

if ($customer_exist && $id_shop == $current_id_shop)

{

$customer->id = $current_id_customer;

$res &= $customer->update();

}

else

{

$res &= $customer->add();

if (isset($customer_groups))

$customer->addGroups($customer_groups);

if (isset($addresses))

foreach ($addresses as $address)

{

$address['id_customer'] = $customer->id;

unset($address['country'], $address['state'], $address['state_iso'], $address['id_address']);

Db::getInstance()->insert('address', $address);

}

}

}

}

}

$customer_exist = false;

if (!$res)

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$info['email'],

(isset($info['id']) ? $info['id'] : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

$this->closeCsvFile($handle);

}

 

public function addressImport()

{

$this->receiveTab();

$default_language_id = (int)Configuration::get('PS_LANG_DEFAULT');

$handle = $this->openCsvFile();

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

AdminImportController::setDefaultValues($info);

$address = new Address();

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $address);

 

if (isset($address->country) && is_numeric($address->country))

{

if (Country::getNameById(Configuration::get('PS_LANG_DEFAULT'), (int)$address->country))

$address->id_country = (int)$address->country;

}

else if (isset($address->country) && is_string($address->country) && !empty($address->country))

{

if ($id_country = Country::getIdByName(null, $address->country))

$address->id_country = (int)$id_country;

else

{

$country = new Country();

$country->active = 1;

$country->name = AdminImportController::createMultiLangField($address->country);

$country->id_zone = 0; // Default zone for country to create

$country->iso_code = strtoupper(substr($address->country, 0, 2)); // Default iso for country to create

$country->contains_states = 0; // Default value for country to create

$lang_field_error = $country->validateFieldsLang(UNFRIENDLY_ERROR, true);

if (($field_error = $country->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $country->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $country->add())

$address->id_country = (int)$country->id;

else

{

$this->errors[] = sprintf(Tools::displayError('%s cannot be saved'), $country->name[$default_language_id]);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

 

if (isset($address->state) && is_numeric($address->state))

{

if (State::getNameById((int)$address->state))

$address->id_state = (int)$address->state;

}

else if (isset($address->state) && is_string($address->state) && !empty($address->state))

{

if ($id_state = State::getIdByName($address->state))

$address->id_state = (int)$id_state;

else

{

$state = new State();

$state->active = 1;

$state->name = $address->state;

$state->id_country = isset($country->id) ? (int)$country->id : 0;

$state->id_zone = 0; // Default zone for state to create

$state->iso_code = strtoupper(substr($address->state, 0, 2)); // Default iso for state to create

$state->tax_behavior = 0;

if (($field_error = $state->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $state->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $state->add())

$address->id_state = (int)$state->id;

else

{

$this->errors[] = sprintf(Tools::displayError('%s cannot be saved'), $state->name);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

}

 

if (isset($address->customer_email) && !empty($address->customer_email))

{

if (Validate::isEmail($address->customer_email))

{

// a customer could exists in different shop

$customer_list = Customer::getCustomersByEmail($address->customer_email);

 

if (count($customer_list) == 0)

$this->errors[] = sprintf(

Tools::displayError('%1$s does not exist in database %2$s (ID: %3$s) cannot be saved'),

Db::getInstance()->getMsgError(),

$address->customer_email,

(isset($info['id']) ? $info['id'] : 'null')

);

}

else

{

$this->errors[] = sprintf(Tools::displayError('"%s": Is not a valid e-mail address'), $address->customer_email);

continue;

}

}

elseif (isset($address->id_customer) && !empty($address->id_customer))

{

if (Customer::customerIdExistsStatic((int)$address->id_customer))

{

$customer = new Customer((int)$address->id_customer);

 

// a customer could exists in different shop

$customer_list = Customer::getCustomersByEmail($customer->email);

 

if (count($customer_list) == 0)

$this->errors[] = sprintf(

Tools::displayError('%1$s does not exist in database %2$s (ID: %3$s) cannot be saved'),

Db::getInstance()->getMsgError(),

$customer->email,

(int)$address->customer_id

);

}

else

$this->errors[] = sprintf(Tools::displayError('The customer ID n.%d does not exist in database (ID: %d) cannot be saved'), $address->customer_id);

}

else

{

$customer_list = array();

$address->id_customer = 0;

}

 

if (isset($address->manufacturer) && is_numeric($address->manufacturer) && Manufacturer::manufacturerExists((int)$address->manufacturer))

$address->id_manufacturer = (int)$address->manufacturer;

else if (isset($address->manufacturer) && is_string($address->manufacturer) && !empty($address->manufacturer))

{

$manufacturer = new Manufacturer();

$manufacturer->name = $address->manufacturer;

if (($field_error = $manufacturer->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $manufacturer->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $manufacturer->add())

$address->id_manufacturer = (int)$manufacturer->id;

else

{

$this->errors[] = Db::getInstance()->getMsgError().' '.sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$manufacturer->name,

(isset($manufacturer->id) ? $manufacturer->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

 

if (isset($address->supplier) && is_numeric($address->supplier) && Supplier::supplierExists((int)$address->supplier))

$address->id_supplier = (int)$address->supplier;

else if (isset($address->supplier) && is_string($address->supplier) && !empty($address->supplier))

{

$supplier = new Supplier();

$supplier->name = $address->supplier;

if (($field_error = $supplier->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $supplier->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $supplier->add())

$address->id_supplier = (int)$supplier->id;

else

{

$this->errors[] = Db::getInstance()->getMsgError().' '.sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$supplier->name,

(isset($supplier->id) ? $supplier->id : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

 

$res = false;

if (($field_error = $address->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $address->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

if (isset($customer_list) && count($customer_list) > 0)

{

$filter_list = array();

foreach ($customer_list as $customer)

{

if (in_array($customer['id_customer'], $filter_list))

continue;

 

$filter_list[] = $customer['id_customer'];

 

unset($address->id);

$address->id_customer = $customer['id_customer'];

$res = $address->add();

 

if (!$res)

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$info['alias'],

(isset($info['id']) ? $info['id'] : 'null')

);

}

}

else

{

if ($address->id && $address->addressExists($address->id))

$res = $address->update();

if (!$res)

$res = $address->add();

}

}

if (!$res)

{

$this->errors[] = sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

$info['alias'],

(isset($info['id']) ? $info['id'] : 'null')

);

$this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

$this->closeCsvFile($handle);

}

 

public function manufacturerImport()

{

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

AdminImportController::setDefaultValues($info);

 

if (Tools::getValue('forceIDs') && isset($info['id']) && (int)$info['id'])

$manufacturer = new Manufacturer((int)$info['id']);

else

{

if (array_key_exists('id', $info) && (int)$info['id'] && Manufacturer::existsInDatabase((int)$info['id'], 'manufacturer'))

$manufacturer = new Manufacturer((int)$info['id']);

else

$manufacturer = new Manufacturer();

}

 

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $manufacturer);

 

$res = false;

if (($field_error = $manufacturer->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $manufacturer->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

if ($manufacturer->id && $manufacturer->manufacturerExists($manufacturer->id))

$res = $manufacturer->update();

if (!$res)

$res = $manufacturer->add();

 

if ($res)

{

// Associate supplier to group shop

if (Shop::isFeatureActive() && $manufacturer->shop)

{

Db::getInstance()->execute('

DELETE FROM '._DB_PREFIX_.'manufacturer_shop

WHERE id_manufacturer = '.(int)$manufacturer->id

);

$manufacturer->shop = explode($this->multiple_value_separator, $manufacturer->shop);

$shops = array();

foreach ($manufacturer->shop as $shop)

{

$shop = trim($shop);

if (!is_numeric($shop))

$shop = ShopGroup::getIdByName($shop);

$shops[] = $shop;

}

$manufacturer->associateTo($shops);

}

}

}

 

if (!$res)

{

$this->errors[] = Db::getInstance()->getMsgError().' '.sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

(isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'),

(isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID')

);

$this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '').

Db::getInstance()->getMsgError();

}

}

$this->closeCsvFile($handle);

}

 

public function supplierImport()

{

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++)

{

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

AdminImportController::setDefaultValues($info);

 

if (Tools::getValue('forceIDs') && isset($info['id']) && (int)$info['id'])

$supplier = new Supplier((int)$info['id']);

else

{

if (array_key_exists('id', $info) && (int)$info['id'] && Supplier::existsInDatabase((int)$info['id'], 'supplier'))

$supplier = new Supplier((int)$info['id']);

else

$supplier = new Supplier();

}

 

 

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $supplier);

if (($field_error = $supplier->validateFields(UNFRIENDLY_ERROR, true)) === true &&

($lang_field_error = $supplier->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true)

{

$res = false;

if ($supplier->id && $supplier->supplierExists($supplier->id))

$res = $supplier->update();

if (!$res)

$res = $supplier->add();

 

if (!$res)

$this->errors[] = Db::getInstance()->getMsgError().' '.sprintf(

Tools::displayError('%1$s (ID: %2$s) cannot be saved'),

(isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'),

(isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID')

);

else

{

// Associate supplier to group shop

if (Shop::isFeatureActive() && $supplier->shop)

{

Db::getInstance()->execute('

DELETE FROM '._DB_PREFIX_.'supplier_shop

WHERE id_supplier = '.(int)$supplier->id

);

$supplier->shop = explode($this->multiple_value_separator, $supplier->shop);

$shops = array();

foreach ($supplier->shop as $shop)

{

$shop = trim($shop);

if (!is_numeric($shop))

$shop = ShopGroup::getIdByName($shop);

$shops[] = $shop;

}

$supplier->associateTo($shops);

}

}

}

else

{

$this->errors[] = $this->l('Supplier is invalid').' ('.$supplier->name.')';

$this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '');

}

}

$this->closeCsvFile($handle);

}

 

/**

* @since 1.5.0

*/

public function supplyOrdersImport()

{

// opens CSV & sets locale

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

 

// main loop, for each supply orders to import

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); ++$current_line)

{

// if convert requested

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

// sets default values if needed

AdminImportController::setDefaultValues($info);

 

// if an id is set, instanciates a supply order with this id if possible

if (array_key_exists('id', $info) && (int)$info['id'] && SupplyOrder::exists((int)$info['id']))

$supply_order = new SupplyOrder((int)$info['id']);

// if a reference is set, instanciates a supply order with this reference if possible

else if (array_key_exists('reference', $info) && $info['reference'] && SupplyOrder::exists(pSQL($info['reference'])))

$supply_order = SupplyOrder::getSupplyOrderByReference(pSQL($info['reference']));

else // new supply order

$supply_order = new SupplyOrder();

 

// gets parameters

$id_supplier = (int)$info['id_supplier'];

$id_lang = (int)$info['id_lang'];

$id_warehouse = (int)$info['id_warehouse'];

$id_currency = (int)$info['id_currency'];

$reference = pSQL($info['reference']);

$date_delivery_expected = pSQL($info['date_delivery_expected']);

$discount_rate = (float)$info['discount_rate'];

$is_template = (bool)$info['is_template'];

 

// checks parameters

if (!Supplier::supplierExists($id_supplier))

$this->errors[] = sprintf($this->l('Supplier ID (%d) is not valid (at line %d).'), $id_supplier, $current_line + 1);

if (!Language::getLanguage($id_lang))

$this->errors[] = sprintf($this->l('Lang ID (%d) is not valid (at line %d).'), $id_lang, $current_line + 1);

if (!Warehouse::exists($id_warehouse))

$this->errors[] = sprintf($this->l('Warehouse ID (%d) is not valid (at line %d).'), $id_warehouse, $current_line + 1);

if (!Currency::getCurrency($id_currency))

$this->errors[] = sprintf($this->l('Currency ID (%d) is not valid (at line %d).'), $id_currency, $current_line + 1);

if (empty($supply_order->reference) && SupplyOrder::exists($reference))

$this->errors[] = sprintf($this->l('Reference (%s) already exists (at line %d).'), $reference, $current_line + 1);

if (!empty($supply_order->reference) && ($supply_order->reference != $reference && SupplyOrder::exists($reference)))

$this->errors[] = sprintf($this->l('Reference (%s) already exists (at line %d).'), $reference, $current_line + 1);

if (!Validate::isDateFormat($date_delivery_expected))

$this->errors[] = sprintf($this->l('Date (%s) is not valid (at line %d). Format: %s.'), $date_delivery_expected,

$current_line + 1, $this->l('YYYY-MM-DD'));

else if (new DateTime($date_delivery_expected) <= new DateTime('yesterday'))

$this->errors[] = sprintf($this->l('Date (%s) cannot be in the past (at line %d). Format: %s.'), $date_delivery_expected,

$current_line + 1, $this->l('YYYY-MM-DD'));

if ($discount_rate < 0 || $discount_rate > 100)

$this->errors[] = sprintf($this->l('Discount rate (%d) is not valid (at line %d). %s.'), $discount_rate,

$current_line + 1, $this->l('Format: between 0 and 100'));

if ($supply_order->id > 0 && !$supply_order->isEditable())

$this->errors[] = sprintf($this->l('Supply Order (%d) is not editable (at line %d).'), $supply_order->id, $current_line + 1);

 

// if no errors, sets supply order

if (empty($this->errors))

{

// adds parameters

$info['id_ref_currency'] = (int)Currency::getDefaultCurrency()->id;

$info['supplier_name'] = pSQL(Supplier::getNameById($id_supplier));

if ($supply_order->id > 0)

{

$info['id_supply_order_state'] = (int)$supply_order->id_supply_order_state;

$info['id'] = (int)$supply_order->id;

}

else

$info['id_supply_order_state'] = 1;

 

// sets parameters

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $supply_order);

 

// updatesd($supply_order);

$res = true;

if ($supply_order->id > 0)

$res &= $supply_order->update();

else

$res &= $supply_order->add();

 

// errors

if (!$res)

$this->errors[] = sprintf($this->l('Supply Order could not be saved (at line %d).'), $current_line + 1);

}

}

 

// closes

$this->closeCsvFile($handle);

}

 

public function supplyOrdersDetailsImport()

{

// opens CSV & sets locale

$this->receiveTab();

$handle = $this->openCsvFile();

AdminImportController::setLocale();

 

$products = array();

$reset = true;

// main loop, for each supply orders details to import

for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); ++$current_line)

{

// if convert requested

if (Tools::getValue('convert'))

$line = $this->utf8EncodeArray($line);

$info = AdminImportController::getMaskedRow($line);

 

// sets default values if needed

AdminImportController::setDefaultValues($info);

 

// gets the supply order

if (array_key_exists('supply_order_reference', $info) && pSQL($info['supply_order_reference']) && SupplyOrder::exists(pSQL($info['supply_order_reference'])))

$supply_order = SupplyOrder::getSupplyOrderByReference(pSQL($info['supply_order_reference']));

else

$this->errors[] = sprintf($this->l('Supply Order (%s) could not be loaded (at line %d).'), (int)$info['supply_order_reference'], $current_line + 1);

 

if (empty($this->errors))

{

// sets parameters

$id_product = (int)$info['id_product'];

if (!$info['id_product_attribute'])

$info['id_product_attribute'] = 0;

$id_product_attribute = (int)$info['id_product_attribute'];

$unit_price_te = (float)$info['unit_price_te'];

$quantity_expected = (int)$info['quantity_expected'];

$discount_rate = (float)$info['discount_rate'];

$tax_rate = (float)$info['tax_rate'];

 

// checks if one product is there only once

if (isset($product['id_product']))

{

if ($product['id_product'] == $id_product_attribute)

$this->errors[] = sprintf($this->l('Product (%d/%D) cannot be added twice (at line %d).'), $id_product,

$id_product_attribute, $current_line + 1);

else

$product['id_product'] = $id_product_attribute;

}

else

$product['id_product'] = 0;

 

// checks parameters

if (false === ($supplier_reference = ProductSupplier::getProductSupplierReference($id_product, $id_product_attribute, $supply_order->id_supplier)))

$this->errors[] = sprintf($this->l('Product (%d/%d) is not available for this order (at line %d).'), $id_product,

$id_product_attribute, $current_line + 1);

if ($unit_price_te < 0)

$this->errors[] = sprintf($this->l('Unit Price (tax excl.) (%d) is not valid (at line %d).'), $unit_price_te, $current_line + 1);

if ($quantity_expected < 0)

$this->errors[] = sprintf($this->l('Quantity Expected (%d) is not valid (at line %d).'), $quantity_expected, $current_line + 1);

if ($discount_rate < 0 || $discount_rate > 100)

$this->errors[] = sprintf($this->l('Discount rate (%d) is not valid (at line %d). %s.'), $discount_rate,

$current_line + 1, $this->l('Format: between 0 and 100'));

if ($tax_rate < 0 || $tax_rate > 100)

$this->errors[] = sprintf($this->l('Quantity Expected (%d) is not valid (at line %d).'), $tax_rate,

$current_line + 1, $this->l('Format: between 0 and 100'));

 

// if no errors, sets supply order details

if (empty($this->errors))

{

// resets order if needed

if ($reset)

{

$supply_order->resetProducts();

$reset = false;

}

 

// creates new product

$supply_order_detail = new SupplyOrderDetail();

AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $supply_order_detail);

 

// sets parameters

$supply_order_detail->id_supply_order = $supply_order->id;

$currency = new Currency($supply_order->id_ref_currency);

$supply_order_detail->id_currency = $currency->id;

$supply_order_detail->exchange_rate = $currency->conversion_rate;

$supply_order_detail->supplier_reference = $supplier_reference;

$supply_order_detail->name = Product::getProductName($id_product, $id_product_attribute, $supply_order->id_lang);

 

// gets ean13 / ref / upc

$query = new DbQuery();

$query->select('

IFNULL(pa.reference, IFNULL(p.reference, \'\')) as reference,

IFNULL(pa.ean13, IFNULL(p.ean13, \'\')) as ean13,

IFNULL(pa.upc, IFNULL(p.upc, \'\')) as upc

');

$query->from('product', 'p');

$query->leftJoin('product_attribute', 'pa', 'pa.id_product = p.id_product AND id_product_attribute = '.(int)$id_product_attribute);

$query->where('p.id_product = '.(int)$id_product);

$query->where('p.is_virtual = 0 AND p.cache_is_pack = 0');

$res = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query);

$product_infos = $res['0'];

 

$supply_order_detail->reference = $product_infos['reference'];

$supply_order_detail->ean13 = $product_infos['ean13'];

$supply_order_detail->upc = $product_infos['upc'];

 

$supply_order_detail->add();

$supply_order->update();

unset($supply_order_detail);

 

}

}

}

 

// closes

$this->closeCsvFile($handle);

}

 

public function utf8EncodeArray($array)

{

if (is_array($array))

foreach ($array as $key => $value)

$array[$key] = utf8_encode($value);

else

$array = utf8_encode($array);

 

return $array;

}

 

protected function getNbrColumn($handle, $glue)

{

$tmp = fgetcsv($handle, MAX_LINE_SIZE, $glue);

AdminImportController::rewindBomAware($handle);

return count($tmp);

}

 

protected static function usortFiles($a, $ B)

{

$a = strrev(substr(strrev($a), 0, 14));

$b = strrev(substr(strrev($ B), 0, 14));

 

if ($a == $ B)

return 0;

 

return ($a < $ B) ? 1 : -1;

}

 

protected function openCsvFile()

{

$handle = fopen(_PS_ADMIN_DIR_.'/import/'.strval(preg_replace('/\.{2,}/', '.', Tools::getValue('csv'))), 'r');

 

if (!$handle)

$this->errors[] = Tools::displayError('Cannot read the .CSV file');

 

AdminImportController::rewindBomAware($handle);

 

for ($i = 0; $i < (int)Tools::getValue('skip'); ++$i)

$line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator);

return $handle;

}

 

protected function closeCsvFile($handle)

{

fclose($handle);

}

 

protected function truncateTables($case)

{

switch ((int)$case)

{

case $this->entities[$this->l('Categories:')]:

Db::getInstance()->execute('

DELETE FROM `'._DB_PREFIX_.'category`

WHERE id_category NOT IN ('.(int)Configuration::get('PS_HOME_CATEGORY').

', '.(int)Configuration::get('PS_ROOT_CATEGORY').')');

Db::getInstance()->execute('

DELETE FROM `'._DB_PREFIX_.'category_lang`

WHERE id_category NOT IN ('.(int)Configuration::get('PS_HOME_CATEGORY').

', '.(int)Configuration::get('PS_ROOT_CATEGORY').')');

Db::getInstance()->execute('

DELETE FROM `'._DB_PREFIX_.'category_shop`

WHERE `id_category` NOT IN ('.(int)Configuration::get('PS_HOME_CATEGORY').

', '.(int)Configuration::get('PS_ROOT_CATEGORY').')');

Db::getInstance()->execute('ALTER TABLE `'._DB_PREFIX_.'category` AUTO_INCREMENT = 3');

foreach (scandir(_PS_CAT_IMG_DIR_) as $d)

if (preg_match('/^[0-9]+(\-(.*))?\.jpg$/', $d))

unlink(_PS_CAT_IMG_DIR_.$d);

break;

case $this->entities[$this->l('Products:')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_shop');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'feature_product');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_lang');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'category_product');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_tag');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'image');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'image_lang');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'image_shop');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'specific_price');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'specific_price_priority');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_carrier');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'cart_product');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'compare_product');

if (count(Db::getInstance()->executeS('SHOW TABLES LIKE \''._DB_PREFIX_.'favorite_product\' '))) //check if table exist

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'favorite_product');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attachment');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_country_tax');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_download');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_group_reduction_cache');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_sale');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_supplier');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'scene_products');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'warehouse_product_location');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'stock');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'stock_available');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'stock_mvt');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'customization');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'customization_field');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'supply_order_detail');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_impact');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_shop`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_combination`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_image`');

Image::deleteAllImages(_PS_PROD_IMG_DIR_);

if (!file_exists(_PS_PROD_IMG_DIR_))

mkdir(_PS_PROD_IMG_DIR_);

break;

case $this->entities[$this->l('Combinations')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_impact');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_lang`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_group`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_group_lang`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_group_shop`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'attribute_shop`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_shop`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_combination`');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'product_attribute_image`');

Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'stock_available` WHERE id_product_attribute !=0');

break;

case $this->entities[$this->l('Customers')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'customer');

break;

case $this->entities[$this->l('Addresses')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'address');

break;

case $this->entities[$this->l('Manufacturers:')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'manufacturer');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'manufacturer_lang');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'manufacturer_shop');

foreach (scandir(_PS_MANU_IMG_DIR_) as $d)

if (preg_match('/^[0-9]+(\-(.*))?\.jpg$/', $d))

unlink(_PS_MANU_IMG_DIR_.$d);

break;

case $this->entities[$this->l('Suppliers:')]:

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'supplier');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'supplier_lang');

Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'supplier_shop');

foreach (scandir(_PS_SUPP_IMG_DIR_) as $d)

if (preg_match('/^[0-9]+(\-(.*))?\.jpg$/', $d))

unlink(_PS_SUPP_IMG_DIR_.$d);

break;

}

Image::clearTmpDir();

return true;

}

 

public function postProcess()

{

/* PrestaShop demo mode */

if (_PS_MODE_DEMO_)

{

$this->errors[] = Tools::displayError('This functionality has been disabled.');

return;

}

/* PrestaShop demo mode*/

 

if (Tools::isSubmit('submitFileUpload'))

{

if (isset($_FILES['file']) && !empty($_FILES['file']['error']))

{

switch ($_FILES['file']['error'])

{

case UPLOAD_ERR_INI_SIZE:

$this->errors[] = Tools::displayError('The uploaded file exceeds the upload_max_filesize directive in php.ini. If your server configuration allows it, you may add a directive in your .htaccess.');

break;

case UPLOAD_ERR_FORM_SIZE:

$this->errors[] = Tools::displayError('The uploaded file exceeds the post_max_size directive in php.ini.

If your server configuration allows it, you may add a directive in your .htaccess, for example:')

.'<br/><a href="'.$this->context->link->getAdminLink('AdminMeta').'" >

<code>php_value post_max_size 20M</code> '.

Tools::displayError('(click to open "Generators" page)').'</a>';

break;

break;

case UPLOAD_ERR_PARTIAL:

$this->errors[] = Tools::displayError('The uploaded file was only partially uploaded.');

break;

break;

case UPLOAD_ERR_NO_FILE:

$this->errors[] = Tools::displayError('No file was uploaded');

break;

break;

}

}

else if (!file_exists($_FILES['file']['tmp_name']) ||

!@move_uploaded_file($_FILES['file']['tmp_name'], _PS_ADMIN_DIR_.'/import/'.date('Ymdhis').'-'.$_FILES['file']['name']))

$this->errors[] = $this->l('an error occurred while uploading and copying file');

else

Tools::redirectAdmin(self::$currentIndex.'&token='.Tools::getValue('token').'&conf=18');

}

else if (Tools::getValue('import'))

{

// Check if the CSV file exist

if (Tools::getValue('csv'))

{

// If i am a superadmin, i can truncate table

if (((Shop::isFeatureActive() && $this->context->employee->isSuperAdmin()) || !Shop::isFeatureActive()) && Tools::getValue('truncate'))

$this->truncateTables((int)Tools::getValue('entity'));

 

switch ((int)Tools::getValue('entity'))

{

case $this->entities[$this->l('Categories:')]:

$this->categoryImport();

break;

case $this->entities[$this->l('Products:')]:

$this->productImport();

break;

case $this->entities[$this->l('Customers')]:

$this->customerImport();

break;

case $this->entities[$this->l('Addresses')]:

$this->addressImport();

break;

case $this->entities[$this->l('Combinations')]:

$this->attributeImport();

break;

case $this->entities[$this->l('Manufacturers:')]:

$this->manufacturerImport();

break;

case $this->entities[$this->l('Suppliers:')]:

$this->supplierImport();

break;

// @since 1.5.0

case $this->entities[$this->l('SupplyOrders')]:

if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))

$this->supplyOrdersImport();

break;

// @since 1.5.0

case $this->entities[$this->l('SupplyOrdersDetails')]:

if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))

$this->supplyOrdersDetailsImport();

break;

default:

$this->errors[] = $this->l('Please select what you would like to import');

}

}

else

$this->errors[] = $this->l('You must upload a file for go to the next step');

}

 

parent::postProcess();

}

 

public static function setLocale()

{

$iso_lang = trim(Tools::getValue('iso_lang'));

setlocale(LC_COLLATE, strtolower($iso_lang).'_'.strtoupper($iso_lang).'.UTF-8');

setlocale(LC_CTYPE, strtolower($iso_lang).'_'.strtoupper($iso_lang).'.UTF-8');

}

 

protected function addProductWarning($product_name, $product_id = null, $message = '')

{

$this->warnings[] = $product_name.(isset($product_id) ? ' (ID '.$product_id.')' : '').' '.Tools::displayError($message);

}

 

public function ajaxProcessSaveImportMatchs()

{

if ($this->tabAccess['edit'] === '1')

{

$match = implode('|', Tools::getValue('type_value'));

Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'import_match` (

`id_import_match` ,

`name` ,

`match`,

`skip`

)

VALUES (

NULL ,

\''.pSQL(Tools::getValue('newImportMatchs')).'\',

\''.pSQL($match).'\',

\''.pSQL(Tools::getValue('skip')).'\'

)');

 

die('{"id" : "'.Db::getInstance()->Insert_ID().'"}');

}

}

 

public function ajaxProcessLoadImportMatchs()

{

if ($this->tabAccess['edit'] === '1')

{

$return = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'import_match` WHERE `id_import_match` = '.(int)Tools::getValue('idImportMatchs'));

die('{"id" : "'.$return[0]['id_import_match'].'", "matchs" : "'.$return[0]['match'].'", "skip" : "'.$return[0]['skip'].'"}');

}

}

 

public function ajaxProcessDeleteImportMatchs()

{

if ($this->tabAccess['edit'] === '1')

{

Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'import_match` WHERE `id_import_match` = '.(int)Tools::getValue('idImportMatchs'));

die;

}

}

}

 

Dejo el fichero adjunto

 

Recordaros que aunque dejo el fichero adjunto, tambien podeis bajarlo de aqui: https://github.com/PrestaShop/PrestaShop/blob/development/controllers/admin/AdminImportController.php

 

Por otro lado, recordaros, que para quien use la versión 1.5.4 o superior el parche ya viene incluido.

AdminImportController.php

Link to comment
Share on other sites

Las imágenes las tienes que subir a un sitio conocido de tu servidor (por ejemplo: http://www.tudominio.com/imagenes), de tal forma que en la columna URL images del csv tienes que poner la ruta entera de las imágenes, por ejemplo: http://www.tudominio...es/image_01.jpg (y así con todas).

 

Una vez hayas subido todos los productos puedes borrar la carpeta imagenes de tu servidor ya que prestashop habrá copiado las imágenes donde las tenga que copiar.

 

Si esto te falla revisa los permisos de la carpeta img de prestashop.

 

 

Yo por ejemplo algunas veces las he guardado en una carpeta llamada "upload", luego he subido la carpeta al hosting, y luego en la ruta de imagenes al importar he puesto esto:

 

../upload/nombre_imagen.jpg

 

Y prestashop luego las ha importado a sus carpetas correspondientes sin ningun problema.

 

Por otro lado, cuando quieres colocar las urls completas y externas de las imagenes del proveedor (

 

http://wwww.proveedor.com/producto/pepitolospalotes.jpg

 

), en el hosting, tenéis que tener habilitado el parametro: allow_url_fopen en On. (Luego prestashop las descarga y las coloca en sus correspondientes carpetas)

Link to comment
Share on other sites

¿Pero has aplicado el parche?

 

Si Rubalcaba, aplicando parche y nada. Al final he bajado hasta la version PrestaShop™ 1.5.2.0 y me sube sin cambios de ningun tipo todas categorias, iamgenes, etc........ya saldrá alguna historieta, pero gracias por recordarmelo que se me podria haber pasado.

Link to comment
Share on other sites

Hola, ya avía visto la pagina que menciona rubalcaba, pero como mi ingles es muy malo no entendía como como cambiar el código, gracias por la explicación, lo voy a probar, aunque también encontré otra solución aquí.

 

http://www.prestasho..._1#entry1067176

 

solo hay que cambiar esta linea:

$fd = fopen($temp, 'r');

 

 

por

 

 

$fd = fopen(_PS_UPLOAD_DIR_.$uniqid, 'r');

 

En el archivo controllers/admin/AdminImportController.php

 

con ese cambio me a funcionado bien, pone los productos en sus categorías y también agarra las imágenes.

 

Saludos.

 

Despues de muchos fallos que tengo, haciendo las minimas correcciones en los archivos tpl/php por fin me funciona como antes la tienda.......................................de momento.

 

Agradezco todo a todos.......................hasta las llamadas de atencion, jejejejeje.

Link to comment
Share on other sites

  • 4 months later...
Guest
This topic is now closed to further replies.
×
×
  • Create New...