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

Client::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
use Phpoaipmh\Exception\HttpException;
21
use Phpoaipmh\Exception\OaipmhException;
22
use Phpoaipmh\Exception\MalformedResponseException;
23
use Phpoaipmh\HttpAdapter\CurlAdapter;
24
use Phpoaipmh\HttpAdapter\GuzzleAdapter;
25
use Phpoaipmh\HttpAdapter\HttpAdapterInterface;
26
use RuntimeException;
27
28
/**
29
 * OAI-PMH Client class retrieves and decodes OAI-PMH from a given URL
30
 *
31
 * @since v1.0
32
 * @author Casey McLaughlin <[email protected]>
33
 */
34
class Client implements ClientInterface
35
{
36
    /**
37
     * @var string
38
     */
39
    private $url;
40
41
    /**
42
     * @var HttpAdapterInterface
43
     */
44
    private $httpClient;
45
46
    /**
47
     * Constructor
48
     *
49
     * @param string $url The URL of the OAI-PMH Endpoint
50
     * @param HttpAdapterInterface $httpClient Optional HTTP HttpAdapterInterface class; attempt to
51
     *                                         auto-build dependency if not passed
52
     * @throws \Exception
53
     */
54
    public function __construct($url = null, HttpAdapterInterface $httpClient = null)
55
    {
56
        $this->url = $url;
57
58
        if ($httpClient) {
59
            $this->httpClient = $httpClient;
60
        } else {
61
            $this->httpClient = (class_exists('GuzzleHttp\Client'))
62
                ? new GuzzleAdapter()
63
                : new CurlAdapter();
64
        }
65
    }
66
67
    /**
68
     * Perform a request and return a OAI SimpleXML Document
69
     *
70
     * @param  string            $verb   Which OAI-PMH verb to use
71
     * @param  array             $params An array of key/value parameters
72
     * @return \SimpleXMLElement An XML document
73
     */
74
    public function request($verb, array $params = array())
75
    {
76
        if (! $this->url) {
77
            throw new RuntimeException("Cannot perform request when URL not set.  Use setUrl() method");
78
        }
79
80
        //Build the URL
81
        $params = array_merge(array('verb' => $verb), $params);
82
        $url = $this->url . (parse_url($this->url, PHP_URL_QUERY) ? '&' : '?') . http_build_query($params);
83
84
        //Do the request
85
        try {
86
            $resp = $this->httpClient->request($url);
87
        } catch (HttpException $e) {
88
            $this->checkForOaipmhException($e);
89
            $resp = '';
90
        }
91
92
        return $this->decodeResponse($resp);
93
    }
94
95
    /**
96
     * Check for OAI-PMH Exception from HTTP Exception
97
     *
98
     * Converts a HttpException into an OAI-PMH exception if there is an
99
     * OAI-PMH Error Code.
100
     *
101
     * @param HttpException $httpException
102
     */
103
    private function checkForOaipmhException(HttpException $httpException)
104
    {
105
        try {
106
            if ($resp = $httpException->getBody()) {
107
                $this->decodeResponse($resp); // Throw OaipmhException in case of an error
108
            }
109
        } catch (MalformedResponseException $e) {
110
            // There was no valid OAI error in the response, therefore re-throw HttpException
111
        }
112
113
        throw $httpException;
114
    }
115
116
    /**
117
     * Decode the response into XML
118
     *
119
     * @param  string            $resp The response body from a HTTP request
120
     * @return \SimpleXMLElement An XML document
121
     */
122
    protected function decodeResponse($resp)
123
    {
124
        //Setup a SimpleXML Document
125
        try {
126
            $xml = @new \SimpleXMLElement($resp);
127
        } catch (\Exception $e) {
128
            throw new MalformedResponseException(sprintf("Could not decode XML Response: %s", $e->getMessage()));
129
        }
130
131
        //If we get back a OAI-PMH error, throw a OaipmhException
132
        if (isset($xml->error)) {
133
            $code = (string) $xml->error['code'];
134
            $msg  = (string) $xml->error;
135
136
            throw new OaipmhException($code, $msg);
137
        }
138
139
        return $xml;
140
    }
141
}
142