array( 'fr' => 'Arrête l\'opération en cours. Facultatif.', 'en' => 'Stops the current update. Optional.' ), ); echo Tools::jsonEncode($help); exit(); } //$token = Tools::getValue('ec_token'); /* if ($token != Catalog::getInfoEco('ECO_TOKEN')) { header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); header('Cache-Control: no-store, no-cache, must-revalidate'); header('Cache-Control: post-check=0, pre-check=0', false); header('Pragma: no-cache'); header('Location: ../'); exit(); } */ $logging = true; if ($logging) { $logger = new FileLogger(); $logger->setFilename(_PS_ROOT_DIR_ . '/modules/ecstock/log/ecupdatestock.log'); } else { $logger = false; } $stopTime = time() + 15; $listStages = array( '1' => 'STARTED', '2' => 'UPDSTOCK', ); $id_supplier = 0; // 0 => all suppliers, if else => only one supplier // paramètres $paramNbCron = Tools::getValue('nbC', null); $nbCron = is_null($paramNbCron) ? 0 : (int) $paramNbCron; $paramAct = Tools::getValue('act', null); $action = (Configuration::getGlobalValue('ECI_USTK_ACT') === 'die') ? 'die' : (is_null($paramAct) ? 'go' : $paramAct); $paramSpy = Tools::getValue('spy', null); $spy = is_null($paramSpy) ? false : true; $paramSpy2 = Tools::getValue('spytwo', null); $spy2 = (empty($paramSpy2)) ? false : true; $who = $spy ? ($spy2 ? 'spy2' : 'spy') : 'normal'; $paramKill = Tools::getValue('kill', null); $kill = is_null($paramKill) ? false : true; //link $base_uri = (((Configuration::get('PS_SSL_ENABLED') == 1) && (Configuration::get('PS_SSL_ENABLED_EVERYWHERE') == 1)) ? 'https://' : 'http://' ) . Tools::getShopDomain() . __PS_BASE_URI__ . str_replace(_PS_ROOT_DIR_ . '/', '', __FILE__) . '?ts=' . microtime(true); if ($logging) { $logger->logInfo( $who . ' entered, parameters ' . $nbCron . ',' . $action . ',' . $spy . ',' . $spy2 . ',' . $kill . ',' ); } // kill if ($kill) { if (Configuration::getGlobalValue('ECI_USTK_STATE') != 'done') { Configuration::updateGlobalValue('ECI_USTK_ACT', 'die'); } exit('willdiesoon'); } // espion if ($spy) { sleep(14); $state = Configuration::getGlobalValue('ECI_USTK_STATE'); $progress = Configuration::getGlobalValue('ECI_USTK_PROGRESS'); if ($nbCron == $progress) { if ($spy2) { if ($state != 'done') { Configuration::updateGlobalValue('ECI_USTK_STATE', 'still'); } } else { followLink($base_uri . '&spy=1&spytwo=1&nbC=' . $progress); } } else { followLink($base_uri . '&spy=1&nbC=' . $progress); } exit('spywillreturn'); } // abandon ou initialisation $etat = Configuration::getGlobalValue('ECI_USTK_STATE'); $starting = is_null($paramSpy) & is_null($paramNbCron) & is_null($paramKill) & is_null($paramAct); if (!$starting && ($action === 'die')) { // abandon demandé par un kill Configuration::updateGlobalValue('ECI_USTK_STATE', 'done'); Configuration::updateGlobalValue('ECI_USTK_END_TIME', date('Y-m-d H:i:s')); Configuration::updateGlobalValue('ECI_USTK_ACT', 'go'); exit('dead'); } if ($starting && ($etat === 'running')) { // tentative de double lancement à éviter $progress = Configuration::getGlobalValue('ECI_USTK_PROGRESS'); // envoi d'espion pour déjouer un plantage de serveur pendant une mise à jour followLink($base_uri . '&spy=1&nbC=' . (int) $progress); exit('nodoublestartplease'); } if (!$starting && ($etat === 'still')) { // un espion a pensé à tort qu'on était planté mais on est là ! Configuration::updateGlobalValue('ECI_USTK_STATE', 'running'); followLink($base_uri . '&spy=1&nbC=' . $nbCron); } if ($starting) { // initialisation du process $aShops = Shop::getShops(true, null, true); asort($aShops); $listShops = array_values($aShops); Configuration::updateGlobalValue('ECI_USTK_START_TIME', date('Y-m-d H:i:s')); Configuration::updateGlobalValue('ECI_USTK_END_TIME', ''); Configuration::updateGlobalValue('ECI_USTK_SHOPS_TODO', implode(',', $listShops)); Configuration::updateGlobalValue('ECI_USTK_SHOP', reset($listShops)); Configuration::updateGlobalValue('ECI_USTK_STAGE', $listStages['1']); Configuration::updateGlobalValue('ECI_USTK_PROGRESS', 0); Configuration::updateGlobalValue('ECI_USTK_LOOPS', 0); Configuration::updateGlobalValue('ECI_USTK_STATE', 'running'); Configuration::updateGlobalValue('ECI_USTK_ACT', 'go'); // lancement de l'espion followLink($base_uri . '&spy=1&nbC=0'); } else { Configuration::updateGlobalValue('ECI_USTK_PROGRESS', $nbCron); } $listShopsTodo = explode(',', Configuration::getGlobalValue('ECI_USTK_SHOPS_TODO')); $id_shop = (int) Configuration::getGlobalValue('ECI_USTK_SHOP'); $stage = Configuration::getGlobalValue('ECI_USTK_STAGE'); // gestion des reprises, ruptures, fin if ($action === 'next') { $action = 'go'; Configuration::updateGlobalValue('ECI_USTK_ACT', 'go'); $numStage = array_search($stage, $listStages, true); $keys = array_keys($listStages); $next = $nextKey = false; foreach ($keys as $key) { if ($next) { $nextKey = $key; break; } if ($numStage == $key) { $next = true; } } if ($nextKey) { $stage = $listStages[$nextKey]; $nbCron = 0; } else { $ShopJustDone = array_shift($listShopsTodo); if (count($listShopsTodo) > 0) { $id_shop = reset($listShopsTodo); $stage = $listStages['1']; $nbCron = 0; } else { Configuration::updateGlobalValue('ECI_USTK_SHOPS_TODO', ''); Configuration::updateGlobalValue('ECI_USTK_STATE', 'done'); Configuration::updateGlobalValue('ECI_USTK_END_TIME', date('Y-m-d H:i:s')); //chaining with other task exit('alldone'); } } Configuration::updateGlobalValue('ECI_USTK_SHOPS_TODO', implode(',', $listShopsTodo)); Configuration::updateGlobalValue('ECI_USTK_SHOP', $id_shop); Configuration::updateGlobalValue('ECI_USTK_STAGE', $stage); Configuration::updateGlobalValue('ECI_USTK_LOOPS', 0); Configuration::updateGlobalValue('ECI_USTK_PROGRESS', 0); } if ($logging) { $logger->logInfo($who . ' do ' . $stage . ',' . $action); } // aiguillage switch ($stage) { case $listStages['1']: $reps = stage1($stage); if ($reps === true) { Configuration::updateGlobalValue('ECI_USTK_ACT', 'next'); followLink($base_uri . '&nbC=0&act=next'); } elseif (is_numeric($reps)) { Configuration::updateGlobalValue('ECI_USTK_LOOPS', Configuration::getGlobalValue('ECI_USTK_LOOPS') + 1); followLink($base_uri . '&nbC=' . $reps); } break; case $listStages['2']: $reps = stage2($nbCron, $id_supplier, $id_shop, $stopTime, $logger); if ($reps === true) { Configuration::updateGlobalValue('ECI_USTK_ACT', 'next'); followLink($base_uri . '&nbC=0&act=next'); } elseif (is_numeric($reps)) { Configuration::updateGlobalValue('ECI_USTK_LOOPS', Configuration::getGlobalValue('ECI_USTK_LOOPS') + 1); followLink($base_uri . '&nbC=' . $reps); } break; default: exit('dontunderstand'); } if ($reps !== true && !is_numeric($reps)) { if ($logging) { $logger->logInfo($who . ', stage ' . $stage . ', ' . $reps); } } exit('Bye'); function stage1($stage) { //tell the calling process that we begin working thus avoiding error 500 echo 'Task successfully started. '; return true; } function stage2($nbCron, $id_supplier, $id_shop, $stopTime, $logger) { Shop::setContext(Shop::CONTEXT_SHOP, (int) $id_shop); Context::getContext()->employee = 1; Context::getContext()->shop->id = (int) $id_shop; if (!Shop::isFeatureActive()) { $id_shop = 0; } if ($logger) { $logger->logInfo('Nbcon ' . $nbCron); } if ($nbCron == 0) { if (Configuration::get('ECSTOCK_FTP')) { $local_file = dirname(__FILE__) . '/file/1.csv'; $server_file = Configuration::get('ECSTOCK_CHEM'); $conn_id = ftp_connect(Configuration::get('ECSTOCK_HOTE')); $login_result = ftp_login($conn_id, Configuration::get('ECSTOCK_LOGIN'), Configuration::get('ECSTOCK_PASSWORD')); if ($logger) { if (!$login_result) { $logger->logInfo('Erreur login ftp ' .Configuration::get('ECSTOCK_HOTE').'..'. Configuration::get('ECSTOCK_LOGIN').'..'.Configuration::get('ECSTOCK_PASSWORD')); } } if (ftp_get($conn_id, $local_file, $server_file, FTP_BINARY)) { $lm = 1; } else { $lm = 0; } if ($logger) { $logger->logInfo('copy ftp 1 = > oui / 0 => non ::: ' . $lm); } ftp_close($conn_id); //$sstock = Configuration::get('ECSTOCK_MIN'); } } $fStock = dirname(__FILE__) . '/file/1.csv'; if (($handle = fopen($fStock, 'rb')) === false) { if ($logger) { $logger->logInfo('erreur lecture fichier ' . $fStock); } return false; } $jobLine = 0; while (($line = fgets($handle)) !== false) { if (($stopTime < time()) && ($jobLine > $nbCron)) { fclose($handle); return $jobLine; } $jobLine++; if (($jobLine < $nbCron) || empty($line)) { continue; } $logger->logInfo($line); $data = explode(';', $line); if (count($data) < 1) { continue; } $ref = trim($data[0]); $qt = trim($data[1]); $action = trim($data[2]); if (0 === ($jobLine % 50)) { Configuration::updateGlobalValue('ECI_USTK_PROGRESS', $jobLine); } $res = explode('-', $ref); if (count($res) > 1) { $ref = $res[0].'-'; $ids = getPIdsByReferenceLike($ref, $id_supplier); foreach ($ids as $key => $value) { $stock = StockAvailable::getQuantityAvailableByProduct( (int) $value['id_product'], (int) $value['id_product_attribute'], ($id_shop ? (int) $id_shop : null) ); if ($action == 'update') { $logger->logInfo('add ref:'.$data[0]); StockAvailable::setQuantity( (int) $value['id_product'], (int) $value['id_product_attribute'], (int) ($qt + $stock), ($id_shop ? (int) $id_shop : null), false ); if (0 !== ($jobLine % 50)) { Configuration::updateGlobalValue('ECI_USTK_PROGRESS', $jobLine); } } else { $logger->logInfo('maj qt '.$qt.' ref:'.$ref); StockAvailable::setQuantity( (int) $ids['id_product'], (int) $ids['id_product_attribute'], (int) $qt, ($id_shop ? (int) $id_shop : null) ); if (0 !== ($jobLine % 50)) { Configuration::updateGlobalValue('ECI_USTK_PROGRESS', $jobLine); } } } } else { $ids = getPIdsByReference($ref, $id_supplier); if (!$ids) { continue; } $stock = StockAvailable::getQuantityAvailableByProduct( (int) $ids['id_product'], (int) $ids['id_product_attribute'], ($id_shop ? (int) $id_shop : null) ); if ($action == 'update') { //$logger->logInfo('add ref:'.$data[0]); StockAvailable::setQuantity( (int) $ids['id_product'], (int) $ids['id_product_attribute'], (int) ($qt + $stock), ($id_shop ? (int) $id_shop : null) ); if (0 !== ($jobLine % 50)) { Configuration::updateGlobalValue('ECI_USTK_PROGRESS', $jobLine); } } else { $logger->logInfo('maj qt '.$qt.' ref:'.$ref); StockAvailable::setQuantity( (int) $ids['id_product'], (int) $ids['id_product_attribute'], (int) $qt, ($id_shop ? (int) $id_shop : null) ); if (0 !== ($jobLine % 50)) { Configuration::updateGlobalValue('ECI_USTK_PROGRESS', $jobLine); } } } } fclose($handle); return true; } function getPIdsByReference($reference, $id_fournisseur = false) { $res = Db::getInstance()->getRow(' SELECT pa.id_product, pa.id_product_attribute FROM ' . _DB_PREFIX_ . 'product_attribute pa ' . (!$id_fournisseur ? '' : 'LEFT JOIN ' . _DB_PREFIX_ . 'product p ON pa.id_product = p.id_product') . ' WHERE pa.reference = "' . pSQL($reference) . '"' . (!$id_fournisseur ? '' : ' AND p.id_supplier = ' . (int) $id_fournisseur)); if (isset($res['id_product_attribute'])) { return $res; } $id = Db::getInstance()->getValue(' SELECT `id_product` FROM `' . _DB_PREFIX_ . 'product` WHERE `reference` = "' . pSQL($reference) . '"' . (!$id_fournisseur ? '' : ' AND `id_supplier` = ' . (int) $id_fournisseur)); if ($id) { return array('id_product' => $id, 'id_product_attribute' => 0); } return false; } function getPIdsByReferenceLike($reference, $id_fournisseur = false) { $res = Db::getInstance()->ExecuteS(' SELECT pa.id_product, pa.id_product_attribute FROM ' . _DB_PREFIX_ . 'product_attribute pa ' . (!$id_fournisseur ? '' : 'LEFT JOIN ' . _DB_PREFIX_ . 'product p ON pa.id_product = p.id_product') . ' WHERE pa.reference like "' . pSQL($reference) . '%" '. (!$id_fournisseur ? '' : ' AND p.id_supplier = ' . (int) $id_fournisseur)); //if (isset($res['id_product_attribute'])) { return $res; //} //$id = Db::getInstance()->ExecuteS(' // SELECT `id_product` // FROM `' . _DB_PREFIX_ . 'product` // WHERE `reference` = "' . pSQL($reference) . '"' . // (!$id_fournisseur ? '' : ' AND `id_supplier` = ' . (int) $id_fournisseur)); // if ($id) { // return array('id_product' => $id, 'id_product_attribute' => 0); // } // // return false; } function followLink($link, $timeout = 4) { $link.='&token='.Tools::getValue('token'); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $link); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); $result = curl_exec($ch); curl_close($ch); return $result; }