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

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