Como añadir un producto a Prestashop por código PHP

Como estamos viendo, cuando estamos desarrollando y programando un módulo para Prestashop necesitamos saber en ocasiones varios códigos diferentes y códigos que nos van a servir en algún momento del desarrollo del modulo que estamos programando, en esta ocasión vamos a ver como añadir un producto por medio del código y usando PHP
Lo normal y al principio del código lo que debemos verificar es si existe o no existe este producto, por supuesto para no duplicar información, la mejor manera es usando la referencia del producto, al poder usar 2 referencias, 1 usando la referencia propia y que usamos internamente, 2 la referencia del fabricante o distribuidor, debemos buscar el producto usando estas 2 opciones, recordando que las referencias también pueden estar en las combinaciones, pero esto lo veremos mas adelante.
En el ejemplo vamos a añadir el siguiente producto
El producto sera un array con esta información, el array se llama $producto
- Nombre : Cuadro acrílico – Dientes de león mullidos
- Referencia : A1-Acrylglasbild19
- Descripción y descripción corta
- Precio : 134.98 Sin Inpuestos
- Categoría : cuadros
- Peso : 1Kg
- Combinaciones : SI Usaremos un Array con estos datos
- Tamaño – 120×80 -> Referencia : A1-Acrylglasbild19 -> precio 134.98 sin impuestos -> Stock : 500
- Tamaño – 60×40 -> Referencia : A1-Acrylglasbild20 -> Precio 44.98 sin impuestos -> Stock : 500
- Imágenes : SI array con las url de las imágenes
- Características : NO
Función y código para buscar la referencia y si existe enviamos la variable Pexiste = true o false si no existe. esta funciona la vamos a usar en la primera linea de nuestro codigo, por lo cual necesitamos añadirla al principio de nuestro desarrollo
public function checkproduct($refp){ // estamos usando codigo dentro de un "class" clase, debemos usar public function
$reference =$refp;
//codigo para verificar referencia
$sqlid_product = "select * from "._DB_PREFIX_."product where reference = '".$reference."'";
$rowsidp = 0;
$rowsidp = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($sqlid_product);
if(count($rowsidp) > 0 ){ // comprobamos si tiene lineas
$pexiste = true; // Si existe
}else{
$pexiste = false; // No existe
}
return $pexiste; // devolvemos que existe o no existe
}
Una vez tenemos la función para verificar el producto, vamos por apartados y como añadiremos el producto al Prestashop
public function add_producto($producto){
$idproducto = 0 ;
$refp = $producto['Referencia'];
$pexiste = self::checkproduct($refp);
Ya tenemos verificado si el producto existe, por lo que añadimos un if
if($pexiste){
$productoadd = null;
}else{
// principio de Add
$productoadd = array();
//Aqui vamos a ir añadiendo todo el codigo
//fin product->add
}
En el siguiente codigo vamos a añadir las variables que vamos a usar mas adelante, como el idioma predeterminado, las tiendas, y otras
$id_lang = Configuration::get('PS_LANG_DEFAULT'); // buscamos el ID del idioma
$shops = Shop::getShops($active = true, $id_shop_group = null, $get_as_list_id = false); // vemos las tiendas que tiene el prestashop
A partir de esto añadiremos el código siguiente
Creamos un nuevo producto sin ID
Generamos la url usando la función SEO para convertir los espacios, acentos y caracteres no compatibles
$product = new Product(); //añadimos un nuevo producto
$product->name = array($id_lang => $producto['nombre']);
$seo = self::seo_friendly_url($producto['nombre']); // función externa para convertir el nombre en formato URL
$product->link_rewrite = array($id_lang => $seo);
Y lo añadimos al Prestashop con un IF para asegurarnos
if($product->add()){
//seguimos con el código aqui
}
Ahora añadimos todos los datos del producto, peso, precio, categoria etc…
$id_product = $product->id;
$product->reference = $producto['referencia']; //añadimos referencia
$product->ean13 = ""; // añadimos ean13
$product->weight = 1; // añadimos peso
$product->price = (float)str_replace(',','.',$producto['precio']) ; //añadimos precio cambiando la , por un .
//buscamos las categorias de la tienda
$categorias = Category::getSimpleCategories($id_lang);
$encontrada = false; // ponemos que no existe la categoria antes de buscarla
Si es necesario vamos a comprobar si existe la categoria y si no existe la añadimos
$catparent = 2; // indicamos que la categoria padre es la 2 que siempre suele ser "home"
$cat = $producto['categoria'];
foreach ($categorias as $categoria){
if ($cat == $categoria['name']){
$encontrada = true;
$catparent = $categoria["id_category"];
$catpro = $categoria["id_category"];
break;
}
if ($encontrada == false){
$category = new Category();
$category->name = array($id_lang => $cat);
$seo = self::seo_friendly_url($cat);
$category->link_rewrite = array($id_lang => $seo);
$category->id_parent = $catparent;
$category->is_root_category = false;
$category->add();
$catpro = $category->id;
$catparent = $category->id;
$product->addToCategories(array($catpro));
$product->id_category = $catpro;
$product->id_category_default = $catpro;
$product->save();
}
}
Ya tenemos añadido el producto, hemos añadido la categoría y la hemos asociado con nuestro nuevo producto, seguimos añadiendo datos e información del producto
$product->addToCategories(array($catpro));
$product->id_category = $catpro;
$product->id_category_default = $catpro;
$product->minimal_quantity = 1;
$product->price = ((float)str_replace(',','.',$producto['precio'])) ;
Ahora vamos a añadir la descripción corta y la descripción larga, como vamos a usar el mismo texto para las dos cosas, debemos reducir el tamaño del texto para la descripción corta y dejar todo el texto para la larga, por lo que vamos a usar la orden if y comprobar la longitud del texto, una vez tenemos la longitud, cortamos la descripcion en el siguiente «.» y la añadimos a la descripción corta
if (strlen($producto['descripcion']) > 50 ){
$pos = strpos($producto['descripcion'], ".",10);
}
if (strlen($producto['descripcion']) > 150 ){
$pos = strpos($producto['descripcion'], ".",100);
}
if (strlen($producto['descripcion']) > 250 ){
$pos = strpos($producto['descripcion'], ".",200);
}
if (strlen($producto['descripcion']) > 350 ){
$pos = strpos($producto['descripcion'], ".",300);
}
$descrip = substr($producto['descripcion'], 0, $pos);
$product->description_short = $descrip;
$product->description = $producto['descripcion'];
Seguimos añadiendo datos al producto
$product->advanced_stock_management = 0; $product->show_price = 1; $product->on_sale = 0; $product->unit_price = $product->price; $product->weight = (float)(1); $product->redirect_type = '404'; $product->minimal_quantity = 1; $product->show_price = 1; $product->on_sale = 0; $product->minimal_quantity = 1; $product->available_for_order = 1; $product->online_only = 1; $product->unit_price = $product->price; $product->active = 0; // dejamos el producto NO activado, mejor activar despues manualmente $product->save() // Guardamos los datos del producto y continuamos
Una vez se ha añadido toda la información vamos a añadir las combinaciones del producto.
- Tamaño – 120×80 -> Referencia : A1-Acrylglasbild19 -> precio 134.98 sin impuestos -> Stock : 500
- Tamaño – 60×40 -> Referencia : A1-Acrylglasbild20 -> Precio 44.98 sin impuestos -> Stock : 500
Como añadimos combinaciones a un producto por medio de PHP y codigo :
Lo primero que debemos hacer es añadir el nombre del atributo y por lo tanto de la combinación, en este caso usaremos Tamaño
$nameatt = 'tamaño'; //usamos una variable para el nombre del atributo para las combinaciones
foreach ($producto['combinaciones'] as $combinacion){
$linc = 0; // añadimos un contador, si es 0 sera la combinacion por defecto y si es mas de 0 no sera la combinacion por defecto
$valoratt = $combinacion['tamaño']; // añadimos a un variable el valor
$idattt = self::check_option($nameop,$nameg); // usamos una función para comprobar el ID del atributo, o añadir tanto el atributo como el valor del atributo si fuera necesario
$refp = $combinacion['referencia'];
$combinationAttributes = array();
$combinationAttributes[] = $idattt;
$qty = $combinacion['stock'];
$precioproducto = $product->price;
$precioatt = (float)str_replace(',','.',$combinacion['precio']);
// importante, vamos a ver si la combinación es mas cara o mas barata que el propio producto
if ($precioproducto > $precioatt){
$precio = $precioatt - $precioproducto;
}
if ($precioproducto > $precioatt){
$precio = $precioatt - $precioproducto;
}
if($linc == 0){
$defaultc = 1;
}else{
$defaultc = 0;
}
$idProductAttribute = $product->addProductAttribute(
0, //price
(float)0, //weight combination
0, //unit_impact
null , //ecotax
(int)$qty, //quantity
"", //id_images
$refp, //reference
$defaultc, //default
NULL, //location
NULL //upc
);
$product->addAttributeCombinaison($idProductAttribute,$combinationAttributes); //añadirmos la combinación
$linc++;
}
Finalmente volvemos a guardar el producto y añadimos las imágenes o imagen
$product->save();
$cover = true;
$id_product =
if(self::add_images($id_product,$producto,$cover)){}
}//fin de la function add_producto
public function add_images($id_product,$producto,$cover){
$idpadd = $id_product;
$imageid = false;
$shops = Shop::getShops($active = true, $id_shop_group = null, $get_as_list_id = false);
$imagenes = array ();
$lincover = 0;
if($lincover == 0){
$cover = true;
}else{
$cover = false;
}
foreach ($producto['imagenes'] as $image){
$imagenes[] = array (
'url' => $image['url'],
'cover' => $cover,
);
$lincover++;
}
foreach ($imagenes as $imagen){
$id_lang = Configuration::get('PS_LANG_DEFAULT');
$url = $imagen['url'];
$image = new Image();
$image->id_product = $id_product;
$image->position = Image::getHighestPosition($id_product) + 1;
if (($image->validateFields(false, true)) === true && ($image->validateFieldsLang(false, true)) === true && $image->add()){
$copy = self::copyImg($idpadd, $image->id, $url, 'products', true);
if (!$copy){
$image->delete();
}
$imageid = $image->id;
}
if($imagen['cover'] == true){
$image->cover = $image->id;
}
$image->save();
}
$imagenes = Image::getImages($id_lang, $id_product);
$covimg = 0;
foreach ($imagenes as $imagen){
$shops = Shop::getShops($active = true, $id_shop_group = null, $get_as_list_id = false);
foreach ($shops as $shop){
if($cover == $imagen['id_image']){
$covimg = 1;
}else{
$covimg = 0;
}
if ($covimg == 0){
$sqlimshop = "INSERT INTO "._DB_PREFIX_."image_shop (`id_product`, `id_image`, `id_shop`, `cover`) VALUES
(".$idpadd.",".$imagen['id_image'].",".$shop['id_shop'].",0)";
if (Db::getInstance()->execute($sqlimshop)){}
}
}
}
return true;
}
FUNCIONES ADICIONALES AL CÓDIGO
function copyImg
public function copyImg($id_entity, $id_image = null, $url, $entity = 'products')
{
//añadimos la imagen que nos envia el codigo desde WS al prestashop
$tmpfile = tempnam(_PS_TMP_IMG_DIR_, 'ps_import');
$watermark_types = explode(',', Configuration::get('WATERMARK_TYPES'));
$image_obj = new Image($id_image);
$path = $image_obj->getPathForCreation();
$url = str_replace(' ', '%20', trim($url));
if (!ImageManager::checkImageMemoryLimit($url))
return false;
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;
}
function seo_friendly_url
function seo_friendly_url($string){
//De nombre del producto a url, limpieza
$string = str_replace(array('[\', \']'), '', $string);
$string = preg_replace('/\[.*\]/U', '', $string);
$string = preg_replace('/&(amp;)?#?[a-z0-9]+;/i', '-', $string);
$string = htmlentities($string, ENT_COMPAT, 'utf-8');
$string = preg_replace('/&([a-z])(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig|quot|rsquo);/i', '\\1', $string );
$string = preg_replace(array('/[^a-z0-9]/i', '/[-]+/') , '-', $string);
return strtolower(trim($string, '-'));
}
Function check_feature
public function check_feature($ncar){
//Comprobamos la caracteristica y su nombre
$id_lang = Configuration::get('PS_LANG_DEFAULT');
$idiomas = Language::getLanguages($active = true, $id_shop = false);
$sqlfe ="select id_feature as id from "._DB_PREFIX_."feature_lang where name = '".(string)$ncar."' and id_lang = ".$id_lang."";
$rfe = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($sqlfe);
if(count($rfe) == 0){
$feature = new Feature();
foreach ($idiomas as $idioma){
$id_lang = $idioma['id_lang'];
$feature->name[$id_lang] = $ncar;
}
$feature->position = Feature::getHigherPosition() + 1;
$feature->add();
return $feature->id;
}else{
return $rfe[0]['id'];
}
}
function check_option
public function check_option($nameop,$nameg){
//Comprobamos el atributo/opcion del producto
$id_lang = Configuration::get('PS_LANG_DEFAULT');
$atributos = Attribute::getAttributes($id_lang, $not_null = false);
$existe = false;
if (count($atributos)> 0) {
foreach ($atributos as $atributo){
if($atributo['name'] == $nameop){
$idattt = $atributo['id_attribute'];
$existe = true;
break;
}else{
$existe = false;
}
}
}
if(!$existe){
//Si no existe lo añadimos
$idattt = self::addatt($nameop,$nameg);
}
//devolvemos el id del atributo, que ya existia o añadido
return $idattt;
}
function addatt
public function addatt($nameop,$nameg){
// Añadimos el atributo, comprobanco que el grupo de atributos exista o lo creamos
$id_lang = Configuration::get('PS_LANG_DEFAULT');
$idiomas = Language::getLanguages($active = true, $id_shop = false);
$nameg = 'tamaño';
$existegrupo = false;
$gruposatt = AttributeGroup::getAttributesGroups($id_lang);
foreach ($gruposatt as $grouptt){
if($grouptt['name'] == $nameg){
$idgroupr = $grouptt["id_attribute_group"];
$existegrupo = true;
break;
}else{
$existegrupo = false;
}
}
if(!$existegrupo){
//Si no existe el grupo lo añadimos
$newGroup = new AttributeGroup();
foreach ($idiomas as $idioma){
$id_lang = $idioma['id_lang'];
$newGroup->name[$id_lang] = (string)$nameg;
$newGroup->public_name[$id_lang] = (string)$nameg;
}
$newGroup->group_type = 'select';
$newGroup->add();
//una vez añadido lo asignamos al atributo que añadimos - Si no existe el grupo no debe existir el atributo
$idgroupr = $newGroup->id ;
$newAttribute = new Attribute();
foreach ($idiomas as $idioma){
$id_lang = $idioma['id_lang'];
$newAttribute->name[$id_lang] = $nameop;
}
$newAttribute->id_attribute_group = $idgroupr ;
$newAttribute->add();
$idattt = $newAttribute->id;
}else{
//Al existir el grupo añadimos el atributo
$newAttribute = new Attribute();
foreach ($idiomas as $idioma){
$id_lang = $idioma['id_lang'];
$newAttribute->name[$id_lang] = $nameop;
}
$newAttribute->id_attribute_group = $idgroupr;
$newAttribute->add();
$idattt = $newAttribute->id;
}
return $idattt;
}