00001 <?php
00026 require_once 'Zend/View/Helper/Navigation/Helper.php';
00027
00031 require_once 'Zend/View/Helper/HtmlElement.php';
00032
00042 abstract class Zend_View_Helper_Navigation_HelperAbstract
00043 extends Zend_View_Helper_HtmlElement
00044 implements Zend_View_Helper_Navigation_Helper
00045 {
00051 protected $_container;
00052
00058 protected $_minDepth;
00059
00065 protected $_maxDepth;
00066
00072 protected $_indent = '';
00073
00079 protected $_translator;
00080
00086 protected $_acl;
00087
00093 protected $_renderInvisible = false;
00094
00100 protected $_role;
00101
00107 protected $_useTranslator = true;
00108
00114 protected $_useAcl = true;
00115
00122 protected static $_defaultAcl;
00123
00130 protected static $_defaultRole;
00131
00132
00133
00147 public function setContainer(Zend_Navigation_Container $container = null)
00148 {
00149 $this->_container = $container;
00150 return $this;
00151 }
00152
00168 public function getContainer()
00169 {
00170 if (null === $this->_container) {
00171
00172 require_once 'Zend/Registry.php';
00173 if (Zend_Registry::isRegistered('Zend_Navigation')) {
00174 $nav = Zend_Registry::get('Zend_Navigation');
00175 if ($nav instanceof Zend_Navigation_Container) {
00176 return $this->_container = $nav;
00177 }
00178 }
00179
00180
00181 require_once 'Zend/Navigation.php';
00182 $this->_container = new Zend_Navigation();
00183 }
00184
00185 return $this->_container;
00186 }
00187
00198 public function setMinDepth($minDepth = null)
00199 {
00200 if (null === $minDepth || is_int($minDepth)) {
00201 $this->_minDepth = $minDepth;
00202 } else {
00203 $this->_minDepth = (int) $minDepth;
00204 }
00205 return $this;
00206 }
00207
00213 public function getMinDepth()
00214 {
00215 if (!is_int($this->_minDepth) || $this->_minDepth < 0) {
00216 return 0;
00217 }
00218 return $this->_minDepth;
00219 }
00220
00231 public function setMaxDepth($maxDepth = null)
00232 {
00233 if (null === $maxDepth || is_int($maxDepth)) {
00234 $this->_maxDepth = $maxDepth;
00235 } else {
00236 $this->_maxDepth = (int) $maxDepth;
00237 }
00238 return $this;
00239 }
00240
00246 public function getMaxDepth()
00247 {
00248 return $this->_maxDepth;
00249 }
00250
00260 public function setIndent($indent)
00261 {
00262 $this->_indent = $this->_getWhitespace($indent);
00263 return $this;
00264 }
00265
00271 public function getIndent()
00272 {
00273 return $this->_indent;
00274 }
00275
00292 public function setTranslator($translator = null)
00293 {
00294 if (null == $translator ||
00295 $translator instanceof Zend_Translate_Adapter) {
00296 $this->_translator = $translator;
00297 } elseif ($translator instanceof Zend_Translate) {
00298 $this->_translator = $translator->getAdapter();
00299 }
00300
00301 return $this;
00302 }
00303
00311 public function getTranslator()
00312 {
00313 if (null === $this->_translator) {
00314 require_once 'Zend/Registry.php';
00315 if (Zend_Registry::isRegistered('Zend_Translate')) {
00316 $this->setTranslator(Zend_Registry::get('Zend_Translate'));
00317 }
00318 }
00319
00320 return $this->_translator;
00321 }
00322
00333 public function setAcl(Zend_Acl $acl = null)
00334 {
00335 $this->_acl = $acl;
00336 return $this;
00337 }
00338
00347 public function getAcl()
00348 {
00349 if ($this->_acl === null && self::$_defaultAcl !== null) {
00350 return self::$_defaultAcl;
00351 }
00352
00353 return $this->_acl;
00354 }
00355
00372 public function setRole($role = null)
00373 {
00374 if (null === $role || is_string($role) ||
00375 $role instanceof Zend_Acl_Role_Interface) {
00376 $this->_role = $role;
00377 } else {
00378 require_once 'Zend/View/Exception.php';
00379 throw new Zend_View_Exception(sprintf(
00380 '$role must be a string, null, or an instance of ' .
00381 'Zend_Acl_Role_Interface; %s given',
00382 gettype($role)));
00383 }
00384
00385 return $this;
00386 }
00387
00396 public function getRole()
00397 {
00398 if ($this->_role === null && self::$_defaultRole !== null) {
00399 return self::$_defaultRole;
00400 }
00401
00402 return $this->_role;
00403 }
00404
00416 public function setUseAcl($useAcl = true)
00417 {
00418 $this->_useAcl = (bool) $useAcl;
00419 return $this;
00420 }
00421
00429 public function getUseAcl()
00430 {
00431 return $this->_useAcl;
00432 }
00433
00439 public function getRenderInvisible()
00440 {
00441 return $this->_renderInvisible;
00442 }
00443
00451 public function setRenderInvisible($renderInvisible = true)
00452 {
00453 $this->_renderInvisible = (bool) $renderInvisible;
00454 return $this;
00455 }
00456
00468 public function setUseTranslator($useTranslator = true)
00469 {
00470 $this->_useTranslator = (bool) $useTranslator;
00471 return $this;
00472 }
00473
00481 public function getUseTranslator()
00482 {
00483 return $this->_useTranslator;
00484 }
00485
00486
00487
00496 public function __call($method, array $arguments = array())
00497 {
00498 return call_user_func_array(
00499 array($this->getContainer(), $method),
00500 $arguments);
00501 }
00502
00513 public function __toString()
00514 {
00515 try {
00516 return $this->render();
00517 } catch (Exception $e) {
00518 $msg = get_class($e) . ': ' . $e->getMessage();
00519 trigger_error($msg, E_USER_ERROR);
00520 return '';
00521 }
00522 }
00523
00524
00525
00547 public function findActive(Zend_Navigation_Container $container,
00548 $minDepth = null,
00549 $maxDepth = -1)
00550 {
00551 if (!is_int($minDepth)) {
00552 $minDepth = $this->getMinDepth();
00553 }
00554 if ((!is_int($maxDepth) || $maxDepth < 0) && null !== $maxDepth) {
00555 $maxDepth = $this->getMaxDepth();
00556 }
00557
00558 $found = null;
00559 $foundDepth = -1;
00560 $iterator = new RecursiveIteratorIterator($container,
00561 RecursiveIteratorIterator::CHILD_FIRST);
00562
00563 foreach ($iterator as $page) {
00564 $currDepth = $iterator->getDepth();
00565 if ($currDepth < $minDepth || !$this->accept($page)) {
00566
00567 continue;
00568 }
00569
00570 if ($page->isActive(false) && $currDepth > $foundDepth) {
00571
00572 $found = $page;
00573 $foundDepth = $currDepth;
00574 }
00575 }
00576
00577 if (is_int($maxDepth) && $foundDepth > $maxDepth) {
00578 while ($foundDepth > $maxDepth) {
00579 if (--$foundDepth < $minDepth) {
00580 $found = null;
00581 break;
00582 }
00583
00584 $found = $found->getParent();
00585 if (!$found instanceof Zend_Navigation_Page) {
00586 $found = null;
00587 break;
00588 }
00589 }
00590 }
00591
00592 if ($found) {
00593 return array('page' => $found, 'depth' => $foundDepth);
00594 } else {
00595 return array();
00596 }
00597 }
00598
00606 public function hasContainer()
00607 {
00608 return null !== $this->_container;
00609 }
00610
00618 public function hasAcl()
00619 {
00620 return null !== $this->_acl;
00621 }
00622
00630 public function hasRole()
00631 {
00632 return null !== $this->_role;
00633 }
00634
00642 public function hasTranslator()
00643 {
00644 return null !== $this->_translator;
00645 }
00646
00653 public function htmlify(Zend_Navigation_Page $page)
00654 {
00655
00656 $label = $page->getLabel();
00657 $title = $page->getTitle();
00658
00659 if ($this->getUseTranslator() && $t = $this->getTranslator()) {
00660 if (is_string($label) && !empty($label)) {
00661 $label = $t->translate($label);
00662 }
00663 if (is_string($title) && !empty($title)) {
00664 $title = $t->translate($title);
00665 }
00666 }
00667
00668
00669 $attribs = array(
00670 'id' => $page->getId(),
00671 'title' => $title,
00672 'class' => $page->getClass(),
00673 'href' => $page->getHref(),
00674 'target' => $page->getTarget()
00675 );
00676
00677 return '<a' . $this->_htmlAttribs($attribs) . '>'
00678 . $this->view->escape($label)
00679 . '</a>';
00680 }
00681
00682
00683
00705 public function accept(Zend_Navigation_Page $page, $recursive = true)
00706 {
00707
00708 $accept = true;
00709
00710 if (!$page->isVisible(false) && !$this->getRenderInvisible()) {
00711
00712 $accept = false;
00713 } elseif ($this->getUseAcl() && !$this->_acceptAcl($page)) {
00714
00715 $accept = false;
00716 }
00717
00718 if ($accept && $recursive) {
00719 $parent = $page->getParent();
00720 if ($parent instanceof Zend_Navigation_Page) {
00721 $accept = $this->accept($parent, true);
00722 }
00723 }
00724
00725 return $accept;
00726 }
00727
00740 protected function _acceptAcl(Zend_Navigation_Page $page)
00741 {
00742 if (!$acl = $this->getAcl()) {
00743
00744 return true;
00745 }
00746
00747 $role = $this->getRole();
00748 $resource = $page->getResource();
00749 $privilege = $page->getPrivilege();
00750
00751 if ($resource || $privilege) {
00752
00753 return $acl->isAllowed($role, $resource, $privilege);
00754 }
00755
00756 return true;
00757 }
00758
00759
00760
00767 protected function _getWhitespace($indent)
00768 {
00769 if (is_int($indent)) {
00770 $indent = str_repeat(' ', $indent);
00771 }
00772
00773 return (string) $indent;
00774 }
00775
00785 protected function _htmlAttribs($attribs)
00786 {
00787
00788 foreach ($attribs as $key => $value) {
00789 if ($value === null || (is_string($value) && !strlen($value))) {
00790 unset($attribs[$key]);
00791 }
00792 }
00793
00794 return parent::_htmlAttribs($attribs);
00795 }
00796
00805 protected function _normalizeId($value)
00806 {
00807 $prefix = get_class($this);
00808 $prefix = strtolower(trim(substr($prefix, strrpos($prefix, '_')), '_'));
00809
00810 return $prefix . '-' . $value;
00811 }
00812
00813
00814
00822 public static function setDefaultAcl(Zend_Acl $acl = null)
00823 {
00824 self::$_defaultAcl = $acl;
00825 }
00826
00839 public static function setDefaultRole($role = null)
00840 {
00841 if (null === $role ||
00842 is_string($role) ||
00843 $role instanceof Zend_Acl_Role_Interface) {
00844 self::$_defaultRole = $role;
00845 } else {
00846 require_once 'Zend/View/Exception.php';
00847 throw new Zend_View_Exception(
00848 '$role must be null|string|Zend_Acl_Role_Interface');
00849 }
00850 }
00851 }