PageRenderTime 37ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/View/Helper/Navigation/HelperAbstract.php

https://bitbucket.org/hjain/loudmusic
PHP | 921 lines | 358 code | 88 blank | 475 comment | 62 complexity | d58ee3cdc919fa8452c7be8c2299a715 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_View
  17. * @subpackage Helper
  18. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: HelperAbstract.php 24962 2012-06-15 14:28:42Z adamlundrigan $
  21. */
  22. /**
  23. * @see Zend_View_Helper_Navigation_Helper
  24. */
  25. require_once 'Zend/View/Helper/Navigation/Helper.php';
  26. /**
  27. * @see Zend_View_Helper_HtmlElement
  28. */
  29. require_once 'Zend/View/Helper/HtmlElement.php';
  30. /**
  31. * Base class for navigational helpers
  32. *
  33. * @category Zend
  34. * @package Zend_View
  35. * @subpackage Helper
  36. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  37. * @license http://framework.zend.com/license/new-bsd New BSD License
  38. */
  39. abstract class Zend_View_Helper_Navigation_HelperAbstract
  40. extends Zend_View_Helper_HtmlElement
  41. implements Zend_View_Helper_Navigation_Helper
  42. {
  43. /**
  44. * Container to operate on by default
  45. *
  46. * @var Zend_Navigation_Container
  47. */
  48. protected $_container;
  49. /**
  50. * The minimum depth a page must have to be included when rendering
  51. *
  52. * @var int
  53. */
  54. protected $_minDepth;
  55. /**
  56. * The maximum depth a page can have to be included when rendering
  57. *
  58. * @var int
  59. */
  60. protected $_maxDepth;
  61. /**
  62. * Indentation string
  63. *
  64. * @var string
  65. */
  66. protected $_indent = '';
  67. /**
  68. * Prefix for IDs when they are normalized
  69. *
  70. * @var string|null
  71. */
  72. protected $_prefixForId = null;
  73. /**
  74. * Skip current prefix for IDs when they are normalized (flag)
  75. *
  76. * @var bool
  77. */
  78. protected $_skipPrefixForId = false;
  79. /**
  80. * Translator
  81. *
  82. * @var Zend_Translate_Adapter
  83. */
  84. protected $_translator;
  85. /**
  86. * ACL to use when iterating pages
  87. *
  88. * @var Zend_Acl
  89. */
  90. protected $_acl;
  91. /**
  92. * Wheter invisible items should be rendered by this helper
  93. *
  94. * @var bool
  95. */
  96. protected $_renderInvisible = false;
  97. /**
  98. * ACL role to use when iterating pages
  99. *
  100. * @var string|Zend_Acl_Role_Interface
  101. */
  102. protected $_role;
  103. /**
  104. * Whether translator should be used for page labels and titles
  105. *
  106. * @var bool
  107. */
  108. protected $_useTranslator = true;
  109. /**
  110. * Whether ACL should be used for filtering out pages
  111. *
  112. * @var bool
  113. */
  114. protected $_useAcl = true;
  115. /**
  116. * Default ACL to use when iterating pages if not explicitly set in the
  117. * instance by calling {@link setAcl()}
  118. *
  119. * @var Zend_Acl
  120. */
  121. protected static $_defaultAcl;
  122. /**
  123. * Default ACL role to use when iterating pages if not explicitly set in the
  124. * instance by calling {@link setRole()}
  125. *
  126. * @var string|Zend_Acl_Role_Interface
  127. */
  128. protected static $_defaultRole;
  129. // Accessors:
  130. /**
  131. * Sets navigation container the helper operates on by default
  132. *
  133. * Implements {@link Zend_View_Helper_Navigation_Interface::setContainer()}.
  134. *
  135. * @param Zend_Navigation_Container $container [optional] container
  136. * to operate on.
  137. * Default is null,
  138. * meaning container
  139. * will be reset.
  140. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface,
  141. * returns self
  142. */
  143. public function setContainer(Zend_Navigation_Container $container = null)
  144. {
  145. $this->_container = $container;
  146. return $this;
  147. }
  148. /**
  149. * Returns the navigation container helper operates on by default
  150. *
  151. * Implements {@link Zend_View_Helper_Navigation_Interface::getContainer()}.
  152. *
  153. * If a helper is not explicitly set in this helper instance by calling
  154. * {@link setContainer()} or by passing it through the helper entry point,
  155. * this method will look in {@link Zend_Registry} for a container by using
  156. * the key 'Zend_Navigation'.
  157. *
  158. * If no container is set, and nothing is found in Zend_Registry, a new
  159. * container will be instantiated and stored in the helper.
  160. *
  161. * @return Zend_Navigation_Container navigation container
  162. */
  163. public function getContainer()
  164. {
  165. if (null === $this->_container) {
  166. // try to fetch from registry first
  167. require_once 'Zend/Registry.php';
  168. if (Zend_Registry::isRegistered('Zend_Navigation')) {
  169. $nav = Zend_Registry::get('Zend_Navigation');
  170. if ($nav instanceof Zend_Navigation_Container) {
  171. return $this->_container = $nav;
  172. }
  173. }
  174. // nothing found in registry, create new container
  175. require_once 'Zend/Navigation.php';
  176. $this->_container = new Zend_Navigation();
  177. }
  178. return $this->_container;
  179. }
  180. /**
  181. * Sets the minimum depth a page must have to be included when rendering
  182. *
  183. * @param int $minDepth [optional] minimum
  184. * depth. Default is
  185. * null, which sets
  186. * no minimum depth.
  187. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface,
  188. * returns self
  189. */
  190. public function setMinDepth($minDepth = null)
  191. {
  192. if (null === $minDepth || is_int($minDepth)) {
  193. $this->_minDepth = $minDepth;
  194. } else {
  195. $this->_minDepth = (int) $minDepth;
  196. }
  197. return $this;
  198. }
  199. /**
  200. * Returns minimum depth a page must have to be included when rendering
  201. *
  202. * @return int|null minimum depth or null
  203. */
  204. public function getMinDepth()
  205. {
  206. if (!is_int($this->_minDepth) || $this->_minDepth < 0) {
  207. return 0;
  208. }
  209. return $this->_minDepth;
  210. }
  211. /**
  212. * Sets the maximum depth a page can have to be included when rendering
  213. *
  214. * @param int $maxDepth [optional] maximum
  215. * depth. Default is
  216. * null, which sets no
  217. * maximum depth.
  218. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface,
  219. * returns self
  220. */
  221. public function setMaxDepth($maxDepth = null)
  222. {
  223. if (null === $maxDepth || is_int($maxDepth)) {
  224. $this->_maxDepth = $maxDepth;
  225. } else {
  226. $this->_maxDepth = (int) $maxDepth;
  227. }
  228. return $this;
  229. }
  230. /**
  231. * Returns maximum depth a page can have to be included when rendering
  232. *
  233. * @return int|null maximum depth or null
  234. */
  235. public function getMaxDepth()
  236. {
  237. return $this->_maxDepth;
  238. }
  239. /**
  240. * Set the indentation string for using in {@link render()}, optionally a
  241. * number of spaces to indent with
  242. *
  243. * @param string|int $indent indentation string or
  244. * number of spaces
  245. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface,
  246. * returns self
  247. */
  248. public function setIndent($indent)
  249. {
  250. $this->_indent = $this->_getWhitespace($indent);
  251. return $this;
  252. }
  253. /**
  254. * Returns indentation
  255. *
  256. * @return string
  257. */
  258. public function getIndent()
  259. {
  260. return $this->_indent;
  261. }
  262. /**
  263. * Sets prefix for IDs when they are normalized
  264. *
  265. * @param string $prefix Prefix for IDs
  266. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, returns self
  267. */
  268. public function setPrefixForId($prefix)
  269. {
  270. if (is_string($prefix)) {
  271. $this->_prefixForId = trim($prefix);
  272. }
  273. return $this;
  274. }
  275. /**
  276. * Returns prefix for IDs when they are normalized
  277. *
  278. * @return string Prefix for
  279. */
  280. public function getPrefixForId()
  281. {
  282. if (null === $this->_prefixForId) {
  283. $prefix = get_class($this);
  284. $this->_prefixForId = strtolower(
  285. trim(substr($prefix, strrpos($prefix, '_')), '_')
  286. ) . '-';
  287. }
  288. return $this->_prefixForId;
  289. }
  290. /**
  291. * Skip the current prefix for IDs when they are normalized
  292. *
  293. * @param bool $flag
  294. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, returns self
  295. */
  296. public function skipPrefixForId($flag = true)
  297. {
  298. $this->_skipPrefixForId = (bool) $flag;
  299. return $this;
  300. }
  301. /**
  302. * Sets translator to use in helper
  303. *
  304. * Implements {@link Zend_View_Helper_Navigation_Helper::setTranslator()}.
  305. *
  306. * @param mixed $translator [optional] translator.
  307. * Expects an object of
  308. * type
  309. * {@link Zend_Translate_Adapter}
  310. * or {@link Zend_Translate},
  311. * or null. Default is
  312. * null, which sets no
  313. * translator.
  314. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface,
  315. * returns self
  316. */
  317. public function setTranslator($translator = null)
  318. {
  319. if (null == $translator ||
  320. $translator instanceof Zend_Translate_Adapter) {
  321. $this->_translator = $translator;
  322. } elseif ($translator instanceof Zend_Translate) {
  323. $this->_translator = $translator->getAdapter();
  324. }
  325. return $this;
  326. }
  327. /**
  328. * Returns translator used in helper
  329. *
  330. * Implements {@link Zend_View_Helper_Navigation_Helper::getTranslator()}.
  331. *
  332. * @return Zend_Translate_Adapter|null translator or null
  333. */
  334. public function getTranslator()
  335. {
  336. if (null === $this->_translator) {
  337. require_once 'Zend/Registry.php';
  338. if (Zend_Registry::isRegistered('Zend_Translate')) {
  339. $this->setTranslator(Zend_Registry::get('Zend_Translate'));
  340. }
  341. }
  342. return $this->_translator;
  343. }
  344. /**
  345. * Sets ACL to use when iterating pages
  346. *
  347. * Implements {@link Zend_View_Helper_Navigation_Helper::setAcl()}.
  348. *
  349. * @param Zend_Acl $acl [optional] ACL object.
  350. * Default is null.
  351. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface,
  352. * returns self
  353. */
  354. public function setAcl(Zend_Acl $acl = null)
  355. {
  356. $this->_acl = $acl;
  357. return $this;
  358. }
  359. /**
  360. * Returns ACL or null if it isn't set using {@link setAcl()} or
  361. * {@link setDefaultAcl()}
  362. *
  363. * Implements {@link Zend_View_Helper_Navigation_Helper::getAcl()}.
  364. *
  365. * @return Zend_Acl|null ACL object or null
  366. */
  367. public function getAcl()
  368. {
  369. if ($this->_acl === null && self::$_defaultAcl !== null) {
  370. return self::$_defaultAcl;
  371. }
  372. return $this->_acl;
  373. }
  374. /**
  375. * Sets ACL role(s) to use when iterating pages
  376. *
  377. * Implements {@link Zend_View_Helper_Navigation_Helper::setRole()}.
  378. *
  379. * @param mixed $role [optional] role to
  380. * set. Expects a string,
  381. * an instance of type
  382. * {@link Zend_Acl_Role_Interface},
  383. * or null. Default is
  384. * null, which will set
  385. * no role.
  386. * @throws Zend_View_Exception if $role is invalid
  387. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface,
  388. * returns self
  389. */
  390. public function setRole($role = null)
  391. {
  392. if (null === $role || is_string($role) ||
  393. $role instanceof Zend_Acl_Role_Interface) {
  394. $this->_role = $role;
  395. } else {
  396. require_once 'Zend/View/Exception.php';
  397. $e = new Zend_View_Exception(sprintf(
  398. '$role must be a string, null, or an instance of '
  399. . 'Zend_Acl_Role_Interface; %s given',
  400. gettype($role)
  401. ));
  402. $e->setView($this->view);
  403. throw $e;
  404. }
  405. return $this;
  406. }
  407. /**
  408. * Returns ACL role to use when iterating pages, or null if it isn't set
  409. * using {@link setRole()} or {@link setDefaultRole()}
  410. *
  411. * Implements {@link Zend_View_Helper_Navigation_Helper::getRole()}.
  412. *
  413. * @return string|Zend_Acl_Role_Interface|null role or null
  414. */
  415. public function getRole()
  416. {
  417. if ($this->_role === null && self::$_defaultRole !== null) {
  418. return self::$_defaultRole;
  419. }
  420. return $this->_role;
  421. }
  422. /**
  423. * Sets whether ACL should be used
  424. *
  425. * Implements {@link Zend_View_Helper_Navigation_Helper::setUseAcl()}.
  426. *
  427. * @param bool $useAcl [optional] whether ACL
  428. * should be used.
  429. * Default is true.
  430. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface,
  431. * returns self
  432. */
  433. public function setUseAcl($useAcl = true)
  434. {
  435. $this->_useAcl = (bool) $useAcl;
  436. return $this;
  437. }
  438. /**
  439. * Returns whether ACL should be used
  440. *
  441. * Implements {@link Zend_View_Helper_Navigation_Helper::getUseAcl()}.
  442. *
  443. * @return bool whether ACL should be used
  444. */
  445. public function getUseAcl()
  446. {
  447. return $this->_useAcl;
  448. }
  449. /**
  450. * Return renderInvisible flag
  451. *
  452. * @return bool
  453. */
  454. public function getRenderInvisible()
  455. {
  456. return $this->_renderInvisible;
  457. }
  458. /**
  459. * Render invisible items?
  460. *
  461. * @param bool $renderInvisible [optional] boolean flag
  462. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface
  463. * returns self
  464. */
  465. public function setRenderInvisible($renderInvisible = true)
  466. {
  467. $this->_renderInvisible = (bool) $renderInvisible;
  468. return $this;
  469. }
  470. /**
  471. * Sets whether translator should be used
  472. *
  473. * Implements {@link Zend_View_Helper_Navigation_Helper::setUseTranslator()}.
  474. *
  475. * @param bool $useTranslator [optional] whether
  476. * translator should be
  477. * used. Default is true.
  478. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface,
  479. * returns self
  480. */
  481. public function setUseTranslator($useTranslator = true)
  482. {
  483. $this->_useTranslator = (bool) $useTranslator;
  484. return $this;
  485. }
  486. /**
  487. * Returns whether translator should be used
  488. *
  489. * Implements {@link Zend_View_Helper_Navigation_Helper::getUseTranslator()}.
  490. *
  491. * @return bool whether translator should be used
  492. */
  493. public function getUseTranslator()
  494. {
  495. return $this->_useTranslator;
  496. }
  497. // Magic overloads:
  498. /**
  499. * Magic overload: Proxy calls to the navigation container
  500. *
  501. * @param string $method method name in container
  502. * @param array $arguments [optional] arguments to pass
  503. * @return mixed returns what the container returns
  504. * @throws Zend_Navigation_Exception if method does not exist in container
  505. */
  506. public function __call($method, array $arguments = array())
  507. {
  508. return call_user_func_array(
  509. array($this->getContainer(), $method),
  510. $arguments);
  511. }
  512. /**
  513. * Magic overload: Proxy to {@link render()}.
  514. *
  515. * This method will trigger an E_USER_ERROR if rendering the helper causes
  516. * an exception to be thrown.
  517. *
  518. * Implements {@link Zend_View_Helper_Navigation_Helper::__toString()}.
  519. *
  520. * @return string
  521. */
  522. public function __toString()
  523. {
  524. try {
  525. return $this->render();
  526. } catch (Exception $e) {
  527. $msg = get_class($e) . ': ' . $e->getMessage();
  528. trigger_error($msg, E_USER_ERROR);
  529. return '';
  530. }
  531. }
  532. // Public methods:
  533. /**
  534. * Finds the deepest active page in the given container
  535. *
  536. * @param Zend_Navigation_Container $container container to search
  537. * @param int|null $minDepth [optional] minimum depth
  538. * required for page to be
  539. * valid. Default is to use
  540. * {@link getMinDepth()}. A
  541. * null value means no minimum
  542. * depth required.
  543. * @param int|null $minDepth [optional] maximum depth
  544. * a page can have to be
  545. * valid. Default is to use
  546. * {@link getMaxDepth()}. A
  547. * null value means no maximum
  548. * depth required.
  549. * @return array an associative array with
  550. * the values 'depth' and
  551. * 'page', or an empty array
  552. * if not found
  553. */
  554. public function findActive(Zend_Navigation_Container $container,
  555. $minDepth = null,
  556. $maxDepth = -1)
  557. {
  558. if (!is_int($minDepth)) {
  559. $minDepth = $this->getMinDepth();
  560. }
  561. if ((!is_int($maxDepth) || $maxDepth < 0) && null !== $maxDepth) {
  562. $maxDepth = $this->getMaxDepth();
  563. }
  564. $found = null;
  565. $foundDepth = -1;
  566. $iterator = new RecursiveIteratorIterator($container,
  567. RecursiveIteratorIterator::CHILD_FIRST);
  568. foreach ($iterator as $page) {
  569. $currDepth = $iterator->getDepth();
  570. if ($currDepth < $minDepth || !$this->accept($page)) {
  571. // page is not accepted
  572. continue;
  573. }
  574. if ($page->isActive(false) && $currDepth > $foundDepth) {
  575. // found an active page at a deeper level than before
  576. $found = $page;
  577. $foundDepth = $currDepth;
  578. }
  579. }
  580. if (is_int($maxDepth) && $foundDepth > $maxDepth) {
  581. while ($foundDepth > $maxDepth) {
  582. if (--$foundDepth < $minDepth) {
  583. $found = null;
  584. break;
  585. }
  586. $found = $found->getParent();
  587. if (!$found instanceof Zend_Navigation_Page) {
  588. $found = null;
  589. break;
  590. }
  591. }
  592. }
  593. if ($found) {
  594. return array('page' => $found, 'depth' => $foundDepth);
  595. } else {
  596. return array();
  597. }
  598. }
  599. /**
  600. * Checks if the helper has a container
  601. *
  602. * Implements {@link Zend_View_Helper_Navigation_Helper::hasContainer()}.
  603. *
  604. * @return bool whether the helper has a container or not
  605. */
  606. public function hasContainer()
  607. {
  608. return null !== $this->_container;
  609. }
  610. /**
  611. * Checks if the helper has an ACL instance
  612. *
  613. * Implements {@link Zend_View_Helper_Navigation_Helper::hasAcl()}.
  614. *
  615. * @return bool whether the helper has a an ACL instance or not
  616. */
  617. public function hasAcl()
  618. {
  619. return null !== $this->_acl;
  620. }
  621. /**
  622. * Checks if the helper has an ACL role
  623. *
  624. * Implements {@link Zend_View_Helper_Navigation_Helper::hasRole()}.
  625. *
  626. * @return bool whether the helper has a an ACL role or not
  627. */
  628. public function hasRole()
  629. {
  630. return null !== $this->_role;
  631. }
  632. /**
  633. * Checks if the helper has a translator
  634. *
  635. * Implements {@link Zend_View_Helper_Navigation_Helper::hasTranslator()}.
  636. *
  637. * @return bool whether the helper has a translator or not
  638. */
  639. public function hasTranslator()
  640. {
  641. return null !== $this->_translator;
  642. }
  643. /**
  644. * Returns an HTML string containing an 'a' element for the given page
  645. *
  646. * @param Zend_Navigation_Page $page page to generate HTML for
  647. * @return string HTML string for the given page
  648. */
  649. public function htmlify(Zend_Navigation_Page $page)
  650. {
  651. // get label and title for translating
  652. $label = $page->getLabel();
  653. $title = $page->getTitle();
  654. if ($this->getUseTranslator() && $t = $this->getTranslator()) {
  655. if (is_string($label) && !empty($label)) {
  656. $label = $t->translate($label);
  657. }
  658. if (is_string($title) && !empty($title)) {
  659. $title = $t->translate($title);
  660. }
  661. }
  662. // get attribs for anchor element
  663. $attribs = array_merge(
  664. array(
  665. 'id' => $page->getId(),
  666. 'title' => $title,
  667. 'class' => $page->getClass(),
  668. 'href' => $page->getHref(),
  669. 'target' => $page->getTarget()
  670. ),
  671. $page->getCustomHtmlAttribs()
  672. );
  673. return '<a' . $this->_htmlAttribs($attribs) . '>'
  674. . $this->view->escape($label)
  675. . '</a>';
  676. }
  677. // Iterator filter methods:
  678. /**
  679. * Determines whether a page should be accepted when iterating
  680. *
  681. * Rules:
  682. * - If a page is not visible it is not accepted, unless RenderInvisible has
  683. * been set to true.
  684. * - If helper has no ACL, page is accepted
  685. * - If helper has ACL, but no role, page is not accepted
  686. * - If helper has ACL and role:
  687. * - Page is accepted if it has no resource or privilege
  688. * - Page is accepted if ACL allows page's resource or privilege
  689. * - If page is accepted by the rules above and $recursive is true, the page
  690. * will not be accepted if it is the descendant of a non-accepted page.
  691. *
  692. * @param Zend_Navigation_Page $page page to check
  693. * @param bool $recursive [optional] if true, page will not
  694. * be accepted if it is the
  695. * descendant of a page that is not
  696. * accepted. Default is true.
  697. * @return bool whether page should be accepted
  698. */
  699. public function accept(Zend_Navigation_Page $page, $recursive = true)
  700. {
  701. // accept by default
  702. $accept = true;
  703. if (!$page->isVisible(false) && !$this->getRenderInvisible()) {
  704. // don't accept invisible pages
  705. $accept = false;
  706. } elseif ($this->getUseAcl() && !$this->_acceptAcl($page)) {
  707. // acl is not amused
  708. $accept = false;
  709. }
  710. if ($accept && $recursive) {
  711. $parent = $page->getParent();
  712. if ($parent instanceof Zend_Navigation_Page) {
  713. $accept = $this->accept($parent, true);
  714. }
  715. }
  716. return $accept;
  717. }
  718. /**
  719. * Determines whether a page should be accepted by ACL when iterating
  720. *
  721. * Rules:
  722. * - If helper has no ACL, page is accepted
  723. * - If page has a resource or privilege defined, page is accepted
  724. * if the ACL allows access to it using the helper's role
  725. * - If page has no resource or privilege, page is accepted
  726. *
  727. * @param Zend_Navigation_Page $page page to check
  728. * @return bool whether page is accepted by ACL
  729. */
  730. protected function _acceptAcl(Zend_Navigation_Page $page)
  731. {
  732. if (!$acl = $this->getAcl()) {
  733. // no acl registered means don't use acl
  734. return true;
  735. }
  736. $role = $this->getRole();
  737. $resource = $page->getResource();
  738. $privilege = $page->getPrivilege();
  739. if ($resource || $privilege) {
  740. // determine using helper role and page resource/privilege
  741. return $acl->isAllowed($role, $resource, $privilege);
  742. }
  743. return true;
  744. }
  745. // Util methods:
  746. /**
  747. * Retrieve whitespace representation of $indent
  748. *
  749. * @param int|string $indent
  750. * @return string
  751. */
  752. protected function _getWhitespace($indent)
  753. {
  754. if (is_int($indent)) {
  755. $indent = str_repeat(' ', $indent);
  756. }
  757. return (string) $indent;
  758. }
  759. /**
  760. * Converts an associative array to a string of tag attributes.
  761. *
  762. * Overloads {@link Zend_View_Helper_HtmlElement::_htmlAttribs()}.
  763. *
  764. * @param array $attribs an array where each key-value pair is converted
  765. * to an attribute name and value
  766. * @return string an attribute string
  767. */
  768. protected function _htmlAttribs($attribs)
  769. {
  770. // filter out null values and empty string values
  771. foreach ($attribs as $key => $value) {
  772. if ($value === null || (is_string($value) && !strlen($value))) {
  773. unset($attribs[$key]);
  774. }
  775. }
  776. return parent::_htmlAttribs($attribs);
  777. }
  778. /**
  779. * Normalize an ID
  780. *
  781. * Extends {@link Zend_View_Helper_HtmlElement::_normalizeId()}.
  782. *
  783. * @param string $value ID
  784. * @return string Normalized ID
  785. */
  786. protected function _normalizeId($value)
  787. {
  788. if (false === $this->_skipPrefixForId) {
  789. $prefix = $this->getPrefixForId();
  790. if (strlen($prefix)) {
  791. return $prefix . $value;
  792. }
  793. }
  794. return parent::_normalizeId($value);
  795. }
  796. // Static methods:
  797. /**
  798. * Sets default ACL to use if another ACL is not explicitly set
  799. *
  800. * @param Zend_Acl $acl [optional] ACL object. Default is null, which
  801. * sets no ACL object.
  802. * @return void
  803. */
  804. public static function setDefaultAcl(Zend_Acl $acl = null)
  805. {
  806. self::$_defaultAcl = $acl;
  807. }
  808. /**
  809. * Sets default ACL role(s) to use when iterating pages if not explicitly
  810. * set later with {@link setRole()}
  811. *
  812. * @param midex $role [optional] role to set. Expects null,
  813. * string, or an instance of
  814. * {@link Zend_Acl_Role_Interface}.
  815. * Default is null, which sets no default
  816. * role.
  817. * @throws Zend_View_Exception if role is invalid
  818. * @return void
  819. */
  820. public static function setDefaultRole($role = null)
  821. {
  822. if (null === $role ||
  823. is_string($role) ||
  824. $role instanceof Zend_Acl_Role_Interface) {
  825. self::$_defaultRole = $role;
  826. } else {
  827. require_once 'Zend/View/Exception.php';
  828. throw new Zend_View_Exception(
  829. '$role must be null|string|Zend_Acl_Role_Interface'
  830. );
  831. }
  832. }
  833. }