![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/app/code/Cnc/Catalog/Setup/Patch/Data/ |
<?php /** * Copyright (c) 2020 Kaliop Digital Commerce (https://digitalcommerce.kaliop.com) All Rights Reserved. * https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * * Hugo Herblot <[email protected]> <[email protected]> */ declare(strict_types=1); namespace Cnc\Catalog\Setup\Patch\Data; use Exception; use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Catalog\Model\Category; use Magento\Catalog\Model\CategoryFactory; use Magento\Framework\File\Csv; use Magento\Framework\Filesystem\Driver\File; use Magento\Framework\Registry; use Magento\Framework\Setup\Patch\DataPatchInterface; use Magento\Framework\Setup\SampleData\FixtureManager; use Magento\Indexer\Console\Command\IndexerReindexCommand; use Magento\Store\Model\StoreManagerInterface; use Psr\Log\LoggerInterface; class CreateCategories implements DataPatchInterface { const FIXTURE_CATEGORIES_FR_FILE_PATH = 'Cnc_Catalog::fixtures/all_cat.csv'; /** * Custom Attribute start in csv file */ const CUSTOM_ATTR = 'attr'; /** * "include_in_menu" attribute */ const CUSTOM_ATTR_INCLUDE_IN_MENU = 'attr-include_in_menu'; /** * Custom Level Attribute start in csv file */ const CUSTOM_LEVEL_ATTR = 'level'; /** * Custom display mode attribute */ const CUSTOM_DISPLAY_MODE = 'attr-display_mode'; const CUSTOM_DISPLAY_MODE_DEFAULT = 'PRODUCTS'; const CUSTOM_DISPLAY_MODE_PAGE = 'PAGE'; /** * @var CategoryFactory */ private $categoryFactory; /** * @var Registry */ private $registry; /** * @var StoreManagerInterface */ private $storeManager; /** * @var CategoryRepositoryInterface */ private $categoryRepository; /** * @var $currentCategory */ private $currentCategory; /** * @var $previousCategory */ private $previousCategory; /** * @var IndexerReindexCommand */ private $reindexCommand; /** * @var FixtureManager */ private $fixtureManager; /** * @var Csv */ private $csv; /** * @var LoggerInterface */ private $logger; /** * @var File */ private $file; /** * Category constructor. * @param CategoryFactory $categoryFactory * @param Registry $registry * @param StoreManagerInterface $storeManager * @param CategoryRepositoryInterface $categoryRepository * @param IndexerReindexCommand $reindexCommand * @param FixtureManager $fixtureManager * @param Csv $csv * @param LoggerInterface $logger * @param File $file */ public function __construct( CategoryFactory $categoryFactory, Registry $registry, StoreManagerInterface $storeManager, CategoryRepositoryInterface $categoryRepository, IndexerReindexCommand $reindexCommand, FixtureManager $fixtureManager, Csv $csv, LoggerInterface $logger, File $file ) { $this->categoryFactory = $categoryFactory; $this->registry = $registry; $this->storeManager = $storeManager; $this->categoryRepository = $categoryRepository; $this->reindexCommand = $reindexCommand; $this->fixtureManager = $fixtureManager; $this->csv = $csv; $this->logger = $logger; $this->file = $file; } public static function getDependencies(): array { return [\Cnc\Catalog\Setup\Patch\Data\CreateCategoryAttributesFromOsCommerce::class]; } public function apply(): void { try { $data = []; $fileName = $this->fixtureManager->getFixture(self::FIXTURE_CATEGORIES_FR_FILE_PATH); $file = $this->file->fileOpen($fileName, "r"); $header = $this->file->fileGetCsv($file, 0, ";"); while ($row = $this->file->fileGetCsv($file, 0, ";")) { $data[] = array_filter(array_combine($header, $row)); } $this->removeAllCategories(); $this->importCategories($data); } catch (Exception $e) { $this->logger->critical($e->getMessage()); } } /** * Remove all categories */ private function removeAllCategories() { var_export('Removing all categories before import new ones...'); $categories = $this->categoryFactory->create()->getCollection(); $this->registry->register("isSecureArea", true); foreach ($categories as $category) { // We don't remove Root Category if ($category->getId() <= 2) { continue; } // Remove all categories try { var_export("Removed Category ID : {$category->getId()}"); $category->delete(); } catch (Exception $e) { $this->logger->critical($e->getMessage()); $this->logger->critical(var_export($category->getId(), true)); } } var_export('Clean done!'); } /** * Import Categories main run * * @param $data * @throws Exception */ private function importCategories($data) { $parentIds = [1 => $this->storeManager->getDefaultStoreView()->getRootCategoryId()]; foreach ($data as $item) { // Get the store Id $this->currentCategory['storeId'] = $this->getStoreId($item); // Get the name of the category $this->currentCategory['name'] = $this->getCategoryName($item); // Get the level of the category $this->currentCategory['level'] = $this->getCategoryLevel($item); // Get all custom Attributes $this->currentCategory['attributes'] = $this->getCategoryAttribute($item); // Get the Parent Id $this->currentCategory['parent_id'] = $parentIds[$this->currentCategory['level']]; // Create the category $this->createCategory($this->currentCategory); $parentIds[$this->currentCategory['level'] + 1] = $this->previousCategory->getId(); } var_export('Import done!'); } /** * Get the store ID * * @param $item * @return int * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function getStoreId($item) { // Get the Store Code to default if is empty if (empty($item['store_code'])) { $storeCode = $this->storeManager->getDefaultStoreView()->getCode(); } else { $storeCode = $item['store_code']; } return $this->storeManager->getStore($storeCode)->getId(); } /** * Get the category name * * @param $item * @return string */ private function getCategoryName($item) { foreach ($item as $key => $value) { if (strpos($key, self::CUSTOM_LEVEL_ATTR) === 0) { if (!empty($value)) { return $value; } } } } /** * Get the category level * * @param $item * @return int */ private function getCategoryLevel($item) { foreach ($item as $key => $value) { if (strpos($key, self::CUSTOM_LEVEL_ATTR) === 0) { if (!empty($value)) { return str_replace(self::CUSTOM_LEVEL_ATTR, '', $key); } } } } /** * Get attribute from file to our new category * * @param $item * @return array */ private function getCategoryAttribute($item) { $attributes = []; foreach ($item as $key => $value) { $expKey = explode('-', $key); if ($expKey[0] == self::CUSTOM_ATTR) { $attributes[$key] = $value; } } //Fix for white spaces in url key attribute if (isset($attributes['attr-url_key'])) { $attributes['attr-url_key'] = $this->getFormattedUrlKey($attributes['attr-url_key']); } return $attributes; } /** * Prepare SEO friendly url key for category * @param $urlKey * @return string|string[] */ private function getFormattedUrlKey($urlKey) { //Check if c element is in url import value if (strrpos($urlKey, 'c')) { //put '-' before and after c element in url for SEO purposes $urlKey = substr_replace($urlKey, '-', strrpos($urlKey, 'c'), 0); $urlKey = substr_replace($urlKey, '-', strrpos($urlKey, 'c') + 1, 0); } return strtolower(str_replace(' ', '-', $urlKey)); } /** * Create our new category with all parameter * (We must save the category right now due to children) * * @param $category */ private function createCategory($category) { $categoryName = trim($category['name']); try { $categoryAction = 'Updating'; $this->storeManager->setCurrentStore($category['storeId']); // Add a new Category /** @var Category $categoryTmp */ $categoryTmp = $this->categoryFactory->create(); $collection = $categoryTmp->getCollection() ->addAttributeToFilter('name', $categoryName) ->addAttributeToFilter('parent_id', $category['parent_id']) ->setPageSize(1); if ($collection->getSize()) { $categoryTmp = $this->categoryRepository ->get($collection->getFirstItem()->getId(), $category['storeId']); $categoryAction = 'Updating'; } var_export("{$categoryAction} category '{$categoryName}'..."); // Set store_id $categoryTmp->setStoreId($category['storeId']); // Set name $categoryTmp->setName($categoryName); // Set parent_id $categoryTmp->setParentId($category['parent_id']); // Set attribute $this->setCategoryAttribute($category['attributes'], $categoryTmp); // Save current Category $this->categoryRepository->save($categoryTmp); $this->previousCategory = $categoryTmp; } catch (Exception $e) { var_export("Failed to create category '{$categoryName}' : {$e->getMessage()}", true); } } /** * Set specific attribute from file to our new category * * @param $category * @param $categoryTmp */ private function setCategoryAttribute($category, Category $categoryTmp) { $categoryTmp->setData('display_mode', self::CUSTOM_DISPLAY_MODE_DEFAULT); foreach ($category as $key => $value) { $expKey = explode('-', $key); // Custom "name" for other store_view if ($key == self::CUSTOM_ATTR_INCLUDE_IN_MENU) { $categoryTmp->setIncludeInMenu(false); continue; } if ($key == self::CUSTOM_DISPLAY_MODE && $value == self::CUSTOM_DISPLAY_MODE_PAGE) { $categoryTmp->setDisplayMode(self::CUSTOM_DISPLAY_MODE_PAGE); continue; } // All classic attributes if ($expKey[0] == self::CUSTOM_ATTR) { $categoryTmp->setData($expKey[1], $value); } } } public function getAliases(): array { return []; } }