|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Ldap |
|
17 * @subpackage Node |
|
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
20 * @version $Id: Abstract.php 20096 2010-01-06 02:05:09Z bkarwin $ |
|
21 */ |
|
22 |
|
23 /** |
|
24 * @see Zend_Ldap_Attribute |
|
25 */ |
|
26 require_once 'Zend/Ldap/Attribute.php'; |
|
27 /** |
|
28 * @see Zend_Ldap_Dn |
|
29 */ |
|
30 require_once 'Zend/Ldap/Dn.php'; |
|
31 |
|
32 /** |
|
33 * Zend_Ldap_Node_Abstract provides a bas eimplementation for LDAP nodes |
|
34 * |
|
35 * @category Zend |
|
36 * @package Zend_Ldap |
|
37 * @subpackage Node |
|
38 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
39 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
40 */ |
|
41 abstract class Zend_Ldap_Node_Abstract implements ArrayAccess, Countable |
|
42 { |
|
43 protected static $_systemAttributes=array('createtimestamp', 'creatorsname', |
|
44 'entrycsn', 'entrydn', 'entryuuid', 'hassubordinates', 'modifiersname', |
|
45 'modifytimestamp', 'structuralobjectclass', 'subschemasubentry', |
|
46 'distinguishedname', 'instancetype', 'name', 'objectcategory', 'objectguid', |
|
47 'usnchanged', 'usncreated', 'whenchanged', 'whencreated'); |
|
48 |
|
49 /** |
|
50 * Holds the node's DN. |
|
51 * |
|
52 * @var Zend_Ldap_Dn |
|
53 */ |
|
54 protected $_dn; |
|
55 |
|
56 /** |
|
57 * Holds the node's current data. |
|
58 * |
|
59 * @var array |
|
60 */ |
|
61 protected $_currentData; |
|
62 |
|
63 /** |
|
64 * Constructor. |
|
65 * |
|
66 * Constructor is protected to enforce the use of factory methods. |
|
67 * |
|
68 * @param Zend_Ldap_Dn $dn |
|
69 * @param array $data |
|
70 * @param boolean $fromDataSource |
|
71 */ |
|
72 protected function __construct(Zend_Ldap_Dn $dn, array $data, $fromDataSource) |
|
73 { |
|
74 $this->_dn = $dn; |
|
75 $this->_loadData($data, $fromDataSource); |
|
76 } |
|
77 |
|
78 /** |
|
79 * @param array $data |
|
80 * @param boolean $fromDataSource |
|
81 * @throws Zend_Ldap_Exception |
|
82 */ |
|
83 protected function _loadData(array $data, $fromDataSource) |
|
84 { |
|
85 if (array_key_exists('dn', $data)) { |
|
86 unset($data['dn']); |
|
87 } |
|
88 ksort($data, SORT_STRING); |
|
89 $this->_currentData = $data; |
|
90 } |
|
91 |
|
92 /** |
|
93 * Reload node attributes from LDAP. |
|
94 * |
|
95 * This is an online method. |
|
96 * |
|
97 * @param Zend_Ldap $ldap |
|
98 * @return Zend_Ldap_Node_Abstract Provides a fluid interface |
|
99 * @throws Zend_Ldap_Exception |
|
100 */ |
|
101 public function reload(Zend_Ldap $ldap = null) |
|
102 { |
|
103 if ($ldap !== null) { |
|
104 $data = $ldap->getEntry($this->_getDn(), array('*', '+'), true); |
|
105 $this->_loadData($data, true); |
|
106 } |
|
107 return $this; |
|
108 } |
|
109 |
|
110 /** |
|
111 * Gets the DN of the current node as a Zend_Ldap_Dn. |
|
112 * |
|
113 * This is an offline method. |
|
114 * |
|
115 * @return Zend_Ldap_Dn |
|
116 */ |
|
117 protected function _getDn() |
|
118 { |
|
119 return $this->_dn; |
|
120 } |
|
121 |
|
122 /** |
|
123 * Gets the DN of the current node as a Zend_Ldap_Dn. |
|
124 * The method returns a clone of the node's DN to prohibit modification. |
|
125 * |
|
126 * This is an offline method. |
|
127 * |
|
128 * @return Zend_Ldap_Dn |
|
129 */ |
|
130 public function getDn() |
|
131 { |
|
132 $dn = clone $this->_getDn(); |
|
133 return $dn; |
|
134 } |
|
135 |
|
136 /** |
|
137 * Gets the DN of the current node as a string. |
|
138 * |
|
139 * This is an offline method. |
|
140 * |
|
141 * @param string $caseFold |
|
142 * @return string |
|
143 */ |
|
144 public function getDnString($caseFold = null) |
|
145 { |
|
146 return $this->_getDn()->toString($caseFold); |
|
147 } |
|
148 |
|
149 /** |
|
150 * Gets the DN of the current node as an array. |
|
151 * |
|
152 * This is an offline method. |
|
153 * |
|
154 * @param string $caseFold |
|
155 * @return array |
|
156 */ |
|
157 public function getDnArray($caseFold = null) |
|
158 { |
|
159 return $this->_getDn()->toArray($caseFold); |
|
160 } |
|
161 |
|
162 /** |
|
163 * Gets the RDN of the current node as a string. |
|
164 * |
|
165 * This is an offline method. |
|
166 * |
|
167 * @param string $caseFold |
|
168 * @return string |
|
169 */ |
|
170 public function getRdnString($caseFold = null) |
|
171 { |
|
172 return $this->_getDn()->getRdnString($caseFold); |
|
173 } |
|
174 |
|
175 /** |
|
176 * Gets the RDN of the current node as an array. |
|
177 * |
|
178 * This is an offline method. |
|
179 * |
|
180 * @param string $caseFold |
|
181 * @return array |
|
182 */ |
|
183 public function getRdnArray($caseFold = null) |
|
184 { |
|
185 return $this->_getDn()->getRdn($caseFold); |
|
186 } |
|
187 |
|
188 /** |
|
189 * Gets the objectClass of the node |
|
190 * |
|
191 * @return array |
|
192 */ |
|
193 public function getObjectClass() |
|
194 { |
|
195 return $this->getAttribute('objectClass', null); |
|
196 } |
|
197 |
|
198 /** |
|
199 * Gets all attributes of node. |
|
200 * |
|
201 * The collection contains all attributes. |
|
202 * |
|
203 * This is an offline method. |
|
204 * |
|
205 * @param boolean $includeSystemAttributes |
|
206 * @return array |
|
207 */ |
|
208 public function getAttributes($includeSystemAttributes = true) |
|
209 { |
|
210 $data = array(); |
|
211 foreach ($this->getData($includeSystemAttributes) as $name => $value) { |
|
212 $data[$name] = $this->getAttribute($name, null); |
|
213 } |
|
214 return $data; |
|
215 } |
|
216 |
|
217 /** |
|
218 * Returns the DN of the current node. {@see getDnString()} |
|
219 * |
|
220 * @return string |
|
221 */ |
|
222 public function toString() |
|
223 { |
|
224 return $this->getDnString(); |
|
225 } |
|
226 |
|
227 /** |
|
228 * Cast to string representation {@see toString()} |
|
229 * |
|
230 * @return string |
|
231 */ |
|
232 public function __toString() |
|
233 { |
|
234 return $this->toString(); |
|
235 } |
|
236 |
|
237 /** |
|
238 * Returns an array representation of the current node |
|
239 * |
|
240 * @param boolean $includeSystemAttributes |
|
241 * @return array |
|
242 */ |
|
243 public function toArray($includeSystemAttributes = true) |
|
244 { |
|
245 $attributes = $this->getAttributes($includeSystemAttributes); |
|
246 return array_merge(array('dn' => $this->getDnString()), $attributes); |
|
247 } |
|
248 |
|
249 /** |
|
250 * Returns a JSON representation of the current node |
|
251 * |
|
252 * @param boolean $includeSystemAttributes |
|
253 * @return string |
|
254 */ |
|
255 public function toJson($includeSystemAttributes = true) |
|
256 { |
|
257 return json_encode($this->toArray($includeSystemAttributes)); |
|
258 } |
|
259 |
|
260 /** |
|
261 * Gets node attributes. |
|
262 * |
|
263 * The array contains all attributes in its internal format (no conversion). |
|
264 * |
|
265 * This is an offline method. |
|
266 * |
|
267 * @param boolean $includeSystemAttributes |
|
268 * @return array |
|
269 */ |
|
270 public function getData($includeSystemAttributes = true) |
|
271 { |
|
272 if ($includeSystemAttributes === false) { |
|
273 $data = array(); |
|
274 foreach ($this->_currentData as $key => $value) { |
|
275 if (!in_array($key, self::$_systemAttributes)) { |
|
276 $data[$key] = $value; |
|
277 } |
|
278 } |
|
279 return $data; |
|
280 } else { |
|
281 return $this->_currentData; |
|
282 } |
|
283 } |
|
284 |
|
285 /** |
|
286 * Checks whether a given attribute exists. |
|
287 * |
|
288 * If $emptyExists is false empty attributes (containing only array()) are |
|
289 * treated as non-existent returning false. |
|
290 * If $emptyExists is true empty attributes are treated as existent returning |
|
291 * true. In this case method returns false only if the attribute name is |
|
292 * missing in the key-collection. |
|
293 * |
|
294 * @param string $name |
|
295 * @param boolean $emptyExists |
|
296 * @return boolean |
|
297 */ |
|
298 public function existsAttribute($name, $emptyExists = false) |
|
299 { |
|
300 $name = strtolower($name); |
|
301 if (isset($this->_currentData[$name])) { |
|
302 if ($emptyExists) return true; |
|
303 return count($this->_currentData[$name])>0; |
|
304 } |
|
305 else return false; |
|
306 } |
|
307 |
|
308 /** |
|
309 * Checks if the given value(s) exist in the attribute |
|
310 * |
|
311 * @param string $attribName |
|
312 * @param mixed|array $value |
|
313 * @return boolean |
|
314 */ |
|
315 public function attributeHasValue($attribName, $value) |
|
316 { |
|
317 return Zend_Ldap_Attribute::attributeHasValue($this->_currentData, $attribName, $value); |
|
318 } |
|
319 |
|
320 /** |
|
321 * Gets a LDAP attribute. |
|
322 * |
|
323 * This is an offline method. |
|
324 * |
|
325 * @param string $name |
|
326 * @param integer $index |
|
327 * @return mixed |
|
328 * @throws Zend_Ldap_Exception |
|
329 */ |
|
330 public function getAttribute($name, $index = null) |
|
331 { |
|
332 if ($name == 'dn') { |
|
333 return $this->getDnString(); |
|
334 } |
|
335 else { |
|
336 return Zend_Ldap_Attribute::getAttribute($this->_currentData, $name, $index); |
|
337 } |
|
338 } |
|
339 |
|
340 /** |
|
341 * Gets a LDAP date/time attribute. |
|
342 * |
|
343 * This is an offline method. |
|
344 * |
|
345 * @param string $name |
|
346 * @param integer $index |
|
347 * @return array|integer |
|
348 * @throws Zend_Ldap_Exception |
|
349 */ |
|
350 public function getDateTimeAttribute($name, $index = null) |
|
351 { |
|
352 return Zend_Ldap_Attribute::getDateTimeAttribute($this->_currentData, $name, $index); |
|
353 } |
|
354 |
|
355 /** |
|
356 * Sets a LDAP attribute. |
|
357 * |
|
358 * This is an offline method. |
|
359 * |
|
360 * @param string $name |
|
361 * @param mixed $value |
|
362 * @return null |
|
363 * @throws BadMethodCallException |
|
364 */ |
|
365 public function __set($name, $value) |
|
366 { |
|
367 throw new BadMethodCallException(); |
|
368 } |
|
369 |
|
370 /** |
|
371 * Gets a LDAP attribute. |
|
372 * |
|
373 * This is an offline method. |
|
374 * |
|
375 * @param string $name |
|
376 * @return array |
|
377 * @throws Zend_Ldap_Exception |
|
378 */ |
|
379 public function __get($name) |
|
380 { |
|
381 return $this->getAttribute($name, null); |
|
382 } |
|
383 |
|
384 /** |
|
385 * Deletes a LDAP attribute. |
|
386 * |
|
387 * This method deletes the attribute. |
|
388 * |
|
389 * This is an offline method. |
|
390 * |
|
391 * @param string $name |
|
392 * @return null |
|
393 * @throws BadMethodCallException |
|
394 */ |
|
395 public function __unset($name) |
|
396 { |
|
397 throw new BadMethodCallException(); |
|
398 } |
|
399 |
|
400 /** |
|
401 * Checks whether a given attribute exists. |
|
402 * |
|
403 * Empty attributes will be treated as non-existent. |
|
404 * |
|
405 * @param string $name |
|
406 * @return boolean |
|
407 */ |
|
408 public function __isset($name) |
|
409 { |
|
410 return $this->existsAttribute($name, false); |
|
411 } |
|
412 |
|
413 /** |
|
414 * Sets a LDAP attribute. |
|
415 * Implements ArrayAccess. |
|
416 * |
|
417 * This is an offline method. |
|
418 * |
|
419 * @param string $name |
|
420 * @param mixed $value |
|
421 * @return null |
|
422 * @throws BadMethodCallException |
|
423 */ |
|
424 public function offsetSet($name, $value) |
|
425 { |
|
426 throw new BadMethodCallException(); |
|
427 } |
|
428 |
|
429 /** |
|
430 * Gets a LDAP attribute. |
|
431 * Implements ArrayAccess. |
|
432 * |
|
433 * This is an offline method. |
|
434 * |
|
435 * @param string $name |
|
436 * @return array |
|
437 * @throws Zend_Ldap_Exception |
|
438 */ |
|
439 public function offsetGet($name) |
|
440 { |
|
441 return $this->getAttribute($name, null); |
|
442 } |
|
443 |
|
444 /** |
|
445 * Deletes a LDAP attribute. |
|
446 * Implements ArrayAccess. |
|
447 * |
|
448 * This method deletes the attribute. |
|
449 * |
|
450 * This is an offline method. |
|
451 * |
|
452 * @param string $name |
|
453 * @return null |
|
454 * @throws BadMethodCallException |
|
455 */ |
|
456 public function offsetUnset($name) |
|
457 { |
|
458 throw new BadMethodCallException(); |
|
459 } |
|
460 |
|
461 /** |
|
462 * Checks whether a given attribute exists. |
|
463 * Implements ArrayAccess. |
|
464 * |
|
465 * Empty attributes will be treated as non-existent. |
|
466 * |
|
467 * @param string $name |
|
468 * @return boolean |
|
469 */ |
|
470 public function offsetExists($name) |
|
471 { |
|
472 return $this->existsAttribute($name, false); |
|
473 } |
|
474 |
|
475 /** |
|
476 * Returns the number of attributes in node. |
|
477 * Implements Countable |
|
478 * |
|
479 * @return int |
|
480 */ |
|
481 public function count() |
|
482 { |
|
483 return count($this->_currentData); |
|
484 } |
|
485 } |