|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* This file is part of Sulu. |
|
5
|
|
|
* |
|
6
|
|
|
* (c) MASSIVE ART WebServices GmbH |
|
7
|
|
|
* |
|
8
|
|
|
* This source file is subject to the MIT license that is bundled |
|
9
|
|
|
* with this source code in the file LICENSE. |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
namespace Sulu\Bundle\ArticleBundle\Content; |
|
13
|
|
|
|
|
14
|
|
|
use ONGR\ElasticsearchBundle\Service\Manager; |
|
15
|
|
|
use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery; |
|
16
|
|
|
use ONGR\ElasticsearchDSL\Query\MatchAllQuery; |
|
17
|
|
|
use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery; |
|
18
|
|
|
use ONGR\ElasticsearchDSL\Search; |
|
19
|
|
|
use ONGR\ElasticsearchDSL\Sort\FieldSort; |
|
20
|
|
|
use ProxyManager\Factory\LazyLoadingValueHolderFactory; |
|
21
|
|
|
use ProxyManager\Proxy\LazyLoadingInterface; |
|
22
|
|
|
use Sulu\Bundle\ArticleBundle\Document\ArticleDocument; |
|
23
|
|
|
use Sulu\Bundle\ArticleBundle\Document\ArticleViewDocumentInterface; |
|
24
|
|
|
use Sulu\Bundle\WebsiteBundle\ReferenceStore\ReferenceStoreInterface; |
|
25
|
|
|
use Sulu\Component\Content\Compat\PropertyParameter; |
|
26
|
|
|
use Sulu\Component\DocumentManager\DocumentManagerInterface; |
|
27
|
|
|
use Sulu\Component\SmartContent\AliasDataProviderInterface; |
|
28
|
|
|
use Sulu\Component\SmartContent\Configuration\Builder; |
|
29
|
|
|
use Sulu\Component\SmartContent\Configuration\BuilderInterface; |
|
30
|
|
|
use Sulu\Component\SmartContent\DataProviderInterface; |
|
31
|
|
|
use Sulu\Component\SmartContent\DataProviderResult; |
|
32
|
|
|
|
|
33
|
|
|
/** |
|
34
|
|
|
* Introduces articles in smart-content. |
|
35
|
|
|
*/ |
|
36
|
|
|
class ArticleDataProvider implements DataProviderInterface, AliasDataProviderInterface |
|
37
|
|
|
{ |
|
38
|
|
|
/** |
|
39
|
|
|
* @var Manager |
|
40
|
|
|
*/ |
|
41
|
|
|
protected $searchManager; |
|
42
|
|
|
|
|
43
|
|
|
/** |
|
44
|
|
|
* @var DocumentManagerInterface |
|
45
|
|
|
*/ |
|
46
|
|
|
protected $documentManager; |
|
47
|
|
|
|
|
48
|
|
|
/** |
|
49
|
|
|
* @var LazyLoadingValueHolderFactory |
|
50
|
|
|
*/ |
|
51
|
|
|
protected $proxyFactory; |
|
52
|
|
|
|
|
53
|
|
|
/** |
|
54
|
|
|
* @var ReferenceStoreInterface |
|
55
|
|
|
*/ |
|
56
|
|
|
private $referenceStore; |
|
57
|
|
|
|
|
58
|
|
|
/** |
|
59
|
|
|
* @var string |
|
60
|
|
|
*/ |
|
61
|
|
|
protected $articleDocumentClass; |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* @var int |
|
65
|
|
|
*/ |
|
66
|
|
|
protected $defaultLimit; |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* @param Manager $searchManager |
|
70
|
|
|
* @param DocumentManagerInterface $documentManager |
|
71
|
|
|
* @param LazyLoadingValueHolderFactory $proxyFactory |
|
72
|
|
|
* @param ReferenceStoreInterface $referenceStore |
|
73
|
|
|
* @param string $articleDocumentClass |
|
74
|
|
|
* @param int $defaultLimit |
|
75
|
15 |
|
*/ |
|
76
|
|
|
public function __construct( |
|
77
|
|
|
Manager $searchManager, |
|
78
|
|
|
DocumentManagerInterface $documentManager, |
|
79
|
|
|
LazyLoadingValueHolderFactory $proxyFactory, |
|
80
|
|
|
ReferenceStoreInterface $referenceStore, |
|
81
|
|
|
$articleDocumentClass, |
|
82
|
|
|
$defaultLimit |
|
83
|
15 |
|
) { |
|
84
|
15 |
|
$this->searchManager = $searchManager; |
|
85
|
15 |
|
$this->documentManager = $documentManager; |
|
86
|
15 |
|
$this->proxyFactory = $proxyFactory; |
|
87
|
15 |
|
$this->referenceStore = $referenceStore; |
|
88
|
15 |
|
$this->articleDocumentClass = $articleDocumentClass; |
|
89
|
15 |
|
$this->defaultLimit = $defaultLimit; |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
/** |
|
93
|
|
|
* {@inheritdoc} |
|
94
|
|
|
*/ |
|
95
|
|
|
public function getConfiguration() |
|
96
|
|
|
{ |
|
97
|
|
|
return $this->getConfigurationBuilder()->getConfiguration(); |
|
98
|
|
|
} |
|
99
|
|
|
|
|
100
|
|
|
/** |
|
101
|
|
|
* Create new configuration-builder. |
|
102
|
|
|
* |
|
103
|
|
|
* @return BuilderInterface |
|
104
|
|
|
*/ |
|
105
|
|
|
protected function getConfigurationBuilder() |
|
106
|
|
|
{ |
|
107
|
|
|
return Builder::create() |
|
108
|
|
|
->enableTags() |
|
109
|
|
|
->enableCategories() |
|
110
|
|
|
->enableLimit() |
|
111
|
|
|
->enablePagination() |
|
112
|
|
|
->enablePresentAs() |
|
113
|
|
|
->setDeepLink('article/{locale}/edit:{id}/details') |
|
114
|
|
|
->enableSorting( |
|
115
|
|
|
[ |
|
116
|
|
|
['column' => 'published', 'title' => 'sulu_article.smart-content.published'], |
|
117
|
|
|
['column' => 'authored', 'title' => 'sulu_article.smart-content.authored'], |
|
118
|
|
|
['column' => 'created', 'title' => 'sulu_article.smart-content.created'], |
|
119
|
|
|
['column' => 'title', 'title' => 'sulu_article.smart-content.title'], |
|
120
|
|
|
['column' => 'author_full_name', 'title' => 'sulu_article.smart-content.author-full-name'], |
|
121
|
|
|
] |
|
122
|
|
|
); |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
/** |
|
126
|
|
|
* {@inheritdoc} |
|
127
|
|
|
*/ |
|
128
|
|
|
public function getDefaultPropertyParameter() |
|
129
|
|
|
{ |
|
130
|
|
|
return ['type' => new PropertyParameter('type', null)]; |
|
|
|
|
|
|
131
|
|
|
} |
|
132
|
|
|
|
|
133
|
|
|
/** |
|
134
|
|
|
* {@inheritdoc} |
|
135
|
11 |
|
*/ |
|
136
|
|
|
public function resolveDataItems( |
|
137
|
|
|
array $filters, |
|
138
|
|
|
array $propertyParameter, |
|
139
|
|
|
array $options = [], |
|
140
|
|
|
$limit = null, |
|
141
|
|
|
$page = 1, |
|
142
|
|
|
$pageSize = null |
|
143
|
11 |
|
) { |
|
144
|
11 |
|
$filters['types'] = $this->getTypesProperty($propertyParameter); |
|
145
|
|
|
$filters['excluded'] = $this->getExcludedFilter($filters, $propertyParameter); |
|
146
|
11 |
|
|
|
147
|
|
|
$queryResult = $this->getSearchResult($filters, $limit, $page, $pageSize, $options['locale']); |
|
148
|
11 |
|
|
|
149
|
11 |
|
$result = []; |
|
150
|
|
|
$uuids = []; |
|
151
|
11 |
|
/** @var ArticleViewDocumentInterface $document */ |
|
152
|
10 |
|
foreach ($queryResult as $document) { |
|
|
|
|
|
|
153
|
10 |
|
$uuids[] = $document->getUuid(); |
|
154
|
|
|
$result[] = new ArticleDataItem($document->getUuid(), $document->getTitle(), $document); |
|
155
|
|
|
} |
|
156
|
11 |
|
|
|
157
|
|
|
return new DataProviderResult($result, $this->hasNextPage($queryResult, $limit, $page, $pageSize), $uuids); |
|
158
|
|
|
} |
|
159
|
|
|
|
|
160
|
|
|
/** |
|
161
|
|
|
* {@inheritdoc} |
|
162
|
2 |
|
*/ |
|
163
|
|
|
public function resolveResourceItems( |
|
164
|
|
|
array $filters, |
|
165
|
|
|
array $propertyParameter, |
|
166
|
|
|
array $options = [], |
|
167
|
|
|
$limit = null, |
|
168
|
|
|
$page = 1, |
|
169
|
|
|
$pageSize = null |
|
170
|
2 |
|
) { |
|
171
|
2 |
|
$filters['types'] = $this->getTypesProperty($propertyParameter); |
|
172
|
|
|
$filters['excluded'] = $this->getExcludedFilter($filters, $propertyParameter); |
|
173
|
2 |
|
|
|
174
|
|
|
$queryResult = $this->getSearchResult($filters, $limit, $page, $pageSize, $options['locale']); |
|
175
|
2 |
|
|
|
176
|
2 |
|
$result = []; |
|
177
|
|
|
$uuids = []; |
|
178
|
2 |
|
/** @var ArticleViewDocumentInterface $document */ |
|
179
|
2 |
|
foreach ($queryResult as $document) { |
|
|
|
|
|
|
180
|
|
|
$this->referenceStore->add($document->getUuid()); |
|
181
|
2 |
|
|
|
182
|
2 |
|
$uuids[] = $document->getUuid(); |
|
183
|
|
|
$result[] = new ArticleResourceItem( |
|
184
|
2 |
|
$document, |
|
185
|
|
|
$this->getResource($document->getUuid(), $document->getLocale()) |
|
|
|
|
|
|
186
|
|
|
); |
|
187
|
|
|
} |
|
188
|
2 |
|
|
|
189
|
|
|
return new DataProviderResult($result, $this->hasNextPage($queryResult, $limit, $page, $pageSize), $uuids); |
|
190
|
|
|
} |
|
191
|
|
|
|
|
192
|
|
|
/** |
|
193
|
|
|
* {@inheritdoc} |
|
194
|
|
|
*/ |
|
195
|
|
|
public function resolveDatasource($datasource, array $propertyParameter, array $options) |
|
196
|
|
|
{ |
|
197
|
|
|
return; |
|
198
|
|
|
} |
|
199
|
|
|
|
|
200
|
|
|
/** |
|
201
|
|
|
* Returns flag "hasNextPage". |
|
202
|
|
|
* It combines the limit/query-count with the page and page-size. |
|
203
|
|
|
* |
|
204
|
|
|
* @param \Countable $queryResult |
|
205
|
|
|
* @param int $limit |
|
206
|
|
|
* @param int $page |
|
207
|
|
|
* @param int $pageSize |
|
208
|
|
|
* |
|
209
|
|
|
* @return bool |
|
210
|
13 |
|
*/ |
|
211
|
|
|
private function hasNextPage(\Countable $queryResult, $limit, $page, $pageSize) |
|
212
|
13 |
|
{ |
|
213
|
13 |
|
$count = $queryResult->count(); |
|
214
|
2 |
|
if ($limit && $limit < $count) { |
|
215
|
|
|
$count = $limit; |
|
216
|
|
|
} |
|
217
|
13 |
|
|
|
218
|
|
|
return $count > ($page * $pageSize); |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
/** |
|
222
|
|
|
* Creates search for filters and returns search-result. |
|
223
|
|
|
* |
|
224
|
|
|
* @param array $filters |
|
225
|
|
|
* @param int $limit |
|
226
|
|
|
* @param int $page |
|
227
|
|
|
* @param int $pageSize |
|
228
|
|
|
* @param string $locale |
|
229
|
|
|
* |
|
230
|
|
|
* @return \Countable |
|
231
|
13 |
|
*/ |
|
232
|
|
|
private function getSearchResult(array $filters, $limit, $page, $pageSize, $locale) |
|
233
|
13 |
|
{ |
|
234
|
13 |
|
$repository = $this->searchManager->getRepository($this->articleDocumentClass); |
|
235
|
13 |
|
$search = $this->createSearch($repository->createSearch(), $filters, $locale); |
|
236
|
|
|
if (!$search) { |
|
237
|
|
|
return new \ArrayIterator([]); |
|
238
|
|
|
} |
|
239
|
13 |
|
|
|
240
|
|
|
$this->addPagination($search, $pageSize, $page, $limit); |
|
241
|
13 |
|
|
|
242
|
|
|
if (array_key_exists('sortBy', $filters) && is_array($filters['sortBy'])) { |
|
243
|
|
|
$sortMethod = array_key_exists('sortMethod', $filters) ? $filters['sortMethod'] : 'asc'; |
|
244
|
|
|
$this->appendSortBy($filters['sortBy'], $sortMethod, $search); |
|
245
|
|
|
} |
|
246
|
13 |
|
|
|
247
|
|
|
return $repository->findDocuments($search); |
|
248
|
|
|
} |
|
249
|
|
|
|
|
250
|
|
|
/** |
|
251
|
|
|
* Initialize search with neccesary queries. |
|
252
|
|
|
* |
|
253
|
|
|
* @param Search $search |
|
254
|
|
|
* @param array $filters |
|
255
|
|
|
* @param string $locale |
|
256
|
|
|
* |
|
257
|
|
|
* @return Search |
|
258
|
12 |
|
*/ |
|
259
|
|
|
protected function createSearch(Search $search, array $filters, $locale) |
|
260
|
12 |
|
{ |
|
261
|
2 |
|
if (0 < count($filters['excluded'])) { |
|
262
|
2 |
|
foreach ($filters['excluded'] as $uuid) { |
|
263
|
|
|
$search->addQuery(new TermQuery('uuid', $uuid), BoolQuery::MUST_NOT); |
|
264
|
|
|
} |
|
265
|
|
|
} |
|
266
|
12 |
|
|
|
267
|
|
|
$query = new BoolQuery(); |
|
268
|
12 |
|
|
|
269
|
12 |
|
$queriesCount = 0; |
|
270
|
12 |
|
$operator = $this->getFilter($filters, 'tagOperator', 'or'); |
|
271
|
12 |
|
$this->addBoolQuery('tags', $filters, 'excerpt.tags.id', $operator, $query, $queriesCount); |
|
272
|
12 |
|
$operator = $this->getFilter($filters, 'websiteTagsOperator', 'or'); |
|
273
|
|
|
$this->addBoolQuery('websiteTags', $filters, 'excerpt.tags.id', $operator, $query, $queriesCount); |
|
274
|
12 |
|
|
|
275
|
12 |
|
$operator = $this->getFilter($filters, 'categoryOperator', 'or'); |
|
276
|
12 |
|
$this->addBoolQuery('categories', $filters, 'excerpt.categories.id', $operator, $query, $queriesCount); |
|
277
|
12 |
|
$operator = $this->getFilter($filters, 'websiteCategoriesOperator', 'or'); |
|
278
|
|
|
$this->addBoolQuery('websiteCategories', $filters, 'excerpt.categories.id', $operator, $query, $queriesCount); |
|
279
|
12 |
|
|
|
280
|
12 |
|
if (null !== $locale) { |
|
281
|
|
|
$search->addQuery(new TermQuery('locale', $locale)); |
|
282
|
|
|
} |
|
283
|
12 |
|
|
|
284
|
3 |
|
if (array_key_exists('types', $filters) && $filters['types']) { |
|
285
|
3 |
|
$typesQuery = new BoolQuery(); |
|
286
|
3 |
|
foreach ($filters['types'] as $typeFilter) { |
|
287
|
|
|
$typesQuery->add(new TermQuery('type', $typeFilter), BoolQuery::SHOULD); |
|
288
|
3 |
|
} |
|
289
|
|
|
$search->addQuery($typesQuery); |
|
290
|
|
|
} |
|
291
|
12 |
|
|
|
292
|
12 |
|
if (0 === $queriesCount) { |
|
293
|
|
|
$search->addQuery(new MatchAllQuery(), BoolQuery::MUST); |
|
294
|
|
|
} else { |
|
295
|
|
|
$search->addQuery($query, BoolQuery::MUST); |
|
296
|
|
|
} |
|
297
|
12 |
|
|
|
298
|
|
|
return $search; |
|
299
|
|
|
} |
|
300
|
|
|
|
|
301
|
|
|
/** |
|
302
|
|
|
* Returns array with all types defined in property parameter. |
|
303
|
|
|
* |
|
304
|
|
|
* @param array $propertyParameter |
|
305
|
|
|
* |
|
306
|
|
|
* @return array |
|
307
|
13 |
|
*/ |
|
308
|
|
|
private function getTypesProperty($propertyParameter) |
|
309
|
13 |
|
{ |
|
310
|
|
|
$filterTypes = []; |
|
311
|
13 |
|
|
|
312
|
13 |
|
if (array_key_exists('types', $propertyParameter) |
|
313
|
|
|
&& null !== ($types = explode(',', $propertyParameter['types']->getValue())) |
|
314
|
3 |
|
) { |
|
315
|
3 |
|
foreach ($types as $type) { |
|
316
|
|
|
$filterTypes[] = $type; |
|
317
|
|
|
} |
|
318
|
|
|
} |
|
319
|
13 |
|
|
|
320
|
|
|
return $filterTypes; |
|
321
|
|
|
} |
|
322
|
|
|
|
|
323
|
|
|
/** |
|
324
|
|
|
* Returns excluded articles. |
|
325
|
|
|
* |
|
326
|
|
|
* @param array $filters |
|
327
|
|
|
* @param PropertyParameter[] $propertyParameter |
|
328
|
|
|
* |
|
329
|
|
|
* @return array |
|
330
|
13 |
|
*/ |
|
331
|
|
|
private function getExcludedFilter(array $filters, array $propertyParameter) |
|
332
|
13 |
|
{ |
|
333
|
13 |
|
$excluded = array_key_exists('excluded', $filters) ? $filters['excluded'] : []; |
|
334
|
13 |
|
if (array_key_exists('exclude_duplicates', $propertyParameter) |
|
335
|
|
|
&& $propertyParameter['exclude_duplicates']->getValue() |
|
336
|
1 |
|
) { |
|
337
|
|
|
$excluded = array_merge($excluded, $this->referenceStore->getAll()); |
|
338
|
|
|
} |
|
339
|
13 |
|
|
|
340
|
|
|
return $excluded; |
|
341
|
|
|
} |
|
342
|
|
|
|
|
343
|
|
|
/** |
|
344
|
|
|
* Extension point to append order. |
|
345
|
|
|
* |
|
346
|
|
|
* @param array $sortBy |
|
347
|
|
|
* @param string $sortMethod |
|
348
|
|
|
* @param Search $search |
|
349
|
|
|
* |
|
350
|
|
|
* @return array parameters for query |
|
351
|
|
|
*/ |
|
352
|
|
|
private function appendSortBy($sortBy, $sortMethod, $search) |
|
353
|
|
|
{ |
|
354
|
|
|
foreach ($sortBy as $column) { |
|
355
|
|
|
$search->addSort(new FieldSort($column, $sortMethod)); |
|
356
|
|
|
} |
|
357
|
|
|
} |
|
358
|
|
|
|
|
359
|
|
|
/** |
|
360
|
|
|
* Add the pagination to given query. |
|
361
|
|
|
* |
|
362
|
|
|
* @param Search $search |
|
363
|
|
|
* @param int $pageSize |
|
364
|
|
|
* @param int $page |
|
365
|
|
|
* @param int $limit |
|
366
|
13 |
|
*/ |
|
367
|
|
|
private function addPagination(Search $search, $pageSize, $page, $limit) |
|
368
|
13 |
|
{ |
|
369
|
13 |
|
$offset = 0; |
|
370
|
4 |
|
if ($pageSize) { |
|
371
|
4 |
|
$pageSize = intval($pageSize); |
|
372
|
|
|
$offset = ($page - 1) * $pageSize; |
|
373
|
|
|
} |
|
374
|
13 |
|
|
|
375
|
11 |
|
if ($limit === null) { |
|
376
|
|
|
$limit = $this->defaultLimit; |
|
377
|
|
|
} |
|
378
|
13 |
|
|
|
379
|
11 |
|
if ($pageSize === null || $offset + $pageSize > $limit) { |
|
380
|
|
|
$pageSize = $limit - $offset; |
|
381
|
11 |
|
|
|
382
|
|
|
if ($pageSize < 0) { |
|
383
|
|
|
$pageSize = 0; |
|
384
|
|
|
} |
|
385
|
|
|
} |
|
386
|
13 |
|
|
|
387
|
13 |
|
$search->setFrom($offset); |
|
388
|
13 |
|
$search->setSize($pageSize); |
|
389
|
|
|
} |
|
390
|
|
|
|
|
391
|
|
|
/** |
|
392
|
|
|
* Add a boolean-query if filter exists. |
|
393
|
|
|
* |
|
394
|
|
|
* @param string $filterName |
|
395
|
|
|
* @param array $filters |
|
396
|
|
|
* @param string $field |
|
397
|
|
|
* @param string $operator |
|
398
|
|
|
* @param BoolQuery $query |
|
399
|
|
|
* @param int $queriesCount |
|
400
|
12 |
|
*/ |
|
401
|
|
|
private function addBoolQuery($filterName, array $filters, $field, $operator, BoolQuery $query, &$queriesCount) |
|
402
|
12 |
|
{ |
|
403
|
|
|
if (0 !== count($tags = $this->getFilter($filters, $filterName))) { |
|
404
|
|
|
++$queriesCount; |
|
405
|
|
|
$query->add($this->getBoolQuery($field, $tags, $operator)); |
|
406
|
12 |
|
} |
|
407
|
|
|
} |
|
408
|
|
|
|
|
409
|
|
|
/** |
|
410
|
|
|
* Returns boolean query for given fields and values. |
|
411
|
|
|
* |
|
412
|
|
|
* @param string $field |
|
413
|
|
|
* @param array $values |
|
414
|
|
|
* @param string $operator |
|
415
|
|
|
* |
|
416
|
|
|
* @return BoolQuery |
|
417
|
|
|
*/ |
|
418
|
|
|
private function getBoolQuery($field, array $values, $operator) |
|
419
|
|
|
{ |
|
420
|
|
|
$type = ('or' === strtolower($operator) ? BoolQuery::SHOULD : BoolQuery::MUST); |
|
421
|
|
|
|
|
422
|
|
|
$query = new BoolQuery(); |
|
423
|
|
|
foreach ($values as $value) { |
|
424
|
|
|
$query->add(new TermQuery($field, $value), $type); |
|
425
|
|
|
} |
|
426
|
|
|
|
|
427
|
|
|
return $query; |
|
428
|
|
|
} |
|
429
|
|
|
|
|
430
|
|
|
/** |
|
431
|
|
|
* Returns filter value. |
|
432
|
|
|
* |
|
433
|
|
|
* @param array $filters |
|
434
|
|
|
* @param string $name |
|
435
|
|
|
* @param mixed $default |
|
436
|
|
|
* |
|
437
|
|
|
* @return mixed |
|
438
|
12 |
|
*/ |
|
439
|
|
|
private function getFilter(array $filters, $name, $default = null) |
|
440
|
12 |
|
{ |
|
441
|
|
|
if ($this->hasFilter($filters, $name)) { |
|
442
|
|
|
return $filters[$name]; |
|
443
|
|
|
} |
|
444
|
12 |
|
|
|
445
|
|
|
return $default; |
|
446
|
|
|
} |
|
447
|
|
|
|
|
448
|
|
|
/** |
|
449
|
|
|
* Returns true if filter-value exists. |
|
450
|
|
|
* |
|
451
|
|
|
* @param array $filters |
|
452
|
|
|
* @param string $name |
|
453
|
|
|
* |
|
454
|
|
|
* @return bool |
|
455
|
12 |
|
*/ |
|
456
|
|
|
private function hasFilter(array $filters, $name) |
|
457
|
12 |
|
{ |
|
458
|
|
|
return array_key_exists($name, $filters) && null !== $filters[$name]; |
|
459
|
|
|
} |
|
460
|
|
|
|
|
461
|
|
|
/** |
|
462
|
|
|
* Returns Proxy document for uuid. |
|
463
|
|
|
* |
|
464
|
|
|
* @param string $uuid |
|
465
|
|
|
* @param string $locale |
|
466
|
|
|
* |
|
467
|
|
|
* @return object |
|
468
|
2 |
|
*/ |
|
469
|
|
|
private function getResource($uuid, $locale) |
|
470
|
2 |
|
{ |
|
471
|
2 |
|
return $this->proxyFactory->createProxy( |
|
472
|
2 |
|
ArticleDocument::class, |
|
473
|
|
|
function ( |
|
474
|
|
|
&$wrappedObject, |
|
475
|
|
|
LazyLoadingInterface $proxy, |
|
476
|
|
|
$method, |
|
477
|
|
|
array $parameters, |
|
478
|
|
|
&$initializer |
|
479
|
|
|
) use ($uuid, $locale) { |
|
480
|
|
|
$initializer = null; |
|
481
|
|
|
$wrappedObject = $this->documentManager->find($uuid, $locale); |
|
482
|
|
|
|
|
483
|
2 |
|
return true; |
|
484
|
|
|
} |
|
485
|
|
|
); |
|
486
|
|
|
} |
|
487
|
|
|
|
|
488
|
|
|
/** |
|
489
|
|
|
* {@inheritdoc} |
|
490
|
|
|
*/ |
|
491
|
|
|
public function getAlias() |
|
492
|
|
|
{ |
|
493
|
|
|
return 'article'; |
|
494
|
|
|
} |
|
495
|
|
|
} |
|
496
|
|
|
|
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.