jat Posted August 30, 2018 Share Posted August 30, 2018 (edited) Hola a tod@s Estoy buscando e intentando adaptar un script para importar productos desde un csv automáticamente, en un Prestashop He visto una para Prestashop 1.6: Script Importacion Automatica Prestashop 1.6 Me gustaría poder adaptarlo para Prestashop 1.7 y dejarlo aquí para compartirlo He adaptado parte del código, pero en Prestashop 1.7 ha cambiado las funcionalidades: <?php // definimos la cabecera y el juego de caracteres header("Content-Type: text/html;charset=utf-8"); // colocamos el directorio de adminxxxxx en la variable cogiendo el directorio donde está este script con getcwd define('_PS_ADMIN_DIR_', getcwd()); // incluimos los parametros que se definieron en la instalación include(_PS_ADMIN_DIR_.'../../config/config.inc.php'); // incluimos las funciones php de Prestashop que vamos a usar // Que esta dentro de la carpeta del admin donde entrtamos al panel include(_PS_ADMIN_DIR_.'/functions.php'); // incluimos el script php que hace las importaciones de CSV de Prestashop include_once '../../controllers/admin/AdminImportController.php'; // Duda si la funcionalidad para importar productos en PS 1.7 esta en: //include_once '../../controllers/admin/AdminProductsController.php'; // loadProductsPost() -> loadProduct() ? function loadProduct() { $_POST = array ( 'tab' => 'AdminImport', 'skip' => '1', 'csv' => 'productos.csv', 'forceIDs' => '0', 'match_ref' => '1', 'convert' => '', 'entity' => '1', 'separator' => ';', 'multiple_value_separator' => ',', 'iso_lang' => 'es', 'import' => 'Importar datos CSV', 'type_value' => array ( 1 => "ID", 2 => "Activo (0/1)", 3 => "Nombre *", 4 => "Categorías (x,y,z...)", 5 => "Precio impuestos excluidos", 6 => "ID regla de impuestos", 7 => "Precio de coste", 8 => "En oferta (0/1)", 9 => "Valor del descuento", 10 => "Porcentaje de descuento", 11 => "Descuento desde (aaaa-mm-dd)", 12 => "Descuento hasta (aaaa-mm-dd)", 13 => "Referencia nº", 14 => "N° de referencia proveedor", 15 => "Proveedor", 16 => "Marca", 17 => "EAN13", 18 => "UPC", 19 => "Ecotasa", 20 => "Anchura", 21 => "Altura", 22 => "Profundidad", 23 => "Peso", 24 => "Cantidad", 25 => "Cantidad mínima", 26 => "Visible en", 27 => "Coste adicional del envío", 28 => "Unidad para el precio unitario", 29 => "Precio unitario", 30 => "Resumen", // Short Description 31 => "Descripción", // Long Description 32 => "Etiquetas (x,y,z...)", 33 => "Meta título", 34 => "Meta keywords", 35 => "Meta descripción", 36 => "URL reescrita", 37 => "Etiqueta cuando se encuentra en stock", 38 => "Etiqueta para cuando se permiten pedidos en espera", 39 => "Disponible para pedidos (0 = No, 1 = Yes)", 40 => "Fecha de disponibilidad del producto", 41 => "Fecha de creación del producto", 42 => "Mostrar Precio (0 = No, 1 = Yes)", 43 => "URL's de las imágenes (x,y,z...)", // Url de la imagen 44 => "Textos alternativos de imagen (x,y,z...)", 45 => "Elimine las imágenes existentes (0 = No, 1 = Yes)", 46 => "Característica (Nombre:Valor:Posición:Personalizado)", // Feature( Name:Value:Position ) 47 => "Solo disponible por Internet (0 = No, 1 = Yes)", 48 => "Estado", 49 => "Personalizable (0 = No, 1 = Yes)", 50 => "Se pueden subir archivos (0 = No, 1 = Yes)", 51 => "Campos de texto (0 = No, 1 = Yes)", 52 => "Fuera de stock", // Out of stock 53 => "ID / Nombre de la tienda", 54 => "Administración Avanzada de Stock ", 55 => "Dependiendo del stock", 56 => "Almacén", ), ); } $import = New AdminImportController(); loadProduct(); ¿Alguno ha podido adaptar un script similar? o ¿sabéis que funciones tengo que usar para enviar el csv? Muchas gracias! Edited August 27, 2020 by jat (see edit history) Link to comment Share on other sites More sharing options...
Rolige Posted September 10, 2018 Share Posted September 10, 2018 Hola, Aun no he tenido la necesidad de hacerlo, pero te pregunto, ¿porque no hacerlo con el CSV desde la pagina de importación de productos de PrestaShop que al final esta hecho para eso y en ambiente gráfico? Saludos! Link to comment Share on other sites More sharing options...
jat Posted September 10, 2018 Author Share Posted September 10, 2018 hace 2 minutos, Rolige dijo: Aun no he tenido la necesidad de hacerlo, pero te pregunto, ¿porque no hacerlo con el CSV desde la pagina de importación de productos de PrestaShop que al final esta hecho para eso y en ambiente gráfico? Hola Rolige por que quiero dejar un script que lo haga automáticamente. Es mucho más rapido y cubre mis necesidades de desarrollo. Ya lo tengo hecho, en breve lo publicare. Link to comment Share on other sites More sharing options...
Rolige Posted September 10, 2018 Share Posted September 10, 2018 Excelente, seguro sera un buen aporte para quienes lo quieran hacer de esa manera. Link to comment Share on other sites More sharing options...
jsiesquen Posted November 3, 2018 Share Posted November 3, 2018 Podrias compartirnos el script estimado @jat ? Saludos! 1 Link to comment Share on other sites More sharing options...
jfcordova Posted December 8, 2018 Share Posted December 8, 2018 @jat Nos dejaste con las ganas y no lo subiste 🙄🤓 1 Link to comment Share on other sites More sharing options...
agsinformatica Posted December 9, 2018 Share Posted December 9, 2018 Buenas tardes. Me uno a la petición. Yo hice para prestashop 1.6 pero en esta versión 1.7 no funciona. Espero con los brazos abiertos. Saludos. Link to comment Share on other sites More sharing options...
xatursa Posted April 16, 2019 Share Posted April 16, 2019 Yo tengo hecho un script que actualiza el stock de las combinaciones y los productos sin combinaciones. Si ejecuto el script directamente por medio de la URL, funciona correctamente. ¿como hay que hacer para que se ejecute de manera automática? Link to comment Share on other sites More sharing options...
jfcordova Posted April 16, 2019 Share Posted April 16, 2019 Usando un CronJob. Hay modulos gratuitos de prestashop para esto. también revisa con tu server, posiblemente incluye una opción para tareas programadas recurrentes, usando tu url. Fuera un buen aporte si nos compartes ese script. Puede ayudar a varios usuarios. Saludos 3 hours ago, xatursa said: Yo tengo hecho un script que actualiza el stock de las combinaciones y los productos sin combinaciones. Si ejecuto el script directamente por medio de la URL, funciona correctamente. ¿como hay que hacer para que se ejecute de manera automática? 1 Link to comment Share on other sites More sharing options...
alexloma Posted May 7, 2019 Share Posted May 7, 2019 Os dejo el script que he realizado para un Prestashop 1.7.4 Es para importar productos y combinaciones Funciona todo menos las imágenes , estoy peleándome con ese tema. Sé que Prestashop espera un array al recibir este dato pero por mas pruebas que hago no doy con la solución. En fin, aquí dejo esto para el que le pueda ser útil <?php header("Content-Type: text/html;charset=utf-8"); ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); if (!defined('_PS_ADMIN_DIR_')) define('_PS_ADMIN_DIR_', getcwd()); include(_PS_ADMIN_DIR_.'/../config/config.inc.php'); include(_PS_ADMIN_DIR_.'/functions.php'); include_once './tabs/AdminImport.php'; require_once(_PS_ADMIN_DIR_.'/init.php'); $context = Context::getContext(); $import = New AdminImportController(); loadProductsPost(); $import->productImport(); loadCombinationsPost(); $import->attributeImport(); function loadProductsPost() { $_POST = array ( 'tab' => 'AdminImport', 'forceIDs' => '1', 'skip' => '1', 'csv' => 'productos.csv', 'entity' => '1', 'separator' => ';', 'multiple_value_separator' => ',', 'iso_lang' => 'es', 'convert' => '', 'import' => '1', "type_value" => array( 0 => 'id', 1 => 'active', 2 => 'name', 3 => 'category', 4 => 'price_tex', 5 => 'id_tax_rules_group', 6 => 'wholesale_price', 7 => 'on_sale', 8 => 'reduction_price', 9 => 'reduction_percent', 10 => 'reduction_from', 11 => 'reduction_to', 12 => 'reference', 13 => 'supplier_reference', 14 => 'supplier', 15 => 'manufacturer', 16 => 'ean13', 17 => 'upc', 18 => 'ecotax', 29 => 'width', 20 => 'height', 21 => 'depth', 22 => 'weight', 23 => 'quantity', 24 => 'minimal_quantity', 25 => 'visibility', 26 => 'additional_shipping_cost', 27 => 'unity', 28 => 'unit_price', 29 => 'description_short', 30 => 'description', 31 => 'tags', 32 => 'meta_title', 33 => 'meta_keywords', 34 => 'meta_description', 36 => 'text_when_in_stock', 37 => 'text_when_backorder_allowed', 41 => 'show_price', 42 => 'image', 43 => 'image_alt', 44 => 'delete_existing_images', 45 => 'features', 46 => 'online_only', 47 => 'condition', 48 => 'customizable', 49 => 'uploadable_files', 50 => 'text_fields', 51 => 'out_of_stock', 52 => 'is_virtual', 53 => 'file_url', 54 => 'nb_downloadable', 55 => 'date_expiration', 56 => 'nb_days_accessible', 57 => 'shop', 58 => 'advanced_stock_management', 59 => 'depends_on_stock', 60 => 'warehouse', 61 => 'accessories', ), ); } function loadCombinationsPost() { $_POST = array ( 'tab' => 'AdminImport', 'forceIDs' => '1', 'skip' => '1', 'csv' => 'combinaciones.csv', 'entity' => '2', 'separator' => ';', 'multiple_value_separator' => ',', 'iso_lang' => 'es', 'convert' => '', 'import' => '2', "type_value" => array( 0 => 'id_product', 1 => 'product_reference', 2 => 'group', 3 => 'attribute', 4 => 'supplier_reference', 5 => 'reference', 6 => 'ean13', 7 => 'upc', 8 => 'wholesale_price', 9 => 'price', 10 => 'ecotax', 11 => 'quantity', 12 => 'minimal_quantity', 13 => 'weight', 14 => 'default_on', 15 => 'available_date', 16 => 'image_position', 17 => 'image_url', 18 => 'delete_existing_images', 19 => 'shop', 20 => 'advanced_stock_management', 21 => 'depends_on_stock', 22 => 'warehouse', ), ); } Tools::clearSmartyCache(); Tools::clearXMLCache(); Media::clearCache(); Tools::generateIndex(); ?> Link to comment Share on other sites More sharing options...
alexloma Posted May 7, 2019 Share Posted May 7, 2019 Al final ya puedo subir imágenes. Este es el código completo: <?php header("Content-Type: text/html;charset=utf-8"); ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); if (!defined('_PS_ADMIN_DIR_')) define('_PS_ADMIN_DIR_', getcwd()); include(_PS_ADMIN_DIR_.'/../config/config.inc.php'); include(_PS_ADMIN_DIR_.'/functions.php'); include_once './tabs/AdminImport.php'; require_once(_PS_ADMIN_DIR_.'/init.php'); $context = Context::getContext(); function copyImg($id_entity, $id_image, $url, $entity = 'products', $regenerate = true) { $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; case 'manufacturers': $path = _PS_MANU_IMG_DIR_ . (int) $id_entity; break; case 'suppliers': $path = _PS_SUPP_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 makes the import slower. // Just hide the warning, the processing will be the same. if (Tools::copy($url, $tmpfile)) { ImageManager::resize($tmpfile, $path . '.jpg'); $images_types = ImageType::getImagesTypes($entity); if ($regenerate) 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; } $import = New AdminImportController(); $url = "http://localhost/mi_imagen.jpg"; $image = new Image(); $image->id_product = (int) $Codigo_del_articulo; $image->position = Image::getHighestPosition($Codigo_del_articulo) + 1; $image->cover = true; $image->add(); if (!copyImg($Codigo_del_articulo, $image->id, $url, 'products', !Tools::getValue('regenerate'))) { $image->delete(); } loadProductsPost(); $import->productImport(); loadCombinationsPost(); $import->attributeImport(); function loadProductsPost() { $_POST = array ( 'tab' => 'AdminImport', 'forceIDs' => '1', 'skip' => '1', 'csv' => 'productos.csv', 'entity' => '1', 'separator' => ';', 'multiple_value_separator' => ',', 'iso_lang' => 'es', 'convert' => '', 'import' => '1', "type_value" => array( 0 => 'id', 1 => 'active', 2 => 'name', 3 => 'category', 4 => 'price_tex', 5 => 'id_tax_rules_group', 6 => 'wholesale_price', 7 => 'on_sale', 8 => 'reduction_price', 9 => 'reduction_percent', 10 => 'reduction_from', 11 => 'reduction_to', 12 => 'reference', 13 => 'supplier_reference', 14 => 'supplier', 15 => 'manufacturer', 16 => 'ean13', 17 => 'upc', 18 => 'ecotax', 29 => 'width', 20 => 'height', 21 => 'depth', 22 => 'weight', 23 => 'quantity', 24 => 'minimal_quantity', 25 => 'visibility', 26 => 'additional_shipping_cost', 27 => 'unity', 28 => 'unit_price', 29 => 'description_short', 30 => 'description', 31 => 'tags', 32 => 'meta_title', 33 => 'meta_keywords', 34 => 'meta_description', 36 => 'text_when_in_stock', 37 => 'text_when_backorder_allowed', 41 => 'show_price', 42 => 'image', 43 => 'image_alt', 44 => 'delete_existing_images', 45 => 'features', 46 => 'online_only', 47 => 'condition', 48 => 'customizable', 49 => 'uploadable_files', 50 => 'text_fields', 51 => 'out_of_stock', 52 => 'is_virtual', 53 => 'file_url', 54 => 'nb_downloadable', 55 => 'date_expiration', 56 => 'nb_days_accessible', 57 => 'shop', 58 => 'advanced_stock_management', 59 => 'depends_on_stock', 60 => 'warehouse', 61 => 'accessories', ), ); } function loadCombinationsPost() { $_POST = array ( 'tab' => 'AdminImport', 'forceIDs' => '1', 'skip' => '1', 'csv' => 'combinaciones.csv', 'entity' => '2', 'separator' => ';', 'multiple_value_separator' => ',', 'iso_lang' => 'es', 'convert' => '', 'import' => '2', "type_value" => array( 0 => 'id_product', 1 => 'product_reference', 2 => 'group', 3 => 'attribute', 4 => 'supplier_reference', 5 => 'reference', 6 => 'ean13', 7 => 'upc', 8 => 'wholesale_price', 9 => 'price', 10 => 'ecotax', 11 => 'quantity', 12 => 'minimal_quantity', 13 => 'weight', 14 => 'default_on', 15 => 'available_date', 16 => 'image_position', 17 => 'image_url', 18 => 'delete_existing_images', 19 => 'shop', 20 => 'advanced_stock_management', 21 => 'depends_on_stock', 22 => 'warehouse', ), ); } Tools::clearSmartyCache(); Tools::clearXMLCache(); Media::clearCache(); Tools::generateIndex(); ?> Link to comment Share on other sites More sharing options...
rufodek2 Posted May 13, 2019 Share Posted May 13, 2019 Muchisimas gracias por el aporte, funciona perfecto excepto lo de las imaganes. No entiendo muy bien si es que hay que subirlas antes a una carpeta o no. Podrias explicarlo un poco, gracias. Link to comment Share on other sites More sharing options...
alexloma Posted May 14, 2019 Share Posted May 14, 2019 La función copyImg es la que se encarga de todo. Suponiendo que tienes un artículo con un id = 555 y quieres añadirle una imagen que está en "http://localhost/img/imagen1.jpg" o "https://tudominio.com/img/imagen1.jpg" la llamada a la función sería: $url = "http://localhost/img/imagen1.jpg"; $image = new Image(); $image->id_product = (int) 555; $image->position = Image::getHighestPosition(555) + 1; $image->cover = true; $image->add(); if (!copyImg(555, $image->id, $url, 'products', !Tools::getValue('regenerate'))) { $image->delete(); } Dependiendo del resto de tu código y como realizas el bucle, igual tienes que colocar este código en otro lugar mas adecuado. Si el contenido de $url tiene más de una imagen, estás van separadas por comas. Link to comment Share on other sites More sharing options...
gusman126 Posted May 14, 2019 Share Posted May 14, 2019 hace 2 horas, alexloma dijo: $image->cover = true; ¿Esto no puede dar problemas si ya existe una cover añadida? Mejor si comprueba la posición , si es cero que sea cover, si es mayor no es cover $position = Image::getHighestPosition(555); if($position == 0){ $image->cover = true; }else{ $image->cover = false; } Link to comment Share on other sites More sharing options...
devildriver Posted September 5, 2019 Share Posted September 5, 2019 On 5/7/2019 at 5:15 PM, alexloma said: Al final ya puedo subir imágenes. Este es el código completo: <?php header("Content-Type: text/html;charset=utf-8"); ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); if (!defined('_PS_ADMIN_DIR_')) define('_PS_ADMIN_DIR_', getcwd()); include(_PS_ADMIN_DIR_.'/../config/config.inc.php'); include(_PS_ADMIN_DIR_.'/functions.php'); include_once './tabs/AdminImport.php'; require_once(_PS_ADMIN_DIR_.'/init.php'); $context = Context::getContext(); function copyImg($id_entity, $id_image, $url, $entity = 'products', $regenerate = true) { $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; case 'manufacturers': $path = _PS_MANU_IMG_DIR_ . (int) $id_entity; break; case 'suppliers': $path = _PS_SUPP_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 makes the import slower. // Just hide the warning, the processing will be the same. if (Tools::copy($url, $tmpfile)) { ImageManager::resize($tmpfile, $path . '.jpg'); $images_types = ImageType::getImagesTypes($entity); if ($regenerate) 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; } $import = New AdminImportController(); $url = "http://localhost/mi_imagen.jpg"; $image = new Image(); $image->id_product = (int) $Codigo_del_articulo; $image->position = Image::getHighestPosition($Codigo_del_articulo) + 1; $image->cover = true; $image->add(); if (!copyImg($Codigo_del_articulo, $image->id, $url, 'products', !Tools::getValue('regenerate'))) { $image->delete(); } loadProductsPost(); $import->productImport(); loadCombinationsPost(); $import->attributeImport(); function loadProductsPost() { $_POST = array ( 'tab' => 'AdminImport', 'forceIDs' => '1', 'skip' => '1', 'csv' => 'productos.csv', 'entity' => '1', 'separator' => ';', 'multiple_value_separator' => ',', 'iso_lang' => 'es', 'convert' => '', 'import' => '1', "type_value" => array( 0 => 'id', 1 => 'active', 2 => 'name', 3 => 'category', 4 => 'price_tex', 5 => 'id_tax_rules_group', 6 => 'wholesale_price', 7 => 'on_sale', 8 => 'reduction_price', 9 => 'reduction_percent', 10 => 'reduction_from', 11 => 'reduction_to', 12 => 'reference', 13 => 'supplier_reference', 14 => 'supplier', 15 => 'manufacturer', 16 => 'ean13', 17 => 'upc', 18 => 'ecotax', 29 => 'width', 20 => 'height', 21 => 'depth', 22 => 'weight', 23 => 'quantity', 24 => 'minimal_quantity', 25 => 'visibility', 26 => 'additional_shipping_cost', 27 => 'unity', 28 => 'unit_price', 29 => 'description_short', 30 => 'description', 31 => 'tags', 32 => 'meta_title', 33 => 'meta_keywords', 34 => 'meta_description', 36 => 'text_when_in_stock', 37 => 'text_when_backorder_allowed', 41 => 'show_price', 42 => 'image', 43 => 'image_alt', 44 => 'delete_existing_images', 45 => 'features', 46 => 'online_only', 47 => 'condition', 48 => 'customizable', 49 => 'uploadable_files', 50 => 'text_fields', 51 => 'out_of_stock', 52 => 'is_virtual', 53 => 'file_url', 54 => 'nb_downloadable', 55 => 'date_expiration', 56 => 'nb_days_accessible', 57 => 'shop', 58 => 'advanced_stock_management', 59 => 'depends_on_stock', 60 => 'warehouse', 61 => 'accessories', ), ); } function loadCombinationsPost() { $_POST = array ( 'tab' => 'AdminImport', 'forceIDs' => '1', 'skip' => '1', 'csv' => 'combinaciones.csv', 'entity' => '2', 'separator' => ';', 'multiple_value_separator' => ',', 'iso_lang' => 'es', 'convert' => '', 'import' => '2', "type_value" => array( 0 => 'id_product', 1 => 'product_reference', 2 => 'group', 3 => 'attribute', 4 => 'supplier_reference', 5 => 'reference', 6 => 'ean13', 7 => 'upc', 8 => 'wholesale_price', 9 => 'price', 10 => 'ecotax', 11 => 'quantity', 12 => 'minimal_quantity', 13 => 'weight', 14 => 'default_on', 15 => 'available_date', 16 => 'image_position', 17 => 'image_url', 18 => 'delete_existing_images', 19 => 'shop', 20 => 'advanced_stock_management', 21 => 'depends_on_stock', 22 => 'warehouse', ), ); } Tools::clearSmartyCache(); Tools::clearXMLCache(); Media::clearCache(); Tools::generateIndex(); ?> Saludos estoy utilizado este script y me crea los articulos pero las imagenes no me las genera hay una variable que se llama $codigo_del_articulo que desconozco de donde la toma alguien logro realizarlo? Link to comment Share on other sites More sharing options...
el_charlie Posted March 9, 2020 Share Posted March 9, 2020 El script funciona excelente. Pero no funciona si no hay sesión iniciada en el admin de Prestashop. No hay una manera de iniciar sesión en el script? Colocando usuario y pass para poder ejecutarlo periódicamente con un cron? Gracias! Link to comment Share on other sites More sharing options...
el_charlie Posted March 11, 2020 Share Posted March 11, 2020 Ya funciona sin necesidad de iniciar sesión, no es necesario el init.php. Aquí el código completo sólo para productos e importando imágenes cuyo nombre de archivo es la [referencia del producto].jpg y en mi caso están en la carpeta /imgs_prods/. <?php header("Content-Type: text/html;charset=utf-8"); ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); if (!defined('_PS_ADMIN_DIR_')) define('_PS_ADMIN_DIR_', getcwd()); include(_PS_ADMIN_DIR_.'/../config/config.inc.php'); include(_PS_ADMIN_DIR_.'/functions.php'); include_once '../controllers/admin/AdminImportController.php'; set_time_limit(0); function copyImg($id_entity, $id_image, $url, $entity = 'products', $regenerate = true) { $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; case 'manufacturers': $path = _PS_MANU_IMG_DIR_ . (int) $id_entity; break; case 'suppliers': $path = _PS_SUPP_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 makes the import slower. // Just hide the warning, the processing will be the same. if (Tools::copy($url, $tmpfile)) { ImageManager::resize($tmpfile, $path . '.jpg'); $images_types = ImageType::getImagesTypes($entity); if ($regenerate) 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; } $import = New AdminImportController(); loadProductsPost(); $import->productImport(); function loadProductsPost() { $_POST = array ( 'tab' => 'AdminImportController', 'truncate'=>'0', 'forceIDs' => '1', 'match_ref' => '1', 'skip' => '0', 'csv' => '../../../dropbox/nuevos.csv', // Por comodidad se almacena el archivo en una carpeta que no es adminxxx/import 'entity' => '1', 'separator' => ';', 'multiple_value_separator' => ',', 'iso_lang' => 'es', 'convert' => '', 'import' => '1', "type_value" => array( 0 => 'id', //el archivo tiene el ID que será necesario para importar imágenes 1 => 'reference', 2 => 'name', 3 => 'quantity', 4 => 'price_tex', 5 => 'category' ), ); } $file_handle = fopen("../../dropbox/nuevos.csv", "r"); //la ruta remota del CSV ó TXT. El mismo archivo que importamos while (!feof($file_handle)) { $line = fgets($file_handle); echo $line."<br>"; //para mostrar el contenido del archivo que importamos $linea = explode(";",$line); if (file_exists('../../imgs_prods/'.$linea[1].'.jpg')){ $url = "https://miurl.com/imgs_prods/".$linea[1].".jpg"; $image = new Image(); $image->id_product = (int) $linea[0]; $image->position = Image::getHighestPosition($linea[0]) + 1; $image->cover = true; $image->add(); if (!copyImg($linea[0], $image->id, $url, 'products', !Tools::getValue('regenerate'))) { $image->delete(); } } } fclose($file_handle); Tools::clearSmartyCache(); Tools::clearXMLCache(); Media::clearCache(); Tools::generateIndex(); ?> 1 Link to comment Share on other sites More sharing options...
jat Posted August 27, 2020 Author Share Posted August 27, 2020 (edited) En 08/12/2018 a las 8:14 PM, jfcordova dijo: @jat Nos dejaste con las ganas y no lo subiste 🙄🤓 Os paso el codigo, @jsiesquen @jfcordova ya siento el retraso. 😓 Hay mucha cosas que modificar. Y mucha gracias @el_charlie por tu ayuda y aportación 😉 El código que desarrolle en su dia: <?php /** * User: Jatniel Guzmán * E-mail: <[email protected]> * Date: 6/08/18 * Time: 10:58 */ $currentDir = dirname(__FILE__); if (!defined('_PS_ROOT_DIR_')) { define('_PS_ROOT_DIR_', realpath($currentDir.'/..')); } include(_PS_ROOT_DIR_.'/config/config.inc.php'); include(_PS_ROOT_DIR_.'/init.php'); $total_lineas_fichero=0; $numero_lineas_insertadas=0; $numero_lineas_modificadas=0; $error_accesorios=''; $line=0; $productos_insertados=''; $path_importacion='/upload/'; $path_log=$path_importacion.'logs/'; $path_doc=dirname(_PS_ROOT_DIR_).$path_importacion.'doc_man/'; $path_imagenes=_PS_ROOT_DIR_.$path_importacion.'imagenes/'; $fichier=_PS_ROOT_DIR_.$path_importacion.'productos.csv'; $filename_log=_PS_ROOT_DIR_.$path_log.'log_importacion_productos_'.date("j_m_Y").".txt"; if (file_exists($fichier)) { $fp = fopen("$fichier", "r"); } else { echo "Fichero no existe importación parada !."; $donnees = array('{lastname}' => '' , '{firstname}' => '' ); $destinataire = '[email protected]'; Mail::Send(1, 'import_erp_error', 'Importacion de produtos ERP' , $donnees, $destinataire); exit(); } $file = new SplFileObject($fichier); $file->setFlags(SplFileObject::READ_CSV); $file->setCsvControl(';'); foreach ($file as $row) { if (!empty($row[0])) { list ($referencia_producto, $nombre_producto, $precio ,$disponibilidad,$imagen_principal,$imagenes,$documentacion_man,$documentacion_com,$accesorios) = $row; if(!empty($referencia_producto)) { $id_product = getProductbyRef($referencia_producto); $product = $id_product>0 ? new Product((int)$id_product, true) : new Product(); if (empty($id_product)) { //solo para los nuevos productos $product->id_category_default = 51; // categoría de los productos $product->link_rewrite[1] = Tools::link_rewrite( str_replace('º','', utf8_encode($nombre_producto) ) ); $product->name[1] = utf8_encode($nombre_producto) ; $product->meta_description[1] = 'Compra online '.utf8_encode($nombre_producto). ' entrega 48h'; $product->meta_title = utf8_encode($nombre_producto) ; $tab_categories=array(); $tab_categories[]=51; // categoria por defecto $productos_insertados.=$referencia_producto .', '; } $product->active = $disponibilidad ; $product->price = floatval(str_ireplace(',','.',$precio )) ; $product->reference = $referencia_producto ; product_save($product) ; //salvamos el producto // Si se crea un producto se pone la categoria por defecto if (empty($id_product)){ addCategoriestoproducto($tab_categories ,$product->id); } if ($product->id>0 ){ //Cantidad de producto $quantity=$disponibilidad== 1 ? 10000 : 0 ; StockAvailable::setQuantity($product->id,'', $quantity ); /* //Imagen principal del producto $tab_imagenes_productos[]=add_images($path_imagenes,$imagen_principal,$product->id,true); //Otras Imagenes del producto $tab_imagenes=array(); $tab_imagenes=explode("|",$imagenes); foreach ($tab_imagenes as $key =>$nombre_imagen) { if (!empty($nombre_imagen)){ $tab_imagenes_productos[]=add_images($path_imagenes,$nombre_imagen,$product->id,false); } } //Adjuntos documentacion man (manuales...) if (isset($documentacion_man)){ crud_attachment($product->id,$documentacion_man); } if (isset($documentacion_com)){ crud_attachment($product->id,$documentacion_com); } */ } $total_lineas_fichero++; $id_product ? $numero_lineas_modificadas++ : $numero_lineas_insertadas++ ; echo 'Product <b>'.$product->reference .' - '.$product->name[1].'</b> '.($id_product ? 'updated' : 'created').' Disponibilidad :'.$disponibilidad.'<br />'; } $line++; } } /* //Tratamos los accesorios de los productos $file = new SplFileObject($fichier); $file->setFlags(SplFileObject::READ_CSV); $file->setCsvControl(';'); $line=0; foreach ($file as $row) { if ($line!=0){ list ($referencia_producto, $nombre_producto, $precio ,$disponibilidad,$imagen_principal,$imagenes,$documentacion_man,$documentacion_com,$accesorios) = $row; if(!empty($referencia_producto) && !empty($accesorios)) { $error=0; addaccesories($accesorios,$id_product); $error_accesorios.=$error!=0 ? ' Error accesorios en '.$id_product.chr(13).chr(10) :''; } } $line++; } */ // LOG DE IMPORTACION $log_txt=date("j/m/Y H:i").' - Log de importacion de productos '.chr(13).chr(10) ; $log_txt.='Total de productos :'.$total_lineas_fichero.chr(13).chr(10) ; $log_txt.='Total de productos insertados :'.$numero_lineas_insertadas.chr(13).chr(10) ; $log_txt.='Total de productos modificados :'.$numero_lineas_modificadas.chr(13).chr(10); addLog($log_txt,$filename_log); $file = null; copy($fichier , _PS_ROOT_DIR_.$path_importacion.'backups/importacion_erp'.date("j_m_Y").'.csv' ); echo "<br>Importacion terminada, con exito."; $fichier=dirname(__FILE__).'importacion_erp.csv'; $subject = 'Importacion de produtos del ERP'; $donnees = array('{lastname}' => '' , '{firstname}' => '' ,'{filename}' => $fichier , '{productos_insertados}' =>$productos_insertados); $destinataire = '[email protected]'; Mail::Send(1, 'import_erp', $subject , $donnees, $destinataire); echo 'Mail enviado'; exit; //Importación de los accesorios multiples para la compra con el producto function addaccesories ($accesorios,$id_product) { $error=1; $group_accesories=array(18=>'1',19=>'2',52=>'3',53=>'5'); // tabla de equivalencia categorias grupos solucions 1, reactivos 2, electrodos y sondas 3 , accesorios y complementos 5 if (!empty($id_product) && !empty($accesorios)) { $error = 0; Db::getInstance()->delete('ps_accessory', 'id_product_1=' . $id_product); Db::getInstance()->delete('accessory_group_product_lang', 'id_lang=1 and id_accessory_group_product in (select id_accessory_group_product from ps_accessory_group_product where id_product=' . $id_product . ')'); Db::getInstance()->delete('cart_rule', 'reduction_product in (select id_accessory_group_product from ps_accessory_group_product where id_product=' . $id_product . ' )'); Db::getInstance()->delete('accessory_product_cart_rule', 'id_accessory in (select id_accessory from ps_accessory_group_product where id_product=' . $id_product . ' )'); Db::getInstance()->delete('accessory_group_product', 'id_product=' . $id_product ); $tab_accesories = explode("$", $accesorios); $product = $id_product>0 ? new Product((int)$id_product, true) : new Product(); foreach ($tab_accesories as $key => $referencia_producto) { if (!empty(trim($referencia_producto))) { $id_product_accesorio = getProductbyRef(trim($referencia_producto)); $product_accesorio = new Product((int)$id_product_accesorio, true) ; /* para añadir el producto asociado al producot $accesorio_asociado = array( 'id_product_1' => $id_product, 'id_product_2' => (int)$id_product_accesorio ); Db::getInstance()->insert('accessory', $accesorio_asociado); */ $accessory = new HsAccessoriesGroupProduct(); $accessory->id_accessory = $id_product_accesorio; $accessory->id_product = $id_product ; $accessory->id_accessory_group = $group_accesories ; $accessory->id_product_attribute = 0; $accessory->default_quantity = 1; $accessory->min_quantity = 1 ; $accessory->name = $product_accesorio->name; $accessory->position = HsAccessoriesGroupProductAbstract::getHighestPosition(1 , $id_product) + 1; $accessory->add(); $cart_rule = new HsMaCartRule(); $cart_rule->product = $product; $cart_rule->accessory = $accessory; $cart_rule->id_shops = 1 ; $cart_rule->addCartRule(0 , 5, array(1=>'descuento para el producto'), 'Solo valido comprando los productos juntos'); } } } return $error; } //Recupera el id del producto con la referencia function getProductbyRef($referencia_producto){ $id_product=0; $id_product= (int)Db::getInstance()->getValue("SELECT id_product FROM ps_product WHERE reference = '".pSQL($referencia_producto,false)."'"); return $id_product; } //Guarda los datos del producto function product_save($product){ $product->id_tax_rules_group= 1 ; $product->weight = 0 ; $product->quantity = 1; $product->redirect_type = '404'; $product->show_price = 1; $product->on_sale = 0 ; $product->is_virtual=0; $product->minimal_quantity = 1 ; if (!isset($product->date_add) || empty($product->date_add)) $product->date_add = date('Y-m-d H:i:s'); $product->date_upd = date('Y-m-d H:i:s'); $product->save(); } //function para añadir una imagen function add_images($path_imagenes,$tab_imagen,$id_product,$principal) { $imagen=explode("$",$tab_imagen); $nombre_imagen=$imagen[0]; $desc_imagen=$imagen[1]; $fecha_imagen=$imagen[2]; // formateamos la fecha de imagen para poder compararla $fecha_imagen= new DateTime($fecha_imagen); $fecha_imagen=$fecha_imagen->format('Y-m-d'); //recuperamos los parametros de log de las imagenes $imagen_log=get_fecha_log($id_product,$nombre_imagen); $fecha_imagen_log=$imagen_log['fecha_modificacion']; $id_imagen_log=$imagen_log['id_imagen']; if ( $fecha_imagen > $fecha_imagen_log || empty($fecha_imagen_log)) { // si se ha modificado o si es una nueva imagen la borramos o la añadimos // si la imagen existe la boramos delete_image($id_imagen_log,$id_product,$principal) ; $shops = Shop::getShops(true, null, true); $image = new Image(); $image->id_product = $id_product; $image->legend = $desc_imagen ; $image->position = Image::getHighestPosition($id_product) + 1; $image->cover = $principal; // or false; if (($image->validateFields(false, true)) === true && ($image->validateFieldsLang(false, true)) === true && $image->add()) { $id_imagen_log=$image->id ; $image->associateTo($shops); if (!AdminImportController::copyImg($id_product, $image->id, $path_imagenes.$nombre_imagen , 'products', true)) { $image->delete(); } else { add_image_to_log($fecha_imagen, $nombre_imagen,$id_product,$image->id); // añadimos la imagen a la tabla de logs } } } return $id_imagen_log; } //function para modificar añadir o borrar los manuales function crud_attachment($id_product, $tab_adjuntos) { global $path_doc; $attachment = new Attachment(); //recogemos los adjuntos del producto de la BD $tab_attachments = $attachment->getAttachments(1, $id_product); if (!empty($tab_adjuntos)){ if (!empty($tab_adjuntos) ) { $tab_adjuntos =explode("|",$tab_adjuntos ); foreach($tab_adjuntos as $key_adjunto => $adjunto) { $adjunto =explode("$",$adjunto ); $nombre_fichero=$adjunto[0]; $descripcion_fichero=$adjunto[1]; $fecha_modificacion_fichero=$adjunto[2]; // formateamos la fecha de imagen para poder compararla $fecha_modificacion_fichero= new DateTime($fecha_modificacion_fichero); $fecha_modificacion_fichero=$fecha_modificacion_fichero->format('Y-m-d'); //recuperamos los parametros de log de las imagenes $fichero_log=get_fecha_log_fichero($id_product,$nombre_fichero); $fecha_fichero_log=$fichero_log['fecha_modificacion']; $id_imagen_log=$fichero_log['id_attachment']; if ( $fecha_modificacion_fichero > $fecha_fichero_log || empty($fecha_fichero_log)) { // si se ha modificado o si es un nuevo fichero if ( array_search( $nombre_fichero , array_column($tab_attachments, 'file_name') ) !== false ) { $key_file =array_search( $nombre_fichero , array_column($tab_attachments, 'file_name') ) ; $row_attachment=$tab_attachments[$key_file]; $attachment = new Attachment($row_attachment['id_attachment']); // borramos el fichero fisico if (file_exists(_PS_DOWNLOAD_DIR_.$attachment->file )) { unlink(_PS_DOWNLOAD_DIR_.$attachment->file); echo 'unlink'; } // creamos el uniq ID para presta do $uniqid = sha1(microtime()); while (file_exists(_PS_DOWNLOAD_DIR_.$uniqid)); $path_file = $path_doc.$nombre_fichero ; copy(trim($path_file), _PS_DOWNLOAD_DIR_.$uniqid); $attachment->file=$uniqid; $finfo = finfo_open(FILEINFO_MIME_TYPE); $attachment->mime = finfo_file($finfo, $path_file); $attachment->file_name = $nombre_fichero; $attachment->file_size = filesize($path_file); $attachment->update_documentos($path_file); // update attachment BD $id_attachment=$attachment->id_attachment; // echo 'update'.$nombre_fichero; } else { $id_attachment= add_attachment($id_product,$adjunto); // echo 'add'.$nombre_fichero; } delete_ficheros_to_log($id_attachment,$id_product) ; add_ficheros_to_log($fecha_modificacion_fichero, $nombre_fichero,$id_product,$id_attachment) ; } } } // Borramos lod ficheros que no estan en la lista porque se han suprimidos $tab_attachments = $attachment->getAttachments(1, $id_product); foreach($tab_attachments as $attachment) { $file_exist=0; foreach($tab_adjuntos as $key_adjunto => $adjunto) { $adjunto =explode("$",$adjunto ); if ($adjunto[0]== $attachment['file_name']) $file_exist=1 ; } if (!$file_exist ){ echo 'delete'.$attachment['file_name']; $myattachment = new Attachment($attachment['id_attachment']); $myattachment->deleteProductAttachments($id_product); delete_ficheros_to_log($myattachment->id,$id_product) ; } } } } // Function para añadir un manual function add_attachment ($id_product,$adjunto) { global $path_doc; $nombre_fichero=$adjunto[0]; $descripcion_fichero=$adjunto[1]; $fecha_modificacion_fichero=$adjunto[2]; $path_file=$path_doc.$nombre_fichero; $filename=basename($path_file); // Generate unique filename do $uniqid = sha1(microtime()); while (file_exists(_PS_DOWNLOAD_DIR_.$uniqid)); // Copy file to target copy(trim($path_file), _PS_DOWNLOAD_DIR_.$uniqid); // Create file attachment $attachment = new Attachment(); $attachment->file = $uniqid; $path_file = $path_doc.$filename; $finfo = finfo_open(FILEINFO_MIME_TYPE); $attachment->mime = finfo_file($finfo, $path_file); $attachment->file_name = $nombre_fichero ; $attachment->file_size = filesize($path_file); // Create name and description for each language $languages = Language::getLanguages(false); foreach ($languages as $language) { $attachment->name[(int)$language['id_lang']] = substr($descripcion_fichero , 0, 32); $attachment->description[(int)$language['id_lang']] = '' ; } // Put to DB $attachment->add(); // Attach to product $attachment->attachProduct($id_product); return (int)$attachment->id; } //recupera la fecha de modificaion de una imagen function get_fecha_log($id_product,$nombre_imagen) { $row=''; if (!empty($id_product) && !empty($nombre_imagen)) { } return $row; } //recupera la fecha de modificacion de un fichero function get_fecha_log_fichero($id_product,$nombre_fichero) { $row=''; if (!empty($id_product) && !empty($nombre_fichero)) { $sql = "select fecha_modificacion, id_attachment from log_import_manuales where id_producto=".$id_product." and nombre_fichero='".$nombre_fichero."'" ; $row= Db::getInstance()->getRow($sql); } return $row; } //Añade las imagenes de la tabla de log de las imagenes function add_image_to_log($fecha_imagen, $nombre_imagen,$id_product,$id_imagen){ $sql = "insert into log_import_imagenes values (null,".$id_product.",".$id_imagen.",'".$nombre_imagen."','".$fecha_imagen."')" ; return Db::getInstance()->Execute($sql); } //Añade los ficheros a la tabla de log de las ficheros function add_ficheros_to_log($fecha_fichero, $nombre_fichero,$id_product,$id_attachment){ $sql = "insert into log_import_manuales values (null,".$id_product.",".$id_attachment.",'".$nombre_fichero."','".$fecha_fichero."')" ; return Db::getInstance()->Execute($sql); } // borramos del log los ficheros function delete_ficheros_to_log($id_attachment,$id_product) { if (!empty($id_attachment)){ // si la imagen existe la borramos $sql = "delete from log_import_manuales where id_attachment=".$id_attachment." and id_producto=".$id_product ; Db::getInstance()->Execute($sql); } } //Recuepera el id_imegen que hay que borrar function get_image_to_delete($tab_imagenes_productos,$id_producto){ $id_imagenes=''; $rows=''; foreach ($tab_imagenes_productos as $key=> $imagenes) { $id_imagenes.=$imagenes.","; } $id_imagenes.='0'; $sql = "select id_imagen from log_import_imagenes where id_producto=".$id_producto." and id_imagen not in (".$id_imagenes.") " ; $rows=Db::getInstance()->ExecuteS($sql); return $rows ; } function addLog($txt,$filename) { if (!file_exists($filename)) file_put_contents($filename, ""); file_put_contents($filename,$txt." \r\n".file_get_contents($filename)); } // borramos del log function delete_image($id_image,$id_product,$principal) { // Borramos del log if ($principal && empty($id_image) ) { $image = Product::getCover($id_product) ; $id_image=$image['id_image']; } if (!empty($id_image)){ // si la imagen existe la borramos $image = new Image($id_image); $image->delete(); $sql = "delete from log_import_imagenes where id_imagen=".$id_image." and id_producto=".$id_product ; Db::getInstance()->Execute($sql); } } function addCategoriestoproducto($tab_categories ,$id_product) { $product_cats = array(); foreach ($tab_categories as $key=>$new_id_categ) { $product_cats[] = array( 'id_category' => (int)$new_id_categ, 'id_product' => (int)$id_product, 'position' => 1, ); } Db::getInstance()->insert('category_product', $product_cats); return true; } Muchas gracias a tod@s Edited August 27, 2020 by jat un ajuste (see edit history) Link to comment Share on other sites More sharing options...
RCTSH Posted October 28, 2020 Share Posted October 28, 2020 buenos dias yo estoy ultimamente con errores a ala hora de improtar mediante el asisten, que si pagina no encontrada que si no has subido un fichero. si son mas de 1000 productos se cuelta con lo que estoy emocionado tras encontrar tu hilo . me podrias decir donde debo meter ese script para que realice la funcion? Link to comment Share on other sites More sharing options...
jat Posted October 28, 2020 Author Share Posted October 28, 2020 il y a 2 minutes, RCTSH a dit : buenos dias yo estoy ultimamente con errores a ala hora de improtar mediante el asisten, que si pagina no encontrada que si no has subido un fichero. si son mas de 1000 productos se cuelta con lo que estoy emocionado tras encontrar tu hilo . me podrias decir donde debo meter ese script para que realice la funcion? Hola @RCTSH yo lo utilizo en la raíz en la carpeta principal donde tienes las instalación de ps. Que versión de PS tienes? Link to comment Share on other sites More sharing options...
RCTSH Posted October 28, 2020 Share Posted October 28, 2020 1.7.6.4 con warehouse 4.34 Link to comment Share on other sites More sharing options...
elenaso Posted December 7, 2020 Share Posted December 7, 2020 Sé que ha pasado mucho tiempo y que hay muchas respuestas, pero he encontrado una forma más óptima de resolver el problema de la carga de imágenes sin tener que copiar una función de PS, si a alguien le sirve, ahí va: El problema de este script está en que en el constructor de AdminImportController, necesita tener el $_POST ya cargado, sino, habrá variables que no encuentre. Por lo tanto, la solución a este problema de que no funciona la carga de imágenes simplemente se resuelve cambiando estas líneas: $import=new AdminImportController(); loadProductsPost(); $import->productImport(); Por estas: loadProductsPost(); $import=new AdminImportController(); $import->productImport(); Sencillamente se cambia el orden. De este modo, el $_POST se carga en loadProductsPost() y al llamar al constructor ya tiene el $_POST cargado. Haciéndolo de este modo, a mi me funciona pasando en el CSV la ruta de las imágenes separadas por comas, como texto simple, tal que así: "https://midominio.com/carpeta_de_mis_imagenes/imagen1.jpg,https://midominio.com/carpeta_de_mis_imagenes/imagen2.jpg" Además, para que regenere las imágenes (cree las miniaturas necesarias), tendremos que pasarle por $_POST el valor "regenerate" a 0, esto lo hago en el loadProductsPost, tal que así: function loadProductsPost() { $_POST = array ( 'tab' => 'AdminImport', 'truncate'=>'0', // Eliminar todas las productos antes de importar 'forceIDs' => '0', // Si activas esta opción, los números ID de tus objetos importados se utilizarán tal cual. Si no la activas, se ignorarán los números de ID importados y, en su lugar, PrestaShop creará números de ID que se incrementarán automáticamente para todos los elementos importados. 'skip' => '0', // líneas a saltar del csv 'csv' => ARCHIVO_DESTINO, // nombre del archivo csv a importar 'convert' => '', 'regenerate' => '0', // 0: regenera miniaturas | 1: no regenera miniaturas 'entity' => '1', // Productos = 1 'iso_lang' => 'es', 'match_ref' => '1', // Si está activado, ¡la referencia del producto TIENE que ser única! 'separator' => DELIMITADOR_CAMPOS_CSV, // separador de campo 'multiple_value_separator' => ',', // separador de valor múltiple 'import' => '1', 'type_value' => array ( 0 => 'reference', 1 => 'name', 2 => 'category', 3 => 'id_tax_rules_group', 4 => 'ean13', 5 => 'available_for_order', 6 => 'online_only', 7 => 'show_price', 8 => 'condition', 9 => 'customizable', 10 => 'uploadable_files', 11 => 'text_fields', 12 => 'is_virtual', 13 => 'shop', 14 => 'manufacturer', 15 => 'date_add', 16 => 'active', 17 => 'image', 18 => 'image_alt', 19 => 'delete_existing_images', 20 => 'minimal_quantity', 21 => 'unity', 22 => 'unit_price_ratio', 23 => 'quantity', 24 => 'wholesale_price', 25 => 'price_tex', 26 => 'unit_price'), ); } Espero que a alguien le sirva. Las pruebas las he hecho en un PS 1.7.6.5 Link to comment Share on other sites More sharing options...
jat Posted December 8, 2020 Author Share Posted December 8, 2020 Il y a 11 heures, elenaso a dit : Sé que ha pasado mucho tiempo y que hay muchas respuestas, pero he encontrado una forma más óptima de resolver el problema de la carga de imágenes sin tener que copiar una función de PS, si a alguien le sirve, ahí va: Muchas gracias @elenaso es de actualidad, nunca pensé que este hilo/post pudiera ser útil. En cuanto tenga tiempo, actualizo los archivos y los pruebo en las últimas versiones de PS y os lo paso despues 😉 Link to comment Share on other sites More sharing options...
Aldeag Posted January 13, 2021 Share Posted January 13, 2021 Hola: me hice mi propia página con Prestashop desde la versión 1.4 y ya tengo la 1.7.7 (hace unos días cumplí 10 años en este foro) Ni soy programador ni tengo idea de php, bastante hago con subir módulos y trastear archivos por FTP y si acaso editando (copia y pega) dichos archivos con aportaciones de otros foreros. Estoy interesado en subir y actualizar productos mediante csv y ahora he llegado a este hilo desde otro. ¿Habrá la posibilidad de disponer de un módulo para añadir/actualizar productos mediante ficheros proporcionados por mi proveedor? 1 Link to comment Share on other sites More sharing options...
elenaso Posted January 14, 2021 Share Posted January 14, 2021 16 hours ago, Aldeag said: Hola: me hice mi propia página con Prestashop desde la versión 1.4 y ya tengo la 1.7.7 (hace unos días cumplí 10 años en este foro) Ni soy programador ni tengo idea de php, bastante hago con subir módulos y trastear archivos por FTP y si acaso editando (copia y pega) dichos archivos con aportaciones de otros foreros. Estoy interesado en subir y actualizar productos mediante csv y ahora he llegado a este hilo desde otro. ¿Habrá la posibilidad de disponer de un módulo para añadir/actualizar productos mediante ficheros proporcionados por mi proveedor? Hola @aldeag, entiendo que no tienes un programa TPV local (en tienda física por ejemplo), entonces, si lo que te envían son archivos (CSVs por ejemplo), para mi la mejor solución ha sido el script que explicamos aquí. Si sigues los pasos no es complejo aunque no seas programador. Otra solución es hacer la importación de forma manual desde el backoffice de PrestaShop, dependiendo de tu caso podría servirte. Lo engorroso de este proceso es que es tienes que subir tú los ficheros de forma manual. Link to comment Share on other sites More sharing options...
Aldeag Posted January 14, 2021 Share Posted January 14, 2021 Mi tpv físico es muy antiguo y mis proveedores me facilitan archivos csv. Más o menos me aclaro con subir los csv a Prestashop desde en Backoffice. Así que ando buscando la opción TPV con Prestashop para prescindir de mi antiguo TPV y no me aclaro con las soluciones que encuentro. Y si usara ese script ¿como se utiliza? Link to comment Share on other sites More sharing options...
elenaso Posted January 14, 2021 Share Posted January 14, 2021 4 hours ago, Aldeag said: Mi tpv físico es muy antiguo y mis proveedores me facilitan archivos csv. Más o menos me aclaro con subir los csv a Prestashop desde en Backoffice. Así que ando buscando la opción TPV con Prestashop para prescindir de mi antiguo TPV y no me aclaro con las soluciones que encuentro. Y si usara ese script ¿como se utiliza? Si vas a cambiar el TPV, mejor haz esto primero. Hay algunos TPVs que ya te ofrecen módulos para PrestaShop. Si no tienen módulo para conectar con PS, los archivos que te pasen serán diferentes y tendrás que volver a cambiar el script. Así que si estás pensando en cambiar, yo haría eso primero. Para usar el script, básicamente crea un archivo PHP con el siguiente contenido (este es solo para productos simples, sin combinaciones): loadProductsPost(); $import=new AdminImportController(); $import->productImport(); function loadProductsPost() { $_POST = array ( 'tab' => 'AdminImport', 'truncate'=>'0', // Eliminar todas las productos antes de importar 'forceIDs' => '0', // Si activas esta opción, los números ID de tus objetos importados se utilizarán tal cual. Si no la activas, se ignorarán los números de ID importados y, en su lugar, PrestaShop creará números de ID que se incrementarán automáticamente para todos los elementos importados. 'skip' => '0', // líneas a saltar del csv 'csv' => ARCHIVO_DESTINO, // nombre del archivo csv a importar 'convert' => '', 'regenerate' => '0', // 0: regenera miniaturas | 1: no regenera miniaturas 'entity' => '1', // Productos = 1 'iso_lang' => 'es', 'match_ref' => '1', // Si está activado, ¡la referencia del producto TIENE que ser única! 'separator' => DELIMITADOR_CAMPOS_CSV, // separador de campo 'multiple_value_separator' => ',', // separador de valor múltiple 'import' => '1', 'type_value' => array ( 0 => 'reference', 1 => 'name', 2 => 'category', 3 => 'id_tax_rules_group', 4 => 'ean13', 5 => 'available_for_order', 6 => 'online_only', 7 => 'show_price', 8 => 'condition', 9 => 'customizable', 10 => 'uploadable_files', 11 => 'text_fields', 12 => 'is_virtual', 13 => 'shop', 14 => 'manufacturer', 15 => 'date_add', 16 => 'active', 17 => 'image', 18 => 'image_alt', 19 => 'delete_existing_images', 20 => 'minimal_quantity', 21 => 'unity', 22 => 'unit_price_ratio', 23 => 'quantity', 24 => 'wholesale_price', 25 => 'price_tex', 26 => 'unit_price'), ); } En la función, es donde tendrás que hacer los ajustes necesarios para que funcione con tus archivos y los campos que le pasas. Yo envío esos campos, pero puedes borrar o añadir otros. Los valores a configurar tienen comentarios explicando para qué son. Si te lías con esto quizá sea mejor que hables con alguna programadora o programador que te lo personalice. 1 Link to comment Share on other sites More sharing options...
alexloma Posted January 15, 2021 Share Posted January 15, 2021 (edited) Yo aporté este código para versiones 1.7 y funcionar funciona.....pero es un dolor hacerlo funcionar. Un csv puede venir con los datos de cualquier manera (a veces parece que lo haya generado un psicópata) y primero hay que realizar un script capaz de obtener esos datos y generar en base a ellos, otro csv que cumpla con el formato que espera PS. Una vez tenemos ese csv es cuando se aplica sobre él lo de arriba. Dependiendo de la versión de PS, puede funcionar o tener que readaptarlo. Para los que no andan muy sueltos en php lineal, o simplemente no conocen este lenguaje, pueden encontrarse con montones de problemas para hacer que esto funcione, por no hablar de que el servidor debe de estar también muy bien afinado. Hay una aplicación por ahí llamada Store Manager https://www.prestashopmanager.com/es/ que es una maravilla y no precisa de ningún conocimiento de php. Se puede descargar una versión de prueba de 14 días totalmente operativa (Si nunca cierras el programa instalándolo por ejemplo en una máquina virtual, funciona para siempre) El problema es su precio. Si no fuera porque sé php y no me dedico al tráfico de crack, esa sería la herramienta que usaría para las importaciones. Fácil, rápido, seguro y cómodo. Edited January 15, 2021 by alexloma (see edit history) Link to comment Share on other sites More sharing options...
Miquel2 Posted March 15, 2021 Share Posted March 15, 2021 Hola, gracias por el aporte que habéis hecho en este post para poder importar productos al PrestaShop. Estoy utilizando el código que puso @alexloma en mi PrestaShop multitienda v.1.7.7.0 y funciona muy bien. Pero veo que no actualiza las tablas de ps_product y ps_stock_mvt. Sí que se actualizan cuando utilizas la función importar del menú opciones avanzadas del PrestaShop. He estado mirando el código y buscando información sobre como poder decir a PrestaShop que actualice estas dos tablas, pero no consigo encontrar una solución. ¿Alguien se ha encontrado con este problema y ha podido solventarlo? Muchas gracias Saludos Link to comment Share on other sites More sharing options...
elenaso Posted June 28, 2023 Share Posted June 28, 2023 ¡Hola! ¿Alguien ha probado este script en Prestashop 8? Tengo problemas con la carga de imágenes :S Link to comment Share on other sites More sharing options...
elenaso Posted June 28, 2023 Share Posted June 28, 2023 Solucionado! Me faltaba incluir este par de líneas antes de llamar a loadProductsPost(): include(_PS_ADMIN_DIR_.'/functions.php'); require_once(_PS_ADMIN_DIR_.'/init.php'); $context = Context::getContext(); Link to comment Share on other sites More sharing options...
RCTSH Posted June 29, 2023 Share Posted June 29, 2023 a ver si pillo tiempo yo tb este verano y lo pruebo Link to comment Share on other sites More sharing options...
elenaso Posted June 30, 2023 Share Posted June 30, 2023 Estoy intentando actualizar los productos con este script pero las categorías se me machacan siempre, aunque no le mande ese dato en el CSV. Y esto no me permite poder afinarlas en el PrestaShop. ¿Alguien ha conseguido actualizar los productos con loadProductsPost() sin modificar las categorías? Gracias! Link to comment Share on other sites More sharing options...
JulioMarichales02 Posted November 14, 2023 Share Posted November 14, 2023 On 5/14/2019 at 1:19 PM, alexloma said: La función copyImg es la que se encarga de todo. Suponiendo que tienes un artículo con un id = 555 y quieres añadirle una imagen que está en "http://localhost/img/imagen1.jpg" o "https://tudominio.com/img/imagen1.jpg" la llamada a la función sería: $url = "http://localhost/img/imagen1.jpg"; $image = new Image(); $image->id_product = (int) 555; $image->position = Image::getHighestPosition(555) + 1; $image->cover = true; $image->add(); if (!copyImg(555, $image->id, $url, 'products', !Tools::getValue('regenerate'))) { $image->delete(); } Dependiendo del resto de tu código y como realizas el bucle, igual tienes que colocar este código en otro lugar mas adecuado. Si el contenido de $url tiene más de una imagen, estás van separadas por comas. Y como haria para subir una imagen por cada producto?, ya que aqui por lo visto puedo subir solo uno, o asi yo lo veo. Link to comment Share on other sites More sharing options...
JulioMarichales02 Posted November 14, 2023 Share Posted November 14, 2023 On 3/11/2020 at 11:05 AM, el_charlie said: Ya funciona sin necesidad de iniciar sesión, no es necesario el init.php. Aquí el código completo sólo para productos e importando imágenes cuyo nombre de archivo es la [referencia del producto].jpg y en mi caso están en la carpeta /imgs_prods/. <?php header("Content-Type: text/html;charset=utf-8"); ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); if (!defined('_PS_ADMIN_DIR_')) define('_PS_ADMIN_DIR_', getcwd()); include(_PS_ADMIN_DIR_.'/../config/config.inc.php'); include(_PS_ADMIN_DIR_.'/functions.php'); include_once '../controllers/admin/AdminImportController.php'; set_time_limit(0); function copyImg($id_entity, $id_image, $url, $entity = 'products', $regenerate = true) { $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; case 'manufacturers': $path = _PS_MANU_IMG_DIR_ . (int) $id_entity; break; case 'suppliers': $path = _PS_SUPP_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 makes the import slower. // Just hide the warning, the processing will be the same. if (Tools::copy($url, $tmpfile)) { ImageManager::resize($tmpfile, $path . '.jpg'); $images_types = ImageType::getImagesTypes($entity); if ($regenerate) 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; } $import = New AdminImportController(); loadProductsPost(); $import->productImport(); function loadProductsPost() { $_POST = array ( 'tab' => 'AdminImportController', 'truncate'=>'0', 'forceIDs' => '1', 'match_ref' => '1', 'skip' => '0', 'csv' => '../../../dropbox/nuevos.csv', // Por comodidad se almacena el archivo en una carpeta que no es adminxxx/import 'entity' => '1', 'separator' => ';', 'multiple_value_separator' => ',', 'iso_lang' => 'es', 'convert' => '', 'import' => '1', "type_value" => array( 0 => 'id', //el archivo tiene el ID que será necesario para importar imágenes 1 => 'reference', 2 => 'name', 3 => 'quantity', 4 => 'price_tex', 5 => 'category' ), ); } $file_handle = fopen("../../dropbox/nuevos.csv", "r"); //la ruta remota del CSV ó TXT. El mismo archivo que importamos while (!feof($file_handle)) { $line = fgets($file_handle); echo $line."<br>"; //para mostrar el contenido del archivo que importamos $linea = explode(";",$line); if (file_exists('../../imgs_prods/'.$linea[1].'.jpg')){ $url = "https://miurl.com/imgs_prods/".$linea[1].".jpg"; $image = new Image(); $image->id_product = (int) $linea[0]; $image->position = Image::getHighestPosition($linea[0]) + 1; $image->cover = true; $image->add(); if (!copyImg($linea[0], $image->id, $url, 'products', !Tools::getValue('regenerate'))) { $image->delete(); } } } fclose($file_handle); Tools::clearSmartyCache(); Tools::clearXMLCache(); Media::clearCache(); Tools::generateIndex(); ?> Puedes explicarme a detalle como subes la imagen? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now