Completed
Push — master ( 78a8ff...f55562 )
by Christopher
02:55
created

Connection::getFirstAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 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
     * Returns true/false if the current connection is bound.
218
     * @return bool
219
     */
220
    public function getBound()
221
    {
222
        return $this->_bound;
223
    }
224
    
225
    /**
226
     * Get the current resource of connection.
227
     * @return resource
228
     */
229
    public function getResource()
230
    {
231
        return $this->resource;
232
    }
233
    
234
    /**
235
     * Sorts an AD search result by the specified attribute.
236
     * @param resource $result
237
     * @param string   $attribute
238
     * @return bool
239
     */
240
    public function sort($result, $attribute)
241
    {
242
        return ldap_sort($this->resource, $result, $attribute);
243
    }
244
245
    /**
246
     * Adds an entry to the current connection.
247
     * @param string $dn
248
     * @param array  $entry
249
     * @return bool
250
     */
251
    public function add($dn, array $entry)
252
    {
253
        return ldap_add($this->resource, $dn, $entry);
254
    }
255
256
    /**
257
     * Deletes an entry on the current connection.
258
     * @param string $dn
259
     * @return bool
260
     */
261
    public function delete($dn)
262
    {
263
        return ldap_delete($this->resource, $dn);
264
    }
265
266
    /**
267
     * Modify the name of an entry on the current connection.
268
     *
269
     * @param string $dn
270
     * @param string $newRdn
271
     * @param string $newParent
272
     * @param bool   $deleteOldRdn
273
     * @return bool
274
     */
275
    public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false)
276
    {
277
        return ldap_rename($this->resource, $dn, $newRdn, $newParent, $deleteOldRdn);
278
    }
279
280
    /**
281
     * Batch modifies an existing entry on the current connection.
282
     * The types of modifications:
283
     *      LDAP_MODIFY_BATCH_ADD - Each value specified through values is added.
284
     *      LDAP_MODIFY_BATCH_REMOVE - Each value specified through values is removed. 
285
     *          Any value of the attribute not contained in the values array will remain untouched.
286
     *      LDAP_MODIFY_BATCH_REMOVE_ALL - All values are removed from the attribute named by attrib.
287
     *      LDAP_MODIFY_BATCH_REPLACE - All current values are replaced by new one.
288
     * @param string $dn
289
     * @param array  $values array associative with three keys: "attrib", "modtype" and "values".
290
     * ```php
291
     * [
292
     *     "attrib"  => "attribute",
293
     *     "modtype" => LDAP_MODIFY_BATCH_ADD,
294
     *     "values"  => ["attribute value one"],
295
     * ],
296
     * ```
297
     * @return mixed
298
     */
299
    public function modify($dn, array $values)
300
    {
301
        return ldap_modify_batch($this->resource, $dn, $values);
302
    }    
303
    
304
    /**
305
     * Retrieve the entries from a search result.
306
     * @param resource $searchResult
307
     * @return array|boolean
308
     */
309
    public function getEntries($searchResult)
310
    {
311
        return ldap_get_entries($this->resource, $searchResult);
312
    }
313
    
314
    /**
315
     * Retrieves the number of entries from a search result.
316
     * @param resource $searchResult
317
     * @return int
318
     */
319
    public function countEntries($searchResult)
320
    {
321
        return ldap_count_entries($this->resource, $searchResult);
322
    }
323
324
    /**
325
     * Retrieves the first entry from a search result.
326
     * @param resource $searchResult
327
     * @return resource link identifier
328
     */
329
    public function getFirstEntry($searchResult)
330
    {
331
        return ldap_first_entry($this->resource, $searchResult);
332
    }
333
334
    /**
335
     * Retrieves the next entry from a search result.
336
     * @param resource $entry link identifier
337
     * @return resource
338
     */
339
    public function getNextEntry($entry)
340
    {
341
        return ldap_next_entry($this->resource, $entry);
342
    }
343
    
344
    /**
345
     * Retrieves the ldap first entry attribute.
346
     * @param resource $entry
347
     * @return string
348
     */
349
    public function getFirstAttribute($entry)
350
    {
351
        return ldap_first_attribute($this->resource, $entry);
352
    }
353
    
354
    /**
355
     * Retrieves the ldap next entry attribute.
356
     * @param resource $entry
357
     * @return string
358
     */
359
    public function getNextAttribute($entry)
360
    {
361
        return ldap_next_attribute($this->resource, $entry);
362
    }
363
364
    /**
365
     * Retrieves the ldap entry's attributes.
366
     * @param resource $entry
367
     * @return array
368
     */
369
    public function getAttributes($entry)
370
    {
371
        return ldap_get_attributes($this->resource, $entry);
372
    }
373
    
374
    /**
375
     * Retrieves all binary values from a result entry.
376
     * @param resource $entry link identifier
377
     * @param string $attribute name of attribute
378
     * @return array
379
     */
380
    public function getValuesLen($entry, $attribute)
381
    {
382
        return ldap_get_values_len($this->resource, $entry, $attribute);
383
    }
384
    
385
    /**
386
     * Retrieves the DN of a result entry.
387
     * @param resource $entry
388
     * @return string
389
     */
390
    public function getDn($entry)
391
    {
392
        return ldap_get_dn($this->resource, $entry);
393
    }
394
395
    /**
396
     * Free result memory.
397
     * @param resource $searchResult
398
     * @return bool
399
     */
400
    public function freeResult($searchResult)
401
    {
402
        return ldap_free_result($searchResult);
403
    }
404
405
    /**
406
     * Sets an option on the current connection.
407
     * @param int   $option
408
     * @param mixed $value
409
     * @return boolean
410
     */
411
    public function setOption($option, $value)
412
    {
413
        return ldap_set_option($this->resource, $option, $value);
414
    }
415
416
    /**
417
     * Starts a connection using TLS.
418
     * @return bool
419
     */
420
    public function startTLS()
421
    {
422
        return ldap_start_tls($this->resource);
423
    }
424
    
425
    /**
426
     * Send LDAP pagination control.
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
     * Retrieve a paginated result response.
439
     * @param resource $result
440
     * @param string $cookie
441
     * @return bool
442
     */
443
    public function setControlPagedResultResponse($result, &$cookie)
444
    {
445
        return ldap_control_paged_result_response($this->resource, $result, $cookie);
446
    }
447
       
448
    /**
449
     * Retrieve the last error on the current connection.
450
     * @return string
451
     */
452
    public function getLastError()
453
    {
454
        return ldap_error($this->resource);
455
    }
456
    
457
    /**
458
     * Returns the number of the last error on the current connection.
459
     * @return int
460
     */
461
    public function getErrNo()
462
    {
463
        return ldap_errno($this->resource);
464
    }
465
466
    /**
467
     * Returns the error string of the specified error number.
468
     * @param int $number
469
     * @return string
470
     */
471
    public function err2Str($number)
472
    {
473
        return ldap_err2str($number);
474
    }
475
}
476