28 Novembre, 2018 | Di

PrestaShop: come effettuare l'importazione incrementale di un catalogo prodotti

PrestaShop: come effettuare l'importazione incrementale di un catalogo prodotti

PrestaShop è una soluzione ecommerce pubblicata sotto licenza OSL (Open Software License) e sviluppata in linguaggio PHP con database MySQL. Semplice da usare grazie ai tanti moduli disponibili (anche gratuiti), offre un set completo di funzionalità che la rendono un’ottima soluzione per tutte le aziende che vendono beni fisici o digitali online con un catalogo di medio-piccole dimensioni.

Tra le varie funzioni integrate, PrestaShop consente l'accesso al suo database da applicazioni remote multipiattaforma tramite web service.

Di recente abbiamo soddisfatto l’esigenza di un cliente che, a partire da un file excel, aveva la necessità di importare un catalogo di N prodotti e di rendere le successive importazioni incrementali. Il catalogo esistente non è stato cancellato, bensì modificato con le “nuove” informazioni quando presenti, ovvero:

  • Codice prodotto
  • Nome
  • Descrizione
  • Categoria
  • Immagine
  • Casa Produttrice
  • Prezzo pieno
  • Prezzo scontato
  • Peso
  • Priorità (utile per dare un ordine ai prodotti sul frontend)
  • altro

La struttura del file in formato xlsx è stata concordata preventivamente con il cliente (colonne, valori obbligatori, ecc.) in modo da sviluppare un sistema di controllo e di validazione dei dati.

Come abbiamo reso possibile l'importazione incrementale del catalogo

Per realizzare questa funzionalità abbiamo sviluppato un piccolo applicativo che, successivamente all’importazione del file excel, aggiornasse il catalogo dei prodotti dell’ecommerce attraverso richieste al web service di PrestaShop.

L’importazione e il successivo aggiornamento del catalogo hanno rappresentato due distinte: 

  • Lettura del file in formato xlsx, caricato in una cartella raggiungibile con accesso FTP, e salvataggio dei dati nel database.
  • Lettura del database e creazione/aggiornamento dei prodotti tramite il web service di PrestaShop.

Nella prima fase, il nostro applicativo si è occupato della lettura e della validazione del file excel e successivamente del salvataggio dei dati in una tabella che permettesse l’elaborazione da un’altra risorsa (seconda fase). Per la lettura e l’analisi del file abbiamo utilizzato una libreria scritta interamente in PHP e completa di numerose funzionalità: PhpSpreadsheet

La libreria fornisce un set di classi che permettono di leggere e scrivere su una varietà di diversi formati di file.

Una volta installata nel nostro progetto tramite composer

composer require phpoffice/phpspreadsheet

Abbiamo incluso la libreria e abbiamo creato un'istanza di un nuovo oggetto Reader\Xlsx per la lettura del file in formato xlsx. Quindi, utilizzando il metodo load() dell’oggetto del lettore, abbiamo letto il file e lo abbiamo caricato in un oggetto Spreadsheet per poterlo analizzare e poter salvare i dati nel database.

require 'vendor/autoload.php';
 
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
 
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load(‘file_da_importare.xlsx’);

Abbiamo utilizzato il metodo setReadDataOnly(true) in quanto era necessario recuperare i valori e le formule delle celle del foglio di lavoro, evitando di caricare informazioni inutili come le informazioni di formattazione.

Nella seconda fase del progetto, l’applicativo doveva entrare in comunicazione con i servizi web di PrestaShop.

Per iniziare a utilizzare il web service è necessario creare e abilitare una chiave di autenticazione accedendo al Pannello di amministrazione nella sezione Parametri avanzati -> Webservice, che occorre specificare per riuscire a collegarsi al servizio web di PrestaShop.

 

PrestaShop: come effettuare l'importazione incrementale di un catalogo prodotti

Per lavorare con il suo web service, PrestaShop mette a disposizione una libreria PHP pronta all'uso: PSWebServiceLibrary.

Per utilizzare questa libreria è necessario installare e abilitare l’estensione cURL sul server.

Abbiamo creato una classe che si occupa di comunicare i dati dei prodotti importati al database dell’ecommerce attraverso il web service di PrestaShop, andando a inserire i prodotti nuovi e ad aggiornare quelli già presenti nel catalogo.

<?php
require_once "PSWebServiceLibrary.php";
 
class MyClass
{
  /**
   * Private istance of Prestashop Web Service.
   * @Object or null
   */
  private $ws = null;
 
  /**
   * Istance a webservice.
   * @return Mixed
   */
  private function getWebService()
  {
    if (!is_null($this->ws))
      return $this->ws;
 
    $this->ws = new PrestaShopWebservice($website = 'http://www.website.com/', $auth_key = '', $debug = false);
 
    return $this->ws;
  }
 
  /**
   * Retrive all info of a specific product
   * @param Integer ( id_product )
   * @return mixed
   */
  public function getProduct($id=null)
  {
    $product = array();
 
    if (!is_numeric($id))
      return;
 
    $ws = $this->getWebService();
    $opt['resource'] = 'products';
    $opt['id'] = $id;
    $xml = $ws->get($opt);
 
    foreach ($xml->children()->children() as $k=>$v)
    {
      if ($k=="name" || $k=="description" || $k=="description_short" || $k=="link_rewrite" || $k=="meta_title" || $k=="meta_description"||$k=="meta_keywords")
        $product[$k] = strip_tags((String)$v->language);
      else
        $product[$k] = $v;
    }
 
    return $product;
  }
 
  /**
   * Retrive all info of all products.
   * @return mixed
   */
  public function getProducts($filters)
  {
    $products = array();
 
    $ws = $this->getWebService();
    $opt['resource'] = 'products';
 
    if (is_array($filters) && !empty($filters))
      $opt['filter'] = $filters;
 
    $xml = $ws->get($opt);
 
    foreach ($xml->children()->children() as $product)
    {
      $id = (String)$product->attributes();
      $products[] = $this->getProduct($id);
      break;
    }
 
    return $products;
  }
 
  /**
   * Save new product on prestashop.
   * @param Array
   * @return Integer
   */
  public function insertProduct($item)
  {
    # Verify unique name
    $filters = array();
    $filters["reference"] = $item["reference"];
 
    $products = $this->getProducts($filters);
 
    # If product reference code already exists, update first array element.
    if (!empty($products))
      return $this->updateProduct($item, $products[0]["id"]);
 
    # Recovery blank schema
    $xml = $this->getSynopsis();
    $properties = $xml->children()->children();
 
    # Merge value
    foreach ($item as $key => $val) {
      if ($key=="name" || $key=="description" || $key=="description_short" || $key=="link_rewrite" || $key=="meta_title" || $key=="meta_description" || $key=="meta_keywords")
        $properties->{$key}->language[0][0] = $val;
      else
        $properties->{$key} = $val;
    }
 
    # Get WebService Instance
    $ws = $this->getWebService();
 
    # Add product to remote Prestashop
    $opt = array('resource' => "products");
    $opt['postXml'] = $xml->asXML();
    $xml = $ws->add($opt);
 
    $response = $xml->children()->children();
 
    if (isset($response->id))
      return (Integer)$response->id;
    else
      return false;
  }
 
  /**
   * Update product on prestashop.
   * @param Array
   * @param Integer ( id prestashop product )
   * @return Integer
   */
  public function updateProduct($item, $id=null)
  {
    $item['id'] = $id;
    $item['date_upd'] = date('Y-m-d H:i:s');
 
     # Recovery blank schema
    $xml = $this->getSynopsis();
    $properties = $xml->children()->children();
 
    # Merge value
    foreach ($item as $key => $val) {
      if ($key=="name" || $key=="link_rewrite" || $key=="description" || $key=="meta_title" || $key=="meta_description" || $key=="meta_keywords")
        $properties->{$key}->language[0][0] = $val;
      else
        $properties->{$key} = $val;
    }
 
    # Add product to remote Prestashop
    $opt = array('resource' => "products");
    $opt['id'] = $id;
    $opt['putXml'] = $xml->asXML();
 
    # Get WebService Instance
    $ws = $this->getWebService();
    $response = $ws->edit($opt);
    $response = $response->children()->children();
 
    if (isset($response->id))
      return (Integer)$response->id;
    else
      return false;
  }
 
  /**
   * Get schema for avaiable api.
   * @return Mixed
   */
  public function getSynopsis()
  {
    $ws = $this->getWebService();
    $opt['url'] =$this->website .'/api/products?schema=blank';
    $xml = $ws->get($opt);
 
    return $xml;
  }
}
 
?>

Nella classe è stata creata un’istanza dell’oggetto PrestaShopWebservice, in cui abbiamo indicato i tre parametri richiesti dal suo costruttore:

  • L’Url del negozio;
  • La chiave di autenticazione;
  • Un valore booleano, che indica se il web service deve utilizzare la sua modalità di debug.

L’applicativo legge i dati importati dall’importazione e, attraverso la classe che abbiamo scritto, aggiunge i nuovi prodotti e aggiorna le informazioni di quelli già presenti nel catalogo utilizzando i vari metodi delle risorse disponibili del web service (products, categories, ecc.)

Infine, abbiamo impostato un cron job che si occupa di eseguire il nostro applicativo con una cadenza periodica e automatizzata.

Se vuoi scoprire come usare PrestaShop per vendere online e aumentare il tuo fatturato, contattaci!