v7‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT User.php000064400000014350152101616340006175 0ustar00addPage(array( 'id' => 'member', 'controller' => 'member', 'label' => ___('Dashboard'), 'title' => ___('Dashboard'), 'order' => 0 )); $forms = Am_Di::getInstance()->savedFormTable->findBy(array( 'type' => SavedForm::T_SIGNUP, 'hide' => 0), null, null, 'sort_order'); if (!$forms) { //nop } elseif (count($forms) == 1) { list($f) = $forms; $page = array( 'id' => 'add-renew', 'controller' => 'signup', 'action' => 'index', 'route' => 'signup', 'label' => ___('Add/Renew Subscription'), 'order' => 100, ); if (!$f->isDefault(SavedForm::D_MEMBER)) { $page['params'] = array( 'c' => $f->code ); } $this->addPage($page); } else { $pages = array(); foreach ($forms as $f) { $params = $f->isDefault(SavedForm::D_MEMBER) ? array() : array('c' => $f->code); $pages[] = array( 'id' => 'add-renew-' . ($f->code ? $f->code : 'default'), 'label' => ___($f->title), 'controller' => 'signup', 'action' => 'index', 'route' => 'signup', 'params' => $params ); } $this->addPage(array( 'id' => 'add-renew', 'uri' => 'javascript:;', 'label' => ___('Add/Renew Subscription'), 'order' => 100, 'pages' => $pages )); } $forms = Am_Di::getInstance()->savedFormTable->findBy(array( 'type' => SavedForm::T_PROFILE, 'hide' => 0), null, null, 'sort_order'); if (!$forms) { //nop } elseif (count($forms) == 1) { list($f) = $forms; $page = array( 'id' => 'profile', 'controller' => 'profile', 'route' => 'profile', 'label' => ___('Profile'), 'order' => 300, ); if (!$f->isDefault(SavedForm::D_PROFILE)) { $page['params'] = array( 'c' => $f->code ); } $this->addPage($page); } else { $pages = array(); foreach ($forms as $f) { $params = $f->isDefault(SavedForm::D_PROFILE) ? array() : array('c' => $f->code); $pages[] = array( 'id' => 'profile-' . ($f->code ? $f->code : 'default'), 'label' => ___($f->title), 'controller' => 'profile', 'route' => 'profile', 'params' => $params ); } $this->addPage(array( 'id' => 'profile', 'uri' => 'javascript:;', 'label' => ___('Profile'), 'order' => 300, 'pages' => $pages )); } try { $user = Am_Di::getInstance()->user; } catch (Am_Exception_Db_NotFound $e) { $user = null; } if ($user) { $tree = Am_Di::getInstance()->resourceCategoryTable->getAllowedTree($user); $pages = array(); foreach ($tree as $node) { $pages[] = $this->getContentCategoryPage($node); } if (count($pages)) $this->addPages($pages); } if ($user) { $sort = 0; $pages = Am_Di::getInstance()->resourceAccessTable ->getAllowedResources($user, ResourceAccess::PAGE); foreach ($pages as $p) { if ($p->onmenu) { $this->addPage(array( 'id' => 'page-' . $p->pk(), 'uri' => $p->getUrl(), 'label' => ___($p->title), 'order' => 400 + $sort++ )); } } $links = Am_Di::getInstance()->resourceAccessTable ->getAllowedResources($user, ResourceAccess::LINK); foreach ($links as $l) { if ($l->onmenu) { $this->addPage(array( 'id' => 'link-' . $l->pk(), 'uri' => $l->getUrl(), 'label' => ___($l->title), 'order' => 400 + $sort++ )); } } } Am_Di::getInstance()->hook->call(Am_Event::USER_MENU, array( 'menu' => $this, 'user' => $user)); /// workaround against using the current route for generating urls foreach (new RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST) as $child) if ($child instanceof Am_Navigation_Page_Mvc && $child->getRoute()===null) $child->setRoute('default'); } protected function getContentCategoryPage($node) { $page = $node->self_cnt ? array( 'id' => 'content-category-' . $node->pk(), 'route' => 'content-c', 'controller' => 'content', 'action' => 'c', 'label' => ___($node->title), 'order' => 500 + $node->sort_order, 'params' => array( 'id' => $node->pk(), 'title' => $node->title ) ) : array( 'id' => 'content-category-' . $node->pk(), 'uri' => 'javascript:;', 'label' => ___($node->title), 'order' => 500 + $node->sort_order ); $subpages = array(); foreach ($node->getChildNodes() as $n) $subpages[] = $this->getContentCategoryPage($n); if (count($subpages)) { $page['pages'] = $subpages; } return $page; } }Page.php000064400000122655152101616340006143 0ustar00toArray(); } if (!is_array($options)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $options must be an array or Zend_Config'); } if (isset($options['type'])) { $type = $options['type']; } elseif(self::getDefaultPageType()!= null) { $type = self::getDefaultPageType(); } if(isset($type)) { if (is_string($type) && !empty($type)) { switch (strtolower($type)) { case 'mvc': $type = 'Zend_Navigation_Page_Mvc'; break; case 'uri': $type = 'Zend_Navigation_Page_Uri'; break; } if (!class_exists($type)) { //--//require_once 'Zend/Loader.php'; @Zend_Loader::loadClass($type); } $page = new $type($options); if (!$page instanceof Zend_Navigation_Page) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception(sprintf( 'Invalid argument: Detected type "%s", which ' . 'is not an instance of Zend_Navigation_Page', $type)); } return $page; } } $hasUri = isset($options['uri']); $hasMvc = isset($options['action']) || isset($options['controller']) || isset($options['module']) || isset($options['route']) || isset($options['params']); if ($hasMvc) { //--//require_once 'Zend/Navigation/Page/Mvc.php'; return new Zend_Navigation_Page_Mvc($options); } elseif ($hasUri) { //--//require_once 'Zend/Navigation/Page/Uri.php'; return new Zend_Navigation_Page_Uri($options); } else { //--//require_once 'Zend/Navigation/Exception.php'; $message = 'Invalid argument: Unable to determine class to instantiate'; if (isset($options['label'])) { $message .= ' (Page label: ' . $options['label'] . ')'; } throw new Zend_Navigation_Exception($message); } } /** * Page constructor * * @param array|Zend_Config $options [optional] page options. Default is * null, which should set defaults. * @throws Zend_Navigation_Exception if invalid options are given */ public function __construct($options = null) { if (is_array($options)) { $this->setOptions($options); } elseif ($options instanceof Zend_Config) { $this->setConfig($options); } // do custom initialization $this->_init(); } /** * Initializes page (used by subclasses) * * @return void */ protected function _init() { } /** * Sets page properties using a Zend_Config object * * @param Zend_Config $config config object to get properties from * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if invalid options are given */ public function setConfig(Zend_Config $config) { return $this->setOptions($config->toArray()); } /** * Sets page properties using options from an associative array * * Each key in the array corresponds to the according set*() method, and * each word is separated by underscores, e.g. the option 'target' * corresponds to setTarget(), and the option 'reset_params' corresponds to * the method setResetParams(). * * @param array $options associative array of options to set * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if invalid options are given */ public function setOptions(array $options) { foreach ($options as $key => $value) { $this->set($key, $value); } return $this; } // Accessors: /** * Sets page label * * @param string $label new page label * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if empty/no string is given */ public function setLabel($label) { if (null !== $label && !is_string($label)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $label must be a string or null'); } $this->_label = $label; return $this; } /** * Returns page label * * @return string page label or null */ public function getLabel() { return $this->_label; } /** * Sets a fragment identifier * * @param string $fragment new fragment identifier * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if empty/no string is given */ public function setFragment($fragment) { if (null !== $fragment && !is_string($fragment)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $fragment must be a string or null'); } $this->_fragment = $fragment; return $this; } /** * Returns fragment identifier * * @return string|null fragment identifier */ public function getFragment() { return $this->_fragment; } /** * Sets page id * * @param string|null $id [optional] id to set. Default is null, * which sets no id. * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if not given string or null */ public function setId($id = null) { if (null !== $id && !is_string($id) && !is_numeric($id)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $id must be a string, number or null'); } $this->_id = null === $id ? $id : (string) $id; return $this; } /** * Returns page id * * @return string|null page id or null */ public function getId() { return $this->_id; } /** * Sets page CSS class * * @param string|null $class [optional] CSS class to set. Default * is null, which sets no CSS class. * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if not given string or null */ public function setClass($class = null) { if (null !== $class && !is_string($class)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $class must be a string or null'); } $this->_class = $class; return $this; } /** * Returns page class (CSS) * * @return string|null page's CSS class or null */ public function getClass() { return $this->_class; } /** * Sets page title * * @param string $title [optional] page title. Default is * null, which sets no title. * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if not given string or null */ public function setTitle($title = null) { if (null !== $title && !is_string($title)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $title must be a non-empty string'); } $this->_title = $title; return $this; } /** * Returns page title * * @return string|null page title or null */ public function getTitle() { return $this->_title; } /** * Sets page target * * @param string|null $target [optional] target to set. Default is * null, which sets no target. * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if target is not string or null */ public function setTarget($target = null) { if (null !== $target && !is_string($target)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $target must be a string or null'); } $this->_target = $target; return $this; } /** * Returns page target * * @return string|null page target or null */ public function getTarget() { return $this->_target; } /** * Sets access key for this page * * @param string|null $character [optional] access key to set. Default * is null, which sets no access key. * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if access key is not string or null or * if the string length not equal to one */ public function setAccesskey($character = null) { if (null !== $character && (!is_string($character) || 1 != strlen($character))) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $character must be a single character or null' ); } $this->_accesskey = $character; return $this; } /** * Returns page access key * * @return string|null page access key or null */ public function getAccesskey() { return $this->_accesskey; } /** * Sets the page's forward links to other pages * * This method expects an associative array of forward links to other pages, * where each element's key is the name of the relation (e.g. alternate, * prev, next, help, etc), and the value is a mixed value that could somehow * be considered a page. * * @param array|Zend_Config $relations [optional] an associative array of * forward links to other pages * @return Zend_Navigation_Page fluent interface, returns self */ public function setRel($relations = null) { $this->_rel = array(); if (null !== $relations) { if ($relations instanceof Zend_Config) { $relations = $relations->toArray(); } if (!is_array($relations)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $relations must be an ' . 'array or an instance of Zend_Config'); } foreach ($relations as $name => $relation) { if (is_string($name)) { $this->_rel[$name] = $relation; } } } return $this; } /** * Returns the page's forward links to other pages * * This method returns an associative array of forward links to other pages, * where each element's key is the name of the relation (e.g. alternate, * prev, next, help, etc), and the value is a mixed value that could somehow * be considered a page. * * @param string $relation [optional] name of relation to return. If not * given, all relations will be returned. * @return array an array of relations. If $relation is not * specified, all relations will be returned in * an associative array. */ public function getRel($relation = null) { if (null !== $relation) { return isset($this->_rel[$relation]) ? $this->_rel[$relation] : null; } return $this->_rel; } /** * Sets the page's reverse links to other pages * * This method expects an associative array of reverse links to other pages, * where each element's key is the name of the relation (e.g. alternate, * prev, next, help, etc), and the value is a mixed value that could somehow * be considered a page. * * @param array|Zend_Config $relations [optional] an associative array of * reverse links to other pages * @return Zend_Navigation_Page fluent interface, returns self */ public function setRev($relations = null) { $this->_rev = array(); if (null !== $relations) { if ($relations instanceof Zend_Config) { $relations = $relations->toArray(); } if (!is_array($relations)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $relations must be an ' . 'array or an instance of Zend_Config'); } foreach ($relations as $name => $relation) { if (is_string($name)) { $this->_rev[$name] = $relation; } } } return $this; } /** * Returns the page's reverse links to other pages * * This method returns an associative array of forward links to other pages, * where each element's key is the name of the relation (e.g. alternate, * prev, next, help, etc), and the value is a mixed value that could somehow * be considered a page. * * @param string $relation [optional] name of relation to return. If not * given, all relations will be returned. * @return array an array of relations. If $relation is not * specified, all relations will be returned in * an associative array. */ public function getRev($relation = null) { if (null !== $relation) { return isset($this->_rev[$relation]) ? $this->_rev[$relation] : null; } return $this->_rev; } /** * Sets a single custom HTML attribute * * @param string $name name of the HTML attribute * @param string|null $value value for the HTML attribute * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if name is not string or value is * not null or a string */ public function setCustomHtmlAttrib($name, $value) { if (!is_string($name)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $name must be a string' ); } if (null !== $value && !is_string($value)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $value must be a string or null' ); } if (null === $value && isset($this->_customHtmlAttribs[$name])) { unset($this->_customHtmlAttribs[$name]); } else { $this->_customHtmlAttribs[$name] = $value; } return $this; } /** * Returns a single custom HTML attributes by name * * @param string $name name of the HTML attribute * @return string|null value for the HTML attribute or null * @throws Zend_Navigation_Exception if name is not string */ public function getCustomHtmlAttrib($name) { if (!is_string($name)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $name must be a string' ); } if (isset($this->_customHtmlAttribs[$name])) { return $this->_customHtmlAttribs[$name]; } return null; } /** * Sets multiple custom HTML attributes at once * * @param array $attribs an associative array of html attributes * @return Zend_Navigation_Page fluent interface, returns self */ public function setCustomHtmlAttribs(array $attribs) { foreach ($attribs as $key => $value) { $this->setCustomHtmlAttrib($key, $value); } return $this; } /** * Returns all custom HTML attributes as an array * * @return array an array containing custom HTML attributes */ public function getCustomHtmlAttribs() { return $this->_customHtmlAttribs; } /** * Removes a custom HTML attribute from the page * * @param string $name name of the custom HTML attribute * @return Zend_Navigation_Page fluent interface, returns self */ public function removeCustomHtmlAttrib($name) { if (!is_string($name)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $name must be a string' ); } if (isset($this->_customHtmlAttribs[$name])) { unset($this->_customHtmlAttribs[$name]); } } /** * Clear all custom HTML attributes * * @return Zend_Navigation_Page fluent interface, returns self */ public function clearCustomHtmlAttribs() { $this->_customHtmlAttribs = array(); return $this; } /** * Sets page order to use in parent container * * @param int $order [optional] page order in container. * Default is null, which sets no * specific order. * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if order is not integer or null */ public function setOrder($order = null) { if (is_string($order)) { $temp = (int) $order; if ($temp < 0 || $temp > 0 || $order == '0') { $order = $temp; } } if (null !== $order && !is_int($order)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $order must be an integer or null, ' . 'or a string that casts to an integer'); } $this->_order = $order; // notify parent, if any if (isset($this->_parent)) { $this->_parent->notifyOrderUpdated(); } return $this; } /** * Returns page order used in parent container * * @return int|null page order or null */ public function getOrder() { return $this->_order; } /** * Sets ACL resource assoicated with this page * * @param string|Zend_Acl_Resource_Interface $resource [optional] resource * to associate with * page. Default is * null, which sets no * resource. * @throws Zend_Navigation_Exception if $resource if * invalid * @return Zend_Navigation_Page fluent interface, * returns self */ public function setResource($resource = null) { if (null === $resource || is_string($resource) || $resource instanceof Zend_Acl_Resource_Interface) { $this->_resource = $resource; } else { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $resource must be null, a string, ' . ' or an instance of Zend_Acl_Resource_Interface'); } return $this; } /** * Returns ACL resource assoicated with this page * * @return string|Zend_Acl_Resource_Interface|null ACL resource or null */ public function getResource() { return $this->_resource; } /** * Sets ACL privilege associated with this page * * @param string|null $privilege [optional] ACL privilege to associate * with this page. Default is null, which * sets no privilege. * @return Zend_Navigation_Page fluent interface, returns self */ public function setPrivilege($privilege = null) { $this->_privilege = is_string($privilege) ? $privilege : null; return $this; } /** * Returns ACL privilege associated with this page * * @return string|null ACL privilege or null */ public function getPrivilege() { return $this->_privilege; } /** * Sets whether page should be considered active or not * * @param bool $active [optional] whether page should be * considered active or not. Default is true. * @return Zend_Navigation_Page fluent interface, returns self */ public function setActive($active = true) { $this->_active = (bool) $active; return $this; } /** * Returns whether page should be considered active or not * * @param bool $recursive [optional] whether page should be considered * active if any child pages are active. Default is * false. * @return bool whether page should be considered active */ public function isActive($recursive = false) { if (!$this->_active && $recursive) { foreach ($this->_pages as $page) { if ($page->isActive(true)) { return true; } } return false; } return $this->_active; } /** * Proxy to isActive() * * @param bool $recursive [optional] whether page should be considered * active if any child pages are active. Default * is false. * @return bool whether page should be considered active */ public function getActive($recursive = false) { return $this->isActive($recursive); } /** * Sets whether the page should be visible or not * * @param bool $visible [optional] whether page should be * considered visible or not. Default is true. * @return Zend_Navigation_Page fluent interface, returns self */ public function setVisible($visible = true) { if (is_string($visible) && 'false' == strtolower($visible)) { $visible = false; } $this->_visible = (bool) $visible; return $this; } /** * Returns a boolean value indicating whether the page is visible * * @param bool $recursive [optional] whether page should be considered * invisible if parent is invisible. Default is * false. * @return bool whether page should be considered visible */ public function isVisible($recursive = false) { if ($recursive && isset($this->_parent) && $this->_parent instanceof Zend_Navigation_Page) { if (!$this->_parent->isVisible(true)) { return false; } } return $this->_visible; } /** * Proxy to isVisible() * * Returns a boolean value indicating whether the page is visible * * @param bool $recursive [optional] whether page should be considered * invisible if parent is invisible. Default is * false. * @return bool whether page should be considered visible */ public function getVisible($recursive = false) { return $this->isVisible($recursive); } /** * Sets parent container * * @param Zend_Navigation_Container $parent [optional] new parent to set. * Default is null which will set * no parent. * @return Zend_Navigation_Page fluent interface, returns self */ public function setParent(Zend_Navigation_Container $parent = null) { if ($parent === $this) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'A page cannot have itself as a parent'); } // return if the given parent already is parent if ($parent === $this->_parent) { return $this; } // remove from old parent if (null !== $this->_parent) { $this->_parent->removePage($this); } // set new parent $this->_parent = $parent; // add to parent if page and not already a child if (null !== $this->_parent && !$this->_parent->hasPage($this, false)) { $this->_parent->addPage($this); } return $this; } /** * Returns parent container * * @return Zend_Navigation_Container|null parent container or null */ public function getParent() { return $this->_parent; } /** * Sets the given property * * If the given property is native (id, class, title, etc), the matching * set method will be used. Otherwise, it will be set as a custom property. * * @param string $property property name * @param mixed $value value to set * @return Zend_Navigation_Page fluent interface, returns self * @throws Zend_Navigation_Exception if property name is invalid */ public function set($property, $value) { if (!is_string($property) || empty($property)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $property must be a non-empty string'); } $method = 'set' . self::_normalizePropertyName($property); if ($method != 'setOptions' && $method != 'setConfig' && method_exists($this, $method)) { $this->$method($value); } else { $this->_properties[$property] = $value; } return $this; } /** * Returns the value of the given property * * If the given property is native (id, class, title, etc), the matching * get method will be used. Otherwise, it will return the matching custom * property, or null if not found. * * @param string $property property name * @return mixed the property's value or null * @throws Zend_Navigation_Exception if property name is invalid */ public function get($property) { if (!is_string($property) || empty($property)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $property must be a non-empty string'); } $method = 'get' . self::_normalizePropertyName($property); if (method_exists($this, $method)) { return $this->$method(); } elseif (isset($this->_properties[$property])) { return $this->_properties[$property]; } return null; } // Magic overloads: /** * Sets a custom property * * Magic overload for enabling $page->propname = $value. * * @param string $name property name * @param mixed $value value to set * @return void * @throws Zend_Navigation_Exception if property name is invalid */ public function __set($name, $value) { $this->set($name, $value); } /** * Returns a property, or null if it doesn't exist * * Magic overload for enabling $page->propname. * * @param string $name property name * @return mixed property value or null * @throws Zend_Navigation_Exception if property name is invalid */ public function __get($name) { return $this->get($name); } /** * Checks if a property is set * * Magic overload for enabling isset($page->propname). * * Returns true if the property is native (id, class, title, etc), and * true or false if it's a custom property (depending on whether the * property actually is set). * * @param string $name property name * @return bool whether the given property exists */ public function __isset($name) { $method = 'get' . self::_normalizePropertyName($name); if (method_exists($this, $method)) { return true; } return isset($this->_properties[$name]); } /** * Unsets the given custom property * * Magic overload for enabling unset($page->propname). * * @param string $name property name * @return void * @throws Zend_Navigation_Exception if the property is native */ public function __unset($name) { $method = 'set' . self::_normalizePropertyName($name); if (method_exists($this, $method)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception(sprintf( 'Unsetting native property "%s" is not allowed', $name)); } if (isset($this->_properties[$name])) { unset($this->_properties[$name]); } } /** * Returns page label * * Magic overload for enabling echo $page. * * @return string page label */ public function __toString() { return $this->_label; } // Public methods: /** * Adds a forward relation to the page * * @param string $relation relation name (e.g. alternate, glossary, * canonical, etc) * @param mixed $value value to set for relation * @return Zend_Navigation_Page fluent interface, returns self */ public function addRel($relation, $value) { if (is_string($relation)) { $this->_rel[$relation] = $value; } return $this; } /** * Adds a reverse relation to the page * * @param string $relation relation name (e.g. alternate, glossary, * canonical, etc) * @param mixed $value value to set for relation * @return Zend_Navigation_Page fluent interface, returns self */ public function addRev($relation, $value) { if (is_string($relation)) { $this->_rev[$relation] = $value; } return $this; } /** * Removes a forward relation from the page * * @param string $relation name of relation to remove * @return Zend_Navigation_Page fluent interface, returns self */ public function removeRel($relation) { if (isset($this->_rel[$relation])) { unset($this->_rel[$relation]); } return $this; } /** * Removes a reverse relation from the page * * @param string $relation name of relation to remove * @return Zend_Navigation_Page fluent interface, returns self */ public function removeRev($relation) { if (isset($this->_rev[$relation])) { unset($this->_rev[$relation]); } return $this; } /** * Returns an array containing the defined forward relations * * @return array defined forward relations */ public function getDefinedRel() { return array_keys($this->_rel); } /** * Returns an array containing the defined reverse relations * * @return array defined reverse relations */ public function getDefinedRev() { return array_keys($this->_rev); } /** * Returns custom properties as an array * * @return array an array containing custom properties */ public function getCustomProperties() { return $this->_properties; } /** * Returns a hash code value for the page * * @return string a hash code value for this page */ public final function hashCode() { return spl_object_hash($this); } /** * Returns an array representation of the page * * @return array associative array containing all page properties */ public function toArray() { return array_merge( $this->getCustomProperties(), array( 'label' => $this->getlabel(), 'fragment' => $this->getFragment(), 'id' => $this->getId(), 'class' => $this->getClass(), 'title' => $this->getTitle(), 'target' => $this->getTarget(), 'accesskey' => $this->getAccesskey(), 'rel' => $this->getRel(), 'rev' => $this->getRev(), 'customHtmlAttribs' => $this->getCustomHtmlAttribs(), 'order' => $this->getOrder(), 'resource' => $this->getResource(), 'privilege' => $this->getPrivilege(), 'active' => $this->isActive(), 'visible' => $this->isVisible(), 'type' => get_class($this), 'pages' => parent::toArray() ) ); } // Internal methods: /** * Normalizes a property name * * @param string $property property name to normalize * @return string normalized property name */ protected static function _normalizePropertyName($property) { return str_replace(' ', '', ucwords(str_replace('_', ' ', $property))); } public static function setDefaultPageType($type = null) { if($type !== null && !is_string($type)) { throw new Zend_Navigation_Exception( 'Cannot set default page type: type is no string but should be' ); } self::$_defaultPageType = $type; } public static function getDefaultPageType() { return self::$_defaultPageType; } // Abstract methods: /** * Returns href for this page * * @return string the page's href */ abstract public function getHref(); } Page/Mvc.php000064400000043545152101616340006670 0ustar00_active) { $front = Zend_Controller_Front::getInstance(); $request = $front->getRequest(); $reqParams = array(); if ($request) { $reqParams = $request->getParams(); if (!array_key_exists('module', $reqParams)) { $reqParams['module'] = $front->getDefaultModule(); } } $myParams = $this->_params; if ($this->_route && method_exists($front->getRouter(), 'getRoute') ) { $route = $front->getRouter()->getRoute($this->_route); if (method_exists($route, 'getDefaults')) { $myParams = array_merge($route->getDefaults(), $myParams); } } if (null !== $this->_module) { $myParams['module'] = $this->_module; } elseif (!array_key_exists('module', $myParams)) { $myParams['module'] = $front->getDefaultModule(); } if (null !== $this->_controller) { $myParams['controller'] = $this->_controller; } elseif (!array_key_exists('controller', $myParams)) { $myParams['controller'] = $front->getDefaultControllerName(); } if (null !== $this->_action) { $myParams['action'] = $this->_action; } elseif (!array_key_exists('action', $myParams)) { $myParams['action'] = $front->getDefaultAction(); } foreach ($myParams as $key => $value) { if (null === $value) { unset($myParams[$key]); } } if (count(array_intersect_assoc($reqParams, $myParams)) == count($myParams) ) { $this->_active = true; return true; } $this->_active = false; } return parent::isActive($recursive); } /** * Returns href for this page * * This method uses {@link Zend_Controller_Action_Helper_Url} to assemble * the href based on the page's properties. * * @return string page href */ public function getHref() { if ($this->_hrefCache) { return $this->_hrefCache; } if (null === self::$_urlHelper) { self::$_urlHelper = Zend_Controller_Action_HelperBroker::getStaticHelper('Url'); } $params = $this->getParams(); if ($param = $this->getModule()) { $params['module'] = $param; } if ($param = $this->getController()) { $params['controller'] = $param; } if ($param = $this->getAction()) { $params['action'] = $param; } $url = self::$_urlHelper->url( $params, $this->getRoute(), $this->getResetParams(), $this->getEncodeUrl() ); // Use scheme? $scheme = $this->getScheme(); if (null !== $scheme) { if (null === self::$_schemeHelper) { //--//require_once 'Zend/View/Helper/ServerUrl.php'; self::$_schemeHelper = new Zend_View_Helper_ServerUrl(); } $url = self::$_schemeHelper->setScheme($scheme)->serverUrl($url); } // Add the fragment identifier if it is set $fragment = $this->getFragment(); if (null !== $fragment) { $url .= '#' . $fragment; } return $this->_hrefCache = $url; } /** * Sets action name to use when assembling URL * * @see getHref() * * @param string $action action name * @return Zend_Navigation_Page_Mvc fluent interface, returns self * @throws Zend_Navigation_Exception if invalid $action is given */ public function setAction($action) { if (null !== $action && !is_string($action)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $action must be a string or null' ); } $this->_action = $action; $this->_hrefCache = null; return $this; } /** * Returns action name to use when assembling URL * * @see getHref() * * @return string|null action name */ public function getAction() { return $this->_action; } /** * Sets controller name to use when assembling URL * * @see getHref() * * @param string|null $controller controller name * @return Zend_Navigation_Page_Mvc fluent interface, returns self * @throws Zend_Navigation_Exception if invalid controller name is given */ public function setController($controller) { if (null !== $controller && !is_string($controller)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $controller must be a string or null' ); } $this->_controller = $controller; $this->_hrefCache = null; return $this; } /** * Returns controller name to use when assembling URL * * @see getHref() * * @return string|null controller name or null */ public function getController() { return $this->_controller; } /** * Sets module name to use when assembling URL * * @see getHref() * * @param string|null $module module name * @return Zend_Navigation_Page_Mvc fluent interface, returns self * @throws Zend_Navigation_Exception if invalid module name is given */ public function setModule($module) { if (null !== $module && !is_string($module)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $module must be a string or null' ); } $this->_module = $module; $this->_hrefCache = null; return $this; } /** * Returns module name to use when assembling URL * * @see getHref() * * @return string|null module name or null */ public function getModule() { return $this->_module; } /** * Set multiple parameters (to use when assembling URL) at once * * URL options passed to the url action helper for assembling URLs. * Overwrites any previously set parameters! * * @see getHref() * * @param array|null $params [optional] paramters as array * ('name' => 'value'). Default is null * which clears all params. * @return Zend_Navigation_Page_Mvc fluent interface, returns self */ public function setParams(array $params = null) { $this->clearParams(); if (is_array($params)) { $this->addParams($params); } return $this; } /** * Set parameter (to use when assembling URL) * * URL option passed to the url action helper for assembling URLs. * * @see getHref() * * @param string $name parameter name * @param mixed $value parameter value * @return Zend_Navigation_Page_Mvc fluent interface, returns self */ public function setParam($name, $value) { $name = (string)$name; $this->_params[$name] = $value; $this->_hrefCache = null; return $this; } /** * Add multiple parameters (to use when assembling URL) at once * * URL options passed to the url action helper for assembling URLs. * * @see getHref() * * @param array $params paramters as array ('name' => 'value') * @return Zend_Navigation_Page_Mvc fluent interface, returns self */ public function addParams(array $params) { foreach ($params as $name => $value) { $this->setParam($name, $value); } return $this; } /** * Remove parameter (to use when assembling URL) * * @see getHref() * * @param string $name * @return bool */ public function removeParam($name) { if (array_key_exists($name, $this->_params)) { unset($this->_params[$name]); $this->_hrefCache = null; return true; } return false; } /** * Clear all parameters (to use when assembling URL) * * @see getHref() * * @return Zend_Navigation_Page_Mvc fluent interface, returns self */ public function clearParams() { $this->_params = array(); $this->_hrefCache = null; return $this; } /** * Retrieve all parameters (to use when assembling URL) * * @see getHref() * * @return array parameters as array ('name' => 'value') */ public function getParams() { return $this->_params; } /** * Retrieve a single parameter (to use when assembling URL) * * @see getHref() * * @param string $name parameter name * @return mixed */ public function getParam($name) { $name = (string) $name; if (!array_key_exists($name, $this->_params)) { return null; } return $this->_params[$name]; } /** * Sets route name to use when assembling URL * * @see getHref() * * @param string $route route name to use when assembling URL * @return Zend_Navigation_Page_Mvc fluent interface, returns self * @throws Zend_Navigation_Exception if invalid $route is given */ public function setRoute($route) { if (null !== $route && (!is_string($route) || strlen($route) < 1)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $route must be a non-empty string or null' ); } $this->_route = $route; $this->_hrefCache = null; return $this; } /** * Returns route name to use when assembling URL * * @see getHref() * * @return string route name */ public function getRoute() { return $this->_route; } /** * Sets whether params should be reset when assembling URL * * @see getHref() * * @param bool $resetParams whether params should be reset when * assembling URL * @return Zend_Navigation_Page_Mvc fluent interface, returns self */ public function setResetParams($resetParams) { $this->_resetParams = (bool) $resetParams; $this->_hrefCache = null; return $this; } /** * Returns whether params should be reset when assembling URL * * @see getHref() * * @return bool whether params should be reset when assembling URL */ public function getResetParams() { return $this->_resetParams; } /** * Sets whether href should be encoded when assembling URL * * @see getHref() * * @param $encodeUrl * @return Zend_Navigation_Page_Mvc fluent interface, returns self */ public function setEncodeUrl($encodeUrl) { $this->_encodeUrl = (bool) $encodeUrl; $this->_hrefCache = null; return $this; } /** * Returns whether herf should be encoded when assembling URL * * @see getHref() * * @return bool whether herf should be encoded when assembling URL */ public function getEncodeUrl() { return $this->_encodeUrl; } /** * Sets scheme to use when assembling URL * * @see getHref() * * @param string|null $scheme scheme * @throws Zend_Navigation_Exception * @return Zend_Navigation_Page_Mvc fluent interface, returns self */ public function setScheme($scheme) { if (null !== $scheme && !is_string($scheme)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $scheme must be a string or null' ); } $this->_scheme = $scheme; return $this; } /** * Returns scheme to use when assembling URL * * @see getHref() * * @return string|null scheme or null */ public function getScheme() { return $this->_scheme; } /** * Sets action helper for assembling URLs * * @see getHref() * * @param Zend_Controller_Action_Helper_Url $uh URL helper * @return void */ public static function setUrlHelper(Zend_Controller_Action_Helper_Url $uh) { self::$_urlHelper = $uh; } /** * Sets view helper for assembling URLs with schemes * * @see getHref() * * @param Zend_View_Helper_ServerUrl $sh scheme helper * @return void */ public static function setSchemeHelper(Zend_View_Helper_ServerUrl $sh) { self::$_schemeHelper = $sh; } // Public methods: /** * Returns an array representation of the page * * @return array associative array containing all page properties */ public function toArray() { return array_merge( parent::toArray(), array( 'action' => $this->getAction(), 'controller' => $this->getController(), 'module' => $this->getModule(), 'params' => $this->getParams(), 'route' => $this->getRoute(), 'reset_params' => $this->getResetParams(), 'encodeUrl' => $this->getEncodeUrl(), 'scheme' => $this->getScheme(), ) ); } } Page/Uri.php000064400000005321152101616340006670 0ustar00_uri = $uri; return $this; } /** * Returns URI * * @return string */ public function getUri() { return $this->_uri; } /** * Returns href for this page * * @return string */ public function getHref() { $uri = $this->getUri(); $fragment = $this->getFragment(); if (null !== $fragment) { if ('#' == substr($uri, -1)) { return $uri . $fragment; } else { return $uri . '#' . $fragment; } } return $uri; } // Public methods: /** * Returns an array representation of the page * * @return array */ public function toArray() { return array_merge( parent::toArray(), array( 'uri' => $this->getUri() )); } } Admin.php000064400000027660152101616340006317 0ustar00addPage(array( 'id' => 'dashboard', 'controller' => 'admin', 'label' => ___('Dashboard') )); $this->addPage(Am_Navigation_Page::factory(array( 'id' => 'users', 'uri' => '#', 'label' => ___('Users'), 'resource' => 'grid_u', 'privilege' => 'browse', 'pages' => array_merge( array( array( 'id' => 'users-browse', 'controller' => 'admin-users', 'label' => ___('Browse Users'), 'resource' => 'grid_u', 'privilege' => 'browse', 'class' => 'bold', ), array( 'id' => 'users-insert', 'uri' => Am_Di::getInstance()->url('admin-users',array('_u_a'=>'insert')), 'label' => ___('Add User'), 'resource' => 'grid_u', 'privilege' => 'insert', ), ), !Am_Di::getInstance()->config->get('manually_approve') ? array() : array(array( 'id' => 'user-not-approved', 'controller' => 'admin-users', 'action' => 'not-approved', 'label' => ___('Not Approved Users'), 'resource' => 'grid_u', 'privilege' => 'browse', )), array( array( 'id' => 'users-email', 'controller' => 'admin-email', 'label' => ___('E-Mail Users'), 'resource' => Am_Auth_Admin::PERM_EMAIL, ), array( 'id' => 'users-import', 'controller' => 'admin-import', 'label' => ___('Import Users'), 'resource' => Am_Auth_Admin::PERM_IMPORT, ) )) ))); $this->addPage(array( 'id' => 'reports', 'uri' => '#', 'label' => ___('Reports'), 'pages' => array( array( 'id' => 'reports-reports', 'controller' => 'admin-reports', 'label' => ___('Reports'), 'resource' => Am_Auth_Admin::PERM_REPORT, ), array( 'id' => 'reports-payments', 'type' => 'Am_Navigation_Page_Mvc', 'controller' => 'admin-payments', 'label' => ___('Payments'), 'resource' => array( 'grid_payment', 'grid_invoice' ) ), ) )); $this->addPage(array( 'id' => 'products', 'uri' => '#', 'label' => ___('Products'), 'pages' => array_filter(array( array( 'id' => 'products-manage', 'controller' => 'admin-products', 'label' => ___('Manage Products'), 'resource' => 'grid_product', 'class' => 'bold', ), array( 'id' => 'products-coupons', 'controller' => 'admin-coupons', 'label' => ___('Coupons'), 'resource' => 'grid_coupon', ), )) )); /** * Temporary disable this menu if user is on upgrade controller in order to avoid error: * Fatal error: Class Folder contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (ResourceAbstract::getAccessType) * * @todo Remove this in the future; * */ $content_pages = array(); if(Am_Di::getInstance()->request->getControllerName() != 'admin-upgrade') { foreach (Am_Di::getInstance()->resourceAccessTable->getAccessTables() as $t) { $k = $t->getPageId(); $content_pages[] = array( 'id' => 'content-'.$k, 'module' => 'default', 'controller' => 'admin-content', 'action' => 'index', 'label' => $t->getAccessTitle(), 'resource' => 'grid_' . $t->getPageId(), 'params' => array( 'page_id' => $k, ), 'route' => 'inside-pages' ); } } $this->addPage(array( 'id' => 'content', 'controller' => 'admin-content', 'label' => ___('Protect Content'), 'class' => 'bold', 'pages' => $content_pages, )); $this->addPage(array( 'id' => 'configuration', 'uri' => '#', 'label' => ___('Configuration'), 'pages' => array_filter(array( array( 'id' => 'setup', 'controller' => 'admin-setup', 'label' => ___('Setup/Configuration'), 'resource' => Am_Auth_Admin::PERM_SETUP, 'class' => 'bold', ), array( 'id' => 'saved-form', 'controller' => 'admin-saved-form', 'label' => ___('Forms Editor'), 'resource' => @constant('Am_Auth_Admin::PERM_FORM'), 'class' => 'bold', ), array( 'id' => 'fields', 'controller' => 'admin-fields', 'label' => ___('Add User Fields'), 'resource' => @constant('Am_Auth_Admin::PERM_ADD_USER_FIELD'), ), array( 'id' => 'email-template-layout', 'controller' => 'admin-email-template-layout', 'label' => ___('Email Layouts'), 'resource' => Am_Auth_Admin::PERM_SETUP, ), array( 'id' => 'ban', 'controller' => 'admin-ban', 'label' => ___('Blocking IP/E-Mail'), 'resource' => @constant('Am_Auth_Admin::PERM_BAN'), ), array( 'id' => 'countries', 'controller' => 'admin-countries', 'label' => ___('Countries/States'), 'resource' => @constant('Am_Auth_Admin::PERM_COUNTRY_STATE') ), array( 'id' => 'admins', 'controller' => 'admin-admins', 'label' => ___('Admin Accounts'), 'resource' => Am_Auth_Admin::PERM_SUPER_USER, ), array( 'id' => 'change-pass', 'controller' => 'admin-change-pass', 'label' => ___('Change Password') ), )), )); $this->addPage(array( 'id' => 'utilites', 'uri' => '#', 'label' => ___('Utilities'), 'order' => 1000, 'pages' => array_filter(array( Am_Di::getInstance()->modules->isEnabled('cc') ? null : array( 'id' => 'backup', 'controller' => 'admin-backup', 'label' => ___('Backup'), 'resource' => Am_Auth_Admin::PERM_BACKUP_RESTORE, ), Am_Di::getInstance()->modules->isEnabled('cc') ? null : array( 'id' => 'restore', 'controller' => 'admin-restore', 'label' => ___('Restore'), 'resource' => Am_Auth_Admin::PERM_BACKUP_RESTORE, ), array( 'id' => 'rebuild', 'controller' => 'admin-rebuild', 'label' => ___('Rebuild Db'), 'resource' => @constant('Am_Auth_Admin::PERM_REBUILD_DB'), ), array( 'id' => 'logs', 'type' => 'Am_Navigation_Page_Mvc', 'controller' => 'admin-logs', 'label' => ___('Logs'), 'resource' => array( @constant('Am_Auth_Admin::PERM_LOGS'), @constant('Am_Auth_Admin::PERM_LOGS_ACCESS'), // to avoid problems on upgrade! @constant('Am_Auth_Admin::PERM_LOGS_INVOICE'), @constant('Am_Auth_Admin::PERM_LOGS_MAIL'), @constant('Am_Auth_Admin::PERM_LOGS_ADMIN'), ) ), array( 'id' => 'info', 'controller' => 'admin-info', 'label' => ___('System Info'), 'resource' => @constant('Am_Auth_Admin::PERM_SYSTEM_INFO'), ), array( 'id' => 'trans-global', 'controller' => 'admin-trans-global', 'label' => ___('Edit Messages'), 'resource' => @constant('Am_Auth_Admin::PERM_TRANSLATION') ), // (count(Am_Di::getInstance()->config->get('lang.enabled')) > 1) ? array( // 'controller' => 'admin-trans-local', // 'label' => ___('Local Translations'), // 'resource' => Am_Auth_Admin::PERM_SUPER_USER, // ) : null, array( 'id' => 'clear', 'controller' => 'admin-clear', 'label' => ___('Delete Old Records'), 'resource' => @constant('Am_Auth_Admin::PERM_CLEAR'), ), array( 'id' => 'build-demo', 'controller' => 'admin-build-demo', 'label' => ___('Build Demo'), 'resource' => @constant('Am_Auth_Admin::PERM_BUILD_DEMO'), ), )), )); $this->addPage(array( 'id' => 'help', 'uri' => '#', 'label' => ___('Help & Support'), 'order' => 1001, 'pages' => array_filter(array( array( 'id' => 'documentation', 'uri' => 'http://www.amember.com/docs/', 'target' => '_blank', 'label' => ___('Documentation'), ), array( 'id' => 'support', 'uri' => 'https://www.amember.com/support/', 'target' => '_blank', 'label' => ___('Support'), ), array( 'id' => 'report-bugs', 'uri' => 'http://bt.amember.com/', 'target' => '_blank', 'label' => ___('Report Bugs'), ), array( 'id' => 'report-feature', 'uri' => 'http://bt.amember.com/', 'target' => '_blank', 'label' => ___('Suggest Feature'), ), ) ))); Am_Di::getInstance()->hook->call(Am_Event::ADMIN_MENU, array('menu' => $this)); /// workaround against using the current route for generating urls foreach (new RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST) as $child) if ($child instanceof Am_Navigation_Page_Mvc && $child->getRoute()===null) $child->setRoute('default'); } } UserTabs.php000064400000012346152101616340007012 0ustar00request; $id = $request->getInt('user_id', $request->getInt('id')); if (!$id && $request->getInt('_u_id')) $id = $request->getInt('_u_id'); if (!$id && $request->getParam('_u_a') == 'insert') $id = 'insert'; if (!$id) throw new Am_Exception_InputError("Could not find out [id]"); $uParams = array(); if ($action = $request->getFiltered('_u_a', 'edit')) $uParams['_u_a'] = $action; if ($a = $request->getFiltered('_u_id', $id)) $uParams['_u_id'] = $a; $userUrl = Am_Di::getInstance()->url('admin-users', $uParams, false); $this ->addPage(array( 'id' => 'users', 'uri' => $userUrl, 'label' => ___('User Info'), 'order' => 0, 'disabled' => $id <= 0, 'resource' => 'grid_u', 'active' => $request->getFiltered('_u_id', false) ))->addPage(array( 'id' => 'payments', 'type' => 'Am_Navigation_Page_Uri', 'label' => ___('Payments/Access'), 'uri' => 'javascript:;', 'order' => 100, 'resource' => array( 'grid_payment', 'grid_access' ), 'pages' => array( array( 'id' => 'payments-invoice', 'type' => 'Am_Navigation_Page_Mvc', 'label' => ___('Invoices/Access'), 'controller' => 'admin-user-payments', 'params' => array( 'user_id' => $id, ), 'resource' => array( 'grid_payment', 'grid_access' ) ), array( 'id' => 'payments-payment', 'label' => ___('Payments'), 'controller' => 'admin-user-payments', 'action' => 'payment', 'params' => array( 'user_id' => $id, ), 'resource' => 'grid_payment', ) ) ))->addPage(array( 'id' => 'access-log', 'label' => ___('Access Log'), 'controller' => 'admin-users', 'action' => 'access-log', 'params' => array( 'user_id' => $id, ), 'order' => 200, 'resource' => Am_Auth_Admin::PERM_LOGS_ACCESS, )); if (Am_Di::getInstance()->config->get('email_log_days')) { $this->addPage(array( 'id' => 'mail-queue', 'label' => ___('Mail Queue'), 'controller' => 'admin-users', 'action' => 'mail-queue', 'params' => array( 'user_id' => $id, ), 'order' => 300, 'resource' => Am_Auth_Admin::PERM_LOGS_MAIL, )); } if (Am_Di::getInstance()->cacheFunction->call(array($this, 'isDownloadLimitEnabled'))) { $this->addPage(array( 'id' => 'file-download', 'order' => 120, 'label' => ___('File Downloads'), 'controller' => 'admin-file-download', 'params' => array( 'user_id' => $id, ), 'resource' => Am_Auth_Admin::PERM_LOGS_DOWNLOAD, )); } $cnt = Am_Di::getInstance()->db->selectCell("SELECT COUNT(*) FROM ?_user_note WHERE user_id=?", $id); $this->addPage( array( 'id' => 'user-note', 'controller' => 'admin-user-note', 'action' => 'index', 'label' => ___('Notes') . ($cnt ? " ($cnt)" : ''), 'resource' => 'grid_un', 'order' => 400, 'params' => array( 'user_id' => $id ) ) ); $event = new Am_Event_UserTabs($this, $id<=0, (int)$id); Am_Di::getInstance()->hook->call($event); /// workaround against using the current route for generating urls foreach (new RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST) as $child) { if ($child instanceof Am_Navigation_Page_Mvc && $child->getRoute()===null) $child->setRoute('default'); if ($id<=0) $child->set('disabled', true); } } public function setActive($id) { foreach($this->getPages() as $page) { $page->setActive($page->getId() == $id); } } public function isDownloadLimitEnabled() { return Am_Di::getInstance()->fileTable->countBy(array('download_limit'=>'<>')); } } Container.php000064400000044265152101616340007211 0ustar00_dirtyIndex) { $newIndex = array(); $index = 0; foreach ($this->_pages as $hash => $page) { $order = $page->getOrder(); if ($order === null) { $newIndex[$hash] = $index; $index++; } else { $newIndex[$hash] = $order; } } asort($newIndex); $this->_index = $newIndex; $this->_dirtyIndex = false; } } // Public methods: /** * Notifies container that the order of pages are updated * * @return void */ public function notifyOrderUpdated() { $this->_dirtyIndex = true; } /** * Adds a page to the container * * This method will inject the container as the given page's parent by * calling {@link Zend_Navigation_Page::setParent()}. * * @param Zend_Navigation_Page|array|Zend_Config $page page to add * @return Zend_Navigation_Container fluent interface, * returns self * @throws Zend_Navigation_Exception if page is invalid */ public function addPage($page) { if ($page === $this) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'A page cannot have itself as a parent'); } if (is_array($page) || $page instanceof Zend_Config) { //--//require_once 'Zend/Navigation/Page.php'; $page = Zend_Navigation_Page::factory($page); } elseif (!$page instanceof Zend_Navigation_Page) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $page must be an instance of ' . 'Zend_Navigation_Page or Zend_Config, or an array'); } $hash = $page->hashCode(); if (array_key_exists($hash, $this->_index)) { // page is already in container return $this; } // adds page to container and sets dirty flag $this->_pages[$hash] = $page; $this->_index[$hash] = $page->getOrder(); $this->_dirtyIndex = true; // inject self as page parent $page->setParent($this); return $this; } /** * Adds several pages at once * * @param array|Zend_Config|Zend_Navigation_Container $pages pages to add * @return Zend_Navigation_Container fluent interface, * returns self * @throws Zend_Navigation_Exception if $pages is not * array, Zend_Config or * Zend_Navigation_Container */ public function addPages($pages) { if ($pages instanceof Zend_Config) { $pages = $pages->toArray(); } if ($pages instanceof Zend_Navigation_Container) { $pages = iterator_to_array($pages); } if (!is_array($pages)) { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Invalid argument: $pages must be an array, an ' . 'instance of Zend_Config or an instance of ' . 'Zend_Navigation_Container'); } foreach ($pages as $page) { $this->addPage($page); } return $this; } /** * Sets pages this container should have, removing existing pages * * @param array $pages pages to set * @return Zend_Navigation_Container fluent interface, returns self */ public function setPages(array $pages) { $this->removePages(); return $this->addPages($pages); } /** * Returns pages in the container * * @return array array of Zend_Navigation_Page instances */ public function getPages() { return $this->_pages; } /** * Removes the given page from the container * * @param Zend_Navigation_Page|int $page page to remove, either a page * instance or a specific page order * @return bool whether the removal was * successful */ public function removePage($page) { if ($page instanceof Zend_Navigation_Page) { $hash = $page->hashCode(); } elseif (is_int($page)) { $this->_sort(); if (!$hash = array_search($page, $this->_index)) { return false; } } else { return false; } if (isset($this->_pages[$hash])) { unset($this->_pages[$hash]); unset($this->_index[$hash]); $this->_dirtyIndex = true; return true; } return false; } /** * Removes all pages in container * * @return Zend_Navigation_Container fluent interface, returns self */ public function removePages() { $this->_pages = array(); $this->_index = array(); return $this; } /** * Checks if the container has the given page * * @param Zend_Navigation_Page $page page to look for * @param bool $recursive [optional] whether to search * recursively. Default is false. * @return bool whether page is in container */ public function hasPage(Zend_Navigation_Page $page, $recursive = false) { if (array_key_exists($page->hashCode(), $this->_index)) { return true; } elseif ($recursive) { foreach ($this->_pages as $childPage) { if ($childPage->hasPage($page, true)) { return true; } } } return false; } /** * Returns true if container contains any pages * * @return bool whether container has any pages */ public function hasPages() { return count($this->_index) > 0; } /** * Returns a child page matching $property == $value or * preg_match($value, $property), or null if not found * * @param string $property name of property to match against * @param mixed $value value to match property against * @param bool $useRegex [optional] if true PHP's preg_match * is used. Default is false. * @return Zend_Navigation_Page|null matching page or null */ public function findOneBy($property, $value, $useRegex = false) { $iterator = new RecursiveIteratorIterator( $this, RecursiveIteratorIterator::SELF_FIRST ); foreach ($iterator as $page) { $pageProperty = $page->get($property); // Rel and rev if (is_array($pageProperty)) { foreach ($pageProperty as $item) { if (is_array($item)) { // Use regex? if (true === $useRegex) { foreach ($item as $item2) { if (0 !== preg_match($value, $item2)) { return $page; } } } else { if (in_array($value, $item)) { return $page; } } } else { // Use regex? if (true === $useRegex) { if (0 !== preg_match($value, $item)) { return $page; } } else { if ($item == $value) { return $page; } } } } continue; } // Use regex? if (true === $useRegex) { if (preg_match($value, $pageProperty)) { return $page; } } else { if ($pageProperty == $value) { return $page; } } } return null; } /** * Returns all child pages matching $property == $value or * preg_match($value, $property), or an empty array if no pages are found * * @param string $property name of property to match against * @param mixed $value value to match property against * @param bool $useRegex [optional] if true PHP's preg_match is used. * Default is false. * @return array array containing only Zend_Navigation_Page * instances */ public function findAllBy($property, $value, $useRegex = false) { $found = array(); $iterator = new RecursiveIteratorIterator( $this, RecursiveIteratorIterator::SELF_FIRST ); foreach ($iterator as $page) { $pageProperty = $page->get($property); // Rel and rev if (is_array($pageProperty)) { foreach ($pageProperty as $item) { if (is_array($item)) { // Use regex? if (true === $useRegex) { foreach ($item as $item2) { if (0 !== preg_match($value, $item2)) { $found[] = $page; } } } else { if (in_array($value, $item)) { $found[] = $page; } } } else { // Use regex? if (true === $useRegex) { if (0 !== preg_match($value, $item)) { $found[] = $page; } } else { if ($item == $value) { $found[] = $page; } } } } continue; } // Use regex? if (true === $useRegex) { if (0 !== preg_match($value, $pageProperty)) { $found[] = $page; } } else { if ($pageProperty == $value) { $found[] = $page; } } } return $found; } /** * Returns page(s) matching $property == $value or * preg_match($value, $property) * * @param string $property name of property to match against * @param mixed $value value to match property against * @param bool $all [optional] whether an array of all matching * pages should be returned, or only the first. * If true, an array will be returned, even if not * matching pages are found. If false, null will * be returned if no matching page is found. * Default is false. * @param bool $useRegex [optional] if true PHP's preg_match is used. * Default is false. * @return Zend_Navigation_Page|null matching page or null */ public function findBy($property, $value, $all = false, $useRegex = false) { if ($all) { return $this->findAllBy($property, $value, $useRegex); } else { return $this->findOneBy($property, $value, $useRegex); } } /** * Magic overload: Proxy calls to finder methods * * Examples of finder calls: * * // METHOD // SAME AS * $nav->findByLabel('foo'); // $nav->findOneBy('label', 'foo'); * $nav->findByLabel('/foo/', true); // $nav->findBy('label', '/foo/', true); * $nav->findOneByLabel('foo'); // $nav->findOneBy('label', 'foo'); * $nav->findAllByClass('foo'); // $nav->findAllBy('class', 'foo'); * * * @param string $method method name * @param array $arguments method arguments * @return mixed Zend_Navigation|array|null matching page, array of pages * or null * @throws Zend_Navigation_Exception if method does not exist */ public function __call($method, $arguments) { if (@preg_match('/(find(?:One|All)?By)(.+)/', $method, $match)) { return $this->{$match[1]}($match[2], $arguments[0], !empty($arguments[1])); } //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( sprintf( 'Bad method call: Unknown method %s::%s', get_class($this), $method ) ); } /** * Returns an array representation of all pages in container * * @return array */ public function toArray() { $pages = array(); $this->_dirtyIndex = true; $this->_sort(); $indexes = array_keys($this->_index); foreach ($indexes as $hash) { $pages[] = $this->_pages[$hash]->toArray(); } return $pages; } // RecursiveIterator interface: /** * Returns current page * * Implements RecursiveIterator interface. * * @return Zend_Navigation_Page current page or null * @throws Zend_Navigation_Exception if the index is invalid */ public function current() { $this->_sort(); current($this->_index); $hash = key($this->_index); if (isset($this->_pages[$hash])) { return $this->_pages[$hash]; } else { //--//require_once 'Zend/Navigation/Exception.php'; throw new Zend_Navigation_Exception( 'Corruption detected in container; ' . 'invalid key found in internal iterator'); } } /** * Returns hash code of current page * * Implements RecursiveIterator interface. * * @return string hash code of current page */ public function key() { $this->_sort(); return key($this->_index); } /** * Moves index pointer to next page in the container * * Implements RecursiveIterator interface. * * @return void */ public function next() { $this->_sort(); next($this->_index); } /** * Sets index pointer to first page in the container * * Implements RecursiveIterator interface. * * @return void */ public function rewind() { $this->_sort(); reset($this->_index); } /** * Checks if container index is valid * * Implements RecursiveIterator interface. * * @return bool */ public function valid() { $this->_sort(); return current($this->_index) !== false; } /** * Proxy to hasPages() * * Implements RecursiveIterator interface. * * @return bool whether container has any pages */ public function hasChildren() { return $this->hasPages(); } /** * Returns the child container. * * Implements RecursiveIterator interface. * * @return Zend_Navigation_Page|null */ public function getChildren() { $hash = key($this->_index); if (isset($this->_pages[$hash])) { return $this->_pages[$hash]; } return null; } // Countable interface: /** * Returns number of pages in container * * Implements Countable interface. * * @return int number of pages in the container */ public function count() { return count($this->_index); } } Exception.php000064400000002072152101616340007213 0ustar00 tag * * @var string */ const SITEMAP_NS = 'http://www.sitemaps.org/schemas/sitemap/0.9'; /** * Schema URL * * @var string */ const SITEMAP_XSD = 'http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd'; /** * Whether the XML declaration should be included in XML output * * @var bool */ protected $_useXmlDeclaration = true; /** * Whether sitemap should be validated using Zend_Validate_Sitemap_* * * @var bool */ protected $_useSitemapValidators = true; /** * Whether sitemap should be schema validated when generated * * @var bool */ protected $_useSchemaValidation = false; /** * Server url * * @var string */ protected $_serverUrl; /** * View helper entry point: * Retrieves helper and optionally sets container to operate on * * @param Zend_Navigation_Container $container [optional] container to * operate on * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns * self */ public function sitemap(Zend_Navigation_Container $container = null) { if (null !== $container) { $this->setContainer($container); } return $this; } // Accessors: /** * Sets whether the XML declaration should be used in output * * @param bool $useXmlDecl whether XML delcaration * should be rendered * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns * self */ public function setUseXmlDeclaration($useXmlDecl) { $this->_useXmlDeclaration = (bool) $useXmlDecl; return $this; } /** * Returns whether the XML declaration should be used in output * * @return bool whether the XML declaration should be used in output */ public function getUseXmlDeclaration() { return $this->_useXmlDeclaration; } /** * Sets whether sitemap should be validated using Zend_Validate_Sitemap_* * * @param bool $useSitemapValidators whether sitemap validators * should be used * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns * self */ public function setUseSitemapValidators($useSitemapValidators) { $this->_useSitemapValidators = (bool) $useSitemapValidators; return $this; } /** * Returns whether sitemap should be validated using Zend_Validate_Sitemap_* * * @return bool whether sitemap should be validated using validators */ public function getUseSitemapValidators() { return $this->_useSitemapValidators; } /** * Sets whether sitemap should be schema validated when generated * * @param bool $schemaValidation whether sitemap should * validated using XSD Schema * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns * self */ public function setUseSchemaValidation($schemaValidation) { $this->_useSchemaValidation = (bool) $schemaValidation; return $this; } /** * Returns true if sitemap should be schema validated when generated * * @return bool */ public function getUseSchemaValidation() { return $this->_useSchemaValidation; } /** * Sets server url (scheme and host-related stuff without request URI) * * E.g. http://www.example.com * * @param string $serverUrl server URL to set (only * scheme and host) * @throws Zend_Uri_Exception if invalid server URL * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns * self */ public function setServerUrl($serverUrl) { //--//require_once 'Zend/Uri.php'; $uri = Zend_Uri::factory($serverUrl); $uri->setFragment(''); $uri->setPath(''); $uri->setQuery(''); if ($uri->valid()) { $this->_serverUrl = $uri->getUri(); } else { //--//require_once 'Zend/Uri/Exception.php'; $e = new Zend_Uri_Exception(sprintf( 'Invalid server URL: "%s"', $serverUrl)); $e->setView($this->view); throw $e; } return $this; } /** * Returns server URL * * @return string server URL */ public function getServerUrl() { if (!isset($this->_serverUrl)) { $this->_serverUrl = $this->view->serverUrl(); } return $this->_serverUrl; } // Helper methods: /** * Escapes string for XML usage * * @param string $string string to escape * @return string escaped string */ protected function _xmlEscape($string) { $enc = 'UTF-8'; if ($this->view instanceof Zend_View_Interface && method_exists($this->view, 'getEncoding') ) { $enc = $this->view->getEncoding(); } // do not encode existing HTML entities return htmlspecialchars($string, ENT_QUOTES, $enc, false); } // Public methods: /** * Returns an escaped absolute URL for the given page * * @param Zend_Navigation_Page $page page to get URL from * @return string */ public function url(Zend_Navigation_Page $page) { $href = $page->getHref(); if (!isset($href{0})) { // no href return ''; } elseif ($href{0} == '/') { // href is relative to root; use serverUrl helper $url = $this->getServerUrl() . $href; } elseif (preg_match('/^[a-z]+:/im', (string) $href)) { // scheme is given in href; assume absolute URL already $url = (string) $href; } else { // href is relative to current document; use url helpers $url = $this->getServerUrl() . rtrim($this->view->url(), '/') . '/' . $href; } return $this->_xmlEscape($url); } /** * Returns a DOMDocument containing the Sitemap XML for the given container * * @param Zend_Navigation_Container $container [optional] container to get * breadcrumbs from, defaults * to what is registered in the * helper * @return DOMDocument DOM representation of the * container * @throws Zend_View_Exception if schema validation is on * and the sitemap is invalid * according to the sitemap * schema, or if sitemap * validators are used and the * loc element fails validation */ public function getDomSitemap(Zend_Navigation_Container $container = null) { if (null === $container) { $container = $this->getContainer(); } // check if we should validate using our own validators if ($this->getUseSitemapValidators()) { //--//require_once 'Zend/Validate/Sitemap/Changefreq.php'; //--//require_once 'Zend/Validate/Sitemap/Lastmod.php'; //--//require_once 'Zend/Validate/Sitemap/Loc.php'; //--//require_once 'Zend/Validate/Sitemap/Priority.php'; // create validators $locValidator = new Zend_Validate_Sitemap_Loc(); $lastmodValidator = new Zend_Validate_Sitemap_Lastmod(); $changefreqValidator = new Zend_Validate_Sitemap_Changefreq(); $priorityValidator = new Zend_Validate_Sitemap_Priority(); } // create document $dom = new DOMDocument('1.0', 'UTF-8'); $dom->formatOutput = $this->getFormatOutput(); // ...and urlset (root) element $urlSet = $dom->createElementNS(self::SITEMAP_NS, 'urlset'); $dom->appendChild($urlSet); // create iterator $iterator = new RecursiveIteratorIterator($container, RecursiveIteratorIterator::SELF_FIRST); $maxDepth = $this->getMaxDepth(); if (is_int($maxDepth)) { $iterator->setMaxDepth($maxDepth); } $minDepth = $this->getMinDepth(); if (!is_int($minDepth) || $minDepth < 0) { $minDepth = 0; } // iterate container foreach ($iterator as $page) { if ($iterator->getDepth() < $minDepth || !$this->accept($page)) { // page should not be included continue; } // get absolute url from page if (!$url = $this->url($page)) { // skip page if it has no url (rare case) continue; } // create url node for this page $urlNode = $dom->createElementNS(self::SITEMAP_NS, 'url'); $urlSet->appendChild($urlNode); if ($this->getUseSitemapValidators() && !$locValidator->isValid($url)) { //--//require_once 'Zend/View/Exception.php'; $e = new Zend_View_Exception(sprintf( 'Encountered an invalid URL for Sitemap XML: "%s"', $url)); $e->setView($this->view); throw $e; } // put url in 'loc' element $urlNode->appendChild($dom->createElementNS(self::SITEMAP_NS, 'loc', $url)); // add 'lastmod' element if a valid lastmod is set in page if (isset($page->lastmod)) { $lastmod = strtotime((string) $page->lastmod); // prevent 1970-01-01... if ($lastmod !== false) { $lastmod = date('c', $lastmod); } if (!$this->getUseSitemapValidators() || $lastmodValidator->isValid($lastmod)) { $urlNode->appendChild( $dom->createElementNS(self::SITEMAP_NS, 'lastmod', $lastmod) ); } } // add 'changefreq' element if a valid changefreq is set in page if (isset($page->changefreq)) { $changefreq = $page->changefreq; if (!$this->getUseSitemapValidators() || $changefreqValidator->isValid($changefreq)) { $urlNode->appendChild( $dom->createElementNS(self::SITEMAP_NS, 'changefreq', $changefreq) ); } } // add 'priority' element if a valid priority is set in page if (isset($page->priority)) { $priority = $page->priority; if (!$this->getUseSitemapValidators() || $priorityValidator->isValid($priority)) { $urlNode->appendChild( $dom->createElementNS(self::SITEMAP_NS, 'priority', $priority) ); } } } // validate using schema if specified if ($this->getUseSchemaValidation()) { if (!@$dom->schemaValidate(self::SITEMAP_XSD)) { //--//require_once 'Zend/View/Exception.php'; $e = new Zend_View_Exception(sprintf( 'Sitemap is invalid according to XML Schema at "%s"', self::SITEMAP_XSD)); $e->setView($this->view); throw $e; } } return $dom; } // Zend_View_Helper_Navigation_Helper: /** * Renders helper * * Implements {@link Zend_View_Helper_Navigation_Helper::render()}. * * @param Zend_Navigation_Container $container [optional] container to * render. Default is to * render the container * registered in the helper. * @return string helper output */ public function render(Zend_Navigation_Container $container = null) { $dom = $this->getDomSitemap($container); $xml = $this->getUseXmlDeclaration() ? $dom->saveXML() : $dom->saveXML($dom->documentElement); return rtrim($xml, self::EOL); } } Links.php000064400000063000152101700250006325 0ustar00 elements * * @category Zend * @package Zend_View * @subpackage Helper * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ class Zend_View_Helper_Navigation_Links extends Zend_View_Helper_Navigation_HelperAbstract { /**#@+ * Constants used for specifying which link types to find and render * * @var int */ const RENDER_ALTERNATE = 0x0001; const RENDER_STYLESHEET = 0x0002; const RENDER_START = 0x0004; const RENDER_NEXT = 0x0008; const RENDER_PREV = 0x0010; const RENDER_CONTENTS = 0x0020; const RENDER_INDEX = 0x0040; const RENDER_GLOSSARY = 0x0080; const RENDER_COPYRIGHT = 0x0100; const RENDER_CHAPTER = 0x0200; const RENDER_SECTION = 0x0400; const RENDER_SUBSECTION = 0x0800; const RENDER_APPENDIX = 0x1000; const RENDER_HELP = 0x2000; const RENDER_BOOKMARK = 0x4000; const RENDER_CUSTOM = 0x8000; const RENDER_ALL = 0xffff; /**#@+**/ /** * Maps render constants to W3C link types * * @var array */ protected static $_RELATIONS = array( self::RENDER_ALTERNATE => 'alternate', self::RENDER_STYLESHEET => 'stylesheet', self::RENDER_START => 'start', self::RENDER_NEXT => 'next', self::RENDER_PREV => 'prev', self::RENDER_CONTENTS => 'contents', self::RENDER_INDEX => 'index', self::RENDER_GLOSSARY => 'glossary', self::RENDER_COPYRIGHT => 'copyright', self::RENDER_CHAPTER => 'chapter', self::RENDER_SECTION => 'section', self::RENDER_SUBSECTION => 'subsection', self::RENDER_APPENDIX => 'appendix', self::RENDER_HELP => 'help', self::RENDER_BOOKMARK => 'bookmark' ); /** * The helper's render flag * * @see render() * @see setRenderFlag() * @var int */ protected $_renderFlag = self::RENDER_ALL; /** * Root container * * Used for preventing methods to traverse above the container given to * the {@link render()} method. * * @see _findRoot() * * @var Zend_Navigation_Container */ protected $_root; /** * View helper entry point: * Retrieves helper and optionally sets container to operate on * * @param Zend_Navigation_Container $container [optional] container to * operate on * @return Zend_View_Helper_Navigation_Links fluent interface, returns * self */ public function links(Zend_Navigation_Container $container = null) { if (null !== $container) { $this->setContainer($container); } return $this; } /** * Magic overload: Proxy calls to {@link findRelation()} or container * * Examples of finder calls: * * // METHOD // SAME AS * $h->findRelNext($page); // $h->findRelation($page, 'rel', 'next') * $h->findRevSection($page); // $h->findRelation($page, 'rev', 'section'); * $h->findRelFoo($page); // $h->findRelation($page, 'rel', 'foo'); * * * @param string $method method name * @param array $arguments method arguments * @throws Zend_Navigation_Exception if method does not exist in container */ public function __call($method, array $arguments = array()) { if (@preg_match('/find(Rel|Rev)(.+)/', $method, $match)) { return $this->findRelation($arguments[0], strtolower($match[1]), strtolower($match[2])); } return parent::__call($method, $arguments); } // Accessors: /** * Sets the helper's render flag * * The helper uses the bitwise '&' operator against the hex values of the * render constants. This means that the flag can is "bitwised" value of * the render constants. Examples: * * // render all links except glossary * $flag = Zend_View_Helper_Navigation_Links:RENDER_ALL ^ * Zend_View_Helper_Navigation_Links:RENDER_GLOSSARY; * $helper->setRenderFlag($flag); * * // render only chapters and sections * $flag = Zend_View_Helper_Navigation_Links:RENDER_CHAPTER | * Zend_View_Helper_Navigation_Links:RENDER_SECTION; * $helper->setRenderFlag($flag); * * // render only relations that are not native W3C relations * $helper->setRenderFlag(Zend_View_Helper_Navigation_Links:RENDER_CUSTOM); * * // render all relations (default) * $helper->setRenderFlag(Zend_View_Helper_Navigation_Links:RENDER_ALL); * * * Note that custom relations can also be rendered directly using the * {@link renderLink()} method. * * @param int $renderFlag render flag * @return Zend_View_Helper_Navigation_Links fluent interface, returns self */ public function setRenderFlag($renderFlag) { $this->_renderFlag = (int) $renderFlag; return $this; } /** * Returns the helper's render flag * * @return int render flag */ public function getRenderFlag() { return $this->_renderFlag; } // Finder methods: /** * Finds all relations (forward and reverse) for the given $page * * The form of the returned array: * * // $page denotes an instance of Zend_Navigation_Page * $returned = array( * 'rel' => array( * 'alternate' => array($page, $page, $page), * 'start' => array($page), * 'next' => array($page), * 'prev' => array($page), * 'canonical' => array($page) * ), * 'rev' => array( * 'section' => array($page) * ) * ); * * * @param Zend_Navigation_Page $page page to find links for * @return array related pages */ public function findAllRelations(Zend_Navigation_Page $page, $flag = null) { if (!is_int($flag)) { $flag = self::RENDER_ALL; } $result = array('rel' => array(), 'rev' => array()); $native = array_values(self::$_RELATIONS); foreach (array_keys($result) as $rel) { $meth = 'getDefined' . ucfirst($rel); $types = array_merge($native, array_diff($page->$meth(), $native)); foreach ($types as $type) { if (!$relFlag = array_search($type, self::$_RELATIONS)) { $relFlag = self::RENDER_CUSTOM; } if (!($flag & $relFlag)) { continue; } if ($found = $this->findRelation($page, $rel, $type)) { if (!is_array($found)) { $found = array($found); } $result[$rel][$type] = $found; } } } return $result; } /** * Finds relations of the given $rel=$type from $page * * This method will first look for relations in the page instance, then * by searching the root container if nothing was found in the page. * * @param Zend_Navigation_Page $page page to find relations for * @param string $rel relation, "rel" or "rev" * @param string $type link type, e.g. 'start', 'next' * @return Zend_Navigaiton_Page|array|null page(s), or null if not found * @throws Zend_View_Exception if $rel is not "rel" or "rev" */ public function findRelation(Zend_Navigation_Page $page, $rel, $type) { if (!in_array($rel, array('rel', 'rev'))) { //--//require_once 'Zend/View/Exception.php'; $e = new Zend_View_Exception(sprintf( 'Invalid argument: $rel must be "rel" or "rev"; "%s" given', $rel)); $e->setView($this->view); throw $e; } if (!$result = $this->_findFromProperty($page, $rel, $type)) { $result = $this->_findFromSearch($page, $rel, $type); } return $result; } /** * Finds relations of given $type for $page by checking if the * relation is specified as a property of $page * * @param Zend_Navigation_Page $page page to find relations for * @param string $rel relation, 'rel' or 'rev' * @param string $type link type, e.g. 'start', 'next' * @return Zend_Navigation_Page|array|null page(s), or null if not found */ protected function _findFromProperty(Zend_Navigation_Page $page, $rel, $type) { $method = 'get' . ucfirst($rel); if ($result = $page->$method($type)) { if ($result = $this->_convertToPages($result)) { if (!is_array($result)) { $result = array($result); } foreach ($result as $key => $page) { if (!$this->accept($page)) { unset($result[$key]); } } return count($result) == 1 ? $result[0] : $result; } } return null; } /** * Finds relations of given $rel=$type for $page by using the helper to * search for the relation in the root container * * @param Zend_Navigation_Page $page page to find relations for * @param string $rel relation, 'rel' or 'rev' * @param string $type link type, e.g. 'start', 'next', etc * @return array|null array of pages, or null if not found */ protected function _findFromSearch(Zend_Navigation_Page $page, $rel, $type) { $found = null; $method = 'search' . ucfirst($rel) . ucfirst($type); if (method_exists($this, $method)) { $found = $this->$method($page); } return $found; } // Search methods: /** * Searches the root container for the forward 'start' relation of the given * $page * * From {@link http://www.w3.org/TR/html4/types.html#type-links}: * Refers to the first document in a collection of documents. This link type * tells search engines which document is considered by the author to be the * starting point of the collection. * * @param Zend_Navigation_Page $page page to find relation for * @return Zend_Navigation_Page|null page or null */ public function searchRelStart(Zend_Navigation_Page $page) { $found = $this->_findRoot($page); if (!$found instanceof Zend_Navigation_Page) { $found->rewind(); $found = $found->current(); } if ($found === $page || !$this->accept($found)) { $found = null; } return $found; } /** * Searches the root container for the forward 'next' relation of the given * $page * * From {@link http://www.w3.org/TR/html4/types.html#type-links}: * Refers to the next document in a linear sequence of documents. User * agents may choose to preload the "next" document, to reduce the perceived * load time. * * @param Zend_Navigation_Page $page page to find relation for * @return Zend_Navigation_Page|null page(s) or null */ public function searchRelNext(Zend_Navigation_Page $page) { $found = null; $break = false; $iterator = new RecursiveIteratorIterator($this->_findRoot($page), RecursiveIteratorIterator::SELF_FIRST); foreach ($iterator as $intermediate) { if ($intermediate === $page) { // current page; break at next accepted page $break = true; continue; } if ($break && $this->accept($intermediate)) { $found = $intermediate; break; } } return $found; } /** * Searches the root container for the forward 'prev' relation of the given * $page * * From {@link http://www.w3.org/TR/html4/types.html#type-links}: * Refers to the previous document in an ordered series of documents. Some * user agents also support the synonym "Previous". * * @param Zend_Navigation_Page $page page to find relation for * @return Zend_Navigation_Page|null page or null */ public function searchRelPrev(Zend_Navigation_Page $page) { $found = null; $prev = null; $iterator = new RecursiveIteratorIterator( $this->_findRoot($page), RecursiveIteratorIterator::SELF_FIRST); foreach ($iterator as $intermediate) { if (!$this->accept($intermediate)) { continue; } if ($intermediate === $page) { $found = $prev; break; } $prev = $intermediate; } return $found; } /** * Searches the root container for forward 'chapter' relations of the given * $page * * From {@link http://www.w3.org/TR/html4/types.html#type-links}: * Refers to a document serving as a chapter in a collection of documents. * * @param Zend_Navigation_Page $page page to find relation for * @return Zend_Navigation_Page|array|null page(s) or null */ public function searchRelChapter(Zend_Navigation_Page $page) { $found = array(); // find first level of pages $root = $this->_findRoot($page); // find start page(s) $start = $this->findRelation($page, 'rel', 'start'); if (!is_array($start)) { $start = array($start); } foreach ($root as $chapter) { // exclude self and start page from chapters if ($chapter !== $page && !in_array($chapter, $start) && $this->accept($chapter)) { $found[] = $chapter; } } switch (count($found)) { case 0: return null; case 1: return $found[0]; default: return $found; } } /** * Searches the root container for forward 'section' relations of the given * $page * * From {@link http://www.w3.org/TR/html4/types.html#type-links}: * Refers to a document serving as a section in a collection of documents. * * @param Zend_Navigation_Page $page page to find relation for * @return Zend_Navigation_Page|array|null page(s) or null */ public function searchRelSection(Zend_Navigation_Page $page) { $found = array(); // check if given page has pages and is a chapter page if ($page->hasPages() && $this->_findRoot($page)->hasPage($page)) { foreach ($page as $section) { if ($this->accept($section)) { $found[] = $section; } } } switch (count($found)) { case 0: return null; case 1: return $found[0]; default: return $found; } } /** * Searches the root container for forward 'subsection' relations of the * given $page * * From {@link http://www.w3.org/TR/html4/types.html#type-links}: * Refers to a document serving as a subsection in a collection of * documents. * * @param Zend_Navigation_Page $page page to find relation for * @return Zend_Navigation_Page|array|null page(s) or null */ public function searchRelSubsection(Zend_Navigation_Page $page) { $found = array(); if ($page->hasPages()) { // given page has child pages, loop chapters foreach ($this->_findRoot($page) as $chapter) { // is page a section? if ($chapter->hasPage($page)) { foreach ($page as $subsection) { if ($this->accept($subsection)) { $found[] = $subsection; } } } } } switch (count($found)) { case 0: return null; case 1: return $found[0]; default: return $found; } } /** * Searches the root container for the reverse 'section' relation of the * given $page * * From {@link http://www.w3.org/TR/html4/types.html#type-links}: * Refers to a document serving as a section in a collection of documents. * * @param Zend_Navigation_Page $page page to find relation for * @return Zend_Navigation_Page|null page(s) or null */ public function searchRevSection(Zend_Navigation_Page $page) { $found = null; if ($parent = $page->getParent()) { if ($parent instanceof Zend_Navigation_Page && $this->_findRoot($page)->hasPage($parent)) { $found = $parent; } } return $found; } /** * Searches the root container for the reverse 'section' relation of the * given $page * * From {@link http://www.w3.org/TR/html4/types.html#type-links}: * Refers to a document serving as a subsection in a collection of * documents. * * @param Zend_Navigation_Page $page page to find relation for * @return Zend_Navigation_Page|null page(s) or null */ public function searchRevSubsection(Zend_Navigation_Page $page) { $found = null; if ($parent = $page->getParent()) { if ($parent instanceof Zend_Navigation_Page) { $root = $this->_findRoot($page); foreach ($root as $chapter) { if ($chapter->hasPage($parent)) { $found = $parent; break; } } } } return $found; } // Util methods: /** * Returns the root container of the given page * * When rendering a container, the render method still store the given * container as the root container, and unset it when done rendering. This * makes sure finder methods will not traverse above the container given * to the render method. * * @param Zend_Navigaiton_Page $page page to find root for * @return Zend_Navigation_Container the root container of the given page */ protected function _findRoot(Zend_Navigation_Page $page) { if ($this->_root) { return $this->_root; } $root = $page; while ($parent = $page->getParent()) { $root = $parent; if ($parent instanceof Zend_Navigation_Page) { $page = $parent; } else { break; } } return $root; } /** * Converts a $mixed value to an array of pages * * @param mixed $mixed mixed value to get page(s) from * @param bool $recursive whether $value should be looped * if it is an array or a config * @return Zend_Navigation_Page|array|null empty if unable to convert */ protected function _convertToPages($mixed, $recursive = true) { if (is_object($mixed)) { if ($mixed instanceof Zend_Navigation_Page) { // value is a page instance; return directly return $mixed; } elseif ($mixed instanceof Zend_Navigation_Container) { // value is a container; return pages in it $pages = array(); foreach ($mixed as $page) { $pages[] = $page; } return $pages; } elseif ($mixed instanceof Zend_Config) { // convert config object to array and extract return $this->_convertToPages($mixed->toArray(), $recursive); } } elseif (is_string($mixed)) { // value is a string; make an URI page return Zend_Navigation_Page::factory(array( 'type' => 'uri', 'uri' => $mixed )); } elseif (is_array($mixed) && !empty($mixed)) { if ($recursive && is_numeric(key($mixed))) { // first key is numeric; assume several pages $pages = array(); foreach ($mixed as $value) { if ($value = $this->_convertToPages($value, false)) { $pages[] = $value; } } return $pages; } else { // pass array to factory directly try { $page = Zend_Navigation_Page::factory($mixed); return $page; } catch (Exception $e) { } } } // nothing found return null; } // Render methods: /** * Renders the given $page as a link element, with $attrib = $relation * * @param Zend_Navigation_Page $page the page to render the link for * @param string $attrib the attribute to use for $type, * either 'rel' or 'rev' * @param string $relation relation type, muse be one of; * alternate, appendix, bookmark, * chapter, contents, copyright, * glossary, help, home, index, next, * prev, section, start, stylesheet, * subsection * @return string rendered link element * @throws Zend_View_Exception if $attrib is invalid */ public function renderLink(Zend_Navigation_Page $page, $attrib, $relation) { if (!in_array($attrib, array('rel', 'rev'))) { //--//require_once 'Zend/View/Exception.php'; $e = new Zend_View_Exception(sprintf( 'Invalid relation attribute "%s", must be "rel" or "rev"', $attrib)); $e->setView($this->view); throw $e; } if (!$href = $page->getHref()) { return ''; } // TODO: add more attribs // http://www.w3.org/TR/html401/struct/links.html#h-12.2 $attribs = array( $attrib => $relation, 'href' => $href, 'title' => $page->getLabel() ); return '_htmlAttribs($attribs) . $this->getClosingBracket(); } // Zend_View_Helper_Navigation_Helper: /** * Renders helper * * Implements {@link Zend_View_Helper_Navigation_Helper::render()}. * * @param Zend_Navigation_Container $container [optional] container to * render. Default is to * render the container * registered in the helper. * @return string helper output */ public function render(Zend_Navigation_Container $container = null) { if (null === $container) { $container = $this->getContainer(); } if ($active = $this->findActive($container)) { $active = $active['page']; } else { // no active page return ''; } $output = ''; $indent = $this->getIndent(); $this->_root = $container; $result = $this->findAllRelations($active, $this->getRenderFlag()); foreach ($result as $attrib => $types) { foreach ($types as $relation => $pages) { foreach ($pages as $page) { if ($r = $this->renderLink($page, $attrib, $relation)) { $output .= $indent . $r . $this->getEOL(); } } } } $this->_root = null; // return output (trim last newline by spec) return strlen($output) ? rtrim($output, self::EOL) : ''; } } Menu.php000064400000114234152101700250006157 0ustar00setContainer($container); } return $this; } // Accessors: /** * Sets CSS class to use for the first 'ul' element when rendering * * @param string $ulClass CSS class to set * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self */ public function setUlClass($ulClass) { if (is_string($ulClass)) { $this->_ulClass = $ulClass; } return $this; } /** * Returns CSS class to use for the first 'ul' element when rendering * * @return string CSS class */ public function getUlClass() { return $this->_ulClass; } /** * Sets unique identifier (id) to use for the first 'ul' element when * rendering * * @param string|null $ulId Unique identifier (id) to set * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self */ public function setUlId($ulId) { if (is_string($ulId)) { $this->_ulId = $ulId; } return $this; } /** * Returns unique identifier (id) to use for the first 'ul' element when * rendering * * @return string|null Unique identifier (id); Default is 'null' */ public function getUlId() { return $this->_ulId; } /** * Sets CSS class to use for the active elements when rendering * * @param string $activeClass CSS class to set * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self */ public function setActiveClass($activeClass) { if (is_string($activeClass)) { $this->_activeClass = $activeClass; } return $this; } /** * Returns CSS class to use for the active elements when rendering * * @return string CSS class */ public function getActiveClass() { return $this->_activeClass; } /** * Sets CSS class to use for the parent li elements when rendering * * @param string $parentClass CSS class to set to parents * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self */ public function setParentClass($parentClass) { if (is_string($parentClass)) { $this->_parentClass = $parentClass; } return $this; } /** * Returns CSS class to use for the parent lie elements when rendering * * @return string CSS class */ public function getParentClass() { return $this->_parentClass; } /** * Enables/disables rendering of parent class to the li element * * @param bool $flag [optional] render with parent * class. Default is true. * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self */ public function setRenderParentClass($flag = true) { $this->_renderParentClass = (bool) $flag; return $this; } /** * Returns flag indicating whether parent class should be rendered to the li * element * * @return bool whether parent class should be rendered */ public function getRenderParentClass() { return $this->_renderParentClass; } /** * Sets a flag indicating whether only active branch should be rendered * * @param bool $flag [optional] render only active * branch. Default is true. * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self */ public function setOnlyActiveBranch($flag = true) { $this->_onlyActiveBranch = (bool) $flag; return $this; } /** * Returns a flag indicating whether only active branch should be rendered * * By default, this value is false, meaning the entire menu will be * be rendered. * * @return bool whether only active branch should be rendered */ public function getOnlyActiveBranch() { return $this->_onlyActiveBranch; } /** * Sets a flag indicating whether to expand all sibling nodes of the active branch * * @param bool $flag [optional] expand all siblings of * nodes in the active branch. Default is true. * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self */ public function setExpandSiblingNodesOfActiveBranch($flag = true) { $this->_expandSiblingNodesOfActiveBranch = (bool) $flag; return $this; } /** * Returns a flag indicating whether to expand all sibling nodes of the active branch * * By default, this value is false, meaning the entire menu will be * be rendered. * * @return bool whether siblings of nodes in the active branch should be expanded */ public function getExpandSiblingNodesOfActiveBranch() { return $this->_expandSiblingNodesOfActiveBranch; } /** * Enables/disables rendering of parents when only rendering active branch * * See {@link setOnlyActiveBranch()} for more information. * * @param bool $flag [optional] render parents when * rendering active branch. * Default is true. * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self */ public function setRenderParents($flag = true) { $this->_renderParents = (bool) $flag; return $this; } /** * Returns flag indicating whether parents should be rendered when rendering * only the active branch * * By default, this value is true. * * @return bool whether parents should be rendered */ public function getRenderParents() { return $this->_renderParents; } /** * Sets which partial view script to use for rendering menu * * @param string|array $partial partial view script or null. If * an array is given, it is * expected to contain two values; * the partial view script to use, * and the module where the script * can be found. * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self */ public function setPartial($partial) { if (null === $partial || is_string($partial) || is_array($partial)) { $this->_partial = $partial; } return $this; } /** * Returns partial view script to use for rendering menu * * @return string|array|null */ public function getPartial() { return $this->_partial; } /** * Adds CSS class from page to li element * * Before: * *
  • * Bar *
  • *
    * * After: * *
  • * Bar *
  • *
    * * @param bool $flag [optional] adds CSS class from * page to li element * * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self */ public function addPageClassToLi($flag = true) { $this->_addPageClassToLi = (bool) $flag; return $this; } /** * Returns a flag indicating whether the CSS class from page to be added to * li element * * @return bool */ public function getAddPageClassToLi() { return $this->_addPageClassToLi; } /** * Set the inner indentation string for using in {@link render()}, optionally * a number of spaces to indent with * * @param string|int $indent indentation string or * number of spaces * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, * returns self */ public function setInnerIndent($indent) { $this->_innerIndent = $this->_getWhitespace($indent); return $this; } /** * Returns inner indentation (format output is respected) * * @see getFormatOutput() * * @return string indentation string or an empty string */ public function getInnerIndent() { if (false === $this->getFormatOutput()) { return ''; } return $this->_innerIndent; } // Public methods: /** * Returns an HTML string containing an 'a' element for the given page if * the page's href is not empty, and a 'span' element if it is empty * * Overrides {@link Zend_View_Helper_Navigation_Abstract::htmlify()}. * * @param Zend_Navigation_Page $page page to generate HTML for * @return string HTML string for the given page */ public function htmlify(Zend_Navigation_Page $page) { // get label and title for translating $label = $page->getLabel(); $title = $page->getTitle(); // translate label and title? if ($this->getUseTranslator() && $t = $this->getTranslator()) { if (is_string($label) && !empty($label)) { $label = $t->translate($label); } if (is_string($title) && !empty($title)) { $title = $t->translate($title); } } // get attribs for element $attribs = array( 'id' => $page->getId(), 'title' => $title, ); if (false === $this->getAddPageClassToLi()) { $attribs['class'] = $page->getClass(); } // does page have a href? if ($href = $page->getHref()) { $element = 'a'; $attribs['href'] = $href; $attribs['target'] = $page->getTarget(); $attribs['accesskey'] = $page->getAccessKey(); } else { $element = 'span'; } // Add custom HTML attributes $attribs = array_merge($attribs, $page->getCustomHtmlAttribs()); return '<' . $element . $this->_htmlAttribs($attribs) . '>' . $this->view->escape($label) . ''; } /** * Normalizes given render options * * @param array $options [optional] options to normalize * @return array normalized options */ protected function _normalizeOptions(array $options = array()) { // Ident if (isset($options['indent'])) { $options['indent'] = $this->_getWhitespace($options['indent']); } else { $options['indent'] = $this->getIndent(); } // Inner ident if (isset($options['innerIndent'])) { $options['innerIndent'] = $this->_getWhitespace($options['innerIndent']); } else { $options['innerIndent'] = $this->getInnerIndent(); } // UL class if (isset($options['ulClass']) && $options['ulClass'] !== null) { $options['ulClass'] = (string) $options['ulClass']; } else { $options['ulClass'] = $this->getUlClass(); } // UL id if (isset($options['ulId']) && $options['ulId'] !== null) { $options['ulId'] = (string) $options['ulId']; } else { $options['ulId'] = $this->getUlId(); } // Active class if (isset($options['activeClass']) && $options['activeClass'] !== null ) { $options['activeClass'] = (string) $options['activeClass']; } else { $options['activeClass'] = $this->getActiveClass(); } // Parent class if (isset($options['parentClass']) && $options['parentClass'] !== null) { $options['parentClass'] = (string) $options['parentClass']; } else { $options['parentClass'] = $this->getParentClass(); } // Minimum depth if (array_key_exists('minDepth', $options)) { if (null !== $options['minDepth']) { $options['minDepth'] = (int) $options['minDepth']; } } else { $options['minDepth'] = $this->getMinDepth(); } if ($options['minDepth'] < 0 || $options['minDepth'] === null) { $options['minDepth'] = 0; } // Maximum depth if (array_key_exists('maxDepth', $options)) { if (null !== $options['maxDepth']) { $options['maxDepth'] = (int) $options['maxDepth']; } } else { $options['maxDepth'] = $this->getMaxDepth(); } // Only active branch if (!isset($options['onlyActiveBranch'])) { $options['onlyActiveBranch'] = $this->getOnlyActiveBranch(); } // Expand sibling nodes of active branch if (!isset($options['expandSiblingNodesOfActiveBranch'])) { $options['expandSiblingNodesOfActiveBranch'] = $this->getExpandSiblingNodesOfActiveBranch(); } // Render parents? if (!isset($options['renderParents'])) { $options['renderParents'] = $this->getRenderParents(); } // Render parent class? if (!isset($options['renderParentClass'])) { $options['renderParentClass'] = $this->getRenderParentClass(); } // Add page CSS class to LI element if (!isset($options['addPageClassToLi'])) { $options['addPageClassToLi'] = $this->getAddPageClassToLi(); } return $options; } // Render methods: /** * Renders the deepest active menu within [$minDepth, $maxDeth], (called * from {@link renderMenu()}) * * @param Zend_Navigation_Container $container container to render * @param string $ulClass CSS class for first UL * @param string $indent initial indentation * @param string $innerIndent inner indentation * @param int|null $minDepth minimum depth * @param int|null $maxDepth maximum depth * @param string|null $ulId unique identifier (id) * for first UL * @param bool $addPageClassToLi adds CSS class from * page to li element * @param string|null $activeClass CSS class for active * element * @param string $parentClass CSS class for parent * li's * @param bool $renderParentClass Render parent class? * @return string rendered menu (HTML) */ protected function _renderDeepestMenu(Zend_Navigation_Container $container, $ulClass, $indent, $innerIndent, $minDepth, $maxDepth, $ulId, $addPageClassToLi, $activeClass, $parentClass, $renderParentClass) { if (!$active = $this->findActive($container, $minDepth - 1, $maxDepth)) { return ''; } // special case if active page is one below minDepth if ($active['depth'] < $minDepth) { if (!$active['page']->hasPages()) { return ''; } } else if (!$active['page']->hasPages()) { // found pages has no children; render siblings $active['page'] = $active['page']->getParent(); } else if (is_int($maxDepth) && $active['depth'] + 1 > $maxDepth) { // children are below max depth; render siblings $active['page'] = $active['page']->getParent(); } $attribs = array( 'class' => $ulClass, 'id' => $ulId, ); // We don't need a prefix for the menu ID (backup) $skipValue = $this->_skipPrefixForId; $this->skipPrefixForId(); $html = $indent . '_htmlAttribs($attribs) . '>' . $this->getEOL(); // Reset prefix for IDs $this->_skipPrefixForId = $skipValue; foreach ($active['page'] as $subPage) { if (!$this->accept($subPage)) { continue; } $liClass = ''; if ($subPage->isActive(true) && $addPageClassToLi) { $liClass = $this->_htmlAttribs( array('class' => $activeClass . ' ' . $subPage->getClass()) ); } else if ($subPage->isActive(true)) { $liClass = $this->_htmlAttribs(array('class' => $activeClass)); } else if ($addPageClassToLi) { $liClass = $this->_htmlAttribs( array('class' => $subPage->getClass()) ); } $html .= $indent . $innerIndent . '' . $this->getEOL(); $html .= $indent . str_repeat($innerIndent, 2) . $this->htmlify($subPage) . $this->getEOL(); $html .= $indent . $innerIndent . '' . $this->getEOL(); } $html .= $indent . ''; return $html; } /** * Renders a normal menu (called from {@link renderMenu()}) * * @param Zend_Navigation_Container $container container to render * @param string $ulClass CSS class for first UL * @param string $indent initial indentation * @param string $innerIndent inner indentation * @param int|null $minDepth minimum depth * @param int|null $maxDepth maximum depth * @param bool $onlyActive render only active branch? * @param bool $expandSibs render siblings of active * branch nodes? * @param string|null $ulId unique identifier (id) * for first UL * @param bool $addPageClassToLi adds CSS class from * page to li element * @param string|null $activeClass CSS class for active * element * @param string $parentClass CSS class for parent * li's * @param bool $renderParentClass Render parent class? * @return string rendered menu (HTML) */ protected function _renderMenu(Zend_Navigation_Container $container, $ulClass, $indent, $innerIndent, $minDepth, $maxDepth, $onlyActive, $expandSibs, $ulId, $addPageClassToLi, $activeClass, $parentClass, $renderParentClass) { $html = ''; // find deepest active if ($found = $this->findActive($container, $minDepth, $maxDepth)) { $foundPage = $found['page']; $foundDepth = $found['depth']; } else { $foundPage = null; } // create iterator $iterator = new RecursiveIteratorIterator($container, RecursiveIteratorIterator::SELF_FIRST); if (is_int($maxDepth)) { $iterator->setMaxDepth($maxDepth); } // iterate container $prevDepth = -1; foreach ($iterator as $page) { $depth = $iterator->getDepth(); $isActive = $page->isActive(true); if ($depth < $minDepth || !$this->accept($page)) { // page is below minDepth or not accepted by acl/visibilty continue; } else if ($expandSibs && $depth > $minDepth) { // page is not active itself, but might be in the active branch $accept = false; if ($foundPage) { if ($foundPage->hasPage($page)) { // accept if page is a direct child of the active page $accept = true; } else if ($page->getParent()->isActive(true)) { // page is a sibling of the active branch... $accept = true; } } if (!$isActive && !$accept) { continue; } } else if ($onlyActive && !$isActive) { // page is not active itself, but might be in the active branch $accept = false; if ($foundPage) { if ($foundPage->hasPage($page)) { // accept if page is a direct child of the active page $accept = true; } else if ($foundPage->getParent()->hasPage($page)) { // page is a sibling of the active page... if (!$foundPage->hasPages() || is_int($maxDepth) && $foundDepth + 1 > $maxDepth) { // accept if active page has no children, or the // children are too deep to be rendered $accept = true; } } } if (!$accept) { continue; } } // make sure indentation is correct $depth -= $minDepth; $myIndent = $indent . str_repeat($innerIndent, $depth * 2); if ($depth > $prevDepth) { $attribs = array(); // start new ul tag if (0 == $depth) { $attribs = array( 'class' => $ulClass, 'id' => $ulId, ); } // We don't need a prefix for the menu ID (backup) $skipValue = $this->_skipPrefixForId; $this->skipPrefixForId(); $html .= $myIndent . '_htmlAttribs($attribs) . '>' . $this->getEOL(); // Reset prefix for IDs $this->_skipPrefixForId = $skipValue; } else if ($prevDepth > $depth) { // close li/ul tags until we're at current depth for ($i = $prevDepth; $i > $depth; $i--) { $ind = $indent . str_repeat($innerIndent, $i * 2); $html .= $ind . $innerIndent . '' . $this->getEOL(); $html .= $ind . '' . $this->getEOL(); } // close previous li tag $html .= $myIndent . $innerIndent . '' . $this->getEOL(); } else { // close previous li tag $html .= $myIndent . $innerIndent . '' . $this->getEOL(); } // render li tag and page $liClasses = array(); // Is page active? if ($isActive) { $liClasses[] = $activeClass; } // Add CSS class from page to LI? if ($addPageClassToLi) { $liClasses[] = $page->getClass(); } // Add CSS class for parents to LI? if ($renderParentClass && $page->hasChildren()) { // Check max depth if ((is_int($maxDepth) && ($depth + 1 < $maxDepth)) || !is_int($maxDepth) ) { $liClasses[] = $parentClass; } } $html .= $myIndent . $innerIndent . '_htmlAttribs(array('class' => implode(' ', $liClasses))) . '>' . $this->getEOL() . $myIndent . str_repeat($innerIndent, 2) . $this->htmlify($page) . $this->getEOL(); // store as previous depth for next iteration $prevDepth = $depth; } if ($html) { // done iterating container; close open ul/li tags for ($i = $prevDepth+1; $i > 0; $i--) { $myIndent = $indent . str_repeat($innerIndent . $innerIndent, $i - 1); $html .= $myIndent . $innerIndent . '' . $this->getEOL() . $myIndent . '' . $this->getEOL(); } $html = rtrim($html, $this->getEOL()); } return $html; } /** * Renders helper * * Renders a HTML 'ul' for the given $container. If $container is not given, * the container registered in the helper will be used. * * Available $options: * * * @param Zend_Navigation_Container $container [optional] container to * create menu from. Default * is to use the container * retrieved from * {@link getContainer()}. * @param array $options [optional] options for * controlling rendering * @return string rendered menu */ public function renderMenu(Zend_Navigation_Container $container = null, array $options = array()) { if (null === $container) { $container = $this->getContainer(); } $options = $this->_normalizeOptions($options); if ($options['onlyActiveBranch'] && !$options['renderParents']) { $html = $this->_renderDeepestMenu( $container, $options['ulClass'], $options['indent'], $options['innerIndent'], $options['minDepth'], $options['maxDepth'], $options['ulId'], $options['addPageClassToLi'], $options['activeClass'], $options['parentClass'], $options['renderParentClass'] ); } else { $html = $this->_renderMenu( $container, $options['ulClass'], $options['indent'], $options['innerIndent'], $options['minDepth'], $options['maxDepth'], $options['onlyActiveBranch'], $options['expandSiblingNodesOfActiveBranch'], $options['ulId'], $options['addPageClassToLi'], $options['activeClass'], $options['parentClass'], $options['renderParentClass'] ); } return $html; } /** * Renders the inner-most sub menu for the active page in the $container * * This is a convenience method which is equivalent to the following call: * * renderMenu($container, array( * 'indent' => $indent, * 'ulClass' => $ulClass, * 'minDepth' => null, * 'maxDepth' => null, * 'onlyActiveBranch' => true, * 'renderParents' => false * )); * * * @param Zend_Navigation_Container $container [optional] container to * render. Default is to render * the container registered in * the helper. * @param string|null $ulClass [optional] CSS class to * use for UL element. Default * is to use the value from * {@link getUlClass()}. * @param string|int $indent [optional] indentation as * a string or number of * spaces. Default is to use * the value retrieved from * {@link getIndent()}. * @param string|null $ulId [optional] Unique identifier * (id) use for UL element * @param bool $addPageClassToLi adds CSS class from * page to li element * @param string|int $innerIndent [optional] inner * indentation as a string * or number of spaces. * Default is to use the * {@link getInnerIndent()}. * @return string rendered content */ public function renderSubMenu(Zend_Navigation_Container $container = null, $ulClass = null, $indent = null, $ulId = null, $addPageClassToLi = false, $innerIndent = null) { return $this->renderMenu($container, array( 'indent' => $indent, 'innerIndent' => $innerIndent, 'ulClass' => $ulClass, 'minDepth' => null, 'maxDepth' => null, 'onlyActiveBranch' => true, 'renderParents' => false, 'ulId' => $ulId, 'addPageClassToLi' => $addPageClassToLi, )); } /** * Renders the given $container by invoking the partial view helper * * The container will simply be passed on as a model to the view script * as-is, and will be available in the partial script as 'container', e.g. * echo 'Number of pages: ', count($this->container);. * * @param Zend_Navigation_Container $container [optional] container to * pass to view script. Default * is to use the container * registered in the helper. * @param string|array $partial [optional] partial view * script to use. Default is to * use the partial registered * in the helper. If an array * is given, it is expected to * contain two values; the * partial view script to use, * and the module where the * script can be found. * @return string helper output * * @throws Zend_View_Exception When no partial script is set */ public function renderPartial(Zend_Navigation_Container $container = null, $partial = null) { if (null === $container) { $container = $this->getContainer(); } if (null === $partial) { $partial = $this->getPartial(); } if (empty($partial)) { //--//require_once 'Zend/View/Exception.php'; $e = new Zend_View_Exception( 'Unable to render menu: No partial view script provided' ); $e->setView($this->view); throw $e; } $model = array( 'container' => $container ); if (is_array($partial)) { if (count($partial) != 2) { //--//require_once 'Zend/View/Exception.php'; $e = new Zend_View_Exception( 'Unable to render menu: A view partial supplied as ' . 'an array must contain two values: partial view ' . 'script and module where script can be found' ); $e->setView($this->view); throw $e; } return $this->view->partial($partial[0], $partial[1], $model); } return $this->view->partial($partial, null, $model); } // Zend_View_Helper_Navigation_Helper: /** * Renders menu * * Implements {@link Zend_View_Helper_Navigation_Helper::render()}. * * If a partial view is registered in the helper, the menu will be rendered * using the given partial script. If no partial is registered, the menu * will be rendered as an 'ul' element by the helper's internal method. * * @see renderPartial() * @see renderMenu() * * @param Zend_Navigation_Container $container [optional] container to * render. Default is to * render the container * registered in the helper. * @return string helper output */ public function render(Zend_Navigation_Container $container = null) { if ($partial = $this->getPartial()) { return $this->renderPartial($container, $partial); } else { return $this->renderMenu($container); } } } HelperAbstract.php000064400000074431152101700250010162 0ustar00_container = $container; return $this; } /** * Returns the navigation container helper operates on by default * * Implements {@link Zend_View_Helper_Navigation_Interface::getContainer()}. * * If a helper is not explicitly set in this helper instance by calling * {@link setContainer()} or by passing it through the helper entry point, * this method will look in {@link Zend_Registry} for a container by using * the key 'Zend_Navigation'. * * If no container is set, and nothing is found in Zend_Registry, a new * container will be instantiated and stored in the helper. * * @return Zend_Navigation_Container navigation container */ public function getContainer() { if (null === $this->_container) { // try to fetch from registry first //--//require_once 'Zend/Registry.php'; if (Zend_Registry::isRegistered('Zend_Navigation')) { $nav = Zend_Registry::get('Zend_Navigation'); if ($nav instanceof Zend_Navigation_Container) { return $this->_container = $nav; } } // nothing found in registry, create new container //--//require_once 'Zend/Navigation.php'; $this->_container = new Zend_Navigation(); } return $this->_container; } /** * Sets the minimum depth a page must have to be included when rendering * * @param int $minDepth [optional] minimum * depth. Default is * null, which sets * no minimum depth. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, * returns self */ public function setMinDepth($minDepth = null) { if (null === $minDepth || is_int($minDepth)) { $this->_minDepth = $minDepth; } else { $this->_minDepth = (int) $minDepth; } return $this; } /** * Returns minimum depth a page must have to be included when rendering * * @return int|null minimum depth or null */ public function getMinDepth() { if (!is_int($this->_minDepth) || $this->_minDepth < 0) { return 0; } return $this->_minDepth; } /** * Sets the maximum depth a page can have to be included when rendering * * @param int $maxDepth [optional] maximum * depth. Default is * null, which sets no * maximum depth. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, * returns self */ public function setMaxDepth($maxDepth = null) { if (null === $maxDepth || is_int($maxDepth)) { $this->_maxDepth = $maxDepth; } else { $this->_maxDepth = (int) $maxDepth; } return $this; } /** * Returns maximum depth a page can have to be included when rendering * * @return int|null maximum depth or null */ public function getMaxDepth() { return $this->_maxDepth; } /** * Set the indentation string for using in {@link render()}, optionally a * number of spaces to indent with * * @param string|int $indent indentation string or * number of spaces * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, * returns self */ public function setIndent($indent) { $this->_indent = $this->_getWhitespace($indent); return $this; } /** * Returns indentation (format output is respected) * * @return string indentation string or an empty string */ public function getIndent() { if (false === $this->getFormatOutput()) { return ''; } return $this->_indent; } /** * Returns the EOL character (format output is respected) * * @see self::EOL * @see getFormatOutput() * * @return string standard EOL charater or an empty string */ public function getEOL() { if (false === $this->getFormatOutput()) { return ''; } return self::EOL; } /** * Sets whether HTML/XML output should be formatted * * @param bool $formatOutput [optional] whether output * should be formatted. Default * is true. * * @return Zend_View_Helper_Navigation_Sitemap fluent interface, returns * self */ public function setFormatOutput($formatOutput = true) { $this->_formatOutput = (bool)$formatOutput; return $this; } /** * Returns whether HTML/XML output should be formatted * * @return bool whether HTML/XML output should be formatted */ public function getFormatOutput() { return $this->_formatOutput; } /** * Sets prefix for IDs when they are normalized * * @param string $prefix Prefix for IDs * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, returns self */ public function setPrefixForId($prefix) { if (is_string($prefix)) { $this->_prefixForId = trim($prefix); } return $this; } /** * Returns prefix for IDs when they are normalized * * @return string Prefix for */ public function getPrefixForId() { if (null === $this->_prefixForId) { $prefix = get_class($this); $this->_prefixForId = strtolower( trim(substr($prefix, strrpos($prefix, '_')), '_') ) . '-'; } return $this->_prefixForId; } /** * Skip the current prefix for IDs when they are normalized * * @param bool $flag * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, returns self */ public function skipPrefixForId($flag = true) { $this->_skipPrefixForId = (bool) $flag; return $this; } /** * Sets translator to use in helper * * Implements {@link Zend_View_Helper_Navigation_Helper::setTranslator()}. * * @param mixed $translator [optional] translator. * Expects an object of * type * {@link Zend_Translate_Adapter} * or {@link Zend_Translate}, * or null. Default is * null, which sets no * translator. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, * returns self */ public function setTranslator($translator = null) { if (null == $translator || $translator instanceof Zend_Translate_Adapter) { $this->_translator = $translator; } elseif ($translator instanceof Zend_Translate) { $this->_translator = $translator->getAdapter(); } return $this; } /** * Returns translator used in helper * * Implements {@link Zend_View_Helper_Navigation_Helper::getTranslator()}. * * @return Zend_Translate_Adapter|null translator or null */ public function getTranslator() { if (null === $this->_translator) { //--//require_once 'Zend/Registry.php'; if (Zend_Registry::isRegistered('Zend_Translate')) { $this->setTranslator(Zend_Registry::get('Zend_Translate')); } } return $this->_translator; } /** * Sets ACL to use when iterating pages * * Implements {@link Zend_View_Helper_Navigation_Helper::setAcl()}. * * @param Zend_Acl $acl [optional] ACL object. * Default is null. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, * returns self */ public function setAcl(Zend_Acl $acl = null) { $this->_acl = $acl; return $this; } /** * Returns ACL or null if it isn't set using {@link setAcl()} or * {@link setDefaultAcl()} * * Implements {@link Zend_View_Helper_Navigation_Helper::getAcl()}. * * @return Zend_Acl|null ACL object or null */ public function getAcl() { if ($this->_acl === null && self::$_defaultAcl !== null) { return self::$_defaultAcl; } return $this->_acl; } /** * Sets ACL role(s) to use when iterating pages * * Implements {@link Zend_View_Helper_Navigation_Helper::setRole()}. * * @param mixed $role [optional] role to * set. Expects a string, * an instance of type * {@link Zend_Acl_Role_Interface}, * or null. Default is * null, which will set * no role. * @throws Zend_View_Exception if $role is invalid * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, * returns self */ public function setRole($role = null) { if (null === $role || is_string($role) || $role instanceof Zend_Acl_Role_Interface) { $this->_role = $role; } else { //--//require_once 'Zend/View/Exception.php'; $e = new Zend_View_Exception(sprintf( '$role must be a string, null, or an instance of ' . 'Zend_Acl_Role_Interface; %s given', gettype($role) )); $e->setView($this->view); throw $e; } return $this; } /** * Returns ACL role to use when iterating pages, or null if it isn't set * using {@link setRole()} or {@link setDefaultRole()} * * Implements {@link Zend_View_Helper_Navigation_Helper::getRole()}. * * @return string|Zend_Acl_Role_Interface|null role or null */ public function getRole() { if ($this->_role === null && self::$_defaultRole !== null) { return self::$_defaultRole; } return $this->_role; } /** * Sets whether ACL should be used * * Implements {@link Zend_View_Helper_Navigation_Helper::setUseAcl()}. * * @param bool $useAcl [optional] whether ACL * should be used. * Default is true. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, * returns self */ public function setUseAcl($useAcl = true) { $this->_useAcl = (bool) $useAcl; return $this; } /** * Returns whether ACL should be used * * Implements {@link Zend_View_Helper_Navigation_Helper::getUseAcl()}. * * @return bool whether ACL should be used */ public function getUseAcl() { return $this->_useAcl; } /** * Return renderInvisible flag * * @return bool */ public function getRenderInvisible() { return $this->_renderInvisible; } /** * Render invisible items? * * @param bool $renderInvisible [optional] boolean flag * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface * returns self */ public function setRenderInvisible($renderInvisible = true) { $this->_renderInvisible = (bool) $renderInvisible; return $this; } /** * Sets whether translator should be used * * Implements {@link Zend_View_Helper_Navigation_Helper::setUseTranslator()}. * * @param bool $useTranslator [optional] whether * translator should be * used. Default is true. * @return Zend_View_Helper_Navigation_HelperAbstract fluent interface, * returns self */ public function setUseTranslator($useTranslator = true) { $this->_useTranslator = (bool) $useTranslator; return $this; } /** * Returns whether translator should be used * * Implements {@link Zend_View_Helper_Navigation_Helper::getUseTranslator()}. * * @return bool whether translator should be used */ public function getUseTranslator() { return $this->_useTranslator; } // Magic overloads: /** * Magic overload: Proxy calls to the navigation container * * @param string $method method name in container * @param array $arguments [optional] arguments to pass * @return mixed returns what the container returns * @throws Zend_Navigation_Exception if method does not exist in container */ public function __call($method, array $arguments = array()) { return call_user_func_array( array($this->getContainer(), $method), $arguments); } /** * Magic overload: Proxy to {@link render()}. * * This method will trigger an E_USER_ERROR if rendering the helper causes * an exception to be thrown. * * Implements {@link Zend_View_Helper_Navigation_Helper::__toString()}. * * @return string */ public function __toString() { try { return $this->render(); } catch (Exception $e) { $msg = get_class($e) . ': ' . $e->getMessage(); trigger_error($msg, E_USER_ERROR); return ''; } } // Public methods: /** * Finds the deepest active page in the given container * * @param Zend_Navigation_Container $container container to search * @param int|null $minDepth [optional] minimum depth * required for page to be * valid. Default is to use * {@link getMinDepth()}. A * null value means no minimum * depth required. * @param int|null $minDepth [optional] maximum depth * a page can have to be * valid. Default is to use * {@link getMaxDepth()}. A * null value means no maximum * depth required. * @return array an associative array with * the values 'depth' and * 'page', or an empty array * if not found */ public function findActive(Zend_Navigation_Container $container, $minDepth = null, $maxDepth = -1) { if (!is_int($minDepth)) { $minDepth = $this->getMinDepth(); } if ((!is_int($maxDepth) || $maxDepth < 0) && null !== $maxDepth) { $maxDepth = $this->getMaxDepth(); } $found = null; $foundDepth = -1; $iterator = new RecursiveIteratorIterator($container, RecursiveIteratorIterator::CHILD_FIRST); foreach ($iterator as $page) { $currDepth = $iterator->getDepth(); if ($currDepth < $minDepth || !$this->accept($page)) { // page is not accepted continue; } if ($page->isActive(false) && $currDepth > $foundDepth) { // found an active page at a deeper level than before $found = $page; $foundDepth = $currDepth; } } if (is_int($maxDepth) && $foundDepth > $maxDepth) { while ($foundDepth > $maxDepth) { if (--$foundDepth < $minDepth) { $found = null; break; } $found = $found->getParent(); if (!$found instanceof Zend_Navigation_Page) { $found = null; break; } } } if ($found) { return array('page' => $found, 'depth' => $foundDepth); } else { return array(); } } /** * Checks if the helper has a container * * Implements {@link Zend_View_Helper_Navigation_Helper::hasContainer()}. * * @return bool whether the helper has a container or not */ public function hasContainer() { return null !== $this->_container; } /** * Checks if the helper has an ACL instance * * Implements {@link Zend_View_Helper_Navigation_Helper::hasAcl()}. * * @return bool whether the helper has a an ACL instance or not */ public function hasAcl() { return null !== $this->_acl; } /** * Checks if the helper has an ACL role * * Implements {@link Zend_View_Helper_Navigation_Helper::hasRole()}. * * @return bool whether the helper has a an ACL role or not */ public function hasRole() { return null !== $this->_role; } /** * Checks if the helper has a translator * * Implements {@link Zend_View_Helper_Navigation_Helper::hasTranslator()}. * * @return bool whether the helper has a translator or not */ public function hasTranslator() { return null !== $this->_translator; } /** * Returns an HTML string containing an 'a' element for the given page * * @param Zend_Navigation_Page $page page to generate HTML for * @return string HTML string for the given page */ public function htmlify(Zend_Navigation_Page $page) { // get label and title for translating $label = $page->getLabel(); $title = $page->getTitle(); if ($this->getUseTranslator() && $t = $this->getTranslator()) { if (is_string($label) && !empty($label)) { $label = $t->translate($label); } if (is_string($title) && !empty($title)) { $title = $t->translate($title); } } // get attribs for anchor element $attribs = array_merge( array( 'id' => $page->getId(), 'title' => $title, 'class' => $page->getClass(), 'href' => $page->getHref(), 'target' => $page->getTarget() ), $page->getCustomHtmlAttribs() ); return '_htmlAttribs($attribs) . '>' . $this->view->escape($label) . ''; } // Iterator filter methods: /** * Determines whether a page should be accepted when iterating * * Rules: * - If a page is not visible it is not accepted, unless RenderInvisible has * been set to true. * - If helper has no ACL, page is accepted * - If helper has ACL, but no role, page is not accepted * - If helper has ACL and role: * - Page is accepted if it has no resource or privilege * - Page is accepted if ACL allows page's resource or privilege * - If page is accepted by the rules above and $recursive is true, the page * will not be accepted if it is the descendant of a non-accepted page. * * @param Zend_Navigation_Page $page page to check * @param bool $recursive [optional] if true, page will not * be accepted if it is the * descendant of a page that is not * accepted. Default is true. * @return bool whether page should be accepted */ public function accept(Zend_Navigation_Page $page, $recursive = true) { // accept by default $accept = true; if (!$page->isVisible(false) && !$this->getRenderInvisible()) { // don't accept invisible pages $accept = false; } elseif ($this->getUseAcl() && !$this->_acceptAcl($page)) { // acl is not amused $accept = false; } if ($accept && $recursive) { $parent = $page->getParent(); if ($parent instanceof Zend_Navigation_Page) { $accept = $this->accept($parent, true); } } return $accept; } /** * Determines whether a page should be accepted by ACL when iterating * * Rules: * - If helper has no ACL, page is accepted * - If page has a resource or privilege defined, page is accepted * if the ACL allows access to it using the helper's role * - If page has no resource or privilege, page is accepted * * @param Zend_Navigation_Page $page page to check * @return bool whether page is accepted by ACL */ protected function _acceptAcl(Zend_Navigation_Page $page) { if (!$acl = $this->getAcl()) { // no acl registered means don't use acl return true; } $role = $this->getRole(); $resource = $page->getResource(); $privilege = $page->getPrivilege(); if ($resource || $privilege) { // determine using helper role and page resource/privilege return $acl->isAllowed($role, $resource, $privilege); } return true; } // Util methods: /** * Retrieve whitespace representation of $indent * * @param int|string $indent * @return string */ protected function _getWhitespace($indent) { if (is_int($indent)) { $indent = str_repeat(' ', $indent); } return (string) $indent; } /** * Converts an associative array to a string of tag attributes. * * Overloads {@link Zend_View_Helper_HtmlElement::_htmlAttribs()}. * * @param array $attribs an array where each key-value pair is converted * to an attribute name and value * @return string an attribute string */ protected function _htmlAttribs($attribs) { // filter out null values and empty string values foreach ($attribs as $key => $value) { if ($value === null || (is_string($value) && !strlen($value))) { unset($attribs[$key]); } } return parent::_htmlAttribs($attribs); } /** * Normalize an ID * * Extends {@link Zend_View_Helper_HtmlElement::_normalizeId()}. * * @param string $value ID * @return string Normalized ID */ protected function _normalizeId($value) { if (false === $this->_skipPrefixForId) { $prefix = $this->getPrefixForId(); if (strlen($prefix)) { return $prefix . $value; } } return parent::_normalizeId($value); } // Static methods: /** * Sets default ACL to use if another ACL is not explicitly set * * @param Zend_Acl $acl [optional] ACL object. Default is null, which * sets no ACL object. * @return void */ public static function setDefaultAcl(Zend_Acl $acl = null) { self::$_defaultAcl = $acl; } /** * Sets default ACL role(s) to use when iterating pages if not explicitly * set later with {@link setRole()} * * @param midex $role [optional] role to set. Expects null, * string, or an instance of * {@link Zend_Acl_Role_Interface}. * Default is null, which sets no default * role. * @throws Zend_View_Exception if role is invalid * @return void */ public static function setDefaultRole($role = null) { if (null === $role || is_string($role) || $role instanceof Zend_Acl_Role_Interface) { self::$_defaultRole = $role; } else { //--//require_once 'Zend/View/Exception.php'; throw new Zend_View_Exception( '$role must be null|string|Zend_Acl_Role_Interface' ); } } } Helper.php000064400000016356152101700250006500 0ustar00setContainer($container); } return $this; } // Accessors: /** * Sets breadcrumb separator * * @param string $separator separator string * @return Zend_View_Helper_Navigation_Breadcrumbs fluent interface, * returns self */ public function setSeparator($separator) { if (is_string($separator)) { $this->_separator = $separator; } return $this; } /** * Returns breadcrumb separator * * @return string breadcrumb separator */ public function getSeparator() { return $this->_separator; } /** * Sets whether last page in breadcrumbs should be hyperlinked * * @param bool $linkLast whether last page should * be hyperlinked * @return Zend_View_Helper_Navigation_Breadcrumbs fluent interface, * returns self */ public function setLinkLast($linkLast) { $this->_linkLast = (bool) $linkLast; return $this; } /** * Returns whether last page in breadcrumbs should be hyperlinked * * @return bool whether last page in breadcrumbs should be hyperlinked */ public function getLinkLast() { return $this->_linkLast; } /** * Sets which partial view script to use for rendering menu * * @param string|array $partial partial view script or * null. If an array is * given, it is expected to * contain two values; * the partial view script * to use, and the module * where the script can be * found. * @return Zend_View_Helper_Navigation_Breadcrumbs fluent interface, * returns self */ public function setPartial($partial) { if (null === $partial || is_string($partial) || is_array($partial)) { $this->_partial = $partial; } return $this; } /** * Returns partial view script to use for rendering menu * * @return string|array|null */ public function getPartial() { return $this->_partial; } // Render methods: /** * Renders breadcrumbs by chaining 'a' elements with the separator * registered in the helper * * @param Zend_Navigation_Container $container [optional] container to * render. Default is to * render the container * registered in the helper. * @return string helper output */ public function renderStraight(Zend_Navigation_Container $container = null) { if (null === $container) { $container = $this->getContainer(); } // find deepest active if (!$active = $this->findActive($container)) { return ''; } $active = $active['page']; // put the deepest active page last in breadcrumbs if ($this->getLinkLast()) { $html = $this->htmlify($active); } else { $html = $active->getLabel(); if ($this->getUseTranslator() && $t = $this->getTranslator()) { $html = $t->translate($html); } $html = $this->view->escape($html); } // walk back to root while ($parent = $active->getParent()) { if ($parent instanceof Zend_Navigation_Page) { // prepend crumb to html $html = $this->htmlify($parent) . $this->getSeparator() . $html; } if ($parent === $container) { // at the root of the given container break; } $active = $parent; } return strlen($html) ? $this->getIndent() . $html : ''; } /** * Renders the given $container by invoking the partial view helper * * The container will simply be passed on as a model to the view script, * so in the script it will be available in $this->container. * * @param Zend_Navigation_Container $container [optional] container to * pass to view script. * Default is to use the * container registered in the * helper. * @param string|array $partial [optional] partial view * script to use. Default is * to use the partial * registered in the helper. * If an array is given, it is * expected to contain two * values; the partial view * script to use, and the * module where the script can * be found. * @return string helper output */ public function renderPartial(Zend_Navigation_Container $container = null, $partial = null) { if (null === $container) { $container = $this->getContainer(); } if (null === $partial) { $partial = $this->getPartial(); } if (empty($partial)) { //--//require_once 'Zend/View/Exception.php'; $e = new Zend_View_Exception( 'Unable to render menu: No partial view script provided' ); $e->setView($this->view); throw $e; } // put breadcrumb pages in model $model = array('pages' => array()); if ($active = $this->findActive($container)) { $active = $active['page']; $model['pages'][] = $active; while ($parent = $active->getParent()) { if ($parent instanceof Zend_Navigation_Page) { $model['pages'][] = $parent; } else { break; } if ($parent === $container) { // break if at the root of the given container break; } $active = $parent; } $model['pages'] = array_reverse($model['pages']); } if (is_array($partial)) { if (count($partial) != 2) { //--//require_once 'Zend/View/Exception.php'; $e = new Zend_View_Exception( 'Unable to render menu: A view partial supplied as ' . 'an array must contain two values: partial view ' . 'script and module where script can be found' ); $e->setView($this->view); throw $e; } return $this->view->partial($partial[0], $partial[1], $model); } return $this->view->partial($partial, null, $model); } // Zend_View_Helper_Navigation_Helper: /** * Renders helper * * Implements {@link Zend_View_Helper_Navigation_Helper::render()}. * * @param Zend_Navigation_Container $container [optional] container to * render. Default is to * render the container * registered in the helper. * @return string helper output */ public function render(Zend_Navigation_Container $container = null) { if ($partial = $this->getPartial()) { return $this->renderPartial($container, $partial); } else { return $this->renderStraight($container); } } }