Net_LDAP
[ class tree: Net_LDAP ] [ index: Net_LDAP ] [ all elements ]

Source for file Schema.php

Documentation is available at Schema.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +--------------------------------------------------------------------------+
  4. // | Net_LDAP                                                                 |
  5. // +--------------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                    |
  7. // +--------------------------------------------------------------------------+
  8. // | This library is free software; you can redistribute it and/or            |
  9. // | modify it under the terms of the GNU Lesser General Public               |
  10. // | License as published by the Free Software Foundation; either             |
  11. // | version 2.1 of the License, or (at your option) any later version.       |
  12. // |                                                                          |
  13. // | This library is distributed in the hope that it will be useful,          |
  14. // | but WITHOUT ANY WARRANTY; without even the implied warranty of           |
  15. // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        |
  16. // | Lesser General Public License for more details.                          |
  17. // |                                                                          |
  18. // | You should have received a copy of the GNU Lesser General Public         |
  19. // | License along with this library; if not, write to the Free Software      |
  20. // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA |
  21. // +--------------------------------------------------------------------------+
  22. // | Authors: Jan Wagner                                                      |
  23. // +--------------------------------------------------------------------------+
  24. //
  25. // $Id: Schema.php,v 1.11 2006/11/24 11:29:56 beni Exp $
  26.  
  27. define('NET_LDAP_SYNTAX_BOOLEAN''1.3.6.1.4.1.1466.115.121.1.7');
  28. define('NET_LDAP_SYNTAX_DIRECTORY_STRING''1.3.6.1.4.1.1466.115.121.1.15');
  29. define('NET_LDAP_SYNTAX_DISTINGUISHED_NAME''1.3.6.1.4.1.1466.115.121.1.12');
  30. define('NET_LDAP_SYNTAX_INTEGER''1.3.6.1.4.1.1466.115.121.1.27');
  31. define('NET_LDAP_SYNTAX_NUMERIC_STRING''1.3.6.1.4.1.1466.115.121.1.36');
  32. define('NET_LDAP_SYNTAX_OID''1.3.6.1.4.1.1466.115.121.1.38');
  33. define('NET_LDAP_SYNTAX_OCTET_STRING''1.3.6.1.4.1.1466.115.121.1.40');
  34.  
  35. /**
  36.  * Load an LDAP Schema and provide information
  37.  *
  38.  * This class takes a Subschema entry, parses this information
  39.  * and makes it available in an array. Most of the code has been
  40.  * inspired by perl-ldap( http://perl-ldap.sourceforge.net).
  41.  * You will find portions of their implementation in here.
  42.  *
  43.  * @package Net_LDAP
  44.  * @author Jan Wagner <wagner@netsols.de>
  45.  * @version $Revision: 1.11 $
  46.  */
  47.  class Net_LDAP_Schema extends PEAR
  48.  {
  49.     /**
  50.      * Map of entry types to ldap attributes of subschema entry
  51.      *
  52.      * @access public
  53.      * @var array 
  54.      */
  55.     var $types = array('attribute'        => 'attributeTypes',
  56.                        'ditcontentrule'   => 'dITContentRules',
  57.                        'ditstructurerule' => 'dITStructureRules',
  58.                        'matchingrule'     => 'matchingRules',
  59.                        'matchingruleuse'  => 'matchingRuleUse',
  60.                        'nameform'         => 'nameForms',
  61.                        'objectclass'      => 'objectClasses',
  62.                        'syntax'           => 'ldapSyntaxes');
  63.  
  64.     /**
  65.      * Array of entries belonging to this type
  66.      *
  67.      * @access private
  68.      * @var array 
  69.      */
  70.     var $_attributeTypes    = array();
  71.     var $_matchingRules     = array();
  72.     var $_matchingRuleUse   = array();
  73.     var $_ldapSyntaxes      = array();
  74.     var $_objectClasses     = array();
  75.     var $_dITContentRules   = array();
  76.     var $_dITStructureRules = array();
  77.     var $_nameForms         = array();
  78.  
  79.  
  80.     /**
  81.      * hash of all fetched oids
  82.      *
  83.      * @access private
  84.      * @var array 
  85.      */
  86.     var $_oids = array();
  87.  
  88.     /**
  89.      * constructor of the class
  90.      *
  91.      * @access protected
  92.      */
  93.     function Net_LDAP_Schema()
  94.     {
  95.         $this->PEAR('Net_LDAP_Error')// default error class
  96.     }
  97.  
  98.     /**
  99.      * Return a hash of entries for the given type
  100.      *
  101.      * Returns a hash of entry for th givene type. Types may be:
  102.      * objectclasses, attributes, ditcontentrules, ditstructurerules, matchingrules,
  103.      * matchingruleuses, nameforms, syntaxes
  104.      *
  105.      * @access public
  106.      * @param string $type Type to fetch
  107.      * @return array|Net_LDAP_ErrorArray or Net_LDAP_Error
  108.      */
  109.     function &getAll($type)
  110.     {
  111.         $map = array('objectclasses'     => &$this->_objectClasses,
  112.                      'attributes'        => &$this->_attributeTypes,
  113.                      'ditcontentrules'   => &$this->_dITContentRules,
  114.                      'ditstructurerules' => &$this->_dITStructureRules,
  115.                      'matchingrules'     => &$this->_matchingRules,
  116.                      'matchingruleuses'  => &$this->_matchingRuleUse,
  117.                      'nameforms'         => &$this->_nameForms,
  118.                      'syntaxes'          => &$this->_ldapSyntaxes );
  119.  
  120.         $key strtolower($type);
  121.         $ret ((key_exists($key$map)) $map[$key: PEAR::raiseError("Unknown type $type"));
  122.         return $ret;
  123.     }
  124.  
  125.     /**
  126.      * Return a specific entry
  127.      *
  128.      * @access public
  129.      * @param string $type Type of name
  130.      * @param string $name Name or OID to fetch
  131.      * @return mixed Entry or Net_LDAP_Error
  132.      */
  133.      function &get($type$name)
  134.      {
  135.         $type strtolower($type);
  136.         if (false == key_exists($type$this->types)) {
  137.             return PEAR::raiseError("No such type $type");
  138.         }
  139.  
  140.         $name strtolower($name);
  141.         $type_var &$this->{'_' $this->types[$type]};
  142.  
  143.         ifkey_exists($name$type_var)) {
  144.             return $type_var[$name];
  145.         elseif(key_exists($name$this->_oids&& $this->_oids[$name]['type'== $type{
  146.             return $this->_oids[$name];
  147.         else {
  148.             return PEAR::raiseError("Could not find $type $name");
  149.         }
  150.      }
  151.  
  152.  
  153.     /**
  154.      * Fetches attributes that MAY be present in the given objectclass
  155.      *
  156.      * @access public
  157.      * @param string $oc Name or OID of objectclass
  158.      * @return array|Net_LDAP_ErrorArray with attributes or Net_LDAP_Error
  159.      */
  160.     function may($oc)
  161.     {
  162.         return $this->_getAttr($oc'may');
  163.     }
  164.  
  165.     /**
  166.      * Fetches attributes that MUST be present in the given objectclass
  167.      *
  168.      * @access public
  169.      * @param string $oc Name or OID of objectclass
  170.      * @return array|Net_LDAP_ErrorArray with attributes or Net_LDAP_Error
  171.      */
  172.     function must($oc)
  173.     {
  174.         return $this->_getAttr($oc'must');
  175.     }
  176.  
  177.     /**
  178.      * Fetches the given attribute from the given objectclass
  179.      *
  180.      * @access private
  181.      * @param string $oc   Name or OID of objectclass
  182.      * @param string $attr Name of attribute to fetch
  183.      * @return array|Net_LDAP_ErrorThe attribute or Net_LDAP_Error
  184.      */
  185.     function _getAttr($oc$attr)
  186.     {
  187.         $oc strtolower($oc);
  188.         if (key_exists($oc$this->_objectClasses&& key_exists($attr$this->_objectClasses[$oc])) {
  189.             return $this->_objectClasses[$oc][$attr];
  190.         }
  191.         elseif (key_exists($oc$this->_oids&&
  192.                 $this->_oids[$oc]['type'== 'objectclass' &&
  193.                 key_exists($attr$this->_oids[$oc])) {
  194.             return $this->_oids[$oc][$attr];
  195.         else {
  196.             return PEAR::raiseError("Could not find $attr attributes for $oc ");
  197.         }
  198.     }
  199.  
  200.     /**
  201.      * Returns the name(s) of the immediate superclass(es)
  202.      *
  203.      * @param string $oc Name or OID of objectclass
  204.      * @return array|Net_LDAP_Error Array of names or Net_LDAP_Error
  205.      */
  206.     function superclass($oc)
  207.     {
  208.         $o $this->get('objectclass'$oc);
  209.         if (Net_LDAP::isError($o)) {
  210.             return $o;
  211.         }
  212.         return (key_exists('sup'$o$o['sup': array());
  213.     }
  214.  
  215.     /**
  216.      * Parses the schema of the given Subschema entry
  217.      *
  218.      * @access public
  219.      * @param Net_LDAP_Entry $entry Subschema entry
  220.      */
  221.     function parse(&$entry)
  222.     {
  223.         foreach ($this->types as $type => $attr)
  224.         {
  225.             // initialize map type to entry
  226.             $type_var '_' $attr;
  227.             $this->{$type_var= array();
  228.  
  229.             // get values for this type
  230.             $values $entry->get_value($attr);
  231.  
  232.             if (is_array($values))
  233.             {
  234.                 foreach ($values as $value{
  235.  
  236.                     unset($schema_entry)// this was a real mess without it
  237.  
  238.                     // get the schema entry
  239.                     $schema_entry $this->_parse_entry($value);
  240.  
  241.                     // set the type
  242.                     $schema_entry['type'$type;
  243.  
  244.                     // save a ref in $_oids
  245.                     $this->_oids[$schema_entry['oid']] &$schema_entry;
  246.  
  247.                     // save refs for all names in type map
  248.                     $names $schema_entry['aliases'];
  249.                     array_push($names$schema_entry['name']);
  250.                     foreach ($names as $name{
  251.                         $this->{$type_var}[strtolower($name)&$schema_entry;
  252.                     }
  253.                 }
  254.             }
  255.         }
  256.     }
  257.  
  258.     /**
  259.      * parses an attribute value into a schema entry
  260.      *
  261.      * @access private
  262.      * @param string $value Attribute value
  263.      * @return array|falseSchema entry array or false
  264.      */
  265.     function &_parse_entry($value)
  266.     {
  267.         // tokens that have no value associated
  268.         $noValue = array('single-value',
  269.                          'obsolete',
  270.                          'collective',
  271.                          'no-user-modification',
  272.                          'abstract',
  273.                          'structural',
  274.                          'auxiliary');
  275.  
  276.         // tokens that can have multiple values
  277.         $multiValue = array('must''may''sup');
  278.  
  279.         $schema_entry = array('aliases' => array())// initilization
  280.  
  281.         $tokens $this->_tokenize($value)// get an array of tokens
  282.  
  283.         // remove surrounding brackets
  284.         if ($tokens[0== '('array_shift($tokens);
  285.         if ($tokens[count($tokens- 1== ')'array_pop($tokens)// -1 doesnt work on arrays :-(
  286.  
  287.         $schema_entry['oid'array_shift($tokens)// first token is the oid
  288.  
  289.         // cycle over the tokens until none are left
  290.         while (count($tokens> 0{
  291.             $token strtolower(array_shift($tokens));
  292.             if (in_array($token$noValue)) {
  293.                 $schema_entry[$token= 1; // single value token
  294.             else {
  295.                 // this one follows a string or a list if it is multivalued
  296.                 if (($schema_entry[$tokenarray_shift($tokens)) == '('{
  297.                     // this creates the list of values and cycles through the tokens
  298.                     // until the end of the list is reached ')'
  299.                     $schema_entry[$token= array();
  300.                     while ($tmp array_shift($tokens)) {
  301.                         if ($tmp == ')'break;
  302.                         if ($tmp != '$'array_push($schema_entry[$token]$tmp);
  303.                     }
  304.                 }
  305.                 // create a array if the value should be multivalued but was not
  306.                 if (in_array($token$multiValue && !is_array($schema_entry[$token])) {
  307.                     $schema_entry[$token= array($schema_entry[$token]);
  308.                 }
  309.             }
  310.         }
  311.         // get max length from syntax
  312.         if (key_exists('syntax'$schema_entry)) {
  313.             if (preg_match('/{(\d+)}/'$schema_entry['syntax']$matches)) {
  314.                 $schema_entry['max_length'$matches[1];
  315.             }
  316.         }
  317.         // force a name
  318.         if (empty($schema_entry['name'])) {
  319.             $schema_entry['name'$schema_entry['oid'];
  320.         }
  321.         // make one name the default and put the other ones into aliases
  322.         if (is_array($schema_entry['name'])) {
  323.             $aliases $schema_entry['name'];
  324.             $schema_entry['name'array_shift($aliases);
  325.             $schema_entry['aliases'$aliases;
  326.         }
  327.         return $schema_entry;
  328.     }
  329.  
  330.     /**
  331.      * tokenizes the given value into an array of tokens
  332.      *
  333.      * @access private
  334.      * @param string $value String to parse
  335.      * @return array Array of tokens
  336.      */
  337.     function _tokenize($value)
  338.     {
  339.         $tokens = array();        // array of tokens
  340.         $matches = array();       // matches[0] full pattern match, [1,2,3] subpatterns
  341.  
  342.         // this one is taken from perl-ldap, modified for php
  343.         $pattern "/\s* (?:([()]) | ([^'\s()]+) | '((?:[^']+|'[^\s)])*)') \s*/x";
  344.  
  345.         /**
  346.          * This one matches one big pattern wherin only one of the three subpatterns matched
  347.          * We are interested in the subpatterns that matched. If it matched its value will be
  348.          * non-empty and so it is a token. Tokens may be round brackets, a string, or a string
  349.          * enclosed by '
  350.          */
  351.         preg_match_all($pattern$value$matches);
  352.  
  353.         for ($i = 0; $i count($matches[0])$i++{     // number of tokens (full pattern match)
  354.             for ($j = 1; $j < 4; $j++{                  // each subpattern
  355.                 if (null != trim($matches[$j][$i])) {     // pattern match in this subpattern
  356.                     $tokens[$itrim($matches[$j][$i])// this is the token
  357.                 }
  358.             }
  359.         }
  360.         return $tokens;
  361.     }
  362.  }
  363.  
  364. ?>

Documentation generated on Mon, 11 Mar 2019 14:56:27 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.