Completed
Pull Request — master (#333)
by Simon
04:01
created

SwQuery::extractCategory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 7
rs 9.4285
c 1
b 0
f 0
1
<?php
2
/**
3
 * (c) shopware AG <[email protected]>
4
 * For the full copyright and license information, please view the LICENSE
5
 * file that was distributed with this source code.
6
 */
7
8
namespace ShopwarePlugins\Connect\Components\CategoryQuery;
9
10
use Shopware\Components\Model\ModelManager;
11
use Shopware\Models\Article\Article;
12
use Shopware\Models\Category\Category;
13
use Shopware\Models\Category\Category as CategoryModel;
14
use ShopwarePlugins\Connect\Components\CategoryQuery;
15
use Shopware\Models\Article\Repository as ArticleRepository;
16
use Shopware\Models\Category\Repository as CategoryRepository;
17
18
class SwQuery implements CategoryQuery
19
{
20
    /**
21
     * @var ModelManager
22
     */
23
    protected $manager;
24
25
    /**
26
     * @var RelevanceSorter
27
     */
28
    protected $relevanceSorter;
29
30
    /**
31
     * @param ModelManager $manager
32
     * @param RelevanceSorter $relevanceSorter
33
     */
34
    public function __construct(ModelManager $manager, RelevanceSorter $relevanceSorter)
35
    {
36
        $this->manager = $manager;
37
        $this->relevanceSorter = $relevanceSorter;
38
    }
39
40
    /**
41
     * @return RelevanceSorter
42
     */
43
    public function getRelevanceSorter()
44
    {
45
        return $this->relevanceSorter;
46
    }
47
48
    /**
49
     * @return ArticleRepository
50
     */
51
    protected function getArticleRepository()
52
    {
53
        return $this->manager->getRepository(
54
            Article::class
55
        );
56
    }
57
58
    /**
59
     * @return CategoryRepository
60
     */
61
    protected function getCategoryRepository()
62
    {
63
        return $this->manager->getRepository(
64
            CategoryModel::class
65
        );
66
    }
67
68
    /**
69
     * Return connect category mapping for the given product id
70
     *
71
     * @param $id
72
     * @return array
73
     */
74
    public function getConnectCategoryForProduct($id)
75
    {
76
        $builder = $this->manager->createQueryBuilder();
77
        $builder->select(['categories'])
78
            ->from('Shopware\Models\Category\Category', 'categories', 'categories.id')
79
            ->andWhere(':articleId MEMBER OF categories.articles')
80
            ->setParameters(['articleId' => $id]);
81
82
        $result = $builder->getQuery()->getResult();
83
        if (empty($result)) {
84
            return [];
85
        }
86
87
        $categories = [];
88
        /** @var CategoryModel $category */
89
        foreach ($result as $category) {
90
            list($key, $name) = $this->extractCategory($category);
91
            $categories[$key] = $name;
92
            $parent = $category;
93
            while ($parent = $parent->getParent()) {
94
                if (!$parent->getParentId()) {
95
                    continue;
96
                }
97
                list($key, $name) = $this->extractCategory($parent);
98
                $categories[$key] = $name;
99
            }
100
        }
101
102
        return $categories;
103
    }
104
105
    /**
106
     * Returns category path and category name as array
107
     * @param Category $category
108
     * @return array
109
     */
110
    private function extractCategory(Category $category)
111
    {
112
        $path = $this->getCategoryRepository()->getPathById($category->getId(), 'name', ' > ');
113
        $key = $this->normalizeCategory($path);
114
115
        return [$key, $category->getName()];
116
    }
117
118
    /**
119
     * Normalize category name
120
     *
121
     * @param string $name
122
     * @return string
123
     */
124
    private function normalizeCategoryName($name)
125
    {
126
        return preg_replace('/[^\p{L}\p{N}]+/u', '_', strtolower($name));
127
    }
128
129
    /**
130
     * Convert a clear text category name into normalized format.
131
     *
132
     * @param string $categoryName
133
     * @return string
134
     */
135
    public function normalizeCategory($categoryName)
136
    {
137
        $path = preg_split('(\\s+>\\s+)', trim($categoryName));
138
139
        return '/' . implode(
140
            '/',
141
            array_map([$this, 'normalizeCategoryName'], $path)
142
        );
143
    }
144
}
145