2q5lcw
Last Updated: August 08, 2017
·
20.48K
· croustibat
Tinyterror

PRESTASHOP background/cron CSV products import

Here's useful code I use on one of my project with a multi-shop setup PRESTASHOP (v1.5.6) to automatically import product for each shops. First i generate the CSV file with the product data i want to insert or update, then the script log in like you would do on the prestashop admin area and POST the data on the AdminImport controller.

Here is the background/cron script and below the curl wrapper class (You can replace the php curl wrapper of course)


require_once ('class.PSRequest.php'); //see class source code below

$shopID = "myfirstshop"; // ID or unqiue name of the target shop
$products = ...; // your set of product object or array

// CSV first line for products
$csv = "id;Active (0/1);Name*;Categories (x,y,z,...);Price tax excluded;Tax rules id;Wholesale price;On sale (0/1);Discount amount;Discount percent;Discount from (yyy-mm-dd);Discount to (yyy-mm-dd);Reference #;Supplier reference #;Supplier;Manufacturer;EAN13;UPC;Ecotax;Weight;Quantity;Short description;Description;Tags (x,y,z,...);Meta-title;Meta-keywords;Meta-description;URL rewritten;Text when in-stock;Text if back-order allowed;Available for order (0 = No, 1 = Yes);Product creation date;Show price (0 = No, 1 = Yes);Image URLs (x,y,z,...);Delete existing images (0 = No, 1 = Yes);Feature (Name:Value:Position);Available online only (0 = No, 1 = Yes);Condition (new,used,refurbished);ID / Name of shop".PHP_EOL;

foreach ($products as $prod) {
        // fill in the csv string with your datas
       $csv .= $prod->id.";1;".html_entity_decode($prod->name)......$shopID.PHP_EOL;
}

$now=time();
$csvname = $now."-PRODUCTS-".$shopID.".csv";
$file = YOUR_PATH.$csvname;
file_put_contents($file, $csv);

echo "Write file : ".$file.PHP_EOL;

echo "Login on Prestashop Admin area...".PHP_EOL;   
$adminUrl = "http://YOUR_PS_ADMIN/adminXXXX/"; // change that with your admin url of course
$request = new PSRequest();
$request->setCookiFileLocation(__DIR__.'/PScookie.txt');

$request->setPost(array("email" => "YOUR_ADMIN_EMAIL","passwd" => "YOUR_ADMIN_PASS", "submitLogin" => "Connexion")); // you must be a super admin
$request->call($adminUrl."index.php?controller=AdminLogin");

echo "Get token...".PHP_EOL;

$request->call($adminUrl."index.php?controller=AdminImport");
list(,$response) = explode("\r\n\r\n", $request->_webpage, 2);
preg_match("/token=([a-z0-9]+)/", $response, $matches);
$token = $matches[1];

echo "Token : ".$token.PHP_EOL;

// Send POST datas just like the admin form would do it, those datas depends on what you want to do : check the import admin page.
$request->setPost(array(
    "controller"               => "AdminImport",
    "token"                    => $token,
    "skip"                     => 1,
    "csv"                      => $csvname,
    "convert"                  => '',
    "regenerate"               => '',
    "entity"                   => 1, //1 is for products import
    "iso_lang"                 => "fr",
    "truncate"                 => 0,
    "forceIDs"                 => 1,
    "match_ref"                => 1,
    "separator"                => ";",
    "multiple_value_separator" => ",",
    "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', 19 => 'weight', 20 => 'quantity', 21 => 'description_short', 22 => 'description', 23 => 'tags', 24 => 'meta_title', 25 => 'meta_keywords', 26 => 'meta_description', 27 => 'link_rewrite', 28 => 'available_now', 29 => 'available_later', 30 => 'available_for_order', 31 => 'date_add', 32 => 'show_price', 33 => 'image', 34 => 'delete_existing_images', 35 => 'features', 36 => 'online_only', 37 => 'condition', 38 => 'shop')
    )
);

echo "call AdminImport and POST datas...".PHP_EOL;

$request->call($adminUrl."index.php?controller=AdminImport&token=".$token);

echo "-- END --".PHP_EOL;

$request = null;

Here's the wrapper curl class


class PSRequest {

    protected $_useragent          = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2';
    protected $_cookieFileLocation = './cookie.txt';
    protected $_referer            = "http://www.google.com";

    protected $_url;
    protected $_followlocation;
    protected $_timeout;
    protected $_maxRedirects;
    protected $_post;
    protected $_postFields;

    protected $_session;
    protected $_includeHeader;
    protected $_noBody;
    protected $_status;
    protected $_binaryTransfer;

    public $_webpage;
    public $authentication = 0;
    public $auth_name      = '';
    public $auth_pass      = '';

    protected $ch; // curl handler

    public function __construct($url = '', $followlocation = true, $timeOut = 30, $maxRedirecs = 4, $binaryTransfer = false, $includeHeader = true, $noBody = false)
    {
        $this->_url                = $url;
        $this->_followlocation     = $followlocation;
        $this->_timeout            = $timeOut;
        $this->_maxRedirects       = $maxRedirecs;
        $this->_noBody             = $noBody;
        $this->_includeHeader      = $includeHeader;
        $this->_binaryTransfer     = $binaryTransfer;

        $this->_cookieFileLocation = dirname(__FILE__).'/cookie.txt';

        $this->ch = curl_init();
    }

    public function __destruct() {
        curl_close($this->ch);
    }

    public function useAuth($use){
        $this->authentication = 0;
        if($use == true) $this->authentication = 1;
    }

    public function setName($name){
        $this->auth_name = $name;
    }

    public function setPass($pass){
        $this->auth_pass = $pass;
    }

    public function setReferer($referer){
        $this->_referer = $referer;
    }

    public function setCookiFileLocation($path)
    {
        $this->_cookieFileLocation = $path;
    }

    public function setPost($postFields)
    {
        $this->_post = true;

        if (is_array($postFields)) {
            $fields_string = http_build_query($postFields);
        }
        else {
            $fields_string = $postFields;
        }

        $this->_postFields = $fields_string;
    }

    public function setUserAgent($userAgent)
    {
        $this->_useragent = $userAgent;
    }

    public function call($url = null)
    {
        if ($url) {
            $this->_url = $url;
        }

        if (!$url) {
            throw new Exception('You should set an URL to call.');
        }

        curl_setopt($this->ch,CURLOPT_URL,$this->_url);
        curl_setopt($this->ch,CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
        curl_setopt($this->ch,CURLOPT_TIMEOUT,$this->_timeout);
        curl_setopt($this->ch,CURLOPT_MAXREDIRS,$this->_maxRedirects);
        curl_setopt($this->ch,CURLOPT_RETURNTRANSFER,true);
        curl_setopt($this->ch,CURLOPT_FOLLOWLOCATION,$this->_followlocation);
        curl_setopt($this->ch,CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($this->ch,CURLOPT_COOKIESESSION, true );
        curl_setopt($this->ch,CURLOPT_COOKIEJAR,$this->_cookieFileLocation);
        curl_setopt($this->ch,CURLOPT_COOKIEFILE,$this->_cookieFileLocation);

        if ($this->authentication == 1) {
            curl_setopt($this->ch, CURLOPT_USERPWD, $this->auth_name.':'.$this->auth_pass);
        }

        if ($this->_post) {
            curl_setopt($this->ch,CURLOPT_POST,true);
            curl_setopt($this->ch,CURLOPT_POSTFIELDS,$this->_postFields);

        }

        if ($this->_includeHeader) {
            curl_setopt($this->ch,CURLOPT_HEADER,true);
        }

        if ($this->_noBody) {
            curl_setopt($this->ch,CURLOPT_NOBODY,true);
        }

        curl_setopt($this->ch,CURLOPT_USERAGENT,$this->_useragent);
        curl_setopt($this->ch,CURLOPT_REFERER,$this->_referer);

        $this->_webpage = curl_exec($this->ch);
        $this->_status = curl_getinfo($this->ch,CURLINFO_HTTP_CODE);

        return $this->_webpage;
    }

    public function getHttpStatus()
    {
        return $this->_status;
    }

    public function __tostring(){
        return $this->_webpage;
    }

}

and that's it. Just setup your cron like this for example :

@daily /usr/bin/php /path/to/my_script.php > /dev/null 2>&1

You can add a log to file logic to the script to check everything went well !

Say Thanks
Respond

19 Responses
Add your response

11511
Default profile 2 normal

Doesn't work for me.
Doing var_dump of response i get 'Token not valid'.

over 1 year ago ·
11521
Tinyterror

Hi,
Works fine for me.
Double check if your login/pass array("email" => "YOURADMINEMAIL","passwd" => "YOURADMINPASS" and check your PSCookie.txt file, the directry should be writable

over 1 year ago ·
11527
Default profile 2 normal

I had solved the problem of the token, thank you anyway for your reply, but know i've another problem.

I adapted the script to recognize entities (products or combinations) and to work with existing csv file generated by previously executed cronjob.
I was able to make the script works only if I put it in the same folder of csv files ("$adminUrl/import").

Giving in output "$request" I get the import page with the error ".csv file unreadable".

over 1 year ago ·
11534
Default profile 2 normal

Solved passing the basename of csv url.

over 1 year ago ·
11598
4a4b14b44b57b615e806865c594377fd

Hi,
I'm not technical person and affraid of code that may not work or even worse - can act unexpectedly and damage my database.
I use a kind of cron tool in Store Manager for Prestashop, it is it's addon called Automated products import.
It can do updates of your existing products as well as import new ones from third-party storage place on daily, weekly or monthly bases.
There is 30-days free trial as well. You can find it at the same web-site as Store Manager. This article will explain how Automated products import can help you - http://www.prestashopmanager.com/useful-articles/how-to/how-to-accomplish-prestashop-cron-import-with-automated-product-import-addon/

over 1 year ago ·
12746
8b4939012160bc789188ec7211f0fc7d

Hello Baptiste, it worked one time for me but now I have an error "Clé de sécurité invalide" on my pages everytime i try to restart the cron. Any idea of where it could come from?
Thanks

over 1 year ago ·
13630
3e1fad3aa3061cc0f95a0a96d7f4f928

Thanks for this nice little snippet. Works smoothly

over 1 year ago ·
14881
Default profile 5 normal

Hello i don't understand very well how i can use this script.

First i create a file named script.php and in this i put the first code that you have posted.

Second i create a file named class.PSRequest.php and i put the second code.

So what is the directory then i must put these files?

And how i can run this script manually?

Thank you for answer and for the code.

over 1 year ago ·
14883
Tinyterror

Hi prontier,

you can put the scripts anywhere on your server, but the directory should be writeable and the main php script should be executable by the owner.

Then launch the main script like that :

> /usr/bin/php /path/to/my_script.php

Note that i didn't test it with the new prestashop 1.6

over 1 year ago ·
15265
0 bvdvue8yequurdeud1pquo8ahchnkedu5tjouoamctpk7ao2ipjmze586oew1sh8qnfwns bc3yz

Thanks for your code.
I have modified your code because it doesn't work to my.
Your code doesn't send csv file by post to prestashop server.

This is my code:
https://coderwall.com/p/fwoaqq

over 1 year ago ·
15610
0 o y3pbxczpcil k7on7tpqkgzllm1 37pkeypqbgotay2f9ftqudtn12rj5lkkh 0ay01pjkrbse

Hello
Any body have same script for prestashop 1.6 or Any one tried same script with 1.6 ?

over 1 year ago ·
15913

Hi all, in prestashop 1.6 i've got always invalid token, any suggest?

over 1 year ago ·
16170
0 bvdvue8yequurdeud1pquo8ahchnkedu5tjouoamctpk7ao2ipjmze586oew1sh8qnfwns bc3yz

This script (or my version of this script https://coderwall.com/p/fwoaqq) works for prestashop 1.6.
Token invalid is because the login is failed or the script that split the response of the login page don't catch the token. Try to show all the response of login action.

over 1 year ago ·
17081
Logo2

Hi croustibat,

I tried your solution and magicianred's one, to import Attributes (entity = 2), but I keep on having the same issue : _webpage is desperately void, thus preventing an AdminImport token to be retrieved. I tried using the token provided by the call to AdminLogin but i still can't import anything.
Any idea ?

Regards

over 1 year ago ·
20129
None

Here add this file ? Also i not found this class.PSRequest.php...

over 1 year ago ·
21237
Tinyterror

Hello,

FYI, it works with Prestashop 1.6.0.X !

over 1 year ago ·
24533
9ahpdgv3 normal

how to know file is completed !!!

over 1 year ago ·
27619

Hi i'm trying to set this script on my domain i get token but it doesn't enter in prestashop adin? someone can explain me why? thanks a lot

over 1 year ago ·
28213

My modified version for prestashop 1.6.1.7

http://pastebin.com/YYMdkZj1

over 1 year ago ·