Completed
Push — master ( 6be563...93587f )
by Gareth
03:22
created

ExchangeWebServices::setClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 6
ccs 1
cts 1
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * Contains ExchangeWebServices.
4
 */
5
6
namespace jamesiarmes\PEWS\API;
7
8
use jamesiarmes\PEWS\API\Exception\ExchangeException;
9
use jamesiarmes\PEWS\API\Exception\NoResponseReturnedException;
10
use jamesiarmes\PEWS\API\Exception\ServiceUnavailableException;
11
use jamesiarmes\PEWS\API\Exception\UnauthorizedException;
12
use jamesiarmes\PEWS\API\Message;
13
use jamesiarmes\PEWS\API\Type\EmailAddressType;
14
15
/**
16
 * Base class of the Exchange Web Services application.
17
 *
18
 * @package php-ews\Client
19
 *
20
 * @method Type CreateItem($request)
21
 * @method Type FindItem($request)
22
 * @method Type GetFolder($request)
23
 * @method Type SyncFolderItems($request)
24
 * @method Type FindFolder($request)
25
 * @method Type UpdateItem($request)
26
 * @method Type DeleteItem($request)
27
 * @method Type GetItem($request)
28
 */
29
class ExchangeWebServices
30
{
31
    /**
32
     * Microsoft Exchange 2007
33
     *
34
     * @var string
35
     */
36
    const VERSION_2007 = 'Exchange2007';
37
38
    /**
39
     * Microsoft Exchange 2007 SP1
40
     *
41
     * @var string
42
     */
43
    const VERSION_2007_SP1 = 'Exchange2007_SP1';
44
45
    /**
46
     * Microsoft Exchange 2007 SP2
47
     *
48
     * @var string
49
     */
50
    const VERSION_2007_SP2 = 'Exchange2007_SP2';
51
52
    /**
53
     * Microsoft Exchange 2007 SP3
54
     *
55
     * @var string
56
     */
57
    const VERSION_2007_SP3 = 'Exchange2007_SP3';
58
59
    /**
60
     * Microsoft Exchange 2010
61
     *
62
     * @var string
63
     */
64
    const VERSION_2010 = 'Exchange2010';
65
66
    /**
67
     * Microsoft Exchange 2010 SP1
68
     *
69
     * @var string
70
     */
71
    const VERSION_2010_SP1 = 'Exchange2010_SP1';
72
73
    /**
74
     * Microsoft Exchange 2010 SP2
75
     *
76
     * @var string
77
     */
78
    const VERSION_2010_SP2 = 'Exchange2010_SP2';
79
80
    /**
81
     * Password to use when connecting to the Exchange server.
82
     *
83
     * @var string
84
     */
85
    protected $password;
86
87
    /**
88
     * Location of the Exchange server.
89
     *
90
     * @var string
91
     */
92
    protected $server;
93
94
    /**
95
     * SOAP client used to make the request
96
     *
97
     * @var NTLMSoapClient
98
     */
99
    protected $soap;
100
101
    /**
102
     * Username to use when connecting to the Exchange server.
103
     *
104
     * @var string
105
     */
106
    protected $username;
107
108
    /**
109
     * @var EmailAddressType
110
     */
111
    protected $primarySmtpMailbox;
112
113
    /**
114
     * A setting to check whether or not responses should be drilled down before being returned. Setting this to false
115
     * will return the raw responses without any filtering
116
     *
117
     * @var bool
118
     */
119
    protected $drillDownResponses = true;
120
121 16
    /**
122
     * @return EmailAddressType
123 16
     */
124
    public function getPrimarySmtpMailbox()
125
    {
126 1
        return $this->primarySmtpMailbox;
127
    }
128 1
129 1
    public function getPrimarySmtpEmailAddress()
130
    {
131
        if ($this->primarySmtpMailbox == null) {
132 1
            return null;
133
        }
134
135 1
        return $this->primarySmtpMailbox->getEmailAddress();
136
    }
137 1
138 1
    public function setPrimarySmtpEmailAddress($emailAddress)
139 1
    {
140
        $mailbox = new EmailAddressType();
141 1
        $mailbox->setEmailAddress($emailAddress);
142
        $this->primarySmtpMailbox = $mailbox;
143
144
        return $this;
145
    }
146
147
    /**
148
     * Miscrosoft Exchange version that we are going to connect to
149
     *
150
     * @var string
151
     *
152
     * @see ExchangeWebServices::VERSION_2007
153
     * @see ExchangeWebServices::VERSION_2007_SP1
154
     * @see ExchangeWebServices::VERSION_2010
155
     * @see ExchangeWebServices::VERSION_2010_SP1
156
     */
157
    protected $version;
158
159
    protected $options;
160
161
    /**
162
     * The timezone for the client
163
     *
164
     * @var bool
165
     */
166
    protected $timezone = false;
167
168
    /**
169
     * @param boolean $timezone
170
     */
171
    public function setTimezone($timezone)
172
    {
173
        $this->timezone = $timezone;
174
    }
175
176
    /**
177
     * Constructor for the ExchangeWebServices class
178
     *
179
     * @deprecated Since 0.6.3
180
     * @param string $server
181
     * @param string $username
182
     * @param string $password
183
     * @param array $options
184
     */
185
    public function __construct(
186
        $server = null,
187
        $username = null,
188
        $password = null,
189
        $options = []
190
    ) {
191
        if ($server !== null) {
192
            $this->createClient(
193
                $server,
194
                ExchangeWebServicesAuth::fromUsernameAndPassword($username, $password),
195
                $options
196
            );
197 22
        }
198
    }
199 22
200 22
    public static function fromUsernameAndPassword($server, $username, $password, $options)
201
    {
202 22
        $self = new static();
203
        $self->createClient($server, ExchangeWebServicesAuth::fromUsernameAndPassword($username, $password), $options);
204
205 1
        return $self;
206
    }
207 1
208 1
    public static function fromCallbackToken($server, $token, $options)
209
    {
210 1
        $self = new static();
211
        $self->createClient($server, ExchangeWebServicesAuth::fromCallbackToken($token), $options);
212
213 25
        return $self;
214
    }
215 25
216
    protected function createClient($server, $auth, $options)
217 25
    {
218 25
        $location = 'https://' . $this->cleanServerUrl($server) . '/EWS/Exchange.asmx';
219 25
220 25
        $options = array_replace_recursive([
221 25
            'version' => self::VERSION_2007,
222
            'trace' => 1,
223 25
            'exceptions' => true,
224
            'classmap' => ClassMap::getClassMap(),
225 25
            'drillDownResponses' => true
226 25
        ], $options);
227 25
228 25
        $this->soap = new NTLMSoapClient(
229
            $location,
230 25
            $auth,
231
            dirname(__FILE__) . '/../../Resources/wsdl/services.wsdl',
232 25
            $options
233 1
        );
234 1
235
        if (isset($options['primarySmtpEmailAddress'])) {
236 25
            $this->setPrimarySmtpEmailAddress($options['primarySmtpEmailAddress']);
237 1
        }
238 1
239
        if (isset($options['impersonation'])) {
240 25
            $this->setPrimarySmtpEmailAddress($options['impersonation']);
241 25
        }
242
243
        $this->drillDownResponses = $options['drillDownResponses'];
244
    }
245
246
    /**
247
     * @codeCoverageIgnore
248
     *
249
     * @param $name
250
     * @param $arguments
251
     * @return Type
252
     * @throws \jamesiarmes\PEWS\API\Exception
253
     */
254
    public function __call($name, $arguments)
255
    {
256
        $response = $this->getClient()->__call($name, $arguments);
257
258
        return $this->processResponse($response);
259
    }
260
261
    /**
262
     * Returns the SOAP Client that may be used to make calls against the server
263 21
     *
264
     * @return NTLMSoapClient
265 21
     */
266
    public function getClient()
267
    {
268
        return $this->soap;
269
    }
270
271
    /**
272
     * Sets the client
273
     *
274 2
     * @param NTLMSoapClient $client
275
     * @return $this
276 2
     */
277
    public function setClient($client)
278 2
    {
279
        $this->soap = $client;
280
281
        return $this;
282
    }
283
284
    /**
285
     * Cleans the server URL for usage
286
     *
287 32
     * @param $server
288
     * @return string
289 32
     */
290 32
    public function cleanServerUrl($server)
291 27
    {
292 27
        $url = parse_url($server);
293 27
        if (!isset($url['host']) && isset($url['path'])) {
294
            $url['host'] = $url['path'];
295 32
            unset($url['path']);
296 32
        }
297 2
298 2
        $server = $url['host'];
299
        if (isset($url['port'])) {
300 32
            $server .= ':' . $url['port'];
301 4
        }
302 4
303
        if (isset($url['path'])) {
304 32
            $server .= $url['path'];
305
        }
306 32
307
        $server = rtrim($server, "/");
308
309
        return $server;
310
    }
311
312
    /**
313
     * Process a response to verify that it succeeded and take the appropriate
314
     * action
315
     *
316
     * @param \jamesiarmes\PEWS\API\Message\BaseResponseMessageType $response
317
     * @return \jamesiarmes\PEWS\API\Message\ArrayOfResponseMessageType|\jamesiarmes\PEWS\API\Message\ResponseMessageType
318 20
     * @throws \jamesiarmes\PEWS\API\Exception
319
     */
320
    protected function processResponse($response)
321 20
    {
322 20
        // If the soap call failed then we need to thow an exception.
323 2
        $code = $this->getClient()->getResponseCode();
324
        if ($code == 401) {
325
            throw new UnauthorizedException();
326 18
        }
327 18
328 18
        if ($code == 503) {
329
            throw new ServiceUnavailableException();
330
        }
331
332 18
        if ($code != 200) {
333
            throw new ExchangeException('SOAP client returned status of ' . $code, $code);
334
        }
335
336 18
        if (empty($response) ||
337
            empty($response->getNonNullResponseMessages())
338
        ) {
339
            throw new NoResponseReturnedException();
340 18
        }
341 18
342
        if (!$this->drillDownResponses) {
343 18
            return $response;
344
        }
345
346
        if (!$response->exists('responseMessages')) {
347
            return $response;
348
        }
349
350
        $response = $response->getResponseMessages();
351 18
        $response = $this->drillDownResponseLevels($response);
352
353 18
        return $response;
354 18
    }
355 18
356 18
    /**
357 1
     * @param $response
358 1
     * @return array
359
     * @throws \jamesiarmes\PEWS\API\Exception
360 18
     */
361 18
    public function drillDownResponseLevels($response)
362 1
    {
363
        $items = array();
364
        if ($response instanceof Type) {
365 18
            $items = $response->getNonNullItems();
366 18
        } elseif (is_array($response)) {
367 18
            $items = $response;
368
        }
369 18
370 18
        if ($response instanceof Message\ResponseMessageType) {
371 18
            if ($response->getResponseClass() !== "Success") {
372 18
                throw new ExchangeException($response->getMessageText());
373 18
            }
374
375 18
            unset($items['responseClass']);
376 18
            unset($items['responseCode']);
377 1
        }
378 1
379 1
        if (count($items) == 1) {
380 1
            reset($items);
381 1
            $key = key($items);
382
            $methodName = "get$key";
383 18
            $response = $response->$methodName();
384
385
            $response = $this->drillDownResponseLevels($response);
386
        } elseif (is_array($items) && isset($items[1]) && $items[1] instanceof Message\ResponseMessageType) {
387
            $response = array();
388
            foreach ($items as $responseItem) {
389
                $response[] = $this->drillDownResponseLevels($responseItem);
390
            }
391
        }
392
393
        return $response;
394
    }
395
}
396