Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like SearchServiceTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SearchServiceTest, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
34 | class SearchServiceTest extends BaseTest |
||
35 | { |
||
36 | public function getFilterContentSearches() |
||
37 | { |
||
38 | $fixtureDir = $this->getFixtureDir(); |
||
39 | |||
40 | return array( |
||
41 | 0 => array( |
||
42 | array( |
||
43 | 'filter' => new Criterion\ContentId( |
||
44 | array(1, 4, 10) |
||
45 | ), |
||
46 | 'sortClauses' => array(new SortClause\ContentId()), |
||
47 | ), |
||
48 | $fixtureDir . 'ContentId.php', |
||
49 | ), |
||
50 | 1 => array( |
||
51 | array( |
||
52 | 'filter' => new Criterion\LogicalAnd( |
||
53 | array( |
||
54 | new Criterion\ContentId( |
||
55 | array(1, 4, 10) |
||
56 | ), |
||
57 | new Criterion\ContentId( |
||
58 | array(4, 12) |
||
59 | ), |
||
60 | ) |
||
61 | ), |
||
62 | 'sortClauses' => array(new SortClause\ContentId()), |
||
63 | ), |
||
64 | $fixtureDir . 'LogicalAnd.php', |
||
65 | ), |
||
66 | 2 => array( |
||
67 | array( |
||
68 | 'filter' => new Criterion\LogicalOr( |
||
69 | array( |
||
70 | new Criterion\ContentId( |
||
71 | array(1, 4, 10) |
||
72 | ), |
||
73 | new Criterion\ContentId( |
||
74 | array(4, 12) |
||
75 | ), |
||
76 | ) |
||
77 | ), |
||
78 | 'sortClauses' => array(new SortClause\ContentId()), |
||
79 | ), |
||
80 | $fixtureDir . 'LogicalOr.php', |
||
81 | ), |
||
82 | 3 => array( |
||
83 | array( |
||
84 | 'filter' => new Criterion\LogicalAnd( |
||
85 | array( |
||
86 | new Criterion\ContentId( |
||
87 | array(1, 4, 10) |
||
88 | ), |
||
89 | new Criterion\LogicalNot( |
||
90 | new Criterion\ContentId( |
||
91 | array(10, 12) |
||
92 | ) |
||
93 | ), |
||
94 | ) |
||
95 | ), |
||
96 | 'sortClauses' => array(new SortClause\ContentId()), |
||
97 | ), |
||
98 | $fixtureDir . 'LogicalNot.php', |
||
99 | ), |
||
100 | 4 => array( |
||
101 | array( |
||
102 | 'filter' => new Criterion\LogicalAnd( |
||
103 | array( |
||
104 | new Criterion\ContentId( |
||
105 | array(1, 4, 10) |
||
106 | ), |
||
107 | new Criterion\LogicalAnd( |
||
108 | array( |
||
109 | new Criterion\LogicalNot( |
||
110 | new Criterion\ContentId( |
||
111 | array(10, 12) |
||
112 | ) |
||
113 | ), |
||
114 | ) |
||
115 | ), |
||
116 | ) |
||
117 | ), |
||
118 | 'sortClauses' => array(new SortClause\ContentId()), |
||
119 | ), |
||
120 | $fixtureDir . 'LogicalNot.php', |
||
121 | ), |
||
122 | 5 => array( |
||
123 | array( |
||
124 | 'filter' => new Criterion\ContentTypeId( |
||
125 | 4 |
||
126 | ), |
||
127 | 'sortClauses' => array(new SortClause\ContentId()), |
||
128 | ), |
||
129 | $fixtureDir . 'ContentTypeId.php', |
||
130 | ), |
||
131 | 6 => array( |
||
132 | array( |
||
133 | 'filter' => new Criterion\ContentTypeIdentifier( |
||
134 | 'user' |
||
135 | ), |
||
136 | 'sortClauses' => array(new SortClause\ContentId()), |
||
137 | ), |
||
138 | $fixtureDir . 'ContentTypeId.php', |
||
139 | ), |
||
140 | 7 => array( |
||
141 | array( |
||
142 | 'filter' => new Criterion\MatchNone(), |
||
143 | 'sortClauses' => array(new SortClause\ContentId()), |
||
144 | ), |
||
145 | $fixtureDir . 'MatchNone.php', |
||
146 | ), |
||
147 | 8 => array( |
||
148 | array( |
||
149 | 'filter' => new Criterion\ContentTypeGroupId( |
||
150 | 2 |
||
151 | ), |
||
152 | 'sortClauses' => array(new SortClause\ContentId()), |
||
153 | ), |
||
154 | $fixtureDir . 'ContentTypeGroupId.php', |
||
155 | ), |
||
156 | 9 => array( |
||
157 | array( |
||
158 | 'filter' => new Criterion\DateMetadata( |
||
159 | Criterion\DateMetadata::MODIFIED, |
||
160 | Criterion\Operator::GT, |
||
161 | 1343140540 |
||
162 | ), |
||
163 | 'sortClauses' => array(new SortClause\ContentId()), |
||
164 | ), |
||
165 | $fixtureDir . 'DateMetadataGt.php', |
||
166 | ), |
||
167 | 10 => array( |
||
168 | array( |
||
169 | 'filter' => new Criterion\DateMetadata( |
||
170 | Criterion\DateMetadata::MODIFIED, |
||
171 | Criterion\Operator::GTE, |
||
172 | 1311154215 |
||
173 | ), |
||
174 | 'sortClauses' => array(new SortClause\ContentId()), |
||
175 | ), |
||
176 | $fixtureDir . 'DateMetadataGte.php', |
||
177 | ), |
||
178 | 11 => array( |
||
179 | array( |
||
180 | 'filter' => new Criterion\DateMetadata( |
||
181 | Criterion\DateMetadata::MODIFIED, |
||
182 | Criterion\Operator::LTE, |
||
183 | 1311154215 |
||
184 | ), |
||
185 | 'limit' => 10, |
||
186 | 'sortClauses' => array(new SortClause\ContentId()), |
||
187 | ), |
||
188 | $fixtureDir . 'DateMetadataLte.php', |
||
189 | ), |
||
190 | 12 => array( |
||
191 | array( |
||
192 | 'filter' => new Criterion\DateMetadata( |
||
193 | Criterion\DateMetadata::MODIFIED, |
||
194 | Criterion\Operator::IN, |
||
195 | array(1033920794, 1060695457, 1343140540) |
||
196 | ), |
||
197 | 'sortClauses' => array(new SortClause\ContentId()), |
||
198 | ), |
||
199 | $fixtureDir . 'DateMetadataIn.php', |
||
200 | ), |
||
201 | 13 => array( |
||
202 | array( |
||
203 | 'filter' => new Criterion\DateMetadata( |
||
204 | Criterion\DateMetadata::MODIFIED, |
||
205 | Criterion\Operator::BETWEEN, |
||
206 | array(1033920776, 1072180276) |
||
207 | ), |
||
208 | 'sortClauses' => array(new SortClause\ContentId()), |
||
209 | ), |
||
210 | $fixtureDir . 'DateMetadataBetween.php', |
||
211 | ), |
||
212 | 14 => array( |
||
213 | array( |
||
214 | 'filter' => new Criterion\DateMetadata( |
||
215 | Criterion\DateMetadata::CREATED, |
||
216 | Criterion\Operator::BETWEEN, |
||
217 | array(1033920776, 1072180278) |
||
218 | ), |
||
219 | 'sortClauses' => array(new SortClause\ContentId()), |
||
220 | ), |
||
221 | $fixtureDir . 'DateMetadataCreated.php', |
||
222 | ), |
||
223 | 15 => array( |
||
224 | array( |
||
225 | 'filter' => new Criterion\CustomField( |
||
226 | 'user_group_name_value_s', |
||
227 | Criterion\Operator::EQ, |
||
228 | 'Members' |
||
229 | ), |
||
230 | 'sortClauses' => array(new SortClause\ContentId()), |
||
231 | ), |
||
232 | $fixtureDir . 'Field.php', |
||
233 | ), |
||
234 | 16 => array( |
||
235 | array( |
||
236 | 'filter' => new Criterion\CustomField( |
||
237 | 'user_group_name_value_s', |
||
238 | Criterion\Operator::CONTAINS, |
||
239 | 'Members' |
||
240 | ), |
||
241 | 'sortClauses' => array(new SortClause\ContentId()), |
||
242 | ), |
||
243 | $fixtureDir . 'Field.php', |
||
244 | ), |
||
245 | 17 => array( |
||
246 | array( |
||
247 | 'filter' => new Criterion\CustomField( |
||
248 | 'user_group_name_value_s', |
||
249 | Criterion\Operator::LT, |
||
250 | 'Members' |
||
251 | ), |
||
252 | 'sortClauses' => array(new SortClause\ContentId()), |
||
253 | ), |
||
254 | $fixtureDir . 'CustomFieldLt.php', |
||
255 | ), |
||
256 | 18 => array( |
||
257 | array( |
||
258 | 'filter' => new Criterion\CustomField( |
||
259 | 'user_group_name_value_s', |
||
260 | Criterion\Operator::LTE, |
||
261 | 'Members' |
||
262 | ), |
||
263 | 'sortClauses' => array(new SortClause\ContentId()), |
||
264 | ), |
||
265 | $fixtureDir . 'CustomFieldLte.php', |
||
266 | ), |
||
267 | 19 => array( |
||
268 | array( |
||
269 | 'filter' => new Criterion\CustomField( |
||
270 | 'user_group_name_value_s', |
||
271 | Criterion\Operator::GT, |
||
272 | 'Members' |
||
273 | ), |
||
274 | 'sortClauses' => array(new SortClause\ContentId()), |
||
275 | ), |
||
276 | $fixtureDir . 'CustomFieldGt.php', |
||
277 | ), |
||
278 | 20 => array( |
||
279 | array( |
||
280 | 'filter' => new Criterion\CustomField( |
||
281 | 'user_group_name_value_s', |
||
282 | Criterion\Operator::GTE, |
||
283 | 'Members' |
||
284 | ), |
||
285 | 'sortClauses' => array(new SortClause\ContentId()), |
||
286 | ), |
||
287 | $fixtureDir . 'CustomFieldGte.php', |
||
288 | ), |
||
289 | 21 => array( |
||
290 | array( |
||
291 | 'filter' => new Criterion\CustomField( |
||
292 | 'user_group_name_value_s', |
||
293 | Criterion\Operator::BETWEEN, |
||
294 | array('Administrator users', 'Members') |
||
295 | ), |
||
296 | 'sortClauses' => array(new SortClause\ContentId()), |
||
297 | ), |
||
298 | $fixtureDir . 'CustomFieldBetween.php', |
||
299 | ), |
||
300 | 22 => array( |
||
301 | array( |
||
302 | 'filter' => new Criterion\RemoteId( |
||
303 | array('f5c88a2209584891056f987fd965b0ba', 'faaeb9be3bd98ed09f606fc16d144eca') |
||
304 | ), |
||
305 | 'sortClauses' => array(new SortClause\ContentId()), |
||
306 | ), |
||
307 | $fixtureDir . 'RemoteId.php', |
||
308 | ), |
||
309 | 23 => array( |
||
310 | array( |
||
311 | 'filter' => new Criterion\SectionId( |
||
312 | array(2) |
||
313 | ), |
||
314 | 'sortClauses' => array(new SortClause\ContentId()), |
||
315 | ), |
||
316 | $fixtureDir . 'SectionId.php', |
||
317 | ), |
||
318 | 24 => array( |
||
319 | array( |
||
320 | 'filter' => new Criterion\Field( |
||
321 | 'name', |
||
322 | Criterion\Operator::EQ, |
||
323 | 'Members' |
||
324 | ), |
||
325 | 'sortClauses' => array(new SortClause\ContentId()), |
||
326 | ), |
||
327 | $fixtureDir . 'Field.php', |
||
328 | ), |
||
329 | 25 => array( |
||
330 | array( |
||
331 | 'filter' => new Criterion\Field( |
||
332 | 'name', |
||
333 | Criterion\Operator::IN, |
||
334 | array('Members', 'Anonymous Users') |
||
335 | ), |
||
336 | 'sortClauses' => array(new SortClause\ContentId()), |
||
337 | ), |
||
338 | $fixtureDir . 'FieldIn.php', |
||
339 | ), |
||
340 | 26 => array( |
||
341 | array( |
||
342 | 'filter' => new Criterion\DateMetadata( |
||
343 | Criterion\DateMetadata::MODIFIED, |
||
344 | Criterion\Operator::BETWEEN, |
||
345 | array(1033920275, 1033920794) |
||
346 | ), |
||
347 | 'sortClauses' => array(new SortClause\ContentId()), |
||
348 | ), |
||
349 | $fixtureDir . 'FieldBetween.php', |
||
350 | ), |
||
351 | 27 => array( |
||
352 | array( |
||
353 | 'filter' => new Criterion\LogicalOr( |
||
354 | array( |
||
355 | new Criterion\Field( |
||
356 | 'name', |
||
357 | Criterion\Operator::EQ, |
||
358 | 'Members' |
||
359 | ), |
||
360 | new Criterion\DateMetadata( |
||
361 | Criterion\DateMetadata::MODIFIED, |
||
362 | Criterion\Operator::BETWEEN, |
||
363 | array(1033920275, 1033920794) |
||
364 | ), |
||
365 | ) |
||
366 | ), |
||
367 | 'sortClauses' => array(new SortClause\ContentId()), |
||
368 | ), |
||
369 | $fixtureDir . 'FieldOr.php', |
||
370 | ), |
||
371 | 28 => array( |
||
372 | array( |
||
373 | 'filter' => new Criterion\Subtree( |
||
374 | '/1/5/' |
||
375 | ), |
||
376 | 'sortClauses' => array(new SortClause\ContentId()), |
||
377 | ), |
||
378 | $fixtureDir . 'Subtree.php', |
||
379 | ), |
||
380 | 29 => array( |
||
381 | array( |
||
382 | 'filter' => new Criterion\LocationId( |
||
383 | array(1, 2, 5) |
||
384 | ), |
||
385 | 'sortClauses' => array(new SortClause\ContentId()), |
||
386 | ), |
||
387 | $fixtureDir . 'LocationId.php', |
||
388 | ), |
||
389 | 30 => array( |
||
390 | array( |
||
391 | 'filter' => new Criterion\ParentLocationId( |
||
392 | array(1) |
||
393 | ), |
||
394 | 'sortClauses' => array(new SortClause\ContentId()), |
||
395 | ), |
||
396 | $fixtureDir . 'ParentLocationId.php', |
||
397 | ), |
||
398 | 31 => array( |
||
399 | array( |
||
400 | 'filter' => new Criterion\LocationRemoteId( |
||
401 | array('3f6d92f8044aed134f32153517850f5a', 'f3e90596361e31d496d4026eb624c983') |
||
402 | ), |
||
403 | 'sortClauses' => array(new SortClause\ContentId()), |
||
404 | ), |
||
405 | $fixtureDir . 'LocationRemoteId.php', |
||
406 | ), |
||
407 | 32 => array( |
||
408 | array( |
||
409 | // There is no Status Criterion anymore, this should match all published as well |
||
410 | 'filter' => new Criterion\Subtree( |
||
411 | '/1/' |
||
412 | ), |
||
413 | 'sortClauses' => array(new SortClause\ContentId()), |
||
414 | 'limit' => 50, |
||
415 | ), |
||
416 | $fixtureDir . 'Status.php', |
||
417 | // Result having the same sort level should be sorted between them to be system independent |
||
418 | function (&$data) { |
||
419 | usort( |
||
420 | $data->searchHits, |
||
421 | function ($a, $b) { |
||
422 | if ($a->score == $b->score) { |
||
423 | if ($a->valueObject['id'] == $b->valueObject['id']) { |
||
424 | return 0; |
||
425 | } |
||
426 | |||
427 | // Order by ascending ID |
||
428 | return ($a->valueObject['id'] < $b->valueObject['id']) ? -1 : 1; |
||
429 | } |
||
430 | |||
431 | // Order by descending score |
||
432 | return ($a->score > $b->score) ? -1 : 1; |
||
433 | } |
||
434 | ); |
||
435 | }, |
||
436 | ), |
||
437 | 33 => array( |
||
438 | array( |
||
439 | 'filter' => new Criterion\UserMetadata( |
||
440 | Criterion\UserMetadata::MODIFIER, |
||
441 | Criterion\Operator::EQ, |
||
442 | 14 |
||
443 | ), |
||
444 | 'sortClauses' => array( |
||
445 | new SortClause\ContentId(), |
||
446 | ), |
||
447 | 'limit' => 50, |
||
448 | ), |
||
449 | $fixtureDir . 'UserMetadata.php', |
||
450 | ), |
||
451 | 34 => array( |
||
452 | array( |
||
453 | 'filter' => new Criterion\UserMetadata( |
||
454 | Criterion\UserMetadata::MODIFIER, |
||
455 | Criterion\Operator::IN, |
||
456 | array(14) |
||
457 | ), |
||
458 | 'sortClauses' => array( |
||
459 | new SortClause\ContentId(), |
||
460 | ), |
||
461 | 'limit' => 50, |
||
462 | ), |
||
463 | $fixtureDir . 'UserMetadata.php', |
||
464 | ), |
||
465 | 35 => array( |
||
466 | array( |
||
467 | 'filter' => new Criterion\UserMetadata( |
||
468 | Criterion\UserMetadata::OWNER, |
||
469 | Criterion\Operator::EQ, |
||
470 | 14 |
||
471 | ), |
||
472 | 'sortClauses' => array( |
||
473 | new SortClause\ContentId(), |
||
474 | ), |
||
475 | 'limit' => 50, |
||
476 | ), |
||
477 | $fixtureDir . 'UserMetadata.php', |
||
478 | ), |
||
479 | 36 => array( |
||
480 | array( |
||
481 | 'filter' => new Criterion\UserMetadata( |
||
482 | Criterion\UserMetadata::OWNER, |
||
483 | Criterion\Operator::IN, |
||
484 | array(14) |
||
485 | ), |
||
486 | 'sortClauses' => array( |
||
487 | new SortClause\ContentId(), |
||
488 | ), |
||
489 | 'limit' => 50, |
||
490 | ), |
||
491 | $fixtureDir . 'UserMetadata.php', |
||
492 | ), |
||
493 | 37 => array( |
||
494 | array( |
||
495 | 'filter' => new Criterion\UserMetadata( |
||
496 | Criterion\UserMetadata::GROUP, |
||
497 | Criterion\Operator::EQ, |
||
498 | 12 |
||
499 | ), |
||
500 | 'sortClauses' => array( |
||
501 | new SortClause\ContentId(), |
||
502 | ), |
||
503 | 'limit' => 50, |
||
504 | ), |
||
505 | $fixtureDir . 'UserMetadata.php', |
||
506 | ), |
||
507 | 38 => array( |
||
508 | array( |
||
509 | 'filter' => new Criterion\UserMetadata( |
||
510 | Criterion\UserMetadata::GROUP, |
||
511 | Criterion\Operator::IN, |
||
512 | array(12) |
||
513 | ), |
||
514 | 'sortClauses' => array( |
||
515 | new SortClause\ContentId(), |
||
516 | ), |
||
517 | 'limit' => 50, |
||
518 | ), |
||
519 | $fixtureDir . 'UserMetadata.php', |
||
520 | ), |
||
521 | 39 => array( |
||
522 | array( |
||
523 | 'filter' => new Criterion\UserMetadata( |
||
524 | Criterion\UserMetadata::GROUP, |
||
525 | Criterion\Operator::EQ, |
||
526 | 4 |
||
527 | ), |
||
528 | 'sortClauses' => array( |
||
529 | new SortClause\ContentId(), |
||
530 | ), |
||
531 | 'limit' => 50, |
||
532 | ), |
||
533 | $fixtureDir . 'UserMetadata.php', |
||
534 | ), |
||
535 | 40 => array( |
||
536 | array( |
||
537 | 'filter' => new Criterion\UserMetadata( |
||
538 | Criterion\UserMetadata::GROUP, |
||
539 | Criterion\Operator::IN, |
||
540 | array(4) |
||
541 | ), |
||
542 | 'sortClauses' => array( |
||
543 | new SortClause\ContentId(), |
||
544 | ), |
||
545 | 'limit' => 50, |
||
546 | ), |
||
547 | $fixtureDir . 'UserMetadata.php', |
||
548 | ), |
||
549 | 41 => array( |
||
550 | array( |
||
551 | 'filter' => new Criterion\Ancestor( |
||
552 | array( |
||
|
|||
553 | '/1/5/44/', |
||
554 | '/1/5/44/45/', |
||
555 | ) |
||
556 | ), |
||
557 | 'sortClauses' => array( |
||
558 | new SortClause\ContentId(), |
||
559 | ), |
||
560 | 'limit' => 50, |
||
561 | ), |
||
562 | $fixtureDir . 'AncestorContent.php', |
||
563 | ), |
||
564 | ); |
||
565 | } |
||
566 | |||
567 | public function getContentQuerySearches() |
||
568 | { |
||
569 | $fixtureDir = $this->getFixtureDir(); |
||
570 | |||
571 | return array( |
||
572 | array( |
||
573 | array( |
||
574 | 'filter' => new Criterion\ContentId( |
||
575 | array(58, 10) |
||
576 | ), |
||
577 | 'query' => new Criterion\FullText('contact'), |
||
578 | 'sortClauses' => array(new SortClause\ContentId()), |
||
579 | ), |
||
580 | $fixtureDir . 'FullTextFiltered.php', |
||
581 | ), |
||
582 | array( |
||
583 | array( |
||
584 | 'query' => new Criterion\FullText( |
||
585 | 'contact', |
||
586 | array( |
||
587 | 'boost' => array( |
||
588 | 'title' => 2, |
||
589 | ), |
||
590 | 'fuzziness' => .5, |
||
591 | ) |
||
592 | ), |
||
593 | 'sortClauses' => array(new SortClause\ContentId()), |
||
594 | ), |
||
595 | $fixtureDir . 'FullText.php', |
||
596 | ), |
||
597 | array( |
||
598 | array( |
||
599 | 'query' => new Criterion\FullText( |
||
600 | 'Contact*' |
||
601 | ), |
||
602 | 'sortClauses' => array(new SortClause\ContentId()), |
||
603 | ), |
||
604 | $fixtureDir . 'FullTextWildcard.php', |
||
605 | ), |
||
606 | array( |
||
607 | array( |
||
608 | 'query' => new Criterion\LanguageCode('eng-GB', false), |
||
609 | 'sortClauses' => array(new SortClause\ContentId()), |
||
610 | ), |
||
611 | $fixtureDir . 'LanguageCode.php', |
||
612 | ), |
||
613 | array( |
||
614 | array( |
||
615 | 'query' => new Criterion\LanguageCode(array('eng-US', 'eng-GB')), |
||
616 | 'offset' => 10, |
||
617 | 'sortClauses' => array(new SortClause\ContentId()), |
||
618 | ), |
||
619 | $fixtureDir . 'LanguageCodeIn.php', |
||
620 | ), |
||
621 | array( |
||
622 | array( |
||
623 | 'query' => new Criterion\LanguageCode('eng-GB'), |
||
624 | 'offset' => 10, |
||
625 | 'sortClauses' => array(new SortClause\ContentId()), |
||
626 | ), |
||
627 | $fixtureDir . 'LanguageCodeAlwaysAvailable.php', |
||
628 | ), |
||
629 | array( |
||
630 | array( |
||
631 | 'query' => new Criterion\Visibility( |
||
632 | Criterion\Visibility::VISIBLE |
||
633 | ), |
||
634 | 'sortClauses' => array(new SortClause\ContentId()), |
||
635 | 'limit' => 50, |
||
636 | ), |
||
637 | $fixtureDir . 'Visibility.php', |
||
638 | ), |
||
639 | ); |
||
640 | } |
||
641 | |||
642 | public function getLocationQuerySearches() |
||
643 | { |
||
644 | $fixtureDir = $this->getFixtureDir(); |
||
645 | |||
646 | return array( |
||
647 | array( |
||
648 | array( |
||
649 | 'query' => new Criterion\Location\Depth(Criterion\Operator::EQ, 1), |
||
650 | 'sortClauses' => array(new SortClause\ContentId()), |
||
651 | ), |
||
652 | $fixtureDir . 'Depth.php', |
||
653 | ), |
||
654 | array( |
||
655 | array( |
||
656 | 'query' => new Criterion\Location\Depth(Criterion\Operator::IN, array(1, 3)), |
||
657 | 'sortClauses' => array(new SortClause\ContentId()), |
||
658 | ), |
||
659 | $fixtureDir . 'DepthIn.php', |
||
660 | ), |
||
661 | array( |
||
662 | array( |
||
663 | 'query' => new Criterion\Location\Depth(Criterion\Operator::GT, 2), |
||
664 | 'sortClauses' => array(new SortClause\ContentId()), |
||
665 | ), |
||
666 | $fixtureDir . 'DepthGt.php', |
||
667 | ), |
||
668 | array( |
||
669 | array( |
||
670 | 'query' => new Criterion\Location\Depth(Criterion\Operator::GTE, 2), |
||
671 | 'sortClauses' => array(new SortClause\ContentId()), |
||
672 | 'limit' => 50, |
||
673 | ), |
||
674 | $fixtureDir . 'DepthGte.php', |
||
675 | ), |
||
676 | array( |
||
677 | array( |
||
678 | 'query' => new Criterion\Location\Depth(Criterion\Operator::LT, 2), |
||
679 | 'sortClauses' => array(new SortClause\ContentId()), |
||
680 | ), |
||
681 | $fixtureDir . 'Depth.php', |
||
682 | ), |
||
683 | array( |
||
684 | array( |
||
685 | 'query' => new Criterion\Location\Depth(Criterion\Operator::LTE, 2), |
||
686 | 'sortClauses' => array(new SortClause\ContentId()), |
||
687 | 'limit' => 50, |
||
688 | ), |
||
689 | $fixtureDir . 'DepthLte.php', |
||
690 | ), |
||
691 | array( |
||
692 | array( |
||
693 | 'query' => new Criterion\Location\Depth(Criterion\Operator::BETWEEN, array(1, 2)), |
||
694 | 'sortClauses' => array(new SortClause\ContentId()), |
||
695 | 'limit' => 50, |
||
696 | ), |
||
697 | $fixtureDir . 'DepthLte.php', |
||
698 | ), |
||
699 | array( |
||
700 | array( |
||
701 | 'filter' => new Criterion\Ancestor('/1/5/44/45/'), |
||
702 | 'sortClauses' => array( |
||
703 | new SortClause\Location\Depth(), |
||
704 | ), |
||
705 | 'limit' => 50, |
||
706 | ), |
||
707 | $fixtureDir . 'AncestorLocation.php', |
||
708 | ), |
||
709 | ); |
||
710 | } |
||
711 | |||
712 | /** |
||
713 | * Test for the findContent() method. |
||
714 | * |
||
715 | * @dataProvider getFilterContentSearches |
||
716 | * |
||
717 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
718 | */ |
||
719 | public function testFindContentFiltered($queryData, $fixture, $closure = null) |
||
720 | { |
||
721 | $query = new Query($queryData); |
||
722 | $this->assertQueryFixture($query, $fixture, $closure); |
||
723 | } |
||
724 | |||
725 | /** |
||
726 | * Test for the findContentInfo() method. |
||
727 | * |
||
728 | * @dataProvider getFilterContentSearches |
||
729 | * @see \eZ\Publish\API\Repository\SearchService::findContentInfo() |
||
730 | */ |
||
731 | public function testFindContentInfoFiltered($queryData, $fixture, $closure = null) |
||
732 | { |
||
733 | $query = new Query($queryData); |
||
734 | $this->assertQueryFixture($query, $fixture, $this->getContentInfoFixtureClosure($closure), true); |
||
735 | } |
||
736 | |||
737 | /** |
||
738 | * Test for the findLocations() method. |
||
739 | * |
||
740 | * @dataProvider getFilterContentSearches |
||
741 | * |
||
742 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
743 | */ |
||
744 | public function testFindLocationsContentFiltered($queryData, $fixture, $closure = null) |
||
745 | { |
||
746 | $query = new LocationQuery($queryData); |
||
747 | $this->assertQueryFixture($query, $fixture, $closure); |
||
748 | } |
||
749 | |||
750 | /** |
||
751 | * Test for deprecated $criterion property on query object. |
||
752 | * |
||
753 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
754 | * @deprecated |
||
755 | */ |
||
756 | public function testDeprecatedCriteriaProperty() |
||
757 | { |
||
758 | $this->assertQueryFixture( |
||
759 | new Query( |
||
760 | array( |
||
761 | 'query' => new Criterion\ContentId( |
||
762 | array(1, 4, 10) |
||
763 | ), |
||
764 | 'sortClauses' => array(new SortClause\ContentId()), |
||
765 | ) |
||
766 | ), |
||
767 | $this->getFixtureDir() . 'DeprecatedContentIdQuery.php' |
||
768 | ); |
||
769 | } |
||
770 | |||
771 | /** |
||
772 | * Test for the findContent() method. |
||
773 | * |
||
774 | * @dataProvider getContentQuerySearches |
||
775 | * |
||
776 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
777 | */ |
||
778 | public function testQueryContent($queryData, $fixture, $closure = null) |
||
779 | { |
||
780 | $query = new Query($queryData); |
||
781 | $this->assertQueryFixture($query, $fixture, $closure); |
||
782 | } |
||
783 | |||
784 | /** |
||
785 | * Test for the findContentInfo() method. |
||
786 | * |
||
787 | * @dataProvider getContentQuerySearches |
||
788 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
789 | */ |
||
790 | public function testQueryContentInfo($queryData, $fixture, $closure = null) |
||
791 | { |
||
792 | $query = new Query($queryData); |
||
793 | $this->assertQueryFixture($query, $fixture, $this->getContentInfoFixtureClosure($closure), true); |
||
794 | } |
||
795 | |||
796 | /** |
||
797 | * Test for the findLocations() method. |
||
798 | * |
||
799 | * @dataProvider getContentQuerySearches |
||
800 | * |
||
801 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
802 | */ |
||
803 | public function testQueryContentLocations($queryData, $fixture, $closure = null) |
||
804 | { |
||
805 | $query = new LocationQuery($queryData); |
||
806 | $this->assertQueryFixture($query, $fixture, $closure); |
||
807 | } |
||
808 | |||
809 | /** |
||
810 | * Test for the findLocations() method. |
||
811 | * |
||
812 | * @dataProvider getLocationQuerySearches |
||
813 | * |
||
814 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
815 | */ |
||
816 | public function testQueryLocations($queryData, $fixture, $closure = null) |
||
817 | { |
||
818 | $query = new LocationQuery($queryData); |
||
819 | $this->assertQueryFixture($query, $fixture, $closure); |
||
820 | } |
||
821 | |||
822 | public function getCaseInsensitiveSearches() |
||
823 | { |
||
824 | return array( |
||
825 | array( |
||
826 | array( |
||
827 | 'filter' => new Criterion\Field( |
||
828 | 'name', |
||
829 | Criterion\Operator::EQ, |
||
830 | 'Members' |
||
831 | ), |
||
832 | 'sortClauses' => array(new SortClause\ContentId()), |
||
833 | ), |
||
834 | ), |
||
835 | array( |
||
836 | array( |
||
837 | 'filter' => new Criterion\Field( |
||
838 | 'name', |
||
839 | Criterion\Operator::EQ, |
||
840 | 'members' |
||
841 | ), |
||
842 | 'sortClauses' => array(new SortClause\ContentId()), |
||
843 | ), |
||
844 | ), |
||
845 | array( |
||
846 | array( |
||
847 | 'filter' => new Criterion\Field( |
||
848 | 'name', |
||
849 | Criterion\Operator::EQ, |
||
850 | 'MEMBERS' |
||
851 | ), |
||
852 | 'sortClauses' => array(new SortClause\ContentId()), |
||
853 | ), |
||
854 | ), |
||
855 | ); |
||
856 | } |
||
857 | |||
858 | /** |
||
859 | * Test for the findContent() method. |
||
860 | * |
||
861 | * @dataProvider getCaseInsensitiveSearches |
||
862 | * |
||
863 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
864 | */ |
||
865 | public function testFindContentFieldFiltersCaseSensitivity($queryData) |
||
866 | { |
||
867 | $query = new Query($queryData); |
||
868 | $this->assertQueryFixture( |
||
869 | $query, |
||
870 | $this->getFixtureDir() . 'Field.php' |
||
871 | ); |
||
872 | } |
||
873 | |||
874 | /** |
||
875 | * Test for the findLocations() method. |
||
876 | * |
||
877 | * @dataProvider getCaseInsensitiveSearches |
||
878 | * |
||
879 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
880 | */ |
||
881 | public function testFindLocationsFieldFiltersCaseSensitivity($queryData) |
||
882 | { |
||
883 | $query = new LocationQuery($queryData); |
||
884 | $this->assertQueryFixture( |
||
885 | $query, |
||
886 | $this->getFixtureDir() . 'Field.php' |
||
887 | ); |
||
888 | } |
||
889 | |||
890 | public function getRelationFieldFilterContentSearches() |
||
891 | { |
||
892 | $fixtureDir = $this->getFixtureDir(); |
||
893 | |||
894 | return array( |
||
895 | 0 => array( |
||
896 | array( |
||
897 | 'filter' => new Criterion\FieldRelation( |
||
898 | 'image', |
||
899 | Criterion\Operator::IN, |
||
900 | array(1, 4, 10) |
||
901 | ), |
||
902 | 'sortClauses' => array(new SortClause\ContentId()), |
||
903 | ), |
||
904 | $fixtureDir . 'FieldRelation.php', |
||
905 | ), |
||
906 | 1 => array( |
||
907 | array( |
||
908 | 'filter' => new Criterion\FieldRelation( |
||
909 | 'image', |
||
910 | Criterion\Operator::IN, |
||
911 | array(4, 49) |
||
912 | ), |
||
913 | 'sortClauses' => array(new SortClause\ContentId()), |
||
914 | ), |
||
915 | $fixtureDir . 'FieldRelationAll.php', |
||
916 | ), |
||
917 | 2 => array( |
||
918 | array( |
||
919 | 'filter' => new Criterion\FieldRelation( |
||
920 | 'image', |
||
921 | Criterion\Operator::IN, |
||
922 | array(4) |
||
923 | ), |
||
924 | 'sortClauses' => array(new SortClause\ContentId()), |
||
925 | ), |
||
926 | $fixtureDir . 'FieldRelation.php', |
||
927 | ), |
||
928 | 3 => array( |
||
929 | array( |
||
930 | 'filter' => new Criterion\FieldRelation( |
||
931 | 'image', |
||
932 | Criterion\Operator::CONTAINS, |
||
933 | array(1, 4, 10) |
||
934 | ), |
||
935 | 'sortClauses' => array(new SortClause\ContentId()), |
||
936 | ), |
||
937 | $fixtureDir . 'MatchNone.php', |
||
938 | ), |
||
939 | 4 => array( |
||
940 | array( |
||
941 | 'filter' => new Criterion\FieldRelation( |
||
942 | 'image', |
||
943 | Criterion\Operator::CONTAINS, |
||
944 | array(4, 49) |
||
945 | ), |
||
946 | 'sortClauses' => array(new SortClause\ContentId()), |
||
947 | ), |
||
948 | $fixtureDir . 'MatchNone.php', |
||
949 | ), |
||
950 | 5 => array( |
||
951 | array( |
||
952 | 'filter' => new Criterion\FieldRelation( |
||
953 | 'image', |
||
954 | Criterion\Operator::CONTAINS, |
||
955 | array(4) |
||
956 | ), |
||
957 | 'sortClauses' => array(new SortClause\ContentId()), |
||
958 | ), |
||
959 | $fixtureDir . 'FieldRelation.php', |
||
960 | ), |
||
961 | ); |
||
962 | } |
||
963 | |||
964 | /** |
||
965 | * Purely for creating relation data needed for testFindRelationFieldContentInfoFiltered(). |
||
966 | */ |
||
967 | public function testRelationContentCreation() |
||
968 | { |
||
969 | $repository = $this->getRepository(); |
||
970 | $galleryType = $repository->getContentTypeService()->loadContentTypeByIdentifier('gallery'); |
||
971 | $contentService = $repository->getContentService(); |
||
972 | |||
973 | $createStruct = $contentService->newContentCreateStruct($galleryType, 'eng-GB'); |
||
974 | $createStruct->setField('name', 'Image gallery'); |
||
975 | $createStruct->setField('image', 49);// Images folder |
||
976 | $draft = $contentService->createContent($createStruct); |
||
977 | $contentService->publishVersion($draft->getVersionInfo()); |
||
978 | |||
979 | $createStruct = $contentService->newContentCreateStruct($galleryType, 'eng-GB'); |
||
980 | $createStruct->setField('name', 'User gallery'); |
||
981 | $createStruct->setField('image', 4);// User folder |
||
982 | $draft = $contentService->createContent($createStruct); |
||
983 | $contentService->publishVersion($draft->getVersionInfo()); |
||
984 | |||
985 | $this->refreshSearch($repository); |
||
986 | } |
||
987 | |||
988 | /** |
||
989 | * Test for FieldRelation using findContentInfo() method. |
||
990 | * |
||
991 | * @dataProvider getRelationFieldFilterContentSearches |
||
992 | * @see \eZ\Publish\API\Repository\SearchService::findContentInfo() |
||
993 | * @depends eZ\Publish\API\Repository\Tests\SearchServiceTest::testRelationContentCreation |
||
994 | */ |
||
995 | public function testFindRelationFieldContentInfoFiltered($queryData, $fixture, $closure = null) |
||
996 | { |
||
997 | $this->getRepository(false);// To make sure repo is setup w/o removing data from testRelationContentCreation |
||
998 | $query = new Query($queryData); |
||
999 | $this->assertQueryFixture($query, $fixture, $this->getContentInfoFixtureClosure($closure), true, true, false); |
||
1000 | } |
||
1001 | |||
1002 | View Code Duplication | public function testFindSingle() |
|
1003 | { |
||
1004 | $repository = $this->getRepository(); |
||
1005 | $searchService = $repository->getSearchService(); |
||
1006 | |||
1007 | $content = $searchService->findSingle( |
||
1008 | new Criterion\ContentId( |
||
1009 | array(4) |
||
1010 | ) |
||
1011 | ); |
||
1012 | |||
1013 | $this->assertEquals( |
||
1014 | 4, |
||
1015 | $content->id |
||
1016 | ); |
||
1017 | } |
||
1018 | |||
1019 | View Code Duplication | public function testFindNoPerformCount() |
|
1020 | { |
||
1021 | $repository = $this->getRepository(); |
||
1022 | $searchService = $repository->getSearchService(); |
||
1023 | |||
1024 | $query = new Query(); |
||
1025 | $query->performCount = false; |
||
1026 | $query->query = new Criterion\ContentTypeId( |
||
1027 | array(4) |
||
1028 | ); |
||
1029 | |||
1030 | $searchHit = $searchService->findContent($query); |
||
1031 | |||
1032 | if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') { |
||
1033 | $this->assertEquals( |
||
1034 | null, |
||
1035 | $searchHit->totalCount |
||
1036 | ); |
||
1037 | } else { |
||
1038 | $this->assertEquals( |
||
1039 | 2, |
||
1040 | $searchHit->totalCount |
||
1041 | ); |
||
1042 | } |
||
1043 | } |
||
1044 | |||
1045 | /** |
||
1046 | * @expectedException \RuntimeException |
||
1047 | */ |
||
1048 | View Code Duplication | public function testFindNoPerformCountException() |
|
1049 | { |
||
1050 | if (ltrim(get_class($this->getSetupFactory()), '\\') !== 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') { |
||
1051 | $this->markTestSkipped('Only applicable to Legacy/DB based search'); |
||
1052 | } |
||
1053 | |||
1054 | $repository = $this->getRepository(); |
||
1055 | $searchService = $repository->getSearchService(); |
||
1056 | |||
1057 | $query = new Query(); |
||
1058 | $query->performCount = false; |
||
1059 | $query->limit = 0; |
||
1060 | $query->query = new Criterion\ContentTypeId( |
||
1061 | array(4) |
||
1062 | ); |
||
1063 | |||
1064 | $searchService->findContent($query); |
||
1065 | } |
||
1066 | |||
1067 | View Code Duplication | public function testFindLocationsNoPerformCount() |
|
1068 | { |
||
1069 | $repository = $this->getRepository(); |
||
1070 | $searchService = $repository->getSearchService(); |
||
1071 | |||
1072 | $query = new LocationQuery(); |
||
1073 | $query->performCount = false; |
||
1074 | $query->query = new Criterion\ContentTypeId( |
||
1075 | array(4) |
||
1076 | ); |
||
1077 | |||
1078 | $searchHit = $searchService->findLocations($query); |
||
1079 | |||
1080 | if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') { |
||
1081 | $this->assertEquals( |
||
1082 | null, |
||
1083 | $searchHit->totalCount |
||
1084 | ); |
||
1085 | } else { |
||
1086 | $this->assertEquals( |
||
1087 | 2, |
||
1088 | $searchHit->totalCount |
||
1089 | ); |
||
1090 | } |
||
1091 | } |
||
1092 | |||
1093 | /** |
||
1094 | * @expectedException \RuntimeException |
||
1095 | */ |
||
1096 | View Code Duplication | public function testFindLocationsNoPerformCountException() |
|
1097 | { |
||
1098 | if (ltrim(get_class($this->getSetupFactory()), '\\') !== 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') { |
||
1099 | $this->markTestSkipped('Only applicable to Legacy/DB based search'); |
||
1100 | } |
||
1101 | |||
1102 | $repository = $this->getRepository(); |
||
1103 | $searchService = $repository->getSearchService(); |
||
1104 | |||
1105 | $query = new LocationQuery(); |
||
1106 | $query->performCount = false; |
||
1107 | $query->limit = 0; |
||
1108 | $query->query = new Criterion\ContentTypeId( |
||
1109 | array(4) |
||
1110 | ); |
||
1111 | |||
1112 | $searchService->findLocations($query); |
||
1113 | } |
||
1114 | |||
1115 | /** |
||
1116 | * Create test Content with ezcountry field having multiple countries selected. |
||
1117 | * |
||
1118 | * @return Content |
||
1119 | */ |
||
1120 | protected function createMultipleCountriesContent() |
||
1121 | { |
||
1122 | $repository = $this->getRepository(); |
||
1123 | $contentTypeService = $repository->getContentTypeService(); |
||
1124 | $contentService = $repository->getContentService(); |
||
1125 | |||
1126 | $createStruct = $contentTypeService->newContentTypeCreateStruct('countries-multiple'); |
||
1127 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
1128 | $createStruct->remoteId = 'countries-multiple-123'; |
||
1129 | $createStruct->names = array('eng-GB' => 'Multiple countries'); |
||
1130 | $createStruct->creatorId = 14; |
||
1131 | $createStruct->creationDate = new \DateTime(); |
||
1132 | |||
1133 | $fieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('countries', 'ezcountry'); |
||
1134 | $fieldCreate->names = array('eng-GB' => 'Countries'); |
||
1135 | $fieldCreate->fieldGroup = 'main'; |
||
1136 | $fieldCreate->position = 1; |
||
1137 | $fieldCreate->isTranslatable = false; |
||
1138 | $fieldCreate->isSearchable = true; |
||
1139 | $fieldCreate->fieldSettings = array('isMultiple' => true); |
||
1140 | |||
1141 | $createStruct->addFieldDefinition($fieldCreate); |
||
1142 | |||
1143 | $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content'); |
||
1144 | $contentTypeDraft = $contentTypeService->createContentType($createStruct, array($contentGroup)); |
||
1145 | $contentTypeService->publishContentTypeDraft($contentTypeDraft); |
||
1146 | $contentType = $contentTypeService->loadContentType($contentTypeDraft->id); |
||
1147 | |||
1148 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
1149 | $createStruct->remoteId = 'countries-multiple-456'; |
||
1150 | $createStruct->alwaysAvailable = false; |
||
1151 | $createStruct->setField( |
||
1152 | 'countries', |
||
1153 | array('BE', 'DE', 'FR', 'HR', 'NO', 'PT', 'RU') |
||
1154 | ); |
||
1155 | |||
1156 | $draft = $contentService->createContent($createStruct); |
||
1157 | $content = $contentService->publishVersion($draft->getVersionInfo()); |
||
1158 | |||
1159 | $this->refreshSearch($repository); |
||
1160 | |||
1161 | return $content; |
||
1162 | } |
||
1163 | |||
1164 | /** |
||
1165 | * Test for the findContent() method. |
||
1166 | * |
||
1167 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
1168 | */ |
||
1169 | View Code Duplication | public function testFieldCollectionContains() |
|
1170 | { |
||
1171 | $testContent = $this->createMultipleCountriesContent(); |
||
1172 | |||
1173 | $query = new Query( |
||
1174 | array( |
||
1175 | 'query' => new Criterion\Field( |
||
1176 | 'countries', |
||
1177 | Criterion\Operator::CONTAINS, |
||
1178 | 'Belgium' |
||
1179 | ), |
||
1180 | ) |
||
1181 | ); |
||
1182 | |||
1183 | $repository = $this->getRepository(); |
||
1184 | $searchService = $repository->getSearchService(); |
||
1185 | $result = $searchService->findContent($query); |
||
1186 | |||
1187 | $this->assertEquals(1, $result->totalCount); |
||
1188 | $this->assertEquals( |
||
1189 | $testContent->id, |
||
1190 | $result->searchHits[0]->valueObject->id |
||
1191 | ); |
||
1192 | } |
||
1193 | |||
1194 | /** |
||
1195 | * Test for the findContent() method. |
||
1196 | * |
||
1197 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
1198 | * @depends eZ\Publish\API\Repository\Tests\SearchServiceTest::testFieldCollectionContains |
||
1199 | */ |
||
1200 | View Code Duplication | public function testFieldCollectionContainsNoMatch() |
|
1201 | { |
||
1202 | $this->createMultipleCountriesContent(); |
||
1203 | $query = new Query( |
||
1204 | array( |
||
1205 | 'query' => new Criterion\Field( |
||
1206 | 'countries', |
||
1207 | Criterion\Operator::CONTAINS, |
||
1208 | 'Netherlands Antilles' |
||
1209 | ), |
||
1210 | ) |
||
1211 | ); |
||
1212 | |||
1213 | $repository = $this->getRepository(); |
||
1214 | $searchService = $repository->getSearchService(); |
||
1215 | $result = $searchService->findContent($query); |
||
1216 | |||
1217 | $this->assertEquals(0, $result->totalCount); |
||
1218 | } |
||
1219 | |||
1220 | /** |
||
1221 | * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
||
1222 | * @expectedExceptionMessage Argument '$criterion->target' is invalid: No searchable fields found for the given criterion target 'some_hopefully_unknown_field' |
||
1223 | */ |
||
1224 | View Code Duplication | public function testInvalidFieldIdentifierRange() |
|
1225 | { |
||
1226 | $repository = $this->getRepository(); |
||
1227 | $searchService = $repository->getSearchService(); |
||
1228 | |||
1229 | $searchService->findContent( |
||
1230 | new Query( |
||
1231 | array( |
||
1232 | 'filter' => new Criterion\Field( |
||
1233 | 'some_hopefully_unknown_field', |
||
1234 | Criterion\Operator::BETWEEN, |
||
1235 | array(10, 1000) |
||
1236 | ), |
||
1237 | 'sortClauses' => array(new SortClause\ContentId()), |
||
1238 | ) |
||
1239 | ) |
||
1240 | ); |
||
1241 | } |
||
1242 | |||
1243 | /** |
||
1244 | * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
||
1245 | * @expectedExceptionMessage Argument '$criterion->target' is invalid: No searchable fields found for the given criterion target 'some_hopefully_unknown_field' |
||
1246 | */ |
||
1247 | View Code Duplication | public function testInvalidFieldIdentifierIn() |
|
1248 | { |
||
1249 | $repository = $this->getRepository(); |
||
1250 | $searchService = $repository->getSearchService(); |
||
1251 | |||
1252 | $searchService->findContent( |
||
1253 | new Query( |
||
1254 | array( |
||
1255 | 'filter' => new Criterion\Field( |
||
1256 | 'some_hopefully_unknown_field', |
||
1257 | Criterion\Operator::EQ, |
||
1258 | 1000 |
||
1259 | ), |
||
1260 | 'sortClauses' => array(new SortClause\ContentId()), |
||
1261 | ) |
||
1262 | ) |
||
1263 | ); |
||
1264 | } |
||
1265 | |||
1266 | /** |
||
1267 | * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
||
1268 | * @expectedExceptionMessage Argument '$criterion->target' is invalid: No searchable fields found for the given criterion target 'tag_cloud_url' |
||
1269 | */ |
||
1270 | View Code Duplication | public function testFindContentWithNonSearchableField() |
|
1271 | { |
||
1272 | $repository = $this->getRepository(); |
||
1273 | $searchService = $repository->getSearchService(); |
||
1274 | |||
1275 | $searchService->findContent( |
||
1276 | new Query( |
||
1277 | array( |
||
1278 | 'filter' => new Criterion\Field( |
||
1279 | 'tag_cloud_url', |
||
1280 | Criterion\Operator::EQ, |
||
1281 | 'http://nimbus.com' |
||
1282 | ), |
||
1283 | 'sortClauses' => array(new SortClause\ContentId()), |
||
1284 | ) |
||
1285 | ) |
||
1286 | ); |
||
1287 | } |
||
1288 | |||
1289 | /** |
||
1290 | * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
||
1291 | * @expectedExceptionMessage Argument '$sortClause->targetData' is invalid: No searchable fields found for the given sort clause target 'title' on 'template_look' |
||
1292 | */ |
||
1293 | View Code Duplication | public function testSortFieldWithNonSearchableField() |
|
1294 | { |
||
1295 | $repository = $this->getRepository(); |
||
1296 | $searchService = $repository->getSearchService(); |
||
1297 | |||
1298 | $searchService->findContent( |
||
1299 | new Query( |
||
1300 | array( |
||
1301 | 'sortClauses' => array(new SortClause\Field('template_look', 'title')), |
||
1302 | ) |
||
1303 | ) |
||
1304 | ); |
||
1305 | } |
||
1306 | |||
1307 | /** |
||
1308 | * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
||
1309 | * @expectedExceptionMessage Argument '$sortClause->targetData' is invalid: No searchable fields found for the given sort clause target 'title' on 'template_look' |
||
1310 | */ |
||
1311 | View Code Duplication | public function testSortMapLocationDistanceWithNonSearchableField() |
|
1312 | { |
||
1313 | $repository = $this->getRepository(); |
||
1314 | $searchService = $repository->getSearchService(); |
||
1315 | |||
1316 | $searchService->findContent( |
||
1317 | new Query( |
||
1318 | array( |
||
1319 | 'sortClauses' => array( |
||
1320 | new SortClause\MapLocationDistance( |
||
1321 | 'template_look', |
||
1322 | 'title', |
||
1323 | 1, |
||
1324 | 2 |
||
1325 | ), |
||
1326 | ), |
||
1327 | ) |
||
1328 | ) |
||
1329 | ); |
||
1330 | } |
||
1331 | |||
1332 | /** |
||
1333 | * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
||
1334 | */ |
||
1335 | View Code Duplication | public function testFindSingleFailMultiple() |
|
1336 | { |
||
1337 | $repository = $this->getRepository(); |
||
1338 | $searchService = $repository->getSearchService(); |
||
1339 | |||
1340 | $searchService->findSingle( |
||
1341 | new Criterion\ContentId( |
||
1342 | array(4, 10) |
||
1343 | ) |
||
1344 | ); |
||
1345 | } |
||
1346 | |||
1347 | /** |
||
1348 | * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException |
||
1349 | */ |
||
1350 | public function testFindSingleWithNonSearchableField() |
||
1351 | { |
||
1352 | $repository = $this->getRepository(); |
||
1353 | $searchService = $repository->getSearchService(); |
||
1354 | |||
1355 | $searchService->findSingle( |
||
1356 | new Criterion\Field( |
||
1357 | 'tag_cloud_url', |
||
1358 | Criterion\Operator::EQ, |
||
1359 | 'http://nimbus.com' |
||
1360 | ) |
||
1361 | ); |
||
1362 | } |
||
1363 | |||
1364 | public function getSortedContentSearches() |
||
1365 | { |
||
1366 | $fixtureDir = $this->getFixtureDir(); |
||
1367 | |||
1368 | return array( |
||
1369 | 0 => array( |
||
1370 | array( |
||
1371 | 'filter' => new Criterion\SectionId(array(2)), |
||
1372 | 'offset' => 0, |
||
1373 | 'limit' => 10, |
||
1374 | 'sortClauses' => array(), |
||
1375 | ), |
||
1376 | $fixtureDir . 'SortNone.php', |
||
1377 | // Result having the same sort level should be sorted between them to be system independent |
||
1378 | function (&$data) { |
||
1379 | usort( |
||
1380 | $data->searchHits, |
||
1381 | function ($a, $b) { |
||
1382 | return ($a->valueObject['id'] < $b->valueObject['id']) ? -1 : 1; |
||
1383 | } |
||
1384 | ); |
||
1385 | }, |
||
1386 | ), |
||
1387 | 1 => array( |
||
1388 | array( |
||
1389 | 'filter' => new Criterion\SectionId(array(2)), |
||
1390 | 'offset' => 0, |
||
1391 | 'limit' => 10, |
||
1392 | 'sortClauses' => array( |
||
1393 | new SortClause\DatePublished(), |
||
1394 | new SortClause\ContentId(), |
||
1395 | ), |
||
1396 | ), |
||
1397 | $fixtureDir . 'SortDatePublished.php', |
||
1398 | ), |
||
1399 | 2 => array( |
||
1400 | array( |
||
1401 | 'filter' => new Criterion\SectionId(array(2)), |
||
1402 | 'offset' => 0, |
||
1403 | 'limit' => 50, |
||
1404 | 'sortClauses' => array( |
||
1405 | new SortClause\DateModified(), |
||
1406 | new SortClause\ContentId(), |
||
1407 | ), |
||
1408 | ), |
||
1409 | $fixtureDir . 'SortDateModified.php', |
||
1410 | ), |
||
1411 | 3 => array( |
||
1412 | array( |
||
1413 | 'filter' => new Criterion\SectionId(array(4, 2, 6, 3)), |
||
1414 | 'offset' => 0, |
||
1415 | 'limit' => 50, |
||
1416 | 'sortClauses' => array( |
||
1417 | new SortClause\SectionIdentifier(), |
||
1418 | new SortClause\ContentId(), |
||
1419 | ), |
||
1420 | ), |
||
1421 | $fixtureDir . 'SortSectionIdentifier.php', |
||
1422 | ), |
||
1423 | 4 => array( |
||
1424 | array( |
||
1425 | 'filter' => new Criterion\SectionId(array(4, 2, 6, 3)), |
||
1426 | 'offset' => 0, |
||
1427 | 'limit' => 50, |
||
1428 | 'sortClauses' => array( |
||
1429 | new SortClause\SectionName(), |
||
1430 | new SortClause\ContentId(), |
||
1431 | ), |
||
1432 | ), |
||
1433 | $fixtureDir . 'SortSectionName.php', |
||
1434 | ), |
||
1435 | 5 => array( |
||
1436 | array( |
||
1437 | 'filter' => new Criterion\SectionId(array(2, 3)), |
||
1438 | 'offset' => 0, |
||
1439 | 'limit' => 50, |
||
1440 | 'sortClauses' => array( |
||
1441 | new SortClause\ContentName(), |
||
1442 | new SortClause\ContentId(), |
||
1443 | ), |
||
1444 | ), |
||
1445 | $fixtureDir . 'SortContentName.php', |
||
1446 | ), |
||
1447 | 6 => array( |
||
1448 | array( |
||
1449 | 'filter' => new Criterion\ContentTypeId(1), |
||
1450 | 'offset' => 0, |
||
1451 | 'limit' => 50, |
||
1452 | 'sortClauses' => array( |
||
1453 | new SortClause\Field('folder', 'name', Query::SORT_ASC), |
||
1454 | new SortClause\ContentId(), |
||
1455 | ), |
||
1456 | ), |
||
1457 | $fixtureDir . 'SortFolderName.php', |
||
1458 | ), |
||
1459 | 7 => array( |
||
1460 | array( |
||
1461 | 'filter' => new Criterion\ContentTypeId(array(1, 3)), |
||
1462 | 'offset' => 0, |
||
1463 | 'limit' => 50, |
||
1464 | 'sortClauses' => array( |
||
1465 | new SortClause\Field('folder', 'name', Query::SORT_ASC), |
||
1466 | new SortClause\ContentId(), |
||
1467 | ), |
||
1468 | ), |
||
1469 | $fixtureDir . 'SortFieldMultipleTypes.php', |
||
1470 | ), |
||
1471 | 8 => array( |
||
1472 | array( |
||
1473 | 'filter' => new Criterion\ContentTypeId(array(1, 3)), |
||
1474 | 'offset' => 0, |
||
1475 | 'limit' => 50, |
||
1476 | 'sortClauses' => array( |
||
1477 | new SortClause\Field('folder', 'name', Query::SORT_DESC), |
||
1478 | new SortClause\ContentId(), |
||
1479 | ), |
||
1480 | ), |
||
1481 | $fixtureDir . 'SortFieldMultipleTypesReverse.php', |
||
1482 | ), |
||
1483 | 9 => array( |
||
1484 | array( |
||
1485 | 'filter' => new Criterion\ContentTypeId(array(1, 3)), |
||
1486 | 'offset' => 3, |
||
1487 | 'limit' => 5, |
||
1488 | 'sortClauses' => array( |
||
1489 | new SortClause\Field('folder', 'name', Query::SORT_ASC), |
||
1490 | new SortClause\Field('user', 'first_name', Query::SORT_ASC), |
||
1491 | new SortClause\ContentId(), |
||
1492 | ), |
||
1493 | ), |
||
1494 | $fixtureDir . 'SortFieldMultipleTypesSlice.php', |
||
1495 | ), |
||
1496 | 10 => array( |
||
1497 | array( |
||
1498 | 'filter' => new Criterion\ContentTypeId(array(1, 3)), |
||
1499 | 'offset' => 3, |
||
1500 | 'limit' => 5, |
||
1501 | 'sortClauses' => array( |
||
1502 | new SortClause\Field('folder', 'name', Query::SORT_DESC), |
||
1503 | new SortClause\Field('user', 'first_name', Query::SORT_ASC), |
||
1504 | new SortClause\ContentId(), |
||
1505 | ), |
||
1506 | ), |
||
1507 | $fixtureDir . 'SortFieldMultipleTypesSliceReverse.php', |
||
1508 | ), |
||
1509 | ); |
||
1510 | } |
||
1511 | |||
1512 | public function getSortedLocationSearches() |
||
1513 | { |
||
1514 | $fixtureDir = $this->getFixtureDir(); |
||
1515 | |||
1516 | return array( |
||
1517 | array( |
||
1518 | array( |
||
1519 | 'filter' => new Criterion\SectionId(array(2)), |
||
1520 | 'offset' => 0, |
||
1521 | 'limit' => 10, |
||
1522 | 'sortClauses' => array(new SortClause\Location\Path(Query::SORT_DESC)), |
||
1523 | ), |
||
1524 | $fixtureDir . 'SortPathString.php', |
||
1525 | ), |
||
1526 | array( |
||
1527 | array( |
||
1528 | 'filter' => new Criterion\SectionId(array(2)), |
||
1529 | 'offset' => 0, |
||
1530 | 'limit' => 10, |
||
1531 | 'sortClauses' => array(new SortClause\Location\Depth(Query::SORT_ASC)), |
||
1532 | ), |
||
1533 | $fixtureDir . 'SortLocationDepth.php', |
||
1534 | // Result having the same sort level should be sorted between them to be system independent |
||
1535 | function (&$data) { |
||
1536 | // Result with ids: |
||
1537 | // 4 has depth = 1 |
||
1538 | // 11, 12, 13, 42, 59 have depth = 2 |
||
1539 | // 10, 14 have depth = 3 |
||
1540 | $map = array( |
||
1541 | 4 => 0, |
||
1542 | 11 => 1, |
||
1543 | 12 => 2, |
||
1544 | 13 => 3, |
||
1545 | 42 => 4, |
||
1546 | 59 => 5, |
||
1547 | 10 => 6, |
||
1548 | 14 => 7, |
||
1549 | ); |
||
1550 | usort( |
||
1551 | $data->searchHits, |
||
1552 | function ($a, $b) use ($map) { |
||
1553 | return ($map[$a->valueObject['id']] < $map[$b->valueObject['id']]) ? -1 : 1; |
||
1554 | } |
||
1555 | ); |
||
1556 | }, |
||
1557 | ), |
||
1558 | array( |
||
1559 | array( |
||
1560 | 'filter' => new Criterion\SectionId(array(3)), |
||
1561 | 'offset' => 0, |
||
1562 | 'limit' => 10, |
||
1563 | 'sortClauses' => array( |
||
1564 | new SortClause\Location\Path(Query::SORT_DESC), |
||
1565 | new SortClause\ContentName(Query::SORT_ASC), |
||
1566 | ), |
||
1567 | ), |
||
1568 | $fixtureDir . 'SortMultiple.php', |
||
1569 | ), |
||
1570 | array( |
||
1571 | array( |
||
1572 | 'filter' => new Criterion\SectionId(array(2)), |
||
1573 | 'offset' => 0, |
||
1574 | 'limit' => 10, |
||
1575 | 'sortClauses' => array( |
||
1576 | new SortClause\Location\Priority(Query::SORT_DESC), |
||
1577 | new SortClause\ContentId(), |
||
1578 | ), |
||
1579 | ), |
||
1580 | $fixtureDir . 'SortDesc.php', |
||
1581 | ), |
||
1582 | ); |
||
1583 | } |
||
1584 | |||
1585 | /** |
||
1586 | * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType |
||
1587 | */ |
||
1588 | View Code Duplication | protected function createTestContentType() |
|
1589 | { |
||
1590 | $repository = $this->getRepository(); |
||
1591 | $contentTypeService = $repository->getContentTypeService(); |
||
1592 | |||
1593 | $createStruct = $contentTypeService->newContentTypeCreateStruct('test-type'); |
||
1594 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
1595 | $createStruct->names = array('eng-GB' => 'Test type'); |
||
1596 | $createStruct->creatorId = 14; |
||
1597 | $createStruct->creationDate = new \DateTime(); |
||
1598 | |||
1599 | $translatableFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('integer', 'ezinteger'); |
||
1600 | $translatableFieldCreate->names = array('eng-GB' => 'Simple translatable integer field'); |
||
1601 | $translatableFieldCreate->fieldGroup = 'main'; |
||
1602 | $translatableFieldCreate->position = 1; |
||
1603 | $translatableFieldCreate->isTranslatable = true; |
||
1604 | $translatableFieldCreate->isSearchable = true; |
||
1605 | |||
1606 | $createStruct->addFieldDefinition($translatableFieldCreate); |
||
1607 | |||
1608 | $nonTranslatableFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('integer2', 'ezinteger'); |
||
1609 | $nonTranslatableFieldCreate->names = array('eng-GB' => 'Simple non-translatable integer field'); |
||
1610 | $nonTranslatableFieldCreate->fieldGroup = 'main'; |
||
1611 | $nonTranslatableFieldCreate->position = 2; |
||
1612 | $nonTranslatableFieldCreate->isTranslatable = false; |
||
1613 | $nonTranslatableFieldCreate->isSearchable = true; |
||
1614 | |||
1615 | $createStruct->addFieldDefinition($nonTranslatableFieldCreate); |
||
1616 | |||
1617 | $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content'); |
||
1618 | $contentTypeDraft = $contentTypeService->createContentType($createStruct, array($contentGroup)); |
||
1619 | $contentTypeService->publishContentTypeDraft($contentTypeDraft); |
||
1620 | $contentType = $contentTypeService->loadContentType($contentTypeDraft->id); |
||
1621 | |||
1622 | return $contentType; |
||
1623 | } |
||
1624 | |||
1625 | /** |
||
1626 | * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType |
||
1627 | * @param int $fieldValue11 Value for translatable field in first language |
||
1628 | * @param int $fieldValue12 Value for translatable field in second language |
||
1629 | * @param int $fieldValue2 Value for non translatable field |
||
1630 | * @param string $mainLanguageCode |
||
1631 | * @param bool $alwaysAvailable |
||
1632 | * |
||
1633 | * @return Content |
||
1634 | */ |
||
1635 | protected function createMultilingualContent( |
||
1636 | $contentType, |
||
1637 | $fieldValue11 = null, |
||
1638 | $fieldValue12 = null, |
||
1639 | $fieldValue2 = null, |
||
1640 | $mainLanguageCode = 'eng-GB', |
||
1641 | $alwaysAvailable = false |
||
1642 | ) { |
||
1643 | $repository = $this->getRepository(); |
||
1644 | $contentService = $repository->getContentService(); |
||
1645 | |||
1646 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
1647 | $createStruct->alwaysAvailable = $alwaysAvailable; |
||
1648 | $createStruct->mainLanguageCode = $mainLanguageCode; |
||
1649 | if ($fieldValue11) { |
||
1650 | $createStruct->setField('integer', $fieldValue11, 'eng-GB'); |
||
1651 | } |
||
1652 | if ($fieldValue12) { |
||
1653 | $createStruct->setField('integer', $fieldValue12, 'ger-DE'); |
||
1654 | } |
||
1655 | $createStruct->setField('integer2', $fieldValue2, $mainLanguageCode); |
||
1656 | |||
1657 | $locationCreateStruct = $repository->getLocationService()->newLocationCreateStruct(2); |
||
1658 | $draft = $contentService->createContent($createStruct, array($locationCreateStruct)); |
||
1659 | $content = $contentService->publishVersion($draft->getVersionInfo()); |
||
1660 | |||
1661 | $this->refreshSearch($repository); |
||
1662 | |||
1663 | return $content; |
||
1664 | } |
||
1665 | |||
1666 | protected function checkPrioritizedLanguagesSupport() |
||
1667 | { |
||
1668 | $setupFactory = $this->getSetupFactory(); |
||
1669 | if ($setupFactory instanceof LegacyElasticsearch) { |
||
1670 | $this->markTestIncomplete('Prioritized languages are not supported with Elasticsearch engine'); |
||
1671 | } |
||
1672 | } |
||
1673 | |||
1674 | public function providerForTestMultilingualFieldSort() |
||
1675 | { |
||
1676 | return array( |
||
1677 | 0 => array( |
||
1678 | array( |
||
1679 | 1 => array(1, 2, 1), |
||
1680 | 2 => array(2, 1, 2), |
||
1681 | 3 => array(2, 1, 3), |
||
1682 | 4 => array(1, 2, 4), |
||
1683 | ), |
||
1684 | array( |
||
1685 | 'languages' => array( |
||
1686 | 'eng-GB', |
||
1687 | 'ger-DE', |
||
1688 | ), |
||
1689 | ), |
||
1690 | array( |
||
1691 | new SortClause\Field('test-type', 'integer', Query::SORT_ASC), |
||
1692 | new SortClause\Field('test-type', 'integer2', Query::SORT_DESC), |
||
1693 | ), |
||
1694 | /** |
||
1695 | * Expected order, Value eng-GB, Value ger-DE. |
||
1696 | * |
||
1697 | * Content 4, 1, 2, 4 |
||
1698 | * Content 1, 1, 2, 1 |
||
1699 | * Content 3, 2, 1, 3 |
||
1700 | * Content 2, 2, 1, 2 |
||
1701 | */ |
||
1702 | array(4, 1, 3, 2), |
||
1703 | ), |
||
1704 | 1 => array( |
||
1705 | array( |
||
1706 | 1 => array(1, 2, 1), |
||
1707 | 2 => array(2, 1, 2), |
||
1708 | 3 => array(2, 1, 3), |
||
1709 | 4 => array(1, 2, 4), |
||
1710 | ), |
||
1711 | array( |
||
1712 | 'languages' => array( |
||
1713 | 'ger-DE', |
||
1714 | 'eng-GB', |
||
1715 | ), |
||
1716 | ), |
||
1717 | array( |
||
1718 | new SortClause\Field('test-type', 'integer', Query::SORT_ASC), |
||
1719 | new SortClause\Field('test-type', 'integer2', Query::SORT_DESC), |
||
1720 | ), |
||
1721 | /** |
||
1722 | * Expected order, Value eng-GB, Value ger-DE. |
||
1723 | * |
||
1724 | * Content 3, 2, 1, 3 |
||
1725 | * Content 2, 2, 1, 2 |
||
1726 | * Content 4, 1, 2, 4 |
||
1727 | * Content 1, 1, 2, 1 |
||
1728 | */ |
||
1729 | array(3, 2, 4, 1), |
||
1730 | ), |
||
1731 | 2 => array( |
||
1732 | array( |
||
1733 | 1 => array(null, 2, null, 'ger-DE'), |
||
1734 | 2 => array(3, null, null, 'eng-GB'), |
||
1735 | 3 => array(4, null, null, 'eng-GB'), |
||
1736 | 4 => array(null, 1, null, 'ger-DE'), |
||
1737 | ), |
||
1738 | array( |
||
1739 | 'languages' => array( |
||
1740 | 'eng-GB', |
||
1741 | ), |
||
1742 | ), |
||
1743 | array( |
||
1744 | new SortClause\Field('test-type', 'integer', Query::SORT_DESC), |
||
1745 | ), |
||
1746 | /** |
||
1747 | * Expected order, Value eng-GB, Value ger-DE. |
||
1748 | * |
||
1749 | * Content 3, 4, - |
||
1750 | * Content 2, 3, - |
||
1751 | */ |
||
1752 | array(3, 2), |
||
1753 | ), |
||
1754 | 3 => array( |
||
1755 | array( |
||
1756 | 1 => array(null, 2, null, 'ger-DE'), |
||
1757 | 2 => array(3, null, null, 'eng-GB'), |
||
1758 | 3 => array(4, null, null, 'eng-GB'), |
||
1759 | 4 => array(null, 1, null, 'ger-DE'), |
||
1760 | ), |
||
1761 | array( |
||
1762 | 'languages' => array( |
||
1763 | 'ger-DE', |
||
1764 | ), |
||
1765 | ), |
||
1766 | array( |
||
1767 | new SortClause\Field('test-type', 'integer', Query::SORT_DESC), |
||
1768 | ), |
||
1769 | /** |
||
1770 | * Expected order, Value eng-GB, Value ger-DE. |
||
1771 | * |
||
1772 | * Content 1, -, 2 |
||
1773 | * Content 4, -, 1 |
||
1774 | */ |
||
1775 | array(1, 4), |
||
1776 | ), |
||
1777 | 4 => array( |
||
1778 | array( |
||
1779 | 1 => array(null, 2, null, 'ger-DE'), |
||
1780 | 2 => array(3, null, null, 'eng-GB'), |
||
1781 | 3 => array(4, null, null, 'eng-GB'), |
||
1782 | 4 => array(null, 1, null, 'ger-DE'), |
||
1783 | ), |
||
1784 | array( |
||
1785 | 'languages' => array( |
||
1786 | 'eng-GB', |
||
1787 | 'ger-DE', |
||
1788 | ), |
||
1789 | ), |
||
1790 | array( |
||
1791 | new SortClause\Field('test-type', 'integer', Query::SORT_DESC), |
||
1792 | ), |
||
1793 | /** |
||
1794 | * Expected order, Value eng-GB, Value ger-DE. |
||
1795 | * |
||
1796 | * Content 3, 4, - |
||
1797 | * Content 2, 3, - |
||
1798 | * Content 1, -, 2 |
||
1799 | * Content 4, -, 1 |
||
1800 | */ |
||
1801 | array(3, 2, 1, 4), |
||
1802 | ), |
||
1803 | 5 => array( |
||
1804 | array( |
||
1805 | 1 => array(null, 2, null, 'ger-DE'), |
||
1806 | 2 => array(3, null, null, 'eng-GB'), |
||
1807 | 3 => array(4, null, null, 'eng-GB'), |
||
1808 | 4 => array(null, 1, null, 'ger-DE'), |
||
1809 | ), |
||
1810 | array( |
||
1811 | 'languages' => array( |
||
1812 | 'ger-DE', |
||
1813 | 'eng-GB', |
||
1814 | ), |
||
1815 | ), |
||
1816 | array( |
||
1817 | new SortClause\Field('test-type', 'integer', Query::SORT_DESC), |
||
1818 | ), |
||
1819 | /** |
||
1820 | * Expected order, Value eng-GB, Value ger-DE. |
||
1821 | * |
||
1822 | * Content 3, 4, - |
||
1823 | * Content 2, 3, - |
||
1824 | * Content 1, -, 2 |
||
1825 | * Content 4, -, 1 |
||
1826 | */ |
||
1827 | array(3, 2, 1, 4), |
||
1828 | ), |
||
1829 | 6 => array( |
||
1830 | array( |
||
1831 | 1 => array(null, 2, null, 'ger-DE'), |
||
1832 | 2 => array(3, 4, null, 'eng-GB'), |
||
1833 | 3 => array(4, 3, null, 'eng-GB'), |
||
1834 | 4 => array(null, 1, null, 'ger-DE'), |
||
1835 | ), |
||
1836 | array( |
||
1837 | 'languages' => array( |
||
1838 | 'eng-GB', |
||
1839 | 'ger-DE', |
||
1840 | ), |
||
1841 | ), |
||
1842 | array( |
||
1843 | new SortClause\Field('test-type', 'integer', Query::SORT_DESC), |
||
1844 | ), |
||
1845 | /** |
||
1846 | * Expected order, Value eng-GB, Value ger-DE. |
||
1847 | * |
||
1848 | * Content 3, 4, 3 |
||
1849 | * Content 2, 3, 4 |
||
1850 | * Content 1, -, 2 |
||
1851 | * Content 4, -, 1 |
||
1852 | */ |
||
1853 | array(3, 2, 1, 4), |
||
1854 | ), |
||
1855 | 7 => array( |
||
1856 | array( |
||
1857 | 1 => array(null, 2, null, 'ger-DE'), |
||
1858 | 2 => array(3, 4, null, 'eng-GB'), |
||
1859 | 3 => array(4, 3, null, 'eng-GB'), |
||
1860 | 4 => array(null, 1, null, 'ger-DE'), |
||
1861 | ), |
||
1862 | array( |
||
1863 | 'languages' => array( |
||
1864 | 'ger-DE', |
||
1865 | 'eng-GB', |
||
1866 | ), |
||
1867 | ), |
||
1868 | array( |
||
1869 | new SortClause\Field('test-type', 'integer', Query::SORT_DESC), |
||
1870 | ), |
||
1871 | /** |
||
1872 | * Expected order, Value eng-GB, Value ger-DE. |
||
1873 | * |
||
1874 | * Content 2, 3, 4 |
||
1875 | * Content 3, 4, 3 |
||
1876 | * Content 1, -, 2 |
||
1877 | * Content 4, -, 1 |
||
1878 | */ |
||
1879 | array(2, 3, 1, 4), |
||
1880 | ), |
||
1881 | 8 => array( |
||
1882 | array( |
||
1883 | 1 => array(null, 1, null, 'ger-DE', true), |
||
1884 | 2 => array(4, null, null, 'eng-GB', true), |
||
1885 | 3 => array(3, null, null, 'eng-GB', false), |
||
1886 | 4 => array(null, 2, null, 'ger-DE', false), |
||
1887 | ), |
||
1888 | array( |
||
1889 | 'languages' => array( |
||
1890 | 'eng-GB', |
||
1891 | ), |
||
1892 | ), |
||
1893 | array( |
||
1894 | new SortClause\Field('test-type', 'integer', Query::SORT_ASC), |
||
1895 | ), |
||
1896 | /** |
||
1897 | * Expected order, Value eng-GB, Value ger-DE. |
||
1898 | * |
||
1899 | * Content 1, -, 1 |
||
1900 | * Content 3, 3, - |
||
1901 | * Content 2, 4, - |
||
1902 | */ |
||
1903 | array(1, 3, 2), |
||
1904 | ), |
||
1905 | 9 => array( |
||
1906 | array( |
||
1907 | 1 => array(null, 1, null, 'ger-DE', true), |
||
1908 | 2 => array(4, null, null, 'eng-GB', true), |
||
1909 | 3 => array(3, null, null, 'eng-GB', false), |
||
1910 | 4 => array(null, 2, null, 'ger-DE', false), |
||
1911 | ), |
||
1912 | array( |
||
1913 | 'languages' => array( |
||
1914 | 'ger-DE', |
||
1915 | ), |
||
1916 | ), |
||
1917 | array( |
||
1918 | new SortClause\Field('test-type', 'integer', Query::SORT_DESC), |
||
1919 | ), |
||
1920 | /** |
||
1921 | * Expected order, Value eng-GB, Value ger-DE. |
||
1922 | * |
||
1923 | * Content 2, 4, - |
||
1924 | * Content 4, -, 2 |
||
1925 | * Content 1, -, 1 |
||
1926 | */ |
||
1927 | array(2, 4, 1), |
||
1928 | ), |
||
1929 | 10 => array( |
||
1930 | array( |
||
1931 | 1 => array(null, 1, null, 'ger-DE', true), |
||
1932 | 2 => array(4, null, null, 'eng-GB', true), |
||
1933 | 3 => array(3, null, null, 'eng-GB', false), |
||
1934 | 4 => array(null, 2, null, 'ger-DE', false), |
||
1935 | ), |
||
1936 | array( |
||
1937 | 'languages' => array( |
||
1938 | 'eng-GB', |
||
1939 | ), |
||
1940 | 'useAlwaysAvailable' => false, |
||
1941 | ), |
||
1942 | array( |
||
1943 | new SortClause\Field('test-type', 'integer', Query::SORT_ASC), |
||
1944 | ), |
||
1945 | /** |
||
1946 | * Expected order, Value eng-GB, Value ger-DE. |
||
1947 | * |
||
1948 | * Content 3, 3, - |
||
1949 | * Content 2, 4, - |
||
1950 | */ |
||
1951 | array(3, 2), |
||
1952 | ), |
||
1953 | 11 => array( |
||
1954 | array( |
||
1955 | 1 => array(null, 1, null, 'ger-DE', true), |
||
1956 | 2 => array(4, null, null, 'eng-GB', true), |
||
1957 | 3 => array(3, null, null, 'eng-GB', false), |
||
1958 | 4 => array(null, 2, null, 'ger-DE', false), |
||
1959 | ), |
||
1960 | array( |
||
1961 | 'languages' => array( |
||
1962 | 'ger-DE', |
||
1963 | ), |
||
1964 | 'useAlwaysAvailable' => false, |
||
1965 | ), |
||
1966 | array( |
||
1967 | new SortClause\Field('test-type', 'integer', Query::SORT_DESC), |
||
1968 | ), |
||
1969 | /** |
||
1970 | * Expected order, Value eng-GB, Value ger-DE. |
||
1971 | * |
||
1972 | * Content 4, -, 2 |
||
1973 | * Content 1, -, 1 |
||
1974 | */ |
||
1975 | array(4, 1), |
||
1976 | ), |
||
1977 | ); |
||
1978 | } |
||
1979 | |||
1980 | /** |
||
1981 | * Test for the findContent() method. |
||
1982 | * |
||
1983 | * @group rrr |
||
1984 | * @dataProvider providerForTestMultilingualFieldSort |
||
1985 | * |
||
1986 | * @param array $contentDataList |
||
1987 | * @param array $languageSettings |
||
1988 | * @param \eZ\Publish\API\Repository\Values\Content\Query\SortClause[] $sortClauses |
||
1989 | * @param array $expected |
||
1990 | */ |
||
1991 | public function testMultilingualFieldSortContent( |
||
1992 | array $contentDataList, |
||
1993 | $languageSettings, |
||
1994 | array $sortClauses, |
||
1995 | $expected |
||
1996 | ) { |
||
1997 | $this->assertMultilingualFieldSort( |
||
1998 | $contentDataList, |
||
1999 | $languageSettings, |
||
2000 | $sortClauses, |
||
2001 | $expected |
||
2002 | ); |
||
2003 | } |
||
2004 | |||
2005 | /** |
||
2006 | * Test for the findLocations() method. |
||
2007 | * |
||
2008 | * @group rrr |
||
2009 | * @dataProvider providerForTestMultilingualFieldSort |
||
2010 | * |
||
2011 | * @param array $contentDataList |
||
2012 | * @param array $languageSettings |
||
2013 | * @param \eZ\Publish\API\Repository\Values\Content\Query\SortClause[] $sortClauses |
||
2014 | * @param array $expected |
||
2015 | */ |
||
2016 | public function testMultilingualFieldSortLocation( |
||
2017 | array $contentDataList, |
||
2018 | $languageSettings, |
||
2019 | array $sortClauses, |
||
2020 | $expected |
||
2021 | ) { |
||
2022 | $this->assertMultilingualFieldSort( |
||
2023 | $contentDataList, |
||
2024 | $languageSettings, |
||
2025 | $sortClauses, |
||
2026 | $expected, |
||
2027 | false |
||
2028 | ); |
||
2029 | } |
||
2030 | |||
2031 | /** |
||
2032 | * @param array $contentDataList |
||
2033 | * @param array $languageSettings |
||
2034 | * @param \eZ\Publish\API\Repository\Values\Content\Query\SortClause[] $sortClauses |
||
2035 | * @param array $expected |
||
2036 | * @param bool $contentSearch |
||
2037 | */ |
||
2038 | protected function assertMultilingualFieldSort( |
||
2039 | array $contentDataList, |
||
2040 | $languageSettings, |
||
2041 | array $sortClauses, |
||
2042 | $expected, |
||
2043 | $contentSearch = true |
||
2044 | ) { |
||
2045 | $this->checkPrioritizedLanguagesSupport(); |
||
2046 | $contentType = $this->createTestContentType(); |
||
2047 | |||
2048 | // Create a draft to account for behaviour with ContentType in different states |
||
2049 | $repository = $this->getRepository(); |
||
2050 | $contentTypeService = $repository->getContentTypeService(); |
||
2051 | $contentTypeService->createContentTypeDraft($contentType); |
||
2052 | |||
2053 | $defaults = array(null, null, null, 'eng-GB', false); |
||
2054 | $contentIdList = array(); |
||
2055 | View Code Duplication | foreach ($contentDataList as $key => $contentData) { |
|
2056 | $contentData = $contentData + $defaults; |
||
2057 | list( |
||
2058 | $fieldValue11, |
||
2059 | $fieldValue12, |
||
2060 | $fieldValue2, |
||
2061 | $mainLanguageCode, |
||
2062 | $alwaysAvailable |
||
2063 | ) = $contentData; |
||
2064 | |||
2065 | $contentIdList[$key] = $this->createMultilingualContent( |
||
2066 | $contentType, |
||
2067 | $fieldValue11, |
||
2068 | $fieldValue12, |
||
2069 | $fieldValue2, |
||
2070 | $mainLanguageCode, |
||
2071 | $alwaysAvailable |
||
2072 | )->id; |
||
2073 | } |
||
2074 | |||
2075 | // "article" type Content is not matched, this ensures that non-matched |
||
2076 | // field does not affect sort |
||
2077 | $dummySortClause = new SortClause\Field('article', 'title', Query::SORT_ASC); |
||
2078 | array_unshift($sortClauses, $dummySortClause); |
||
2079 | array_push($sortClauses, $dummySortClause); |
||
2080 | |||
2081 | $searchService = $repository->getSearchService(); |
||
2082 | if ($contentSearch) { |
||
2083 | $query = new Query( |
||
2084 | array( |
||
2085 | 'query' => new Criterion\ContentTypeId($contentType->id), |
||
2086 | 'sortClauses' => $sortClauses, |
||
2087 | ) |
||
2088 | ); |
||
2089 | $result = $searchService->findContent($query, $languageSettings); |
||
2090 | } else { |
||
2091 | $query = new LocationQuery( |
||
2092 | array( |
||
2093 | 'query' => new Criterion\ContentTypeId($contentType->id), |
||
2094 | 'sortClauses' => $sortClauses, |
||
2095 | ) |
||
2096 | ); |
||
2097 | $result = $searchService->findLocations($query, $languageSettings); |
||
2098 | } |
||
2099 | |||
2100 | $this->assertEquals(count($expected), $result->totalCount); |
||
2101 | |||
2102 | $expectedIdList = array(); |
||
2103 | foreach ($expected as $contentNumber) { |
||
2104 | $expectedIdList[] = $contentIdList[$contentNumber]; |
||
2105 | } |
||
2106 | |||
2107 | $this->assertEquals($expectedIdList, $this->mapResultContentIds($result)); |
||
2108 | } |
||
2109 | |||
2110 | public function providerForTestMultilingualFieldFilter() |
||
2111 | { |
||
2112 | return array( |
||
2113 | 0 => array( |
||
2114 | $fixture = array( |
||
2115 | 1 => array(null, 1, null, 'ger-DE', true), |
||
2116 | 2 => array(4, null, null, 'eng-GB', true), |
||
2117 | 3 => array(3, null, null, 'eng-GB', false), |
||
2118 | 4 => array(null, 2, null, 'ger-DE', false), |
||
2119 | 5 => array(5, null, null, 'eng-GB', true), |
||
2120 | ), |
||
2121 | $languageSettings = array( |
||
2122 | 'languages' => array( |
||
2123 | 'ger-DE', |
||
2124 | ), |
||
2125 | ), |
||
2126 | new Criterion\Field('integer', Criterion\Operator::LT, 5), |
||
2127 | /** |
||
2128 | * Expected order, Value eng-GB, Value ger-DE. |
||
2129 | * |
||
2130 | * Content 2, 4, - |
||
2131 | * Content 4, -, 2 |
||
2132 | * Content 1, -, 1 |
||
2133 | */ |
||
2134 | array(2, 4, 1), |
||
2135 | ), |
||
2136 | 1 => array( |
||
2137 | $fixture, |
||
2138 | array( |
||
2139 | 'languages' => array( |
||
2140 | 'ger-DE', |
||
2141 | ), |
||
2142 | 'useAlwaysAvailable' => false, |
||
2143 | ), |
||
2144 | new Criterion\Field('integer', Criterion\Operator::LT, 2), |
||
2145 | /** |
||
2146 | * Expected order, Value eng-GB, Value ger-DE. |
||
2147 | * |
||
2148 | * Content 1, -, 1 |
||
2149 | */ |
||
2150 | array(1), |
||
2151 | ), |
||
2152 | 2 => array( |
||
2153 | $fixture, |
||
2154 | array( |
||
2155 | 'languages' => array( |
||
2156 | 'eng-GB', |
||
2157 | ), |
||
2158 | ), |
||
2159 | new Criterion\Field('integer', Criterion\Operator::LTE, 4), |
||
2160 | /** |
||
2161 | * Expected order, Value eng-GB, Value ger-DE. |
||
2162 | * |
||
2163 | * Content 5, 5, - |
||
2164 | * Content 2, 4, - |
||
2165 | * Content 3, 3, - |
||
2166 | * Content 1, -, 1 |
||
2167 | */ |
||
2168 | array(2, 3, 1), |
||
2169 | ), |
||
2170 | 3 => array( |
||
2171 | $fixture, |
||
2172 | array( |
||
2173 | 'languages' => array( |
||
2174 | 'eng-GB', |
||
2175 | ), |
||
2176 | 'useAlwaysAvailable' => false, |
||
2177 | ), |
||
2178 | new Criterion\Field('integer', Criterion\Operator::LTE, 4), |
||
2179 | /** |
||
2180 | * Expected order, Value eng-GB, Value ger-DE. |
||
2181 | * |
||
2182 | * Content 2, 4, - |
||
2183 | * Content 3, 3, - |
||
2184 | */ |
||
2185 | array(2, 3), |
||
2186 | ), |
||
2187 | 4 => array( |
||
2188 | $fixture, |
||
2189 | $languageSettings, |
||
2190 | new Criterion\Field('integer', Criterion\Operator::LTE, 4), |
||
2191 | /** |
||
2192 | * Expected order, Value eng-GB, Value ger-DE. |
||
2193 | * |
||
2194 | * Content 2, 4, - |
||
2195 | * Content 4, -, 2 |
||
2196 | * Content 1, -, 1 |
||
2197 | */ |
||
2198 | array(2, 4, 1), |
||
2199 | ), |
||
2200 | 5 => array( |
||
2201 | $fixture, |
||
2202 | $languageSettings, |
||
2203 | new Criterion\Field('integer', Criterion\Operator::GT, 1), |
||
2204 | /** |
||
2205 | * Expected order, Value eng-GB, Value ger-DE. |
||
2206 | * |
||
2207 | * Content 5, 5, - |
||
2208 | * Content 2, 4, - |
||
2209 | * Content 4, -, 2 |
||
2210 | */ |
||
2211 | array(5, 2, 4), |
||
2212 | ), |
||
2213 | 6 => array( |
||
2214 | $fixture, |
||
2215 | $languageSettings, |
||
2216 | new Criterion\Field('integer', Criterion\Operator::GTE, 2), |
||
2217 | /** |
||
2218 | * Expected order, Value eng-GB, Value ger-DE. |
||
2219 | * |
||
2220 | * Content 5, 5, - |
||
2221 | * Content 2, 4, - |
||
2222 | * Content 4, -, 2 |
||
2223 | */ |
||
2224 | array(5, 2, 4), |
||
2225 | ), |
||
2226 | 7 => array( |
||
2227 | $fixture, |
||
2228 | $languageSettings, |
||
2229 | new Criterion\Field('integer', Criterion\Operator::BETWEEN, array(2, 4)), |
||
2230 | /** |
||
2231 | * Expected order, Value eng-GB, Value ger-DE. |
||
2232 | * |
||
2233 | * Content 2, 4, - |
||
2234 | * Content 4, -, 2 |
||
2235 | */ |
||
2236 | array(2, 4), |
||
2237 | ), |
||
2238 | 8 => array( |
||
2239 | $fixture, |
||
2240 | $languageSettings, |
||
2241 | new Criterion\Field('integer', Criterion\Operator::BETWEEN, array(4, 2)), |
||
2242 | array(), |
||
2243 | ), |
||
2244 | 9 => array( |
||
2245 | $fixture, |
||
2246 | $languageSettings, |
||
2247 | new Criterion\Field('integer', Criterion\Operator::EQ, 4), |
||
2248 | /** |
||
2249 | * Expected order, Value eng-GB, Value ger-DE. |
||
2250 | * |
||
2251 | * Content 4, -, 2 |
||
2252 | */ |
||
2253 | array(2), |
||
2254 | ), |
||
2255 | 10 => array( |
||
2256 | $fixture, |
||
2257 | $languageSettings, |
||
2258 | new Criterion\Field('integer', Criterion\Operator::EQ, 2), |
||
2259 | /** |
||
2260 | * Expected order, Value eng-GB, Value ger-DE. |
||
2261 | * |
||
2262 | * Content 2, 4, - |
||
2263 | */ |
||
2264 | array(4), |
||
2265 | ), |
||
2266 | ); |
||
2267 | } |
||
2268 | |||
2269 | /** |
||
2270 | * Test for the findContent() method. |
||
2271 | * |
||
2272 | * @group ttt |
||
2273 | * @dataProvider providerForTestMultilingualFieldFilter |
||
2274 | * |
||
2275 | * @param array $contentDataList |
||
2276 | * @param array $languageSettings |
||
2277 | * @param \eZ\Publish\API\Repository\Values\Content\Query\Criterion $criterion |
||
2278 | * @param array $expected |
||
2279 | */ |
||
2280 | public function testMultilingualFieldFilterContent( |
||
2281 | array $contentDataList, |
||
2282 | $languageSettings, |
||
2283 | Criterion $criterion, |
||
2284 | $expected |
||
2285 | ) { |
||
2286 | $this->assertMultilingualFieldFilter( |
||
2287 | $contentDataList, |
||
2288 | $languageSettings, |
||
2289 | $criterion, |
||
2290 | $expected |
||
2291 | ); |
||
2292 | } |
||
2293 | |||
2294 | /** |
||
2295 | * Test for the findLocations() method. |
||
2296 | * |
||
2297 | * @group ttt |
||
2298 | * @dataProvider providerForTestMultilingualFieldFilter |
||
2299 | * |
||
2300 | * @param array $contentDataList |
||
2301 | * @param array $languageSettings |
||
2302 | * @param \eZ\Publish\API\Repository\Values\Content\Query\Criterion $criterion |
||
2303 | * @param array $expected |
||
2304 | */ |
||
2305 | public function testMultilingualFieldFilterLocation( |
||
2306 | array $contentDataList, |
||
2307 | $languageSettings, |
||
2308 | Criterion $criterion, |
||
2309 | $expected |
||
2310 | ) { |
||
2311 | $this->assertMultilingualFieldFilter( |
||
2312 | $contentDataList, |
||
2313 | $languageSettings, |
||
2314 | $criterion, |
||
2315 | $expected, |
||
2316 | false |
||
2317 | ); |
||
2318 | } |
||
2319 | |||
2320 | /** |
||
2321 | * @param array $contentDataList |
||
2322 | * @param array $languageSettings |
||
2323 | * @param \eZ\Publish\API\Repository\Values\Content\Query\Criterion $criterion |
||
2324 | * @param array $expected |
||
2325 | * @param bool $contentSearch |
||
2326 | */ |
||
2327 | protected function assertMultilingualFieldFilter( |
||
2328 | array $contentDataList, |
||
2329 | $languageSettings, |
||
2330 | Criterion $criterion, |
||
2331 | $expected, |
||
2332 | $contentSearch = true |
||
2333 | ) { |
||
2334 | $this->checkPrioritizedLanguagesSupport(); |
||
2335 | $contentType = $this->createTestContentType(); |
||
2336 | |||
2337 | // Create a draft to account for behaviour with ContentType in different states |
||
2338 | $repository = $this->getRepository(); |
||
2339 | $contentTypeService = $repository->getContentTypeService(); |
||
2340 | $contentTypeService->createContentTypeDraft($contentType); |
||
2341 | |||
2342 | $defaults = array(null, null, null, 'eng-GB', false); |
||
2343 | $contentIdList = array(); |
||
2344 | View Code Duplication | foreach ($contentDataList as $key => $contentData) { |
|
2345 | $contentData = $contentData + $defaults; |
||
2346 | list( |
||
2347 | $fieldValue11, |
||
2348 | $fieldValue12, |
||
2349 | $fieldValue2, |
||
2350 | $mainLanguageCode, |
||
2351 | $alwaysAvailable |
||
2352 | ) = $contentData; |
||
2353 | |||
2354 | $contentIdList[$key] = $this->createMultilingualContent( |
||
2355 | $contentType, |
||
2356 | $fieldValue11, |
||
2357 | $fieldValue12, |
||
2358 | $fieldValue2, |
||
2359 | $mainLanguageCode, |
||
2360 | $alwaysAvailable |
||
2361 | )->id; |
||
2362 | } |
||
2363 | |||
2364 | $sortClause = new SortClause\Field('test-type', 'integer', Query::SORT_DESC); |
||
2365 | $searchService = $repository->getSearchService(); |
||
2366 | if ($contentSearch) { |
||
2367 | $query = new Query( |
||
2368 | array( |
||
2369 | 'query' => new Criterion\LogicalAnd( |
||
2370 | array( |
||
2371 | new Criterion\ContentTypeId($contentType->id), |
||
2372 | $criterion, |
||
2373 | ) |
||
2374 | ), |
||
2375 | 'sortClauses' => array($sortClause), |
||
2376 | ) |
||
2377 | ); |
||
2378 | $result = $searchService->findContent($query, $languageSettings); |
||
2379 | } else { |
||
2380 | $query = new LocationQuery( |
||
2381 | array( |
||
2382 | 'query' => new Criterion\LogicalAnd( |
||
2383 | array( |
||
2384 | new Criterion\ContentTypeId($contentType->id), |
||
2385 | $criterion, |
||
2386 | ) |
||
2387 | ), |
||
2388 | 'sortClauses' => array($sortClause), |
||
2389 | ) |
||
2390 | ); |
||
2391 | $result = $searchService->findLocations($query, $languageSettings); |
||
2392 | } |
||
2393 | |||
2394 | $this->assertEquals(count($expected), $result->totalCount); |
||
2395 | |||
2396 | $expectedIdList = array(); |
||
2397 | foreach ($expected as $contentNumber) { |
||
2398 | $expectedIdList[] = $contentIdList[$contentNumber]; |
||
2399 | } |
||
2400 | |||
2401 | $this->assertEquals($expectedIdList, $this->mapResultContentIds($result)); |
||
2402 | } |
||
2403 | |||
2404 | /** |
||
2405 | * @param \eZ\Publish\API\Repository\Values\Content\Search\SearchResult $result |
||
2406 | * |
||
2407 | * @return array |
||
2408 | */ |
||
2409 | protected function mapResultContentIds(SearchResult $result) |
||
2410 | { |
||
2411 | return array_map( |
||
2412 | function (SearchHit $searchHit) { |
||
2413 | if ($searchHit->valueObject instanceof Location) { |
||
2414 | return $searchHit->valueObject->contentInfo->id; |
||
2415 | } |
||
2416 | |||
2417 | return $searchHit->valueObject->id; |
||
2418 | }, |
||
2419 | $result->searchHits |
||
2420 | ); |
||
2421 | } |
||
2422 | |||
2423 | /** |
||
2424 | * Test for the findContent() method. |
||
2425 | * |
||
2426 | * @dataProvider getSortedContentSearches |
||
2427 | * |
||
2428 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
2429 | */ |
||
2430 | public function testFindAndSortContent($queryData, $fixture, $closure = null) |
||
2431 | { |
||
2432 | $query = new Query($queryData); |
||
2433 | $this->assertQueryFixture($query, $fixture, $closure); |
||
2434 | } |
||
2435 | |||
2436 | /** |
||
2437 | * Test for the findContentInfo() method. |
||
2438 | * |
||
2439 | * @dataProvider getSortedContentSearches |
||
2440 | * @see \eZ\Publish\API\Repository\SearchService::findContentInfo() |
||
2441 | */ |
||
2442 | public function testFindAndSortContentInfo($queryData, $fixture, $closure = null) |
||
2443 | { |
||
2444 | $query = new Query($queryData); |
||
2445 | $this->assertQueryFixture($query, $fixture, $this->getContentInfoFixtureClosure($closure), true); |
||
2446 | } |
||
2447 | |||
2448 | /** |
||
2449 | * Test for the findLocations() method. |
||
2450 | * |
||
2451 | * @dataProvider getSortedContentSearches |
||
2452 | * |
||
2453 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
2454 | */ |
||
2455 | public function testFindAndSortContentLocations($queryData, $fixture, $closure = null) |
||
2456 | { |
||
2457 | $query = new LocationQuery($queryData); |
||
2458 | $this->assertQueryFixture($query, $fixture, $closure); |
||
2459 | } |
||
2460 | |||
2461 | /** |
||
2462 | * Test for the findLocations() method. |
||
2463 | * |
||
2464 | * @dataProvider getSortedLocationSearches |
||
2465 | * |
||
2466 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
2467 | */ |
||
2468 | public function testFindAndSortLocations($queryData, $fixture, $closure = null) |
||
2469 | { |
||
2470 | $query = new LocationQuery($queryData); |
||
2471 | $this->assertQueryFixture($query, $fixture, $closure); |
||
2472 | } |
||
2473 | |||
2474 | public function getFacettedSearches() |
||
2475 | { |
||
2476 | $fixtureDir = $this->getFixtureDir(); |
||
2477 | |||
2478 | return array( |
||
2479 | array( |
||
2480 | new Query( |
||
2481 | array( |
||
2482 | 'filter' => new Criterion\SectionId(array(1)), |
||
2483 | 'offset' => 0, |
||
2484 | 'limit' => 10, |
||
2485 | 'facetBuilders' => array( |
||
2486 | new FacetBuilder\ContentTypeFacetBuilder( |
||
2487 | array( |
||
2488 | 'name' => 'type', |
||
2489 | ) |
||
2490 | ), |
||
2491 | ), |
||
2492 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2493 | ) |
||
2494 | ), |
||
2495 | $fixtureDir . '/FacetContentType.php', |
||
2496 | ), |
||
2497 | array( |
||
2498 | new Query( |
||
2499 | array( |
||
2500 | 'filter' => new Criterion\SectionId(array(1)), |
||
2501 | 'offset' => 0, |
||
2502 | 'limit' => 10, |
||
2503 | 'facetBuilders' => array( |
||
2504 | new FacetBuilder\ContentTypeFacetBuilder( |
||
2505 | array( |
||
2506 | 'name' => 'type', |
||
2507 | 'minCount' => 3, |
||
2508 | ) |
||
2509 | ), |
||
2510 | ), |
||
2511 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2512 | ) |
||
2513 | ), |
||
2514 | $fixtureDir . '/FacetContentTypeMinCount.php', |
||
2515 | ), |
||
2516 | array( |
||
2517 | new Query( |
||
2518 | array( |
||
2519 | 'filter' => new Criterion\SectionId(array(1)), |
||
2520 | 'offset' => 0, |
||
2521 | 'limit' => 10, |
||
2522 | 'facetBuilders' => array( |
||
2523 | new FacetBuilder\ContentTypeFacetBuilder( |
||
2524 | array( |
||
2525 | 'name' => 'type', |
||
2526 | 'limit' => 5, |
||
2527 | ) |
||
2528 | ), |
||
2529 | ), |
||
2530 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2531 | ) |
||
2532 | ), |
||
2533 | $fixtureDir . '/FacetContentTypeMinLimit.php', |
||
2534 | ), |
||
2535 | array( |
||
2536 | new Query( |
||
2537 | array( |
||
2538 | 'filter' => new Criterion\SectionId(array(1)), |
||
2539 | 'offset' => 0, |
||
2540 | 'limit' => 10, |
||
2541 | 'facetBuilders' => array( |
||
2542 | new FacetBuilder\SectionFacetBuilder( |
||
2543 | array( |
||
2544 | 'name' => 'section', |
||
2545 | ) |
||
2546 | ), |
||
2547 | ), |
||
2548 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2549 | ) |
||
2550 | ), |
||
2551 | $fixtureDir . '/FacetSection.php', |
||
2552 | ), |
||
2553 | array( |
||
2554 | new Query( |
||
2555 | array( |
||
2556 | 'filter' => new Criterion\SectionId(array(1)), |
||
2557 | 'offset' => 0, |
||
2558 | 'limit' => 10, |
||
2559 | 'facetBuilders' => array( |
||
2560 | new FacetBuilder\UserFacetBuilder( |
||
2561 | array( |
||
2562 | 'name' => 'creator', |
||
2563 | ) |
||
2564 | ), |
||
2565 | ), |
||
2566 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2567 | ) |
||
2568 | ), |
||
2569 | $fixtureDir . '/FacetUser.php', |
||
2570 | ), |
||
2571 | array( |
||
2572 | new Query( |
||
2573 | array( |
||
2574 | 'filter' => new Criterion\SectionId(array(1)), |
||
2575 | 'offset' => 0, |
||
2576 | 'limit' => 10, |
||
2577 | 'facetBuilders' => array( |
||
2578 | new FacetBuilder\TermFacetBuilder(), |
||
2579 | ), |
||
2580 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2581 | ) |
||
2582 | ), |
||
2583 | $fixtureDir . '/FacetTerm.php', |
||
2584 | ), |
||
2585 | /* @todo: It needs to be defined how this one is supposed to work. |
||
2586 | array( |
||
2587 | new Query( |
||
2588 | array( |
||
2589 | 'filter' => new Criterion\SectionId( array( 1 ) ), |
||
2590 | 'offset' => 0, |
||
2591 | 'limit' => 10, |
||
2592 | 'facetBuilders' => array( |
||
2593 | new FacetBuilder\CriterionFacetBuilder() |
||
2594 | ), |
||
2595 | 'sortClauses' => array( new SortClause\ContentId() ) |
||
2596 | ) |
||
2597 | ), |
||
2598 | $fixtureDir . '/FacetCriterion.php', |
||
2599 | ), // */ |
||
2600 | /* @todo: Add sane ranges here: |
||
2601 | array( |
||
2602 | new Query( |
||
2603 | array( |
||
2604 | 'filter' => new Criterion\SectionId( array( 1 ) ), |
||
2605 | 'offset' => 0, |
||
2606 | 'limit' => 10, |
||
2607 | 'facetBuilders' => array( |
||
2608 | new FacetBuilder\DateRangeFacetBuilder( array() ) |
||
2609 | ), |
||
2610 | 'sortClauses' => array( new SortClause\ContentId() ) |
||
2611 | ) |
||
2612 | ), |
||
2613 | $fixtureDir . '/FacetDateRange.php', |
||
2614 | ), // */ |
||
2615 | array( |
||
2616 | new Query( |
||
2617 | array( |
||
2618 | 'filter' => new Criterion\SectionId(array(1)), |
||
2619 | 'offset' => 0, |
||
2620 | 'limit' => 10, |
||
2621 | 'facetBuilders' => array( |
||
2622 | new FacetBuilder\FieldFacetBuilder( |
||
2623 | array( |
||
2624 | 'fieldPaths' => array('article/title'), |
||
2625 | ) |
||
2626 | ), |
||
2627 | ), |
||
2628 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2629 | ) |
||
2630 | ), |
||
2631 | $fixtureDir . '/FacetFieldSimple.php', |
||
2632 | ), |
||
2633 | array( |
||
2634 | new Query( |
||
2635 | array( |
||
2636 | 'filter' => new Criterion\SectionId(array(1)), |
||
2637 | 'offset' => 0, |
||
2638 | 'limit' => 10, |
||
2639 | 'facetBuilders' => array( |
||
2640 | new FacetBuilder\FieldFacetBuilder( |
||
2641 | array( |
||
2642 | 'fieldPaths' => array('article/title'), |
||
2643 | 'regex' => '(a|b|c)', |
||
2644 | ) |
||
2645 | ), |
||
2646 | ), |
||
2647 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2648 | ) |
||
2649 | ), |
||
2650 | $fixtureDir . '/FacetFieldRegexp.php', |
||
2651 | ), |
||
2652 | array( |
||
2653 | new Query( |
||
2654 | array( |
||
2655 | 'filter' => new Criterion\SectionId(array(1)), |
||
2656 | 'offset' => 0, |
||
2657 | 'limit' => 10, |
||
2658 | 'facetBuilders' => array( |
||
2659 | new FacetBuilder\FieldFacetBuilder( |
||
2660 | array( |
||
2661 | 'fieldPaths' => array('article/title'), |
||
2662 | 'regex' => '(a|b|c)', |
||
2663 | 'sort' => FacetBuilder\FieldFacetBuilder::TERM_DESC, |
||
2664 | ) |
||
2665 | ), |
||
2666 | ), |
||
2667 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2668 | ) |
||
2669 | ), |
||
2670 | $fixtureDir . '/FacetFieldRegexpSortTerm.php', |
||
2671 | ), |
||
2672 | array( |
||
2673 | new Query( |
||
2674 | array( |
||
2675 | 'filter' => new Criterion\SectionId(array(1)), |
||
2676 | 'offset' => 0, |
||
2677 | 'limit' => 10, |
||
2678 | 'facetBuilders' => array( |
||
2679 | new FacetBuilder\FieldFacetBuilder( |
||
2680 | array( |
||
2681 | 'fieldPaths' => array('article/title'), |
||
2682 | 'regex' => '(a|b|c)', |
||
2683 | 'sort' => FacetBuilder\FieldFacetBuilder::COUNT_DESC, |
||
2684 | ) |
||
2685 | ), |
||
2686 | ), |
||
2687 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2688 | ) |
||
2689 | ), |
||
2690 | $fixtureDir . '/FacetFieldRegexpSortCount.php', |
||
2691 | ), |
||
2692 | /* @todo: Add sane ranges here: |
||
2693 | array( |
||
2694 | new Query( |
||
2695 | array( |
||
2696 | 'filter' => new Criterion\SectionId( array( 1 ) ), |
||
2697 | 'offset' => 0, |
||
2698 | 'limit' => 10, |
||
2699 | 'facetBuilders' => array( |
||
2700 | new FacetBuilder\FieldRangeFacetBuilder( array( |
||
2701 | 'fieldPath' => 'product/price', |
||
2702 | ) ) |
||
2703 | ), |
||
2704 | 'sortClauses' => array( new SortClause\ContentId() ) |
||
2705 | ) |
||
2706 | ), |
||
2707 | $fixtureDir . '/FacetFieldRegexpSortCount.php', |
||
2708 | ), // */ |
||
2709 | ); |
||
2710 | } |
||
2711 | |||
2712 | /** |
||
2713 | * Test for the findContent() method. |
||
2714 | * |
||
2715 | * @dataProvider getFacettedSearches |
||
2716 | * |
||
2717 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
2718 | */ |
||
2719 | public function testFindFacettedContent(Query $query, $fixture) |
||
2720 | { |
||
2721 | $this->assertQueryFixture($query, $fixture); |
||
2722 | } |
||
2723 | |||
2724 | /** |
||
2725 | * Test for the findContentInfo() method. |
||
2726 | * |
||
2727 | * @dataProvider getFacettedSearches |
||
2728 | * @see \eZ\Publish\API\Repository\SearchService::findContentInfo() |
||
2729 | */ |
||
2730 | public function testFindFacettedContentInfo(Query $query, $fixture) |
||
2731 | { |
||
2732 | $this->assertQueryFixture($query, $fixture, $this->getContentInfoFixtureClosure(), true); |
||
2733 | } |
||
2734 | |||
2735 | /** |
||
2736 | * Test for the findContent() method. |
||
2737 | * |
||
2738 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
2739 | */ |
||
2740 | View Code Duplication | public function testQueryCustomField() |
|
2741 | { |
||
2742 | $query = new Query( |
||
2743 | array( |
||
2744 | 'query' => new Criterion\CustomField( |
||
2745 | 'custom_field', |
||
2746 | Criterion\Operator::EQ, |
||
2747 | 'AdMiNiStRaToR' |
||
2748 | ), |
||
2749 | 'offset' => 0, |
||
2750 | 'limit' => 10, |
||
2751 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2752 | ) |
||
2753 | ); |
||
2754 | $this->assertQueryFixture( |
||
2755 | $query, |
||
2756 | $this->getFixtureDir() . '/QueryCustomField.php' |
||
2757 | ); |
||
2758 | } |
||
2759 | |||
2760 | /** |
||
2761 | * Test for the findContent() method. |
||
2762 | * |
||
2763 | * This tests explicitely queries the first_name while user is contained in |
||
2764 | * the last_name of admin and anonymous. This is done to show the custom |
||
2765 | * copy field working. |
||
2766 | * |
||
2767 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
2768 | */ |
||
2769 | View Code Duplication | public function testQueryModifiedField() |
|
2770 | { |
||
2771 | // Check using get_class since the others extend SetupFactory\Legacy |
||
2772 | if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') { |
||
2773 | $this->markTestIncomplete( |
||
2774 | 'Custom fields not supported by LegacySE ' . |
||
2775 | '(@todo: Legacy should fallback to just querying normal field so this should be tested here)' |
||
2776 | ); |
||
2777 | } |
||
2778 | |||
2779 | $query = new Query( |
||
2780 | array( |
||
2781 | 'query' => new Criterion\Field( |
||
2782 | 'first_name', |
||
2783 | Criterion\Operator::EQ, |
||
2784 | 'User' |
||
2785 | ), |
||
2786 | 'offset' => 0, |
||
2787 | 'limit' => 10, |
||
2788 | 'sortClauses' => array(new SortClause\ContentId()), |
||
2789 | ) |
||
2790 | ); |
||
2791 | $query->query->setCustomField('user', 'first_name', 'custom_field'); |
||
2792 | |||
2793 | $this->assertQueryFixture( |
||
2794 | $query, |
||
2795 | $this->getFixtureDir() . '/QueryModifiedField.php' |
||
2796 | ); |
||
2797 | } |
||
2798 | |||
2799 | /** |
||
2800 | * Test for the findContent() method. |
||
2801 | * |
||
2802 | * This tests first explicitly creates sort clause on the 'short_name' which is empty |
||
2803 | * for all Content instances of 'folder' ContentType. Custom sort field is then set |
||
2804 | * to the index storage name of folder's 'name' field, in order to show the custom |
||
2805 | * sort field working. |
||
2806 | * |
||
2807 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
2808 | */ |
||
2809 | public function testSortModifiedField() |
||
2810 | { |
||
2811 | // Check using get_class since the others extend SetupFactory\Legacy |
||
2812 | if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') { |
||
2813 | $this->markTestIncomplete( |
||
2814 | 'Custom field sort not supported by LegacySE ' . |
||
2815 | '(@todo: Legacy should fallback to just querying normal field so this should be tested here)' |
||
2816 | ); |
||
2817 | } |
||
2818 | |||
2819 | $sortClause = new SortClause\Field('folder', 'short_name', Query::SORT_ASC); |
||
2820 | $sortClause->setCustomField('folder', 'short_name', 'folder_name_value_s'); |
||
2821 | |||
2822 | $query = new Query( |
||
2823 | array( |
||
2824 | 'filter' => new Criterion\ContentTypeId(1), |
||
2825 | 'offset' => 0, |
||
2826 | 'limit' => 10, |
||
2827 | 'sortClauses' => array( |
||
2828 | $sortClause, |
||
2829 | new SortClause\ContentId(), |
||
2830 | ), |
||
2831 | ) |
||
2832 | ); |
||
2833 | |||
2834 | $this->assertQueryFixture( |
||
2835 | $query, |
||
2836 | $this->getFixtureDir() . '/SortFolderName.php' |
||
2837 | ); |
||
2838 | } |
||
2839 | |||
2840 | /** |
||
2841 | * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType |
||
2842 | */ |
||
2843 | View Code Duplication | protected function createTestPlaceContentType() |
|
2844 | { |
||
2845 | $repository = $this->getRepository(); |
||
2846 | $contentTypeService = $repository->getContentTypeService(); |
||
2847 | |||
2848 | $createStruct = $contentTypeService->newContentTypeCreateStruct('testtype'); |
||
2849 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
2850 | $createStruct->names = array('eng-GB' => 'Test type'); |
||
2851 | $createStruct->creatorId = 14; |
||
2852 | $createStruct->creationDate = new \DateTime(); |
||
2853 | |||
2854 | $translatableFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('maplocation', 'ezgmaplocation'); |
||
2855 | $translatableFieldCreate->names = array('eng-GB' => 'Map location field'); |
||
2856 | $translatableFieldCreate->fieldGroup = 'main'; |
||
2857 | $translatableFieldCreate->position = 1; |
||
2858 | $translatableFieldCreate->isTranslatable = false; |
||
2859 | $translatableFieldCreate->isSearchable = true; |
||
2860 | |||
2861 | $createStruct->addFieldDefinition($translatableFieldCreate); |
||
2862 | |||
2863 | $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content'); |
||
2864 | $contentTypeDraft = $contentTypeService->createContentType($createStruct, array($contentGroup)); |
||
2865 | $contentTypeService->publishContentTypeDraft($contentTypeDraft); |
||
2866 | $contentType = $contentTypeService->loadContentType($contentTypeDraft->id); |
||
2867 | |||
2868 | return $contentType; |
||
2869 | } |
||
2870 | |||
2871 | /** |
||
2872 | * Test for the findContent() method. |
||
2873 | * |
||
2874 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
2875 | * @group maplocation |
||
2876 | */ |
||
2877 | View Code Duplication | public function testMapLocationDistanceLessThanOrEqual() |
|
2878 | { |
||
2879 | $contentType = $this->createTestPlaceContentType(); |
||
2880 | |||
2881 | // Create a draft to account for behaviour with ContentType in different states |
||
2882 | $repository = $this->getRepository(); |
||
2883 | $contentTypeService = $repository->getContentTypeService(); |
||
2884 | $contentService = $repository->getContentService(); |
||
2885 | $contentTypeService->createContentTypeDraft($contentType); |
||
2886 | |||
2887 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
2888 | $createStruct->alwaysAvailable = false; |
||
2889 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
2890 | $createStruct->setField( |
||
2891 | 'maplocation', |
||
2892 | array( |
||
2893 | 'latitude' => 45.894877, |
||
2894 | 'longitude' => 15.972699, |
||
2895 | 'address' => 'Here be wild boars', |
||
2896 | ), |
||
2897 | 'eng-GB' |
||
2898 | ); |
||
2899 | |||
2900 | $draft = $contentService->createContent($createStruct); |
||
2901 | $wildBoars = $contentService->publishVersion($draft->getVersionInfo()); |
||
2902 | |||
2903 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
2904 | $createStruct->alwaysAvailable = false; |
||
2905 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
2906 | $createStruct->setField( |
||
2907 | 'maplocation', |
||
2908 | array( |
||
2909 | 'latitude' => 45.927334, |
||
2910 | 'longitude' => 15.934847, |
||
2911 | 'address' => 'A lone tree', |
||
2912 | ), |
||
2913 | 'eng-GB' |
||
2914 | ); |
||
2915 | |||
2916 | $draft = $contentService->createContent($createStruct); |
||
2917 | $tree = $contentService->publishVersion($draft->getVersionInfo()); |
||
2918 | |||
2919 | $this->refreshSearch($repository); |
||
2920 | |||
2921 | $query = new Query( |
||
2922 | array( |
||
2923 | 'filter' => new Criterion\LogicalAnd( |
||
2924 | array( |
||
2925 | new Criterion\ContentTypeId($contentType->id), |
||
2926 | new Criterion\MapLocationDistance( |
||
2927 | 'maplocation', |
||
2928 | Criterion\Operator::LTE, |
||
2929 | 240, |
||
2930 | 43.756825, |
||
2931 | 15.775074 |
||
2932 | ), |
||
2933 | ) |
||
2934 | ), |
||
2935 | 'offset' => 0, |
||
2936 | 'limit' => 10, |
||
2937 | 'sortClauses' => array(), |
||
2938 | ) |
||
2939 | ); |
||
2940 | |||
2941 | $searchService = $repository->getSearchService(); |
||
2942 | $result = $searchService->findContent($query); |
||
2943 | |||
2944 | $this->assertEquals(1, $result->totalCount); |
||
2945 | $this->assertEquals( |
||
2946 | $wildBoars->id, |
||
2947 | $result->searchHits[0]->valueObject->id |
||
2948 | ); |
||
2949 | } |
||
2950 | |||
2951 | /** |
||
2952 | * Test for the findContent() method. |
||
2953 | * |
||
2954 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
2955 | * @group maplocation |
||
2956 | */ |
||
2957 | View Code Duplication | public function testMapLocationDistanceGreaterThanOrEqual() |
|
2958 | { |
||
2959 | $contentType = $this->createTestPlaceContentType(); |
||
2960 | |||
2961 | // Create a draft to account for behaviour with ContentType in different states |
||
2962 | $repository = $this->getRepository(); |
||
2963 | $contentTypeService = $repository->getContentTypeService(); |
||
2964 | $contentService = $repository->getContentService(); |
||
2965 | $contentTypeService->createContentTypeDraft($contentType); |
||
2966 | |||
2967 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
2968 | $createStruct->alwaysAvailable = false; |
||
2969 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
2970 | $createStruct->setField( |
||
2971 | 'maplocation', |
||
2972 | array( |
||
2973 | 'latitude' => 45.894877, |
||
2974 | 'longitude' => 15.972699, |
||
2975 | 'address' => 'Here be wild boars', |
||
2976 | ), |
||
2977 | 'eng-GB' |
||
2978 | ); |
||
2979 | |||
2980 | $draft = $contentService->createContent($createStruct); |
||
2981 | $wildBoars = $contentService->publishVersion($draft->getVersionInfo()); |
||
2982 | |||
2983 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
2984 | $createStruct->alwaysAvailable = false; |
||
2985 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
2986 | $createStruct->setField( |
||
2987 | 'maplocation', |
||
2988 | array( |
||
2989 | 'latitude' => 45.927334, |
||
2990 | 'longitude' => 15.934847, |
||
2991 | 'address' => 'A lone tree', |
||
2992 | ), |
||
2993 | 'eng-GB' |
||
2994 | ); |
||
2995 | |||
2996 | $draft = $contentService->createContent($createStruct); |
||
2997 | $tree = $contentService->publishVersion($draft->getVersionInfo()); |
||
2998 | |||
2999 | $this->refreshSearch($repository); |
||
3000 | |||
3001 | $query = new Query( |
||
3002 | array( |
||
3003 | 'filter' => new Criterion\LogicalAnd( |
||
3004 | array( |
||
3005 | new Criterion\ContentTypeId($contentType->id), |
||
3006 | new Criterion\MapLocationDistance( |
||
3007 | 'maplocation', |
||
3008 | Criterion\Operator::GTE, |
||
3009 | 240, |
||
3010 | 43.756825, |
||
3011 | 15.775074 |
||
3012 | ), |
||
3013 | ) |
||
3014 | ), |
||
3015 | 'offset' => 0, |
||
3016 | 'limit' => 10, |
||
3017 | 'sortClauses' => array(), |
||
3018 | ) |
||
3019 | ); |
||
3020 | |||
3021 | $searchService = $repository->getSearchService(); |
||
3022 | $result = $searchService->findContent($query); |
||
3023 | |||
3024 | $this->assertEquals(1, $result->totalCount); |
||
3025 | $this->assertEquals( |
||
3026 | $tree->id, |
||
3027 | $result->searchHits[0]->valueObject->id |
||
3028 | ); |
||
3029 | } |
||
3030 | |||
3031 | /** |
||
3032 | * Test for the findContent() method. |
||
3033 | * |
||
3034 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
3035 | * @group maplocation |
||
3036 | */ |
||
3037 | public function testMapLocationDistanceBetween() |
||
3038 | { |
||
3039 | $contentType = $this->createTestPlaceContentType(); |
||
3040 | |||
3041 | // Create a draft to account for behaviour with ContentType in different states |
||
3042 | $repository = $this->getRepository(); |
||
3043 | $contentTypeService = $repository->getContentTypeService(); |
||
3044 | $contentService = $repository->getContentService(); |
||
3045 | $contentTypeService->createContentTypeDraft($contentType); |
||
3046 | |||
3047 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3048 | $createStruct->alwaysAvailable = false; |
||
3049 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3050 | $createStruct->setField( |
||
3051 | 'maplocation', |
||
3052 | array( |
||
3053 | 'latitude' => 45.894877, |
||
3054 | 'longitude' => 15.972699, |
||
3055 | 'address' => 'Here be wild boars', |
||
3056 | ), |
||
3057 | 'eng-GB' |
||
3058 | ); |
||
3059 | |||
3060 | $draft = $contentService->createContent($createStruct); |
||
3061 | $wildBoars = $contentService->publishVersion($draft->getVersionInfo()); |
||
3062 | |||
3063 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3064 | $createStruct->alwaysAvailable = false; |
||
3065 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3066 | $createStruct->setField( |
||
3067 | 'maplocation', |
||
3068 | array( |
||
3069 | 'latitude' => 45.927334, |
||
3070 | 'longitude' => 15.934847, |
||
3071 | 'address' => 'A lone tree', |
||
3072 | ), |
||
3073 | 'eng-GB' |
||
3074 | ); |
||
3075 | |||
3076 | $draft = $contentService->createContent($createStruct); |
||
3077 | $tree = $contentService->publishVersion($draft->getVersionInfo()); |
||
3078 | |||
3079 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3080 | $createStruct->alwaysAvailable = false; |
||
3081 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3082 | $createStruct->setField( |
||
3083 | 'maplocation', |
||
3084 | array( |
||
3085 | 'latitude' => 45.903777, |
||
3086 | 'longitude' => 15.958788, |
||
3087 | 'address' => 'Meadow with mushrooms', |
||
3088 | ), |
||
3089 | 'eng-GB' |
||
3090 | ); |
||
3091 | |||
3092 | $draft = $contentService->createContent($createStruct); |
||
3093 | $mushrooms = $contentService->publishVersion($draft->getVersionInfo()); |
||
3094 | |||
3095 | $this->refreshSearch($repository); |
||
3096 | |||
3097 | $query = new Query( |
||
3098 | array( |
||
3099 | 'filter' => new Criterion\LogicalAnd( |
||
3100 | array( |
||
3101 | new Criterion\ContentTypeId($contentType->id), |
||
3102 | new Criterion\MapLocationDistance( |
||
3103 | 'maplocation', |
||
3104 | Criterion\Operator::BETWEEN, |
||
3105 | array(239, 241), |
||
3106 | 43.756825, |
||
3107 | 15.775074 |
||
3108 | ), |
||
3109 | ) |
||
3110 | ), |
||
3111 | 'offset' => 0, |
||
3112 | 'limit' => 10, |
||
3113 | 'sortClauses' => array(), |
||
3114 | ) |
||
3115 | ); |
||
3116 | |||
3117 | $searchService = $repository->getSearchService(); |
||
3118 | $result = $searchService->findContent($query); |
||
3119 | |||
3120 | $this->assertEquals(1, $result->totalCount); |
||
3121 | $this->assertEquals( |
||
3122 | $mushrooms->id, |
||
3123 | $result->searchHits[0]->valueObject->id |
||
3124 | ); |
||
3125 | } |
||
3126 | |||
3127 | /** |
||
3128 | * Test for the findContent() method. |
||
3129 | * |
||
3130 | * This tests the distance over the pole. The tests intentionally uses large range, |
||
3131 | * as the flat Earth model used in Legacy Storage Search is not precise for the use case. |
||
3132 | * What is tested here is that outer bounding box is correctly calculated, so that |
||
3133 | * location is not excluded. |
||
3134 | * |
||
3135 | * Range between 222km and 350km shows the magnitude of error between great-circle |
||
3136 | * (always very precise) and flat Earth (very imprecise for this use case) models. |
||
3137 | * |
||
3138 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
3139 | * @group maplocation |
||
3140 | */ |
||
3141 | public function testMapLocationDistanceBetweenPolar() |
||
3142 | { |
||
3143 | $contentType = $this->createTestPlaceContentType(); |
||
3144 | |||
3145 | // Create a draft to account for behaviour with ContentType in different states |
||
3146 | $repository = $this->getRepository(); |
||
3147 | $contentTypeService = $repository->getContentTypeService(); |
||
3148 | $contentService = $repository->getContentService(); |
||
3149 | $contentTypeService->createContentTypeDraft($contentType); |
||
3150 | |||
3151 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3152 | $createStruct->alwaysAvailable = false; |
||
3153 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3154 | $createStruct->setField( |
||
3155 | 'maplocation', |
||
3156 | array( |
||
3157 | 'latitude' => 89, |
||
3158 | 'longitude' => -164, |
||
3159 | 'address' => 'Polar bear media tower', |
||
3160 | ), |
||
3161 | 'eng-GB' |
||
3162 | ); |
||
3163 | |||
3164 | $draft = $contentService->createContent($createStruct); |
||
3165 | $polarBear = $contentService->publishVersion($draft->getVersionInfo()); |
||
3166 | |||
3167 | $this->refreshSearch($repository); |
||
3168 | |||
3169 | $query = new Query( |
||
3170 | array( |
||
3171 | 'filter' => new Criterion\LogicalAnd( |
||
3172 | array( |
||
3173 | new Criterion\ContentTypeId($contentType->id), |
||
3174 | new Criterion\MapLocationDistance( |
||
3175 | 'maplocation', |
||
3176 | Criterion\Operator::BETWEEN, |
||
3177 | array(221, 350), |
||
3178 | 89, |
||
3179 | 16 |
||
3180 | ), |
||
3181 | ) |
||
3182 | ), |
||
3183 | 'offset' => 0, |
||
3184 | 'limit' => 10, |
||
3185 | 'sortClauses' => array(), |
||
3186 | ) |
||
3187 | ); |
||
3188 | |||
3189 | $searchService = $repository->getSearchService(); |
||
3190 | $result = $searchService->findContent($query); |
||
3191 | |||
3192 | $this->assertEquals(1, $result->totalCount); |
||
3193 | $this->assertEquals( |
||
3194 | $polarBear->id, |
||
3195 | $result->searchHits[0]->valueObject->id |
||
3196 | ); |
||
3197 | } |
||
3198 | |||
3199 | /** |
||
3200 | * Test for the findContent() method. |
||
3201 | * |
||
3202 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
3203 | * @group maplocation |
||
3204 | */ |
||
3205 | View Code Duplication | public function testMapLocationDistanceSortAscending() |
|
3206 | { |
||
3207 | $contentType = $this->createTestPlaceContentType(); |
||
3208 | |||
3209 | // Create a draft to account for behaviour with ContentType in different states |
||
3210 | $repository = $this->getRepository(); |
||
3211 | $contentTypeService = $repository->getContentTypeService(); |
||
3212 | $contentService = $repository->getContentService(); |
||
3213 | $contentTypeService->createContentTypeDraft($contentType); |
||
3214 | |||
3215 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3216 | $createStruct->alwaysAvailable = false; |
||
3217 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3218 | $createStruct->setField( |
||
3219 | 'maplocation', |
||
3220 | array( |
||
3221 | 'latitude' => 45.894877, |
||
3222 | 'longitude' => 15.972699, |
||
3223 | 'address' => 'Here be wild boars', |
||
3224 | ), |
||
3225 | 'eng-GB' |
||
3226 | ); |
||
3227 | |||
3228 | $draft = $contentService->createContent($createStruct); |
||
3229 | $wildBoars = $contentService->publishVersion($draft->getVersionInfo()); |
||
3230 | |||
3231 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3232 | $createStruct->alwaysAvailable = false; |
||
3233 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3234 | $createStruct->setField( |
||
3235 | 'maplocation', |
||
3236 | array( |
||
3237 | 'latitude' => 45.927334, |
||
3238 | 'longitude' => 15.934847, |
||
3239 | 'address' => 'A lone tree', |
||
3240 | ), |
||
3241 | 'eng-GB' |
||
3242 | ); |
||
3243 | |||
3244 | $draft = $contentService->createContent($createStruct); |
||
3245 | $tree = $contentService->publishVersion($draft->getVersionInfo()); |
||
3246 | |||
3247 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3248 | $createStruct->alwaysAvailable = false; |
||
3249 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3250 | $createStruct->setField( |
||
3251 | 'maplocation', |
||
3252 | array( |
||
3253 | 'latitude' => 45.903777, |
||
3254 | 'longitude' => 15.958788, |
||
3255 | 'address' => 'Meadow with mushrooms', |
||
3256 | ), |
||
3257 | 'eng-GB' |
||
3258 | ); |
||
3259 | |||
3260 | $draft = $contentService->createContent($createStruct); |
||
3261 | $mushrooms = $contentService->publishVersion($draft->getVersionInfo()); |
||
3262 | |||
3263 | $this->refreshSearch($repository); |
||
3264 | |||
3265 | $wellInVodice = array( |
||
3266 | 'latitude' => 43.756825, |
||
3267 | 'longitude' => 15.775074, |
||
3268 | ); |
||
3269 | |||
3270 | $query = new Query( |
||
3271 | array( |
||
3272 | 'filter' => new Criterion\LogicalAnd( |
||
3273 | array( |
||
3274 | new Criterion\ContentTypeId($contentType->id), |
||
3275 | new Criterion\MapLocationDistance( |
||
3276 | 'maplocation', |
||
3277 | Criterion\Operator::GTE, |
||
3278 | 235, |
||
3279 | $wellInVodice['latitude'], |
||
3280 | $wellInVodice['longitude'] |
||
3281 | ), |
||
3282 | ) |
||
3283 | ), |
||
3284 | 'offset' => 0, |
||
3285 | 'limit' => 10, |
||
3286 | 'sortClauses' => array( |
||
3287 | new SortClause\MapLocationDistance( |
||
3288 | 'testtype', |
||
3289 | 'maplocation', |
||
3290 | $wellInVodice['latitude'], |
||
3291 | $wellInVodice['longitude'], |
||
3292 | Query::SORT_ASC |
||
3293 | ), |
||
3294 | ), |
||
3295 | ) |
||
3296 | ); |
||
3297 | |||
3298 | $searchService = $repository->getSearchService(); |
||
3299 | $result = $searchService->findContent($query); |
||
3300 | |||
3301 | $this->assertEquals(3, $result->totalCount); |
||
3302 | $this->assertEquals( |
||
3303 | $wildBoars->id, |
||
3304 | $result->searchHits[0]->valueObject->id |
||
3305 | ); |
||
3306 | $this->assertEquals( |
||
3307 | $mushrooms->id, |
||
3308 | $result->searchHits[1]->valueObject->id |
||
3309 | ); |
||
3310 | $this->assertEquals( |
||
3311 | $tree->id, |
||
3312 | $result->searchHits[2]->valueObject->id |
||
3313 | ); |
||
3314 | } |
||
3315 | |||
3316 | /** |
||
3317 | * Test for the findContent() method. |
||
3318 | * |
||
3319 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
3320 | * @group maplocation |
||
3321 | */ |
||
3322 | View Code Duplication | public function testMapLocationDistanceSortDescending() |
|
3323 | { |
||
3324 | $contentType = $this->createTestPlaceContentType(); |
||
3325 | |||
3326 | // Create a draft to account for behaviour with ContentType in different states |
||
3327 | $repository = $this->getRepository(); |
||
3328 | $contentTypeService = $repository->getContentTypeService(); |
||
3329 | $contentService = $repository->getContentService(); |
||
3330 | $contentTypeService->createContentTypeDraft($contentType); |
||
3331 | |||
3332 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3333 | $createStruct->alwaysAvailable = false; |
||
3334 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3335 | $createStruct->setField( |
||
3336 | 'maplocation', |
||
3337 | array( |
||
3338 | 'latitude' => 45.894877, |
||
3339 | 'longitude' => 15.972699, |
||
3340 | 'address' => 'Here be wild boars', |
||
3341 | ), |
||
3342 | 'eng-GB' |
||
3343 | ); |
||
3344 | |||
3345 | $draft = $contentService->createContent($createStruct); |
||
3346 | $wildBoars = $contentService->publishVersion($draft->getVersionInfo()); |
||
3347 | |||
3348 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3349 | $createStruct->alwaysAvailable = false; |
||
3350 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3351 | $createStruct->setField( |
||
3352 | 'maplocation', |
||
3353 | array( |
||
3354 | 'latitude' => 45.927334, |
||
3355 | 'longitude' => 15.934847, |
||
3356 | 'address' => 'A lone tree', |
||
3357 | ), |
||
3358 | 'eng-GB' |
||
3359 | ); |
||
3360 | |||
3361 | $draft = $contentService->createContent($createStruct); |
||
3362 | $tree = $contentService->publishVersion($draft->getVersionInfo()); |
||
3363 | |||
3364 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3365 | $createStruct->alwaysAvailable = false; |
||
3366 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3367 | $createStruct->setField( |
||
3368 | 'maplocation', |
||
3369 | array( |
||
3370 | 'latitude' => 45.903777, |
||
3371 | 'longitude' => 15.958788, |
||
3372 | 'address' => 'Meadow with mushrooms', |
||
3373 | ), |
||
3374 | 'eng-GB' |
||
3375 | ); |
||
3376 | |||
3377 | $draft = $contentService->createContent($createStruct); |
||
3378 | $mushrooms = $contentService->publishVersion($draft->getVersionInfo()); |
||
3379 | |||
3380 | $this->refreshSearch($repository); |
||
3381 | |||
3382 | $well = array( |
||
3383 | 'latitude' => 43.756825, |
||
3384 | 'longitude' => 15.775074, |
||
3385 | ); |
||
3386 | |||
3387 | $query = new Query( |
||
3388 | array( |
||
3389 | 'filter' => new Criterion\LogicalAnd( |
||
3390 | array( |
||
3391 | new Criterion\ContentTypeId($contentType->id), |
||
3392 | new Criterion\MapLocationDistance( |
||
3393 | 'maplocation', |
||
3394 | Criterion\Operator::GTE, |
||
3395 | 235, |
||
3396 | $well['latitude'], |
||
3397 | $well['longitude'] |
||
3398 | ), |
||
3399 | ) |
||
3400 | ), |
||
3401 | 'offset' => 0, |
||
3402 | 'limit' => 10, |
||
3403 | 'sortClauses' => array( |
||
3404 | new SortClause\MapLocationDistance( |
||
3405 | 'testtype', |
||
3406 | 'maplocation', |
||
3407 | $well['latitude'], |
||
3408 | $well['longitude'], |
||
3409 | Query::SORT_DESC |
||
3410 | ), |
||
3411 | ), |
||
3412 | ) |
||
3413 | ); |
||
3414 | |||
3415 | $searchService = $repository->getSearchService(); |
||
3416 | $result = $searchService->findContent($query); |
||
3417 | |||
3418 | $this->assertEquals(3, $result->totalCount); |
||
3419 | $this->assertEquals( |
||
3420 | $wildBoars->id, |
||
3421 | $result->searchHits[2]->valueObject->id |
||
3422 | ); |
||
3423 | $this->assertEquals( |
||
3424 | $mushrooms->id, |
||
3425 | $result->searchHits[1]->valueObject->id |
||
3426 | ); |
||
3427 | $this->assertEquals( |
||
3428 | $tree->id, |
||
3429 | $result->searchHits[0]->valueObject->id |
||
3430 | ); |
||
3431 | } |
||
3432 | |||
3433 | /** |
||
3434 | * Test for the findContent() method. |
||
3435 | * |
||
3436 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
3437 | * @group maplocation |
||
3438 | */ |
||
3439 | public function testMapLocationDistanceWithCustomField() |
||
3440 | { |
||
3441 | $setupFactory = $this->getSetupFactory(); |
||
3442 | if ($setupFactory instanceof LegacyElasticsearch) { |
||
3443 | $this->markTestIncomplete("TODO: Some issues with 'copy_to' and 'geo_point'"); |
||
3444 | } |
||
3445 | |||
3446 | $contentType = $this->createTestPlaceContentType(); |
||
3447 | |||
3448 | // Create a draft to account for behaviour with ContentType in different states |
||
3449 | $repository = $this->getRepository(); |
||
3450 | $contentTypeService = $repository->getContentTypeService(); |
||
3451 | $contentService = $repository->getContentService(); |
||
3452 | $contentTypeService->createContentTypeDraft($contentType); |
||
3453 | |||
3454 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3455 | $createStruct->alwaysAvailable = false; |
||
3456 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3457 | $createStruct->setField( |
||
3458 | 'maplocation', |
||
3459 | array( |
||
3460 | 'latitude' => 45.894877, |
||
3461 | 'longitude' => 15.972699, |
||
3462 | 'address' => 'Here be wild boars', |
||
3463 | ), |
||
3464 | 'eng-GB' |
||
3465 | ); |
||
3466 | |||
3467 | $draft = $contentService->createContent($createStruct); |
||
3468 | $wildBoars = $contentService->publishVersion($draft->getVersionInfo()); |
||
3469 | |||
3470 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3471 | $createStruct->alwaysAvailable = false; |
||
3472 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3473 | $createStruct->setField( |
||
3474 | 'maplocation', |
||
3475 | array( |
||
3476 | 'latitude' => 45.927334, |
||
3477 | 'longitude' => 15.934847, |
||
3478 | 'address' => 'A lone tree', |
||
3479 | ), |
||
3480 | 'eng-GB' |
||
3481 | ); |
||
3482 | |||
3483 | $draft = $contentService->createContent($createStruct); |
||
3484 | $tree = $contentService->publishVersion($draft->getVersionInfo()); |
||
3485 | |||
3486 | $this->refreshSearch($repository); |
||
3487 | |||
3488 | $distanceCriterion = new Criterion\MapLocationDistance( |
||
3489 | 'maplocation', |
||
3490 | Criterion\Operator::LTE, |
||
3491 | 240, |
||
3492 | 43.756825, |
||
3493 | 15.775074 |
||
3494 | ); |
||
3495 | $distanceCriterion->setCustomField('testtype', 'maplocation', 'custom_geolocation_field'); |
||
3496 | |||
3497 | $query = new Query( |
||
3498 | array( |
||
3499 | 'filter' => new Criterion\LogicalAnd( |
||
3500 | array( |
||
3501 | new Criterion\ContentTypeId($contentType->id), |
||
3502 | $distanceCriterion, |
||
3503 | ) |
||
3504 | ), |
||
3505 | 'offset' => 0, |
||
3506 | 'limit' => 10, |
||
3507 | 'sortClauses' => array(), |
||
3508 | ) |
||
3509 | ); |
||
3510 | |||
3511 | $searchService = $repository->getSearchService(); |
||
3512 | $result = $searchService->findContent($query); |
||
3513 | |||
3514 | $this->assertEquals(1, $result->totalCount); |
||
3515 | $this->assertEquals( |
||
3516 | $wildBoars->id, |
||
3517 | $result->searchHits[0]->valueObject->id |
||
3518 | ); |
||
3519 | } |
||
3520 | |||
3521 | /** |
||
3522 | * Test for the findContent() method. |
||
3523 | * |
||
3524 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
3525 | * @group maplocation |
||
3526 | */ |
||
3527 | public function testMapLocationDistanceWithCustomFieldSort() |
||
3528 | { |
||
3529 | $setupFactory = $this->getSetupFactory(); |
||
3530 | if ($setupFactory instanceof LegacyElasticsearch) { |
||
3531 | $this->markTestIncomplete("TODO: Some issues with 'copy_to' and 'geo_point'"); |
||
3532 | } |
||
3533 | |||
3534 | $contentType = $this->createTestPlaceContentType(); |
||
3535 | |||
3536 | // Create a draft to account for behaviour with ContentType in different states |
||
3537 | $repository = $this->getRepository(); |
||
3538 | $contentTypeService = $repository->getContentTypeService(); |
||
3539 | $contentService = $repository->getContentService(); |
||
3540 | $contentTypeService->createContentTypeDraft($contentType); |
||
3541 | |||
3542 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3543 | $createStruct->alwaysAvailable = false; |
||
3544 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3545 | $createStruct->setField( |
||
3546 | 'maplocation', |
||
3547 | array( |
||
3548 | 'latitude' => 45.894877, |
||
3549 | 'longitude' => 15.972699, |
||
3550 | 'address' => 'Here be wild boars', |
||
3551 | ), |
||
3552 | 'eng-GB' |
||
3553 | ); |
||
3554 | |||
3555 | $draft = $contentService->createContent($createStruct); |
||
3556 | $wildBoars = $contentService->publishVersion($draft->getVersionInfo()); |
||
3557 | |||
3558 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3559 | $createStruct->alwaysAvailable = false; |
||
3560 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3561 | $createStruct->setField( |
||
3562 | 'maplocation', |
||
3563 | array( |
||
3564 | 'latitude' => 45.927334, |
||
3565 | 'longitude' => 15.934847, |
||
3566 | 'address' => 'A lone tree', |
||
3567 | ), |
||
3568 | 'eng-GB' |
||
3569 | ); |
||
3570 | |||
3571 | $draft = $contentService->createContent($createStruct); |
||
3572 | $tree = $contentService->publishVersion($draft->getVersionInfo()); |
||
3573 | |||
3574 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3575 | $createStruct->alwaysAvailable = false; |
||
3576 | $createStruct->mainLanguageCode = 'eng-GB'; |
||
3577 | $createStruct->setField( |
||
3578 | 'maplocation', |
||
3579 | array( |
||
3580 | 'latitude' => 45.903777, |
||
3581 | 'longitude' => 15.958788, |
||
3582 | 'address' => 'Meadow with mushrooms', |
||
3583 | ), |
||
3584 | 'eng-GB' |
||
3585 | ); |
||
3586 | |||
3587 | $draft = $contentService->createContent($createStruct); |
||
3588 | $mushrooms = $contentService->publishVersion($draft->getVersionInfo()); |
||
3589 | |||
3590 | $this->refreshSearch($repository); |
||
3591 | |||
3592 | $well = array( |
||
3593 | 'latitude' => 43.756825, |
||
3594 | 'longitude' => 15.775074, |
||
3595 | ); |
||
3596 | |||
3597 | $sortClause = new SortClause\MapLocationDistance( |
||
3598 | 'testtype', |
||
3599 | 'maplocation', |
||
3600 | $well['latitude'], |
||
3601 | $well['longitude'], |
||
3602 | Query::SORT_DESC |
||
3603 | ); |
||
3604 | $sortClause->setCustomField('testtype', 'maplocation', 'custom_geolocation_field'); |
||
3605 | |||
3606 | $query = new Query( |
||
3607 | array( |
||
3608 | 'filter' => new Criterion\LogicalAnd( |
||
3609 | array( |
||
3610 | new Criterion\ContentTypeId($contentType->id), |
||
3611 | new Criterion\MapLocationDistance( |
||
3612 | 'maplocation', |
||
3613 | Criterion\Operator::GTE, |
||
3614 | 235, |
||
3615 | $well['latitude'], |
||
3616 | $well['longitude'] |
||
3617 | ), |
||
3618 | ) |
||
3619 | ), |
||
3620 | 'offset' => 0, |
||
3621 | 'limit' => 10, |
||
3622 | 'sortClauses' => array( |
||
3623 | $sortClause, |
||
3624 | ), |
||
3625 | ) |
||
3626 | ); |
||
3627 | |||
3628 | $searchService = $repository->getSearchService(); |
||
3629 | $result = $searchService->findContent($query); |
||
3630 | |||
3631 | $this->assertEquals(3, $result->totalCount); |
||
3632 | $this->assertEquals( |
||
3633 | $wildBoars->id, |
||
3634 | $result->searchHits[2]->valueObject->id |
||
3635 | ); |
||
3636 | $this->assertEquals( |
||
3637 | $mushrooms->id, |
||
3638 | $result->searchHits[1]->valueObject->id |
||
3639 | ); |
||
3640 | $this->assertEquals( |
||
3641 | $tree->id, |
||
3642 | $result->searchHits[0]->valueObject->id |
||
3643 | ); |
||
3644 | } |
||
3645 | |||
3646 | /** |
||
3647 | * Test for the findLocations() method. |
||
3648 | * |
||
3649 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
3650 | */ |
||
3651 | View Code Duplication | public function testFindMainLocation() |
|
3652 | { |
||
3653 | $plainSiteLocationId = 56; |
||
3654 | $designLocationId = 58; |
||
3655 | $partnersContentId = 59; |
||
3656 | $repository = $this->getRepository(); |
||
3657 | $locationService = $repository->getLocationService(); |
||
3658 | $contentService = $repository->getContentService(); |
||
3659 | |||
3660 | // Add secondary Location for "Partners" user group, under "Design" page |
||
3661 | $locationService->createLocation( |
||
3662 | $contentService->loadContentInfo($partnersContentId), |
||
3663 | $locationService->newLocationCreateStruct($designLocationId) |
||
3664 | ); |
||
3665 | |||
3666 | $this->refreshSearch($repository); |
||
3667 | |||
3668 | $query = new LocationQuery( |
||
3669 | array( |
||
3670 | 'filter' => new Criterion\LogicalAnd( |
||
3671 | array( |
||
3672 | new Criterion\ParentLocationId($designLocationId), |
||
3673 | new Criterion\Location\IsMainLocation( |
||
3674 | Criterion\Location\IsMainLocation::MAIN |
||
3675 | ), |
||
3676 | ) |
||
3677 | ), |
||
3678 | 'offset' => 0, |
||
3679 | 'limit' => 10, |
||
3680 | 'sortClauses' => array(), |
||
3681 | ) |
||
3682 | ); |
||
3683 | |||
3684 | $searchService = $repository->getSearchService(); |
||
3685 | $result = $searchService->findLocations($query); |
||
3686 | |||
3687 | $this->assertEquals(1, $result->totalCount); |
||
3688 | $this->assertEquals($plainSiteLocationId, $result->searchHits[0]->valueObject->id); |
||
3689 | } |
||
3690 | |||
3691 | /** |
||
3692 | * Test for the findLocations() method. |
||
3693 | * |
||
3694 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
3695 | */ |
||
3696 | View Code Duplication | public function testFindNonMainLocation() |
|
3697 | { |
||
3698 | $designLocationId = 58; |
||
3699 | $partnersContentId = 59; |
||
3700 | $repository = $this->getRepository(); |
||
3701 | $locationService = $repository->getLocationService(); |
||
3702 | $contentService = $repository->getContentService(); |
||
3703 | |||
3704 | // Add secondary Location for "Partners" user group, under "Design" page |
||
3705 | $newLocation = $locationService->createLocation( |
||
3706 | $contentService->loadContentInfo($partnersContentId), |
||
3707 | $locationService->newLocationCreateStruct($designLocationId) |
||
3708 | ); |
||
3709 | |||
3710 | $this->refreshSearch($repository); |
||
3711 | |||
3712 | $query = new LocationQuery( |
||
3713 | array( |
||
3714 | 'filter' => new Criterion\LogicalAnd( |
||
3715 | array( |
||
3716 | new Criterion\ParentLocationId($designLocationId), |
||
3717 | new Criterion\Location\IsMainLocation( |
||
3718 | Criterion\Location\IsMainLocation::NOT_MAIN |
||
3719 | ), |
||
3720 | ) |
||
3721 | ), |
||
3722 | 'offset' => 0, |
||
3723 | 'limit' => 10, |
||
3724 | 'sortClauses' => array(), |
||
3725 | ) |
||
3726 | ); |
||
3727 | |||
3728 | $searchService = $repository->getSearchService(); |
||
3729 | $result = $searchService->findLocations($query); |
||
3730 | |||
3731 | $this->assertEquals(1, $result->totalCount); |
||
3732 | $this->assertEquals($newLocation->id, $result->searchHits[0]->valueObject->id); |
||
3733 | } |
||
3734 | |||
3735 | /** |
||
3736 | * Test for the findLocations() method. |
||
3737 | * |
||
3738 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
3739 | */ |
||
3740 | View Code Duplication | public function testSortMainLocationAscending() |
|
3741 | { |
||
3742 | $plainSiteLocationId = 56; |
||
3743 | $designLocationId = 58; |
||
3744 | $partnersContentId = 59; |
||
3745 | $repository = $this->getRepository(); |
||
3746 | $locationService = $repository->getLocationService(); |
||
3747 | $contentService = $repository->getContentService(); |
||
3748 | |||
3749 | // Add secondary Location for "Partners" user group, under "Design" page |
||
3750 | $newLocation = $locationService->createLocation( |
||
3751 | $contentService->loadContentInfo($partnersContentId), |
||
3752 | $locationService->newLocationCreateStruct($designLocationId) |
||
3753 | ); |
||
3754 | |||
3755 | $this->refreshSearch($repository); |
||
3756 | |||
3757 | $query = new LocationQuery( |
||
3758 | array( |
||
3759 | 'filter' => new Criterion\ParentLocationId($designLocationId), |
||
3760 | 'offset' => 0, |
||
3761 | 'limit' => 10, |
||
3762 | 'sortClauses' => array( |
||
3763 | new SortClause\Location\IsMainLocation( |
||
3764 | LocationQuery::SORT_ASC |
||
3765 | ), |
||
3766 | ), |
||
3767 | ) |
||
3768 | ); |
||
3769 | |||
3770 | $searchService = $repository->getSearchService(); |
||
3771 | $result = $searchService->findLocations($query); |
||
3772 | |||
3773 | $this->assertEquals(2, $result->totalCount); |
||
3774 | $this->assertEquals($newLocation->id, $result->searchHits[0]->valueObject->id); |
||
3775 | $this->assertEquals($plainSiteLocationId, $result->searchHits[1]->valueObject->id); |
||
3776 | } |
||
3777 | |||
3778 | /** |
||
3779 | * Test for the findLocations() method. |
||
3780 | * |
||
3781 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
3782 | */ |
||
3783 | View Code Duplication | public function testSortMainLocationDescending() |
|
3784 | { |
||
3785 | $plainSiteLocationId = 56; |
||
3786 | $designLocationId = 58; |
||
3787 | $partnersContentId = 59; |
||
3788 | $repository = $this->getRepository(); |
||
3789 | $locationService = $repository->getLocationService(); |
||
3790 | $contentService = $repository->getContentService(); |
||
3791 | |||
3792 | // Add secondary Location for "Partners" user group, under "Design" page |
||
3793 | $newLocation = $locationService->createLocation( |
||
3794 | $contentService->loadContentInfo($partnersContentId), |
||
3795 | $locationService->newLocationCreateStruct($designLocationId) |
||
3796 | ); |
||
3797 | |||
3798 | $this->refreshSearch($repository); |
||
3799 | |||
3800 | $query = new LocationQuery( |
||
3801 | array( |
||
3802 | 'filter' => new Criterion\ParentLocationId($designLocationId), |
||
3803 | 'offset' => 0, |
||
3804 | 'limit' => 10, |
||
3805 | 'sortClauses' => array( |
||
3806 | new SortClause\Location\IsMainLocation( |
||
3807 | LocationQuery::SORT_DESC |
||
3808 | ), |
||
3809 | ), |
||
3810 | ) |
||
3811 | ); |
||
3812 | |||
3813 | $searchService = $repository->getSearchService(); |
||
3814 | $result = $searchService->findLocations($query); |
||
3815 | |||
3816 | $this->assertEquals(2, $result->totalCount); |
||
3817 | $this->assertEquals($plainSiteLocationId, $result->searchHits[0]->valueObject->id); |
||
3818 | $this->assertEquals($newLocation->id, $result->searchHits[1]->valueObject->id); |
||
3819 | } |
||
3820 | |||
3821 | /** |
||
3822 | * Test for the findLocations() method. |
||
3823 | * |
||
3824 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
3825 | */ |
||
3826 | public function testContentWithMultipleLocations() |
||
3827 | { |
||
3828 | $repository = $this->getRepository(); |
||
3829 | $contentService = $repository->getContentService(); |
||
3830 | $contentTypeService = $repository->getContentTypeService(); |
||
3831 | $locationService = $repository->getLocationService(); |
||
3832 | |||
3833 | $forumType = $contentTypeService->loadContentTypeByIdentifier('forum'); |
||
3834 | |||
3835 | $createStruct = $contentService->newContentCreateStruct($forumType, 'eng-GB'); |
||
3836 | $createStruct->alwaysAvailable = false; |
||
3837 | $createStruct->setField('name', 'An awesome duplicate forum'); |
||
3838 | |||
3839 | $draft = $contentService->createContent($createStruct); |
||
3840 | $content = $contentService->publishVersion($draft->getVersionInfo()); |
||
3841 | |||
3842 | $locationCreateStruct = $repository->getLocationService()->newLocationCreateStruct(2); |
||
3843 | $location1 = $locationService->createLocation($content->contentInfo, $locationCreateStruct); |
||
3844 | $locationCreateStruct = $repository->getLocationService()->newLocationCreateStruct(5); |
||
3845 | $location2 = $locationService->createLocation($content->contentInfo, $locationCreateStruct); |
||
3846 | |||
3847 | $this->refreshSearch($repository); |
||
3848 | |||
3849 | $query = new LocationQuery( |
||
3850 | array( |
||
3851 | 'filter' => new Criterion\ContentId($content->id), |
||
3852 | 'sortClauses' => array( |
||
3853 | new SortClause\Location\Id(LocationQuery::SORT_ASC), |
||
3854 | ), |
||
3855 | ) |
||
3856 | ); |
||
3857 | |||
3858 | $searchService = $repository->getSearchService(); |
||
3859 | $result = $searchService->findLocations($query); |
||
3860 | |||
3861 | $this->assertEquals(2, $result->totalCount); |
||
3862 | $this->assertEquals( |
||
3863 | $location1->id, |
||
3864 | $result->searchHits[0]->valueObject->id |
||
3865 | ); |
||
3866 | $this->assertEquals( |
||
3867 | $location2->id, |
||
3868 | $result->searchHits[1]->valueObject->id |
||
3869 | ); |
||
3870 | } |
||
3871 | |||
3872 | protected function createContentForTestUserMetadataGroupHorizontal() |
||
3873 | { |
||
3874 | $repository = $this->getRepository(); |
||
3875 | $contentService = $repository->getContentService(); |
||
3876 | $contentTypeService = $repository->getContentTypeService(); |
||
3877 | $locationService = $repository->getLocationService(); |
||
3878 | $userService = $repository->getUserService(); |
||
3879 | $administratorUser = $repository->getCurrentUser(); |
||
3880 | // ID of the "Administrators" user group in an eZ Publish demo installation |
||
3881 | $administratorsUserGroupId = 12; |
||
3882 | // ID of the "Editors" user group in an eZ Publish demo installation |
||
3883 | $editorsUserGroupId = 13; |
||
3884 | |||
3885 | $administratorsUserGroup = $userService->loadUserGroup($administratorsUserGroupId); |
||
3886 | $editorsUserGroup = $userService->loadUserGroup($editorsUserGroupId); |
||
3887 | |||
3888 | // Add additional Location for Administrators UserGroup under Editors UserGroup Location |
||
3889 | $locationCreateStruct = $locationService->newLocationCreateStruct( |
||
3890 | $editorsUserGroup->contentInfo->mainLocationId |
||
3891 | ); |
||
3892 | $newAdministratorsUserGroupLocation = $locationService->createLocation( |
||
3893 | $administratorsUserGroup->contentInfo, |
||
3894 | $locationCreateStruct |
||
3895 | ); |
||
3896 | |||
3897 | // Add additional Location for administrator user under newly created UserGroup Location |
||
3898 | $locationCreateStruct = $locationService->newLocationCreateStruct( |
||
3899 | $newAdministratorsUserGroupLocation->id |
||
3900 | ); |
||
3901 | $locationService->createLocation( |
||
3902 | $administratorUser->contentInfo, |
||
3903 | $locationCreateStruct |
||
3904 | ); |
||
3905 | |||
3906 | // Create a Content to be found through Editors UserGroup id. |
||
3907 | // This ensures data is indexed, it could also be done by updating metadata of |
||
3908 | // an existing Content, but slot would need to reindex Content and that should |
||
3909 | // be tested elsewhere (dedicated indexing integration tests, missing ATM). |
||
3910 | $contentType = $contentTypeService->loadContentTypeByIdentifier('folder'); |
||
3911 | |||
3912 | $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB'); |
||
3913 | $createStruct->setField('name', 'test'); |
||
3914 | |||
3915 | $locationCreateStruct = $locationService->newLocationCreateStruct(2); |
||
3916 | $draft = $contentService->createContent($createStruct, array($locationCreateStruct)); |
||
3917 | $content = $contentService->publishVersion($draft->getVersionInfo()); |
||
3918 | $contentTypeService->createContentTypeDraft($contentType); |
||
3919 | |||
3920 | $this->refreshSearch($repository); |
||
3921 | |||
3922 | return $content; |
||
3923 | } |
||
3924 | |||
3925 | /** |
||
3926 | * Test for the findContent() method. |
||
3927 | * |
||
3928 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
3929 | */ |
||
3930 | public function testUserMetadataGroupHorizontalFilterContent($queryType = null) |
||
3931 | { |
||
3932 | if ($queryType === null) { |
||
3933 | $queryType = 'filter'; |
||
3934 | } |
||
3935 | |||
3936 | $repository = $this->getRepository(); |
||
3937 | $searchService = $repository->getSearchService(); |
||
3938 | $editorsUserGroupId = 13; |
||
3939 | |||
3940 | $content = $this->createContentForTestUserMetadataGroupHorizontal(); |
||
3941 | |||
3942 | $criteria = array(); |
||
3943 | $setupFactory = $this->getSetupFactory(); |
||
3944 | |||
3945 | // Do not limit for LSE, as it does not not require reindexing. |
||
3946 | // See explanation below. |
||
3947 | if ($setupFactory instanceof LegacySolrSetupFactory || $setupFactory instanceof LegacyElasticsearch) { |
||
3948 | $criteria[] = new Criterion\ContentTypeIdentifier('folder'); |
||
3949 | } |
||
3950 | |||
3951 | $criteria[] = new Criterion\UserMetadata( |
||
3952 | Criterion\UserMetadata::GROUP, |
||
3953 | Criterion\Operator::EQ, |
||
3954 | $editorsUserGroupId |
||
3955 | ); |
||
3956 | |||
3957 | $query = new Query( |
||
3958 | array( |
||
3959 | $queryType => new Criterion\LogicalAnd($criteria), |
||
3960 | 'sortClauses' => array( |
||
3961 | new SortClause\ContentId(), |
||
3962 | ), |
||
3963 | 'limit' => 50, |
||
3964 | ) |
||
3965 | ); |
||
3966 | |||
3967 | if ($setupFactory instanceof LegacySolrSetupFactory || $setupFactory instanceof LegacyElasticsearch) { |
||
3968 | $result = $searchService->findContent($query); |
||
3969 | |||
3970 | // Administrator User is owned by itself, when additional Locations are added |
||
3971 | // it should be reindexed and its UserGroups will updated, which means it should |
||
3972 | // also be found as a Content of Editors UserGroup. However we do not handle this |
||
3973 | // in slots yet, and also miss SPI methods to do it without using Search (also |
||
3974 | // needed to decouple services), because as indexing is asynchronous Search |
||
3975 | // should not eat its own dog food for reindexing. |
||
3976 | $this->assertEquals(1, $result->totalCount); |
||
3977 | |||
3978 | $this->assertEquals( |
||
3979 | $content->id, |
||
3980 | $result->searchHits[0]->valueObject->id |
||
3981 | ); |
||
3982 | } else { |
||
3983 | // This is how it should eventually work for all search engines, |
||
3984 | // with required reindexing slots properly implemented. |
||
3985 | |||
3986 | $result = $searchService->findContent($query); |
||
3987 | |||
3988 | // Assert last hit manually, as id will change because it is created in test |
||
3989 | // and not present it base fixture. |
||
3990 | $foundContent1 = array_pop($result->searchHits); |
||
3991 | $result->totalCount = $result->totalCount - 1; |
||
3992 | $this->assertEquals($content->id, $foundContent1->valueObject->id); |
||
3993 | |||
3994 | $this->simplifySearchResult($result); |
||
3995 | $this->assertEquals( |
||
3996 | include $this->getFixtureDir() . '/UserMetadata.php', |
||
3997 | $result, |
||
3998 | 'Search results do not match.', |
||
3999 | .1 // Be quite generous regarding delay -- most important for scores |
||
4000 | ); |
||
4001 | } |
||
4002 | } |
||
4003 | |||
4004 | /** |
||
4005 | * Test for the findContent() method. |
||
4006 | * |
||
4007 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
4008 | */ |
||
4009 | public function testUserMetadataGroupHorizontalQueryContent() |
||
4010 | { |
||
4011 | $this->testUserMetadataGroupHorizontalFilterContent('query'); |
||
4012 | } |
||
4013 | |||
4014 | /** |
||
4015 | * Test for the findLocations() method. |
||
4016 | * |
||
4017 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
4018 | */ |
||
4019 | public function testUserMetadataGroupHorizontalFilterLocation($queryType = null) |
||
4020 | { |
||
4021 | if ($queryType === null) { |
||
4022 | $queryType = 'filter'; |
||
4023 | } |
||
4024 | |||
4025 | $repository = $this->getRepository(); |
||
4026 | $searchService = $repository->getSearchService(); |
||
4027 | $editorsUserGroupId = 13; |
||
4028 | |||
4029 | $content = $this->createContentForTestUserMetadataGroupHorizontal(); |
||
4030 | |||
4031 | $criteria = array(); |
||
4032 | $setupFactory = $this->getSetupFactory(); |
||
4033 | |||
4034 | // Do not limit for LSE, as it does not not require reindexing. |
||
4035 | // See explanation below. |
||
4036 | if ($setupFactory instanceof LegacySolrSetupFactory || $setupFactory instanceof LegacyElasticsearch) { |
||
4037 | $criteria[] = new Criterion\ContentTypeIdentifier('folder'); |
||
4038 | } |
||
4039 | |||
4040 | $criteria[] = new Criterion\UserMetadata( |
||
4041 | Criterion\UserMetadata::GROUP, |
||
4042 | Criterion\Operator::EQ, |
||
4043 | $editorsUserGroupId |
||
4044 | ); |
||
4045 | |||
4046 | $query = new LocationQuery( |
||
4047 | array( |
||
4048 | $queryType => new Criterion\LogicalAnd($criteria), |
||
4049 | 'sortClauses' => array( |
||
4050 | new SortClause\Location\Id(), |
||
4051 | ), |
||
4052 | 'limit' => 50, |
||
4053 | ) |
||
4054 | ); |
||
4055 | |||
4056 | if ($setupFactory instanceof LegacySolrSetupFactory || $setupFactory instanceof LegacyElasticsearch) { |
||
4057 | $result = $searchService->findLocations($query); |
||
4058 | |||
4059 | // Administrator User is owned by itself, when additional Locations are added |
||
4060 | // it should be reindexed and its UserGroups will updated, which means it should |
||
4061 | // also be found as a Content of Editors UserGroup. However we do not handle this |
||
4062 | // in slots yet, and also miss SPI methods to do it without using Search (also |
||
4063 | // needed to decouple services), because as indexing is asynchronous Search |
||
4064 | // should not eat its own dog food for reindexing. |
||
4065 | $this->assertEquals(1, $result->totalCount); |
||
4066 | |||
4067 | $this->assertEquals( |
||
4068 | $content->contentInfo->mainLocationId, |
||
4069 | $result->searchHits[0]->valueObject->id |
||
4070 | ); |
||
4071 | } else { |
||
4072 | // This is how it should eventually work for all search engines, |
||
4073 | // with required reindexing slots properly implemented. |
||
4074 | |||
4075 | $result = $searchService->findLocations($query); |
||
4076 | |||
4077 | // Assert last two hits manually, as ids will change because they are created |
||
4078 | // in test and not present in base fixture. |
||
4079 | $foundLocation1 = array_pop($result->searchHits); |
||
4080 | $foundLocation2 = array_pop($result->searchHits); |
||
4081 | // Remove additional Administrators UserGroup Location |
||
4082 | array_pop($result->searchHits); |
||
4083 | $result->totalCount = $result->totalCount - 2; |
||
4084 | $this->assertEquals( |
||
4085 | $content->versionInfo->contentInfo->mainLocationId, |
||
4086 | $foundLocation1->valueObject->id |
||
4087 | ); |
||
4088 | $this->assertEquals( |
||
4089 | $repository->getCurrentUser()->id, |
||
4090 | $foundLocation2->valueObject->contentId |
||
4091 | ); |
||
4092 | |||
4093 | $this->simplifySearchResult($result); |
||
4094 | $this->assertEquals( |
||
4095 | include $this->getFixtureDir() . '/UserMetadataLocation.php', |
||
4096 | $result, |
||
4097 | 'Search results do not match.', |
||
4098 | .1 // Be quite generous regarding delay -- most important for scores |
||
4099 | ); |
||
4100 | } |
||
4101 | } |
||
4102 | |||
4103 | /** |
||
4104 | * Test for the findLocations() method. |
||
4105 | * |
||
4106 | * @see \eZ\Publish\API\Repository\SearchService::findLocations() |
||
4107 | */ |
||
4108 | public function testUserMetadataGroupHorizontalQueryLocation() |
||
4109 | { |
||
4110 | $this->testUserMetadataGroupHorizontalFilterLocation('query'); |
||
4111 | } |
||
4112 | |||
4113 | /** |
||
4114 | * Test for the findContent() method. |
||
4115 | * |
||
4116 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
4117 | */ |
||
4118 | public function testLanguageAnalysisSeparateContent() |
||
4119 | { |
||
4120 | $setupFactory = $this->getSetupFactory(); |
||
4121 | if (!$setupFactory instanceof LegacyElasticsearch) { |
||
4122 | $this->markTestSkipped('Language analysis is implemented only for Elasticsearch storage'); |
||
4123 | } |
||
4124 | |||
4125 | $repository = $this->getRepository(); |
||
4126 | $contentService = $repository->getContentService(); |
||
4127 | $contentTypeService = $repository->getContentTypeService(); |
||
4128 | $locationService = $repository->getLocationService(); |
||
4129 | $searchService = $repository->getSearchService(); |
||
4130 | $languageService = $repository->getContentLanguageService(); |
||
4131 | |||
4132 | $languageCreateStruct = $languageService->newLanguageCreateStruct(); |
||
4133 | $languageCreateStruct->languageCode = 'rus-RU'; |
||
4134 | $languageCreateStruct->name = 'Russian'; |
||
4135 | |||
4136 | $languageService->createLanguage($languageCreateStruct); |
||
4137 | |||
4138 | $contentCreateStruct = $contentService->newContentCreateStruct( |
||
4139 | $contentTypeService->loadContentTypeByIdentifier('folder'), |
||
4140 | 'eng-GB' |
||
4141 | ); |
||
4142 | |||
4143 | $contentCreateStruct->setField('name', 'foxes'); |
||
4144 | |||
4145 | $englishContent = $contentService->publishVersion( |
||
4146 | $contentService->createContent( |
||
4147 | $contentCreateStruct, |
||
4148 | array($locationService->newLocationCreateStruct(2)) |
||
4149 | )->versionInfo |
||
4150 | ); |
||
4151 | |||
4152 | $contentCreateStruct = $contentService->newContentCreateStruct( |
||
4153 | $contentTypeService->loadContentTypeByIdentifier('folder'), |
||
4154 | 'rus-RU' |
||
4155 | ); |
||
4156 | |||
4157 | $contentCreateStruct->setField('name', 'foxes'); |
||
4158 | |||
4159 | $russianContent = $contentService->publishVersion( |
||
4160 | $contentService->createContent( |
||
4161 | $contentCreateStruct, |
||
4162 | array($locationService->newLocationCreateStruct(2)) |
||
4163 | )->versionInfo |
||
4164 | ); |
||
4165 | |||
4166 | // Only Content in English should be found, because Content in Russian |
||
4167 | // will not be correctly stemmed |
||
4168 | $query = new Query( |
||
4169 | array( |
||
4170 | 'query' => new Criterion\FullText('foxing'), |
||
4171 | ) |
||
4172 | ); |
||
4173 | |||
4174 | $searchResult = $searchService->findContent($query); |
||
4175 | |||
4176 | $this->assertEquals(1, $searchResult->totalCount); |
||
4177 | $this->assertEquals($englishContent->id, $searchResult->searchHits[0]->valueObject->id); |
||
4178 | } |
||
4179 | |||
4180 | /** |
||
4181 | * Test for the findContent() method. |
||
4182 | * |
||
4183 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
4184 | */ |
||
4185 | public function testLanguageAnalysisSameContent() |
||
4186 | { |
||
4187 | $setupFactory = $this->getSetupFactory(); |
||
4188 | if (!$setupFactory instanceof LegacyElasticsearch) { |
||
4189 | $this->markTestSkipped('Language analysis is implemented only for Elasticsearch storage'); |
||
4190 | } |
||
4191 | |||
4192 | $repository = $this->getRepository(); |
||
4193 | $contentService = $repository->getContentService(); |
||
4194 | $contentTypeService = $repository->getContentTypeService(); |
||
4195 | $locationService = $repository->getLocationService(); |
||
4196 | $searchService = $repository->getSearchService(); |
||
4197 | $languageService = $repository->getContentLanguageService(); |
||
4198 | |||
4199 | $languageCreateStruct = $languageService->newLanguageCreateStruct(); |
||
4200 | $languageCreateStruct->languageCode = 'rus-RU'; |
||
4201 | $languageCreateStruct->name = 'Russian'; |
||
4202 | |||
4203 | $languageService->createLanguage($languageCreateStruct); |
||
4204 | |||
4205 | $contentCreateStruct = $contentService->newContentCreateStruct( |
||
4206 | $contentTypeService->loadContentTypeByIdentifier('folder'), |
||
4207 | 'eng-GB' |
||
4208 | ); |
||
4209 | |||
4210 | $contentCreateStruct->setField('name', 'foxes важнейшими', 'eng-GB'); |
||
4211 | $contentCreateStruct->setField('name', 'foxes важнейшими', 'rus-RU'); |
||
4212 | |||
4213 | $mixedContent = $contentService->publishVersion( |
||
4214 | $contentService->createContent( |
||
4215 | $contentCreateStruct, |
||
4216 | array($locationService->newLocationCreateStruct(2)) |
||
4217 | )->versionInfo |
||
4218 | ); |
||
4219 | |||
4220 | // Content will be found because translation in Russian will be correctly stemmed |
||
4221 | $query = new Query( |
||
4222 | array( |
||
4223 | 'query' => new Criterion\FullText('важнее'), |
||
4224 | ) |
||
4225 | ); |
||
4226 | |||
4227 | $searchResult = $searchService->findContent($query); |
||
4228 | |||
4229 | $this->assertEquals(1, $searchResult->totalCount); |
||
4230 | $this->assertEquals($mixedContent->id, $searchResult->searchHits[0]->valueObject->id); |
||
4231 | } |
||
4232 | |||
4233 | /** |
||
4234 | * Test for the findContent() method. |
||
4235 | * |
||
4236 | * @see \eZ\Publish\API\Repository\SearchService::findContent() |
||
4237 | */ |
||
4238 | public function testLanguageAnalysisSameContentNotFound() |
||
4286 | |||
4287 | /** |
||
4288 | * Assert that query result matches the given fixture. |
||
4289 | * |
||
4290 | * @param Query $query |
||
4291 | * @param string $fixture |
||
4292 | * @param null|callable $closure |
||
4293 | * @param bool $info |
||
4294 | * @param bool $id |
||
4295 | */ |
||
4296 | protected function assertQueryFixture(Query $query, $fixture, $closure = null, $ignoreScore = true, $info = false, $id = true) |
||
4386 | |||
4387 | /** |
||
4388 | * Show a simplified view of the search result for manual introspection. |
||
4389 | * |
||
4390 | * @param SearchResult $result |
||
4391 | * |
||
4392 | * @return string |
||
4393 | */ |
||
4394 | View Code Duplication | protected function printResult(SearchResult $result) |
|
4395 | { |
||
4396 | $printed = ''; |
||
4397 | foreach ($result->searchHits as $hit) { |
||
4398 | $printed .= sprintf(" - %s (%s)\n", $hit->valueObject['title'], $hit->valueObject['id']); |
||
4399 | } |
||
4400 | |||
4401 | return $printed; |
||
4402 | } |
||
4403 | |||
4404 | /** |
||
4405 | * Simplify search result. |
||
4406 | * |
||
4407 | * This leads to saner comparisons of results, since we do not get the full |
||
4408 | * content objects every time. |
||
4409 | * |
||
4410 | * @param SearchResult $result |
||
4411 | */ |
||
4412 | protected function simplifySearchResult(SearchResult $result) |
||
4413 | { |
||
4414 | $result->time = 1; |
||
4415 | |||
4416 | foreach ($result->searchHits as $hit) { |
||
4417 | switch (true) { |
||
4418 | case $hit->valueObject instanceof Content: |
||
4419 | View Code Duplication | case $hit->valueObject instanceof Location: |
|
4420 | $hit->valueObject = array( |
||
4421 | 'id' => $hit->valueObject->contentInfo->id, |
||
4422 | 'title' => $hit->valueObject->contentInfo->name, |
||
4423 | ); |
||
4424 | break; |
||
4425 | |||
4426 | case $hit->valueObject instanceof ContentInfo: |
||
4427 | $hit->valueObject = array( |
||
4428 | 'id' => $hit->valueObject->id, |
||
4429 | 'title' => $hit->valueObject->name, |
||
4430 | ); |
||
4431 | break; |
||
4432 | |||
4433 | default: |
||
4434 | throw new \RuntimeException('Unknown search result hit type: ' . get_class($hit->valueObject)); |
||
4435 | } |
||
4436 | } |
||
4437 | } |
||
4438 | |||
4439 | /** |
||
4440 | * Get fixture directory. |
||
4441 | * |
||
4442 | * @return string |
||
4443 | */ |
||
4444 | protected function getFixtureDir() |
||
4445 | { |
||
4446 | return __DIR__ . '/_fixtures/' . getenv('fixtureDir') . '/'; |
||
4447 | } |
||
4448 | |||
4449 | /** |
||
4450 | * For findContentInfo tests, to reuse fixtures for findContent tests. |
||
4451 | * |
||
4452 | * @param null|callable $closure |
||
4453 | * |
||
4454 | * @return callable |
||
4455 | */ |
||
4456 | private function getContentInfoFixtureClosure($closure = null) |
||
4457 | { |
||
4458 | /** @var $data \eZ\Publish\API\Repository\Values\Content\Search\SearchResult */ |
||
4459 | return function (&$data) use ($closure) { |
||
4460 | foreach ($data->searchHits as $searchHit) { |
||
4461 | if ($searchHit->valueObject instanceof Content) { |
||
4462 | $searchHit->valueObject = $searchHit->valueObject->getVersionInfo()->getContentInfo(); |
||
4463 | } |
||
4464 | } |
||
4465 | |||
4466 | if (isset($closure)) { |
||
4471 | } |
||
4472 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: