Mixed.php #1

  • //
  • guest/
  • perforce_software/
  • chronicle/
  • main/
  • library/
  • P4Cms/
  • Menu/
  • Mixed.php
  • View
  • Commits
  • Open Download .zip Download (10 KB)
<?php
/**
 * This model is used to normalize P4Cms_Menu and Zend_Navigation_Page classes
 * into a unifom model allowing them to be listed together.
 *
 * Please note a number of the fields in this model are read only:
 * id, menuId, menuItemId, label
 *
 * All of these are derived from the assiciated Menu and, optionally, Menu Item.
 *
 * @copyright   2011 Perforce Software. All rights reserved.
 * @license     Please see LICENSE.txt in top-level folder of this distribution.
 * @version     <release>/<patch>
 */
class P4Cms_Menu_Mixed extends P4Cms_Model
{
    protected static    $_idField           = 'id';
    protected static    $_fields            = array(
        'id'            => array(
            'accessor'  => 'getId',
            'readOnly'  => true
        ),
        'menuId'        => array(
            'accessor'  => 'getMenuId',
            'readOnly'  => true
        ),
        'menuItemId'    => array(
            'accessor'  => 'getMenuItemId',
            'readOnly'  => true
        ),
        'type'          => array(
            'accessor'  => 'getType',
            'readOnly'  => true
        ),
        'depth'         => array(
            'accessor'  => 'getDepth',
            'mutator'   => 'setDepth',
            'default'   => 0
        ),
        'parentId'      => array(
            'accessor'  => 'getParentId',
            'readOnly'  => true
        ),
        'label'         => array(
            'accessor'  => 'getLabel',
            'readOnly'  => true
        )
    );

    protected           $_menu              = null;
    protected           $_menuItem          = null;
    protected           $_parentMenuItem    = null;

    /**
     * Get the id of this record. Extends parent to
     * dynamically generate the ID based on the Menu
     * and Menu Item.
     *
     * This is a read only field calculated off of the
     * menu and menu item.
     *
     * @return  mixed   the value of the id field.
     */
    public function getId()
    {
        if (!$this->hasMenu() || !$this->getMenuId()) {
            return null;
        }

        if (!$this->hasMenuItem()) {
            return $this->getMenuId();
        }

        return $this->getMenuId() . '/' . $this->getMenuItemId();
    }

    /**
     * Retrieve the identifier for this menu or menu item type.
     * The class name is used to id the type of each entry.
     *
     * @return  string|null     the id for this entry type.
     */
    public function getType()
    {
        if ($this->hasMenuItem()) {
            return get_class($this->getMenuItem());
        } else if ($this->hasMenu()) {
            return get_class($this->getMenu());
        }
        
        return null;
    }

    /**
     * Returns the depth of this item in the heigharchy.
     * It is intended all Menu's will be a depth of 0 and all Menu Items
     * will be a depth of >= 1. In practice implementors could violate this
     * intent.
     *
     * @return  int     The depth
     */
    public function getDepth()
    {
        return $this->_getValue('depth');
    }

    /**
     * Set the depth of this item. See getDepth for more details.
     *
     * @param   int     $depth  The depth to use
     * @return  P4Cms_Menu_Mixed        To maintain a fluent interface
     */
    public function setDepth($depth)
    {
        if (!is_int($depth)) {
            throw new InvalidArgumentException('Depth must be an int');
        }

        return $this->_setValue('depth', $depth);
    }

    /**
     * Return the parent P4Cms_Menu_Mixed id if any.
     *
     * This is a read only field calculated off of the 
     * parent menu item, menu item and menu.
     *
     * @return  string|null     The parent's mixed ID
     */
    public function getParentId()
    {
        if ($this->hasParentMenuItem() && $this->hasMenu()) {
            return $this->getMenuId() . '/' . $this->getParentMenuItem()->uuid;
        }

        if ($this->hasMenu() && $this->hasMenuItem()) {
            return $this->getMenuId();
        }

        return null;
    }

    /**
     * Return the label for this model. If a menu item has been set the
     * label is returned from that. Otherwise, we fall back to the menu's
     * name and lastly empty string.
     *
     * This is a read only field calculated off of the menu item or menu.
     *
     * @return  string  The label for this instance.
     */
    public function getLabel()
    {
        if ($this->hasMenuItem()) {
            return $this->getMenuItem()->getLabel();
        }

        if ($this->hasMenu()) {
            return $this->getMenu()->getLabel();
        }

        return '';
    }

    /**
     * Determine if this instance has a menu object set on it.
     *
     * @return  bool    True if a menu has been set false otherwise.
     */
    public function hasMenu()
    {
        return $this->_menu !== null;
    }

    /**
     * Return the menu associated with this instance.
     *
     * @return  P4Cms_Menu|null     The associated menu or null if none
     */
    public function getMenu()
    {
        return $this->_menu;
    }

    /**
     * Returns the ID off of the menu if one has been set.
     * Safe to call even if no menu has been set.
     *
     * This is a read only field calculated off of the menu.
     *
     * @return  string|null     The associated Menu's ID or null
     */
    public function getMenuId()
    {
        if (!$this->hasMenu()) {
            return null;
        }

        return $this->getMenu()->getId();
    }

    /**
     * Set a menu on this instance.
     *
     * @param   P4Cms_Menu|null     $menu   A menu or null.
     * @return  P4Cms_Menu_Mixed        To maintain a fluent interface
     */
    public function setMenu(P4Cms_Menu $menu = null)
    {
        $this->_menu = $menu;

        return $this;
    }

    /**
     * Determine if this instance has a menu item object set on it.
     *
     * @return  bool    True if a menu item has been set false otherwise.
     */
    public function hasMenuItem()
    {
        return $this->_menuItem !== null;
    }

    /**
     * Return the menu item associated with this instance.
     *
     * @return  Zend_Navigation_Page|null     The associated menu item or null if none
     */
    public function getMenuItem()
    {
        return $this->_menuItem;
    }

    /**
     * Returns the ID off of the menu item if one has been set.
     * Safe to call even if no menu item has been set.
     *
     * This is a read only field calculated off of the menu item.
     *
     * @return  string|null     The associated Menu Item's UUID or null
     */
    public function getMenuItemId()
    {
        if (!$this->hasMenuItem()) {
            return null;
        }

        return $this->getMenuItem()->uuid;
    }

    /**
     * Set a menu item on this instance.
     *
     * @param   Zend_Navigation_Page|null   $menuItem   A menu item or null.
     * @return  P4Cms_Menu_Mixed        To maintain a fluent interface
     */
    public function setMenuItem(Zend_Navigation_Page $menuItem = null)
    {
        $this->_menuItem = $menuItem;
    }

    /**
     * The Zend_Navigation_Page based object which is our parent or null.
     *
     * @return  Zend_Navigation_Page|null   The parent page that was set on this model.
     */
    public function getParentMenuItem()
    {
        return $this->_parentMenuItem;
    }

    /**
     * Determine if this instance has a parent menu item object set on it.
     *
     * @return  bool    True if a parent menu item has been set false otherwise.
     */
    public function hasParentMenuItem()
    {
        return $this->_parentMenuItem !== null;
    }

    /**
     * Set a new parent menu item on this instance or null.
     *
     * @param   Zend_Navigation_Page|null   $menuItem   The parent menu item or null
     * @return  P4Cms_Menu_Mixed        To maintain a fluent interface
     */
    public function setParentMenuItem(Zend_Navigation_Page $menuItem = null)
    {
        $this->_parentMenuItem = $menuItem;

        return $this;
    }
    
    /**
     * Return the parent container for this menu item be it another
     * page or a menu. Falls back to returning null for non-menu
     * items or items where parent cannot be determined.
     * 
     * @return  Zend_Navigation_Container|null  The parent container or null
     */
    public function getParentContainer()
    {
        if ($this->hasParentMenuItem()) {
            return $this->getParentMenuItem();
        }
        
        if ($this->hasMenu()) {
            return $this->getMenu()->getContainer();
        }
        
        return null;
    }
    
    /**
     * Returns the previous menu item that lives at the same level as
     * this models menu item. For non-menu item mixed models or when
     * no previous item exists null is returned.
     * 
     * @return  P4Cms_Menu_Mixed|null   The previous menu item or null
     */
    public function getPreviousMenuItem()
    {
        $container = $this->getParentContainer();
        if (!$container || !$this->hasMenuItem()) {
            return null;
        }
        
        $previous = null;
        foreach ($container as $page) {
            if ($page->uuid == $this->getMenuItem()->uuid) {
                break;
            }
            
            $previous = $page;
        }

        if (!$previous) {
            return null;
        }

        $mixed = new static;
        $mixed->setMenu($this->getMenu())
              ->setParentMenuItem($this->getParentMenuItem())
              ->setMenuItem($previous);
        
        return $mixed;
    }
    
    /**
     * Returns the nexdt menu item that lives at the same level as
     * this models menu item. For non-menu item mixed models or when
     * no next item exists null is returned.
     * 
     * @return  P4Cms_Menu_Mixed|null   The next menu item or null
     */
    public function getNextMenuItem()
    {
        $container = $this->getParentContainer();
        if (!$container || !$this->hasMenuItem()) {
            return null;
        }

        foreach ($container as $page) {
            if ($page->uuid == $this->getMenuItem()->uuid) {
                break;
            }
        }

        $container->next();

        if (!$container->valid()) {
            return null;
        }

        $next = $container->current();

        $mixed = new static;
        $mixed->setMenu($this->getMenu())
              ->setParentMenuItem($this->getParentMenuItem())
              ->setMenuItem($next);
        
        return $mixed;
    }
}
# Change User Description Committed
#1 16170 perforce_software Move Chronicle files to follow new path scheme for branching.
//guest/perforce_software/chronicle/library/P4Cms/Menu/Mixed.php
#1 8972 Matt Attaway Initial add of the Chronicle source code