* @copyright 2019 Dalibor Stojcevski * @license Dalibor Stojcevski */ ini_set('memory_limit', '-1'); class Import_ApiImportModuleFrontController extends ModuleFrontController { /** * Assign template vars related to page content * @see FrontController::initContent() */ private $fields = array(); private $product_links = array(); private $import; private $creator; private $convertor; public static $update_limit = 1; public function initContent() { require_once(_PS_MODULE_DIR_ . 'import_api/classes/import.php'); require_once(_PS_MODULE_DIR_ . 'import_api/classes/creator.php'); require_once(_PS_MODULE_DIR_ . 'import_api/classes/filereader.php'); require_once(_PS_MODULE_DIR_ . 'import_api/classes/queue.php'); require_once(_PS_MODULE_DIR_ . 'import_api/classes/convertor.php'); Db::getInstance()->execute("SET session wait_timeout=28800", FALSE); Db::getInstance()->execute("SET session net_read_timeout=28800", FALSE); Db::getInstance()->execute("SET session interactive_timeout=28800", FALSE); $json = array(); $view = Tools::getValue('id'); $file_id = Tools::getValue('file_id'); $this->queue = new Queue(); $this->creator = new Creator($file_id); $action = Tools::getValue('action') ? Tools::getValue('action') : 'cron'; /* if ($this->product_links === null) { $json['error'] = 'Invalid source url. Please check in browser first'; $this->ajaxDie(Tools::jsonEncode($json)); }*/ $this->getModuleSettings(); $this->convertor = new Convertor($this->settings, $this->creator); if ($action == 'test') { //$this->creator->addAttributesToProduct(array('0' => array('0' => array('attribute'=> "DColor", 'attribute_value' => "blue"), '1' => array('attribute'=> "DColor", 'attribute_value' => "green"))), 12685); exit; $this->product_links = $this->getProductLinks($action); $this->printTestJsonData($view); } elseif (Tools::getValue('queue')) { echo $this->queue($file_id); exit; } elseif ($action == 'selected') { $this->importSelected($file_id); } elseif ($action == 'delete') { $this->deleteProducts($file_id); } elseif ($action == 'view_one') { $this->viewOne($file_id, Tools::getValue('index')); } elseif (Tools::getValue('index')) { $this->importOne($file_id, Tools::getValue('index')); } else { $this->importData($file_id, $action, Tools::getValue('limit')); Tools::clearSmartyCache(); Tools::clearXMLCache(); Media::clearCache(); Tools::generateIndex(); } } function queue($file_id) { $product_links = $this->getProductLinks(); $products = array(); foreach ($product_links as $link) { $original_product = $this->importer->getAllData($link); $original_product = $this->convertor->unArray($original_product); $original_product = $this->convertor->replace($original_product); $original_product = $this->convertor->filter($original_product); $original_product = $this->convertor->clearInput($original_product); if ($original_product['belong']) { $products[$original_product['unique']] = $original_product; } } $this->queue->saveTempToDb($products, $file_id); return count($products); } function importData($file_id, $action = 'cron', $limit = 0) { if (!ini_get('max_execution_time')) { ini_set('max_execution_time', 100); } $json['notice'] = ''; $last_queue = $this->queue->getLastQueue($file_id); if (!$last_queue || $last_queue['status'] == 4) { $this->queue($file_id); $last_queue = $this->queue->getLastQueue($file_id); } if (!$last_queue) { exit('Queue creation error'); } if ($last_queue['status'] == 3) { $this->creator->processMissing($file_id, $last_queue['queue_id']); $this->ajaxDie(Tools::jsonEncode($json)); exit; } $products = $this->queue->getQueued($file_id); if (!$products) { $this->queue($file_id); $products = $this->queue->getQueued($file_id); $last_queue = $this->queue->getLastQueue($file_id); } $queue_id = isset($products[0]) ? $products[0]['queue_id'] : 0; $products_created = 0; $products_updated = 0; $json['total'] = count($products); foreach ($products as $product) { $original_product = json_decode($product['product'], true); $product_id = 0; if ($this->settings['unique_equivalent'] == 'id_product') { $product_id = (int)$original_product['unique']; } else { $equivalent = $this->settings['unique_equivalent']; $query = ($equivalent == 'name') ? $original_product['name'] : $original_product['unique']; $product_id = $this->creator->getProductId($query, $this->settings['table_equivalent'], $equivalent); } $this->queue->deleteQueuedProduct($product['product_id']); if ($product_id) { $this->creator->editProduct($product_id, $original_product); Db::getInstance()->execute("UPDATE " . _DB_PREFIX_ . "ia_products SET indx = '" . pSQL($original_product['unique']) . "', product = '" . pSQL(json_encode($original_product)) . "', source = 'admin', date_edited = '" . time() . "', queue_id = '" . (int)$queue_id . "', file_id = '" . (int)$file_id . "' WHERE product_id = '" . (int)$product_id . "' AND shop = 'default'"); $products_updated++; } elseif (empty($this->settings['import_api_settings']['only_update'])) { $frm_product = $this->convertor->convertToFrmProduct($original_product); $product_id = $frm_product->id; Db::getInstance()->execute("INSERT INTO " . _DB_PREFIX_ . "ia_products SET product_id = '" . $product_id . "', indx = '" . pSQL($original_product['unique']) . "', product = '" . pSQL(json_encode($original_product)) . "', shop = 'default', source = 'admin', date_added = '" . time() . "', queue_id = '" . (int)$queue_id . "', file_id = '" . (int)$file_id . "'"); $products_created++; if ($action == 'cron') echo '
DodaĆem nowy produkt: ' . $product_id . '
'; } if ((($products_created + $products_updated) >= self::$update_limit) or ($limit and ($products_created + $products_updated) >= $limit)) { $json['notice'] = 'time_out'; break; } } if (!$json['notice']) { $json['notice'] = 'missing'; Db::getInstance()->execute("UPDATE " . _DB_PREFIX_ . "ia_queues SET source = 'admin', status = '3', date_processed = '" . time() . "' WHERE queue_id = '" . (int)$queue_id . "'"); } if ($action != 'cron') { $json['products_created'] = $products_created; $json['products_updated'] = $products_updated; $this->ajaxDie(Tools::jsonEncode($json)); } exit; } function importSelected($file_id) { $products = array(); $selected = Tools::getValue('indx') ? Tools::getValue('indx') : array(); foreach ($selected as $indx) { $products[] = $this->queue->getQueuedProduct($indx, $file_id); } $queue_id = isset($products[0]) ? $products[0]['queue_id'] : 0; $products_created = 0; $products_updated = 0; $json['notice'] = ''; $json['total'] = count($products); $json['processed'] = array(); foreach ($products as $product) { $original_product = json_decode($product['product'], true); $json['processed'][] = $product['product_id']; $product_id = 0; if ($this->settings['unique_equivalent'] == 'id_product') { $product_id = (int)$original_product['unique']; } else { $equivalent = $this->settings['unique_equivalent']; $query = ($equivalent == 'name') ? $original_product['name'] : $original_product['unique']; $product_id = $this->creator->getProductId($query, $this->settings['table_equivalent'], $equivalent); } $this->queue->deleteQueuedProduct($product['product_id']); if ($product_id) { $this->creator->editProduct($product_id, $original_product); Db::getInstance()->execute("UPDATE " . _DB_PREFIX_ . "ia_products SET indx = '" . pSQL($indx) . "', product = '" . pSQL(json_encode($original_product)) . "', source = 'selected', date_edited = '" . time() . "', queue_id = '" . (int)$queue_id . "', file_id = '" . (int)$file_id . "' WHERE product_id = '" . (int)$product_id . "' AND shop = 'default'"); $products_updated++; } elseif (empty($this->settings['import_api_settings']['only_update'])) { $frm_product = $this->convertor->convertToFrmProduct($original_product); $product_id = $frm_product->id; Db::getInstance()->execute("INSERT INTO " . _DB_PREFIX_ . "ia_products SET product_id = '" . (int)$product_id . "', indx = '" . pSQL($indx) . "', product = '" . pSQL(json_encode($original_product)) . "', shop = 'default', source = 'selected', date_added = '" . time() . "', queue_id = '" . (int)$queue_id . "', file_id = '" . (int)$file_id . "'"); $products_created++; } if (($products_created + $products_updated) >= self::$update_limit) { $json['notice'] = 'time_out'; break; } } $json['products_created'] = $products_created; $json['products_updated'] = $products_updated; $this->ajaxDie(Tools::jsonEncode($json)); exit; } function importOne($file_id, $indx) { $product = $this->queue->getQueuedProduct($indx, $file_id); if (!$product) { echo 'Product not found in queue'; exit; } $queue_id = isset($product[0]) ? $product['queue_id'] : 0; $original_product = json_decode($product['product'], true); $equivalent = $this->settings['unique_equivalent']; $query = ($equivalent == 'name') ? $original_product['name'] : $original_product['unique']; $product_id = $this->creator->getProductId($query, $this->settings['table_equivalent'], $equivalent); $link = new Link(); if ($product_id) { $exising = $this->creator->editProduct($product_id, $original_product); Db::getInstance()->execute("UPDATE " . _DB_PREFIX_ . "ia_products SET indx = '" . pSQL($indx) . "', product = '" . pSQL(json_encode($original_product)) . "', source = 'selected', date_edited = '" . time() . "', queue_id = '" . (int)$queue_id . "', file_id = '" . (int)$file_id . "' WHERE product_id = '" . (int)$product_id . "' AND shop = 'default'"); echo 'Product is updated'; //echo 'link to product ' . $link->getproductlink($product_id) . ''; } else { $frm_product = $this->convertor->convertToFrmProduct($original_product); if ($frm_product) { $product_id = $frm_product->id; Db::getInstance()->execute("INSERT INTO " . _DB_PREFIX_ . "ia_products SET product_id = '" . (int)$product_id . "', indx = '" . pSQL($indx) . "', product = '" . pSQL(json_encode($original_product)) . "', shop = 'default', source = 'selected', date_added = '" . time() . "', queue_id = '" . (int)$queue_id . "', file_id = '" . (int)$file_id . "'"); echo 'Product is inserted'; //echo 'Link to product ' . $link->getProductLink($product_id) . ''; } } exit; } function viewOne($file_id, $indx) { $product = $this->queue->getQueuedProduct($indx, $file_id); if (!$product) { echo 'Product not found in queue'; exit; } $queue_id = isset($product[0]) ? $product['queue_id'] : 0; $original_product = json_decode($product['product'], true); $equivalent = $this->settings['unique_equivalent']; $query = ($equivalent == 'name') ? $original_product['name'] : $original_product['unique']; $product_id = $this->creator->getProductId($query, $this->settings['table_equivalent'], $equivalent); $link = new Link(); if ($product_id) { echo 'Product exists ' . $product_id; //echo 'link to product ' . $link->getproductlink($exising) . ''; } else { echo 'Product is not inserted in Prestashop site '; } foreach ($original_product as $key => $value) { if (!is_array($value)) { echo $key . ':' . $value . ', '; } } if (isset($original_product['cover'])) { if (!$this->UR_exists($original_product['cover'])) { echo 'image is not found. If you need to add server name go to Modifications and add https://servername/[[cover]]'; } else { echo 'image: ' . $original_product['cover']; } } exit; } private function printTestJsonData($view) { $json = array(); foreach ($this->product_links as $link) { $json[] = $this->importer->getAllData($link, $view); } $this->ajaxDie(Tools::jsonEncode($json)); } private function getProductLinks($action = 'import') { $begin_character = 'FEED'; $shop = 'default'; $file_id = Tools::getValue('file_id'); $settings = $this->getModuleSettings($file_id); $query_file = Db::getInstance()->executeS("SELECT * FROM " . _DB_PREFIX_ . "ia_files WHERE file_id = '" . (int)$file_id . "' AND shop = '" . pSQL($shop) . "' LIMIT 1"); $file = $query_file[0]; $FileReader = new FileReader(); list($tmp_array, $error) = $FileReader->getArrayFromLink($file); if (count($tmp_array) > 10 && !empty(array_key_first($tmp_array))) { // if is not 0 $new_array = array(); foreach ($tmp_array as $key => $value) { $value['GENERATED_UNIQUE'] = $key; $new_array[] = $value; } $tmp_array = $new_array; unset($new_array); } $php_array[$begin_character] = $tmp_array; $parts = explode('->', $settings['unique_field']); $identifier_field = $parts[count($parts) - 1]; $importer = new Import($settings); $importer->setJsonArray($php_array); $importer->findUniqueProductsIdentifier($php_array, $parts, $identifier_field); $product_links = $importer->getProductLinks(); //var_dump($product_links); exit; $this->importer = $importer; $start = $limit = 0; if ($action == 'test') { $start = $settings['start']; $limit = 20; } if (Tools::getValue('start')) { $start = Tools::getValue('start'); } if (Tools::getValue('limit')) { $limit = Tools::getValue('limit'); } if ($start && !$limit) { $limit = count($product_links) - $start; } if ($limit) { $product_links = array_slice($product_links, $start, $limit); } return $product_links; } function getModuleSettings($file_id = 0) { if (!$file_id) { $file_id = Tools::getValue('file_id'); } $shop = 'default'; $settings_fields = array('link', 'attribute_group', 'default_brand', 'default_category', 'top_category', 'weight_class_id', 'stock_status_id', 'tax', 'default_option', 'category_path', 'multiplier', 'id_tax_rules_group'); if (Tools::getValue('import_api_field')) { $settings = array( 'import_api_field' => Tools::getValue('import_api_field'), 'import_api_modification' => Tools::getValue('import_api_modification'), 'import_api_combination' => Tools::getValue('import_api_combination'), 'import_api_settings' => Tools::getValue('import_api_settings'), 'import_api_link' => Tools::getValue('import_api_link'), 'import_api_type' => Tools::getValue('import_api_type'), ); } else { $query_file_settings = Db::getInstance()->executeS("SELECT fs.* FROM " . _DB_PREFIX_ . "ia_file_settings fs WHERE fs.file_id = '" . (int)$file_id . "' LIMIT 1"); if ($query_file_settings) { $file_settings = $query_file_settings[0]; $filters = array(); $replaces = array(); if ($file_settings['filter']) { $text_areas = json_decode($file_settings['filter'], true); foreach ($text_areas as $key => $textarea_value) { if ($textarea_value) { $filters[$key] = array_map('trim', explode("\n", $textarea_value)); } } } if ($file_settings['replace']) { $text_areas = json_decode($file_settings['replace'], true); foreach ($text_areas as $key => $textarea_value) { $lines = array_map('trim', explode("\n", $textarea_value)); foreach ($lines as $line) { if ($line) { $replaces[$key][] = explode('##', $line); } } } } $settings = array( 'import_api_field' => json_decode($file_settings['mapping'], true), 'import_api_modification' => json_decode($file_settings['modification'], true), 'import_api_combination' => json_decode($file_settings['split'], true), 'import_api_filter' => $filters, 'import_api_replace' => $replaces, 'import_api_filter_options' => json_decode($file_settings['filter_options'], true), 'import_api_settings' => json_decode($file_settings['settings'], true), ); } } if (!empty($settings['import_api_field']['unique'])) { $settings['unique_field'] = html_entity_decode($settings['import_api_field']['unique'], ENT_QUOTES, 'UTF-8'); } else { $json['error'] = 'you need to set unique field'; $this->ajaxDie(Tools::jsonEncode($json)); } if (Tools::getValue('start')) { $settings['start'] = Tools::getValue('start'); } else { $settings['start'] = 0; } if ($settings['import_api_settings']['top_category']) { $settings['top_category_id'] = $this->creator->getCategoryId($settings['import_api_settings']['top_category']); } else { $settings['top_category_id'] = Configuration::get('PS_HOME_CATEGORY'); } if ($settings['import_api_settings']['default_category']) { if ( is_numeric( $settings['import_api_settings']['default_category'] ) ) { $settings['default_category_id'] = $settings['import_api_settings']['default_category']; } else { $settings['default_category_id'] = $this->creator->getCategoryId($settings['import_api_settings']['default_category']); } } else { $settings['default_category_id'] = 0; } if ($settings['import_api_settings']['default_brand']) { $settings['default_manufacturer_id'] = $this->creator->getManufacturerId($settings['import_api_settings']['default_brand']); } else { $settings['default_manufacturer_id'] = 0; } $settings['id_tax_rules_group'] = isset($settings['import_api_settings']['id_tax_rules_group']) ? $settings['import_api_settings']['id_tax_rules_group'] : -1; $settings['unique_equivalent'] = 'name'; $settings['table_equivalent'] = 'product_lang'; if (isset($settings['import_api_settings']['synchronize_field']) && $settings['import_api_settings']['synchronize_field'] != 'automatic') { $settings['unique_equivalent'] = $settings['import_api_settings']['synchronize_field']; } else { $possible_eq = ['reference', 'sku', 'ean13', 'upc']; foreach ($possible_eq as $f) { if (!empty($settings['import_api_field'][$f]) && $settings['import_api_field'][$f] == $settings['import_api_field']['unique']) { $settings['unique_equivalent'] = $f; break; } } } if ($settings['unique_equivalent'] != 'name') { $settings['table_equivalent'] = 'product'; } $this->settings = $settings; return $settings; } function deleteProducts($file_id) { $query_file = Db::getInstance()->executeS("SELECT * FROM " . _DB_PREFIX_ . "ia_files WHERE file_id = '" . (int)$file_id . "' LIMIT 1"); if (empty($query_file)) { $json['notice'] = 'File not found'; $this->ajaxDie(Tools::jsonEncode($json)); exit; } else { $file = $query_file[0]; } if ($file['mask'] . $file['date_added'] != Tools::getValue('token')) { $json['notice'] = 'File not found.....'; $this->ajaxDie(Tools::jsonEncode($json)); exit; } $max_execution_time = 50; $products = $this->queue->getProducts($file_id); $products_deleted = 0; $json['notice'] = ''; foreach ($products as $product) { $p = new Product($product['product_id']); $p->delete(); $this->queue->deleteProduct($product['product_id']); $products_deleted++; if (($products_created + $products_updated) >= self::$update_limit) { $json['notice'] = 'time_out'; break; } } $json['products_deleted'] = $products_deleted; $this->ajaxDie(Tools::jsonEncode($json)); exit; } function UR_exists($url) { $headers = @get_headers($url); return stripos($headers[0], "200 OK") ? true : false; } }