Page.php 38 KB

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