Completed
Push — master ( cefe06...98d815 )
by Casey
02:08
created

Endpoint::setUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
/**
4
 * PHPOAIPMH Library
5
 *
6
 * @license http://opensource.org/licenses/MIT
7
 * @link https://github.com/caseyamcl/phpoaipmh
8
 * @version 2.0
9
 * @package caseyamcl/phpoaipmh
10
 * @author Casey McLaughlin <[email protected]>
11
 *
12
 * For the full copyright and license information, please view the LICENSE
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
     */
46
    public static function build($url)
47
    {
48
        return new Endpoint(new Client($url));
49
    }
50
51
    /**
52
     * Constructor
53
     *
54
     * @param ClientInterface $client       Optional; will attempt to auto-build dependency if not passed
55
     * @param string          $granularity  Optional; the OAI date format for fetching records, use constants from
56
     *                                      Granularity class
57
     */
58
    public function __construct(ClientInterface $client = null, $granularity = self::AUTO)
59
    {
60
        $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...
61
        $this->granularity = $granularity;
62
    }
63
64
    /**
65
     * Identify the OAI-PMH Endpoint
66
     *
67
     * @return \SimpleXMLElement A XML document with attributes describing the repository
68
     */
69
    public function identify()
70
    {
71
        $resp = $this->client->request('Identify');
72
73
        return $resp;
74
    }
75
76
    /**
77
     * List Metadata Formats
78
     *
79
     * Return the list of supported metadata format for a particular record (if $identifier
80
     * is provided), or the entire repository (if no arguments are provided)
81
     *
82
     * @param  string         $identifier If specified, will return only those metadata formats that a particular record supports
83
     * @return RecordIteratorInterface
84
     */
85
    public function listMetadataFormats($identifier = null)
86
    {
87
        $params = ($identifier) ? array('identifier' => $identifier) : array();
88
89
        return new RecordIterator($this->client, 'ListMetadataFormats', $params);
90
    }
91
92
    /**
93
     * List Record Sets
94
     *
95
     * @return RecordIteratorInterface
96
     */
97
    public function listSets()
98
    {
99
        return new RecordIterator($this->client, 'ListSets');
100
    }
101
102
    /**
103
     * Get a single record
104
     *
105
     * @param  string            $id             Record Identifier
106
     * @param  string            $metadataPrefix Required by OAI-PMH endpoint
107
     * @return \SimpleXMLElement An XML document corresponding to the record
108
     */
109
    public function getRecord($id, $metadataPrefix)
110
    {
111
        $params = array(
112
            'identifier'     => $id,
113
            'metadataPrefix' => $metadataPrefix
114
        );
115
116
        return $this->client->request('GetRecord', $params);
117
    }
118
119
    /**
120
     * List Record identifiers
121
     *
122
     * Corresponds to OAI Verb to list record identifiers
123
     *
124
     * @param  string             $metadataPrefix Required by OAI-PMH endpoint
125
     * @param  \DateTimeInterface $from             An optional 'from' date for selective harvesting
126
     * @param  \DateTimeInterface $until            An optional 'until' date for selective harvesting
127
     * @param  string             $set              An optional setSpec for selective harvesting
128
     * @param  string             $resumptionToken  An optional resumptionToken for selective harvesting
129
     * @return RecordIteratorInterface
130
     */
131
    public function listIdentifiers($metadataPrefix, $from = null, $until = null, $set = null, $resumptionToken = null)
132
    {
133
        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 131 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 131 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...
134
    }
135
136
    /**
137
     * List Records
138
     *
139
     * Corresponds to OAI Verb to list records
140
     *
141
     * @param  string             $metadataPrefix Required by OAI-PMH endpoint
142
     * @param  \DateTimeInterface $from             An optional 'from' date for selective harvesting
143
     * @param  \DateTimeInterface $until            An optional 'from' date for selective harvesting
144
     * @param  string             $set              An optional setSpec for selective harvesting
145
     * @param  string             $resumptionToken  An optional resumptionToken for selective harvesting
146
     * @return RecordIteratorInterface
147
     */
148
    public function listRecords($metadataPrefix, $from = null, $until = null, $set = null, $resumptionToken = null)
149
    {
150
        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 148 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 148 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...
151
    }
152
153
    /**
154
     * Create a record iterator
155
     *
156
     * @param  string             $verb             OAI Verb
157
     * @param  string             $metadataPrefix   Required by OAI-PMH endpoint
158
     * @param  \DateTimeInterface $from             An optional 'from' date for selective harvesting
159
     * @param  \DateTimeInterface $until            An optional 'from' date for selective harvesting
160
     * @param  string             $set              An optional setSpec for selective harvesting
161
     * @param  string             $resumptionToken  An optional resumptionToken for selective harvesting
162
     *
163
     * @return RecordIteratorInterface
164
     */
165
    private function createRecordIterator($verb, $metadataPrefix, $from, $until, $set = null, $resumptionToken = null)
166
    {
167
        $params = array('metadataPrefix' => $metadataPrefix);
168
169
        if ($from instanceof \DateTimeInterface) {
170
            $params['from'] = Granularity::formatDate($from, $this->getGranularity());
171
        } elseif (null !== $from) {
172
            throw new \InvalidArgumentException(sprintf(
173
                '%s::%s $from parameter must be an instance of \DateTimeInterface',
174
                get_called_class(),
175
                'createRecordIterator'
176
            ));
177
        }
178
179
        if ($until instanceof \DateTimeInterface) {
180
            $params['until'] = Granularity::formatDate($until, $this->getGranularity());
181
        } elseif (null !== $until) {
182
            throw new \InvalidArgumentException(sprintf(
183
                '%s::%s $until parameter must be an instance of \DateTimeInterface',
184
                get_called_class(),
185
                'createRecordIterator'
186
            ));
187
        }
188
189
        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...
190
            $params['set'] = $set;
191
        }
192
193
        return new RecordIterator($this->client, $verb, $params, $resumptionToken);
194
    }
195
196
    /**
197
     * Lazy load granularity from Identify, if not specified
198
     *
199
     * @return string
200
     */
201
    private function getGranularity()
202
    {
203
        if ($this->granularity === null) {
204
            $this->granularity = $this->fetchGranularity();
205
        }
206
207
        return $this->granularity;
208
    }
209
210
    /**
211
     * Attempt to fetch date format from Identify endpoint (or use default)
212
     *
213
     * @return string
214
     */
215
    private function fetchGranularity()
216
    {
217
        $response = $this->identify();
218
219
        return (isset($response->Identify->granularity))
220
            ? (string) $response->Identify->granularity
221
            : Granularity::DATE;
222
    }
223
}
224