Completed
Branch master (09022f)
by Gareth
05:56 queued 03:06
created

ExchangeWebServices::setClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1
Metric Value
dl 0
loc 6
ccs 3
cts 3
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 garethp\ews\API;
7
8
use garethp\ews\API\Exception\ExchangeException;
9
use garethp\ews\API\Exception\NoResponseReturnedException;
10
use garethp\ews\API\Exception\ServiceUnavailableException;
11
use garethp\ews\API\Exception\UnauthorizedException;
12
use garethp\ews\API\Message;
13
use garethp\ews\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
    /**
122
     * @return EmailAddressType
123
     */
124 20
    public function getPrimarySmtpMailbox()
125
    {
126 20
        return $this->primarySmtpMailbox;
127
    }
128
129 1
    public function getPrimarySmtpEmailAddress()
130
    {
131 1
        if ($this->primarySmtpMailbox == null) {
132 1
            return null;
133
        }
134
135 1
        return $this->primarySmtpMailbox->getEmailAddress();
136
    }
137
138 2
    public function setPrimarySmtpEmailAddress($emailAddress)
139
    {
140 2
        $mailbox = new EmailAddressType();
141 2
        $mailbox->setEmailAddress($emailAddress);
142 2
        $this->primarySmtpMailbox = $mailbox;
143
144 2
        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 28
    public function __construct(
186
        $server = null,
187
        $username = null,
188
        $password = null,
189
        $options = []
190
    ) {
191 28
        if ($server !== null) {
192 1
            $this->createClient(
193
                $server,
194 1
                ExchangeWebServicesAuth::fromUsernameAndPassword($username, $password),
195
                $options
196
            );
197
        }
198
    }
199
200 26
    public static function fromUsernameAndPassword($server, $username, $password, $options)
201
    {
202 26
        $self = new static();
203 26
        $self->createClient($server, ExchangeWebServicesAuth::fromUsernameAndPassword($username, $password), $options);
204
205 26
        return $self;
206
    }
207
208 1
    public static function fromCallbackToken($server, $token, $options)
209
    {
210 1
        $self = new static();
211 1
        $self->createClient($server, ExchangeWebServicesAuth::fromCallbackToken($token), $options);
212
213 1
        return $self;
214
    }
215
216 28
    protected function createClient($server, $auth, $options)
217
    {
218 28
        $location = 'https://' . $this->cleanServerUrl($server) . '/EWS/Exchange.asmx';
219
220 28
        $options = array_replace_recursive([
221 28
            'version' => self::VERSION_2007,
222 28
            'trace' => 1,
223
            'exceptions' => true,
224 28
            'classmap' => ClassMap::getClassMap(),
225
            'drillDownResponses' => true
226
        ], $options);
227
228 28
        $this->soap = new NTLMSoapClient(
229
            $location,
230
            $auth,
231 28
            dirname(__FILE__) . '/../../Resources/wsdl/services.wsdl',
232
            $options
233
        );
234
235 28
        if (isset($options['primarySmtpEmailAddress'])) {
236 1
            $this->setPrimarySmtpEmailAddress($options['primarySmtpEmailAddress']);
237
        }
238
239 28
        if (isset($options['impersonation'])) {
240 1
            $this->setPrimarySmtpEmailAddress($options['impersonation']);
241
        }
242
243 28
        $this->drillDownResponses = $options['drillDownResponses'];
244
    }
245
246
    /**
247
     * @codeCoverageIgnore
248
     *
249
     * @param $name
250
     * @param $arguments
251
     * @return Type
252
     * @throws \garethp\ews\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
     *
264
     * @return NTLMSoapClient
265
     */
266 26
    public function getClient()
267
    {
268 26
        return $this->soap;
269
    }
270
271
    /**
272
     * Sets the client
273
     *
274
     * @param NTLMSoapClient $client
275
     * @return $this
276
     */
277 2
    public function setClient($client)
278
    {
279 2
        $this->soap = $client;
280
281 2
        return $this;
282
    }
283
284
    /**
285
     * Cleans the server URL for usage
286
     *
287
     * @param $server
288
     * @return string
289
     */
290 35
    public function cleanServerUrl($server)
291
    {
292 35
        $url = parse_url($server);
293 35
        if (!isset($url['host']) && isset($url['path'])) {
294 30
            $url['host'] = $url['path'];
295 30
            unset($url['path']);
296
        }
297
298 35
        $server = $url['host'];
299 35
        if (isset($url['port'])) {
300 2
            $server .= ':' . $url['port'];
301
        }
302
303 35
        if (isset($url['path'])) {
304 4
            $server .= $url['path'];
305
        }
306
307 35
        $server = rtrim($server, "/");
308
309 35
        return $server;
310
    }
311
312
    /**
313
     * Process a response to verify that it succeeded and take the appropriate
314
     * action
315
     *
316
     * @param \garethp\ews\API\Message\BaseResponseMessageType $response
317
     * @return \garethp\ews\API\Message\ArrayOfResponseMessageType|\garethp\ews\API\Message\ResponseMessageType
318
     * @throws \garethp\ews\API\Exception
319
     */
320 24
    protected function processResponse($response)
321
    {
322
        // If the soap call failed then we need to thow an exception.
323 24
        $code = $this->getClient()->getResponseCode();
324 24
        if ($code == 401) {
325
            throw new UnauthorizedException();
326
        }
327
328 24
        if ($code == 503) {
329
            throw new ServiceUnavailableException();
330
        }
331
332 24
        if ($code != 200) {
333 2
            throw new ExchangeException('SOAP client returned status of ' . $code, $code);
334
        }
335
336 22
        if (empty($response) ||
337 22
            empty($response->getNonNullResponseMessages())
338
        ) {
339
            throw new NoResponseReturnedException();
340
        }
341
342 22
        if (!$this->drillDownResponses) {
343
            return $response;
344
        }
345
346 22
        if (!$response->exists('responseMessages')) {
347
            return $response;
348
        }
349
350 22
        $response = $response->getResponseMessages();
351 22
        $response = $this->drillDownResponseLevels($response);
352
353 22
        return $response;
354
    }
355
356
    /**
357
     * @param $response
358
     * @return array
359
     * @throws \garethp\ews\API\Exception
360
     */
361 22
    public function drillDownResponseLevels($response)
362
    {
363 22
        $items = array();
364 22
        if ($response instanceof Type) {
365 22
            $items = $response->getNonNullItems();
366 1
        } elseif (is_array($response)) {
367 1
            $items = $response;
368
        }
369
370 22
        if ($response instanceof Message\ResponseMessageType) {
0 ignored issues
show
Bug introduced by
The class garethp\ews\API\Message\ResponseMessageType does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
371 22
            if ($response->getResponseClass() !== "Success") {
372 1
                throw new ExchangeException($response->getMessageText());
373
            }
374
375 22
            unset($items['responseClass']);
376 22
            unset($items['responseCode']);
377
        }
378
379 22
        if (count($items) == 1) {
380 22
            reset($items);
381 22
            $key = key($items);
382 22
            $methodName = "get$key";
383 22
            $response = $response->$methodName();
384
385 22
            $response = $this->drillDownResponseLevels($response);
386 22
        } elseif (is_array($items) && isset($items[1]) && $items[1] instanceof Message\ResponseMessageType) {
0 ignored issues
show
Bug introduced by
The class garethp\ews\API\Message\ResponseMessageType does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
387 1
            $response = array();
388 1
            foreach ($items as $responseItem) {
389 1
                $response[] = $this->drillDownResponseLevels($responseItem);
390
            }
391
        }
392
393 22
        return $response;
394
    }
395
}
396