web/lib/Zend/Navigation/Container.php
changeset 807 877f952ae2bd
parent 207 621fa6caec0c
child 1230 68c69c656a2c
equal deleted inserted replaced
805:5e7a0fedabdf 807:877f952ae2bd
    12  * obtain it through the world-wide-web, please send an email
    12  * obtain it through the world-wide-web, please send an email
    13  * to license@zend.com so we can send you a copy immediately.
    13  * to license@zend.com so we can send you a copy immediately.
    14  *
    14  *
    15  * @category  Zend
    15  * @category  Zend
    16  * @package   Zend_Navigation
    16  * @package   Zend_Navigation
    17  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    17  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    18  * @license   http://framework.zend.com/license/new-bsd     New BSD License
    18  * @license   http://framework.zend.com/license/new-bsd     New BSD License
    19  * @version    $Id: Container.php 20096 2010-01-06 02:05:09Z bkarwin $
    19  * @version    $Id: Container.php 25237 2013-01-22 08:32:38Z frosch $
    20  */
    20  */
    21 
    21 
    22 /**
    22 /**
    23  * Zend_Navigation_Container
    23  * Zend_Navigation_Container
    24  *
    24  *
    25  * Container class for Zend_Navigation_Page classes.
    25  * Container class for Zend_Navigation_Page classes.
    26  *
    26  *
    27  * @category  Zend
    27  * @category  Zend
    28  * @package   Zend_Navigation
    28  * @package   Zend_Navigation
    29  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    29  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    30  * @license   http://framework.zend.com/license/new-bsd     New BSD License
    30  * @license   http://framework.zend.com/license/new-bsd     New BSD License
    31  */
    31  */
    32 abstract class Zend_Navigation_Container implements RecursiveIterator, Countable
    32 abstract class Zend_Navigation_Container implements RecursiveIterator, Countable
    33 {
    33 {
    34     /**
    34     /**
   141     }
   141     }
   142 
   142 
   143     /**
   143     /**
   144      * Adds several pages at once
   144      * Adds several pages at once
   145      *
   145      *
   146      * @param  array|Zend_Config $pages   pages to add
   146      * @param  array|Zend_Config|Zend_Navigation_Container  $pages  pages to add
   147      * @return Zend_Navigation_Container  fluent interface, returns self
   147      * @return Zend_Navigation_Container                    fluent interface,
   148      * @throws Zend_Navigation_Exception  if $pages is not array or Zend_Config
   148      *                                                      returns self
       
   149      * @throws Zend_Navigation_Exception                    if $pages is not 
       
   150      *                                                      array, Zend_Config or
       
   151      *                                                      Zend_Navigation_Container
   149      */
   152      */
   150     public function addPages($pages)
   153     public function addPages($pages)
   151     {
   154     {
   152         if ($pages instanceof Zend_Config) {
   155         if ($pages instanceof Zend_Config) {
   153             $pages = $pages->toArray();
   156             $pages = $pages->toArray();
       
   157         }
       
   158 
       
   159         if ($pages instanceof Zend_Navigation_Container) {
       
   160             $pages = iterator_to_array($pages);
   154         }
   161         }
   155 
   162 
   156         if (!is_array($pages)) {
   163         if (!is_array($pages)) {
   157             require_once 'Zend/Navigation/Exception.php';
   164             require_once 'Zend/Navigation/Exception.php';
   158             throw new Zend_Navigation_Exception(
   165             throw new Zend_Navigation_Exception(
   159                     'Invalid argument: $pages must be an array or an ' .
   166                     'Invalid argument: $pages must be an array, an ' .
   160                     'instance of Zend_Config');
   167                     'instance of Zend_Config or an instance of ' .
       
   168                     'Zend_Navigation_Container');
   161         }
   169         }
   162 
   170 
   163         foreach ($pages as $page) {
   171         foreach ($pages as $page) {
   164             $this->addPage($page);
   172             $this->addPage($page);
   165         }
   173         }
   264     {
   272     {
   265         return count($this->_index) > 0;
   273         return count($this->_index) > 0;
   266     }
   274     }
   267 
   275 
   268     /**
   276     /**
   269      * Returns a child page matching $property == $value, or null if not found
   277      * Returns a child page matching $property == $value or 
   270      *
   278      * preg_match($value, $property), or null if not found
   271      * @param  string $property           name of property to match against
   279      *
   272      * @param  mixed  $value              value to match property against
   280      * @param  string  $property          name of property to match against
       
   281      * @param  mixed   $value             value to match property against
       
   282      * @param  bool    $useRegex          [optional] if true PHP's preg_match
       
   283      *                                    is used. Default is false.
   273      * @return Zend_Navigation_Page|null  matching page or null
   284      * @return Zend_Navigation_Page|null  matching page or null
   274      */
   285      */
   275     public function findOneBy($property, $value)
   286     public function findOneBy($property, $value, $useRegex = false)
   276     {
   287     {        
   277         $iterator = new RecursiveIteratorIterator($this,
   288         $iterator = new RecursiveIteratorIterator(
   278                             RecursiveIteratorIterator::SELF_FIRST);
   289             $this,
       
   290             RecursiveIteratorIterator::SELF_FIRST
       
   291         );
   279 
   292 
   280         foreach ($iterator as $page) {
   293         foreach ($iterator as $page) {
   281             if ($page->get($property) == $value) {
   294             $pageProperty = $page->get($property);
   282                 return $page;
   295             
       
   296             // Rel and rev
       
   297             if (is_array($pageProperty)) {
       
   298                 foreach ($pageProperty as $item) {
       
   299                     if (is_array($item)) {
       
   300                         // Use regex?
       
   301                         if (true === $useRegex) {
       
   302                             foreach ($item as $item2) {
       
   303                                 if (0 !== preg_match($value, $item2)) {
       
   304                                     return $page;
       
   305                                 }
       
   306                             }
       
   307                         } else {
       
   308                             if (in_array($value, $item)) {
       
   309                                 return $page;
       
   310                             }
       
   311                         }
       
   312                     } else {
       
   313                         // Use regex?
       
   314                         if (true === $useRegex) {
       
   315                             if (0 !== preg_match($value, $item)) {
       
   316                                 return $page;
       
   317                             }
       
   318                         } else {
       
   319                             if ($item == $value) {
       
   320                                 return $page;
       
   321                             }
       
   322                         }
       
   323                     }
       
   324                 }
       
   325                 
       
   326                 continue;
   283             }
   327             }
   284         }
   328             
   285 
   329             // Use regex?
       
   330             if (true === $useRegex) {
       
   331                 if (preg_match($value, $pageProperty)) {
       
   332                     return $page;
       
   333                 }
       
   334             } else {
       
   335                 if ($pageProperty == $value) {
       
   336                     return $page;
       
   337                 }
       
   338             }
       
   339         }
       
   340         
   286         return null;
   341         return null;
   287     }
   342     }
   288 
   343 
   289     /**
   344     /**
   290      * Returns all child pages matching $property == $value, or an empty array
   345      * Returns all child pages matching $property == $value or
   291      * if no pages are found
   346      * preg_match($value, $property), or an empty array if no pages are found
   292      *
   347      *
   293      * @param  string $property  name of property to match against
   348      * @param  string $property  name of property to match against
   294      * @param  mixed  $value     value to match property against
   349      * @param  mixed  $value     value to match property against
       
   350      * @param  bool   $useRegex  [optional] if true PHP's preg_match is used.
       
   351      *                           Default is false.
   295      * @return array             array containing only Zend_Navigation_Page
   352      * @return array             array containing only Zend_Navigation_Page
   296      *                           instances
   353      *                           instances
   297      */
   354      */
   298     public function findAllBy($property, $value)
   355     public function findAllBy($property, $value, $useRegex = false)
   299     {
   356     {        
   300         $found = array();
   357         $found = array();
   301 
   358 
   302         $iterator = new RecursiveIteratorIterator($this,
   359         $iterator = new RecursiveIteratorIterator(
   303                             RecursiveIteratorIterator::SELF_FIRST);
   360             $this,
   304 
   361             RecursiveIteratorIterator::SELF_FIRST
       
   362         );
       
   363         
   305         foreach ($iterator as $page) {
   364         foreach ($iterator as $page) {
   306             if ($page->get($property) == $value) {
   365             $pageProperty = $page->get($property);
   307                 $found[] = $page;
   366             
       
   367             // Rel and rev
       
   368             if (is_array($pageProperty)) {
       
   369                 foreach ($pageProperty as $item) {
       
   370                     if (is_array($item)) {
       
   371                         // Use regex?
       
   372                         if (true === $useRegex) {
       
   373                             foreach ($item as $item2) {
       
   374                                 if (0 !== preg_match($value, $item2)) {
       
   375                                     $found[] = $page;
       
   376                                 }
       
   377                             }
       
   378                         } else {
       
   379                             if (in_array($value, $item)) {
       
   380                                 $found[] = $page;
       
   381                             }
       
   382                         }
       
   383                     } else {
       
   384                         // Use regex?
       
   385                         if (true === $useRegex) {
       
   386                             if (0 !== preg_match($value, $item)) {
       
   387                                 $found[] = $page;
       
   388                             }
       
   389                         } else {
       
   390                             if ($item == $value) {
       
   391                                 $found[] = $page;
       
   392                             }
       
   393                         }
       
   394                     }
       
   395                 }
       
   396                 
       
   397                 continue;
   308             }
   398             }
       
   399             
       
   400             // Use regex?
       
   401             if (true === $useRegex) {
       
   402                 if (0 !== preg_match($value, $pageProperty)) {
       
   403                     $found[] = $page;
       
   404                 }
       
   405             } else {
       
   406                 if ($pageProperty == $value) {
       
   407                     $found[] = $page;
       
   408                 }
       
   409             }
   309         }
   410         }
   310 
   411 
   311         return $found;
   412         return $found;
   312     }
   413     }
   313 
   414 
   314     /**
   415     /**
   315      * Returns page(s) matching $property == $value
   416      * Returns page(s) matching $property == $value or
       
   417      * preg_match($value, $property)
   316      *
   418      *
   317      * @param  string $property  name of property to match against
   419      * @param  string $property  name of property to match against
   318      * @param  mixed  $value     value to match property against
   420      * @param  mixed  $value     value to match property against
   319      * @param  bool   $all       [optional] whether an array of all matching
   421      * @param  bool   $all       [optional] whether an array of all matching
   320      *                           pages should be returned, or only the first.
   422      *                           pages should be returned, or only the first.
   321      *                           If true, an array will be returned, even if not
   423      *                           If true, an array will be returned, even if not
   322      *                           matching pages are found. If false, null will
   424      *                           matching pages are found. If false, null will
   323      *                           be returned if no matching page is found.
   425      *                           be returned if no matching page is found.
   324      *                           Default is false.
   426      *                           Default is false.
       
   427      * @param  bool   $useRegex  [optional] if true PHP's preg_match is used.
       
   428      *                           Default is false.
   325      * @return Zend_Navigation_Page|null  matching page or null
   429      * @return Zend_Navigation_Page|null  matching page or null
   326      */
   430      */
   327     public function findBy($property, $value, $all = false)
   431     public function findBy($property, $value, $all = false, $useRegex = false)
   328     {
   432     {
   329         if ($all) {
   433         if ($all) {
   330             return $this->findAllBy($property, $value);
   434             return $this->findAllBy($property, $value, $useRegex);
   331         } else {
   435         } else {
   332             return $this->findOneBy($property, $value);
   436             return $this->findOneBy($property, $value, $useRegex);
   333         }
   437         }
   334     }
   438     }
   335 
   439 
   336     /**
   440     /**
   337      * Magic overload: Proxy calls to finder methods
   441      * Magic overload: Proxy calls to finder methods
   338      *
   442      *
   339      * Examples of finder calls:
   443      * Examples of finder calls:
   340      * <code>
   444      * <code>
   341      * // METHOD                    // SAME AS
   445      * // METHOD                         // SAME AS
   342      * $nav->findByLabel('foo');    // $nav->findOneBy('label', 'foo');
   446      * $nav->findByLabel('foo');         // $nav->findOneBy('label', 'foo');
   343      * $nav->findOneByLabel('foo'); // $nav->findOneBy('label', 'foo');
   447      * $nav->findByLabel('/foo/', true); // $nav->findBy('label', '/foo/', true);
   344      * $nav->findAllByClass('foo'); // $nav->findAllBy('class', 'foo');
   448      * $nav->findOneByLabel('foo');      // $nav->findOneBy('label', 'foo');
       
   449      * $nav->findAllByClass('foo');      // $nav->findAllBy('class', 'foo');
   345      * </code>
   450      * </code>
   346      *
   451      *
   347      * @param  string $method             method name
   452      * @param  string $method                       method name
   348      * @param  array  $arguments          method arguments
   453      * @param  array  $arguments                    method arguments
   349      * @throws Zend_Navigation_Exception  if method does not exist
   454      * @return mixed  Zend_Navigation|array|null    matching page, array of pages
       
   455      *                                              or null
       
   456      * @throws Zend_Navigation_Exception            if method does not exist
   350      */
   457      */
   351     public function __call($method, $arguments)
   458     public function __call($method, $arguments)
   352     {
   459     {
   353         if (@preg_match('/(find(?:One|All)?By)(.+)/', $method, $match)) {
   460         if (@preg_match('/(find(?:One|All)?By)(.+)/', $method, $match)) {
   354             return $this->{$match[1]}($match[2], $arguments[0]);
   461             return $this->{$match[1]}($match[2], $arguments[0], !empty($arguments[1]));
   355         }
   462         }
   356 
   463 
   357         require_once 'Zend/Navigation/Exception.php';
   464         require_once 'Zend/Navigation/Exception.php';
   358         throw new Zend_Navigation_Exception(sprintf(
   465         throw new Zend_Navigation_Exception(
       
   466             sprintf(
   359                 'Bad method call: Unknown method %s::%s',
   467                 'Bad method call: Unknown method %s::%s',
   360                 get_class($this),
   468                 get_class($this),
   361                 $method));
   469                 $method
       
   470             )
       
   471         );
   362     }
   472     }
   363 
   473 
   364     /**
   474     /**
   365      * Returns an array representation of all pages in container
   475      * Returns an array representation of all pages in container
   366      *
   476      *
   367      * @return array
   477      * @return array
   368      */
   478      */
   369     public function toArray()
   479     public function toArray()
   370     {
   480     {
   371         $pages = array();
   481         $pages = array();
   372         
   482 
   373         $this->_dirtyIndex = true;
   483         $this->_dirtyIndex = true;
   374         $this->_sort();
   484         $this->_sort();
   375         $indexes = array_keys($this->_index);
   485         $indexes = array_keys($this->_index);
   376         foreach ($indexes as $hash) {
   486         foreach ($indexes as $hash) {
   377             $pages[] = $this->_pages[$hash]->toArray();
   487             $pages[] = $this->_pages[$hash]->toArray();