Пишем модуль "Импорт товаров OpenCart", часть 2

Опубликовано: Комментариев: 3
Пишем модуль "Импорт товаров OpenCart", часть 2

Пришло время логического завершения саги под названием "Модуль импорта товаров в Opencart". Для тех, кто не читал первую часть, прошу ознакомиться с содержимым первой статьи: Пишем модуль "Импорт товаров OpenCart", часть 1.

Итак, в тот раз мы остановились на том, что создали все файлы заглушки и сейчас вопрос в реализации непосредственного парсинга и сохранения данных из CSV в БД Opencart.

Ссылка на Bitbucket с работающим плагином: bitbucket.org/Kolpikov/opencart-product-import-module

Тепреь нужно понять, в каком формате нужно передать данные в модель для сохранения товара. В данном случае самый простой вариант состоит в том, чтобы подсмотреть как система сохраняет товары к себе в админке и скопировать данный процесс. Для этого я открываю метод addProduct()  в модели admin/model/catalog/product.php:3 и ставлю breakpoint в IDE в первой же строчке к тела данного метода модели.

Затем открывю админ панель, заполняю поля, которые меня интересуют и жму добавить товар. В итоге я могу видеть массив $data, который система передает в модель:

Модуль импорта товаров Opencart, пример данных

Если нет дебаггера, то просто сделайте var_dump и die перед вызовом сохранения в БД, чтоб увидеть сформированный массив.

Теперь мы знаем, какие данные от нас ожидает получить метод addProduct(), принадлежащий модели catalog/product и можем собрать аналогичный массив с нужными полями

Теперь, когда понятно как формировать массив - можно переходить к кодингу.

1. Пишем метод импорта товаров из CSV

Открываем файл admin/controller/tool/import.php и добавляем после строки:

$this->document->setTitle($this->language->get('heading_title'));

Следующий код:

if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->user->hasPermission('modify', 'tool/import')) {
	if (is_uploaded_file($this->request->files['import']['tmp_name'])) {
		$file = $this->request->files['import']['tmp_name'];
	} else {
		$file = false;
	}


	if ($file && ($handle = fopen($file, "r")) !== false ) {
		$this->import_products($handle);
		fclose($handle);

		$this->session->data['success'] = $this->language->get('text_success');

		$this->response->redirect($this->url->link('tool/import', 'token=' . $this->session->data['token'], true));
	} else {
		$this->error['warning'] = $this->language->get('error_empty');
	}
}

Данный код отвечает за то, чтобы проверить есть ли у текущего пользователя права модицикации для страницы tool/import, и что файл с данными был загружен, и если все норм - пробует открыть файл для чтения и передать ресурс в метод import_products(), который вытащий построчно все данные о товарах.

В общем-то не важно куда именно вставить этот кусочек кода. Но полистав контроллеры Opencart, я пришел к выводу, что в их эко-системе такие вызовы уместней всего располагать именно вот так. 

Теперь реализуем метод import_products() в нашем контроллере:

private function import_products($handle)
{
	$this->load->model('catalog/product');
	$this->load->model('localisation/language');

	$languages = $this->model_localisation_language->getLanguages();


	while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) // Читает строку из файла и производит разбор данных CSV
	{
		$product_description = [];
		foreach ($languages as $language) {
			$product_description[$language['language_id']] = [
				'name' => $data[3], // имя
				'description' => $data[4], //item_desc
				'meta_title' => $data[3], // title = имя
				'meta_h1' => $data[3], // title = имя
				'meta_description' => $data[13],
				'meta_keyword' => $data[12],
				'tag' => '',
			];
		}

		$prod_data = array(
			'product_description' => $product_description,
			'model' => $data[2], //артикул
			'sku' => "",
			'upc' => "",
			'ean' => "",
			'jan' => "",
			'isbn' => "",
			'mpn' => "",
			'location' => "",
			'price' => $data[10],
			'tax_class_id' => "0",
			'quantity' => "1",
			'minimum' => "1",
			'subtract' => "1",
			'stock_status_id' => "6", //статус, когда нет в наличии
			'shipping' => "1",
			'keyword' => $data[6], //seo url
			'date_available' => $data[19],
			'length' => "",
			'width' => "",
			'height' => "",
			'length_class_id' => "1",
			'weight' => "",
			'weight_class_id' => "1",
			'status' => $data[16],
			'sort_order' => "1",
			'manufacturer' => "",
			'manufacturer_id' => "0",
			'category' => '',
			'product_category' => explode(',' , $data[1]),
			'filter' => "",
			'product_store' => array("0"),
			'download' => "",
			'related' => "",
			'option' => "",
			'image' => "",
			'points' => "",
			'product_reward' => array('1' => array('points' => "")),
			'product_layout' => array(""),
			'date_added' => $data[18],
			'supplier_id' => (!empty($data[8])) ? $data[8] : '',
			'cost' => (!empty($data[9])) ? $data[9] : '',
			'notes' => (!empty($data[17])) ? $data[17] : '',
		);
		if (!empty($data[11])) {
			$prod_data['product_discount'] = array(
				array('customer_group_id' => '1',
					'quantity' => "",
					'priority' => "",
					'price' => $data[11],
					'date_start' => "",
					'date_end' => ""
				)
			);
		}
		if ( !empty($data[20]) ) // Основное фото
			$prod_data["image"] = $data[20];

		if ( !empty($data[21]) ) // Доп. фото
		{
			$other_photos = explode(';',$data[21]);
			if( ($key = array_search($data[20],$other_photos)) !== false )
				unset($other_photos[$key]);
			foreach ($other_photos as $other_photo) {
				$prod_data["product_image"][] = array('image' => $other_photo,
					'sort_order' => ''
				);
			}
		}
		$this->model_catalog_product->addProduct($prod_data);
	}
}

Ну вот и всё! Логика готова!

2. Подготавливаем модуль к автоматической установке

Чтобы иметь возможность автоматически устанавливать модуль через менеджер модулей Opencart нам нужно вынести все файлы в отдельную папку, расположить их в порядке, как я показывал на скрин-шоте в первом уроке и затем запаковать в zip архив.

Структура файлов для модуля OpenCart

После чего модуль можно легко добавлять на различные Opencart'ы версии 2.2.0.0 с минимальными затратами времени! Не забудьте только добавить права для группы пользователей на просмотр и редактирование tool/import

Всем спасибо за внимание!

Исходники тут: bitbucket.org/Kolpikov/opencart-product-import-module

Войдите, чтобы оставить комментарий
Комментариев: 3
Pirantul 2019-06-10 23:00:36
Отличный и очень полезный модуль. Спасибо автору за статью! Только ссылка на bitbacket выдает: Access denied
Slicks 2019-06-13 06:32:09
Pirantul, спасибо, поправил. Скорее всего, что я случайно закрыл к нему доступ, когда наводил порядок в репозиториях :)
Алекс Ник 2020-02-25 08:24:25
Спасибо за статью. Очень хотелось бы посмотреть на колонки файла CSV А главное не понятно с фотографиями, в фале CSV ссылки на эти файлы, файлы фото уже в хранилище или они перенесутся туда?