From 174341c1091839c0cbe4ffe51f75dbd184902f5d Mon Sep 17 00:00:00 2001 From: MadFisherman Date: Sun, 17 Apr 2022 22:59:07 +0300 Subject: [PATCH 1/2] APinyansky/hw13 --- README.md | 15 +- after/FeedParser/FeedParserInterface.php | 21 +++ after/FeedParser/ManufacturerFeedParser.php | 72 +++++++++ after/FileParser/ExcelParser.php | 25 +++ after/FileParser/FileParserInterface.php | 14 ++ after/FileParser/XmlParser.php | 25 +++ after/Service/FeedsImportTempTable.php | 18 +++ after/Service/FeedsImporter.php | 109 +++++++++++++ after/Tools/ImportHelper.php | 35 +++++ after/after.svg | 4 + before/FeedParser.php | 104 +++++++++++++ before/FeedsImporter.php | 164 ++++++++++++++++++++ before/before.svg | 4 + 13 files changed, 609 insertions(+), 1 deletion(-) create mode 100644 after/FeedParser/FeedParserInterface.php create mode 100644 after/FeedParser/ManufacturerFeedParser.php create mode 100644 after/FileParser/ExcelParser.php create mode 100644 after/FileParser/FileParserInterface.php create mode 100644 after/FileParser/XmlParser.php create mode 100644 after/Service/FeedsImportTempTable.php create mode 100644 after/Service/FeedsImporter.php create mode 100644 after/Tools/ImportHelper.php create mode 100644 after/after.svg create mode 100644 before/FeedParser.php create mode 100644 before/FeedsImporter.php create mode 100644 before/before.svg diff --git a/README.md b/README.md index 6490de86..57768a07 100644 --- a/README.md +++ b/README.md @@ -1 +1,14 @@ -# PHP2021 \ No newline at end of file +# PHP2021 +# Домашнее задание №13. Архитектура кода + +В рамках разработки рабочего проекта есть необходимость доработки ранее написанного модуля парсера продукции из предоставляемых клиентом данных, для последующего размещения на платформе. На данный момент парсер может работать только с файлами формата XLSX. время от времени производители присылают разного рода XML файлы, которые сейчас приходится парсить в Excel, и в теории можно будет продумать подгрузку файлов других типов. + +В качестве объекта анализа выступает модуль-парсер, который в данный момент состоит из запускаемого через консоль или через Битриксового агента скрипта, который последовательно экземпляр класса FeedsImporter и вызывает его метод run, внутри run создается FeedParser, который в свою очередь вызывает методы ExcelParser и только тогда заполняет временную таблицу данных из файла фида. Добавление еще одного парсера в такой системе выглядит как большое количество переписывания всего модуля. + +Во-первых создадим интерфейс FileParserInterface, для того что бы можно было безболезненно добавлять парсеры других загружаемых файлов. На основе этого интерфейса создадим пока два парсера: для Excel (ExcelParser) и XML (XmlParser). + +На данный момент такой задачи нет, но на всякий случай создадим интерфейс для парсера фидов (поиск файлов фида, настроек пользователя и т.д.) под потенциально разные задачи. В данный момент фиды есть только у Производителей в основном каталоге продукции, но, например, может потребоваться добавлять какие-то элементы в разрабатываемую на платформе в данный момент секцию библиотеки или в каталоги других типов пользователей. Поэтому создадим FeedParserInterface и к нему пока что одну реализацию интерфейса для загрузки данных в товарный каталог ManufacturerFeedParser. + +Управлять всем будет ImportService, который будет использовать например все тем же битриксовым агентом при периодической выгрузке файлов из очереди. + +Отдельно вынесем вспомогательные методы (ImportHelper.php) и запись данных во временную таблицу (FeedsImportTempTable.php) diff --git a/after/FeedParser/FeedParserInterface.php b/after/FeedParser/FeedParserInterface.php new file mode 100644 index 00000000..3583dd86 --- /dev/null +++ b/after/FeedParser/FeedParserInterface.php @@ -0,0 +1,21 @@ +logger = $logger; + } + + public function parseFeedToTable(array $arFeed): void + { + $labelName = "import_{$arFeed['UF_USER_ID']}"; + Debug::startTimeLabel($labelName); + + if (empty($arFeed['file_path'])) { + $this->errors['Critical'][] = ['msg' => 'Не найдены файлы фида']; + $this->logger->addToLog('parse feed', 'error', ['msg' => 'Пустой массив путей к файлам фида', 'feed_id' => $this->feedId]); + throw new Exception('Пустой массив путей к файлам фида'); + } + + try { + if (isset($this->fileParser)) { + $this->fileParser->run($arFeed['UF_USER_ID'], $arFeed['ID'], $arFeed['file_path']); + } else { + throw new Exception('Не задан класс парсера файла'); + } + } catch (\Exception $e) { + $this->logger->addToLog('parse feed', 'error', ['msg' => $e->getMessage(), 'feed_id' => $this->feedId]); + $this->errors['Critical'][] = ['msg' => $e->getMessage()]; + } + + $parseErrors = $this->fileParser->getErrors(); + if (!empty($parseErrors)) { + $this->errors = array_merge($this->errors, $parseErrors); + } + + Debug::endTimeLabel($labelName); + $arLabels = Debug::getTimeLabels(); + $timeSpent = round($arLabels[$labelName]['time'], 2); + $this->logger->addToLog('parse feed', 'success', ['msg' => "Время обработки файла: $timeSpent сек", 'feed_id' => $this->feedId]); + } + + public function getFileParser(): FileParserInterface + { + return $this->fileParser; + } + + public function setFileParser(FileParserInterface $fileParser): void + { + $this->fileParser = $fileParser; + } + + public function getErrors(): array + { + return $this->errors; + } +} \ No newline at end of file diff --git a/after/FileParser/ExcelParser.php b/after/FileParser/ExcelParser.php new file mode 100644 index 00000000..1fd0d82c --- /dev/null +++ b/after/FileParser/ExcelParser.php @@ -0,0 +1,25 @@ +errors; + } +} diff --git a/after/FileParser/FileParserInterface.php b/after/FileParser/FileParserInterface.php new file mode 100644 index 00000000..04a24478 --- /dev/null +++ b/after/FileParser/FileParserInterface.php @@ -0,0 +1,14 @@ +errors; + } +} diff --git a/after/Service/FeedsImportTempTable.php b/after/Service/FeedsImportTempTable.php new file mode 100644 index 00000000..c8703ea3 --- /dev/null +++ b/after/Service/FeedsImportTempTable.php @@ -0,0 +1,18 @@ +importHelper = $importHelper; + $this->logger = $logger; + $this->feedParser = $feedParser; + $this->obElement = $this->obElement = new \CIBlockElement(); + $this->iblockIdCatalog = Core::getInstance()->getIblockId($feedParser::IBLOCK_CODE_CATALOG_NEW); + } + + public function importFeed(int $feedId): void + { + $this->feedId = $feedId; + try { + $this->arFeedInfo = $this->importHelper->getFeedInfo($this->feedId); + $this->fileParser = $this->importHelper->getFileParserInterface((int)$this->arFeedInfo['UF_FILE_ID']); + $this->feedParser->setFileParser($this->fileParser); + $this->feedParser->parseFeedToTable($this->arFeedInfo); + $this->importItems(); + } catch (Exception $e) { + $this->logger->addToLog('feed import', 'error', ['msg' => $e->getMessage(), 'feed_id' => $this->feedId]); + throw new Exception($e->getMessage()); + } + } + + /** + * Импортируем товары из временной таблицы + */ + private function importItems(): void + { + $resItems = FeedsImportTempTable::getList([ + 'select' => ['*'], + 'filter' => ['feed_id'=> (int)$this->arFeedInfo['UF_FILE_ID']] + ]); + + $count = 0; + + while ($row = $resItems->fetch()) { + $arElementFounded = $this->findElement($row['ekn']); + if ($row['errors'] != '') { + continue; + } + + if (!empty($arElementFounded)) { + $this->updateElement($arElementFounded['ID'], $row); + } else { + $this->addElement($row); + } + + $count++; + } + + $this->countItems = $count; + } + + + private function findElement(string $ekn): array + { + /* + * Некоторая логика по поиску сущестующих элементов каталога + */ + return $arElement; + } + + + private function updateElement(int $id, array $row): void + { + /* + * Некоторая логика по подготовке данных для обновления существующего элемента каталога + */ + $this->obElement->SetPropertyValues($id, $this->iblockIdCatalog, $arPropertyValues); + $this->obElement->Update($arFields); + } + + + private function addElement(array $row): bool + { + /* + * Некоторая логика по подготовке данных для добавления нового элемента в каталог + */ + $this->obElement->Add($arFields); + } + +} \ No newline at end of file diff --git a/after/Tools/ImportHelper.php b/after/Tools/ImportHelper.php new file mode 100644 index 00000000..aedc78d4 --- /dev/null +++ b/after/Tools/ImportHelper.php @@ -0,0 +1,35 @@ + + + +FeedsImporter- TableLogger $loggerDebug- int $feedId- ImportHelper $importHelper- FeedParserInterface $feedParser- array $arFeedInfo- int $iblockIdCatalog+ FeedsImporter(ImportHelper $importHelper,TableLogger $logger, FeedParserInterface $feedParser)+ importFeed(int $feedId): void- importItems(): void- findElement(string $ekn): array- updateElement(int $id, array $row): void- addElement(array $row): boolImportHelper+ getFileParserInterface(string $fileType): FileParserInterface+ getFeedInfo(int $feedId): array<<Interface>>FileParserInterface+ run(): void+ getErrors(): arrayXmlParser- array $errors+ XmlParser()+ run(): void+ getErrors(): arrayExcelParser- array $errors+ ExcelParser()+ run(): void+ getErrors(): array<<Interface>>FeedParserInterface+ parseFeedToTable(array $arFeed): void+ getFileParser(): FileParserInterface+ setFileParser(FileParserInterface $fileParser): void+ getErrors(): arrayManufacturerFeedParser- FileParserInterface $fileParser- TableLogger $logger- array $errors+ ManufacturerFeedParser(TableLogger $logger)+ setFileParser(FileParserInterface $fileParser): void+ getFileParser(): FileParserInterface+ parseFeedToTable(array $arFeed): void+ getErrors(): array
Use
Use
Use
Use
Use
Use
FeedsImportTempTable+ addFeedData(array $arFeedData): void
Use
Use
Use
Use
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/before/FeedParser.php b/before/FeedParser.php new file mode 100644 index 00000000..66531c7e --- /dev/null +++ b/before/FeedParser.php @@ -0,0 +1,104 @@ +logger = new TableLogger(new FeedsImporterDebugLogTable()); + $this->tempFolder = "{$_SERVER['DOCUMENT_ROOT']}/upload/feeds_temp/"; + $this->excelParser = new ExcelParser(); + } + + /** + * Считываем содержимое фида во временную таблицу + * @param $arFeed + * @return void + * @throws \Bitrix\Main\ObjectException + */ + public function parseFeedToTable($arFeed) + { + $labelName = "import_{$arFeed['UF_USER_ID']}"; + Debug::startTimeLabel($labelName); + + $this->feedId = $arFeed['ID']; + $this->manufacturerId = $arFeed['UF_USER_ID']; + $this->checkfeedFile($arFeed['UF_FILE']); + + if (empty($this->feedFilePath)) { + $this->errors['Critical'][] = ['msg' => 'Не найдены файлы фида']; + $this->logger->addToLog('parse feed', 'error', ['msg' => 'Пустой массив путей к файлам фида', 'feed_id' => $this->feedId]); + return; + } + + try { + $this->excelParser->run($this->manufacturerId, $this->feedId, $this->feedFilePath); + } catch (\Exception $e) { + $this->logger->addToLog('parse feed', 'error', ['msg' => $e->getMessage(), 'feed_id' => $this->feedId]); + $this->errors['Critical'][] = ['msg' => 'Критическая ошибка в работе модуля ExcelParser']; + } + + $parseErrors = $this->excelParser->getErrors(); + if (!empty($parseErrors)) { + $this->errors = array_merge($this->errors, $parseErrors); + } + + Debug::endTimeLabel($labelName); + $arLabels = Debug::getTimeLabels(); + $timeSpent = round($arLabels[$labelName]['time'], 2); + $this->logger->addToLog('parse feed', 'success', ['msg' => "Время обработки файла: $timeSpent сек", 'feed_id' => $this->feedId]); + } + + /** + * Проверка файла фида на валидность + */ + private function checkfeedFile(int $fileId): bool + { + + if ($fileId <= 0) { + $this->errors['Critical'][] = ['msg' => 'Получен некорректный ID файла']; + $this->logger->addToLog('parser set files paths', 'error', ['msg' => 'Некорректный ID файла', 'feed_id' => $this->feedId]); + return false; + } + + $filePath = $_SERVER['DOCUMENT_ROOT'] . \CFile::GetPath($fileId); + $arFile = \CFile::MakeFileArray($filePath); + + if ($arFile['type'] != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') { + $this->errors['Critical'][] = ['msg' => 'Предоставлен неверный тип файла']; + $this->logger->addToLog('parser set files paths', 'error', ['msg' => 'Неверный тип', 'feed_id' => $this->feedId, 'file_id' => $fileId]); + return false; + } + + if (!file_exists($arFile['tmp_name'])) { + $this->errors['Critical'][] = ['msg' => 'Получен путь до несуществующего файла']; + return false; + } + + $this->feedFilePath = $filePath; + return $arFile; + } + + public function getErrors(): array + { + return $this->errors; + } +} diff --git a/before/FeedsImporter.php b/before/FeedsImporter.php new file mode 100644 index 00000000..3110263f --- /dev/null +++ b/before/FeedsImporter.php @@ -0,0 +1,164 @@ +loggerDebug = new TableLogger(new FeedsImporterDebugLogTable()); + + $core = Core::getInstance(); + $this->iblockIdCatalog = $core->getIblockId($core::IBLOCK_CODE_CATALOG_NEW); + $this->obElement = new \CIBlockElement(); + } + + + /** + * @param $feedId + * ID загруженного файла фида + * @throws \Bitrix\Main\ObjectException + */ + public function run(int $feedId): void + { + $this->loggerDebug->addToLog('feeds importer', 'start', "feed_id $feedId"); + + if ($feedId !== false) { + try { + $this->importFeed($feedId); + } catch (Exception $e) { + AddMessage2Log($e->getMessage()); + $this->loggerDebug->addToLog('feeds importer', 'critical error', [ + 'feed_id' => $feedId, + 'msg' => $e->getMessage(), + ]); + } + } + + $this->loggerDebug->addToLog('feeds importer', 'end', ''); + } + + /** + * Загрузка данных из фида + * @param $feedId + * @return bool + */ + private function importFeed(int $feedId): bool + { + if (!$feedId) { + $this->loggerDebug->addToLog('import feed', 'error', ['msg' => 'incorrect feed id']); + return false; + } + + $this->loggerDebug->addToLog('import feed', 'info', ['feed_id' => $feedId, 'msg' => 'start feed import']); + + $arFeed = ImportHelper::getFeedInfo((int)$feedId); + + $parser = new FeedParser(); + + if ($parser === false) { + return false; + } + + $parser->parseFeedToTable($arFeed); + + $arErrors = $parser->getErrors(); + if (empty($arErrors['Critical'])) { + $this->importItems($feedId); + + } else { + $this->loggerDebug->addToLog('import feed', 'error', ['feed_id' => $feedId, 'msg' => json_encode($arErrors['Critical'], JSON_UNESCAPED_UNICODE)]); + } + + return true; + } + + /** + * Импортируем товары из временной таблицы + * @param $feedId + */ + private function importItems($feedId) + { + $resItems = FeedsImportTempTable::getList([ + 'select' => ['*'], + 'filter' => ['feed_id'=> $feedId] + ]); + + $count = 0; + + while ($row = $resItems->fetch()) { + $arElementFounded = $this->findElement($row['ekn']); + if ($row['errors'] != '') { + continue; + } + + if (!empty($arElementFounded)) { + $this->updateElement($arElementFounded['ID'], $row); + } else { + $this->addElement($row); + } + + $count++; + } + + $this->countItems = $count; + } + + + private function findElement($ekn) + { + /* + * Некоторая логика по поиску сущестующих элементов каталога + */ + return $arElement; + } + + + private function updateElement($ID, $row) + { + /* + * Некоторая логика по подготовке данных для обновления существующего элемента каталога + */ + $this->obElement->SetPropertyValues($ID, $this->iblockIdCatalog, $arPropertyValues); + $this->obElement->Update($arFields); + } + + + private function addElement($row): bool + { + /* + * Некоторая логика по подготовке данных для добавления нового элемента в каталог + */ + $resId = $this->obElement->Add($arFields); + + return $resId ? true : false; + } +} diff --git a/before/before.svg b/before/before.svg new file mode 100644 index 00000000..d3e539bb --- /dev/null +++ b/before/before.svg @@ -0,0 +1,4 @@ + + + +FeedsImporter- TableLogger $loggerDebug- int $iblockIdCatalog- CIBlockElement $obElement+ FeedsImporter()+ run(int $feedId): void- importFeed(int $feedId): void- importItems(int $feedId)- findElement(string $ekn): array- updateElement(int $id, array $row): void- addElement(array $row): boolFeedParser- string $feedFilePath- int $feedId- int $manufacturerId- TableLogger $loggerDebug- array $errors- ExcelParse $excelParser+ FeedParser()+ parseFeedToTable(array $arFeed): void- checkfeedFile(int $fileId): bool- getErrors(): arrayExcelParser- string $feedFilePath- int $feedId- int $manufacturerId- array $errors- ExcelParser $excelParser+ ExcelParser()+ run(int manufacturerId, int feedId, string feedFilePath): void- checkfeedFile(int $fileId)- getErrors() \ No newline at end of file From 5a8b058e5deac0c83a314864a22111754db8ad4e Mon Sep 17 00:00:00 2001 From: MadFisherman Date: Mon, 18 Apr 2022 22:47:24 +0300 Subject: [PATCH 2/2] fix --- after/FeedParser/ManufacturerFeedParser.php | 20 ++++++++++---------- after/FileParser/ExcelParser.php | 9 +++++---- after/FileParser/FileParserInterface.php | 10 +++++----- after/FileParser/XmlParser.php | 7 ++++--- after/Service/FeedsImportTempTable.php | 6 +++--- after/after.svg | 2 +- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/after/FeedParser/ManufacturerFeedParser.php b/after/FeedParser/ManufacturerFeedParser.php index c600d003..b4f53f6e 100644 --- a/after/FeedParser/ManufacturerFeedParser.php +++ b/after/FeedParser/ManufacturerFeedParser.php @@ -10,18 +10,18 @@ class ManufacturerFeedParser implements FeedParserInterface { private FileParserInterface $fileParser; - + private TableLogger $logger; - + private array $errors; - + const IBLOCK_CODE_CATALOG_NEW = 'bitrix.catalog'; - + public function __construct(TableLogger $logger) { $this->logger = $logger; } - + public function parseFeedToTable(array $arFeed): void { $labelName = "import_{$arFeed['UF_USER_ID']}"; @@ -35,7 +35,7 @@ public function parseFeedToTable(array $arFeed): void try { if (isset($this->fileParser)) { - $this->fileParser->run($arFeed['UF_USER_ID'], $arFeed['ID'], $arFeed['file_path']); + $this->fileParser->run($arFeed['UF_USER_ID'],$arFeed['ID'], $arFeed['file_path']); } else { throw new Exception('Не задан класс парсера файла'); } @@ -54,19 +54,19 @@ public function parseFeedToTable(array $arFeed): void $timeSpent = round($arLabels[$labelName]['time'], 2); $this->logger->addToLog('parse feed', 'success', ['msg' => "Время обработки файла: $timeSpent сек", 'feed_id' => $this->feedId]); } - + public function getFileParser(): FileParserInterface { return $this->fileParser; } - + public function setFileParser(FileParserInterface $fileParser): void { $this->fileParser = $fileParser; } - + public function getErrors(): array { return $this->errors; } -} \ No newline at end of file +} diff --git a/after/FileParser/ExcelParser.php b/after/FileParser/ExcelParser.php index 1fd0d82c..d7057b63 100644 --- a/after/FileParser/ExcelParser.php +++ b/after/FileParser/ExcelParser.php @@ -6,16 +6,17 @@ class ExcelParser implements FileParserInterface { - + private array $errors = []; - public function run(): void + public function run(int $userId, int $feedId, string $filePath): void { /** - * Некоторая логика по обработке Excel файла фида, + * Некоторая логика по обработке Excel файла фида находящегося по пути $filePath, * в рамках которой формируем массив $arFeedData для добавления во временную таблицу фидов + * конкретному (пользователю) производителю $userId */ - FeedsImportTempTable::addFeedData($arFeedData); + FeedsImportTempTable::addFeedData($arFeedData, $feedId); } public function getErrors(): array diff --git a/after/FileParser/FileParserInterface.php b/after/FileParser/FileParserInterface.php index 04a24478..7940d95c 100644 --- a/after/FileParser/FileParserInterface.php +++ b/after/FileParser/FileParserInterface.php @@ -6,9 +6,9 @@ interface FileParserInterface { - - public function run(): void; - + + public function run(int $userId, int $feedId, string $filePath): void; + public function getErrors(): array; - -} \ No newline at end of file + +} diff --git a/after/FileParser/XmlParser.php b/after/FileParser/XmlParser.php index a18e9ba4..19ab3029 100644 --- a/after/FileParser/XmlParser.php +++ b/after/FileParser/XmlParser.php @@ -9,13 +9,14 @@ class XmlParser implements FileParserInterface private array $errors = []; - public function run(): void + public function run(int $userId, int $feedId, string $filePath): void { /** - * Некоторая логика по обработке XML файла фида, + * Некоторая логика по обработке Xml файла фида находящегося по пути $filePath, * в рамках которой формируем массив $arFeedData для добавления во временную таблицу фидов + * конкретному (пользователю) производителю $userId */ - FeedsImportTempTable::addFeedData($arFeedData); + FeedsImportTempTable::addFeedData($arFeedData, $feedId); } public function getErrors(): array diff --git a/after/Service/FeedsImportTempTable.php b/after/Service/FeedsImportTempTable.php index c8703ea3..62ab5784 100644 --- a/after/Service/FeedsImportTempTable.php +++ b/after/Service/FeedsImportTempTable.php @@ -6,7 +6,7 @@ class FeedsImportTempTable extends Entity\DataManager { - public static addFeedData(array $arFeedData): void + public static function addFeedData(array $arFeedData, int $feedId): void { foreach ($arFeedData as $row) { /** @@ -14,5 +14,5 @@ class FeedsImportTempTable extends Entity\DataManager */ } } - -} \ No newline at end of file + +} diff --git a/after/after.svg b/after/after.svg index 40ba926f..8cc1bc2a 100644 --- a/after/after.svg +++ b/after/after.svg @@ -1,4 +1,4 @@ -FeedsImporter- TableLogger $loggerDebug- int $feedId- ImportHelper $importHelper- FeedParserInterface $feedParser- array $arFeedInfo- int $iblockIdCatalog+ FeedsImporter(ImportHelper $importHelper,TableLogger $logger, FeedParserInterface $feedParser)+ importFeed(int $feedId): void- importItems(): void- findElement(string $ekn): array- updateElement(int $id, array $row): void- addElement(array $row): boolImportHelper+ getFileParserInterface(string $fileType): FileParserInterface+ getFeedInfo(int $feedId): array<<Interface>>FileParserInterface+ run(): void+ getErrors(): arrayXmlParser- array $errors+ XmlParser()+ run(): void+ getErrors(): arrayExcelParser- array $errors+ ExcelParser()+ run(): void+ getErrors(): array<<Interface>>FeedParserInterface+ parseFeedToTable(array $arFeed): void+ getFileParser(): FileParserInterface+ setFileParser(FileParserInterface $fileParser): void+ getErrors(): arrayManufacturerFeedParser- FileParserInterface $fileParser- TableLogger $logger- array $errors+ ManufacturerFeedParser(TableLogger $logger)+ setFileParser(FileParserInterface $fileParser): void+ getFileParser(): FileParserInterface+ parseFeedToTable(array $arFeed): void+ getErrors(): array
Use
Use
Use
Use
Use
Use
FeedsImportTempTable+ addFeedData(array $arFeedData): void
Use
Use
Use
Use
Viewer does not support full SVG 1.1
\ No newline at end of file +FeedsImporter- TableLogger $loggerDebug- int $feedId- ImportHelper $importHelper- FeedParserInterface $feedParser- array $arFeedInfo- int $iblockIdCatalog+ FeedsImporter(ImportHelper $importHelper,TableLogger $logger, FeedParserInterface $feedParser)+ importFeed(int $feedId): void- importItems(): void- findElement(string $ekn): array- updateElement(int $id, array $row): void- addElement(array $row): boolImportHelper+ getFileParserInterface(string $fileType): FileParserInterface+ getFeedInfo(int $feedId): array<<Interface>>FileParserInterface+ run(int $userId, int $feedId, string $filePath): void+ getErrors(): arrayXmlParser- array $errors+ XmlParser()+ run(int $userId, int $feedId, string $filePath): void+ getErrors(): arrayExcelParser- array $errors+ ExcelParser()+ run(int $userId, int $feedId, string $filePath): void+ getErrors(): array<<Interface>>FeedParserInterface+ parseFeedToTable(array $arFeed): void+ getFileParser(): FileParserInterface+ setFileParser(FileParserInterface $fileParser): void+ getErrors(): arrayManufacturerFeedParser- FileParserInterface $fileParser- TableLogger $logger- array $errors+ ManufacturerFeedParser(TableLogger $logger)+ setFileParser(FileParserInterface $fileParser): void+ getFileParser(): FileParserInterface+ parseFeedToTable(array $arFeed): void+ getErrors(): array
Use
Use
Use
Use
Use
Use
FeedsImportTempTable+ addFeedData(array $arFeedData): void
Use
Use
Use
Use
Text is not SVG - cannot display
\ No newline at end of file