Completed
Push — master ( ab1148...78a8ff )
by Christopher
02:58
created

Connection   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 456
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 35
c 4
b 0
f 0
lcom 1
cbo 2
dl 0
loc 456
rs 9

28 Methods

Rating   Name   Duplication   Size   Complexity  
A open() 0 11 2
A connect() 0 17 3
A close() 0 7 2
A executeQuery() 0 21 4
A execute() 0 8 1
A getBound() 0 4 1
A getResource() 0 4 1
A sort() 0 4 1
A add() 0 4 1
A delete() 0 4 1
A rename() 0 4 1
A modify() 0 4 1
A modifyBatch() 0 4 1
A modAdd() 0 4 1
A modReplace() 0 4 1
A modDelete() 0 4 1
A getEntries() 0 4 1
A countEntries() 0 4 1
A getFirstEntry() 0 4 1
A getNextEntry() 0 4 1
A getAttributes() 0 4 1
A setOption() 0 4 1
A startTLS() 0 4 1
A setControlPagedResult() 0 5 1
A setControlPagedResultResponse() 0 4 1
A getLastError() 0 4 1
A getErrNo() 0 4 1
A err2Str() 0 4 1
1
<?php
2
/**
3
 * @link      https://github.com/chrmorandi/yii2-ldap for the canonical source repository
4
 * @package   yii2-ldap
5
 * @author    Christopher Mota <[email protected]>
6
 * @license   MIT License - view the LICENSE file that was distributed with this source code.
7
 */
8
9
namespace chrmorandi\ldap;
10
11
use yii\base\Component;
12
13
/**
14
 * @property resource $resource
15
 * @property boolean  $bount
16
 * @property int      $errNo Error number of the last command
17
 * @property string   $lastError Error message of the last command
18
 *
19
 * @author Christopher Mota <[email protected]>
20
 * @since 1.0
21
 */
22
class Connection extends Component
23
{
24
    /**
25
     * LDAP protocol string.
26
     * @var string
27
     */
28
    const PROTOCOL = 'ldap://';
29
30
    /**
31
     * LDAP port number.
32
     * @var string
33
     */
34
    const PORT = '389';
35
36
    /**
37
     * @event Event an event that is triggered after a DB connection is established
38
     */
39
    const EVENT_AFTER_OPEN = 'afterOpen';
40
41
    /**
42
     * @var string the LDAP base dn.
43
     */
44
    public $baseDn;
45
46
    /**
47
     * https://msdn.microsoft.com/en-us/library/ms677913(v=vs.85).aspx
48
     * @var bool the integer to instruct the LDAP connection whether or not to follow referrals.
49
     */
50
    public $followReferrals = false;
51
52
    /**
53
     * @var string The LDAP port to use when connecting to the domain controllers.
54
     */
55
    public $port = self::PORT;
56
57
    /**
58
     * @var bool Determines whether or not to use TLS with the current LDAP connection.
59
     */
60
    public $useTLS = false;
61
62
    /**
63
     * @var array the domain controllers to connect to.
64
     */
65
    public $dc = [];
66
    
67
    /**
68
     * @var string the username for establishing LDAP connection. Defaults to `null` meaning no username to use.
69
     */
70
    public $username;
71
72
    /**
73
     * @var string the password for establishing DB connection. Defaults to `null` meaning no password to use.
74
     */
75
    public $password;
76
    
77
    /**
78
     * @var int The page size for the paging operation.
79
     */
80
    public $pageSize = -1;
81
    
82
    /**
83
     * @var integer zero-based offset from where the records are to be returned. If not set or
84
     * less than 1, it means not filter values.
85
     */
86
    public $offset = -1;
87
    
88
    /**
89
     * @var boolean whether to enable caching.
90
     * Note that in order to enable truly caching, a valid cache component as specified
91
     * by [[cache]] must be enabled and [[enableCache]] must be set true.
92
     * @see cacheDuration
93
     * @see cache
94
     */
95
    public $enableCache = false;
96
    
97
    /**
98
     * @var integer number of seconds that table metadata can remain valid in cache.
99
     * Use 0 to indicate that the cached data will never expire.
100
     * @see enableCache
101
     */
102
    public $cacheDuration = 3600;
103
104
    /**
105
     * @var Cache|string the cache object or the ID of the cache application component that
106
     * is used to cache result query.
107
     * @see enableCache
108
     */
109
    public $cache = 'cache';
110
111
    /**
112
     * @var string the LDAP account suffix.
113
     */
114
    protected $accountSuffix;
115
116
    /**
117
     * @var string the LDAP account prefix.
118
     */
119
    protected $accountPrefix;
120
121
    /**
122
     * @var bool stores the bool whether or not the current connection is bound.
123
     */
124
    protected $_bound = false;
125
126
    /**
127
     * @var resource|false
128
     */
129
    protected $resource;
130
    
131
132
    /**
133
     * Connects and Binds to the Domain Controller with a administrator credentials.
134
     * @return void
135
     */
136
    protected function open($anonymous = false)
137
    {
138
        // Connect to the LDAP server.
139
        $this->connect($this->dc, $this->port);
140
141
        if ($anonymous) {               
142
            $this->_bound = ldap_bind($this->resource);
143
        } else {
144
            $this->_bound = ldap_bind($this->resource, $this->username, $this->password);
145
        }
146
    }
147
148
    /**
149
     * Connection.
150
     * @param string|array $hostname
151
     * @param type $port
152
     * @return void
153
     */
154
    public function connect($hostname = [], $port = '389')
155
    {
156
        if (is_array($hostname)) {
157
            $hostname = self::PROTOCOL.implode(' '.self::PROTOCOL, $hostname);
158
        }
159
160
        $this->resource = ldap_connect($hostname, $port);
161
162
        // Set the LDAP options.     
163
        $this->setOption(LDAP_OPT_PROTOCOL_VERSION, 3);
164
        $this->setOption(LDAP_OPT_REFERRALS, $this->followReferrals);
165
        if ($this->useTLS) {
166
            $this->startTLS();
167
        }
168
169
        $this->trigger(self::EVENT_AFTER_OPEN);
170
    }
171
    
172
    /**
173
     * Closes the current connection.
174
     *
175
     * @return boolean
176
     */
177
    public function close()
178
    {
179
        if (is_resource($this->resource)) {
180
            ldap_close($this->resource);
181
        }
182
        return true;
183
    }
184
185
    /**
186
     * Execute ldap functions like.
187
     *
188
     * http://php.net/manual/en/ref.ldap.php
189
     *
190
     * @param  string $function php LDAP function
191
     * @param  array $params params for execute ldap function
192
     * @return bool|DataReader
193
     */
194
    public function executeQuery($function, $params)
195
    {
196
        $this->open();
197
        $results = [];
198
        $cookie = '';
199
        
200
        do {
201
            $this->setControlPagedResult($cookie);
202
203
            $result = call_user_func($function, $this->resource, ...$params);
204
205
            $this->setControlPagedResultResponse($result, $cookie);
206
            $results[] = $result;            
207
        } while ($cookie !== null && $cookie != '');        
208
209
        if($this->offset > 0){
210
            $results = $results[intval($this->offset/$this->pageSize -1)];
211
        }
212
        
213
        return new DataReader($this, $results);
214
    }
215
    
216
    /**
217
     * Execute ldap functions like.
218
     *
219
     * http://php.net/manual/en/ref.ldap.php
220
     *
221
     * @param  string $function php LDAP function
222
     * @param  array $params params for execute ldap function
223
     * @return bool|DataReader
224
     */
225
    public function execute($function, $params)
226
    {
227
        $this->open();
228
229
        $result = call_user_func($function, $this->resource, ...$params);
230
231
        return $result;
232
    }
233
    
234
    /**
235
     * Returns true/false if the current connection is bound.
236
     * @return bool
237
     */
238
    public function getBound()
239
    {
240
        return $this->_bound;
241
    }
242
    
243
    /**
244
     * Get the current resource of connection.
245
     * @return resource
246
     */
247
    public function getResource()
248
    {
249
        return $this->resource;
250
    }
251
    
252
    /**
253
     * Sorts an AD search result by the specified attribute.
254
     * @param resource $result
255
     * @param string   $attribute
256
     * @return bool
257
     */
258
    public function sort($result, $attribute)
259
    {
260
        return ldap_sort($this->resource, $result, $attribute);
261
    }
262
263
    /**
264
     * Adds an entry to the current connection.
265
     * @param string $dn
266
     * @param array  $entry
267
     * @return bool
268
     */
269
    public function add($dn, array $entry)
270
    {
271
        return ldap_add($this->resource, $dn, $entry);
272
    }
273
274
    /**
275
     * Deletes an entry on the current connection.
276
     * @param string $dn
277
     * @return bool
278
     */
279
    public function delete($dn)
280
    {
281
        return ldap_delete($this->resource, $dn);
282
    }
283
284
    /**
285
     * Modify the name of an entry on the current connection.
286
     *
287
     * @param string $dn
288
     * @param string $newRdn
289
     * @param string $newParent
290
     * @param bool   $deleteOldRdn
291
     * @return bool
292
     */
293
    public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false)
294
    {
295
        return ldap_rename($this->resource, $dn, $newRdn, $newParent, $deleteOldRdn);
296
    }
297
298
    /**
299
     * Modifies an existing entry on the
300
     * current connection.
301
     * @param string $dn
302
     * @param array  $entry
303
     * @return bool
304
     */
305
    public function modify($dn, array $entry)
306
    {
307
        return ldap_modify($this->resource, $dn, $entry);
308
    }
309
310
    /**
311
     * Batch modifies an existing entry on the current connection.
312
     * @param string $dn
313
     * @param array  $values
314
     * @return mixed
315
     */
316
    public function modifyBatch($dn, array $values)
317
    {
318
        return ldap_modify_batch($this->resource, $dn, $values);
319
    }
320
321
    /**
322
     * Add attribute values to current attributes.
323
     * @param string $dn
324
     * @param array  $entry
325
     * @return boolean
326
     */
327
    public function modAdd($dn, array $entry)
328
    {
329
        return ldap_mod_add($this->resource, $dn, $entry);
330
    }
331
332
    /**
333
     * Replaces attribute values with new ones.
334
     * @param string $dn
335
     * @param array  $entry
336
     * @return boolean
337
     */
338
    public function modReplace($dn, array $entry)
339
    {
340
        return ldap_mod_replace($this->resource, $dn, $entry);
341
    }
342
343
    /**
344
     * Delete attribute values from current attributes.
345
     * @param string $dn
346
     * @param array  $entry
347
     * @return boolean
348
     */
349
    public function modDelete($dn, array $entry)
350
    {
351
        return ldap_mod_del($this->resource, $dn, $entry);
352
    }
353
    
354
    /**
355
     * Retrieve the entries from a search result.
356
     * @param resource $searchResult
357
     * @return array|boolean
358
     */
359
    public function getEntries($searchResult)
360
    {
361
        return ldap_get_entries($this->resource, $searchResult);
362
    }
363
    
364
    /**
365
     * Returns the number of entries from a search result.
366
     * @param resource $searchResult
367
     * @return int
368
     */
369
    public function countEntries($searchResult)
370
    {
371
        return ldap_count_entries($this->resource, $searchResult);
372
    }
373
374
    /**
375
     * Retrieves the first entry from a search result.
376
     * @param resource $searchResult
377
     * @return resource
378
     */
379
    public function getFirstEntry($searchResult)
380
    {
381
        return ldap_first_entry($this->resource, $searchResult);
382
    }
383
384
    /**
385
     * Retrieves the next entry from a search result.
386
     * @param $entry
387
     * @return resource
388
     */
389
    public function getNextEntry($entry)
390
    {
391
        return ldap_next_entry($this->resource, $entry);
392
    }
393
394
    /**
395
     * Retrieves the ldap entry's attributes.
396
     * @param $entry
397
     * @return mixed
398
     */
399
    public function getAttributes($entry)
400
    {
401
        return ldap_get_attributes($this->resource, $entry);
402
    }
403
404
    /**
405
     * Sets an option on the current connection.
406
     * @param int   $option
407
     * @param mixed $value
408
     * @return boolean
409
     */
410
    public function setOption($option, $value)
411
    {
412
        return ldap_set_option($this->resource, $option, $value);
413
    }
414
    
415
    /**
416
     * Starts a connection using TLS.
417
     * @return bool
418
     */
419
    public function startTLS()
420
    {
421
        return ldap_start_tls($this->resource);
422
    }
423
    
424
    /**
425
     * Send LDAP pagination control.
426
     *
427
     * @param int    $pageSize
0 ignored issues
show
Bug introduced by
There is no parameter named $pageSize. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
428
     * @param bool   $isCritical
0 ignored issues
show
Bug introduced by
There is no parameter named $isCritical. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
429
     * @param string $cookie
430
     * @return bool
431
     */
432
    public function setControlPagedResult($cookie)
433
    {
434
        return ldap_control_paged_result($this->resource, $this->pageSize, false, $cookie);
435
436
    }
437
438
    /**
439
     * Retrieve a paginated result response.
440
     *
441
     * @param resource $result
442
     * @param string $cookie
443
     * @return bool
444
     */
445
    public function setControlPagedResultResponse($result, &$cookie)
446
    {
447
        return @ldap_control_paged_result_response($this->resource, $result, $cookie);
448
    }
449
       
450
    /**
451
     * Retrieve the last error on the current connection.
452
     * @return string
453
     */
454
    public function getLastError()
455
    {
456
        return ldap_error($this->resource);
457
    }
458
    
459
    /**
460
     * Returns the number of the last error on the current connection.
461
     * @return int
462
     */
463
    public function getErrNo()
464
    {
465
        return ldap_errno($this->resource);
466
    }
467
468
    /**
469
     * Returns the error string of the specified error number.
470
     * @param int $number
471
     * @return string
472
     */
473
    public function err2Str($number)
474
    {
475
        return ldap_err2str($number);
476
    }
477
}
478