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

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