Sereke
Новачок-
Публікації
1 -
З нами
-
Відвідування
Відвідувачі профілю
Блок відвідувачів профілю відключений і не буде доступний широкому іншим користувачам
Sereke's Achievements
-
Добрый вечер! Я просто не мог не поделиться своей радостью и своим модификатором, учитывая сколько времени "убил" на его создание с помощью Gemini. Что я только не делал - и отправлял ему файл export_import.php кучу раз, и структуру и примеры строк таблицы oc_product, и бесконечные ошибки из лога opencart... Ничего не получалось, не мог он никак сообразить до конца где что на что менять и добавлять, хотя логика у него была правильная... в итоге плюнул и сам внимательно стал изучать как устроен файл export_import.php. Менять его мне не хотелось изначально, а хотелось сделать полноценный модификатор ocmod с установкой и видимостью в админ-панели. Я открыл по-олдскульному файл export_import.php, нашёл все места, где встречалось слово location и проследил построчно что откуда берётся и что куда вставляется )) Почему именно location? Да просто потому что это одно из текстовых стандартных полей таблицы oc_product, в котором также было и моё нестандартное поле video, которое в свою очередь по умолчанию и не экспортировалось/импортировалось модулем Export/Import Tool (V4.17.9) for OpenCart 3.x. Кстати я использую версию ocStore 3.0.3.7 Когда я разобрался с полем location, то на всякий случай ещё проследил как работают другие jan, image_name, model - более-менее стало понятно куда и какие строки в коде нужно добавить, а какие заменить, чтобы в конечном экспортируемом файле XLSX появилась новая колонка video, в которой будут храниться строки из столбца video таблицы oc_product моей базы данных. Ну, и само-собой, чтоб наоборот при импорте всё обратно из XLSX грузилось в БД. Получился довольно простой симпатичный модификатор, в котором я в комментариях очень подробно расписал где что как и почему я добавлял или заменял. P.S. Добавлю напоследок, что ошибка Gemini была в том, что он пытался менять фрагменты строк или sql-запросов, а я пошёл другим путём (кстати спасибо Maksikus , именно его стиль и модификатор я брал как основу, там ищутся и заменяются в основном целые строки, блоки или переменные целиком, а также удобный стиль оформления кода, чтобы не запутаться). А вот Gemini путался из-за разных отступов, пробелов, переносов строк и пр... А вообще "ему" тоже спасибо и респект за подсказки и идеи где копать. И ещё надо быть очень внимательным к кодировке файла install.xml , тегам (особенно <code>) и комментариям внутри, названию и версиям своего ocmod, упаковке в архив .ocmod.zip для загрузки, чистке кеша, проверке журнала логов в модификаторах после установки и пр. Всем желаю успехов. Надеюсь, мой пост и мод пригодится и сэкономит кучу времени! Привожу код полностью ниже, а во вложении - полноценный архив, который можно поставить через установку расширений в админ-панели <?xml version="1.0" encoding="utf-8"?> <modification> <name>Export/Import Tool - Add Video Column v007</name> <code>Add_video_column_export_import_tool_v007</code> <version>007</version> <author>Sergey</author> <!-- Описание: - Добавление допополнительного столбца video в экспортируемый файл XLSX, т.к. стандарный модуль игорирует нестандартные поля. Также чтение этого поля из XLSX при импорте в БД. Колонка video создаётся в таблице oc_product БД для хранения ссылки и описания ПЕРВОГО видео по аналогии с первым фото в image - модулем Видео Youtube на странице товара - https://https://opencartforum.com/files//xprolance Изменение в файле: admin/model/extension/export_import.php - Export/Import Tool (V4.17.9) За основу берём по всему коду привязку к полю и переменной для "location", т.к. это 1) аналогичный текстовый столбец только (!) в таблице БД oc_product 2) его удобно искать и ориентироваться по нему где что куда вставлять и заменять 3) если взять к примеру поле image , то оно встречается ещё в куче ненужных нам функций, таблицах и пр. Помимо этого может возникнуть путаница, т.к. в таблице БД oc_product оно называется "image",а в XLSX - "image_name" Хотя своё поле video в XLSX я задумал вставить именно справа (следом) с "image_name" !!! Поэтому порой придётся учитывать этот момент, особенно когда перебор колонок в XLSX --> <file path="admin/model/extension/export_import.php"> <!-- здень ничего не меняем, т.к. этот "Location" вообще никак не связан с нашей темой! <operation> <search><![CDATA[ header('Location: ' . str_replace(array('&', "\n", "\r"), array('&', '', ''), $link)); ]]></search> </operation> --> <!-- в этом месте кода по аналогии с $location создаём переменную $video - в которую запишем "очищенное = экранированное" значение из массива $product --> <operation><!-- 1042 - storeProductIntoDatabase --> <search><![CDATA[ $location = $this->db->escape($product['location']); ]]></search> <add position="after"><![CDATA[ $video = $this->db->escape($product['video']); ]]></add> </operation> <!-- Теперь ту переменную $video используем в SQL - запросе для импорта в таблицу БД по аналогии опять же с "location". Для этого заменяем всю строку - так проще Последовательность и название полей имеет значение --> <operation><!-- 1065 - storeProductIntoDatabase --> <search><![CDATA[ $sql .= "`location`,`stock_status_id`,`model`,`manufacturer_id`,`image`,`shipping`,`price`,`points`,`date_added`,`date_modified`,`date_available`,`weight`,`weight_class_id`,`status`,"; ]]></search> <add position="replace"><![CDATA[ $sql .= "`location`,`stock_status_id`,`model`,`manufacturer_id`,`image`,`video`,`shipping`,`price`,`points`,`date_added`,`date_modified`,`date_available`,`weight`,`weight_class_id`,`status`,"; ]]></add> </operation> <operation><!-- 1072 - storeProductIntoDatabase --> <search><![CDATA[ $sql .= "'$location',$stock_status_id,'$model',$manufacturer_id,'$image',$shipping,$price,$points,"; ]]></search> <add position="replace"><![CDATA[ $sql .= "'$location',$stock_status_id,'$model',$manufacturer_id,'$image','$video',$shipping,$price,$points,"; ]]></add> </operation> <!-- Здесь идёт именно вставка в таблицу XLSX по порядку. Я хочу, чтобы video было вставлено справа от image_name, поэтому привязываюсь именно к $image_name Можно было "привяться" и к $location = $this->getCell($data,$i,$j++,''); в строке 1344 и отступить 4 строки вниз, но отступы - хрупкая конструкция в случае обновления модуля или изменения самого кода файла, например. Даже одна новая пустая строка и всё может поплыть, а так - всё чётко вставится, сразу после $image_name! --> <operation><!-- 1348 - uploadProducts --> <search><![CDATA[ $image_name = $this->getCell($data,$i,$j++); ]]></search> <add position="after"><![CDATA[ $video = $this->getCell($data,$i,$j++); ]]></add> </operation> <!-- здесь идёт просто объявление переменных и запись их в массив $product[], поэтому для удобства поиска по коду опять привяжемся к location и по аналогии вставим значение из переменной $video в массив $product[] --> <operation><!-- 1463 - uploadProducts --> <search><![CDATA[ $product['location'] = $location; ]]></search> <add position="after"><![CDATA[ $product['video'] = $video; ]]></add> </operation> <!-- далее по коду у нас есть функция объединения массивов - для проверки товаров Проще заменить всю строку, добавив в неё в нужном месте video по аналогии с location --> <operation><!-- 4054 - validateProducts --> <search><![CDATA[ $expected_heading = array_merge( $expected_heading, array( "location", "quantity", "model", "manufacturer", "image_name", "shipping", "price", "points", "date_added", "date_modified", "date_available", "weight", "weight_unit", "length", "width", "height", "length_unit", "status", "tax_class_id", "description") ); ]]></search> <add position="replace"><![CDATA[ $expected_heading = array_merge( $expected_heading, array( "location", "quantity", "model", "manufacturer", "image_name", "video", "shipping", "price", "points", "date_added", "date_modified", "date_available", "weight", "weight_unit", "length", "width", "height", "length_unit", "status", "tax_class_id", "description") ); ]]></add> </operation> <!-- Аналогичная замена переменной $expected_heading. В коде это всё делается для проверки версии OpenCart, наличия "seo_keyword", но нам это не суть важно. Раз здесь еcть location, то и наш video по аналогии вставляем --> <operation><!-- 4056 - validateProducts --> <search><![CDATA[ $expected_heading = array_merge( $expected_heading, array( "location", "quantity", "model", "manufacturer", "image_name", "shipping", "price", "points", "date_added", "date_modified", "date_available", "weight", "weight_unit", "length", "width", "height", "length_unit", "status", "tax_class_id", "seo_keyword", "description") ); ]]></search> <add position="replace"><![CDATA[ $expected_heading = array_merge( $expected_heading, array( "location", "quantity", "model", "manufacturer", "image_name", "video", "shipping", "price", "points", "date_added", "date_modified", "date_available", "weight", "weight_unit", "length", "width", "height", "length_unit", "status", "tax_class_id", "seo_keyword", "description") ); ]]></add> </operation> <!-- Здесь идёт именно извлечение из таблицы XLSX по порядку. Поскольку video по моей задумке должно быть справа от image_name, то привязываюсь именно к $sql .= " p.image AS image_name,"; Можно было "привяться" и к $sql .= " p.location,"; в строке 6793 и отступить 4 строки вниз, но это хрупкая конструкция на будущее --> <operation><!-- 6797 - getProducts --> <search><![CDATA[ $sql .= " p.image AS image_name,"; ]]></search> <add position="after"><![CDATA[ $sql .= " p.video,"; ]]></add> </operation> <!-- В этих строках уставливается ширина колонки в XLSX. По аналогии с image_name устанавливаем ниже ширину и для video, причём сразу же после image_name, ведь перебор колонок в XLSX идёт по порядку! --> <operation><!-- 6924 - populateProductsWorksheet --> <search><![CDATA[ $worksheet->getColumnDimensionByColumn($j++)->setWidth(max(strlen('image_name'),12)+1); ]]></search> <add position="after"><![CDATA[ $worksheet->getColumnDimensionByColumn($j++)->setWidth(max(strlen('video'),12)+1); ]]></add> </operation> <!-- ниже в этой же функции вставки данных из таблицы (точнее, таблиц) БД в XLSX идёт формирование заголовков и стиль (формат) строк - текст, вес, цена и пр. По аналогии с "image_name" и сразу после него делаем и для "video" - текстовый формат и название колонки --> <operation><!-- 7007 - populateProductsWorksheet --> <search><![CDATA[ $data[$j++] = 'image_name'; ]]></search> <add position="after"><![CDATA[ $styles[$j] = &$text_format; $data[$j++] = 'video'; ]]></add> </operation> <!-- Здесь идёт непосредственно вставка значений в строки XLSX по порядку в зависимости от ключа массива $row (он же $products). Поэтому опять привязываемся к колонке image_name, и после того как из неё все строки вставили, переходим к следующей по порядку колонке video, берем значения и вставляем по очереди в строки --> <operation><!-- 7097 - populateProductsWorksheet --> <search><![CDATA[ $data[$j++] = $row['image_name']; ]]></search> <add position="after"><![CDATA[ $data[$j++] = $row['video']; ]]></add> </operation> </file> </modification> video-column-add-export-import-tool-v007.ocmod.zip