SearchProvider::extractTotalMatches()
last analyzed

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
ccs 0
cts 0
cp 0
c 0
b 0
f 0
nc 1
1
<?php
2
3
namespace Radowoj\Searcher\SearchProvider;
4
5
use stdClass;
6
use Radowoj\Searcher\SearchResult\Collection;
7
use Radowoj\Searcher\SearchResult\ICollection;
8
use Radowoj\Searcher\SearchResult\IItem;
9
10
abstract class SearchProvider implements ISearchProvider
11
{
12
13
    /**
14
     * Performs a search request and returns result as stdClass (json-decoded search API response)
15
     * @param  string    $query  search query
16
     * @param  int       $limit  number of results (API may not support it)
17
     * @param  int       $offset offset of results (again, API may not support it, but most APIs do)
18
     * @return stdClass - json-decoded response from API
19
     */
20
    abstract protected function searchRequest(string $query, int $limit, int $offset) : stdClass;
21
22
23
    /**
24
     * Checks response object for fields necessary to populate a collection
25
     * @param  stdClass API response
26
     * @throws Exception on invalid response
27
     */
28
    abstract protected function validateRequestResult(stdClass $result);
29
30
31
    /**
32
     * Usually API will ignore our limit, so we must take care of it
33
     * @param  stdClass $result to modify
34
     * @param  int       $limit  limit to enforce
35
     * @return stdClass - result after enforcing limit
36
     */
37
    abstract protected function enforceLimit(stdClass $result, int $limit) : stdClass;
38
39
    /**
40
     * Creates a search result item from API-specific stdClass representing single search result
41
     * @param  stdClass $item Single stdClass representing search result, fetched from search API
42
     * @return IItem          Radowoj\Searcher\SearchResult\IItem  Single search result item
43
     */
44
    abstract protected function populateItem(stdClass $item) : IItem;
45
46
47
    /**
48
     * Extracts results array from API-specific response object
49
     * @param  stdClass $result Response object fetched from API
50
     * @return array array of stdClasses representing results
51
     */
52
    abstract protected function extractResults(stdClass $result) : array;
53
54
55
    /**
56
     * Extracts total matches from API-specific response object
57
     * @param  stdClass $result Response object fetched from API
58
     * @return int total number of results
59
     */
60
    abstract protected function extractTotalMatches(stdClass $result) : int;
61
62
63
    /**
64
     * Performs and processes a search request
65
     * @param  string       $query  Search query
66
     * @param  integer      $limit  Result limit (API may return other amount, so result will be truncated)
67
     * @param  integer      $offset Result offset
68
     * @return Radowoj\Searcher\SearchResult\ICollection  Collection of results
69
     */
70 20
    public function search(string $query, int $limit = 100, int $offset = 0) : ICollection
71
    {
72 20
        $requestResult = $this->searchRequest($query, $limit, $offset);
73
74 15
        $this->validateRequestResult($requestResult);
75
76 13
        $requestResult = $this->enforceLimit($requestResult, $limit);
77
78 13
        return $this->populateCollection($requestResult);
79
    }
80
81
82
    /**
83
     * Populates result collection. Concrete class must provide methods to populate a single item,
84
     * extract results list from result object and extract total matches from result object
85
     * @param  stdClass    $result result object from search api
86
     * @return Radowoj\Searcher\SearchResult\ICollection  Collection of results
87
     */
88
    protected function populateCollection(stdClass $result) : ICollection
89
    {
90 13
        $results = array_map(function($item) {
91 2
            return $this->populateItem($item);
92
93 13
        }, $this->extractResults($result));
94
95 13
        return new Collection(
96
            $results,
97 13
            $this->extractTotalMatches($result)
98
        );
99
    }
100
101
}
102