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

Source for file Entry.php

Documentation is available at Entry.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, Tarjej Huse                                         |
  23. // +--------------------------------------------------------------------------+
  24. //
  25. // $Id: Entry.php,v 1.42 2007/06/28 07:59:44 beni Exp $
  26.  
  27. require_once("PEAR.php");
  28. require_once('Util.php');
  29.  
  30. /**
  31.  * Object representation of a directory entry
  32.  *
  33.  * This class represents a directory entry. You can add, delete, replace
  34.  * attributes and their values, rename the entry, delete the entry.
  35.  *
  36.  * @package Net_LDAP
  37.  * @author Jan Wagner <wagner@netsols.de>
  38.  * @author Tarjej Huse
  39.  * @version $Revision: 1.42 $
  40.  */
  41.  
  42. class Net_LDAP_Entry extends PEAR
  43. {
  44.     /**
  45.      * Entry ressource identifier
  46.      *
  47.      * @access private
  48.      * @var ressourcee 
  49.      */
  50.     var $_entry = null;
  51.  
  52.     /**
  53.      * LDAP ressource identifier
  54.      *
  55.      * @access private
  56.      * @var ressource 
  57.      */
  58.     var $_link = null;
  59.  
  60.     /**
  61.      * Net_LDAP object
  62.      *
  63.      * This object will be used for updating and schema checking
  64.      *
  65.      * @access private
  66.      * @var object Net_LDAP 
  67.      */
  68.     var $_ldap = null;
  69.  
  70.     /**
  71.      * Distinguished name of the entry
  72.      *
  73.      * @access private
  74.      * @var string 
  75.      */
  76.     var $_dn = null;
  77.  
  78.     /**
  79.      * Attributes
  80.      *
  81.      * @access private
  82.      * @var array 
  83.      */
  84.     var $_attributes = array();
  85.  
  86.     /**
  87.      * Original attributes before any modification
  88.      *
  89.      * @access private
  90.      * @var array 
  91.      */
  92.     var $_original = array();
  93.  
  94.  
  95.     /**
  96.      * Map of attribute names
  97.      *
  98.      * @access private
  99.      * @var array 
  100.      */
  101.     var $_map = array();
  102.  
  103.  
  104.     /**
  105.      * Is this a new entry?
  106.      *
  107.      * @access private
  108.      * @var boolean 
  109.      */
  110.     var $_new = true;
  111.  
  112.     /**
  113.      * New distinguished name
  114.      *
  115.      * @access private
  116.      * @var string 
  117.      */
  118.     var $_newdn = null;
  119.  
  120.     /**
  121.      * Shall the entry be deleted?
  122.      *
  123.      * @access private
  124.      * @var boolean 
  125.      */
  126.     var $_delete = false;
  127.  
  128.     /**
  129.      * Map with changes to the entry
  130.      *
  131.      * @access private
  132.      * @var array 
  133.      */
  134.     var $_changes = array("add"     => array(),
  135.                           "delete"  => array(),
  136.                           "replace" => array()
  137.                           );
  138.     /**
  139.      * Internal Constructor
  140.      *
  141.      * Constructor of the entry. Sets up the distinguished name and the entries
  142.      * attributes.
  143.      * You should not call this method manually! Use {@link Net_LDAP_Entry::createFresh()} instead!
  144.      *
  145.      * @access protected
  146.      * @param Net_LDAP|ressource|array$ldap   Net_LDAP object, ldap-link ressource or array of attributes
  147.      * @param string|ressource        $entry  Either a DN or a LDAP-Entry ressource
  148.      * @return none 
  149.      */
  150.     function Net_LDAP_Entry(&$ldap$entry = null)
  151.     {
  152.         $this->PEAR('Net_LDAP_Error');
  153.  
  154.         if (is_resource($entry)) {
  155.             $this->_entry &$entry;
  156.         else {
  157.             $this->_dn $entry;
  158.         }
  159.  
  160.         if (is_a($ldap'Net_LDAP')) {
  161.             $this->_ldap &$ldap;
  162.             $this->_link $ldap->getLink();
  163.         elseif (is_resource($ldap)) {
  164.             $this->_link $ldap;
  165.         elseif (is_array($ldap)) {
  166.             $this->_setAttributes($ldap);  // setup attrs manually
  167.         }
  168.  
  169.         if (is_resource($this->_entry&& is_resource($this->_link)) {
  170.             $this->_new = false;
  171.             $this->_dn  @ldap_get_dn($this->_link$this->_entry);
  172.             $this->_setAttributes();  // fetch attributes from server
  173.         }
  174.     }
  175.  
  176.     /**
  177.     * Creates a fresh entry that may be added to the directory later on
  178.     *
  179.     * The method should be called statically: $entry = Net_LDAP_Entry::createFresh();
  180.     *
  181.     * Use this method, if you want to initialize a fresh entry.
  182.     * The attributes parameter is as following:
  183.     * <code>
  184.     * $attrs = array( 'attribute1' => array('value1', 'value2'),
  185.     *                 'attribute2' => 'single value'
  186.     *          );
  187.     * </code>
  188.     *
  189.     * @static
  190.     * @param string $dn     DN of the Entry
  191.     * @param array  $attrs  Attributes of the entry
  192.     * @return Net_LDAP_Entry 
  193.     */
  194.     function createFresh($dn$attrs = array())
  195.     {
  196.         if (!is_array($attrs)) {
  197.             return PEAR::raiseError("Unable to create fresh entry: Parameter \$attrs needs to be an array!");
  198.         }
  199.  
  200.         $entry = new Net_LDAP_Entry($attrs$dn);
  201.         return $entry;
  202.     }
  203.  
  204.     /**
  205.      * Get or set the distinguished name of the entry
  206.      *
  207.      * If called without an argument the current (or the new DN if set) DN gets returned.
  208.      * If you provide an DN, this entry is moved to the new location specified if a DN existed.
  209.      * If the DN was not set, the DN gets initialized. Call {@link update()} to actually create
  210.      * the new Entry in the directory.
  211.      *
  212.      * Please note that special characters (eg german umlauts) should be encoded using utf8_encode().
  213.      *
  214.      * @access public
  215.      * @param string $dn New distinguished name
  216.      * @return string|trueDistinguished name (or true if a new DN was provided)
  217.      */
  218.     function dn($dn = null)
  219.     {
  220.         if (false == is_null($dn)) {
  221.             if (is_null($this->_dn)) {
  222.                 $this->_dn $dn;
  223.             else {
  224.                 $this->_newdn $dn;
  225.             }
  226.             $return = true;
  227.             return $return;
  228.         }
  229.         return (isset($this->_newdn$this->_newdn $this->_dn);
  230.     }
  231.  
  232.     /**
  233.      * Sets the internal attributes array
  234.      *
  235.      * This fetches the values for the attributes from the server.
  236.      * The attribute Syntax will be checked so binary attributes will be returned
  237.      * as binary values.
  238.      *
  239.      * Attributes may be passed directly via the $attributes parameter to setup this
  240.      * entry manually. This overrides attribute fetching from the server.
  241.      *
  242.      * @access private
  243.      * @param array $attributes 
  244.      */
  245.     function _setAttributes($attributes = null)
  246.     {
  247.         /*
  248.         * fetch attributes from the server
  249.         */
  250.         if (is_null($attributes&& is_resource($this->_entry&& is_resource($this->_link))
  251.         {
  252.             // fetch schema
  253.             if (is_a($this->_ldap'Net_LDAP')) {
  254.                 $schema =$this->_ldap->schema();
  255.             }
  256.             // fetch attributes
  257.             $attributes = array();
  258.             do {
  259.                 if (empty($attr)) {
  260.                     $ber = null;
  261.                     $attr @ldap_first_attribute($this->_link$this->_entry$ber);
  262.                 else {
  263.                     $attr @ldap_next_attribute($this->_link$this->_entry$ber);
  264.                 }
  265.                 if ($attr{
  266.                     $func 'ldap_get_values'// standard function to fetch value
  267.  
  268.                     // Try to get binary values as binary data
  269.                     if (is_a($schema'Net_LDAP_Schema')) {
  270.                         if ($schema->isBinary($attr)) {
  271.                              $func 'ldap_get_values_len';
  272.                         }
  273.                     }
  274.                     // fetch attribute value (needs error checking?)
  275.                     $attributes[$attr$func($this->_link$this->_entry$attr);
  276.                 }
  277.             while ($attr);
  278.         }
  279.  
  280.         /*
  281.         * set attribute data directly, if passed
  282.         */
  283.         if (is_array($attributes&& count($attributes> 0{
  284.             if (isset($attributes["count"]&& is_numeric($attributes["count"])) {
  285.                 unset($attributes["count"]);
  286.             }
  287.             foreach ($attributes as $k => $v{
  288.                 // attribute names should not be numeric
  289.                 if (is_numeric($k)) {
  290.                     continue;
  291.                 }
  292.                 // map generic attribute name to real one
  293.                 $this->_map[strtolower($k)$k;
  294.                 // attribute values should be in an array
  295.                 if (false == is_array($v)) {
  296.                     $v = array($v);
  297.                 }
  298.                 // remove the value count (comes from ldap server)
  299.                 if (isset($v["count"])) {
  300.                     unset($v["count"]);
  301.                 }
  302.                 $this->_attributes[$k$v;
  303.             }
  304.         }
  305.  
  306.         // save a copy for later use
  307.         $this->_original $this->_attributes;
  308.     }
  309.  
  310.     /**
  311.      * Get the values of all attributes in a hash
  312.      *
  313.      * The returned hash has the form
  314.      * array('attributename' => 'single value',
  315.      *       'attributename' => array('value1', value2', value3'))
  316.      *
  317.      * @access public
  318.      * @return array Hash of all attributes with their values
  319.      */
  320.     function getValues()
  321.     {
  322.         $attrs = array();
  323.         foreach ($this->_attributes as $attr => $value{
  324.             $attrs[$attr$this->getValue($attr);
  325.         }
  326.         return $attrs;
  327.     }
  328.  
  329.     /**
  330.      * Get the value of a specific attribute
  331.      *
  332.      * The first parameter is the name of the attribute
  333.      * The second parameter influences the way the value is returned:
  334.      * 'single': only the first value is returned as string
  335.      * 'all': all values including the value count are returned in an
  336.      *               array
  337.      * 'default': in all other cases an attribute value with a single value is
  338.      *            returned as string, if it has multiple values it is returned
  339.      *            as an array (without value count)
  340.      *
  341.      * @access public
  342.      * @param string $attr Attribute name
  343.      * @param string $option Option
  344.      * @return string|array|PEAR_Errorstring, array or PEAR_Error
  345.      */
  346.     function getValue($attr$option = null)
  347.     {
  348.         $attr $this->_getAttrName($attr);
  349.  
  350.         if (false == array_key_exists($attr$this->_attributes)) {
  351.             return PEAR::raiseError("Unknown attribute ($attr) requested");
  352.         }
  353.  
  354.         $value $this->_attributes[$attr];
  355.  
  356.         if ($option == "single" || (count($value== 1 && $option != 'all')) {
  357.             $value array_shift($value);
  358.         }
  359.  
  360.         return $value;
  361.     }
  362.  
  363.     /**
  364.      * Alias function of getValue for perl-ldap interface
  365.      *
  366.      * @see getValue()
  367.      */
  368.     function get_value()
  369.     {
  370.         $args func_get_args();
  371.         return call_user_func_array(array&$this'getValue' )$args);
  372.     }
  373.  
  374.     /**
  375.      * Returns an array of attributes names
  376.      *
  377.      * @access public
  378.      * @return array Array of attribute names
  379.      */
  380.     function attributes()
  381.     {
  382.         return array_keys($this->_attributes);
  383.     }
  384.  
  385.     /**
  386.      * Returns whether an attribute exists or not
  387.      *
  388.      * @access public
  389.      * @param string $attr Attribute name
  390.      * @return boolean 
  391.      */
  392.     function exists($attr)
  393.     {
  394.         $attr $this->_getAttrName($attr);
  395.         return array_key_exists($attr$this->_attributes);
  396.     }
  397.  
  398.     /**
  399.      * Adds a new attribute or a new value to an existing attribute
  400.      *
  401.      * The paramter has to be an array of the form:
  402.      * array('attributename' => 'single value',
  403.      *       'attributename' => array('value1', 'value2))
  404.      * When the attribute already exists the values will be added, else the
  405.      * attribute will be created. These changes are local to the entry and do
  406.      * not affect the entry on the server until update() is called.
  407.      *
  408.      * Note, that you can add values of attributes that you haven't selected, but if
  409.      * you do so, {@link getValue()} and {@link getValues()} will only return the
  410.      * values you added, _NOT_ all values present on the server. To avoid this, just refetch
  411.      * the entry after calling {@link update()} or select the attribute.
  412.      *
  413.      * @access public
  414.      * @param array $attr 
  415.      * @return true|Net_LDAP_Error
  416.      */
  417.     function add($attr = array())
  418.     {
  419.         if (false == is_array($attr)) {
  420.             return PEAR::raiseError("Parameter must be an array");
  421.         }
  422.         foreach ($attr as $k => $v{
  423.             $k $this->_getAttrName($k);
  424.             if (false == is_array($v)) {
  425.                 // Do not add empty values
  426.                 if ($v == null{
  427.                     continue;
  428.                 else {
  429.                     $v = array($v);
  430.                 }
  431.             }
  432.             // add new values to existing attribute
  433.             if ($this->exists($k)) {
  434.                 $this->_attributes[$karray_merge($this->_attributes[$k]$v);
  435.             else {
  436.                 $this->_map[strtolower($k)$k;
  437.                 $this->_attributes[$k$v;
  438.             }
  439.             // save changes for update()
  440.             if (empty($this->_changes["add"][$k])) {
  441.                 $this->_changes["add"][$k= array();
  442.             }
  443.             $this->_changes["add"][$karray_merge($this->_changes["add"][$k]$v);
  444.         }
  445.         $return = true;
  446.         return $return;
  447.     }
  448.  
  449.     /**
  450.      * Deletes an whole attribute or a value or the whole entry
  451.      *
  452.      * The parameter can be one of the following:
  453.      *
  454.      * "attributename" - The attribute as a whole will be deleted
  455.      * array("attributename1", "attributename2) - All given attributes will be
  456.      *                                            deleted
  457.      * array("attributename" => "value") - The value will be deleted
  458.      * array("attributename" => array("value1", "value2") - The given values
  459.      *                                                      will be deleted
  460.      * If $attr is null or omitted , then the whole Entry will be deleted!
  461.      *
  462.      * These changes are local to the entry and do
  463.      * not affect the entry on the server until {@link update()} is called.
  464.      *
  465.      * Please note that you must select the attribute (at $ldap->search() for example)
  466.      * to be able to delete values of it, Otherwise {@link update()} will silently fail
  467.      * and remove nothing.
  468.      *
  469.      * @access public
  470.      * @param string|array$attr 
  471.      * @return true 
  472.      */
  473.     function delete($attr = null)
  474.     {
  475.         if (is_null($attr)) {
  476.             $this->_delete = true;
  477.             $return = true;
  478.             return $return;
  479.         }
  480.         if (is_string($attr)) {
  481.             $attr = array($attr);
  482.         }
  483.         // Make the assumption that attribute names cannot be numeric,
  484.         // therefore this has to be a simple list of attribute names to delete
  485.         if (is_numeric(key($attr))) {
  486.             foreach ($attr as $name{
  487.                 $name $this->_getAttrName($name);
  488.                 if ($this->exists($name)) {
  489.                     $this->_changes["delete"][$name= null;
  490.                     unset($this->_attributes[$name]);
  491.                 }
  492.             }
  493.         else {
  494.             // Here we have a hash with "attributename" => "value to delete"
  495.             foreach ($attr as $name => $values{
  496.                 // get the correct attribute name
  497.                 $name $this->_getAttrName($name);
  498.                 if ($this->exists($name)) {
  499.                     if (false == is_array($values)) {
  500.                         $values = array($values);
  501.                     }
  502.                     // save values to be deleted
  503.                     if (empty($this->_changes["delete"][$name])) {
  504.                         $this->_changes["delete"][$name= array();
  505.                     }
  506.                     $this->_changes["delete"][$name=
  507.                         array_merge($this->_changes["delete"][$name]$values);
  508.                     foreach ($values as $value{
  509.                         // find the key for the value that should be deleted
  510.                         $key array_search($value$this->_attributes[$name]);
  511.                         if (false !== $key{
  512.                             // delete the value
  513.                             unset($this->_attributes[$name][$key]);
  514.                         }
  515.                     }
  516.                 }
  517.             }
  518.         }
  519.         $return = true;
  520.         return $return;
  521.     }
  522.  
  523.     /**
  524.      * Replaces attributes or its values
  525.      *
  526.      * The parameter has to an array of the following form:
  527.      * array("attributename" => "single value",
  528.      *       "attribute2name" => array("value1", "value2"))
  529.      * If the attribute does not yet exist it will be added instead.
  530.      * If the attribue value is null, the attribute will de deleted
  531.      *
  532.      * These changes are local to the entry and do
  533.      * not affect the entry on the server until {@link update()} is called.
  534.      *
  535.      * @access public
  536.      * @param array $attr 
  537.      * @return true|Net_LDAP_Error
  538.      */
  539.     function replace($attr = array())
  540.     {
  541.         if (false == is_array($attr)) {
  542.             return PEAR::raiseError("Parameter must be an array");
  543.         }
  544.         foreach ($attr as $k => $v{
  545.             $k $this->_getAttrName($k);
  546.             if (false == is_array($v)) {
  547.                 // delete attributes with empty values
  548.                 if ($v == null{
  549.                     $this->delete($k);
  550.                     continue;
  551.                 else {
  552.                     $v = array($v);
  553.                 }
  554.             }
  555.             // existing attributes will get replaced
  556.             if ($this->exists($k)) {
  557.                 $this->_changes["replace"][$k$v;
  558.                 $this->_attributes[$k$v;
  559.             else {
  560.                 // new ones just get added
  561.                 $this->add(array($k => $v));
  562.             }
  563.         }
  564.         $return = true;
  565.         return $return;
  566.     }
  567.  
  568.     /**
  569.      * Update the entry on the directory server
  570.      *
  571.      * @access public
  572.      * @param Net_LDAP $ldap (optional) If you provide a Net_LDAP object, be sure to PASS IT VIA REFERENCE!
  573.      * @return true|Net_LDAP_Error
  574.      * @todo Entry rename with a DN containing special characters needs testing!
  575.      */
  576.     function update($ldap=false)
  577.     {
  578.         if (!$ldap{  // If object is not provided, then use this entrys ldap object
  579.             $ldap =$this->_ldap;
  580.         else {
  581.             if (!is_a($ldap'Net_LDAP')) {
  582.                 $ldap = false; // throw error
  583.             else {
  584.                 // store the provided ldap object internally, if we haven't got one already
  585.                 if (!$this->_ldap$this->_ldap =$ldap;
  586.             }
  587.         }
  588.  
  589.         // ensure we have a valid LDAP object
  590.         if (!is_a($ldap'Net_LDAP')) {
  591.            return PEAR::raiseError("Need a Net_LDAP object as parameter");
  592.         }
  593.  
  594.         $link $ldap->getLink();
  595.  
  596.         /*
  597.         * Delete the entry
  598.         */
  599.         if (true === $this->_delete{
  600.             return $ldap->delete($this);
  601.         }
  602.  
  603.         /*
  604.         * New entry
  605.         */
  606.         if (true === $this->_new{
  607.             $msg $ldap->add($this);
  608.             if (Net_LDAP::isError($msg)) {
  609.                 return $msg;
  610.             }
  611.             $this->_new = false;
  612.             $this->_changes['add'= array();
  613.             $this->_changes['delete'= array();
  614.             $this->_changes['replace'= array();
  615.             $this->_original $this->_attributes;
  616.  
  617.             $return = true;
  618.             return $return;
  619.         }
  620.  
  621.         /*
  622.         * Rename/move entry
  623.         */
  624.         if (false == is_null($this->_newdn)) {
  625.             if ($ldap->getLDAPVersion(!== 3{
  626.                 return PEAR::raiseError("Renaming/Moving an entry is only supported in LDAPv3");
  627.             }
  628.             // make dn relative to parent (needed for ldap rename)
  629.             $parent Net_LDAP_Util::ldap_explode_dn($this->_newdnarray('casefolding' => 'none''reverse' => false'onlyvalues' => false));
  630.             if (Net_LDAP::isError($parent)) {
  631.                 return $parent;
  632.             }
  633.             $child array_shift($parent);
  634.             // maybe the dn consist of a multivalued RDN, we must build the dn in this case
  635.             // because the $child-RDN is an array!
  636.             if (is_array($child)) {
  637.                 $child Net_LDAP_Util::canonical_dn($child);
  638.             }
  639.             $parent Net_LDAP_Util::canonical_dn($parent);
  640.  
  641.             // rename
  642.             if (false == @ldap_rename($link$this->_dn$child$parenttrue)) {
  643.                 return PEAR::raiseError("Entry not renamed: " .
  644.                                         @ldap_error($link)@ldap_errno($link));
  645.             }
  646.             // reflect changes to local copy
  647.             $this->_dn $this->_newdn;
  648.             $this->_newdn = null;
  649.         }
  650.  
  651.         /*
  652.         * Carry out modifications to the entry
  653.         */
  654.         // ADD
  655.         foreach ($this->_changes["add"as $attr => $value{
  656.             // if attribute exists, add new values
  657.             if ($this->exists($attr)) {
  658.                 if (false === @ldap_mod_add($link$this->dn()array($attr => $value))) {
  659.                     return PEAR::raiseError("Could not add new values to attribute $attr" .
  660.                                             @ldap_error($link)@ldap_errno($link));
  661.                 }
  662.             else {
  663.                 // new attribute
  664.                 if (false === @ldap_modify($link$this->dn()array($attr => $value))) {
  665.                     return PEAR::raiseError("Could not add new attribute $attr" .
  666.                                             @ldap_error($link)@ldap_errno($link));
  667.                 }
  668.             }
  669.             // all went well here, I guess
  670.             unset($this->_changes["add"][$attr]);
  671.         }
  672.  
  673.         // DELETE
  674.         foreach ($this->_changes["delete"as $attr => $value{
  675.             // In LDAPv3 you need to specify the old values for deleting
  676.             if (is_null($value&& $ldap->getLDAPVersion(=== 3{
  677.                 $value $this->_original[$attr];
  678.             }
  679.             if (false === @ldap_mod_del($link$this->dn()array($attr => $value))) {
  680.                 return PEAR::raiseError("Could not delete attribute $attr" .
  681.                                         @ldap_error($link)@ldap_errno($link));
  682.             }
  683.             unset($this->_changes["delete"][$attr]);
  684.         }
  685.  
  686.         // REPLACE
  687.         foreach ($this->_changes["replace"as $attr => $value{
  688.             if (false === @ldap_modify($link$this->dn()array($attr => $value))) {
  689.                 return PEAR::raiseError("Could not replace attribute $attr values: " .
  690.                                         @ldap_error($link)@ldap_errno($link));
  691.             }
  692.             unset($this->_changes["replace"][$attr]);
  693.         }
  694.  
  695.         // all went well, so _original (server) becomes _attributes (local copy)
  696.         $this->_original $this->_attributes;
  697.  
  698.         $return = true;
  699.         return $return;
  700.     }
  701.  
  702.     /**
  703.      * Returns the right attribute name
  704.      *
  705.      * @access private
  706.      * @param string $attr Name of attribute
  707.      * @return string The right name of the attribute
  708.      */
  709.     function _getAttrName($attr)
  710.     {
  711.         $name strtolower($attr);
  712.         if (array_key_exists($name$this->_map)) {
  713.             $attr $this->_map[$name];
  714.         }
  715.         return $attr;
  716.     }
  717.  
  718.     /**
  719.      * Returns a reference to the LDAP-Object of this entry
  720.      *
  721.      * @access public
  722.      * @return Net_LDAP|Net_LDAP_Error  Reference to the Net_LDAP Object (the connection) or Net_LDAP_Error
  723.      */
  724.     function &getLDAP()
  725.     {
  726.         if (!is_a($this->_ldap'Net_LDAP')) {
  727.             return PEAR::raiseError("LDAP is not a valid Net_LDAP object");
  728.         else {
  729.             return $this->_ldap;
  730.         }
  731.     }
  732.  
  733.     /**
  734.     * Applies a regular expression onto a single- or multivalued attribute (like preg_match())
  735.     *
  736.     * This method behaves like PHPs preg_match() but with some exceptions.
  737.     * If you want to retrieve match information, then you MUST pass the
  738.     * $matches parameter via reference! otherwise you will get no matches.
  739.     * Since it is possible to have multi valued attributes the $matches
  740.     * array will have a additionally numerical dimension (one for each value):
  741.     * <code>
  742.     * $matches = array(
  743.     *         0 => array (usual preg_match() returnarray),
  744.     *         1 => array (usual preg_match() returnarray)
  745.     *     )
  746.     * </code>
  747.     * Please note, that $matches will be initialized to an empty array inside.
  748.     *
  749.     * Usage example:
  750.     * <code>
  751.     * $result = $entry->preg_match('/089(\d+)/', 'telephoneNumber', &$matches);
  752.     * if ( $result === true ){
  753.     *     echo "First match: ".$matches[0][1];   // Match of value 1, content of first bracket
  754.     * } else {
  755.     *     if ( Net_LDAP::isError($result) ) {
  756.     *         echo "Error: ".$result->getMessage();
  757.     *     } else {
  758.     *         echo "No match found.";
  759.     *     }
  760.     * }
  761.     * </code>
  762.     *
  763.     * Please note that it is important to test for an Net_LDAP_Error, because objects are
  764.     * evaluating to true by default, thus if a error occured, and you only check using "==" then
  765.     * you get misleading results. Use the "identical" (===) operator to test for matches to
  766.     * avoid this as shown above.
  767.     *
  768.     * @param string $regex     The regular expression
  769.     * @param string $attr_name The attribute to search in
  770.     * @param array  $matches   (optional, PASS BY REFERENCE!) Array to store matches in
  771.     * @return boolean|Net_LDAP_Error TRUE, if we had a match in one of the values, otherwise false. Net_LDAP_Error in case something went wrong
  772.     */
  773.     function preg_match($regex$attr_name$matches = array()){
  774.         $matches = array();
  775.  
  776.         // fetch attribute values
  777.         $attr $this->getValue($attr_name'all');
  778.         if (Net_LDAP::isError($attr)) {
  779.             return $attr;
  780.         else {
  781.             unset($attr['count']);
  782.         }
  783.  
  784.         // perform preg_match() on all values
  785.         $match = false;
  786.         foreach ($attr as $thisvalue{
  787.             $matches_int = array();
  788.             if (preg_match($regex$thisvalue$matches_int)) {
  789.                 $match = true;
  790.                 array_push($matches$matches_int)// store matches in reference
  791.             }
  792.         }
  793.         return $match;
  794.     }
  795. }
  796. ?>

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