YetiForceCompany/YetiForceCRM

View on GitHub
app/Integrations/Magento/Synchronizer/Category.php

Summary

Maintainability
C
1 day
Test Coverage
F
0%
<?php

/**
 * Synchronize products categories file.
 *
 * The file is part of the paid functionality. Using the file is allowed only after purchasing a subscription. File modification allowed only with the consent of the system producer.
 *
 * @package Integration
 *
 * @copyright YetiForce S.A.
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Mariusz Krzaczkowski <m.krzaczkowski@yetiforce.com>
 */

namespace App\Integrations\Magento\Synchronizer;

/**
 * Synchronize products categories class.
 */
class Category extends Record
{
    /**
     * Category cache.
     *
     * @var array
     */
    protected $cache = [];

    /** {@inheritdoc} */
    public function process()
    {
        $this->lastScan = $this->config->getLastScan('category');
        if (!$this->lastScan['start_date'] || (0 === (int) $this->lastScan['id'] && $this->lastScan['start_date'] === $this->lastScan['end_date'])) {
            $this->config->setScan('category');
            $this->lastScan = $this->config->getLastScan('category');
        }
        if ($this->import()) {
            $this->config->setEndScan('category', $this->lastScan['start_date']);
        }
    }

    /**
     * Import categories from Magento.
     *
     * @return bool
     */
    public function import(): bool
    {
        $allChecked = false;
        try {
            if ($categories = $this->getCategoriesFromApi()) {
                foreach ($categories as $category) {
                    if (empty($category)) {
                        \App\Log::error('Empty category details', 'Integrations/Magento');
                        continue;
                    }
                    if (0 === (int) $category['parent_id']) {
                        continue;
                    }
                    try {
                        if (empty($this->getCrmId($category['id']))) {
                            $this->createCategory($category['id'], $category);
                        }
                    } catch (\Throwable $ex) {
                        $this->log('Saving category', $ex);
                        \App\Log::error('Error during saving category: ' . PHP_EOL . $ex->__toString() . PHP_EOL, 'Integrations/Magento');
                    }
                    $this->config->setScan('category', 'id', $category['id']);
                }
            } else {
                $allChecked = true;
            }
        } catch (\Throwable $ex) {
            $this->log('Import categories', $ex);
            \App\Log::error('Error during import category: ' . PHP_EOL . $ex->__toString() . PHP_EOL, 'Integrations/Magento');
        }
        return $allChecked;
    }

    /**
     * Method to get categories form Magento.
     *
     * @return array
     */
    public function getCategoriesFromApi(): array
    {
        $items = [];
        $data = \App\Json::decode($this->connector->request('GET', $this->config->get('store_code') . '/V1/categories/list?' . $this->getSearchCriteria($this->config->get('categories_limit'))));
        if (!empty($data['items'])) {
            $items = $data['items'];
            foreach ($items as $item) {
                $this->cache[$item['id']] = $item;
            }
        }
        return $items;
    }

    /**
     * Get crm id by magento id.
     *
     * @param int         $magentoId
     * @param string|null $moduleName
     *
     * @return int
     */
    public function getCrmId(int $magentoId): int
    {
        if (\App\Cache::staticHas('CrmIdByMagentoIdProductCategory', $magentoId)) {
            return \App\Cache::staticGet('CrmIdByMagentoIdProductCategory', $magentoId);
        }
        $queryGenerator = new \App\QueryGenerator('ProductCategory');
        $queryGenerator->setStateCondition('All');
        $queryGenerator->setFields(['id'])->permissions = false;
        $queryGenerator->addCondition('magento_id', $magentoId, 'e');
        $queryGenerator->addCondition('magento_server_id', $this->config->get('id'), 'e');
        $crmId = $queryGenerator->createQuery()->scalar() ?: 0;
        \App\Cache::staticSave('CrmIdByMagentoIdProductCategory', $magentoId, $crmId);
        return $crmId;
    }

    /**
     * Create category in CRM.
     *
     * @param int   $id
     * @param array $category
     *
     * @return void
     */
    public function createCategory(int $id, array $category = [])
    {
        if (empty($category)) {
            $category = $this->cache[$id] ?? $this->getCategory($id);
        }
        $recordModel = \Vtiger_Record_Model::getCleanInstance('ProductCategory');
        $parentId = 0;
        if ($category['parent_id'] > 1) {
            $parentId = $this->getCrmId($category['parent_id']) ?: $this->createCategory($category['parent_id']);
        }
        $recordModel->setData([
            'category' => trim($category['name']),
            'parent_id' => $parentId,
            'active' => $category['is_active'],
            'magento_server_id' => $this->config->get('id'),
            'magento_id' => $id,
        ]);
        $recordModel->save();
        \App\Cache::staticSave('CrmIdByMagentoIdProductCategory', $id, $recordModel->getId());
        return $recordModel->getId();
    }

    /**
     * Method to get category by id form Magento.
     *
     * @param int $id
     *
     * @return array
     */
    public function getCategory(int $id): array
    {
        return $this->cache[$id] = \App\Json::decode($this->connector->request('GET', $this->config->get('store_code') . '/V1/categories/' . $id));
    }

    /** {@inheritdoc} */
    public function getSearchCriteria(int $pageSize = 10): string
    {
        $searchCriteria = [];
        $searchCriteria[] = 'searchCriteria[filter_groups][0][filters][0][field]=entity_id';
        $searchCriteria[] = 'searchCriteria[filter_groups][0][filters][0][value]=' . $this->lastScan['id'];
        $searchCriteria[] = 'searchCriteria[filter_groups][0][filters][0][condition_type]=gt';
        $searchCriteria[] = 'searchCriteria[filter_groups][1][filters][0][field]=created_at';
        $searchCriteria[] = 'searchCriteria[filter_groups][1][filters][0][value]=' . $this->getFormattedTime($this->lastScan['start_date']);
        $searchCriteria[] = 'searchCriteria[filter_groups][1][filters][0][condition_type]=lteq';
        if (!empty($this->lastScan['end_date'])) {
            $searchCriteria[] = 'searchCriteria[filter_groups][2][filters][0][field]=created_at';
            $searchCriteria[] = 'searchCriteria[filter_groups][2][filters][0][value]=' . $this->getFormattedTime($this->lastScan['end_date']);
            $searchCriteria[] = 'searchCriteria[filter_groups][2][filters][0][condition_type]=gteq';
        }
        $searchCriteria[] = 'searchCriteria[pageSize]=' . $pageSize;
        $searchCriteria = implode('&', $searchCriteria);
        return $searchCriteria ?? 'searchCriteria';
    }
}