Completed
Push — 1.9 ( 5c3e2e...1529fd )
by
unknown
60:20
created

MarketingListProvider::saveColumnInformation()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 27
rs 8.439
cc 6
eloc 17
nc 12
nop 3
1
<?php
2
3
namespace OroCRM\Bundle\MarketingListBundle\Provider;
4
5
use Doctrine\ORM\Query\Expr\From;
6
use Doctrine\ORM\Query\Expr\Select;
7
use Doctrine\ORM\QueryBuilder;
8
9
use Oro\Bundle\BatchBundle\ORM\Query\BufferedQueryResultIterator;
10
use Oro\Bundle\DataGridBundle\Datagrid\Common\DatagridConfiguration;
11
use Oro\Bundle\DataGridBundle\Datagrid\DatagridInterface;
12
use Oro\Bundle\DataGridBundle\Datagrid\Manager;
13
use Oro\Bundle\DataGridBundle\Datasource\Orm\OrmDatasource;
14
use Oro\Bundle\DataGridBundle\Extension\Pager\PagerInterface;
15
use Oro\Bundle\TagBundle\Grid\TagsExtension;
16
17
use OroCRM\Bundle\MarketingListBundle\Entity\MarketingList;
18
use OroCRM\Bundle\MarketingListBundle\Datagrid\ConfigurationProvider;
19
20
class MarketingListProvider
21
{
22
    const RESULT_ITEMS_MIXIN = 'orocrm-marketing-list-items-mixin';
23
    const RESULT_ENTITIES_MIXIN = 'orocrm-marketing-list-entities-mixin';
24
    const FULL_ENTITIES_MIXIN = 'orocrm-marketing-full-mixin';
25
    const MANUAL_RESULT_ITEMS_MIXIN = 'orocrm-marketing-list-manual-items-mixin';
26
    const MANUAL_RESULT_ENTITIES_MIXIN = 'orocrm-marketing-list-manual-entities-mixin';
27
    const DATAGRID_COLUMN_ALIASES_PATH = '[source][query_config][column_aliases]';
28
29
    /**
30
     * @var Manager
31
     */
32
    protected $dataGridManager;
33
34
    /**
35
     * @var array
36
     */
37
    protected $dataGrid = [];
38
39
    /**
40
     * @var array
41
     */
42
    protected $columnInformation = [];
43
44
    /**
45
     * @param Manager $dataGridManager
46
     */
47
    public function __construct(Manager $dataGridManager)
48
    {
49
        $this->dataGridManager = $dataGridManager;
50
    }
51
52
    /**
53
     * @param MarketingList $marketingList
54
     * @param string|null $mixin
55
     *
56
     * @return QueryBuilder
57
     */
58
    public function getMarketingListQueryBuilder(MarketingList $marketingList, $mixin = null)
59
    {
60
        $dataGrid = $this->getMarketingListDataGrid($marketingList, $mixin);
61
62
        /** @var OrmDatasource $dataSource */
63
        $dataSource = $dataGrid->getAcceptedDatasource();
64
        $qb =  $dataSource->getQueryBuilder();
65
        $this->saveColumnInformation($marketingList, $dataGrid, $qb);
66
67
        return $qb;
68
    }
69
70
    /**
71
     * @param MarketingList $marketingList
72
     * @param string|null $mixin
73
     *
74
     * @return \Iterator
75
     */
76
    public function getMarketingListResultIterator(MarketingList $marketingList, $mixin = null)
77
    {
78
        if (!$mixin) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $mixin of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
79
            if ($marketingList->isManual()) {
80
                $mixin = self::MANUAL_RESULT_ITEMS_MIXIN;
81
            } else {
82
                $mixin = self::RESULT_ITEMS_MIXIN;
83
            }
84
        }
85
86
        $queryBuilder = $this->getMarketingListQueryBuilder($marketingList, $mixin);
87
        $dataGridConfig = $this->getMarketingListDataGrid($marketingList, $mixin)->getConfig();
88
89
        $skipCountWalker = $dataGridConfig->offsetGetByPath(
90
            DatagridConfiguration::DATASOURCE_SKIP_COUNT_WALKER_PATH,
91
            false
92
        );
93
        $iterator = new BufferedQueryResultIterator($queryBuilder, !$skipCountWalker);
94
95
        return $iterator;
96
    }
97
98
    /**
99
     * @param MarketingList $marketingList
100
     * @param string|null $mixin
101
     *
102
     * @return QueryBuilder
103
     */
104
    public function getMarketingListEntitiesQueryBuilder(MarketingList $marketingList, $mixin = null)
105
    {
106
        if (!$mixin) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $mixin of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
107
            if ($marketingList->isManual()) {
108
                $mixin = self::MANUAL_RESULT_ENTITIES_MIXIN;
109
            } else {
110
                $mixin = self::RESULT_ENTITIES_MIXIN;
111
            }
112
        }
113
114
        $queryBuilder = clone $this->getMarketingListQueryBuilder($marketingList, $mixin);
115
116
        /** @var From[] $from */
117
        $from = $queryBuilder->getDQLPart('from');
118
        $entityAlias = $from[0]->getAlias();
119
120
        // Select only entity related information ordered by identifier field for maximum performance
121
        $queryBuilder
122
            ->resetDQLPart('select')
123
            ->resetDQLPart('orderBy')
124
            ->select($entityAlias)
125
            ->orderBy($entityAlias . '.id');
126
127
        return $queryBuilder;
128
    }
129
130
    /**
131
     * @param MarketingList $marketingList
132
     * @param string $mixin
133
     *
134
     * @return BufferedQueryResultIterator
135
     */
136
    public function getMarketingListEntitiesIterator(MarketingList $marketingList, $mixin = null)
137
    {
138
        return new BufferedQueryResultIterator(
139
            $this->getMarketingListEntitiesQueryBuilder($marketingList, $mixin),
140
            false
141
        );
142
    }
143
144
    /**
145
     * @param MarketingList $marketingList
146
     * @return null|array
147
     */
148
    public function getColumnInformation(MarketingList $marketingList)
149
    {
150
        if (array_key_exists($marketingList->getId(), $this->columnInformation)) {
151
            return $this->columnInformation[$marketingList->getId()];
152
        }
153
154
        return null;
155
    }
156
157
    /**
158
     * @param MarketingList $marketingList
159
     * @param null|string $mixin
160
     *
161
     * @return DatagridInterface
162
     */
163
    protected function getMarketingListDataGrid(MarketingList $marketingList, $mixin = null)
164
    {
165
        $dataGridName = ConfigurationProvider::GRID_PREFIX . $marketingList->getId();
166
167
        $resultKey = $dataGridName . $mixin;
168
        if (empty($this->dataGrid[$resultKey])) {
169
            $gridParameters = [
170
                PagerInterface::PAGER_ROOT_PARAM => [PagerInterface::DISABLED_PARAM => true],
171
                /**
172
                 * Disable tags extension because of problems with SecurityFacade::isGranted
173
                 * calls during console command running
174
                 */
175
                TagsExtension::TAGS_ROOT_PARAM => [TagsExtension::DISABLED_PARAM => true]
176
            ];
177
            if ($mixin) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $mixin of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
178
                $gridParameters['grid-mixin'] = $mixin;
179
            }
180
            $this->dataGrid[$resultKey] = $this->dataGridManager->getDatagrid($dataGridName, $gridParameters);
181
182
        }
183
184
        return $this->dataGrid[$resultKey];
185
    }
186
187
    /**
188
     * @param MarketingList $marketingList
189
     * @param DatagridInterface $dataGrid
190
     * @param QueryBuilder $qb
191
     */
192
    protected function saveColumnInformation(
193
        MarketingList $marketingList,
194
        DatagridInterface $dataGrid,
195
        QueryBuilder $qb
196
    ) {
197
        /** @var Select[] $selects */
198
        $selects = $qb->getDQLPart('select');
199
        $columnToSelectExpr = [];
200
        foreach ($selects as $select) {
201
            foreach ($select->getParts() as $selectPart) {
202
                $selectData = explode(strrev(' as '), strrev($selectPart), 2);
203
                if (count($selectData) === 2) {
204
                    $columnToSelectExpr[strrev($selectData[0])] = strrev($selectData[1]);
205
                }
206
            }
207
        }
208
209
        $columnAliases = $dataGrid->getConfig()->offsetGetByPath(self::DATAGRID_COLUMN_ALIASES_PATH);
210
        $columnInformation = [];
211
        foreach ($columnAliases as $alias => $selectAlias) {
212
            if (array_key_exists($selectAlias, $columnToSelectExpr)) {
213
                $columnInformation[$alias] = $columnToSelectExpr[$selectAlias];
214
            }
215
        }
216
217
        $this->columnInformation[$marketingList->getId()] = $columnInformation;
218
    }
219
}
220