Completed
Push — master ( 373634...d97c97 )
by Casey
02:52
created

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