Completed
Push — master ( c12050...bcb499 )
by Dan Michael O.
03:24
created

Users::findOne()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Scriptotek\Alma\Users;
4
5
use Scriptotek\Alma\Model\ReadOnlyArrayAccess;
6
use Scriptotek\Alma\Client;
7
use Scriptotek\Alma\Exception\InvalidQuery;
8
9
/**
10
 * Non-iterable collection of User resources.
11
 */
12
class Users implements \ArrayAccess
13
{
14
    use ReadOnlyArrayAccess;
15
16
    /* @var Client */
17
    protected $client;
18
19
    public function __construct(Client $client)
20
    {
21
        $this->client = $client;
22
    }
23
24
    /**
25
     * Get a User object by id.
26
     *
27
     * @param $user_id int
28
     * @param $params array Additional query string parameters
29
     * @return User
30
     */
31
    public function get($user_id, $params = [])
32
    {
33
        return User::make($this->client, $user_id)
34
            ->setParams($params);
35
    }
36
37
    /**
38
     * Get the first user matching a given query, or NULL if not found.
39
     *
40
     * @param string $query
41
     * @param array $options
42
     * @return User|null
43
     */
44
    public function findOne($query, array $options = [])
45
    {
46
        return $this->search($query, $options)->current();
47
    }
48
49
    /**
50
     * Iterates over all users matching the given query.
51
     * Handles continuation.
52
     * @param string $query
53
     * @param array $options
54
     * @return \Generator
55
     */
56
    public function search($query, array $options = [])
57
    {
58
        // Max number of records to fetch. Set to 0 to fetch all.
59
        $limit = array_key_exists('limit', $options) ? $options['limit'] : 0;
60
61
        // Set to true to do a phrase search
62
        $phrase = array_key_exists('phrase', $options) ? $options['phrase'] : false;
63
64
        // Set to true to expand all query results to full records.
65
        // Please note that this will make queries significantly slower!
66
        $expand = array_key_exists('expand', $options) ? $options['expand'] : false;
67
68
        // Number of records to fetch each batch. Usually no need to change this.
69
        $batchSize = array_key_exists('batchSize', $options) ? $options['batchSize'] : 10;
70
71
        if ($limit != 0 && $limit < $batchSize) {
72
            $batchSize = $limit;
73
        }
74
75
        // The API will throw a 400 response if you include properly encoded spaces,
76
        // but underscores work as a substitute.
77
        $query = explode(' AND ', $query);
78
        $query = $phrase ? str_replace(' ', '_', $query) : str_replace(' ', ',', $query);
79
        $query = implode(' AND ', $query);
80
81
        $offset = 0;
82
        while (true) {
83
            $response = $this->client->getJSON('/users', ['q' => $query, 'limit' => $batchSize, 'offset' => $offset]);
84
85
            // The API sometimes returns total_record_count: -1, with no further error message.
86
            // Seems to indicate that the query was not understood.
87
            // See: https://github.com/scriptotek/php-alma-client/issues/8
88
            if ($response->total_record_count == -1) {
89
                throw new InvalidQuery($query);
90
            }
91
92
            if ($response->total_record_count == 0) {
93
                break;
94
            }
95
96
            if (!isset($response->user)) {
97
                // We cannot trust the value in 'total_record_count', so if there are no more records,
98
                // we have to assume the result set is depleted.
99
                // See: https://github.com/scriptotek/php-alma-client/issues/7
100
                break;
101
            }
102
103
            foreach ($response->user as $data) {
104
                // Contacts without a primary identifier will have the primary_id
105
                // field populated with something weird like "no primary id (123456789023)".
106
                // We ignore those.
107
                // See: https://github.com/scriptotek/php-alma-client/issues/6
108
                if (strpos($data->primary_id, 'no primary id') === 0) {
109
                    continue;
110
                }
111
                $user = User::make($this->client, $data->primary_id)
112
                    ->init($data);
113
                if ($expand) {
114
                    $user->init();
115
                }
116
                yield $user;
117
                $offset++;
118
            }
119
            if ($offset >= $response->total_record_count) {
120
                break;
121
            }
122
            if ($limit != 0 && $offset >= $limit) {
123
                break;
124
            }
125
        }
126
    }
127
}
128