Completed
Pull Request — master (#450)
by
unknown
03:11
created

ResultsGenerator::search()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 44
rs 8.9048
c 0
b 0
f 0
cc 5
nc 6
nop 1
1
<?php
2
3
namespace CultuurNet\UDB3\Search;
4
5
use Generator;
6
use Psr\Log\LoggerAwareInterface;
7
use Psr\Log\LoggerAwareTrait;
8
use Psr\Log\NullLogger;
9
10
class ResultsGenerator implements LoggerAwareInterface, ResultsGeneratorInterface
11
{
12
    use LoggerAwareTrait;
13
14
    /**
15
     * Default sorting method because it's ideal for getting consistent paging
16
     * results.
17
     */
18
    private const SORT_CREATED_ASC = ['created' => 'asc'];
19
20
    /**
21
     * @var SearchServiceInterface
22
     */
23
    private $searchService;
24
25
    /**
26
     * @var string
27
     */
28
    private $sorting;
29
30
    /**
31
     * @var int
32
     */
33
    private $pageSize;
34
35
    public function __construct(
36
        SearchServiceInterface $searchService,
37
        array $sorting = null,
38
        int $pageSize = 10
39
    ) {
40
        if ($sorting === null) {
41
            $sorting = self::SORT_CREATED_ASC;
42
        }
43
44
        $this->searchService = $searchService;
45
        $this->sorting = $sorting;
0 ignored issues
show
Documentation Bug introduced by
It seems like $sorting of type array is incompatible with the declared type string of property $sorting.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
46
        $this->pageSize = $pageSize;
47
48
        // Set a default logger so we don't need to check if a logger is set
49
        // when we actually try to log something. This can easily be overridden
50
        // from outside as this method is public.
51
        $this->setLogger(new NullLogger());
52
    }
53
54
    public function withSorting(array $sorting): ResultsGenerator
55
    {
56
        $c = clone $this;
57
        $c->sorting = $sorting;
0 ignored issues
show
Documentation Bug introduced by
It seems like $sorting of type array is incompatible with the declared type string of property $sorting.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
58
        return $c;
59
    }
60
61
    public function getSorting(): array
62
    {
63
        return $this->sorting;
64
    }
65
66
    public function withPageSize(int $pageSize): ResultsGenerator
67
    {
68
        $c = clone $this;
69
        $c->pageSize = $pageSize;
70
        return $c;
71
    }
72
73
    public function getPageSize(): int
74
    {
75
        return $this->pageSize;
76
    }
77
78
    public function search(string $query): Generator
79
    {
80
        $currentPage = 0;
81
        $ids = [];
82
83
        if ($this->searchService instanceof LoggerAwareInterface) {
84
            $this->searchService->setLogger($this->logger);
85
        }
86
87
        do {
88
            $results = $this->searchService->search(
89
                $query,
90
                $this->pageSize,
91
                $this->pageSize * $currentPage,
92
                $this->sorting
0 ignored issues
show
Documentation introduced by
$this->sorting is of type string, but the function expects a null|array.

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:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
93
            );
94
95
            $total = $results->getTotalItems()->toNative();
96
97
            $this->logger->info('Search API reported ' . $total . ' results');
98
99
            foreach ($results->getItems() as $item) {
100
                $id = $item->getId();
101
102
                if (!isset($ids[$id])) {
103
                    // Store result id with current page in case we run into
104
                    // the same id again later.
105
                    $ids[$id] = $currentPage;
106
                    yield $id => $item;
107
                } else {
108
                    $this->logger->error(
109
                        'query_duplicate_event',
110
                        array(
111
                            'query' => $query,
112
                            'error' => "Found duplicate offer {$id} on page {$currentPage}, " .
113
                                "occurred first time on page {$ids[$id]}.",
114
                        )
115
                    );
116
                }
117
            }
118
119
            $currentPage++;
120
        } while ($currentPage < ceil($total / $this->pageSize));
121
    }
122
}
123