Snippets

Create an account or login to be able to add, comment and rate snippets.

Navigation

Refine Tags

Snippets tagged "navigation nested module" Snippets tagged "navigation nested module"

Nested Set Navigation Component Module (PART 2)

NestedSet Model for Navigation

model scheme

enhanced nested set model class

enhanced module action class

navigation list tabular cell template

Features:

enhanced module action class

/apps/backend/modules/navigation/actions/actions.class.php

<?php
 
/**
 * navigation actions.
 */
class navigationActions extends autonavigationActions
{
    public function executeList()
    {
 
        $this->typeOfList = 1;
 
        switch($this->typeOfList)
        {
            case 1:
                $pager = new Navigation();
                $this->pager = $pager->getTree(0,200);
                break;
            default:
 
                $this->processSort();
 
                $this->processFilters();
 
                // pager
 
                $navigation = new Navigation();
                $this->pager = new sfPropelPager('Navigation', 100);
                $c = new Criteria();
                $c->addAscendingOrderByColumn(NavigationPeer::TREE_LEFT);
 
                if($this->getUser()->hasCredential('SHOW_ALL_NAVIGATION_ROOTS')){
 
                } else {
                    $rootNodes = $navigation->getRootNodes();
                    $conditions = array();
                    foreach($rootNodes as $credentialName => $credential) {
                        if($this->getUser()->hasCredential($credentialName)){
                            $c1 = $c->getNewCriterion(NavigationPeer::TREE_LEFT, $credential["left"], Criteria::GREATER_THAN);
                            $c2 = $c->getNewCriterion(NavigationPeer::TREE_RIGHT, $credential["right"], Criteria::LESS_THAN);
                            $conditions[] = $c1->addAnd($c2);
                        }
                    }
                    if(count($conditions) > 1) {
                        foreach($conditions as $condition){
                            $c->addOr($condition);
                        }
                    } else {
                        $c->add($conditions[0]);
                    }
                }
 
 
                $this->addSortCriteria($c);
                $this->addFiltersCriteria($c);
                $this->pager->setCriteria($c);
 
                $this->pager->setPage($this->getRequestParameter('page', 1));
                $this->pager->init();
 
                break;
        }
    }
 
    public function executeShow() {
        $this->component = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $this->paths = $this->component->getPath();
    }
 
    public function executeBlockable() {
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $state = $this->getRequestParameter('state')==1 ? 1 : 0;
        $navigation->setIsBlocked($state);
        $navigation->save();
        $this->state = $state;
        $this->navigation = $navigation;
    }
 
    public function executeNavigatable() {
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $state = $this->getRequestParameter('state')==1 ? 1 : 0;
        $navigation->setIsNavigation($state);
        $navigation->save();
        $this->state = $state;
        $this->navigation = $navigation;
    }
 
 
    private function getPrimaryRoot(){
        return NavigationPeer::retrieveByPk(1);
    }
 
 
    // Default Root Node
    public function executeMakeRoot(){
 
        $root = new Navigation();
        $root->makeRoot();
        $root->save();
 
        return $this->redirect('navigation/edit?component_id='. $root->getNavigationId());
 
    }
 
    // Further Root Node
    public function executeMakeNextRoot(){
 
        $root = new Navigation();
        $root->makeNextRoot();
        $root->save();
 
 
        return $this->redirect('navigation/edit?component_id='. $root->getNavigationId());
 
    }
 
    // Delete Branch
    public function executeDeleteDescendants(){
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $navigation->deleteDescendants();
        $navigation = $navigation->reload();
        $navigation->delete();
        return $this->redirect('navigation/list');
    }
 
    // insert first child node
    public function executeInsertAsFirstChildOf(){
        $this->message = "Nun wird ein Kindelement erzeugt";
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
 
        $child = new Navigation();
        $child->insertAsFirstChildOf($navigation);
        $child->save();
        return $this->redirect('navigation/edit?component_id='. $child->getNavigationId());
 
    }
 
    // insert last child node
    public function executeInsertAsLastChildOf(){
 
        $this->message = "Nun wird ein Kindelement erzeugt";
 
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
 
        $child = new Navigation();
        $child->insertAsLastChildOf($navigation);
        $child->save();
 
 
        return $this->redirect('navigation/edit?component_id='. $child->getNavigationId());
 
    }
 
    // insert sibling before
    public function executeInsertAsNextSiblingOf(){
 
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
 
        $child = new Navigation();
        $child->insertAsNextSiblingOf($navigation);
        $child->save();
 
 
        return $this->redirect('navigation/edit?component_id='. $child->getNavigationId());
    }
 
    // insert sibling after
    public function executeInsertAsPrevSiblingOf(){
 
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
 
        $child = new Navigation();
        $child->insertAsPrevSiblingOf($navigation);
        $child->save();
 
        return $this->redirect('navigation/edit?component_id='. $child->getNavigationId());
    }
 
    /*Tree Modification*/
    // UP
    public function executeMoveToPrevSiblingOf(){
 
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $siblingNavigation = $navigation->retrievePrevSibling($navigation);
 
        $navigation->moveToPrevSiblingOf($siblingNavigation);
        $navigation->save();
 
        return $this->redirect('navigation/list');
 
    }
    //DOWN
    public function executeMoveToNextSiblingOf(){
 
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $siblingNavigation = $navigation->retrieveNextSibling($navigation);
 
        $navigation->moveToNextSiblingOf($siblingNavigation);
        $navigation->save();
 
        return $this->redirect('navigation/list');
 
    }
 
 
    // LEFT UP
    public function executeMoveLeftUp(){
 
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $parentNavigation = NavigationPeer::retrieveByPk($navigation->getParent());
        $navigation->moveToPrevSiblingOf($parentNavigation);
        $navigation->save();
        return $this->redirect('navigation/list');
    }
 
    // LEFT DOWN
    public function executeMoveLeftDown(){
 
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $parentNavigation = NavigationPeer::retrieveByPk($navigation->getParent());
        $navigation->moveToNextSiblingOf($parentNavigation);
        $navigation->save();
        return $this->redirect('navigation/list');
 
    }
 
    // RIGHT FIRST
    public function executeMoveRightPrev(){
 
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $prevSibling = $navigation->retrievePrevSibling($navigation);
        $navigation->moveToLastChildOf($prevSibling);
        $navigation->save();
        return $this->redirect('navigation/list');
    }
 
    // RIGHT LAST
    public function executeMoveRightNext(){
 
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $nextSibling = $navigation->retrieveNextSibling($navigation);
        $navigation->moveToLastChildOf($nextSibling);
        $navigation->save();
        return $this->redirect('navigation/list');
 
    }
 
    // ROOT PREV
    public function executeMoveRootPrev(){
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $rootNavigation = NavigationPeer::retrieveByPk($this->getRequestParameter('root_id'));
        $prevRootNavigation = $rootNavigation->retrievePrevSibling($rootNavigation);
        $navigation->moveToLastChildOf($prevRootNavigation);
        $navigation->save();
 
        return $this->redirect('navigation/list');
    }
 
    // ROOT NEXT
    public function executeMoveRootNext(){
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $rootNavigation = NavigationPeer::retrieveByPk($this->getRequestParameter('root_id'));
        $nextRootNavigation = $rootNavigation->retrieveNextSibling($rootNavigation);
        $navigation->moveToLastChildOf($nextRootNavigation);
        $navigation->save();
        return $this->redirect('navigation/list');
    }
 
    // Duplicate Tree
    public function executeCopyDescendants(){
 
        $navigation = NavigationPeer::retrieveByPk($this->getRequestParameter('component_id'));
        $parentNavigation = NavigationPeer::retrieveByPk($navigation->getParent());
 
        $newParentNavigation = $this->copyNode($navigation, $parentNavigation);
 
        $this->iterateOnDescendants($navigation->getDescendants() , $newParentNavigation);
 
        return $this->redirect('navigation/list');
    }
 
    private function iterateOnDescendants($navigations, $prevNavigation){
 
        foreach($navigations as $navigation){
            $actualNavigation = $this->copyNodeDescendants($navigation, $prevNavigation);
            $prevNavigation = $actualNavigation;
        }
    }
 
    private function transferData(Navigation $navigation){
 
        $newNavigation = new Navigation();
        $newNavigation->setName($navigation->getName());
        $newNavigation->setAction($navigation->getAction());
        $newNavigation->setParameter($navigation->getParameter());
        $newNavigation->setCaption($navigation->getCaption());
        $newNavigation->setDescription($navigation->getDescription());
        $newNavigation->setIsNavigation(0);
        $newNavigation->setIsBlocked(0);
        $newNavigation->setIsTemplate(0);
        return $newNavigation;
    }
 
    private function copyNodeDescendants($navigation, $prevNavigation){
 
        $newNavigation = $this->transferData($navigation);
 
        if($navigation->getLevel() == $prevNavigation->getLevel() ){
            $newNavigation->insertAsNextSiblingOf($prevNavigation);
        } elseif($navigation->getLevel() > $prevNavigation->getLevel()){
            $newNavigation->insertAsLastChildOf($prevNavigation);
        } else {
            $parentNavigation = NavigationPeer::retrieveByPk($prevNavigation->getParent());
            $newNavigation->insertAsNextSiblingOf($parentNavigation);
        }
        $newNavigation->save();
        return $newNavigation->reload();
    }
 
    private function copyNode($navigation, $parentNavigation){
 
        $newNavigation = $this->transferData($navigation);
 
        $newNavigation->insertAsLastChildOf($parentNavigation);
        $newNavigation->save();
 
        return $newNavigation->reload();
    }
 
}
 
by Thomas Schäfer on 2008-03-19, tagged module  navigation  nested  set 

Nested Set Navigation Component Module (PART 1)

NestedSet Model for Navigation

(This module is for administering big nested navigation trees, not for being used in a high performance web site. If you want to build a resultset for navigations then setup a custom query. There are enough examples out there for querying a nested set )

model scheme

enhanced nested set model class

enhanced module action class

navigation list tabular cell template

Features:

NavigationModel Scheme

  <table name="md_components" phpName="Navigation">
    <column name="component_id" type="INTEGER" size="11" primaryKey="true" required="true" autoIncrement="true"/>
    <column name="name" type="VARCHAR" size="50" required="true" phpName="Name"/>
    <column name="action" type="VARCHAR" size="50" phpName="Action"/>
    <column name="caption" type="VARCHAR" size="50" phpName="Caption"/>
    <column name="description" type="LONGVARCHAR" phpName="Description"/>
    <column name="parameter" type="VARCHAR" size="50" phpName="Parameter"/>
    <column name="image" type="VARCHAR" size="50" phpName="Image"/>
    <column name="tree_left" type="INTEGER" size="11" phpName="Left"/>
    <column name="tree_right" type="INTEGER" size="11" phpName="Right"/>
    <column name="tree_parent" type="INTEGER" size="11" default="0" phpName="Parent"/>
    <column name="tree_scope" type="INTEGER" size="11" default="0" phpName="Scope"/>
    <column name="created_at" type="TIMESTAMP" required="true" phpName="CreationDate"/>
    <column name="created_by" type="INTEGER" size="11" default="1" phpName="Creator"/>
    <column name="templatable" type="BOOLEAN" phpName="IsTemplate"/>
    <column name="blockable" type="BOOLEAN" phpName="IsBlocked"/>
    <column name="navigatable" type="BOOLEAN" phpName="IsNavigation"/>
    <column name="deleted_at" type="TIMESTAMP"/>
    <column name="deleted_by" type="INTEGER" size="11"/>
    <foreign-key foreignTable="sf_guard_user" name="creator" onDelete="setnull">
      <reference local="created_by" foreign="id"/>
    </foreign-key>
    <foreign-key foreignTable="sf_guard_user" name="FK_USER" onDelete="setnull">
      <reference local="deleted_by" foreign="id"/>
    </foreign-key>
  </table>
 

enhanced nested set model class

<?php
 
/**
 * Subclass for representing a row from the 'md_components' table.
 *
 *
 *
 * @package lib.model
 */
class Navigation extends BaseNavigation
{
    public function makeNextRoot()
    {
        $max = $this->getMaxRight();
        $this->setLeftValue($max + 1);
        $this->setRightValue($max + 2);
    }
 
    public function getNavigationId(){
        return $this->getComponentId();
    }
 
    public function getMaxRight(){
 
        $connection = Propel::getConnection();
        $query = 'SELECT MAX(%s) AS max FROM %s';
 
        $query = sprintf($query, NavigationPeer::TREE_RIGHT, NavigationPeer::TABLE_NAME);
        $statement = $connection->prepareStatement($query);
        $resultset = $statement->executeQuery();
        $resultset->next();
        return $resultset->getInt('max');
    }
 
    public function getMaxLeft(){
        $connection = Propel::getConnection();
        $query = 'SELECT MAX(%s) AS max FROM %s';
        $query = sprintf($query, NavigationPeer::TREE_LEFT, NavigationPeer::TABLE_NAME);
        $statement = $connection->prepareStatement($query);
        $resultset = $statement->executeQuery();
        $resultset->next();
        return $resultset->getInt('max');
    }
 
    public function getRootNodes(){
 
        $connection = Propel::getConnection();
        $query = 'SELECT * FROM %s WHERE %s %s %s;';
 
        $query = sprintf($query, NavigationPeer::TABLE_NAME, NavigationPeer::TREE_PARENT, Criteria::EQUAL, 0);
        $statement = $connection->prepareStatement($query);
        $resultset = $statement->executeQuery();
        $credential = array();
        foreach($resultset as $result){
            $credential[$result["name"]]["component_id"] = $result["component_id"];
            $credential[$result["name"]]["name"] = $result["name"];
            $credential[$result["name"]]["left"] = $result["tree_left"];
            $credential[$result["name"]]["right"] = $result["tree_right"];
        }
        return $credential;
    }
 
 
    public function getTree($offset = 0, $limit = 10, $options = null){
 
 
        $query = '
SELECT
    *,
    (
        SELECT
            CONCAT(COUNT(*))
        FROM md_components MA
        WHERE
        (
            (
                MA.TREE_LEFT < MM.TREE_LEFT AND MA.TREE_RIGHT > MM.TREE_RIGHT
            )
            AND MA.TREE_SCOPE = MM.TREE_SCOPE
        )
    )
    AS isLevel,
    (
        SELECT MZ4.COMPONENT_ID
                FROM md_components MZ4 , md_components MZ5
                WHERE MZ5.TREE_LEFT BETWEEN MZ4.TREE_LEFT AND MZ4.TREE_RIGHT
                AND MZ5.COMPONENT_ID = MM.COMPONENT_ID
                ORDER BY MZ4.TREE_LEFT  LIMIT 1,1
    )
    AS selfFirstLevel,
    (
        SELECT
            IF( MB.TREE_RIGHT - MB.TREE_LEFT > 1, 1, 0)
        FROM md_components MB
        WHERE MB.COMPONENT_ID = MM.COMPONENT_ID
        AND MB.TREE_SCOPE = MM.TREE_SCOPE
    )
    AS hasChilds,
    (
        SELECT MC.COMPONENT_ID FROM md_components MC
        WHERE (MM.TREE_LEFT = MC.TREE_RIGHT + 1)
        AND MC.TREE_SCOPE = MM.TREE_SCOPE
    )
    AS prevSibling,
    (
        SELECT
            MD.COMPONENT_ID
        FROM md_components MD
        WHERE (MM.TREE_RIGHT = MD.TREE_LEFT - 1)
        AND MD.TREE_SCOPE = MM.TREE_SCOPE
    )
    AS nextSibling,
    (
        SELECT
            IF
            (
                (
                    SELECT
                        IF
                        (
                            MQ.TREE_RIGHT - MQ.TREE_LEFT > 1,
                            1,
                            0
                        )
                    FROM md_components MQ
                    WHERE MQ.COMPONENT_ID = MM.COMPONENT_ID
                    AND MQ.TREE_SCOPE = MM.TREE_SCOPE
                ) = 1 ,
                ME.COMPONENT_ID,
                NULL
            )
        FROM md_components ME
        WHERE ME.TREE_LEFT = MM.TREE_LEFT + 1
        AND ME.TREE_SCOPE = MM.TREE_SCOPE
    )
    AS firstChild,
    (
        SELECT
            IF
            (
                (
                    SELECT
                        IF(
                            MS.TREE_RIGHT - MS.TREE_LEFT > 1,
                            1,
                            0
                        )
                    FROM md_components MS
                    WHERE MS.COMPONENT_ID = MM.COMPONENT_ID
                    AND MS.TREE_SCOPE = MM.TREE_SCOPE
                ) = 1 ,
                MF.COMPONENT_ID,
                NULL
            )
        FROM md_components MF
        WHERE MF.TREE_RIGHT = MM.TREE_RIGHT - 1
        AND MF.TREE_SCOPE = MM.TREE_SCOPE
 
    )
    AS lastChild,
    (
              SELECT
            MX.COMPONENT_ID
            FROM md_components MX
        WHERE MX.TREE_LEFT - 1 =
        (
                  SELECT
            MZ.TREE_RIGHT
            FROM md_components MZ
            WHERE (MZ.TREE_RIGHT > MM.TREE_RIGHT) AND (MZ.TREE_LEFT < MM.TREE_LEFT) AND (MZ.TREE_PARENT = 0)
            AND MZ.TREE_SCOPE = MM.TREE_SCOPE
        )
 
    )
    AS nextRoot,
    (
        SELECT
            MX.COMPONENT_ID
            FROM md_components MX
        WHERE MX.TREE_RIGHT + 1 =
        (
                  SELECT
            MZ2.TREE_LEFT
            FROM md_components MZ2
            WHERE (MZ2.TREE_RIGHT > MM.TREE_RIGHT) AND (MZ2.TREE_LEFT < MM.TREE_LEFT) AND (MZ2.TREE_PARENT = 0)
            AND MZ2.TREE_SCOPE = MM.TREE_SCOPE
        )
 
    )
    AS prevRoot,
    (
            SELECT
            MZ3.COMPONENT_ID
            FROM md_components MZ3
            WHERE (MZ3.TREE_RIGHT > MM.TREE_RIGHT) AND (MZ3.TREE_LEFT < MM.TREE_LEFT) AND (MZ3.TREE_PARENT = 0)
            AND MZ3.TREE_SCOPE = MM.TREE_SCOPE
 
    )
    AS selfRoot
 
FROM md_components MM
';
 
        $query .= ' ORDER BY MM.TREE_LEFT ASC ';
        $query .= 'LIMIT '. $offset . ', ' . $limit;
 
        $connection = Propel::getConnection();
        $statement = $connection->createStatement(  );
        $result = $statement->executeQuery( $query , ResultSet::FETCHMODE_NUM);
 
        $objects = NavigationPeer::populateObjects( $result );
 
        $phpNames = NavigationPeer::getFieldNames(BasePeer::TYPE_PHPNAME);
 
        $additionalColumns =
            array_merge(
                $phpNames,
                array("isLevel", "selfFirstLevel", "hasChilds", "prevSibling", "nextSibling", "firstChild", "lastChild", "prevRoot", "nextRoot", "selfRoot")
            );
 
        foreach($result as $key => $object){
            foreach($object as $column => $value){
                if($column > count($phpNames)-1){
                    $method = $additionalColumns[$column];
 
                    $objects[$key-1]->$method = $value;
                }
            }
        }
        return $objects;
    }
 
    /*no setter functions*/
    public function lastChild(){
        return $this->lastChild;
    }
 
    public function selfFirstLevel(){
        return $this->selfFirstLevel;
    }
 
    public function firstChild(){
        return $this->firstChild;
    }
 
    public function prevRoot(){
        return $this->prevRoot;
    }
 
    public function nextRoot(){
        return $this->nextRoot;
    }
 
    public function selfRoot(){
        return $this->selfRoot;
    }
 
    public function nextSibling(){
        return $this->nextSibling;
    }
 
    public function prevSibling(){
        return $this->prevSibling;
    }
 
    public function isLevel(){
        return $this->isLevel;
    }
 
    public function hasChilds(){
        return $this->hasChilds;
    }
}
 
$columns_map = array
(
    'left'   => NavigationPeer::TREE_LEFT,
    'right'  => NavigationPeer::TREE_RIGHT,
    'parent' => NavigationPeer::TREE_PARENT,
    'scope'  => NavigationPeer::TREE_SCOPE
);
 
sfPropelBehavior::add('Navigation', array('actasnestedset' => array('columns' => $columns_map)));
 
by Thomas Schäfer on 2008-03-19, tagged module  navigation  nested  set