web/enmi/Zend/Navigation/Page.php
changeset 19 1c2f13fd785c
parent 0 4eba9c11703f
equal deleted inserted replaced
18:bd595ad770fc 19:1c2f13fd785c
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    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.
       
    14  *
       
    15  * @category  Zend
       
    16  * @package   Zend_Navigation
       
    17  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    18  * @license   http://framework.zend.com/license/new-bsd     New BSD License
       
    19  * @version    $Id: Page.php 22882 2010-08-22 14:00:16Z freak $
       
    20  */
       
    21 
       
    22 /**
       
    23  * @see Zend_Navigation_Container
       
    24  */
       
    25 require_once 'Zend/Navigation/Container.php';
       
    26 
       
    27 /**
       
    28  * Base class for Zend_Navigation_Page pages
       
    29  *
       
    30  * @category  Zend
       
    31  * @package   Zend_Navigation
       
    32  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    33  * @license   http://framework.zend.com/license/new-bsd     New BSD License
       
    34  */
       
    35 abstract class Zend_Navigation_Page extends Zend_Navigation_Container
       
    36 {
       
    37     /**
       
    38      * Page label
       
    39      *
       
    40      * @var string|null
       
    41      */
       
    42     protected $_label;
       
    43 
       
    44     /**
       
    45      * Page id
       
    46      *
       
    47      * @var string|null
       
    48      */
       
    49     protected $_id;
       
    50 
       
    51     /**
       
    52      * Style class for this page (CSS)
       
    53      *
       
    54      * @var string|null
       
    55      */
       
    56     protected $_class;
       
    57 
       
    58     /**
       
    59      * A more descriptive title for this page
       
    60      *
       
    61      * @var string|null
       
    62      */
       
    63     protected $_title;
       
    64 
       
    65     /**
       
    66      * This page's target
       
    67      *
       
    68      * @var string|null
       
    69      */
       
    70     protected $_target;
       
    71 
       
    72     /**
       
    73      * Forward links to other pages
       
    74      *
       
    75      * @link http://www.w3.org/TR/html4/struct/links.html#h-12.3.1
       
    76      *
       
    77      * @var array
       
    78      */
       
    79     protected $_rel = array();
       
    80 
       
    81     /**
       
    82      * Reverse links to other pages
       
    83      *
       
    84      * @link http://www.w3.org/TR/html4/struct/links.html#h-12.3.1
       
    85      *
       
    86      * @var array
       
    87      */
       
    88     protected $_rev = array();
       
    89 
       
    90     /**
       
    91      * Page order used by parent container
       
    92      *
       
    93      * @var int|null
       
    94      */
       
    95     protected $_order;
       
    96 
       
    97     /**
       
    98      * ACL resource associated with this page
       
    99      *
       
   100      * @var string|Zend_Acl_Resource_Interface|null
       
   101      */
       
   102     protected $_resource;
       
   103 
       
   104     /**
       
   105      * ACL privilege associated with this page
       
   106      *
       
   107      * @var string|null
       
   108      */
       
   109     protected $_privilege;
       
   110 
       
   111     /**
       
   112      * Whether this page should be considered active
       
   113      *
       
   114      * @var bool
       
   115      */
       
   116     protected $_active = false;
       
   117 
       
   118     /**
       
   119      * Whether this page should be considered visible
       
   120      *
       
   121      * @var bool
       
   122      */
       
   123     protected $_visible = true;
       
   124 
       
   125     /**
       
   126      * Parent container
       
   127      *
       
   128      * @var Zend_Navigation_Container|null
       
   129      */
       
   130     protected $_parent;
       
   131 
       
   132     /**
       
   133      * Custom page properties, used by __set(), __get() and __isset()
       
   134      *
       
   135      * @var array
       
   136      */
       
   137     protected $_properties = array();
       
   138 
       
   139     /**
       
   140      * The type of page to use when it wasn't set
       
   141      * 
       
   142      * @var string
       
   143      */
       
   144     protected static $_defaultPageType;
       
   145     
       
   146     // Initialization:
       
   147 
       
   148     /**
       
   149      * Factory for Zend_Navigation_Page classes
       
   150      *
       
   151      * A specific type to construct can be specified by specifying the key
       
   152      * 'type' in $options. If type is 'uri' or 'mvc', the type will be resolved
       
   153      * to Zend_Navigation_Page_Uri or Zend_Navigation_Page_Mvc. Any other value
       
   154      * for 'type' will be considered the full name of the class to construct.
       
   155      * A valid custom page class must extend Zend_Navigation_Page.
       
   156      *
       
   157      * If 'type' is not given, the type of page to construct will be determined
       
   158      * by the following rules:
       
   159      * - If $options contains either of the keys 'action', 'controller',
       
   160      *   'module', or 'route', a Zend_Navigation_Page_Mvc page will be created.
       
   161      * - If $options contains the key 'uri', a Zend_Navigation_Page_Uri page
       
   162      *   will be created.
       
   163      *
       
   164      * @param  array|Zend_Config $options  options used for creating page
       
   165      * @return Zend_Navigation_Page        a page instance
       
   166      * @throws Zend_Navigation_Exception   if $options is not array/Zend_Config
       
   167      * @throws Zend_Exception              if 'type' is specified and
       
   168      *                                     Zend_Loader is unable to load the
       
   169      *                                     class
       
   170      * @throws Zend_Navigation_Exception   if something goes wrong during
       
   171      *                                     instantiation of the page
       
   172      * @throws Zend_Navigation_Exception   if 'type' is given, and the specified
       
   173      *                                     type does not extend this class
       
   174      * @throws Zend_Navigation_Exception   if unable to determine which class
       
   175      *                                     to instantiate
       
   176      */
       
   177     public static function factory($options)
       
   178     {
       
   179         if ($options instanceof Zend_Config) {
       
   180             $options = $options->toArray();
       
   181         }
       
   182 
       
   183         if (!is_array($options)) {
       
   184             require_once 'Zend/Navigation/Exception.php';
       
   185             throw new Zend_Navigation_Exception(
       
   186                 'Invalid argument: $options must be an array or Zend_Config');
       
   187         }
       
   188 
       
   189         if (isset($options['type'])) {
       
   190             $type = $options['type'];
       
   191         } elseif(self::getDefaultPageType()!= null) {
       
   192             $type = self::getDefaultPageType();
       
   193         }
       
   194         
       
   195         if(isset($type)) {
       
   196             if (is_string($type) && !empty($type)) {
       
   197                 switch (strtolower($type)) {
       
   198                     case 'mvc':
       
   199                         $type = 'Zend_Navigation_Page_Mvc';
       
   200                         break;
       
   201                     case 'uri':
       
   202                         $type = 'Zend_Navigation_Page_Uri';
       
   203                         break;
       
   204                 }
       
   205 
       
   206                 if (!class_exists($type)) {
       
   207                     require_once 'Zend/Loader.php';
       
   208                     @Zend_Loader::loadClass($type);
       
   209                 }
       
   210 
       
   211                 $page = new $type($options);
       
   212                 if (!$page instanceof Zend_Navigation_Page) {
       
   213                     require_once 'Zend/Navigation/Exception.php';
       
   214                     throw new Zend_Navigation_Exception(sprintf(
       
   215                             'Invalid argument: Detected type "%s", which ' .
       
   216                             'is not an instance of Zend_Navigation_Page',
       
   217                             $type));
       
   218                 }
       
   219                 return $page;
       
   220             }
       
   221         }
       
   222 
       
   223         $hasUri = isset($options['uri']);
       
   224         $hasMvc = isset($options['action']) || isset($options['controller']) ||
       
   225                   isset($options['module']) || isset($options['route']);
       
   226 
       
   227         if ($hasMvc) {
       
   228             require_once 'Zend/Navigation/Page/Mvc.php';
       
   229             return new Zend_Navigation_Page_Mvc($options);
       
   230         } elseif ($hasUri) {
       
   231             require_once 'Zend/Navigation/Page/Uri.php';
       
   232             return new Zend_Navigation_Page_Uri($options);
       
   233         } else {
       
   234             require_once 'Zend/Navigation/Exception.php';
       
   235             throw new Zend_Navigation_Exception(
       
   236                 'Invalid argument: Unable to determine class to instantiate');
       
   237         }
       
   238     }
       
   239 
       
   240     /**
       
   241      * Page constructor
       
   242      *
       
   243      * @param  array|Zend_Config $options   [optional] page options. Default is
       
   244      *                                      null, which should set defaults.
       
   245      * @throws Zend_Navigation_Exception    if invalid options are given
       
   246      */
       
   247     public function __construct($options = null)
       
   248     {
       
   249         if (is_array($options)) {
       
   250             $this->setOptions($options);
       
   251         } elseif ($options instanceof Zend_Config) {
       
   252             $this->setConfig($options);
       
   253         }
       
   254 
       
   255         // do custom initialization
       
   256         $this->_init();
       
   257     }
       
   258 
       
   259     /**
       
   260      * Initializes page (used by subclasses)
       
   261      *
       
   262      * @return void
       
   263      */
       
   264     protected function _init()
       
   265     {
       
   266     }
       
   267 
       
   268     /**
       
   269      * Sets page properties using a Zend_Config object
       
   270      *
       
   271      * @param  Zend_Config $config        config object to get properties from
       
   272      * @return Zend_Navigation_Page       fluent interface, returns self
       
   273      * @throws Zend_Navigation_Exception  if invalid options are given
       
   274      */
       
   275     public function setConfig(Zend_Config $config)
       
   276     {
       
   277         return $this->setOptions($config->toArray());
       
   278     }
       
   279 
       
   280     /**
       
   281      * Sets page properties using options from an associative array
       
   282      *
       
   283      * Each key in the array corresponds to the according set*() method, and
       
   284      * each word is separated by underscores, e.g. the option 'target'
       
   285      * corresponds to setTarget(), and the option 'reset_params' corresponds to
       
   286      * the method setResetParams().
       
   287      *
       
   288      * @param  array $options             associative array of options to set
       
   289      * @return Zend_Navigation_Page       fluent interface, returns self
       
   290      * @throws Zend_Navigation_Exception  if invalid options are given
       
   291      */
       
   292     public function setOptions(array $options)
       
   293     {
       
   294         foreach ($options as $key => $value) {
       
   295             $this->set($key, $value);
       
   296         }
       
   297 
       
   298         return $this;
       
   299     }
       
   300 
       
   301     // Accessors:
       
   302 
       
   303     /**
       
   304      * Sets page label
       
   305      *
       
   306      * @param  string $label              new page label
       
   307      * @return Zend_Navigation_Page       fluent interface, returns self
       
   308      * @throws Zend_Navigation_Exception  if empty/no string is given
       
   309      */
       
   310     public function setLabel($label)
       
   311     {
       
   312         if (null !== $label && !is_string($label)) {
       
   313             require_once 'Zend/Navigation/Exception.php';
       
   314             throw new Zend_Navigation_Exception(
       
   315                     'Invalid argument: $label must be a string or null');
       
   316         }
       
   317 
       
   318         $this->_label = $label;
       
   319         return $this;
       
   320     }
       
   321 
       
   322     /**
       
   323      * Returns page label
       
   324      *
       
   325      * @return string  page label or null
       
   326      */
       
   327     public function getLabel()
       
   328     {
       
   329         return $this->_label;
       
   330     }
       
   331 
       
   332     /**
       
   333      * Sets page id
       
   334      *
       
   335      * @param  string|null $id            [optional] id to set. Default is null,
       
   336      *                                    which sets no id.
       
   337      * @return Zend_Navigation_Page       fluent interface, returns self
       
   338      * @throws Zend_Navigation_Exception  if not given string or null
       
   339      */
       
   340     public function setId($id = null)
       
   341     {
       
   342         if (null !== $id && !is_string($id) && !is_numeric($id)) {
       
   343             require_once 'Zend/Navigation/Exception.php';
       
   344             throw new Zend_Navigation_Exception(
       
   345                     'Invalid argument: $id must be a string, number or null');
       
   346         }
       
   347 
       
   348         $this->_id = null === $id ? $id : (string) $id;
       
   349 
       
   350         return $this;
       
   351     }
       
   352 
       
   353     /**
       
   354      * Returns page id
       
   355      *
       
   356      * @return string|null  page id or null
       
   357      */
       
   358     public function getId()
       
   359     {
       
   360         return $this->_id;
       
   361     }
       
   362 
       
   363     /**
       
   364      * Sets page CSS class
       
   365      *
       
   366      * @param  string|null $class         [optional] CSS class to set. Default
       
   367      *                                    is null, which sets no CSS class.
       
   368      * @return Zend_Navigation_Page       fluent interface, returns self
       
   369      * @throws Zend_Navigation_Exception  if not given string or null
       
   370      */
       
   371     public function setClass($class = null)
       
   372     {
       
   373         if (null !== $class && !is_string($class)) {
       
   374             require_once 'Zend/Navigation/Exception.php';
       
   375             throw new Zend_Navigation_Exception(
       
   376                     'Invalid argument: $class must be a string or null');
       
   377         }
       
   378 
       
   379         $this->_class = $class;
       
   380         return $this;
       
   381     }
       
   382 
       
   383     /**
       
   384      * Returns page class (CSS)
       
   385      *
       
   386      * @return string|null  page's CSS class or null
       
   387      */
       
   388     public function getClass()
       
   389     {
       
   390         return $this->_class;
       
   391     }
       
   392 
       
   393     /**
       
   394      * Sets page title
       
   395      *
       
   396      * @param  string $title              [optional] page title. Default is
       
   397      *                                    null, which sets no title.
       
   398      * @return Zend_Navigation_Page       fluent interface, returns self
       
   399      * @throws Zend_Navigation_Exception  if not given string or null
       
   400      */
       
   401     public function setTitle($title = null)
       
   402     {
       
   403         if (null !== $title && !is_string($title)) {
       
   404             require_once 'Zend/Navigation/Exception.php';
       
   405             throw new Zend_Navigation_Exception(
       
   406                     'Invalid argument: $title must be a non-empty string');
       
   407         }
       
   408 
       
   409         $this->_title = $title;
       
   410         return $this;
       
   411     }
       
   412 
       
   413     /**
       
   414      * Returns page title
       
   415      *
       
   416      * @return string|null  page title or null
       
   417      */
       
   418     public function getTitle()
       
   419     {
       
   420         return $this->_title;
       
   421     }
       
   422 
       
   423     /**
       
   424      * Sets page target
       
   425      *
       
   426      * @param  string|null $target        [optional] target to set. Default is
       
   427      *                                    null, which sets no target.
       
   428      * @return Zend_Navigation_Page       fluent interface, returns self
       
   429      * @throws Zend_Navigation_Exception  if target is not string or null
       
   430      */
       
   431     public function setTarget($target = null)
       
   432     {
       
   433         if (null !== $target && !is_string($target)) {
       
   434             require_once 'Zend/Navigation/Exception.php';
       
   435             throw new Zend_Navigation_Exception(
       
   436                     'Invalid argument: $target must be a string or null');
       
   437         }
       
   438 
       
   439         $this->_target = $target;
       
   440         return $this;
       
   441     }
       
   442 
       
   443     /**
       
   444      * Returns page target
       
   445      *
       
   446      * @return string|null  page target or null
       
   447      */
       
   448     public function getTarget()
       
   449     {
       
   450         return $this->_target;
       
   451     }
       
   452 
       
   453     /**
       
   454      * Sets the page's forward links to other pages
       
   455      *
       
   456      * This method expects an associative array of forward links to other pages,
       
   457      * where each element's key is the name of the relation (e.g. alternate,
       
   458      * prev, next, help, etc), and the value is a mixed value that could somehow
       
   459      * be considered a page.
       
   460      *
       
   461      * @param  array|Zend_Config $relations  [optional] an associative array of
       
   462      *                                       forward links to other pages
       
   463      * @return Zend_Navigation_Page          fluent interface, returns self
       
   464      */
       
   465     public function setRel($relations = null)
       
   466     {
       
   467         $this->_rel = array();
       
   468 
       
   469         if (null !== $relations) {
       
   470             if ($relations instanceof Zend_Config) {
       
   471                 $relations = $relations->toArray();
       
   472             }
       
   473 
       
   474             if (!is_array($relations)) {
       
   475                 require_once 'Zend/Navigation/Exception.php';
       
   476                 throw new Zend_Navigation_Exception(
       
   477                         'Invalid argument: $relations must be an ' .
       
   478                         'array or an instance of Zend_Config');
       
   479             }
       
   480 
       
   481             foreach ($relations as $name => $relation) {
       
   482                 if (is_string($name)) {
       
   483                     $this->_rel[$name] = $relation;
       
   484                 }
       
   485             }
       
   486         }
       
   487 
       
   488         return $this;
       
   489     }
       
   490 
       
   491     /**
       
   492      * Returns the page's forward links to other pages
       
   493      *
       
   494      * This method returns an associative array of forward links to other pages,
       
   495      * where each element's key is the name of the relation (e.g. alternate,
       
   496      * prev, next, help, etc), and the value is a mixed value that could somehow
       
   497      * be considered a page.
       
   498      *
       
   499      * @param  string $relation  [optional] name of relation to return. If not
       
   500      *                           given, all relations will be returned.
       
   501      * @return array             an array of relations. If $relation is not
       
   502      *                           specified, all relations will be returned in
       
   503      *                           an associative array.
       
   504      */
       
   505     public function getRel($relation = null)
       
   506     {
       
   507         if (null !== $relation) {
       
   508             return isset($this->_rel[$relation]) ?
       
   509                    $this->_rel[$relation] :
       
   510                    null;
       
   511         }
       
   512 
       
   513         return $this->_rel;
       
   514     }
       
   515 
       
   516     /**
       
   517      * Sets the page's reverse links to other pages
       
   518      *
       
   519      * This method expects an associative array of reverse links to other pages,
       
   520      * where each element's key is the name of the relation (e.g. alternate,
       
   521      * prev, next, help, etc), and the value is a mixed value that could somehow
       
   522      * be considered a page.
       
   523      *
       
   524      * @param  array|Zend_Config $relations  [optional] an associative array of
       
   525      *                                       reverse links to other pages
       
   526      * @return Zend_Navigation_Page          fluent interface, returns self
       
   527      */
       
   528     public function setRev($relations = null)
       
   529     {
       
   530         $this->_rev = array();
       
   531 
       
   532         if (null !== $relations) {
       
   533             if ($relations instanceof Zend_Config) {
       
   534                 $relations = $relations->toArray();
       
   535             }
       
   536 
       
   537             if (!is_array($relations)) {
       
   538                 require_once 'Zend/Navigation/Exception.php';
       
   539                 throw new Zend_Navigation_Exception(
       
   540                         'Invalid argument: $relations must be an ' .
       
   541                         'array or an instance of Zend_Config');
       
   542             }
       
   543 
       
   544             foreach ($relations as $name => $relation) {
       
   545                 if (is_string($name)) {
       
   546                     $this->_rev[$name] = $relation;
       
   547                 }
       
   548             }
       
   549         }
       
   550 
       
   551         return $this;
       
   552     }
       
   553 
       
   554     /**
       
   555      * Returns the page's reverse links to other pages
       
   556      *
       
   557      * This method returns an associative array of forward links to other pages,
       
   558      * where each element's key is the name of the relation (e.g. alternate,
       
   559      * prev, next, help, etc), and the value is a mixed value that could somehow
       
   560      * be considered a page.
       
   561      *
       
   562      * @param  string $relation  [optional] name of relation to return. If not
       
   563      *                           given, all relations will be returned.
       
   564      * @return array             an array of relations. If $relation is not
       
   565      *                           specified, all relations will be returned in
       
   566      *                           an associative array.
       
   567      */
       
   568     public function getRev($relation = null)
       
   569     {
       
   570         if (null !== $relation) {
       
   571             return isset($this->_rev[$relation]) ?
       
   572                    $this->_rev[$relation] :
       
   573                    null;
       
   574         }
       
   575 
       
   576         return $this->_rev;
       
   577     }
       
   578 
       
   579     /**
       
   580      * Sets page order to use in parent container
       
   581      *
       
   582      * @param  int $order                 [optional] page order in container.
       
   583      *                                    Default is null, which sets no
       
   584      *                                    specific order.
       
   585      * @return Zend_Navigation_Page       fluent interface, returns self
       
   586      * @throws Zend_Navigation_Exception  if order is not integer or null
       
   587      */
       
   588     public function setOrder($order = null)
       
   589     {
       
   590         if (is_string($order)) {
       
   591             $temp = (int) $order;
       
   592             if ($temp < 0 || $temp > 0 || $order == '0') {
       
   593                 $order = $temp;
       
   594             }
       
   595         }
       
   596 
       
   597         if (null !== $order && !is_int($order)) {
       
   598             require_once 'Zend/Navigation/Exception.php';
       
   599             throw new Zend_Navigation_Exception(
       
   600                     'Invalid argument: $order must be an integer or null, ' .
       
   601                     'or a string that casts to an integer');
       
   602         }
       
   603 
       
   604         $this->_order = $order;
       
   605 
       
   606         // notify parent, if any
       
   607         if (isset($this->_parent)) {
       
   608             $this->_parent->notifyOrderUpdated();
       
   609         }
       
   610 
       
   611         return $this;
       
   612     }
       
   613 
       
   614     /**
       
   615      * Returns page order used in parent container
       
   616      *
       
   617      * @return int|null  page order or null
       
   618      */
       
   619     public function getOrder()
       
   620     {
       
   621         return $this->_order;
       
   622     }
       
   623 
       
   624     /**
       
   625      * Sets ACL resource assoicated with this page
       
   626      *
       
   627      * @param  string|Zend_Acl_Resource_Interface $resource  [optional] resource
       
   628      *                                                       to associate with
       
   629      *                                                       page. Default is
       
   630      *                                                       null, which sets no
       
   631      *                                                       resource.
       
   632      * @throws Zend_Navigation_Exception                     if $resource if
       
   633      *                                                       invalid
       
   634      * @return Zend_Navigation_Page                          fluent interface,
       
   635      *                                                       returns self
       
   636      */
       
   637     public function setResource($resource = null)
       
   638     {
       
   639         if (null === $resource || is_string($resource) ||
       
   640             $resource instanceof Zend_Acl_Resource_Interface) {
       
   641             $this->_resource = $resource;
       
   642         } else {
       
   643             require_once 'Zend/Navigation/Exception.php';
       
   644             throw new Zend_Navigation_Exception(
       
   645                     'Invalid argument: $resource must be null, a string, ' .
       
   646                     ' or an instance of Zend_Acl_Resource_Interface');
       
   647         }
       
   648 
       
   649         return $this;
       
   650     }
       
   651 
       
   652     /**
       
   653      * Returns ACL resource assoicated with this page
       
   654      *
       
   655      * @return string|Zend_Acl_Resource_Interface|null  ACL resource or null
       
   656      */
       
   657     public function getResource()
       
   658     {
       
   659         return $this->_resource;
       
   660     }
       
   661 
       
   662     /**
       
   663      * Sets ACL privilege associated with this page
       
   664      *
       
   665      * @param  string|null $privilege  [optional] ACL privilege to associate
       
   666      *                                 with this page. Default is null, which
       
   667      *                                 sets no privilege.
       
   668      * @return Zend_Navigation_Page    fluent interface, returns self
       
   669      */
       
   670     public function setPrivilege($privilege = null)
       
   671     {
       
   672         $this->_privilege = is_string($privilege) ? $privilege : null;
       
   673         return $this;
       
   674     }
       
   675 
       
   676     /**
       
   677      * Returns ACL privilege associated with this page
       
   678      *
       
   679      * @return string|null  ACL privilege or null
       
   680      */
       
   681     public function getPrivilege()
       
   682     {
       
   683         return $this->_privilege;
       
   684     }
       
   685 
       
   686     /**
       
   687      * Sets whether page should be considered active or not
       
   688      *
       
   689      * @param  bool $active          [optional] whether page should be
       
   690      *                               considered active or not. Default is true.
       
   691      * @return Zend_Navigation_Page  fluent interface, returns self
       
   692      */
       
   693     public function setActive($active = true)
       
   694     {
       
   695         $this->_active = (bool) $active;
       
   696         return $this;
       
   697     }
       
   698 
       
   699     /**
       
   700      * Returns whether page should be considered active or not
       
   701      *
       
   702      * @param  bool $recursive  [optional] whether page should be considered
       
   703      *                          active if any child pages are active. Default is
       
   704      *                          false.
       
   705      * @return bool             whether page should be considered active
       
   706      */
       
   707     public function isActive($recursive = false)
       
   708     {
       
   709         if (!$this->_active && $recursive) {
       
   710             foreach ($this->_pages as $page) {
       
   711                 if ($page->isActive(true)) {
       
   712                     return true;
       
   713                 }
       
   714             }
       
   715             return false;
       
   716         }
       
   717 
       
   718         return $this->_active;
       
   719     }
       
   720 
       
   721     /**
       
   722      * Proxy to isActive()
       
   723      *
       
   724      * @param  bool $recursive  [optional] whether page should be considered
       
   725      *                          active if any child pages are active. Default
       
   726      *                          is false.
       
   727      * @return bool             whether page should be considered active
       
   728      */
       
   729     public function getActive($recursive = false)
       
   730     {
       
   731         return $this->isActive($recursive);
       
   732     }
       
   733 
       
   734     /**
       
   735      * Sets whether the page should be visible or not
       
   736      *
       
   737      * @param  bool $visible         [optional] whether page should be
       
   738      *                               considered visible or not. Default is true.
       
   739      * @return Zend_Navigation_Page  fluent interface, returns self
       
   740      */
       
   741     public function setVisible($visible = true)
       
   742     {
       
   743         $this->_visible = (bool) $visible;
       
   744         return $this;
       
   745     }
       
   746 
       
   747     /**
       
   748      * Returns a boolean value indicating whether the page is visible
       
   749      *
       
   750      * @param  bool $recursive  [optional] whether page should be considered
       
   751      *                          invisible if parent is invisible. Default is
       
   752      *                          false.
       
   753      * @return bool             whether page should be considered visible
       
   754      */
       
   755     public function isVisible($recursive = false)
       
   756     {
       
   757         if ($recursive && isset($this->_parent) &&
       
   758             $this->_parent instanceof Zend_Navigation_Page) {
       
   759             if (!$this->_parent->isVisible(true)) {
       
   760                 return false;
       
   761             }
       
   762         }
       
   763 
       
   764         return $this->_visible;
       
   765     }
       
   766 
       
   767     /**
       
   768      * Proxy to isVisible()
       
   769      *
       
   770      * Returns a boolean value indicating whether the page is visible
       
   771      *
       
   772      * @param  bool $recursive  [optional] whether page should be considered
       
   773      *                          invisible if parent is invisible. Default is
       
   774      *                          false.
       
   775      * @return bool             whether page should be considered visible
       
   776      */
       
   777     public function getVisible($recursive = false)
       
   778     {
       
   779         return $this->isVisible($recursive);
       
   780     }
       
   781 
       
   782     /**
       
   783      * Sets parent container
       
   784      *
       
   785      * @param  Zend_Navigation_Container $parent  [optional] new parent to set.
       
   786      *                                            Default is null which will set
       
   787      *                                            no parent.
       
   788      * @return Zend_Navigation_Page               fluent interface, returns self
       
   789      */
       
   790     public function setParent(Zend_Navigation_Container $parent = null)
       
   791     {
       
   792         if ($parent === $this) {
       
   793             require_once 'Zend/Navigation/Exception.php';
       
   794             throw new Zend_Navigation_Exception(
       
   795                 'A page cannot have itself as a parent');
       
   796         }
       
   797 
       
   798         // return if the given parent already is parent
       
   799         if ($parent === $this->_parent) {
       
   800             return $this;
       
   801         }
       
   802 
       
   803         // remove from old parent
       
   804         if (null !== $this->_parent) {
       
   805             $this->_parent->removePage($this);
       
   806         }
       
   807 
       
   808         // set new parent
       
   809         $this->_parent = $parent;
       
   810 
       
   811         // add to parent if page and not already a child
       
   812         if (null !== $this->_parent && !$this->_parent->hasPage($this, false)) {
       
   813             $this->_parent->addPage($this);
       
   814         }
       
   815 
       
   816         return $this;
       
   817     }
       
   818 
       
   819     /**
       
   820      * Returns parent container
       
   821      *
       
   822      * @return Zend_Navigation_Container|null  parent container or null
       
   823      */
       
   824     public function getParent()
       
   825     {
       
   826         return $this->_parent;
       
   827     }
       
   828 
       
   829     /**
       
   830      * Sets the given property
       
   831      *
       
   832      * If the given property is native (id, class, title, etc), the matching
       
   833      * set method will be used. Otherwise, it will be set as a custom property.
       
   834      *
       
   835      * @param  string $property           property name
       
   836      * @param  mixed  $value              value to set
       
   837      * @return Zend_Navigation_Page       fluent interface, returns self
       
   838      * @throws Zend_Navigation_Exception  if property name is invalid
       
   839      */
       
   840     public function set($property, $value)
       
   841     {
       
   842         if (!is_string($property) || empty($property)) {
       
   843             require_once 'Zend/Navigation/Exception.php';
       
   844             throw new Zend_Navigation_Exception(
       
   845                     'Invalid argument: $property must be a non-empty string');
       
   846         }
       
   847 
       
   848         $method = 'set' . self::_normalizePropertyName($property);
       
   849 
       
   850         if ($method != 'setOptions' && $method != 'setConfig' &&
       
   851             method_exists($this, $method)) {
       
   852             $this->$method($value);
       
   853         } else {
       
   854             $this->_properties[$property] = $value;
       
   855         }
       
   856 
       
   857         return $this;
       
   858     }
       
   859 
       
   860     /**
       
   861      * Returns the value of the given property
       
   862      *
       
   863      * If the given property is native (id, class, title, etc), the matching
       
   864      * get method will be used. Otherwise, it will return the matching custom
       
   865      * property, or null if not found.
       
   866      *
       
   867      * @param  string $property           property name
       
   868      * @return mixed                      the property's value or null
       
   869      * @throws Zend_Navigation_Exception  if property name is invalid
       
   870      */
       
   871     public function get($property)
       
   872     {
       
   873         if (!is_string($property) || empty($property)) {
       
   874             require_once 'Zend/Navigation/Exception.php';
       
   875             throw new Zend_Navigation_Exception(
       
   876                     'Invalid argument: $property must be a non-empty string');
       
   877         }
       
   878 
       
   879         $method = 'get' . self::_normalizePropertyName($property);
       
   880 
       
   881         if (method_exists($this, $method)) {
       
   882             return $this->$method();
       
   883         } elseif (isset($this->_properties[$property])) {
       
   884             return $this->_properties[$property];
       
   885         }
       
   886 
       
   887         return null;
       
   888     }
       
   889 
       
   890     // Magic overloads:
       
   891 
       
   892     /**
       
   893      * Sets a custom property
       
   894      *
       
   895      * Magic overload for enabling <code>$page->propname = $value</code>.
       
   896      *
       
   897      * @param  string $name               property name
       
   898      * @param  mixed  $value              value to set
       
   899      * @return void
       
   900      * @throws Zend_Navigation_Exception  if property name is invalid
       
   901      */
       
   902     public function __set($name, $value)
       
   903     {
       
   904         $this->set($name, $value);
       
   905     }
       
   906 
       
   907     /**
       
   908      * Returns a property, or null if it doesn't exist
       
   909      *
       
   910      * Magic overload for enabling <code>$page->propname</code>.
       
   911      *
       
   912      * @param  string $name               property name
       
   913      * @return mixed                      property value or null
       
   914      * @throws Zend_Navigation_Exception  if property name is invalid
       
   915      */
       
   916     public function __get($name)
       
   917     {
       
   918         return $this->get($name);
       
   919     }
       
   920 
       
   921     /**
       
   922      * Checks if a property is set
       
   923      *
       
   924      * Magic overload for enabling <code>isset($page->propname)</code>.
       
   925      *
       
   926      * Returns true if the property is native (id, class, title, etc), and
       
   927      * true or false if it's a custom property (depending on whether the
       
   928      * property actually is set).
       
   929      *
       
   930      * @param  string $name  property name
       
   931      * @return bool          whether the given property exists
       
   932      */
       
   933     public function __isset($name)
       
   934     {
       
   935         $method = 'get' . self::_normalizePropertyName($name);
       
   936         if (method_exists($this, $method)) {
       
   937             return true;
       
   938         }
       
   939 
       
   940         return isset($this->_properties[$name]);
       
   941     }
       
   942 
       
   943     /**
       
   944      * Unsets the given custom property
       
   945      *
       
   946      * Magic overload for enabling <code>unset($page->propname)</code>.
       
   947      *
       
   948      * @param  string $name               property name
       
   949      * @return void
       
   950      * @throws Zend_Navigation_Exception  if the property is native
       
   951      */
       
   952     public function __unset($name)
       
   953     {
       
   954         $method = 'set' . self::_normalizePropertyName($name);
       
   955         if (method_exists($this, $method)) {
       
   956             require_once 'Zend/Navigation/Exception.php';
       
   957             throw new Zend_Navigation_Exception(sprintf(
       
   958                     'Unsetting native property "%s" is not allowed',
       
   959                     $name));
       
   960         }
       
   961 
       
   962         if (isset($this->_properties[$name])) {
       
   963             unset($this->_properties[$name]);
       
   964         }
       
   965     }
       
   966 
       
   967     /**
       
   968      * Returns page label
       
   969      *
       
   970      * Magic overload for enabling <code>echo $page</code>.
       
   971      *
       
   972      * @return string  page label
       
   973      */
       
   974     public function __toString()
       
   975     {
       
   976         return $this->_label;
       
   977     }
       
   978 
       
   979     // Public methods:
       
   980 
       
   981     /**
       
   982      * Adds a forward relation to the page
       
   983      *
       
   984      * @param  string $relation      relation name (e.g. alternate, glossary,
       
   985      *                               canonical, etc)
       
   986      * @param  mixed  $value         value to set for relation
       
   987      * @return Zend_Navigation_Page  fluent interface, returns self
       
   988      */
       
   989     public function addRel($relation, $value)
       
   990     {
       
   991         if (is_string($relation)) {
       
   992             $this->_rel[$relation] = $value;
       
   993         }
       
   994         return $this;
       
   995     }
       
   996 
       
   997     /**
       
   998      * Adds a reverse relation to the page
       
   999      *
       
  1000      * @param  string $relation      relation name (e.g. alternate, glossary,
       
  1001      *                               canonical, etc)
       
  1002      * @param  mixed  $value         value to set for relation
       
  1003      * @return Zend_Navigation_Page  fluent interface, returns self
       
  1004      */
       
  1005     public function addRev($relation, $value)
       
  1006     {
       
  1007         if (is_string($relation)) {
       
  1008             $this->_rev[$relation] = $value;
       
  1009         }
       
  1010         return $this;
       
  1011     }
       
  1012 
       
  1013     /**
       
  1014      * Removes a forward relation from the page
       
  1015      *
       
  1016      * @param  string $relation      name of relation to remove
       
  1017      * @return Zend_Navigation_Page  fluent interface, returns self
       
  1018      */
       
  1019     public function removeRel($relation)
       
  1020     {
       
  1021         if (isset($this->_rel[$relation])) {
       
  1022             unset($this->_rel[$relation]);
       
  1023         }
       
  1024 
       
  1025         return $this;
       
  1026     }
       
  1027 
       
  1028     /**
       
  1029      * Removes a reverse relation from the page
       
  1030      *
       
  1031      * @param  string $relation      name of relation to remove
       
  1032      * @return Zend_Navigation_Page  fluent interface, returns self
       
  1033      */
       
  1034     public function removeRev($relation)
       
  1035     {
       
  1036         if (isset($this->_rev[$relation])) {
       
  1037             unset($this->_rev[$relation]);
       
  1038         }
       
  1039 
       
  1040         return $this;
       
  1041     }
       
  1042 
       
  1043     /**
       
  1044      * Returns an array containing the defined forward relations
       
  1045      *
       
  1046      * @return array  defined forward relations
       
  1047      */
       
  1048     public function getDefinedRel()
       
  1049     {
       
  1050         return array_keys($this->_rel);
       
  1051     }
       
  1052 
       
  1053     /**
       
  1054      * Returns an array containing the defined reverse relations
       
  1055      *
       
  1056      * @return array  defined reverse relations
       
  1057      */
       
  1058     public function getDefinedRev()
       
  1059     {
       
  1060         return array_keys($this->_rev);
       
  1061     }
       
  1062 
       
  1063     /**
       
  1064      * Returns custom properties as an array
       
  1065      *
       
  1066      * @return array  an array containing custom properties
       
  1067      */
       
  1068     public function getCustomProperties()
       
  1069     {
       
  1070         return $this->_properties;
       
  1071     }
       
  1072 
       
  1073     /**
       
  1074      * Returns a hash code value for the page
       
  1075      *
       
  1076      * @return string  a hash code value for this page
       
  1077      */
       
  1078     public final function hashCode()
       
  1079     {
       
  1080         return spl_object_hash($this);
       
  1081     }
       
  1082 
       
  1083     /**
       
  1084      * Returns an array representation of the page
       
  1085      *
       
  1086      * @return array  associative array containing all page properties
       
  1087      */
       
  1088     public function toArray()
       
  1089     {
       
  1090         return array_merge(
       
  1091             $this->getCustomProperties(),
       
  1092             array(
       
  1093                 'label'     => $this->getlabel(),
       
  1094                 'id'        => $this->getId(),
       
  1095                 'class'     => $this->getClass(),
       
  1096                 'title'     => $this->getTitle(),
       
  1097                 'target'    => $this->getTarget(),
       
  1098                 'rel'       => $this->getRel(),
       
  1099                 'rev'       => $this->getRev(),
       
  1100                 'order'     => $this->getOrder(),
       
  1101                 'resource'  => $this->getResource(),
       
  1102                 'privilege' => $this->getPrivilege(),
       
  1103                 'active'    => $this->isActive(),
       
  1104                 'visible'   => $this->isVisible(),
       
  1105                 'type'      => get_class($this),
       
  1106                 'pages'     => parent::toArray()
       
  1107             ));
       
  1108     }
       
  1109 
       
  1110     // Internal methods:
       
  1111 
       
  1112     /**
       
  1113      * Normalizes a property name
       
  1114      *
       
  1115      * @param  string $property  property name to normalize
       
  1116      * @return string            normalized property name
       
  1117      */
       
  1118     protected static function _normalizePropertyName($property)
       
  1119     {
       
  1120         return str_replace(' ', '', ucwords(str_replace('_', ' ', $property)));
       
  1121     }
       
  1122     
       
  1123     public static function setDefaultPageType($type = null) {
       
  1124         if($type !== null && !is_string($type)) {
       
  1125             throw new Zend_Navigation_Exception(
       
  1126                 'Cannot set default page type: type is no string but should be'
       
  1127             );
       
  1128         }
       
  1129         
       
  1130         self::$_defaultPageType = $type;
       
  1131     }
       
  1132     
       
  1133     public static function getDefaultPageType() {
       
  1134         return self::$_defaultPageType;
       
  1135     }
       
  1136 
       
  1137     // Abstract methods:
       
  1138 
       
  1139     /**
       
  1140      * Returns href for this page
       
  1141      *
       
  1142      * @return string  the page's href
       
  1143      */
       
  1144     abstract public function getHref();
       
  1145 }