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

Documentation generated on Mon, 11 Mar 2019 15:01:39 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.