PageRenderTime 85ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Zend/Navigation/Page.php

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