Location: PHPKode > projects > Mocovie web framework > webs/common/controls/menu.php
<?php
/**
 *  Copyright (C) 2010  Kai Dorschner
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Kai Dorschner <the-hide@address.com>
 * @copyright Copyright 2010, Kai Dorschner
 * @license http://www.gnu.org/licenses/gpl.html GPLv3
 * @package mocovi
 * @subpackage controls
 */

/**
 * Require generic dirlist control.
 */
ControlFactory::load('dirlist');

/**
 * Is able to create recursive menu from the {@link filesystem}.
 *
 * <b>Attributes</b>:
 * - <b>directory</b>: Defines a static directory which is used to create the menu. If this is not set this control will use the "directory" value of {@link $defaultOptions}.
 * - <b>recursion</b>: Sets the maximum value of recursion depth. This attribute operates with the local $depth variable of the {@see recursiveReadElementsIn()} method.
 *
 * <b>Parameters:</b>
 * - <b>restriction</b>: A regular expression which let this control not use elements matching this pattern.
 * - <b>obligation</b>: A regular expression which defines which elements MUST be used when they match this pattern.
 * - <b>type</b>: Sets a datatype for the element. Can be "file", "dir" or even "array", "string", "bool", "int", etc. You can use all strings which should be inserted after "is_" to create a dynamic function such as is_file();
 *
 * An example with dynamic source:
 * <code>
 * <menu recursion="2">
 *   <param name="restriction" value="^\."/>
 *   <param name="obligation" value="^menuelement_"/>
 *   <param name="type" value="dir"/>
 * </menu>
 * </code>
 *
 * Or with static source:
 * <code>
 * <menu directory="./my/directory/" recursion="2">
 *   <param name="restriction" value="^\."/>
 *   <param name="obligation" value="^menuelement_"/>
 *   <param name="type" value="dir"/>
 * </menu>
 * </code>
 *
 * @package mocovi
 * @subpackage controls
 */
class menu_control extends dirlist_control
{
	/**
	 * Is the current directory from the user cut in pieces (array)
	 * @var array Contains all pieces of the user's directory
	 * @access protected
	 */
	protected $activeDirectory = array();
	protected $defaultOptions = array
		( 'directory'			=> '/' // Root Directory
		, 'recursion'			=> 2 // Maximum recursion depth
		, 'readSiblings'		=> 0 // Also read content of neighbour directories
		, 'fold'				=> 1 // Folds peripheral elements
		, 'lastModifiedFormat'	=> 'c' // PHP date(); format (http://de.php.net/date): c = ISO 8601 date
		);

	/**
	 * @override
	 */
	protected function program()
	{
		$this->activeDirectory = explode('/', trim($GLOBALS['page'], '/')); // clear first and last slash
		$this->recursiveReadElementsIn($this->node, $this->getOption('directory'));
	}

	/**
	 * Reads all elements from the given directory in the specified container.
	 *
	 * @access protected
	 * @return void
	 * @param $container 
	 */
	protected function recursiveReadElementsIn(DomNode &$container, $dir)
	{
		static $depth = 0;
		$this->readElementsIn($container, $dir);
		foreach($container->childNodes as $subnode)
		{
			$path = $this->getURIFromElement($subnode);
			$current = $this->dom->createElement($this->getName()); // create empty container
			/*
				Optionally add to IF query:
				&& $depth == count($this->activeDirectory) - 1 // Only marks the current Element as "active"
			*/
			if($path == $this->activeDirectoryFragment($depth))
				$subnode->setAttribute('active', 'true');
			if(($this->getOption('readSiblings') || $path == $this->activeDirectoryFragment($depth)) && ($this->getOption('recursion') == '*' || $depth < $this->getOption('recursion') + count($this->activeDirectory) - 1))
			{
				$depth++;
				$this->recursiveReadElementsIn($current, $path); // Recursion
				$depth--;
			}
			// Only if this element contains subelements
			if($current->firstChild && @count($current->firstChild->childNodes) > 0)
				$subnode->appendChild($current);
		}
	}

	/**
	 * Returns the active part of the directory.
	 *
	 * @access protected
	 */
	protected function activeDirectoryFragment($index)
	{
		$return = '/';
		for($i = 0; $i < count($this->activeDirectory) && $i < ($index + 1); $i++)
			$return .= $this->activeDirectory[$i].'/';
		return $return;
	}
}
Return current item: Mocovie web framework