Completed
Push — master ( 9cb577...7778bf )
by Casey
02:36
created

Endpoint::fetchGranularity()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
/**
4
 * PHPOAIPMH Library
5
 *
6
 * @license http://opensource.org/licenses/MIT
7
 * @link https://github.com/caseyamcl/phpoaipmh
8
 * @version 3.0
9
 * @package caseyamcl/phpoaipmh
10
 * @author Casey McLaughlin <[email protected]>
11
 *
12
 * For the full copyright and license information, -please view the LICENSE.md
13
 * file that was distributed with this source code.
14
 *
15
 * ------------------------------------------------------------------
16
 */
17
18
namespace Phpoaipmh;
19
20
/**
21
 * OAI-PMH Endpoint Class
22
 *
23
 * @since v1.0
24
 * @author Casey McLaughlin <[email protected]>
25
 */
26
class Endpoint implements EndpointInterface
27
{
28
    const AUTO = null;
29
30
    /**
31
     * @var Client
32
     */
33
    private $client;
34
35
    /**
36
     * @var string
37
     */
38
    private $granularity;
39
40
    /**
41
     * Build endpoint using URL and default settings
42
     *
43
     * @param string $url
44
     * @return Endpoint
45
     * @throws \Exception
46
     */
47
    public static function build($url)
48
    {
49
        return new Endpoint(new Client($url));
50
    }
51
52
    /**
53
     * Constructor
54
     *
55
     * @param ClientInterface $client       Optional; will attempt to auto-build dependency if not passed
56
     * @param string          $granularity  Optional; the OAI date format for fetching records, use constants from
57
     *                                      Granularity class
58
     * @throws \Exception
59
     */
60
    public function __construct(ClientInterface $client = null, $granularity = self::AUTO)
61
    {
62
        $this->client = $client ?: new Client();
0 ignored issues
show
Documentation Bug introduced by
$client ?: new \Phpoaipmh\Client() is of type object<Phpoaipmh\ClientInterface>, but the property $client was declared to be of type object<Phpoaipmh\Client>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
63
        $this->granularity = $granularity;
64
    }
65
66
    /**
67
     * Identify the OAI-PMH Endpoint
68
     *
69
     * @return \SimpleXMLElement A XML document with attributes describing the repository
70
     */
71
    public function identify()
72
    {
73
        $resp = $this->client->request('Identify');
74
75
        return $resp;
76
    }
77
78
    /**
79
     * List Metadata Formats
80
     *
81
     * Return the list of supported metadata format for a particular record (if $identifier
82
     * is provided), or the entire repository (if no arguments are provided)
83
     *
84
     * @param  string  $identifier If specified, will return only those metadata formats that a
85
     *                             particular record supports
86
     * @return RecordIteratorInterface
87
     */
88
    public function listMetadataFormats($identifier = null)
89
    {
90
        $params = ($identifier) ? array('identifier' => $identifier) : array();
91
92
        return new RecordIterator($this->client, 'ListMetadataFormats', $params);
93
    }
94
95
    /**
96
     * List Record Sets
97
     *
98
     * @return RecordIteratorInterface
99
     */
100
    public function listSets()
101
    {
102
        return new RecordIterator($this->client, 'ListSets');
103
    }
104
105
    /**
106
     * Get a single record
107
     *
108
     * @param  string            $id             Record Identifier
109
     * @param  string            $metadataPrefix Required by OAI-PMH endpoint
110
     * @return \SimpleXMLElement An XML document corresponding to the record
111
     */
112
    public function getRecord($id, $metadataPrefix)
113
    {
114
        $params = array(
115
            'identifier'     => $id,
116
            'metadataPrefix' => $metadataPrefix
117
        );
118
119
        return $this->client->request('GetRecord', $params);
120
    }
121
122
    /**
123
     * List Record identifiers
124
     *
125
     * Corresponds to OAI Verb to list record identifiers
126
     *
127
     * @param  string             $metadataPrefix Required by OAI-PMH endpoint
128
     * @param  \DateTimeInterface $from             An optional 'from' date for selective harvesting
129
     * @param  \DateTimeInterface $until            An optional 'until' date for selective harvesting
130
     * @param  string             $set              An optional setSpec for selective harvesting
131
     * @param  string             $resumptionToken  An optional resumptionToken for selective harvesting
132
     * @return RecordIteratorInterface
133
     */
134
    public function listIdentifiers($metadataPrefix, $from = null, $until = null, $set = null, $resumptionToken = null)
135
    {
136
        return $this->createRecordIterator("ListIdentifiers", $metadataPrefix, $from, $until, $set, $resumptionToken);
0 ignored issues
show
Bug introduced by
It seems like $from defined by parameter $from on line 134 can be null; however, Phpoaipmh\Endpoint::createRecordIterator() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
Bug introduced by
It seems like $until defined by parameter $until on line 134 can be null; however, Phpoaipmh\Endpoint::createRecordIterator() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
137
    }
138
139
    /**
140
     * List Records
141
     *
142
     * Corresponds to OAI Verb to list records
143
     *
144
     * @param  string             $metadataPrefix Required by OAI-PMH endpoint
145
     * @param  \DateTimeInterface $from             An optional 'from' date for selective harvesting
146
     * @param  \DateTimeInterface $until            An optional 'from' date for selective harvesting
147
     * @param  string             $set              An optional setSpec for selective harvesting
148
     * @param  string             $resumptionToken  An optional resumptionToken for selective harvesting
149
     * @return RecordIteratorInterface
150
     */
151
    public function listRecords($metadataPrefix, $from = null, $until = null, $set = null, $resumptionToken = null)
152
    {
153
        return $this->createRecordIterator("ListRecords", $metadataPrefix, $from, $until, $set, $resumptionToken);
0 ignored issues
show
Bug introduced by
It seems like $from defined by parameter $from on line 151 can be null; however, Phpoaipmh\Endpoint::createRecordIterator() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
Bug introduced by
It seems like $until defined by parameter $until on line 151 can be null; however, Phpoaipmh\Endpoint::createRecordIterator() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
154
    }
155
156
    /**
157
     * Create a record iterator
158
     *
159
     * @param  string             $verb             OAI Verb
160
     * @param  string             $metadataPrefix   Required by OAI-PMH endpoint
161
     * @param  \DateTimeInterface $from             An optional 'from' date for selective harvesting
162
     * @param  \DateTimeInterface $until            An optional 'from' date for selective harvesting
163
     * @param  string             $set              An optional setSpec for selective harvesting
164
     * @param  string             $resumptionToken  An optional resumptionToken for selective harvesting
165
     *
166
     * @return RecordIteratorInterface
167
     */
168
    private function createRecordIterator($verb, $metadataPrefix, $from, $until, $set = null, $resumptionToken = null)
169
    {
170
        $params = array('metadataPrefix' => $metadataPrefix);
171
172
        if ($from instanceof \DateTimeInterface) {
173
            $params['from'] = Granularity::formatDate($from, $this->getGranularity());
174
        } elseif (null !== $from) {
175
            throw new \InvalidArgumentException(sprintf(
176
                '%s::%s $from parameter must be an instance of \DateTimeInterface',
177
                get_called_class(),
178
                'createRecordIterator'
179
            ));
180
        }
181
182
        if ($until instanceof \DateTimeInterface) {
183
            $params['until'] = Granularity::formatDate($until, $this->getGranularity());
184
        } elseif (null !== $until) {
185
            throw new \InvalidArgumentException(sprintf(
186
                '%s::%s $until parameter must be an instance of \DateTimeInterface',
187
                get_called_class(),
188
                'createRecordIterator'
189
            ));
190
        }
191
192
        if ($set) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $set of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
193
            $params['set'] = $set;
194
        }
195
196
        return new RecordIterator($this->client, $verb, $params, $resumptionToken);
197
    }
198
199
    /**
200
     * Lazy load granularity from Identify, if not specified
201
     *
202
     * @return string
203
     */
204
    private function getGranularity()
205
    {
206
        // If the granularity is not specified, attempt to retrieve it from the server
207
        // Fall back on DATE granularity
208
        if ($this->granularity === null) {
209
            $response = $this->identify();
210
            return (isset($response->Identify->granularity))
211
                ? (string) $response->Identify->granularity
212
                : Granularity::DATE;
213
        }
214
215
        return $this->granularity;
216
    }
217
}
218