Passed
Push — 6.4 ( be76f2...e19c4d )
by Christian
14:08 queued 13s
created

CustomerAdminSearchIndexer   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 56
dl 0
loc 113
rs 10
c 1
b 0
f 0
wmc 8

7 Methods

Rating   Name   Duplication   Size   Complexity  
A globalData() 0 7 1
A getIterator() 0 3 1
A fetch() 0 48 2
A __construct() 0 10 1
A getName() 0 3 1
A getEntity() 0 3 1
A getDecorated() 0 3 1
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Elasticsearch\Admin\Indexer;
4
5
use Doctrine\DBAL\Connection;
6
use Shopware\Core\Checkout\Customer\CustomerDefinition;
7
use Shopware\Core\Framework\Context;
8
use Shopware\Core\Framework\DataAbstractionLayer\Dbal\Common\IterableQuery;
9
use Shopware\Core\Framework\DataAbstractionLayer\Dbal\Common\IteratorFactory;
10
use Shopware\Core\Framework\DataAbstractionLayer\Entity;
11
use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
12
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
13
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
14
use Shopware\Core\Framework\Log\Package;
15
use Shopware\Core\Framework\Plugin\Exception\DecorationPatternException;
16
use Shopware\Core\Framework\Uuid\Uuid;
17
18
/**
19
 * @internal
20
 */
21
#[Package('system-settings')]
22
final class CustomerAdminSearchIndexer extends AbstractAdminIndexer
23
{
24
    private Connection $connection;
25
26
    private IteratorFactory $factory;
27
28
    private EntityRepository $repository;
29
30
    private int $indexingBatchSize;
31
32
    public function __construct(
33
        Connection $connection,
34
        IteratorFactory $factory,
35
        EntityRepository $repository,
36
        int $indexingBatchSize
37
    ) {
38
        $this->connection = $connection;
39
        $this->factory = $factory;
40
        $this->repository = $repository;
41
        $this->indexingBatchSize = $indexingBatchSize;
42
    }
43
44
    public function getDecorated(): AbstractAdminIndexer
45
    {
46
        throw new DecorationPatternException(self::class);
47
    }
48
49
    public function getEntity(): string
50
    {
51
        return CustomerDefinition::ENTITY_NAME;
52
    }
53
54
    public function getName(): string
55
    {
56
        return 'customer-listing';
57
    }
58
59
    public function getIterator(): IterableQuery
60
    {
61
        return $this->factory->createIterator($this->getEntity(), null, $this->indexingBatchSize);
62
    }
63
64
    /**
65
     * @param array<string, mixed> $result
66
     *
67
     * @return array{total:int, data:EntityCollection<Entity>}
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{total:int, data:EntityCollection<Entity>} at position 8 could not be parsed: Expected '}' at position 8, but found 'EntityCollection'.
Loading history...
68
     */
69
    public function globalData(array $result, Context $context): array
70
    {
71
        $ids = array_column($result['hits'], 'id');
72
73
        return [
74
            'total' => (int) $result['total'],
75
            'data' => $this->repository->search(new Criteria($ids), $context)->getEntities(),
76
        ];
77
    }
78
79
    /**
80
     * @param array<string>|array<int, array<string>> $ids
81
     *
82
     * @throws \Doctrine\DBAL\Exception
83
     *
84
     * @return array<int|string, array<string, mixed>>
85
     */
86
    public function fetch(array $ids): array
87
    {
88
        $data = $this->connection->fetchAllAssociative(
89
            '
90
            SELECT LOWER(HEX(customer.id)) as id,
91
                   GROUP_CONCAT(DISTINCT tag.name) as tags,
92
                   GROUP_CONCAT(DISTINCT country_translation.name) as country,
93
                   GROUP_CONCAT(DISTINCT customer_address.city) as city,
94
                   GROUP_CONCAT(DISTINCT customer_address.street) as street,
95
                   GROUP_CONCAT(DISTINCT customer_address.zipcode) as zipcode,
96
                   GROUP_CONCAT(DISTINCT customer_address.phone_number) as phone_number,
97
                   GROUP_CONCAT(DISTINCT customer_address.additional_address_line1) as additional_address_line1,
98
                   GROUP_CONCAT(DISTINCT customer_address.additional_address_line2) as additional_address_line2,
99
                   customer.first_name,
100
                   customer.last_name,
101
                   customer.email,
102
                   customer.company,
103
                   customer.customer_number
104
            FROM customer
105
                LEFT JOIN customer_address
106
                    ON customer_address.customer_id = customer.id
107
                LEFT JOIN country
108
                    ON customer_address.country_id = country.id
109
                LEFT JOIN country_translation
110
                    ON country.id = country_translation.country_id
111
                LEFT JOIN customer_tag
112
                    ON customer.id = customer_tag.customer_id
113
                LEFT JOIN tag
114
                    ON customer_tag.tag_id = tag.id
115
            WHERE customer.id IN (:ids)
116
            GROUP BY customer.id
117
        ',
118
            [
119
                'ids' => Uuid::fromHexToBytesList($ids),
120
            ],
121
            [
122
                'ids' => Connection::PARAM_STR_ARRAY,
123
            ]
124
        );
125
126
        $mapped = [];
127
        foreach ($data as $row) {
128
            $id = $row['id'];
129
            $text = \implode(' ', array_filter(array_unique(array_values($row))));
130
            $mapped[$id] = ['id' => $id, 'text' => \strtolower($text)];
131
        }
132
133
        return $mapped;
134
    }
135
}
136