PageRenderTime 49ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/Navigation/Page.php

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