<?php
 document::$snippets['title'][] = language::translate('title_import_export_csv', 'Import/Export CSV'); breadcrumbs::add(language::translate('title_catalog', 'Catalog')); breadcrumbs::add(language::translate('title_import_export_csv', 'Import/Export CSV')); if (isset($_POST['import']) || isset($_GET['resume'])) { try { ini_set('memory_limit', -1); ob_clean(); header('Content-Type: text/plain; charset='. language::$selected['charset']); if (isset($_GET['resume'])) { if (empty(session::$data['csv_batch'])) { throw new Exception('Missing batch to resume'); } $batch = &session::$data['csv_batch']; $progress = round(($batch['total_lines'] - count($batch['rows'])) / $batch['total_lines'] * 100, 2, PHP_ROUND_HALF_DOWN); $time_elapsed = round(microtime(true) - $batch['time_start'], 2); $time_remaining = round($time_elapsed / $progress * 100, 2) - $time_elapsed; $memory_usage = round(memory_get_usage() / 1024 / 1024, 3); echo $progress .'% complete' .' - Estimated time remaining: '. $time_remaining .' s - Memory usage: '. $memory_usage .' MB' . PHP_EOL . PHP_EOL; } else { if (empty($_POST['type'])) throw new Exception(language::translate('error_must_select_type', 'You must select type')); if (!isset($_FILES['file']['tmp_name']) || !is_uploaded_file($_FILES['file']['tmp_name'])) { throw new Exception(language::translate('error_must_select_file_to_upload', 'You must select a file to upload')); } if (!empty($_FILES['file']['error'])) { throw new Exception(language::translate('error_uploaded_file_rejected', 'An uploaded file was rejected for unknown reason')); } $csv = file_get_contents($_FILES['file']['tmp_name']); if (!$csv = functions::csv_decode($csv, $_POST['delimiter'], $_POST['enclosure'], $_POST['escapechar'], $_POST['charset'])) { throw new Exception(language::translate('error_failed_decoding_csv', 'Failed decoding CSV')); } echo 'Creating a batch of '. count($csv) .' lines for processing' . PHP_EOL . PHP_EOL; session::$data['csv_batch'] = [ 'type' => $_POST['type'], 'time_start' => microtime(true), 'rows' => $csv, 'total_lines' => count($csv), 'insert' => !empty($_POST['insert']), 'overwrite' => !empty($_POST['overwrite']), 'onerror' => isset($_POST['onerror']) ? $_POST['onerror'] : 'abort', 'counters' => [ 'updated' => 0, 'inserted' => 0, 'line' => 0, ], ]; $batch = &session::$data['csv_batch']; } $time_start = microtime(true); ignore_user_abort(true); echo 'Processing batch...' . PHP_EOL . PHP_EOL; while ($row = array_shift($batch['rows'])) { if (round(microtime(true) - $time_start) > 5) { array_unshift($batch['rows'], $row); echo PHP_EOL . 'Resuming '. number_format(count($batch['rows']), 0, '', ' ') .' remaining lines for processing...' . PHP_EOL . PHP_EOL; header('Refresh: 0; url='. document::link(null, ['resume' => 'true'])); exit; } if (connection_aborted()) { throw new Exception('Connection aborted'); } try { $batch['counters']['line']++; switch ($batch['type']) { case 'attributes': if (!empty($row['group_id']) && ($attribute_group = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."attribute_groups where id = ". (int)$row['group_id'] ." limit 1;")))) { $attribute_group = new ent_attribute_group($attribute_group['id']); } elseif (!empty($row['code']) && $attribute_group = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."attribute_groups where code = '". database::input($row['code']) ."' limit 1;"))) { $attribute_group = new ent_attribute_group($attribute_group['id']); } elseif (!empty($row['group_name']) && $attribute_group = database::fetch(database::query("select group_id as id from ". DB_TABLE_PREFIX ."attribute_groups_info where name = '". database::input($row['group_name']) ."' and language_code = '". database::input($row['language_code']) ."' limit 1;"))) { $attribute_group = new ent_attribute_group($attribute_group['id']); } if (!empty($attribute_group->data['id'])) { if (empty($batch['overwrite'])) { echo 'Skip updating existing attribute group on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Updating existing attribute group on line '. $batch['counters']['line'] . PHP_EOL; $batch['counters']['updated']++; } else { if (empty($batch['insert'])) { echo 'Skip inserting new attribute group on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Inserting new attribute group on line '. $batch['counters']['line'] . PHP_EOL; $batch['counters']['inserted']++; if (!empty($row['group_id'])) { database::query( "insert into ". DB_TABLE_PREFIX ."attribute_groups
                    (id)
                    values (". (int)$row['group_id'] .");" ); $attribute_group = new ent_attribute_group($row['group_id']); } else { $attribute_group = new ent_attribute_group(); } } if (isset($row['group_code'])) $attribute_group->data['code'] = $row['group_code']; if (isset($row['group_name'])) $attribute_group->data['name'][$row['language_code']] = $row['group_name']; if (isset($row['sort'])) $attribute_group->data['sort'] = $row['sort']; foreach ($attribute_group->data['values'] as $key => $value) { if (!empty($row['value_id']) && $value['id'] == $row['value_id']) { $value_key = $key; break; } if (!empty($row['value_name']) && isset($value['name'][$row['language_code']]) && $value['name'][$row['language_code']] == $row['value_name']) { $value_key = $key; break; } } if (!empty($value_key)) { $attribute_group->data['values'][$value_key]['name'][$row['language_code']] = $row['value_name']; } else { $attribute_group->data['values'][] = [ 'name' => [ $row['language_code'] => $row['value_name'], ], ]; } uasort($attribute_group->data['values'], function($a, $b){ if (!isset($a['priority'])) $a['priority'] = ''; if (!isset($b['priority'])) $b['priority'] = ''; if ($a['priority'] == $b['priority']) { return ($a['name'] < $b['name']) ? -1 : 1; } return ($a['priority'] < $b['priority']) ? -1 : 1; }); $attribute_group->save(); break; case 'campaigns': if (!empty($row['id'])) { $campaign_query = database::query( "select id from ". DB_TABLE_PREFIX ."products_campaigns
                  where id = ". (int)$row['id'] ."
                  limit 1;" ); $campaign = database::fetch($campaign_query); } if (!empty($campaign['id'])) { if (empty($batch['overwrite'])) { echo 'Skip updating existing campaign on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Updating existing campaign on line '. $batch['counters']['line'] . PHP_EOL; $batch['counters']['updated']++; } else { if (empty($batch['insert'])) { echo 'Skip inserting new campaign on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Inserting new campaign on line '. $batch['counters']['line'] . PHP_EOL; $batch['counters']['inserted']++; if (!empty($row['id'])) { database::query( "insert into ". DB_TABLE_PREFIX ."products_campaigns
                    (id, product_id)
                    values (". (int)$row['id'] .", '". $row['product_id'] ."');" ); } } $prices = array_intersect_key($row, currency::$currencies); $sql_update_prices = ''; foreach ($prices as $currency_code => $price) { $sql_update_prices .= database::input($currency_code) ." = ". (float)$price . "," . PHP_EOL; } database::query( "update ". DB_TABLE_PREFIX ."products_campaigns
                set product_id = ". (int)$row['product_id'] .",
                    ". $sql_update_prices ."
                    start_date = ". (empty($row['start_date']) ? "null" : "'". date('Y-m-d H:i:s', strtotime($row['start_date'])) ."'") .",
                    end_date = ". (empty($row['end_date']) ? "null" : "'". date('Y-m-d H:i:s', strtotime($row['end_date'])) ."'") ."
                where id = ". (int)$row['id'] ."
                limit 1;" ); break; case 'categories': if (!empty($row['id']) && $category = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."categories where id = ". (int)$row['id'] ." limit 1;"))) { $category = new ent_category($category['id']); } elseif (!empty($row['code']) && $category = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."categories where code = '". database::input($row['code']) ."' limit 1;"))) { $category = new ent_category($category['id']); } if (!empty($category->data['id'])) { if (empty($batch['overwrite'])) { echo 'Skip updating existing category on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Updating existing category '. (!empty($row['name']) ? $row['name'] : 'on line '. $batch['counters']['line']) . PHP_EOL; $batch['counters']['updated']++; } else { if (empty($batch['insert'])) { echo 'Skip inserting new category on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Inserting new category: '. (!empty($row['name']) ? $row['name'] : 'on line '. $batch['counters']['line']) . PHP_EOL; $batch['counters']['inserted']++; if (!empty($row['id'])) { database::query( "insert into ". DB_TABLE_PREFIX ."categories (id, date_created)
                    values (". (int)$row['id'] .", '". date('Y-m-d H:i:s') ."');" ); $category = new ent_category($row['id']); } else { $category = new ent_category(); } } if (empty($row['parent_id']) && !empty($row['parent_code'])) { $parent_query = database::query( "select id from ". DB_TABLE_PREFIX ."categories
                  where code = '". database::input($row['parent_code']) ."'
                  limit 1;" ); $row['parent_id'] = database::fetch($parent_query, 'id'); } $fields = [ 'parent_id', 'status', 'code', 'keywords', 'image', 'priority', ]; foreach ($fields as $field) { if (isset($row[$field])) $category->data[$field] = $row[$field]; } if (!empty($row['language_code'])) { $fields = [ 'name', 'short_description', 'description', 'head_title', 'h1_title', 'meta_description', ]; foreach ($fields as $field) { if (isset($row[$field])) $category->data[$field][$row['language_code']] = $row[$field]; } } if (!empty($row['new_image'])) { $category->save_image($row['new_image']); } $category->save(); if (!empty($row['date_created'])) { database::query( "update ". DB_TABLE_PREFIX ."categories
                  set date_created = '". date('Y-m-d H:i:s', strtotime($row['date_created'])) ."'
                  where id = ". (int)$category->data['id'] ."
                  limit 1;" ); } break; case 'manufacturers': if (!empty($row['id']) && $manufacturer = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."manufacturers where id = ". (int)$row['id'] ." limit 1;"))) { $manufacturer = new ent_manufacturer($manufacturer['id']); } else if (!empty($row['code']) && $manufacturer = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."manufacturers where code = '". database::input($row['code']) ."' limit 1;"))) { $manufacturer = new ent_manufacturer($manufacturer['id']); } else if (!empty($row['name']) && !empty($row['language_code']) && $manufacturer = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."manufacturers where name = '". database::input($row['name']) ."' limit 1;"))) { $manufacturer = new ent_manufacturer($manufacturer['id']); } if (!empty($manufacturer->data['id'])) { if (empty($batch['overwrite'])) { echo 'Skip updating existing manufacturer on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Updating existing manufacturer '. (!empty($row['name']) ? $row['name'] : 'on line '. $batch['counters']['line']) . PHP_EOL; $batch['counters']['updated']++; } else { if (empty($batch['insert'])) { echo 'Skip inserting new manufacturer on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Inserting new manufacturer: '. (!empty($row['name']) ? $row['name'] : 'on line '. $batch['counters']['line']) . PHP_EOL; $batch['counters']['inserted']++; if (!empty($row['id'])) { database::query( "insert into ". DB_TABLE_PREFIX ."manufacturers (id, date_created)
                    values (". (int)$row['id'] .", '". date('Y-m-d H:i:s') ."');" ); $manufacturer = new ent_manufacturer($row['id']); } else { $manufacturer = new ent_manufacturer(); } } $fields = [ 'status', 'code', 'name', 'keywords', 'image', 'priority', ]; foreach ($fields as $field) { if (isset($row[$field])) $manufacturer->data[$field] = $row[$field]; } if (!empty($row['language_code'])) { $fields = [ 'short_description', 'description', 'head_title', 'h1_title', 'meta_description', ]; foreach ($fields as $field) { if (isset($row[$field])) $manufacturer->data[$field][$row['language_code']] = $row[$field]; } } if (!empty($row['new_image'])) { $manufacturer->save_image($row['new_image']); } $manufacturer->save(); if (!empty($row['date_created'])) { database::query( "update ". DB_TABLE_PREFIX ."manufacturers
                  set date_created = '". date('Y-m-d H:i:s', strtotime($row['date_created'])) ."'
                  where id = ". (int)$manufacturer->data['id'] ."
                  limit 1;" ); } break; case 'products': if (!empty($row['id']) && $product = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."products where id = ". (int)$row['id'] ." limit 1;"))) { $product = new ent_product($product['id']); } elseif (!empty($row['code']) && $product = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."products where code = '". database::input($row['code']) ."' limit 1;"))) { $product = new ent_product($product['id']); } elseif (!empty($row['sku']) && $product = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."products where sku = '". database::input($row['sku']) ."' limit 1;"))) { $product = new ent_product($product['id']); } elseif (!empty($row['mpn']) && $product = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."products where mpn = '". database::input($row['mpn']) ."' limit 1;"))) { $product = new ent_product($product['id']); } elseif (!empty($row['gtin']) && $product = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."products where gtin = '". database::input($row['gtin']) ."' limit 1;"))) { $product = new ent_product($product['id']); } if (!empty($product->data['id'])) { if (empty($batch['overwrite'])) { echo 'Skip updating existing product (ID: '. $product->data['id'] .') on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Updating existing product '. (!empty($row['name']) ? $row['name'] : '') .' (ID: '. $product->data['id'] .') on line '. $batch['counters']['line'] . PHP_EOL; $batch['counters']['updated']++; } else { if (empty($batch['insert'])) { echo 'Skip inserting new product on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Inserting new product '. (!empty($row['name']) ? $row['name'] : '') .' on line '. $batch['counters']['line'] . PHP_EOL; $batch['counters']['inserted']++; if (!empty($row['id'])) { database::query( "insert into ". DB_TABLE_PREFIX ."products (id, date_created)
                    values (". (int)$row['id'] .", '". date('Y-m-d H:i:s') ."');" ); $product = new ent_product($row['id']); } else { $product = new ent_product(); } } if (empty($row['manufacturer_id']) && !empty($row['manufacturer_name'])) { $manufacturers_query = database::query( "select * from ". DB_TABLE_PREFIX ."manufacturers
                  where name = '". database::input($row['manufacturer_name']) ."'
                  limit 1;" ); if ($manufacturer = database::fetch($manufacturers_query)) { $row['manufacturer_id'] = $manufacturer['id']; } else { $manufacturer = new ent_manufacturer(); $manufacturer->data['name'] = $row['manufacturer_name']; $manufacturer->save(); $row['manufacturer_id'] = $manufacturer->data['id']; } } if (empty($row['supplier_id']) && !empty($row['supplier_id'])) { $suppliers_query = database::query( "select * from ". DB_TABLE_PREFIX ."suppliers
                  where name = '". database::input($row['supplier_name']) ."'
                  limit 1;" ); if ($supplier = database::fetch($suppliers_query)) { $row['supplier_id'] = $supplier['id']; } else { $supplier = new ent_supplier(); $supplier->data['name'] = $row['supplier_name']; $supplier->save(); $row['supplier_id'] = $supplier->data['id']; } } $fields = [ 'status', 'default_catgeory_id', 'manufacturer_id', 'supplier_id', 'code', 'sku', 'mpn', 'gtin', 'taric', 'tax_class_id', 'quantity', 'quantity_unit_id', 'quantity_min', 'quantity_max', 'quantity_step', 'weight', 'weight_class', 'dim_x', 'dim_y', 'dim_z', 'dim_class', 'purchase_price', 'purchase_price_currency_code', 'recommended_price', 'delivery_status_id', 'sold_out_status_id', 'date_valid_from', 'date_valid_to', ]; foreach ($fields as $field) { if (isset($row[$field])) $product->data[$field] = $row[$field]; } if (isset($row['categories'])) { $product->data['categories'] = preg_split('#\s*,\s*#', $row['categories'], -1, PREG_SPLIT_NO_EMPTY); } if (!empty($row['currency_code'])) { if (isset($row['price'])) $product->data['prices'][$row['currency_code']] = $row['price']; } if (!empty($row['language_code'])) { $fields = [ 'name', 'short_description', 'description', 'technical_data', 'head_title', 'meta_description', ]; foreach ($fields as $field) { if (isset($row[$field])) $product->data[$field][$row['language_code']] = $row[$field]; } } if (empty($product->data['id'])) { $product->save(); } if (isset($row['images'])) { $row['images'] = preg_split('#;#', $row['images'], -1, PREG_SPLIT_NO_EMPTY); $product->data['images'] = []; foreach ($product->previous['images'] as $key => $image) { if (in_array($image['filename'], $row['images'])) { $product->data['images'][$key] = $image; } } foreach ($row['images'] as $filename) { if (!in_array($filename, array_column($product->data['images'], 'filename'))) { if (!is_file(FS_DIR_STORAGE . 'images/' . $filename)) continue; $checksum = md5(FS_DIR_STORAGE . 'images/' . $filename); database::query( "insert into ". DB_TABLE_PREFIX ."products_images
                      (product_id, filename, checksum)
                      values (". (int)$product->data['id'] .", '". database::input($filename) ."', '". database::input($checksum) ."');" ); $image_id = database::insert_id(); $product->data['images'][$image_id] = [ 'id' => $image_id, 'filename' => $filename, 'checksum' => $checksum, 'priority' => 0, ]; } } } if (!empty($row['new_images'])) { foreach (preg_split('#;#', $row['new_images'], -1, PREG_SPLIT_NO_EMPTY) as $new_image) { $product->add_image($new_image); } } if (isset($row['attributes'])) { $product->data['attributes'] = []; foreach (preg_split('#\R+#', $row['attributes'], -1, PREG_SPLIT_NO_EMPTY) as $attribute_row) { if (preg_match('#^([0-9]+):([0-9]+)$#', $attribute_row, $matches)) { $attribute = [ 'group_id' => $matches[1], 'value_id' => $matches[2], 'custom_value' => '', ]; } else if (preg_match('#^([0-9]+):"([^"]*)"#', $attribute_row, $matches)) { $attribute = [ 'group_id' => $matches[1], 'value_id' => 0, 'custom_value' => $matches[2], ]; } else { echo " - Skipping unknown attribute $attribute_row" . PHP_EOL; continue; } $product->data['attributes'][] = [ 'id' => isset($product->previous['attributes'][$attribute['group_id'].'-'.$attribute['value_id']]) ? $product->previous['attributes'][$attribute['group_id'].'-'.$attribute['value_id']]['id'] : null, 'group_id' => $attribute['group_id'], 'value_id' => $attribute['value_id'], 'custom_value' => $attribute['custom_value'], ]; } } $product->save(); if (!empty($row['date_created'])) { database::query( "update ". DB_TABLE_PREFIX ."products
                  set date_created = '". date('Y-m-d H:i:s', strtotime($row['date_created'])) ."'
                  where id = ". (int)$product->data['id'] ."
                  limit 1;" ); } break; case 'suppliers': if (!empty($row['id']) && $supplier = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."suppliers where id = ". (int)$row['id'] ." limit 1;"))) { $supplier = new ent_supplier($supplier['id']); } else if (!empty($row['code']) && $supplier = database::fetch(database::query("select id from ". DB_TABLE_PREFIX ."suppliers where code = '". database::input($row['code']) ."' limit 1;"))) { $supplier = new ent_supplier($supplier['id']); } if (!empty($supplier->data['id'])) { if (empty($batch['overwrite'])) { echo 'Skip updating existing supplier on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Updating existing supplier '. (!empty($row['name']) ? $row['name'] : 'on line '. $batch['counters']['line']) . PHP_EOL; $batch['counters']['updated']++; } else { if (empty($batch['insert'])) { echo 'Skip inserting new supplier on line '. $batch['counters']['line'] . PHP_EOL; continue 2; } echo 'Inserting new supplier: '. (!empty($row['name']) ? $row['name'] : 'on line '. $batch['counters']['line']) . PHP_EOL; $batch['counters']['inserted']++; if (!empty($row['id'])) { database::query( "insert into ". DB_TABLE_PREFIX ."suppliers (id, date_created)
                    values (". (int)$row['id'] .", '". date('Y-m-d H:i:s') ."');" ); $supplier = new ent_supplier($row['id']); } else { $supplier = new ent_supplier(); } } $fields = [ 'status', 'code', 'name', 'description', 'email', 'phone', 'link', ]; foreach ($fields as $field) { if (isset($row[$field])) $supplier->data[$field] = $row[$field]; } $supplier->save(); if (!empty($row['date_created'])) { database::query( "update ". DB_TABLE_PREFIX ."suppliers
                  set date_created = '". date('Y-m-d H:i:s', strtotime($row['date_created'])) ."'
                  where id = ". (int)$supplier->data['id'] ."
                  limit 1;" ); } break; default: throw new Exception('Unknown type'); } } catch (Exception $e) { if (isset($batch['onerror']) && $batch['onerror'] == 'resume') { echo 'Error: '. $e->getMessage() . PHP_EOL; } else { throw $e; } } } unset(session::$data['csv_batch']); echo PHP_EOL . 'Completed!'; notices::add('success', language::translate('success_import_completed', 'Import completed')); header('Refresh: 5; url='. document::link(null, [], ['app', 'doc'], 'resume')); exit; } catch (Exception $e) { unset(session::$data['csv_batch']); notices::add('errors', $e->getMessage()); echo 'Error: ' . $e->getMessage(); header('Refresh: 5; url='. document::link(null, [], ['app', 'doc'], 'resume')); exit; } } if (isset($_POST['export'])) { try { ini_set('memory_limit', -1); if (empty($_POST['type'])) throw new Exception(language::translate('error_must_select_type', 'You must select type')); $csv = []; switch ($_POST['type']) { case 'attributes': if (empty($_POST['language_code'])) throw new Exception(language::translate('error_must_select_a_language', 'You must select a language')); $attributes_query = database::query( "select ag.id as group_id, ag.code as group_code, agi.name as group_name, av.id as value_id, avi.name as value_name, avi.language_code, av.priority from ". DB_TABLE_PREFIX ."attribute_values av
              left join ". DB_TABLE_PREFIX ."attribute_groups ag on (ag.id = av.group_id)
              left join ". DB_TABLE_PREFIX ."attribute_groups_info agi on (agi.group_id = av.group_id and agi.language_code = '". database::input($_POST['language_code']) ."')
              left join ". DB_TABLE_PREFIX ."attribute_values_info avi on (avi.value_id = av.id and avi.language_code = '". database::input($_POST['language_code']) ."')
              order by agi.name, av.priority;" ); while ($attribute = database::fetch($attributes_query)) { $csv[] = $attribute; } break; case 'campaigns': $campaign_query = database::query( "select * from ". DB_TABLE_PREFIX ."products_campaigns
            order by product_id;" ); if (!database::num_rows($campaign_query)) { $fields_query = database::query( "show fields from ". DB_TABLE_PREFIX ."products_campaigns;" ); $csv[] = database::fetch($fields_query); break; } while ($campaign = database::fetch($campaign_query)) { $csv[] = $campaign; } break; case 'categories': if (empty($_POST['language_code'])) throw new Exception(language::translate('error_must_select_a_language', 'You must select a language')); $categories_query = database::query( "select c.*, c2.code as parent_code, ci.name, ci.short_description, ci.description, ci.meta_description, ci.head_title, ci.h1_title
            from ". DB_TABLE_PREFIX ."categories c
            left join ". DB_TABLE_PREFIX ."categories c2 on (c2.id = c.parent_id)
            left join ". DB_TABLE_PREFIX ."categories_info ci on (ci.category_id = c.id and ci.language_code = '". database::input($_POST['language_code']) ."')
            order by c.priority;" ); while ($category = database::fetch($categories_query)) { $csv[] = [ 'id' => $category['id'], 'status' => $category['status'], 'parent_id' => $category['parent_id'], 'parent_code' => $category['parent_code'], 'code' => $category['code'], 'name' => $category['name'], 'keywords' => $category['keywords'], 'short_description' => $category['short_description'], 'description' => $category['description'], 'meta_description' => $category['meta_description'], 'head_title' => $category['head_title'], 'h1_title' => $category['h1_title'], 'image' => $category['image'], 'new_image' => '', 'priority' => $category['priority'], 'language_code' => $_POST['language_code'], ]; } break; case 'manufacturers': if (empty($_POST['language_code'])) throw new Exception(language::translate('error_must_select_a_language', 'You must select a language')); $manufacturers_query = database::query( "select m.*, mi.short_description, mi.description, mi.meta_description, mi.head_title, mi.h1_title
            from ". DB_TABLE_PREFIX ."manufacturers m
            left join ". DB_TABLE_PREFIX ."manufacturers_info mi on (mi.manufacturer_id = m.id and mi.language_code = '". database::input($_POST['language_code']) ."')
            order by m.name;" ); while ($manufacturer = database::fetch($manufacturers_query)) { $csv[] = [ 'id' => $manufacturer['id'], 'status' => $manufacturer['status'], 'code' => $manufacturer['code'], 'name' => $manufacturer['name'], 'keywords' => $manufacturer['keywords'], 'short_description' => $manufacturer['short_description'], 'description' => $manufacturer['description'], 'meta_description' => $manufacturer['meta_description'], 'head_title' => $manufacturer['head_title'], 'h1_title' => $manufacturer['h1_title'], 'image' => $manufacturer['image'], 'new_image' => '', 'priority' => $manufacturer['priority'], 'language_code' => $_POST['language_code'], ]; } break; case 'products': if (empty($_POST['language_code'])) throw new Exception(language::translate('error_must_select_a_language', 'You must select a language')); if (empty($_POST['currency_code'])) throw new Exception(language::translate('error_must_select_a_currency', 'You must select a currency')); $products_query = database::query( "select p.*, pi.name, pi.description, pi.short_description, pi.technical_data, pi.meta_description, pi.head_title, p2c.categories, pp.price, pim.images, pa.attributes
            from ". DB_TABLE_PREFIX ."products p
            left join ". DB_TABLE_PREFIX ."products_info pi on (pi.product_id = p.id and pi.language_code = '". database::input($_POST['language_code']) ."')
            left join ". DB_TABLE_PREFIX ."manufacturers m on (m.id = p.manufacturer_id)
            left join (
              select product_id, group_concat(category_id separator ',') as categories
              from ". DB_TABLE_PREFIX ."products_to_categories
              group by product_id
              order by category_id
            ) p2c on (p2c.product_id = p.id)
            left join (
              select product_id, group_concat(concat(group_id, ':', if(custom_value != '', concat('\"', custom_value, '\"'), value_id)) separator '\r\n') as attributes
              from ". DB_TABLE_PREFIX ."products_attributes
              group by product_id
            ) pa on (p.id = pa.product_id)
            left join (
              select product_id, group_concat(filename separator ';') as images
              from ". DB_TABLE_PREFIX ."products_images
              group by product_id
              order by priority
            ) pim on (pim.product_id = p.id)
            left join (
              select product_id, `". database::input($_POST['currency_code']) ."` as price
              from ". DB_TABLE_PREFIX ."products_prices
            ) pp on (pp.product_id = p.id)
            order by pi.name, pi.id;" ); while ($product = database::fetch($products_query)) { $csv[] = [ 'id' => $product['id'], 'status' => $product['status'], 'categories' => $product['categories'], 'default_category_id' => $product['default_category_id'], 'manufacturer_id' => $product['manufacturer_id'], 'supplier_id' => $product['supplier_id'], 'code' => $product['code'], 'sku' => $product['sku'], 'mpn' => $product['mpn'], 'gtin' => $product['gtin'], 'taric' => $product['taric'], 'name' => $product['name'], 'short_description' => $product['short_description'], 'description' => $product['description'], 'keywords' => $product['keywords'], 'technical_data' => $product['technical_data'], 'head_title' => $product['head_title'], 'meta_description' => $product['meta_description'], 'images' => $product['images'], 'new_images' => '', 'attributes' => $product['attributes'], 'purchase_price' => (float)$product['purchase_price'], 'purchase_price_currency_code' => $product['purchase_price_currency_code'], 'recommended_price' => (float)$product['recommended_price'], 'price' => (float)$product['price'], 'tax_class_id' => $product['tax_class_id'], 'quantity' => (float)$product['quantity'], 'quantity_unit_id' => $product['quantity_unit_id'], 'quantity_min' => $product['quantity_min'], 'quantity_max' => $product['quantity_max'], 'quantity_step' => $product['quantity_step'], 'weight' => (float)$product['weight'], 'weight_class' => $product['weight_class'], 'dim_x' => (float)$product['dim_x'], 'dim_y' => (float)$product['dim_y'], 'dim_z' => (float)$product['dim_z'], 'dim_class' => $product['dim_class'], 'delivery_status_id' => $product['delivery_status_id'], 'sold_out_status_id' => $product['sold_out_status_id'], 'language_code' => $_POST['language_code'], 'currency_code' => $_POST['currency_code'], 'date_valid_from' => $product['date_valid_from'], 'date_valid_to' => $product['date_valid_to'], ]; } break; case 'suppliers': $suppliers_query = database::query( "select * from ". DB_TABLE_PREFIX ."suppliers
              order by id;" ); while ($supplier = database::fetch($suppliers_query)) { $csv[] = [ 'id' => $supplier['id'], 'status' => $supplier['status'], 'code' => $supplier['code'], 'name' => $supplier['name'], 'keywords' => $supplier['keywords'], 'description' => $supplier['description'], 'email' => $supplier['email'], 'phone' => $supplier['phone'], 'link' => $supplier['link'], ]; } break; default: throw new Exception('Unknown type'); } ob_end_clean(); if ($_POST['output'] == 'screen') { header('Content-Type: text/plain; charset='. $_POST['charset']); } else { header('Content-Type: application/csv; charset='. $_POST['charset']); header('Content-Disposition: attachment; filename='. $_POST['type'] . (!empty($_POST['language_code']) ? '-'. $_POST['language_code'] : '') . (!empty($_POST['currency_code']) ? '-'. $_POST['currency_code'] : '') .'.csv'); } switch($_POST['eol']) { case 'Linux': echo functions::csv_encode($csv, $_POST['delimiter'], $_POST['enclosure'], $_POST['escapechar'], $_POST['charset'], "\r"); break; case 'Mac': echo functions::csv_encode($csv, $_POST['delimiter'], $_POST['enclosure'], $_POST['escapechar'], $_POST['charset'], "\n"); break; case 'Win': default: echo functions::csv_encode($csv, $_POST['delimiter'], $_POST['enclosure'], $_POST['escapechar'], $_POST['charset'], "\r\n"); break; } exit; } catch (Exception $e) { notices::add('errors', $e->getMessage()); } } ?>
<div class="card card-app">
  <div class="card-header">
    <div class="card-title">
      <?php echo $app_icon; ?> <?php echo language::translate('title_csv_import_export', 'CSV Import/Export'); ?>
    </div>
  </div>

  <div class="card-body">

    <div class="row" style="max-width: 980px;">

      <div class="col-xl-6">
        <?php echo functions::form_draw_form_begin('import_form', 'post', '', true); ?>

          <fieldset>
            <legend><?php echo language::translate('title_import', 'Import'); ?></legend>

            <div class="form-group">
              <label><?php echo language::translate('title_type', 'Type'); ?></label>
              <div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'attributes', true, 'data-dependencies="language"'); ?> <?php echo language::translate('title_attributes', 'Attributes'); ?></label></div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'campaigns', true); ?> <?php echo language::translate('title_campaigns', 'Campaigns'); ?></label></div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'categories', true); ?> <?php echo language::translate('title_categories', 'Categories'); ?></label></div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'manufacturers', true); ?> <?php echo language::translate('title_manufacturers', 'Manufacturers'); ?></label></div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'products', true); ?> <?php echo language::translate('title_products', 'Products'); ?></label></div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'suppliers', true); ?> <?php echo language::translate('title_suppliers', 'Suppliers'); ?></label></div>
              </div>
            </div>

            <div class="form-group">
              <label><?php echo language::translate('title_csv_file', 'CSV File'); ?></label>
              <?php echo functions::form_draw_file_field('file'); ?>
            </div>

            <div class="row">
              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_delimiter', 'Delimiter'); ?></label>
                <?php echo functions::form_draw_select_field('delimiter', [[language::translate('title_auto', 'Auto') .' ('. language::translate('text_default', 'default') .')', ''], [','], [';'], ['TAB', "\t"], ['|']], true); ?>
              </div>

              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_enclosure', 'Enclosure'); ?></label>
                <?php echo functions::form_draw_select_field('enclosure', [['" ('. language::translate('text_default', 'default') .')', '"']], true); ?>
              </div>
            </div>

            <div class="row">
              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_escape_character', 'Escape Character'); ?></label>
                <?php echo functions::form_draw_select_field('escapechar', [['" ('. language::translate('text_default', 'default') .')', '"'], ['\\', '\\']], true); ?>
              </div>

              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_charset', 'Charset'); ?></label>
                <?php echo functions::form_draw_encodings_list('charset', !empty($_POST['charset']) ? true : 'UTF-8'); ?>
              </div>
            </div>

            <div class="form-group">
              <div class="checkbox"><label><?php echo functions::form_draw_checkbox('insert', '1', true); ?> <?php echo language::translate('text_insert_new_entries', 'Insert new entries'); ?></label></div>
              <div class="checkbox"><label><?php echo functions::form_draw_checkbox('overwrite', '1', true); ?> <?php echo language::translate('text_overwrite_existing_entries', 'Overwrite existing entries'); ?></label></div>
            </div>

            <div class="form-group">
              <label><?php echo language::translate('title_on_error', 'On Error'); ?></label>
              <label><?php echo functions::form_draw_radio_button('onerror', 'abort', isset($_POST['onerror']) ? true : 'abort'); ?> <?php echo language::translate('title_abort_operation', 'Abort Operation'); ?></label>
              <label><?php echo functions::form_draw_radio_button('onerror', 'resume', isset($_POST['onerror']) ? true : ''); ?> <?php echo language::translate('title_resume_next', 'Resume Next'); ?></label>
            </div>

            <?php echo functions::form_draw_button('import', language::translate('title_import', 'Import'), 'submit'); ?>
          </fieldset>

        <?php echo functions::form_draw_form_end(); ?>
      </div>

      <div class="col-xl-6">
        <?php echo functions::form_draw_form_begin('export_form', 'post'); ?>

          <fieldset>
            <legend><?php echo language::translate('title_export', 'Export'); ?></legend>

            <div class="form-group">
              <label><?php echo language::translate('title_type', 'Type'); ?></label>
              <div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'attributes', true, 'data-dependencies="language"'); ?> <?php echo language::translate('title_attributes', 'Attributes'); ?></label></div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'campaigns', true); ?> <?php echo language::translate('title_campaigns', 'Campaigns'); ?></label></div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'categories', true, 'data-dependencies="language"'); ?> <?php echo language::translate('title_categories', 'Categories'); ?></label></div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'manufacturers', true, 'data-dependencies="language"'); ?> <?php echo language::translate('title_manufacturers', 'Manufacturers'); ?></label></div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'products', true, 'data-dependencies="currency,language"'); ?> <?php echo language::translate('title_products', 'Products'); ?></label></div>
                <div class="checkbox"><label><?php echo functions::form_draw_radio_button('type', 'suppliers', true); ?> <?php echo language::translate('title_suppliers', 'Suppliers'); ?></label></div>
              </div>
            </div>

            <div class="row">
              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_language', 'Language'); ?></label>
                <?php echo functions::form_draw_languages_list('language_code', true, false, 'required'); ?>
              </div>

              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_currency', 'Currency'); ?></label>
                <?php echo functions::form_draw_currencies_list('currency_code', true, false, 'required'); ?>
              </div>
            </div>

            <div class="row">
              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_delimiter', 'Delimiter'); ?></label>
                <?php echo functions::form_draw_select_field('delimiter', [[', ('. language::translate('text_default', 'default') .')', ','], [';'], ['TAB', "\t"], ['|']], true); ?>
              </div>

              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_enclosure', 'Enclosure'); ?></label>
                <?php echo functions::form_draw_select_field('enclosure', [['" ('. language::translate('text_default', 'default') .')', '"']], true); ?>
              </div>
            </div>

            <div class="row">
              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_escape_character', 'Escape Character'); ?></label>
                <?php echo functions::form_draw_select_field('escapechar', [['" ('. language::translate('text_default', 'default') .')', '"'], ['\\', '\\']], true); ?>
              </div>

              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_charset', 'Charset'); ?></label>
                <?php echo functions::form_draw_encodings_list('charset', !empty($_POST['charset']) ? true : 'UTF-8'); ?>
              </div>
            </div>

            <div class="row">
              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_line_ending', 'Line Ending'); ?></label>
                <?php echo functions::form_draw_select_field('eol', [['Win'], ['Mac'], ['Linux']], true); ?>
              </div>

              <div class="form-group col-sm-6">
                <label><?php echo language::translate('title_output', 'Output'); ?></label>
                <?php echo functions::form_draw_select_field('output', [[language::translate('title_file', 'File'), 'file'], [language::translate('title_screen', 'Screen'), 'screen']], true); ?>
              </div>
            </div>

            <?php echo functions::form_draw_button('export', language::translate('title_export', 'Export'), 'submit'); ?>
          </fieldset>

        <?php echo functions::form_draw_form_end(); ?>
      </div>

    </div>
  </div>
</div>

<script>
  $('form[name="export_form"] input[name="type"]').change(function(){
    var dependencies = $(this).data('dependencies') ? $(this).data('dependencies').split(',') : [];
    $('form[name="export_form"] select[name="currency_code"]').prop('disabled', ($.inArray('currency', dependencies) === -1));
    $('form[name="export_form"] select[name="language_code"]').prop('disabled', ($.inArray('language', dependencies) === -1));
  });

  $('form[name="export_form"] input[name="type"]:checked').trigger('change');
</script>