<?
/**
** Class library for tree-like menu output automation
** Use and modify this classes freely.
** @author Eugene Panin, varenich@chat.ru
**/
/**
** Common methods and properties class
**/
class CommonPropertiesClass {
var $prev = '';
var $id = '';
var $items = '';
var $parents = array();
/**
** Sets the parent object for current item
** @param item Reference to a parent item object
** @returns void
** @scope public
**/
function setParent(&$item) {
$this->prev =& $item;
}
/**
** Return parent object for current item
** @returns Menu The parent Menu object reference
** @scope public
**/
function &getParent() {
return $this->prev;
}
/**
** Return unique string id
** @returns string Unique id
** @scope protected
**/
function _generateID() {
return md5 (uniqid (rand()));
}
/**
** Return object's id
** @returns string The object's id value
** @scope public
**/
function getID() {
return $this->id;
}
/**
** Sets the object's id
** @param id The object's new id
** @returns void
** @scope public
**/
function setID($id) {
$this->id = $id;
}
/**
** Finds object with specified id
** @returns object The reference to founded object of Menu or LeafItem type
** @scope public
**/
function &findObject($id) {
if ($this->getID()==$id) {
return $this;
}
# Warning! Recursion here.
if ($this->items) {
reset($this->items);
$keys = array_keys($this->items);
reset($keys);
foreach($keys as $key) {
$res =& $this->items[$key]->findObject($id);
if ($res) {
return $res;
}
}
}
return 0;
}
/**
** Initializes object's parent array
** @returns void
** @scope protected
**/
function _initParents() {
$tid =& $this->prev;
while (is_object($tid->prev)) {
$tid =& $tid->prev;
$this->parents[] =& $tid;
}
}
/**
** Return array of parent objects for current item
** @returns array The array of parent object references
** @scope public
**/
function &getParents() {
if (count($this->parents)==0) { $this->_initParents(); }
return $this->parents;
}
/**
** Returns true if current object is a parent of given id's object
** @returns boolean The result of searching
** @scope public
**/
function isParentOf($id='') {
if (!$id) return 0;
# Warning! Recursion here.
$ob =& $this->findObject($id);
while (is_object($ob->prev)) {
if ($ob->getID()==$id) {
return 1;
}
$ob =& $ob->prev;
}
return 0;
}
}
/**
** The Menu item class
**/
class Menu extends CommonPropertiesClass {
var $name = '';
var $items = array();
var $openedMenuSymbol = '';
var $closedMenuSymbol = '';
/**
** Class constructor
** Creates unique value If parameter "id" is not available
** @param name The name of menu item
** @param id The ID of menu item
**/
function Menu($name='',$id='') {
if ($name) $this->name = $name;
if (!$id) {
$this->id = $this->_generateID();
}
else {
$this->id = $id;
}
}
/**
** Sets the opened menu symbol
** @param val The symbol
** @returns void
** @scope public
**/
function setOpenedMenuSymbol($val='') {
$this->openedMenuSymbol = $val;
$keys = array_keys($this->items);
foreach ($keys as $key) {
if ((get_class($this->items[$key])=='menu') || is_subclass_of($this->items[$key],'menu')) {
$this->items[$key]->setOpenedMenuSymbol($val);
}
}
}
/**
** Sets the closed menu symbol
** @param val The symbol
** @returns void
** @scope public
**/
function setClosedMenuSymbol($val='') {
$this->closedMenuSymbol = $val;
$keys = array_keys($this->items);
foreach ($keys as $key) {
if ((get_class($this->items[$key])=='menu') || is_subclass_of($this->items[$key],'menu')) {
$this->items[$key]->setClosedMenuSymbol($val);
}
}
}
/**
** Return object's name
** @returns string The object's name value
** @scope public
**/
function getName() {
return $this->name;
}
/**
** Sets the object's name
** @param name The object's new name
** @returns void
** @scope public
**/
function setName($name) {
$this->name = $name;
}
/**
** Return array of child object's references
** @returns array The child object's array
** @scope public
**/
function &getItems() {
return $items;
}
/**
** Adds the new child object
** @param item The Menu or LefItem object
** or
** @param array The array of Menu or LefItem objects
** @returns void
** @scope public
**/
function addItem(&$item) {
if (is_array($item)) {
for($i=0;$i<count($item);$i++) {
$it =& $item[$i];
$this->_setItem(&$it);
}
}
else {
$this->_setItem(&$item);
}
}
function _setItem(&$item) {
if ( is_object($item) && ((get_class($item)=='leafitem') || (get_class($item)=='menu') || is_subclass_of($item,'menu') || is_subclass_of($item,'leafitem')) ) {
$item->setParent(&$this);
$this->items[$item->getID()] =& $item;
}
else {
echo "Menu.new error: Invalid object type. Use 'menu' or 'leafitem' classes or subclasses only.<br>\n";
echo "Your object is of type '".get_class($item)."'<br>\n";
exit;
}
}
/**
** Unsets the child object with given id
** @param id The object's id
** @returns void
** @scope public
**/
function dropItem($id='') {
if ($id) {
unset($this->items[$id]);
}
}
/**
** Outputs child menu branches
** @param cid The target object's id
** @param url An url of menu's items
** @param level Leave it blank for inner usage.
** @returns string Child menus branch
** @scope public
**/
function display($cid,$url='',$level=0) {
global $PHP_SELF;
$res = '';
for ($i=0;$i<$level;$i++) {
$res .= " ";
}
$symbol = $this->closedMenuSymbol;
if ($this->isParentOf($cid) || !is_object($this->prev)) {
$symbol = $this->openedMenuSymbol;
}
else {
$symbol = $this->closedMenuSymbol;
}
if (!$url) {
$res .= $symbol."<a href=\"$PHP_SELF?menuid=".$this->getID()."\">{$this->name}</a><br>\n";
}
else {
$res .= $symbol."<a href=\"$url".$this->getID()."\">{$this->name}</a><br>\n";
}
if ($this->isParentOf($cid) || !is_object($this->prev)) {
reset($this->items);
$keys = array_keys($this->items);
foreach($keys as $key) {
$res .= $this->items[$key]->display($cid,$url,($level+1));
}
}
return $res;
}
}
/**
** The LeafItem item class
**/
class LeafItem extends CommonPropertiesClass {
var $name = '';
var $url = '';
var $template = '<a href="URL">NAME</a>';
/**
** Class constructor
** @param url The Item's URL
** @param name The Item's name
** @param id The Item's ID
** (or leave it blank if you want to create it automaticaly)
**/
function LeafItem($url='',$name='',$id='') {
$this->url = $url;
$this->name = $name;
if (!$id) {
$this->id = $this->_generateID();
}
else {
$this->id = $id;
}
}
/**
** Return object's URL
** @returns string The object's URL value
** @scope public
**/
function getUrl() {
return $this->url;
}
/**
** Sets the object's URL
** @param url The object's new URL
** @returns void
** @scope public
**/
function setUrl($url='') {
$this->url = $url;
}
/**
** Return object's Template
** Use template when you want your LeafItem
** will have another form of HTML output. For example,
** if you want not just <a href="URL">NAME</a>, but
** <a href="URL" target=_blank><font color=blue><b>NAME</b></font></a>
** @returns string The object's URL value
** @scope public
**/
function getTemplate() {
return $this->template;
}
/**
** Sets the object's template
** @param val The object's new template
** @returns void
** @scope public
**/
function setTemplate($val='') {
$this->template = $val;
}
/**
** Return object's name
** @returns string The object's URL value
** @scope public
**/
function getName() {
return $this->name;
}
/**
** Sets the object's name
** @param name The object's new name
** @returns void
** @scope public
**/
function setName($name='') {
$this->name = $name;
}
/**
** Outputs current item
** @param cid The target object's id
** @param url An url of menu's items
** @param level Leave it blank for inner usage.
** @returns string Child menus branch
** @scope public
**/
function display($cid,$url='',$level=0) {
$res = '';
for ($i=0;$i<$level;$i++) {
$res .= " ";
}
$templ = preg_replace('/URL/',$this->url,$this->template);
$res .= preg_replace('/NAME/',$this->name,$templ);
return $res."<br>\n";
}
/**
** Outputs current item in given format
** @param format Format of item's output
** @returns string Item in given format
** @scope public
**/
function out($format='HTML') {
switch($format) {
case 'HTML':
$res = _outHTML();
break;
case 'XML':
$res = _outXML();
break;
case 'CSV':
$res = _outCSV();
break;
}
return $res;
}
function _outXML() {
$res = "<A HREF=\"$this->url\">$this->name</A>";
return $res;
}
function _outHTML() {
return $this->_outXML();
}
function _outCSV() {
$res = $this->url.'|'.$this->name;
return $res;
}
}
?>
|