source: trunk/library/Zend/Ldap/Node/Schema/OpenLdap.php @ 5146

Revision 5146, 14.6 KB checked in by wmerlotto, 12 years ago (diff)

Ticket #2305 - Enviando alteracoes, desenvolvidas internamente na Prognus. Library: adicionando arquivos.

Line 
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 Schema
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: OpenLdap.php 20096 2010-01-06 02:05:09Z bkarwin $
21 */
22
23/**
24 * @see Zend_Ldap_Node_Schema
25 */
26require_once 'Zend/Ldap/Node/Schema.php';
27/**
28 * @see Zend_Ldap_Node_Schema_AttributeType_OpenLdap
29 */
30require_once 'Zend/Ldap/Node/Schema/AttributeType/OpenLdap.php';
31/**
32 * @see Zend_Ldap_Node_Schema_ObjectClass_OpenLdap
33 */
34require_once 'Zend/Ldap/Node/Schema/ObjectClass/OpenLdap.php';
35
36/**
37 * Zend_Ldap_Node_Schema_OpenLdap provides a simple data-container for the Schema node of
38 * an OpenLDAP server.
39 *
40 * @category   Zend
41 * @package    Zend_Ldap
42 * @subpackage Schema
43 * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
44 * @license    http://framework.zend.com/license/new-bsd     New BSD License
45 */
46class Zend_Ldap_Node_Schema_OpenLdap extends Zend_Ldap_Node_Schema
47{
48    /**
49     * The attribute Types
50     *
51     * @var array
52     */
53    protected $_attributeTypes = null;
54    /**
55     * The object classes
56     *
57     * @var array
58     */
59    protected $_objectClasses = null;
60    /**
61     * The LDAP syntaxes
62     *
63     * @var array
64     */
65    protected $_ldapSyntaxes = null;
66    /**
67     * The matching rules
68     *
69     * @var array
70     */
71    protected $_matchingRules = null;
72    /**
73     * The matching rule use
74     *
75     * @var array
76     */
77    protected $_matchingRuleUse = null;
78
79    /**
80     * Parses the schema
81     *
82     * @param  Zend_Ldap_Dn $dn
83     * @param  Zend_Ldap    $ldap
84     * @return Zend_Ldap_Node_Schema Provides a fluid interface
85     */
86    protected function _parseSchema(Zend_Ldap_Dn $dn, Zend_Ldap $ldap)
87    {
88        parent::_parseSchema($dn, $ldap);
89        $this->_loadAttributeTypes();
90        $this->_loadLdapSyntaxes();
91        $this->_loadMatchingRules();
92        $this->_loadMatchingRuleUse();
93        $this->_loadObjectClasses();
94        return $this;
95    }
96
97    /**
98     * Gets the attribute Types
99     *
100     * @return array
101     */
102    public function getAttributeTypes()
103    {
104        return $this->_attributeTypes;
105    }
106
107    /**
108     * Gets the object classes
109     *
110     * @return array
111     */
112    public function getObjectClasses()
113    {
114        return $this->_objectClasses;
115    }
116
117    /**
118     * Gets the LDAP syntaxes
119     *
120     * @return array
121     */
122    public function getLdapSyntaxes()
123    {
124        return $this->_ldapSyntaxes;
125    }
126
127    /**
128     * Gets the matching rules
129     *
130     * @return array
131     */
132    public function getMatchingRules()
133    {
134        return $this->_matchingRules;
135    }
136
137    /**
138     * Gets the matching rule use
139     *
140     * @return array
141     */
142    public function getMatchingRuleUse()
143    {
144        return $this->_matchingRuleUse;
145    }
146
147    /**
148     * Loads the attribute Types
149     *
150     * @return void
151     */
152    protected function _loadAttributeTypes()
153    {
154        $this->_attributeTypes = array();
155        foreach ($this->getAttribute('attributeTypes') as $value) {
156            $val = $this->_parseAttributeType($value);
157            $val = new Zend_Ldap_Node_Schema_AttributeType_OpenLdap($val);
158            $this->_attributeTypes[$val->getName()] = $val;
159
160        }
161        foreach ($this->_attributeTypes as $val) {
162            if (count($val->sup) > 0) {
163                $this->_resolveInheritance($val, $this->_attributeTypes);
164            }
165            foreach ($val->aliases as $alias) {
166                $this->_attributeTypes[$alias] = $val;
167            }
168        }
169        ksort($this->_attributeTypes, SORT_STRING);
170    }
171
172    /**
173     * Parses an attributeType value
174     *
175     * @param  string $value
176     * @return array
177     */
178    protected function _parseAttributeType($value)
179    {
180        $attributeType = array(
181            'oid'                  => null,
182            'name'                 => null,
183            'desc'                 => null,
184            'obsolete'             => false,
185            'sup'                  => null,
186            'equality'             => null,
187            'ordering'             => null,
188            'substr'               => null,
189            'syntax'               => null,
190            'max-length'           => null,
191            'single-value'         => false,
192            'collective'           => false,
193            'no-user-modification' => false,
194            'usage'                => 'userApplications',
195            '_string'              => $value,
196            '_parents'             => array());
197
198        $tokens = $this->_tokenizeString($value);
199        $attributeType['oid'] = array_shift($tokens); // first token is the oid
200        $this->_parseLdapSchemaSyntax($attributeType, $tokens);
201
202        if (array_key_exists('syntax', $attributeType)) {
203            // get max length from syntax
204            if (preg_match('/^(.+){(\d+)}$/', $attributeType['syntax'], $matches)) {
205                $attributeType['syntax'] = $matches[1];
206                $attributeType['max-length'] = $matches[2];
207            }
208        }
209
210        $this->_ensureNameAttribute($attributeType);
211
212        return $attributeType;
213    }
214
215    /**
216     * Loads the object classes
217     *
218     * @return void
219     */
220    protected function _loadObjectClasses()
221    {
222        $this->_objectClasses = array();
223        foreach ($this->getAttribute('objectClasses') as $value) {
224            $val = $this->_parseObjectClass($value);
225            $val = new Zend_Ldap_Node_Schema_ObjectClass_OpenLdap($val);
226            $this->_objectClasses[$val->getName()] = $val;
227        }
228        foreach ($this->_objectClasses as $val) {
229            if (count($val->sup) > 0) {
230                $this->_resolveInheritance($val, $this->_objectClasses);
231            }
232            foreach ($val->aliases as $alias) {
233                $this->_objectClasses[$alias] = $val;
234            }
235        }
236        ksort($this->_objectClasses, SORT_STRING);
237    }
238
239    /**
240     * Parses an objectClasses value
241     *
242     * @param string $value
243     * @return array
244     */
245    protected function _parseObjectClass($value)
246    {
247        $objectClass = array(
248            'oid'        => null,
249            'name'       => null,
250            'desc'       => null,
251            'obsolete'   => false,
252            'sup'        => array(),
253            'abstract'   => false,
254            'structural' => false,
255            'auxiliary'  => false,
256            'must'       => array(),
257            'may'        => array(),
258            '_string'    => $value,
259            '_parents'   => array());
260
261        $tokens = $this->_tokenizeString($value);
262        $objectClass['oid'] = array_shift($tokens); // first token is the oid
263        $this->_parseLdapSchemaSyntax($objectClass, $tokens);
264
265        $this->_ensureNameAttribute($objectClass);
266
267        return $objectClass;
268    }
269
270    /**
271     * Resolves inheritance in objectClasses and attributes
272     *
273     * @param Zend_Ldap_Node_Schema_Item $node
274     * @param array                      $repository
275     */
276    protected function _resolveInheritance(Zend_Ldap_Node_Schema_Item $node, array $repository)
277    {
278        $data = $node->getData();
279        $parents = $data['sup'];
280        if ($parents === null || !is_array($parents) || count($parents) < 1) return;
281        foreach ($parents as $parent) {
282            if (!array_key_exists($parent, $repository)) continue;
283            if (!array_key_exists('_parents', $data) || !is_array($data['_parents'])) {
284               $data['_parents'] = array();
285           }
286           $data['_parents'][] = $repository[$parent];
287        }
288        $node->setData($data);
289    }
290
291    /**
292     * Loads the LDAP syntaxes
293     *
294     * @return void
295     */
296    protected function _loadLdapSyntaxes()
297    {
298        $this->_ldapSyntaxes = array();
299        foreach ($this->getAttribute('ldapSyntaxes') as $value) {
300            $val = $this->_parseLdapSyntax($value);
301            $this->_ldapSyntaxes[$val['oid']] = $val;
302        }
303        ksort($this->_ldapSyntaxes, SORT_STRING);
304    }
305
306    /**
307     * Parses an ldapSyntaxes value
308     *
309     * @param  string $value
310     * @return array
311     */
312    protected function _parseLdapSyntax($value)
313    {
314        $ldapSyntax = array(
315            'oid'      => null,
316            'desc'     => null,
317            '_string' => $value);
318
319        $tokens = $this->_tokenizeString($value);
320        $ldapSyntax['oid'] = array_shift($tokens); // first token is the oid
321        $this->_parseLdapSchemaSyntax($ldapSyntax, $tokens);
322
323        return $ldapSyntax;
324    }
325
326    /**
327     * Loads the matching rules
328     *
329     * @return void
330     */
331    protected function _loadMatchingRules()
332    {
333        $this->_matchingRules = array();
334        foreach ($this->getAttribute('matchingRules') as $value) {
335            $val = $this->_parseMatchingRule($value);
336            $this->_matchingRules[$val['name']] = $val;
337        }
338        ksort($this->_matchingRules, SORT_STRING);
339    }
340
341    /**
342     * Parses an matchingRules value
343     *
344     * @param  string $value
345     * @return array
346     */
347    protected function _parseMatchingRule($value)
348    {
349        $matchingRule = array(
350            'oid'      => null,
351            'name'     => null,
352            'desc'     => null,
353            'obsolete' => false,
354            'syntax'   => null,
355            '_string'  => $value);
356
357        $tokens = $this->_tokenizeString($value);
358        $matchingRule['oid'] = array_shift($tokens); // first token is the oid
359        $this->_parseLdapSchemaSyntax($matchingRule, $tokens);
360
361        $this->_ensureNameAttribute($matchingRule);
362
363        return $matchingRule;
364    }
365
366    /**
367     * Loads the matching rule use
368     *
369     * @return void
370     */
371    protected function _loadMatchingRuleUse()
372    {
373        $this->_matchingRuleUse = array();
374        foreach ($this->getAttribute('matchingRuleUse') as $value) {
375            $val = $this->_parseMatchingRuleUse($value);
376            $this->_matchingRuleUse[$val['name']] = $val;
377        }
378        ksort($this->_matchingRuleUse, SORT_STRING);
379    }
380
381    /**
382     * Parses an matchingRuleUse value
383     *
384     * @param  string $value
385     * @return array
386     */
387    protected function _parseMatchingRuleUse($value)
388    {
389        $matchingRuleUse = array(
390            'oid'      => null,
391            'name'     => null,
392            'desc'     => null,
393            'obsolete' => false,
394            'applies'  => array(),
395            '_string'  => $value);
396
397        $tokens = $this->_tokenizeString($value);
398        $matchingRuleUse['oid'] = array_shift($tokens); // first token is the oid
399        $this->_parseLdapSchemaSyntax($matchingRuleUse, $tokens);
400
401        $this->_ensureNameAttribute($matchingRuleUse);
402
403        return $matchingRuleUse;
404    }
405
406    /**
407     * Ensures that a name element is present and that it is single-values.
408     *
409     * @param array $data
410     */
411    protected function _ensureNameAttribute(array &$data)
412    {
413        if (!array_key_exists('name', $data) || empty($data['name'])) {
414            // force a name
415            $data['name'] = $data['oid'];
416        }
417        if (is_array($data['name'])) {
418            // make one name the default and put the other ones into aliases
419            $aliases = $data['name'];
420            $data['name'] = array_shift($aliases);
421            $data['aliases'] = $aliases;
422        } else {
423            $data['aliases'] = array();
424        }
425    }
426
427    /**
428     * Parse the given tokens into a data structure
429     *
430     * @param  array $data
431     * @param  array $tokens
432     * @return void
433     */
434    protected function _parseLdapSchemaSyntax(array &$data, array $tokens)
435    {
436        // tokens that have no value associated
437        $noValue = array('single-value',
438            'obsolete',
439            'collective',
440            'no-user-modification',
441            'abstract',
442            'structural',
443            'auxiliary');
444        // tokens that can have multiple values
445        $multiValue = array('must', 'may', 'sup');
446
447        while (count($tokens) > 0) {
448            $token = strtolower(array_shift($tokens));
449            if (in_array($token, $noValue)) {
450                $data[$token] = true; // single value token
451            } else {
452                $data[$token] = array_shift($tokens);
453                // this one follows a string or a list if it is multivalued
454                if ($data[$token] == '(') {
455                    // this creates the list of values and cycles through the tokens
456                    // until the end of the list is reached ')'
457                    $data[$token] = array();
458                    while ($tmp = array_shift($tokens)) {
459                        if ($tmp == ')') break;
460                        if ($tmp != '$') {
461                            $data[$token][] = Zend_Ldap_Attribute::convertFromLdapValue($tmp);
462                        }
463                    }
464                } else {
465                    $data[$token] = Zend_Ldap_Attribute::convertFromLdapValue($data[$token]);
466                }
467                // create a array if the value should be multivalued but was not
468                if (in_array($token, $multiValue) && !is_array($data[$token])) {
469                    $data[$token] = array($data[$token]);
470                }
471            }
472        }
473    }
474
475    /**
476    * Tokenizes the given value into an array
477    *
478    * @param  string $value
479    * @return array tokens
480    */
481    protected function _tokenizeString($value)
482    {
483        $tokens = array();
484        $matches = array();
485        // this one is taken from PEAR::Net_LDAP2
486        $pattern = "/\s* (?:([()]) | ([^'\s()]+) | '((?:[^']+|'[^\s)])*)') \s*/x";
487        preg_match_all($pattern, $value, $matches);
488        $cMatches = count($matches[0]);
489        $cPattern = count($matches);
490        for ($i = 0; $i < $cMatches; $i++) {     // number of tokens (full pattern match)
491            for ($j = 1; $j < $cPattern; $j++) { // each subpattern
492                $tok = trim($matches[$j][$i]);
493                if (!empty($tok)) {              // pattern match in this subpattern
494                    $tokens[$i] = $tok;          // this is the token
495                }
496            }
497        }
498        if ($tokens[0] == '(') array_shift($tokens);
499        if ($tokens[count($tokens) - 1] == ')') array_pop($tokens);
500        return $tokens;
501    }
502}
Note: See TracBrowser for help on using the repository browser.