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

Source for file Search.php

Documentation is available at Search.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: Tarjej Huse                                                     |
  23. // +--------------------------------------------------------------------------+
  24. //
  25. // $Id: Search.php,v 1.16 2007/01/10 07:38:02 beni Exp $
  26.  
  27. /**
  28.  * Result set of an LDAP search
  29.  *
  30.  * @author  Tarjei Huse
  31.  * @version $Revision: 1.16 $
  32.  * @package Net_LDAP
  33.  */
  34. class Net_LDAP_Search extends PEAR
  35. {
  36.     /**
  37.      * Search result identifier
  38.      *
  39.      * @access private
  40.      * @var resource 
  41.      */
  42.     var $_search;
  43.  
  44.     /**
  45.      * LDAP resource link
  46.      *
  47.      * @access private
  48.      * @var resource 
  49.      */
  50.     var $_link;
  51.  
  52.     /**
  53.      * Net_LDAP object
  54.      *
  55.      * A reference of the Net_LDAP object for passing to Net_LDAP_Entry
  56.      *
  57.      * @access private
  58.      * @var object Net_LDAP 
  59.      */
  60.     var $_ldap;
  61.  
  62.     /**
  63.      * Result entry identifier
  64.      *
  65.      * @access private
  66.      * @var resource 
  67.      */
  68.     var $_entry = null;
  69.  
  70.     /**
  71.      * The errorcode the search got
  72.      *
  73.      * Some errorcodes might be of interest, but might not be best handled as errors.
  74.      * examples: 4 - LDAP_SIZELIMIT_EXCEEDED - indicates a huge search.
  75.      *               Incomplete results are returned. If you just want to check if there's anything in the search.
  76.      *               than this is a point to handle.
  77.      *           32 - no such object - search here returns a count of 0.
  78.      *
  79.      * @access private
  80.      * @var int 
  81.      */
  82.     var $_errorCode = 0; // if not set - sucess!
  83.     
  84.     /**
  85.     * What attributes we searched for
  86.     *
  87.     * The $attributes array contains the names of the searched attributes and gets
  88.     * passed from $Net_LDAP->search() so the Net_LDAP_Search object can tell
  89.     * what attributes was searched for ({@link _searchedAttrs())}
  90.     *
  91.     * This variable gets set from the constructor and returned
  92.     * from {@link _searchedAttrs()}
  93.     *
  94.     * @access private
  95.     * @var array 
  96.     */
  97.     var $_searchedAttrs = array();
  98.  
  99.    /**
  100.     * Constructor
  101.     *
  102.     * @access protected
  103.     * @param resource $search         Search result identifier
  104.     * @param Net_LDAP|resource$ldap  Net_LDAP object or just a LDAP-Link resource
  105.     * @param array $attributes        (optional) Array with searched attribute names. (see {@link $_searchedAttrs})
  106.     */
  107.     function Net_LDAP_Search(&$search&$ldap$attributes = array())
  108.     {
  109.         $this->PEAR('Net_LDAP_Error');
  110.  
  111.         $this->setSearch($search);
  112.  
  113.         if (is_a($ldap'Net_LDAP')) {
  114.             $this->_ldap =$ldap;
  115.             $this->setLink($this->_ldap->getLink());
  116.         else {
  117.             $this->setLink($ldap);
  118.         }
  119.  
  120.         $this->_errorCode @ldap_errno($this->_link);
  121.  
  122.         if (is_array($attributes&& !empty($attributes)) {
  123.             $this->_searchedAttrs $attributes;
  124.         }
  125.     }
  126.  
  127.     /**
  128.      * Returns an assosiative array of entry objects
  129.      *
  130.      * @return array Array of entry objects.
  131.      */
  132.     function entries()
  133.     {
  134.         $entries = array();
  135.  
  136.         while ($entry $this->shiftEntry()) {
  137.             $entries[$entry;
  138.         }
  139.  
  140.         return $entries;
  141.     }
  142.  
  143.     /**
  144.      * Get the next entry in the searchresult.
  145.      *
  146.      * @return Net_LDAP_Entry|false Reference to Net_LDAP_Entry object or false
  147.      */
  148.     function &shiftEntry()
  149.     {
  150.         if ($this->count(== 0 {
  151.             return false;
  152.         }
  153.  
  154.         if (is_null($this->_entry)) {
  155.             $this->_entry @ldap_first_entry($this->_link$this->_search);
  156.             $entry = new Net_LDAP_Entry($this->_ldap$this->_entry);
  157.         else {
  158.             if (!$this->_entry @ldap_next_entry($this->_link$this->_entry)) {
  159.                 return false;
  160.             }
  161.             $entry = new Net_LDAP_Entry($this->_ldap$this->_entry);
  162.         }
  163.         return $entry;
  164.     }
  165.  
  166.     /**
  167.      * alias function of shiftEntry() for perl-ldap interface
  168.      *
  169.      * @see shiftEntry()
  170.      */
  171.     function shift_entry()
  172.     {
  173.         $args func_get_args();
  174.         return call_user_func_array(array&$this'shiftEntry' )$args);
  175.     }
  176.  
  177.     /**
  178.      * Retrieve the last entry of the searchset. NOT IMPLEMENTED
  179.      *
  180.      * @return Net_LDAP_Error 
  181.      * @todo implement me!
  182.      */
  183.     function pop_entry()
  184.     {
  185.         PEAR::raiseError("Not implemented");
  186.     }
  187.  
  188.     /**
  189.     * Return entries sorted as array
  190.     *
  191.     * This returns a array with sorted entries and the values.
  192.     * Sorting is done with PHPs {@link array_multisort()}.
  193.     * This method relies on {@link as_struct()} to fetch the raw data of the entries.
  194.     *
  195.     * Please note that attribute names are case sensitive!
  196.     *
  197.     * Usage example:
  198.     * <code>
  199.     *   // to sort entries first by location, then by surename, but descending:
  200.     *   $entries = $search->sorted_as_struct(array('locality','sn'), SORT_DESC);
  201.     * </code>
  202.     *
  203.     * @param array      $attrs Array of attribute names to sort; order from left to right.
  204.     * @param int        $order Ordering direction, either constant SORT_ASC or SORT_DESC
  205.     * @return array|Net_LDAP_Error  Array with sorted entries or error
  206.     */
  207.     function sorted_as_struct($attrs = array('cn')$order = SORT_ASC)
  208.     {
  209.         /*
  210.         * Old Code, suitable and fast for single valued sorting
  211.         * This code should be used if we know that single valued sorting is desired,
  212.         * but we need some method to get that knowledge...
  213.         */
  214.         /*
  215.         $attrs = array_reverse($attrs);
  216.         foreach ($attrs as $attribute) {
  217.             if (!ldap_sort($this->_link, $this->_search, $attribute)){
  218.                 $this->raiseError("Sorting failed for Attribute " . $attribute);
  219.             }
  220.         }
  221.  
  222.         $results = ldap_get_entries($this->_link, $this->_search);
  223.  
  224.         unset($results['count']); //for tidier output
  225.         if ($order) {
  226.             return array_reverse($results);
  227.         } else {
  228.             return $results;
  229.         }*/
  230.  
  231.         /*
  232.         * New code: complete "client side" sorting
  233.         */
  234.         // first some parameterchecks
  235.         if (!is_array($attrs)) {
  236.             return PEAR::raiseError("Sorting failed: Parameterlist must be an array!");
  237.         }
  238.         if ($order != SORT_ASC && $order != SORT_DESC{
  239.             return PEAR::raiseError("Sorting failed: sorting direction not understood! (neither constant SORT_ASC nor SORT_DESC)");
  240.         }
  241.  
  242.         // fetch the entries data
  243.         $entries $this->as_struct();
  244.  
  245.         // now sort each entries attribute values
  246.         // this is neccessary because later we can only sort by one value,
  247.         // so we need the highest or lowest attribute now, depending on the
  248.         // selected ordering for that specific attribute
  249.         foreach ($entries as $dn => $entry{
  250.             foreach ($entry as $attr_name => $attr_values{
  251.                 sort($entries[$dn][$attr_name]);
  252.                 if($order == SORT_DESC{
  253.                     array_reverse($entries[$dn][$attr_name]);
  254.                 }
  255.             }
  256.         }
  257.  
  258.         // reformat entrys array for later use with array_multisort()
  259.         $to_sort = array()// <- will be a numeric array similar to ldap_get_entries
  260.         foreach ($entries as $dn => $entry_attr{
  261.             $row = array();
  262.             $row['dn'$dn;
  263.             foreach ($entry_attr as $attr_name => $attr_values{
  264.                 $row[$attr_name$attr_values;
  265.             }
  266.             $to_sort[$row;
  267.         }
  268.  
  269.         // Build columns for array_multisort()
  270.         // each requested attribute is one row
  271.         $columns = array();
  272.         foreach ($attrs as $attr_name{
  273.             foreach ($to_sort as $key => $row{
  274.                 $columns[$attr_name][$key=$to_sort[$key][$attr_name][0];
  275.             }
  276.         }
  277.  
  278.         // sort the colums with array_multisort
  279.         $sort_params '';
  280.         foreach ($attrs as $attr_name{
  281.             $sort_params .= '$columns[\''.$attr_name.'\'], '.$order.', ';
  282.         }
  283.         eval("array_multisort($sort_params \$to_sort);")// perform sorting
  284.  
  285.         return $to_sort;
  286.     }
  287.  
  288.     /**
  289.     * Return entries sorted as objects
  290.     *
  291.     * This returns a array with sorted Net_LDAP_Entry objects.
  292.     * The sorting is actually done with {@link sorted_as_struct()}.
  293.     *
  294.     * Please note that attribute names are case sensitive!
  295.     *
  296.     * Usage example:
  297.     * <code>
  298.     *   // to sort entries first by location, then by surename, but descending:
  299.     *   $entries = $search->sorted(array('locality','sn'), SORT_DESC);
  300.     * </code>
  301.     *
  302.     * @param array      $attrs Array of sort attributes to sort; order from left to right.
  303.     * @param int        $order Ordering direction, either constant SORT_ASC or SORT_DESC
  304.     * @return array|Net_LDAP_Error  Array with sorted Net_LDAP_Entries or error
  305.     */
  306.     function sorted($attrs = array('cn')$order = SORT_ASC{
  307.         $return = array();
  308.         $sorted $this->sorted_as_struct($attrs$order);
  309.         if (PEAR::isError($sorted)) {
  310.             return $sorted;
  311.         }
  312.         foreach ($sorted as $key => $row{
  313.             $entry $this->_ldap->getEntry($row['dn']$this->_searchedAttrs());
  314.             if (!PEAR::isError($entry)) {
  315.                 array_push($return$entry);
  316.             else {
  317.                 return $entry;
  318.             }
  319.         }
  320.         return $return;
  321.     }
  322.  
  323.    /**
  324.     * Return entries as array
  325.     *
  326.     * This method returns the entries and the selected attributes values as
  327.     * array.
  328.     * The first array level contains all found entries where the keys are the
  329.     * DNs of the entries. The second level arrays contian the entries attributes
  330.     * such that the keys is the lowercased name of the attribute and the values
  331.     * are stored in another indexed array. Note that the attribute values are stored
  332.     * in an array even if there is no or just one value.
  333.     *
  334.     * The array has the following structure:
  335.     * <code>
  336.     * $return = array(
  337.     *           'cn=foo,dc=example,dc=com' => array(
  338.     *                                                'sn'       => array('foo'),
  339.     *                                                'multival' => array('val1', 'val2', 'valN')
  340.     *                                             )
  341.     *           'cn=bar,dc=example,dc=com' => array(
  342.     *                                                'sn'       => array('bar'),
  343.     *                                                'multival' => array('val1', 'valN')
  344.     *                                             )
  345.     *           )
  346.     * </code>
  347.     *
  348.     * @return array      associative result array as described above
  349.     */
  350.     function as_struct()
  351.     {
  352.         $return = array();
  353.         $entries $this->entries();
  354.         foreach ($entries as $entry{
  355.             $attrs = array();
  356.             $entry_attributes $entry->attributes();
  357.             foreach ($entry_attributes as $attr_name{
  358.                 $attr_values $entry->getValue($attr_name'all');
  359.                 if (!is_array($attr_values)) {
  360.                     $attr_values = array($attr_values);
  361.                 }
  362.                 $attrs[$attr_name$attr_values;
  363.             }
  364.             $return[$entry->dn()$attrs;
  365.         }
  366.         return $return;
  367.     }
  368.  
  369.    /**
  370.     * Set the search objects resource link
  371.     *
  372.     * @access public
  373.     * @param resource $search Search result identifier
  374.     * @return void 
  375.     */
  376.     function setSearch(&$search)
  377.     {
  378.         $this->_search $search;
  379.     }
  380.  
  381.    /**
  382.     * Set the ldap ressource link
  383.     *
  384.     * @access public
  385.     * @param resource $link Link identifier
  386.     * @return void 
  387.     */
  388.     function setLink(&$link)
  389.     {
  390.         $this->_link $link;
  391.     }
  392.  
  393.    /**
  394.     * Returns the number of entries in the searchresult
  395.     *
  396.     * @return int Number of entries in search.
  397.     */
  398.     function count()
  399.     {
  400.         /* this catches the situation where OL returned errno 32 = no such object! */
  401.         if (!$this->_search{
  402.             return 0;
  403.         }
  404.         return @ldap_count_entries($this->_link$this->_search);
  405.     }
  406.  
  407.     /**
  408.      * Get the errorcode the object got in its search.
  409.      *
  410.      * @return int The ldap error number.
  411.      */
  412.     function getErrorCode()
  413.     {
  414.         return $this->_errorCode;
  415.     }
  416.  
  417.    /**
  418.     * Destructor
  419.     *
  420.     * @access protected
  421.     */
  422.     function _Net_LDAP_Search()
  423.     {
  424.         @ldap_free_result($this->_search);
  425.     }
  426.  
  427.    /**
  428.     * Closes search result
  429.     */
  430.     function done()
  431.     {
  432.         $this->_Net_LDAP_Search();
  433.     }
  434.  
  435.     /**
  436.     * Return the attribute names this search selected
  437.     *
  438.     * @return array 
  439.     * @see $_searchedAttrs
  440.     * @access private
  441.     */
  442.     function _searchedAttrs()
  443.     {
  444.         return $this->_searchedAttrs;
  445.     }
  446. }
  447.  
  448. ?>

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