Completed
Push — master ( 198ef6...d4d4ec )
by Christopher
02:36
created

Connection::modReplace()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 2
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 string $errNo Error number of the last command
15
 *
16
 * @author Christopher Mota <[email protected]>
17
 * @since 1.0
18
 */
19
class Connection extends Component
20
{
21
    /**
22
     * LDAP protocol string.
23
     * @var string
24
     */
25
    const PROTOCOL = 'ldap://';
26
27
    /**
28
     * LDAP port number.
29
     * @var string
30
     */
31
    const PORT = '389';
32
33
    /**
34
     * @event Event an event that is triggered after a DB connection is established
35
     */
36
    const EVENT_AFTER_OPEN = 'afterOpen';
37
38
    /**
39
     * @var string the LDAP base dn.
40
     */
41
    public $baseDn;
42
43
    /**
44
     * https://msdn.microsoft.com/en-us/library/ms677913(v=vs.85).aspx
45
     * @var bool the integer to instruct the LDAP connection whether or not to follow referrals.
46
     */
47
    public $followReferrals = false;
48
49
    /**
50
     * @var string The LDAP port to use when connecting to the domain controllers.
51
     */
52
    public $port = self::PORT;
53
54
    /**
55
     * @var bool Determines whether or not to use TLS with the current LDAP connection.
56
     */
57
    public $useTLS = false;
58
59
    /**
60
     * @var array the domain controllers to connect to.
61
     */
62
    public $dc = [];
63
64
    /**
65
     * @var string the LDAP account suffix.
66
     */
67
    protected $accountSuffix;
68
69
    /**
70
     * @var string the LDAP account prefix.
71
     */
72
    protected $accountPrefix;
73
74
    /**
75
     * @var string the username for establishing LDAP connection. Defaults to `null` meaning no username to use.
76
     */
77
    public $username;
78
79
    /**
80
     * @var string the password for establishing DB connection. Defaults to `null` meaning no password to use.
81
     */
82
    public $password;
83
84
    /**
85
     * @var bool stores the bool whether or not the current connection is bound.
86
     */
87
    protected $bound = false;
88
89
    /**
90
     * @var resource
91
     */
92
    protected $resource;
93
94
    /**
95
     * Get the current resource of connection.
96
     * @return mixed
97
     */
98
    public function getResource()
99
    {
100
        return $this->resource;
101
    }
102
103
    /**
104
     * Connects and Binds to the Domain Controller with a administrator credentials.
105
     * @throws LdapException
106
     */
107
    public function open($anonymous = false)
108
    {
109
        // Connect to the LDAP server.
110
        if ($this->connect($this->dc, $this->port)) {
111
            if ($anonymous) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
112
                //TODO
113
            } else {
114
                $this->bound = ldap_bind($this->resource, $this->username, $this->password);
115
            }
116
        } else {
117
            throw new LdapException(sprintf('Unable to connect to server: %s', $this->lastError), $this->errNo);
0 ignored issues
show
Documentation introduced by
The property lastError does not exist on object<chrmorandi\ldap\Connection>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
118
        }
119
    }
120
121
    /**
122
     * Returns true/false if the current connection is bound.
123
     * @return bool
124
     */
125
    public function isBound()
126
    {
127
        return $this->bound;
128
    }
129
130
    /**
131
     * Connection.
132
     * @param string $hostname
133
     * @param type $port
134
     * @return boolean
135
     * @throws LdapException
136
     */
137
    public function connect($hostname = [], $port = '389')
138
    {
139
        $protocol = $this::PROTOCOL;
140
141
        if (is_array($hostname)) {
142
            $hostname = $protocol . implode(' ' . $protocol, $hostname);
143
        }
144
        $this->resource = ldap_connect($hostname, $port);
145
146
        if (!$this->resource) {
147
            return false;
148
        }
149
150
        // Set the LDAP options.
151
        $this->setOption(LDAP_OPT_PROTOCOL_VERSION, 3);
152
        $this->setOption(LDAP_OPT_REFERRALS, $followReferrals);
0 ignored issues
show
Bug introduced by
The variable $followReferrals does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
153
154
        if ($this->useTLS && !$this->startTLS()) {
155
            throw new LdapException($this->lastError, $this->getErrNo());
0 ignored issues
show
Documentation introduced by
The property lastError does not exist on object<chrmorandi\ldap\Connection>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
156
        }
157
158
        $this->trigger(self::EVENT_AFTER_OPEN);
159
160
        return is_resource($this->resource);
161
    }
162
163
    /**
164
     * Closes the current connection.
165
     *
166
     * @return boolean
167
     */
168
    public function close()
169
    {
170
        if (is_resource($this->resource)) {
171
            ldap_close($this->resource);
172
        }
173
        return true;
174
    }
175
176
    /**
177
     * Execute ldap functions like.
178
     *
179
     * http://php.net/manual/en/ref.ldap.php
180
     *
181
     * @param  string $function php LDAP function
182
     * @param  array $params params for execute ldap function
183
     * @return bool|DataReader
184
     * @throws LdapException
185
     */
186
    public function execute($function, $params)
187
    {
188
        $this->open();
189
190
        $result = call_user_func($function, $this->resource, ...$params);
191
        if (!$result) {
192
            throw new LdapException($this->getLastError(), $this->getErrNo());
193
        }
194
195
        if (is_resource($result)) {
196
            return new DataReader($this, $result);
197
        }
198
199
        return $result;
200
    }
201
202
    /**
203
     * Close the connection before serializing.
204
     * @return array
205
     */
206
    public function __sleep()
207
    {
208
        $this->close();
209
        return array_keys((array) $this);
210
    }
211
    
212
    /**
213
     * Sorts an AD search result by the specified attribute.
214
     * @param resource $result
215
     * @param string   $attribute
216
     * @return bool
217
     */
218
    public function sort($result, $attribute)
219
    {
220
        return ldap_sort($this->resource, $result, $attribute);
221
    }
222
223
    /**
224
     * Adds an entry to the current connection.
225
     * @param string $dn
226
     * @param array  $entry
227
     * @return bool
228
     */
229
    public function add($dn, array $entry)
230
    {
231
        return ldap_add($this->resource, $dn, $entry);
232
    }
233
234
    /**
235
     * Deletes an entry on the current connection.
236
     * @param string $dn
237
     * @return bool
238
     */
239
    public function delete($dn)
240
    {
241
        return ldap_delete($this->resource, $dn);
242
    }
243
244
    /**
245
     * Modify the name of an entry on the current connection.
246
     *
247
     * @param string $dn
248
     * @param string $newRdn
249
     * @param string $newParent
250
     * @param bool   $deleteOldRdn
251
     * @return bool
252
     */
253
    public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false)
254
    {
255
        return ldap_rename($this->resource, $dn, $newRdn, $newParent, $deleteOldRdn);
256
    }
257
258
    /**
259
     * Modifies an existing entry on the
260
     * current connection.
261
     * @param string $dn
262
     * @param array  $entry
263
     * @return bool
264
     */
265
    public function modify($dn, array $entry)
266
    {
267
        return ldap_modify($this->resource, $dn, $entry);
268
    }
269
270
    /**
271
     * Batch modifies an existing entry on the current connection.
272
     * @param string $dn
273
     * @param array  $values
274
     * @return mixed
275
     */
276
    public function modifyBatch($dn, array $values)
277
    {
278
        return ldap_modify_batch($this->resource, $dn, $values);
279
    }
280
281
     /**
282
     * Add attribute values to current attributes.
283
     * @param string $dn
284
     * @param array  $entry
285
     * @return mixed
286
     */
287
    public function modAdd($dn, array $entry)
288
    {
289
        return ldap_mod_add($this->resource, $dn, $entry);
290
    }
291
292
    /**
293
     * Replaces attribute values with new ones.
294
     * @param string $dn
295
     * @param array  $entry
296
     * @return mixed
297
     */
298
    public function modReplace($dn, array $entry)
299
    {
300
        return ldap_mod_replace($this->resource, $dn, $entry);
301
    }
302
303
    /**
304
     * Delete attribute values from current attributes.
305
     * @param string $dn
306
     * @param array  $entry
307
     * @return mixed
308
     */
309
    public function modDelete($dn, array $entry)
310
    {
311
        return ldap_mod_del($this->resource, $dn, $entry);
312
    }
313
    
314
    /**
315
     * Retrieve the entries from a search result.
316
     * @param $searchResult
317
     * @return mixed
318
     */
319
    public function getEntries($searchResult)
320
    {
321
        return ldap_get_entries($this->resource, $searchResult);
322
    }
323
    
324
    /**
325
     * Returns the number of entries from a search result.
326
     * @param $searchResult
327
     * @return int
328
     */
329
    public function countEntries($searchResult)
330
    {
331
        return ldap_count_entries($this->resource, $searchResult);
332
    }
333
334
    /**
335
     * Retrieves the first entry from a search result.
336
     * @param $searchResult
337
     * @return mixed
338
     */
339
    public function getFirstEntry($searchResult)
340
    {
341
        return ldap_first_entry($this->resource, $searchResult);
342
    }
343
344
    /**
345
     * Retrieves the next entry from a search result.
346
     * @param $entry
347
     * @return mixed
348
     */
349
    public function getNextEntry($entry)
350
    {
351
        return ldap_next_entry($this->resource, $entry);
352
    }
353
354
    /**
355
     * Retrieves the ldap entry's attributes.
356
     * @param $entry
357
     * @return mixed
358
     */
359
    public function getAttributes($entry)
360
    {
361
        return ldap_get_attributes($this->resource, $entry);
362
    }
363
364
    /**
365
     * Sets an option on the current connection.
366
     * @param int   $option
367
     * @param mixed $value
368
     * @return mixed
369
     */
370
    public function setOption($option, $value)
371
    {
372
        return ldap_set_option($this->resource, $option, $value);
373
    }
374
    
375
    /**
376
     * Starts a connection using TLS.
377
     * @return bool
378
     */
379
    public function startTLS()
380
    {
381
        return ldap_start_tls($this->resource);
382
    }
383
       
384
    /**
385
     * Retrieve the last error on the current connection.
386
     * @return string
387
     */
388
    public function getLastError()
389
    {
390
        return ldap_error($this->resource);
391
    }
392
    
393
    /**
394
     * Returns the number of the last error on the current connection.
395
     * @return mixed
396
     */
397
    public function getErrNo()
398
    {
399
        return ldap_errno($this->resource);
400
    }
401
402
    /**
403
     * Returns the error string of the specified error number.
404
     * @param int $number
405
     * @return string
406
     */
407
    public function err2Str($number)
408
    {
409
        return ldap_err2str($number);
410
    }
411
}
412