From: hickert Date: Tue, 30 Oct 2007 13:42:03 +0000 (+0000) Subject: Added layer menu. X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=1b616ca469e74bf76865bcdac3fc8aac0936b627;p=gosa.git Added layer menu. Initial, not cleaned and so on.. git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@7690 594d385d-05f5-0310-b6e9-bd551577e9d8 --- diff --git a/html/images/down-arrow.png b/html/images/down-arrow.png new file mode 100644 index 000000000..f0fb47d82 Binary files /dev/null and b/html/images/down-arrow.png differ diff --git a/html/images/forward-arrow.png b/html/images/forward-arrow.png new file mode 100644 index 000000000..4f3189a0a Binary files /dev/null and b/html/images/forward-arrow.png differ diff --git a/html/include/layersmenu-browser_detection.js b/html/include/layersmenu-browser_detection.js new file mode 100644 index 000000000..79896a001 --- /dev/null +++ b/html/include/layersmenu-browser_detection.js @@ -0,0 +1,33 @@ +// PHP Layers Menu 3.2.0-rc (C) 2001-2004 Marco Pratesi - http://www.marcopratesi.it/ + +DOM = (document.getElementById) ? 1 : 0; +NS4 = (document.layers) ? 1 : 0; +// We need to explicitly detect Konqueror +// because Konqueror 3 sets IE = 1 ... AAAAAAAAAARGHHH!!! +Konqueror = (navigator.userAgent.indexOf('Konqueror') > -1) ? 1 : 0; +// We need to detect Konqueror 2.2 as it does not handle the window.onresize event +Konqueror22 = (navigator.userAgent.indexOf('Konqueror 2.2') > -1 || navigator.userAgent.indexOf('Konqueror/2.2') > -1) ? 1 : 0; +Konqueror30 = + ( + navigator.userAgent.indexOf('Konqueror 3.0') > -1 + || navigator.userAgent.indexOf('Konqueror/3.0') > -1 + || navigator.userAgent.indexOf('Konqueror 3;') > -1 + || navigator.userAgent.indexOf('Konqueror/3;') > -1 + || navigator.userAgent.indexOf('Konqueror 3)') > -1 + || navigator.userAgent.indexOf('Konqueror/3)') > -1 + ) + ? 1 : 0; +Konqueror31 = (navigator.userAgent.indexOf('Konqueror 3.1') > -1 || navigator.userAgent.indexOf('Konqueror/3.1') > -1) ? 1 : 0; +// We need to detect Konqueror 3.2 and 3.3 as they are affected by the see-through effect only for 2 form elements +Konqueror32 = (navigator.userAgent.indexOf('Konqueror 3.2') > -1 || navigator.userAgent.indexOf('Konqueror/3.2') > -1) ? 1 : 0; +Konqueror33 = (navigator.userAgent.indexOf('Konqueror 3.3') > -1 || navigator.userAgent.indexOf('Konqueror/3.3') > -1) ? 1 : 0; +Opera = (navigator.userAgent.indexOf('Opera') > -1) ? 1 : 0; +Opera5 = (navigator.userAgent.indexOf('Opera 5') > -1 || navigator.userAgent.indexOf('Opera/5') > -1) ? 1 : 0; +Opera6 = (navigator.userAgent.indexOf('Opera 6') > -1 || navigator.userAgent.indexOf('Opera/6') > -1) ? 1 : 0; +Opera56 = Opera5 || Opera6; +IE = (navigator.userAgent.indexOf('MSIE') > -1) ? 1 : 0; +IE = IE && !Opera; +IE5 = IE && DOM; +IE4 = (document.all) ? 1 : 0; +IE4 = IE4 && IE && !DOM; + diff --git a/html/include/layersmenu-library.js b/html/include/layersmenu-library.js new file mode 100644 index 000000000..049abf89d --- /dev/null +++ b/html/include/layersmenu-library.js @@ -0,0 +1,248 @@ +// PHP Layers Menu 3.2.0-rc (C) 2001-2004 Marco Pratesi - http://www.marcopratesi.it/ + +layerLeft = new Array(); +layerTop = new Array(); + +function setVisibility(layer, on) +{ + if (on) { + if (DOM) { + document.getElementById(layer).style.visibility = 'visible'; + } else if (NS4) { + document.layers[layer].visibility = 'show'; + } else { + document.all[layer].style.visibility = 'visible'; + } + } else { + if (DOM) { + document.getElementById(layer).style.visibility = 'hidden'; + } else if (NS4) { + document.layers[layer].visibility = 'hide'; + } else { + document.all[layer].style.visibility = 'hidden'; + } + } +} + +function isVisible(layer) +{ + if (DOM) { + return (document.getElementById(layer).style.visibility == 'visible'); + } else if (NS4) { + return (document.layers[layer].visibility == 'show'); + } else { + return (document.all[layer].style.visibility == 'visible'); + } +} + +function setLeft(layer, x) +{ +layerLeft[layer] = x; + if (DOM && !Opera5) { + document.getElementById(layer).style.left = x + 'px'; + } else if (Opera5) { + document.getElementById(layer).style.left = x; + } else if (NS4) { + document.layers[layer].left = x; + } else { + document.all[layer].style.pixelLeft = x; + } +} + +function getOffsetLeft(layer) +{ + var value = 0; + if (DOM) { // Mozilla, Konqueror >= 2.2, Opera >= 5, IE + object = document.getElementById(layer); + value = object.offsetLeft; +//alert (object.tagName + ' --- ' + object.offsetLeft); + while (object.tagName != 'BODY' && object.offsetParent) { + object = object.offsetParent; +//alert (object.tagName + ' --- ' + object.offsetLeft); + value += object.offsetLeft; + } + } else if (NS4) { + value = document.layers[layer].pageX; + } else { // IE4 IS SIMPLY A BASTARD !!! + if (document.all['IE4' + layer]) { + layer = 'IE4' + layer; + } + object = document.all[layer]; + value = object.offsetLeft; + while (object.tagName != 'BODY') { + object = object.offsetParent; + value += object.offsetLeft; + } + } + return (value); +} + +function setTop(layer, y) +{ +layerTop[layer] = y; + if (DOM && !Opera5) { + document.getElementById(layer).style.top = y + 'px'; + } else if (Opera5) { + document.getElementById(layer).style.top = y; + } else if (NS4) { + document.layers[layer].top = y; + } else { + document.all[layer].style.pixelTop = y; + } +} + +function getOffsetTop(layer) +{ +// IE 5.5 and 6.0 behaviour with this function is really strange: +// in some cases, they return a really too large value... +// ... after all, IE is buggy, nothing new + var value = 0; + if (DOM) { + object = document.getElementById(layer); + value = object.offsetTop; + while (object.tagName != 'BODY' && object.offsetParent) { + object = object.offsetParent; + value += object.offsetTop; + } + } else if (NS4) { + value = document.layers[layer].pageY; + } else { // IE4 IS SIMPLY A BASTARD !!! + if (document.all['IE4' + layer]) { + layer = 'IE4' + layer; + } + object = document.all[layer]; + value = object.offsetTop; + while (object.tagName != 'BODY') { + object = object.offsetParent; + value += object.offsetTop; + } + } + return (value); +} + +function setWidth(layer, w) +{ + if (DOM) { + document.getElementById(layer).style.width = w; + } else if (NS4) { +// document.layers[layer].width = w; + } else { + document.all[layer].style.pixelWidth = w; + } +} + +function getOffsetWidth(layer) +{ + var value = 0; + if (DOM && !Opera56) { + value = document.getElementById(layer).offsetWidth; + } else if (NS4) { + value = document.layers[layer].document.width; + } else if (Opera56) { + value = document.getElementById(layer).style.pixelWidth; + } else { // IE4 IS SIMPLY A BASTARD !!! + if (document.all['IE4' + layer]) { + layer = 'IE4' + layer; + } + value = document.all[layer].offsetWidth; + } + return (value); +} + +function setHeight(layer, h) // unused, not tested +{ + if (DOM) { + document.getElementById(layer).style.height = h; + } else if (NS4) { +// document.layers[layer].height = h; + } else { + document.all[layer].style.pixelHeight = h; + } +} + +function getOffsetHeight(layer) +{ + var value = 0; + if (DOM && !Opera56) { + value = document.getElementById(layer).offsetHeight; + } else if (NS4) { + value = document.layers[layer].document.height; + } else if (Opera56) { + value = document.getElementById(layer).style.pixelHeight; + } else { // IE4 IS SIMPLY A BASTARD !!! + if (document.all['IE4' + layer]) { + layer = 'IE4' + layer; + } + value = document.all[layer].offsetHeight; + } + return (value); +} + +function getWindowWidth() +{ + var value = 0; + if ((DOM && !IE) || NS4 || Konqueror || Opera) { + value = window.innerWidth; +// } else if (NS4) { +// value = document.width; + } else { // IE + if (document.documentElement && document.documentElement.clientWidth) { + value = document.documentElement.clientWidth; + } else if (document.body) { + value = document.body.clientWidth; + } + } + if (isNaN(value)) { + value = window.innerWidth; + } + return (value); +} + +function getWindowXOffset() +{ + var value = 0; + if ((DOM && !IE) || NS4 || Konqueror || Opera) { + value = window.pageXOffset; + } else { // IE + if (document.documentElement && document.documentElement.scrollLeft) { + value = document.documentElement.scrollLeft; + } else if (document.body) { + value = document.body.scrollLeft; + } + } + return (value); +} + +function getWindowHeight() +{ + var value = 0; + if ((DOM && !IE) || NS4 || Konqueror || Opera) { + value = window.innerHeight; + } else { // IE + if (document.documentElement && document.documentElement.clientHeight) { + value = document.documentElement.clientHeight; + } else if (document.body) { + value = document.body.clientHeight; + } + } + if (isNaN(value)) { + value = window.innerHeight; + } + return (value); +} + +function getWindowYOffset() +{ + var value = 0; + if ((DOM && !IE) || NS4 || Konqueror || Opera) { + value = window.pageYOffset; + } else { // IE + if (document.documentElement && document.documentElement.scrollTop) { + value = document.documentElement.scrollTop; + } else if (document.body) { + value = document.body.scrollTop; + } + } + return (value); +} + diff --git a/html/include/layersmenu.js b/html/include/layersmenu.js new file mode 100644 index 000000000..5d29e5bf0 --- /dev/null +++ b/html/include/layersmenu.js @@ -0,0 +1,316 @@ +// PHP Layers Menu 3.2.0-rc (C) 2001-2004 Marco Pratesi - http://www.marcopratesi.it/ + +useTimeouts = 1; +timeoutLength = 1000; // time in ms; not significant if useTimeouts = 0; +shutdownOnClick = 0; + +loaded = 0; +layersMoved = 0; +layerPoppedUp = ''; + +timeoutFlag = 0; +if (Opera56 || IE4) { + useTimeouts = 0; +} +if (NS4 || Opera56 || IE4) { + shutdownOnClick = 1; +} + +currentY = 0; +function grabMouse(e) // for NS4 +{ + currentY = e.pageY; +} +if (NS4) { + document.captureEvents(Event.MOUSEDOWN | Event.MOUSEMOVE); + document.onmousemove = grabMouse; +} + +function seeThroughElements(show) +{ + if (show) { + foobar = 'visible'; + } else { + foobar = 'hidden'; + } + for (i=0; i windowWidth + windowXOffset) { + if (onRight + width1 - windowWidth - windowXOffset > windowXOffset - onLeft) { + onLeft = windowXOffset; + } else { + onRight = windowWidth + windowXOffset - width1; + } + } + if (back[father[menuName]]) { + if (onLeft < windowXOffset) { + back[menuName] = 0; + } else { + back[menuName] = 1; + } + } else { +//alert(onRight + ' - ' + width1 + ' - ' + windowWidth + ' - ' + windowXOffset); + if (onRight + width1 > windowWidth + windowXOffset) { + back[menuName] = 1; + } else { + back[menuName] = 0; + } + } + if (back[menuName]) { + setLeft(menuName, onLeft); + } else { + setLeft(menuName, onRight); + } + } + moveLayerY(menuName); // workaround needed for Mozilla < 1.4 for MS Windows +} + +function moveLayerY(menuName) +{ + if (!loaded || (isVisible(menuName) && menuName != layerPoppedUp)) { + return; + } + if (!layersMoved) { + moveLayers(); + layersMoved = 1; + } + if (!NS4) { + newY = getOffsetTop('ref' + menuName); + } else { + newY = currentY; + } + newY += menuTopShift; + layerHeight = getOffsetHeight(menuName); + windowHeight = getWindowHeight(); + windowYOffset = getWindowYOffset(); + if (newY + layerHeight > windowHeight + windowYOffset) { + if (layerHeight > windowHeight) { + newY = windowYOffset; + } else { + newY = windowHeight + windowYOffset - layerHeight; + } + } + if (Math.abs(getOffsetTop(menuName) - newY) > thresholdY) { + setTop(menuName, newY); + } +} + +function moveLayerX1(menuName, father) +{ + if (!lwidthDetected) { + return; + } + if (!Opera5 && !IE4) { + width1 = lwidth[menuName]; + } else if (Opera5) { + // Opera 5 stupidly and exaggeratedly overestimates layers widths + // hence we consider a default value equal to $abscissaStep + width1 = abscissaStep; + } + foobar = getOffsetLeft(father + menuName); +if (!IE4) { + windowWidth = getWindowWidth(); + windowXOffset = getWindowXOffset(); + if (foobar + width1 > windowWidth + windowXOffset) { + foobar = windowWidth + windowXOffset - width1; + } + if (foobar < windowXOffset) { + foobar = windowXOffset; + } +} + setLeft(menuName, foobar); +} + +function layersOverlap(layer, i) +{ + if (Konqueror22) { + return true; + } + +// xa1 = getOffsetLeft(layer); +//setLeft(layer, xa1); + xa1 = layerLeft[layer]; + xa2 = xa1 + getOffsetWidth(layer); +//setWidth(layer, xa2-xa1); +// ya1 = getOffsetTop(layer); +//setTop(layer, ya1); + ya1 = layerTop[layer]; + ya2 = ya1 + getOffsetHeight(layer); +//setHeight(layer, ya2-ya1); +//alert(':' + xa1 + ':' + xa2 + ':' + ya1 + ':' + ya2 + ':'); + + xb1 = toBeHiddenLeft[i]; + xb2 = xb1 + toBeHidden[i].offsetWidth; + yb1 = toBeHiddenTop[i]; + yb2 = yb1 + toBeHidden[i].offsetHeight; +//alert(':' + xb1 + ':' + xb2 + ':' + yb1 + ':' + yb2 + ':'); + + if(xb1>xa1) xa1=xb1; if(xb2ya1) ya1=yb1; if(yb2xa1 && ya2>ya1); +} + +function seeThroughWorkaround(menuName, on) +{ + for (i=0; i 0) { + seeThroughCoordinatesDetection(); + } +// moveLayers(); + layersMoved = 0; +} +window.onresize = resizeHandler; + +function yaresizeHandler() +{ + if (window.innerWidth != origWidth || window.innerHeight != origHeight) { + if (Konqueror22 || Opera5) { + window.location.reload(); // Opera 5 often fails this + } + origWidth = window.innerWidth; + origHeight = window.innerHeight; + resizeHandler(); + } + setTimeout('yaresizeHandler()', 500); +} +function loadHandler() +{ + if (Konqueror22 || Opera56) { + origWidth = window.innerWidth; + origHeight = window.innerHeight; + yaresizeHandler(); + } +} +window.onload = loadHandler; + +function fixieflm(menuName) +{ + if (DOM) { + setWidth(menuName, '100%'); + } else { // IE4 IS SIMPLY A BASTARD !!! + document.write(''); + document.write('
- {$Header} +
+ + + + + +
+ {$Header} + + {$HeaderDropDown} +
+
diff --git a/ihtml/themes/default/headers.tpl b/ihtml/themes/default/headers.tpl index 31af5cc35..d607f57a6 100644 --- a/ihtml/themes/default/headers.tpl +++ b/ihtml/themes/default/headers.tpl @@ -19,9 +19,12 @@ - - - - + + + + + + + diff --git a/include/class_MultiSelectWindow.inc b/include/class_MultiSelectWindow.inc index b7d4bb916..bc99ac9f1 100644 --- a/include/class_MultiSelectWindow.inc +++ b/include/class_MultiSelectWindow.inc @@ -13,6 +13,7 @@ class MultiSelectWindow{ var $string_Title = ""; var $string_ListHeader = ""; + var $string_ListDropDown= ""; var $string_Summary = ""; var $string_Information = ""; @@ -73,6 +74,33 @@ class MultiSelectWindow{ $this->array_Regexes[] = $arr; } + + function SetDropDownHeaderMenu($str) + { + $this->string_ListDropDown = $str; + } + + function GetDropDownHeaderMenu() + { + if(!empty($this->string_ListDropDown)){ + $mid = new LayersMenu(6, 7, 2, 1); + $mid->setImgwww("./images/"); + $mid->setIcondir("./images/"); + $mid->setDirroot("/storage/hickert/gosa/include/php_layers_menu/"); + $mid->setHorizontalMenuTpl('GOsa_MultiSelectHeader.ihtml'); + $mid->setMenuStructureString($this->string_ListDropDown); + $mid->parseStructureForMenu('menu'); + $mid->newHorizontalMenu('menu'); + $s = $mid->getHeader(); + $s.= $mid->getMenu('menu'); + $s.= $mid->getFooter('menu'); + return($s); + }else{ + return(""); + } + } + + /* Contrucktion */ function MultiSelectWindow(&$config, $filterName, $module) { @@ -172,15 +200,14 @@ class MultiSelectWindow{ $enable_back = FALSE; $enable_root = FALSE; } - + + $listhead =""; + /* Check if we are in users home department */ if(!count($deps) ||$this->selectedBase == get_base_from_people($ui->dn)){ $enable_home = FALSE; } - /* Create header with selected base */ - $listhead = "
"; - /* Draw root button */ if($enable_root){ $listhead .= " assign("Display_alphabet", $this->bool_DisplayAlpahabet); $smarty->assign("alphabet", generate_alphabet()); - $smarty->assign("Header" , $this->string_ListHeader ); + $smarty->assign("Header" , $this->string_ListHeader); + $smarty->assign("HeaderDropDown", $this->GetDropDownHeaderMenu()); $smarty->assign("Summary" , $this->string_Summary); $smarty->assign("Title" , $this->string_Title); $smarty->assign("Information" , $this->string_Information); diff --git a/include/class_location.inc b/include/class_location.inc index a614a33c9..f712da759 100644 --- a/include/class_location.inc +++ b/include/class_location.inc @@ -276,6 +276,13 @@ $class_mapping= array( "mailMethodSendmailCyrus" => "include/class_mail-methods-sendmail-cyrus.inc", "LDAP" => "include/class_ldap.inc", "log" => "include/class_log.inc", + "PlainMenu" => "include/php_layers_menu/lib/plainmenu.inc.php", + "PHPTreeMenu" => "include/php_layers_menu/lib/phptreemenu.inc.php", + "LayersMenu" => "include/php_layers_menu/lib/layersmenu.inc.php", + "Template_PHPLIB" => "include/php_layers_menu/lib/PHPLIB.php", + "TreeMenu" => "include/php_layers_menu/lib/treemenu.inc.php", + "LayersMenuCommon" => "include/php_layers_menu/lib/layersmenu-common.inc.php", + "ProcessLayersMenu" => "include/php_layers_menu/lib/layersmenu-process.inc.php", "hostActionQueue" => "include/class_hostActionQueue.inc", "Step_Ldap" => "setup/class_setupStep_Ldap.inc", "Step_Finish" => "setup/class_setupStep_Finish.inc", diff --git a/include/php_layers_menu/COPYING b/include/php_layers_menu/COPYING new file mode 100644 index 000000000..b1e3f5a26 --- /dev/null +++ b/include/php_layers_menu/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/include/php_layers_menu/lib/PHPLIB.php b/include/php_layers_menu/lib/PHPLIB.php new file mode 100644 index 000000000..11be7988d --- /dev/null +++ b/include/php_layers_menu/lib/PHPLIB.php @@ -0,0 +1,567 @@ + (original from PHPLIB) +// Bjoern Schotte (PEARification) +// Martin Jansen (PEAR conformance) +// +// $Id: PHPLIB.php,v 1.14 2003/06/11 06:03:32 bjoern Exp $ +// + +//require_once "PEAR.php"; + +/** + * Converted PHPLIB Template class + * + * For those who want to use PHPLIB's fine template class, + * here's a PEAR conforming class with the original PHPLIB + * template code from phplib-stable CVS. Original author + * was Kristian Koehntopp + * + * @author Bjoern Schotte + * @author Martin Jansen (PEAR conformance) + * @version 1.0 + */ +class Template_PHPLIB +{ + /** + * If set, echo assignments + * @var bool + */ + var $debug = false; + + /** + * $file[handle] = "filename"; + * @var array + */ + var $file = array(); + + /** + * fallback paths that should be defined in a child class + * @var array + */ + var $file_fallbacks = array(); + + /** + * Relative filenames are relative to this pathname + * @var string + */ + var $root = ""; + + /* + * $_varKeys[key] = "key" + * @var array + */ + var $_varKeys = array(); + + /** + * $_varVals[key] = "value"; + * @var array + */ + var $_varVals = array(); + + /** + * "remove" => remove undefined variables + * "comment" => replace undefined variables with comments + * "keep" => keep undefined variables + * @var string + */ + var $unknowns = "remove"; + + /** + * "yes" => halt, "report" => report error, continue, "no" => ignore error quietly + * @var string + */ + var $haltOnError = "report"; + + /** + * The last error message is retained here + * @var string + * @see halt + */ + var $_lastError = ""; + + + /** + * Constructor + * + * @access public + * @param string template root directory + * @param string how to handle unknown variables + * @param array fallback paths + */ + function Template_PHPLIB($root = ".", $unknowns = "remove", $fallback="") + { + $this->setRoot($root); + $this->setUnknowns($unknowns); + if (is_array($fallback)) $this->file_fallbacks = $fallback; + } + + /** + * Sets the template directory + * + * @access public + * @param string new template directory + * @return bool + */ + function setRoot($root) + { + if (!is_dir($root)) { + $this->halt("setRoot: $root is not a directory."); + return false; + } + + $this->root = $root; + + return true; + } + + /** + * What to do with unknown variables + * + * three possible values: + * + * - "remove" will remove unknown variables + * (don't use this if you define CSS in your page) + * - "comment" will replace undefined variables with comments + * - "keep" will keep undefined variables as-is + * + * @access public + * @param string unknowns + */ + function setUnknowns($unknowns = "keep") + { + $this->unknowns = $unknowns; + } + + /** + * Set appropriate template files + * + * With this method you set the template files you want to use. + * Either you supply an associative array with key/value pairs + * where the key is the handle for the filname and the value + * is the filename itself, or you define $handle as the file name + * handle and $filename as the filename if you want to define only + * one template. + * + * @access public + * @param mixed handle for a filename or array with handle/name value pairs + * @param string name of template file + * @return bool + */ + function setFile($handle, $filename = "") + { + if (!is_array($handle)) { + + if ($filename == "") { + $this->halt("setFile: For handle $handle filename is empty."); + return false; + } + + $this->file[$handle] = $this->_filename($filename); + + } else { + + reset($handle); + while (list($h, $f) = each($handle)) { + $this->file[$h] = $this->_filename($f); + } + } + } + + /** + * Set a block in the appropriate template handle + * + * By setting a block like that: + * + * <!-- BEGIN blockname --> + * html code + * <!-- END blockname --> + * + * you can easily do repeating HTML code, i.e. output + * database data nice formatted into a HTML table where + * each DB row is placed into a HTML table row which is + * defined in this block. + * It extracts the template $handle from $parent and places + * variable {$name} instead. + * + * @access public + * @param string parent handle + * @param string block name handle + * @param string variable substitution name + */ + function setBlock($parent, $handle, $name = "") + { + if (!$this->_loadFile($parent)) { + $this->halt("setBlock: unable to load $parent."); + return false; + } + + if ($name == "") { + $name = $handle; + } + + $str = $this->getVar($parent); + $reg = "/[ \t]*\s*?\n?(\s*.*?\n?)\s*\s*?\n?/sm"; + preg_match_all($reg, $str, $m); + $str = preg_replace($reg, "{" . "$name}", $str); + + if (isset($m[1][0])) $this->setVar($handle, $m[1][0]); + $this->setVar($parent, $str); + } + + /** + * Set corresponding substitutions for placeholders + * + * @access public + * @param string name of a variable that is to be defined or an array of variables with value substitution as key/value pairs + * @param string value of that variable + * @param boolean if true, the value is appended to the variable's existing value + */ + function setVar($varname, $value = "", $append = false) + { + if (!is_array($varname)) { + + if (!empty($varname)) + if ($this->debug) print "scalar: set *$varname* to *$value*
\n"; + + $this->_varKeys[$varname] = $this->_varname($varname); + ($append) ? $this->_varVals[$varname] .= $value : $this->_varVals[$varname] = $value; + + } else { + reset($varname); + + while (list($k, $v) = each($varname)) { + if (!empty($k)) + if ($this->debug) print "array: set *$k* to *$v*
\n"; + + $this->_varKeys[$k] = $this->_varname($k); + ($append) ? $this->_varVals[$k] .= $v : $this->_varVals[$k] = $v; + } + } + } + + /** + * Substitute variables in handle $handle + * + * @access public + * @param string name of handle + * @return mixed string substituted content of handle + */ + function subst($handle) + { + if (!$this->_loadFile($handle)) { + $this->halt("subst: unable to load $handle."); + return false; + } + + return @str_replace($this->_varKeys, $this->_varVals, $this->getVar($handle)); + } + + /** + * Same as subst but printing the result + * + * @access public + * @brother subst + * @param string handle of template + * @return bool always false + */ + function pSubst($handle) + { + print $this->subst($handle); + return false; + } + + /** + * Parse handle into target + * + * Parses handle $handle into $target, eventually + * appending handle at $target if $append is defined + * as TRUE. + * + * @access public + * @param string target handle to parse into + * @param string which handle should be parsed + * @param boolean append it to $target or not? + * @return string parsed handle + */ + function parse($target, $handle, $append = false) + { + if (!is_array($handle)) { + $str = $this->subst($handle); + + ($append) ? $this->setVar($target, $this->getVar($target) . $str) : $this->setVar($target, $str); + } else { + reset($handle); + + while (list(, $h) = each($handle)) { + $str = $this->subst($h); + $this->setVar($target, $str); + } + } + + return $str; + } + + /** + * Same as parse, but printing it. + * + * @access public + * @brother parse + * @param string target to parse into + * @param string handle which should be parsed + * @param should $handle be appended to $target? + * @return bool + */ + function pParse($target, $handle, $append = false) + { + print $this->finish($this->parse($target, $handle, $append)); + return false; + } + + /** + * Return all defined variables and their values + * + * @access public + * @return array with all defined variables and their values + */ + function getVars() + { + reset($this->_varKeys); + + while (list($k, ) = each($this->_varKeys)) { + $result[$k] = $this->getVar($k); + } + + return $result; + } + + /** + * Return one or more specific variable(s) with their values. + * + * @access public + * @param mixed array with variable names or one variable name as a string + * @return mixed array of variable names with their values or value of one specific variable + */ + function getVar($varname) + { + if (!is_array($varname)) { + if (isset($this->_varVals[$varname])) { + return $this->_varVals[$varname]; + } else { + return ""; + } + } else { + reset($varname); + + while (list($k, ) = each($varname)) { + $result[$k] = (isset($this->_varVals[$k])) ? $this->_varVals[$k] : ""; + } + + return $result; + } + } + + /** + * Get undefined values of a handle + * + * @access public + * @param string handle name + * @return mixed false if an error occured or the undefined values + */ + function getUndefined($handle) + { + if (!$this->_loadFile($handle)) { + $this->halt("getUndefined: unable to load $handle."); + return false; + } + + preg_match_all("/{([^ \t\r\n}]+)}/", $this->getVar($handle), $m); + $m = $m[1]; + if (!is_array($m)) { + return false; + } + + reset($m); + while (list(, $v) = each($m)) { + if (!isset($this->_varKeys[$v])) { + $result[$v] = $v; + } + } + + if (isset($result) && count($result)) { + return $result; + } else { + return false; + } + } + + /** + * Finish string + * + * @access public + * @param string string to finish + * @return finished, i.e. substituted string + */ + function finish($str) + { + switch ($this->unknowns) { + case "remove": + $str = preg_replace('/{[^ \t\r\n}]+}/', "", $str); + break; + + case "comment": + $str = preg_replace('/{([^ \t\r\n}]+)}/', "", $str); + break; + } + + return $str; + } + + /** + * Print variable to the browser + * + * @access public + * @param string name of variable to print + */ + function p($varname) + { + print $this->finish($this->getVar($varname)); + } + + /** + * Get finished variable + * + * @access public public + * @param string variable to get + * @return string string with finished variable + */ + function get($varname) + { + return $this->finish($this->getVar($varname)); + } + + /** + * Complete filename + * + * Complete filename, i.e. testing it for slashes + * + * @access private + * @param string filename to be completed + * @return string completed filename + */ + function _filename($filename) + { +// if (substr($filename, 0, 1) != "/") { +// $filename = $this->root."/".$filename; +// } + + if (file_exists($filename)) return $filename; + if (is_array($this->file_fallbacks) && count($this->file_fallbacks) > 0) { + reset($this->file_fallbacks); + while (list(,$v) = each($this->file_fallbacks)) { + if (file_exists($v.basename($filename))) return $v.basename($filename); + } + $this->halt(sprintf("filename: file %s does not exist in the fallback paths %s.",$filename,implode(",",$this->file_fallbacks))); + return false; + } else { + $this->halt(sprintf("filename: file %s does not exist.",$filename)); + return false; + } + + return $filename; + } + + /** + * Protect a replacement variable + * + * @access private + * @param string name of replacement variable + * @return string replaced variable + */ + function _varname($varname) + { + return "{".$varname."}"; + } + + /** + * load file defined by handle if it is not loaded yet + * + * @access private + * @param string handle + * @return bool FALSE if error, true if all is ok + */ + function _loadFile($handle) + { + if (isset($this->_varKeys[$handle]) and !empty($this->_varVals[$handle])) { + return true; + } + + if (!isset($this->file[$handle])) { + $this->halt("loadfile: $handle is not a valid handle."); + return false; + } + + $filename = $this->file[$handle]; + if (function_exists("file_get_contents")) { + $str = file_get_contents($filename); + } else { + if (!$fp = @fopen($filename,"r")) { + $this->halt("loadfile: couldn't open $filename"); + return false; + } + + $str = fread($fp,filesize($filename)); + fclose($fp); + } + + if ($str=='') { + $this->halt("loadfile: While loading $handle, $filename does not exist or is empty."); + return false; + } + + $this->setVar($handle, $str); + + return true; + } + + /** + * Error function. Halt template system with message to show + * + * @access public + * @param string message to show + * @return bool + */ + function halt($msg) + { + $this->_lastError = $msg; + + if ($this->haltOnError != "no") { +// return $this->haltMsg($msg); + $this->haltMsg($msg); + } + + if ($this->haltOnError == "yes") { + die("Halted."); + } + + return false; + } + + /** + * printf error message to show + * + * @access public + * @param string message to show + * @return object PEAR error object + */ + function haltMsg($msg) + { +// PEAR::raiseError(sprintf("Template Error: %s
\n", $msg)); + printf("Template Error: %s
\n", $msg); + } +} +?> diff --git a/include/php_layers_menu/lib/layersmenu-browser_detection.php b/include/php_layers_menu/lib/layersmenu-browser_detection.php new file mode 100644 index 000000000..e351fc57a --- /dev/null +++ b/include/php_layers_menu/lib/layersmenu-browser_detection.php @@ -0,0 +1,80 @@ + diff --git a/include/php_layers_menu/lib/layersmenu-common.inc.php b/include/php_layers_menu/lib/layersmenu-common.inc.php new file mode 100644 index 000000000..aebf55986 --- /dev/null +++ b/include/php_layers_menu/lib/layersmenu-common.inc.php @@ -0,0 +1,955 @@ + 'id', + 'parent_id' => 'parent_id', + 'text' => 'text', + 'href' => 'href', + 'title' => 'title', + 'icon' => 'icon', + 'target' => 'target', + 'orderfield' => 'orderfield', + 'expanded' => 'expanded' +); +/** +* Names of fields of the i18n table corresponding to $tableName +* @access private +* @var array +*/ +var $tableFields_i18n = array( + 'language' => 'language', + 'id' => 'id', + 'text' => 'text', + 'title' => 'title' +); +/** +* A temporary array to store data retrieved from the DB and to perform the depth-first search +* @access private +* @var array +*/ +var $_tmpArray = array(); + +/** +* The constructor method; it initializates the menu system +* @return void +*/ +function LayersMenuCommon() +{ + $this->_packageName = 'PHP Layers Menu'; + $this->version = '3.2.0-rc'; + $this->copyright = '(C) 2001-2004'; + $this->author = 'Marco Pratesi - http://www.marcopratesi.it/'; + + $this->prependedUrl = ''; + + $this->dirroot = './'; + $this->libjsdir = './libjs/'; + $this->imgdir = './menuimages/'; + $this->imgwww = 'menuimages/'; + $this->icondir = './menuicons/'; + $this->iconwww = 'menuicons/'; + $this->tpldir = './templates/'; + $this->menuStructure = ''; + $this->separator = '|'; + + $this->_nodesCount = 0; + $this->tree = array(); + $this->treecnt = array(); + $this->_maxLevel = array(); + $this->_firstLevelCnt = array(); + $this->_firstItem = array(); + $this->_lastItem = array(); +} + +/** +* The method to set the prepended URL +* @access public +* @return boolean +*/ +function setPrependedUrl($prependedUrl) +{ + // We do not perform any check + $this->prependedUrl = $prependedUrl; + return true; +} + +/** +* The method to set the dirroot directory +* @access public +* @return boolean +*/ +function setDirrootCommon($dirroot) +{ + if (!is_dir($dirroot)) { + $this->error("setDirroot: $dirroot is not a directory."); + return false; + } + if (substr($dirroot, -1) != '/') { + $dirroot .= '/'; + } + $oldlength = strlen($this->dirroot); + $foobar = strpos($this->libjsdir, $this->dirroot); + if (!($foobar === false || $foobar != 0)) { + $this->libjsdir = $dirroot . substr($this->libjsdir, $oldlength); + } + $foobar = strpos($this->imgdir, $this->dirroot); + if (!($foobar === false || $foobar != 0)) { + $this->imgdir = $dirroot . substr($this->imgdir, $oldlength); + } + $foobar = strpos($this->icondir, $this->dirroot); + if (!($foobar === false || $foobar != 0)) { + $this->icondir = $dirroot . substr($this->icondir, $oldlength); + } + $foobar = strpos($this->tpldir, $this->dirroot); + if (!($foobar === false || $foobar != 0)) { + $this->tpldir = $dirroot . substr($this->tpldir, $oldlength); + } + $this->dirroot = $dirroot; + return true; +} + +/** +* The method to set the libjsdir directory +* @access public +* @return boolean +*/ +function setLibjsdir($libjsdir) +{ + if ($libjsdir != '' && substr($libjsdir, -1) != '/') { + $libjsdir .= '/'; + } + if ($libjsdir == '' || substr($libjsdir, 0, 1) != '/') { + $foobar = strpos($libjsdir, $this->dirroot); + if ($foobar === false || $foobar != 0) { + $libjsdir = $this->dirroot . $libjsdir; + } + } + if (!is_dir($libjsdir)) { + $this->error("setLibjsdir: $libjsdir is not a directory."); + return false; + } + $this->libjsdir = $libjsdir; + return true; +} + +/** +* The method to set the imgdir directory +* @access public +* @return boolean +*/ +function setImgdir($imgdir) +{ + if ($imgdir != '' && substr($imgdir, -1) != '/') { + $imgdir .= '/'; + } + if ($imgdir == '' || substr($imgdir, 0, 1) != '/') { + $foobar = strpos($imgdir, $this->dirroot); + if ($foobar === false || $foobar != 0) { + $imgdir = $this->dirroot . $imgdir; + } + } + if (!is_dir($imgdir)) { + $this->error("setImgdir: $imgdir is not a directory."); + return false; + } + $this->imgdir = $imgdir; + return true; +} + +/** +* The method to set imgwww +* @access public +* @return void +*/ +function setImgwww($imgwww) +{ + if ($imgwww != '' && substr($imgwww, -1) != '/') { + $imgwww .= '/'; + } + $this->imgwww = $imgwww; +} + +/** +* The method to set the icondir directory +* @access public +* @return boolean +*/ +function setIcondir($icondir) +{ + if ($icondir != '' && substr($icondir, -1) != '/') { + $icondir .= '/'; + } + if ($icondir == '' || substr($icondir, 0, 1) != '/') { + $foobar = strpos($icondir, $this->dirroot); + if ($foobar === false || $foobar != 0) { + $icondir = $this->dirroot . $icondir; + } + } + if (!is_dir($icondir)) { + $this->error("setIcondir: $icondir is not a directory."); + return false; + } + $this->icondir = $icondir; + return true; +} + +/** +* The method to set iconwww +* @access public +* @return void +*/ +function setIconwww($iconwww) +{ + if ($iconwww != '' && substr($iconwww, -1) != '/') { + $iconwww .= '/'; + } + $this->iconwww = $iconwww; +} + +/** +* The method to set the iconsize array +* @access public +* @return void +*/ +function setIconsize($width, $height) +{ + $this->iconsize['width'] = ($width == (int) $width) ? $width : 0; + $this->iconsize['height'] = ($height == (int) $height) ? $height : 0; + $this->issetIconsize = true; +} + +/** +* The method to unset the iconsize array +* @access public +* @return void +*/ +function unsetIconsize() +{ + unset($this->iconsize['width']); + unset($this->iconsize['height']); + $this->issetIconsize = false; +} + +/** +* The method to set the tpldir directory +* @access public +* @return boolean +*/ +function setTpldirCommon($tpldir) +{ + if ($tpldir != '' && substr($tpldir, -1) != '/') { + $tpldir .= '/'; + } + if ($tpldir == '' || substr($tpldir, 0, 1) != '/') { + $foobar = strpos($tpldir, $this->dirroot); + if ($foobar === false || $foobar != 0) { + $tpldir = $this->dirroot . $tpldir; + } + } + if (!is_dir($tpldir)) { + $this->error("setTpldir: $tpldir is not a directory."); + return false; + } + $this->tpldir = $tpldir; + return true; +} + +/** +* The method to read the menu structure from a file +* @access public +* @param string $tree_file the menu structure file +* @return boolean +*/ +function setMenuStructureFile($tree_file) +{ + if (!($fd = fopen($tree_file, 'r'))) { + $this->error("setMenuStructureFile: unable to open file $tree_file."); + return false; + } + $this->menuStructure = ''; + while ($buffer = fgets($fd, 4096)) { + $buffer = ereg_replace(chr(13), '', $buffer); // Microsoft Stupidity Suppression + $this->menuStructure .= $buffer; + } + fclose($fd); + if ($this->menuStructure == '') { + $this->error("setMenuStructureFile: $tree_file is empty."); + return false; + } + return true; +} + +/** +* The method to set the menu structure passing it through a string +* @access public +* @param string $tree_string the menu structure string +* @return boolean +*/ +function setMenuStructureString($tree_string) +{ + $this->menuStructure = ereg_replace(chr(13), '', $tree_string); // Microsoft Stupidity Suppression + if ($this->menuStructure == '') { + $this->error('setMenuStructureString: empty string.'); + return false; + } + return true; +} + +/** +* The method to set the value of separator +* @access public +* @return void +*/ +function setSeparator($separator) +{ + $this->separator = $separator; +} + +/** +* The method to set parameters for the DB connection +* @access public +* @param string $dns Data Source Name: the connection string for PEAR DB +* @param bool $persistent DB connections are either persistent or not persistent +* @return boolean +*/ +function setDBConnParms($dsn, $persistent=false) +{ + if (!is_string($dsn)) { + $this->error('initdb: $dsn is not an string.'); + return false; + } + if (!is_bool($persistent)) { + $this->error('initdb: $persistent is not a boolean.'); + return false; + } + $this->dsn = $dsn; + $this->persistent = $persistent; + return true; +} + +/** +* The method to set the name of the table storing data describing the menu +* @access public +* @param string +* @return boolean +*/ +function setTableName($tableName) +{ + if (!is_string($tableName)) { + $this->error('setTableName: $tableName is not a string.'); + return false; + } + $this->tableName = $tableName; + return true; +} + +/** +* The method to set the name of the i18n table corresponding to $tableName +* @access public +* @param string +* @return boolean +*/ +function setTableName_i18n($tableName_i18n) +{ + if (!is_string($tableName_i18n)) { + $this->error('setTableName_i18n: $tableName_i18n is not a string.'); + return false; + } + $this->tableName_i18n = $tableName_i18n; + return true; +} + +/** +* The method to set names of fields of the table storing data describing the menu +* @access public +* @param array +* @return boolean +*/ +function setTableFields($tableFields) +{ + if (!is_array($tableFields)) { + $this->error('setTableFields: $tableFields is not an array.'); + return false; + } + if (count($tableFields) == 0) { + $this->error('setTableFields: $tableFields is a zero-length array.'); + return false; + } + reset ($tableFields); + while (list($key, $value) = each($tableFields)) { + $this->tableFields[$key] = ($value == '') ? "''" : $value; + } + return true; +} + +/** +* The method to set names of fields of the i18n table corresponding to $tableName +* @access public +* @param array +* @return boolean +*/ +function setTableFields_i18n($tableFields_i18n) +{ + if (!is_array($tableFields_i18n)) { + $this->error('setTableFields_i18n: $tableFields_i18n is not an array.'); + return false; + } + if (count($tableFields_i18n) == 0) { + $this->error('setTableFields_i18n: $tableFields_i18n is a zero-length array.'); + return false; + } + reset ($tableFields_i18n); + while (list($key, $value) = each($tableFields_i18n)) { + $this->tableFields_i18n[$key] = ($value == '') ? "''" : $value; + } + return true; +} + +/** +* The method to parse the current menu structure and correspondingly update related variables +* @access public +* @param string $menu_name the name to be attributed to the menu +* whose structure has to be parsed +* @return void +*/ +function parseStructureForMenu( + $menu_name = '' // non consistent default... + ) +{ + $this->_maxLevel[$menu_name] = 0; + $this->_firstLevelCnt[$menu_name] = 0; + $this->_firstItem[$menu_name] = $this->_nodesCount + 1; + $cnt = $this->_firstItem[$menu_name]; + $menuStructure = $this->menuStructure; + + /* *********************************************** */ + /* Partially based on a piece of code taken from */ + /* TreeMenu 1.1 - Bjorge Dijkstra (bjorge@gmx.net) */ + /* *********************************************** */ + + while ($menuStructure != '') { + $before_cr = strcspn($menuStructure, "\n"); + $buffer = substr($menuStructure, 0, $before_cr); + $menuStructure = substr($menuStructure, $before_cr+1); + if (substr($buffer, 0, 1) == '#') { + continue; // commented item line... + } + $tmp = rtrim($buffer); + $node = explode($this->separator, $tmp); + for ($i=count($node); $i<=6; $i++) { + $node[$i] = ''; + } + $this->tree[$cnt]['level'] = strlen($node[0]); + $this->tree[$cnt]['text'] = $node[1]; + $this->tree[$cnt]['href'] = $node[2]; + $this->tree[$cnt]['title'] = $node[3]; + $this->tree[$cnt]['icon'] = $node[4]; + $this->tree[$cnt]['target'] = $node[5]; + $this->tree[$cnt]['expanded'] = $node[6]; + $cnt++; + } + + /* *********************************************** */ + + $this->_lastItem[$menu_name] = count($this->tree); + $this->_nodesCount = $this->_lastItem[$menu_name]; + $this->tree[$this->_lastItem[$menu_name]+1]['level'] = 0; + $this->_postParse($menu_name); +} + +/** +* The method to parse the current menu table and correspondingly update related variables +* @access public +* @param string $menu_name the name to be attributed to the menu +* whose structure has to be parsed +* @param string $language i18n language; either omit it or pass +* an empty string ('') if you do not want to use any i18n table +* @return void +*/ +function scanTableForMenu( + $menu_name = '', // non consistent default... + $language = '' + ) +{ + $this->_maxLevel[$menu_name] = 0; + $this->_firstLevelCnt[$menu_name] = 0; + unset($this->tree[$this->_nodesCount+1]); + $this->_firstItem[$menu_name] = $this->_nodesCount + 1; +/* BEGIN BENCHMARK CODE +$time_start = $this->_getmicrotime(); +/* END BENCHMARK CODE */ + $db = DB::connect($this->dsn, $this->persistent); + if (DB::isError($db)) { + $this->error('scanTableForMenu: ' . $db->getMessage()); + } + $dbresult = $db->query(' + SELECT ' . + $this->tableFields['id'] . ' AS id, ' . + $this->tableFields['parent_id'] . ' AS parent_id, ' . + $this->tableFields['text'] . ' AS text, ' . + $this->tableFields['href'] . ' AS href, ' . + $this->tableFields['title'] . ' AS title, ' . + $this->tableFields['icon'] . ' AS icon, ' . + $this->tableFields['target'] . ' AS target, ' . + $this->tableFields['expanded'] . ' AS expanded + FROM ' . $this->tableName . ' + WHERE ' . $this->tableFields['id'] . ' <> 1 + ORDER BY ' . $this->tableFields['orderfield'] . ', ' . $this->tableFields['text'] . ' ASC + '); + $this->_tmpArray = array(); + while ($dbresult->fetchInto($row, DB_FETCHMODE_ASSOC)) { + $this->_tmpArray[$row['id']]['parent_id'] = $row['parent_id']; + $this->_tmpArray[$row['id']]['text'] = $row['text']; + $this->_tmpArray[$row['id']]['href'] = $row['href']; + $this->_tmpArray[$row['id']]['title'] = $row['title']; + $this->_tmpArray[$row['id']]['icon'] = $row['icon']; + $this->_tmpArray[$row['id']]['target'] = $row['target']; + $this->_tmpArray[$row['id']]['expanded'] = $row['expanded']; + } + if ($language != '') { + $dbresult = $db->query(' + SELECT ' . + $this->tableFields_i18n['id'] . ' AS id, ' . + $this->tableFields_i18n['text'] . ' AS text, ' . + $this->tableFields_i18n['title'] . ' AS title + FROM ' . $this->tableName_i18n . ' + WHERE ' . $this->tableFields_i18n['id'] . ' <> 1 + AND ' . $this->tableFields_i18n['language'] . ' = ' . "'$language'" . ' + '); + while ($dbresult->fetchInto($row, DB_FETCHMODE_ASSOC)) { + if (isset($this->_tmpArray[$row['id']])) { + $this->_tmpArray[$row['id']]['text'] = $row['text']; + $this->_tmpArray[$row['id']]['title'] = $row['title']; + } + } + } + unset($dbresult); + unset($row); + $this->_depthFirstSearch($menu_name, $this->_tmpArray, 1, 1); +/* BEGIN BENCHMARK CODE +$time_end = $this->_getmicrotime(); +$time = $time_end - $time_start; +print "TIME ELAPSED = $time\n
"; +/* END BENCHMARK CODE */ + $this->_lastItem[$menu_name] = count($this->tree); + $this->_nodesCount = $this->_lastItem[$menu_name]; + $this->tree[$this->_lastItem[$menu_name]+1]['level'] = 0; + $this->_postParse($menu_name); +} + +function _getmicrotime() +{ + list($usec, $sec) = explode(' ', microtime()); + return ((float) $usec + (float) $sec); +} + +/** +* Recursive method to perform the depth-first search of the tree data taken from the current menu table +* @access private +* @param string $menu_name the name to be attributed to the menu +* whose structure has to be parsed +* @param array $tmpArray the temporary array that stores data to perform +* the depth-first search +* @param integer $parent_id id of the item whose children have +* to be searched for +* @param integer $level the hierarchical level of children to be searched for +* @return void +*/ +function _depthFirstSearch($menu_name, $tmpArray, $parent_id=1, $level=1) +{ + reset ($tmpArray); + while (list($id, $foobar) = each($tmpArray)) { + if ($foobar['parent_id'] == $parent_id) { + unset($tmpArray[$id]); + unset($this->_tmpArray[$id]); + $cnt = count($this->tree) + 1; + $this->tree[$cnt]['level'] = $level; + $this->tree[$cnt]['text'] = $foobar['text']; + $this->tree[$cnt]['href'] = $foobar['href']; + $this->tree[$cnt]['title'] = $foobar['title']; + $this->tree[$cnt]['icon'] = $foobar['icon']; + $this->tree[$cnt]['target'] = $foobar['target']; + $this->tree[$cnt]['expanded'] = $foobar['expanded']; + $this->treecnt[$menu_name][$id] = $cnt; + unset($foobar); + if ($id != $parent_id) { + $this->_depthFirstSearch($menu_name, $this->_tmpArray, $id, $level+1); + } + } + } +} + +/** +* A method providing parsing needed after both file/string parsing and DB table parsing +* @access private +* @param string $menu_name the name of the menu for which the parsing +* has to be performed +* @return void +*/ +function _postParse( + $menu_name = '' // non consistent default... + ) +{ + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu + $this->tree[$cnt]['child_of_root_node'] = ($this->tree[$cnt]['level'] == 1); + $this->tree[$cnt]['parsed_text'] = stripslashes($this->tree[$cnt]['text']); + $this->tree[$cnt]['parsed_href'] = (ereg_replace(' ', '', $this->tree[$cnt]['href']) == '') ? '#' : $this->prependedUrl . $this->tree[$cnt]['href']; + $this->tree[$cnt]['parsed_title'] = ($this->tree[$cnt]['title'] == '') ? '' : ' title="' . stripslashes($this->tree[$cnt]['title']) . '"'; + $fooimg = $this->icondir . $this->tree[$cnt]['icon']; + if ($this->tree[$cnt]['icon'] != '' && (substr($this->tree[$cnt]['icon'], 0, 7) == 'http://' || substr($this->tree[$cnt]['icon'], 0, 8) == 'https://')) { + $this->tree[$cnt]['parsed_icon'] = $this->tree[$cnt]['icon']; + if ($this->issetIconsize) { + $this->tree[$cnt]['iconwidth'] = $this->iconsize['width']; + $this->tree[$cnt]['iconheight'] = $this->iconsize['height']; + } else { + $foobar = getimagesize($this->tree[$cnt]['icon']); + $this->tree[$cnt]['iconwidth'] = $foobar[0]; + $this->tree[$cnt]['iconheight'] = $foobar[1]; + } + } elseif ($this->tree[$cnt]['icon'] != '' && file_exists($fooimg)) { + $this->tree[$cnt]['parsed_icon'] = $this->iconwww . $this->tree[$cnt]['icon']; + if ($this->issetIconsize) { + $this->tree[$cnt]['iconwidth'] = $this->iconsize['width']; + $this->tree[$cnt]['iconheight'] = $this->iconsize['height']; + } else { + $foobar = getimagesize($fooimg); + $this->tree[$cnt]['iconwidth'] = $foobar[0]; + $this->tree[$cnt]['iconheight'] = $foobar[1]; + } + } else { + $this->tree[$cnt]['parsed_icon'] = ''; + } + $this->tree[$cnt]['parsed_target'] = ($this->tree[$cnt]['target'] == '') ? '' : ' target="' . $this->tree[$cnt]['target'] . '"'; +// $this->tree[$cnt]['expanded'] = ($this->tree[$cnt]['expanded'] == '') ? 0 : $this->tree[$cnt]['expanded']; + $this->_maxLevel[$menu_name] = max($this->_maxLevel[$menu_name], $this->tree[$cnt]['level']); + if ($this->tree[$cnt]['level'] == 1) { + $this->_firstLevelCnt[$menu_name]++; + } + } +} + +/** +* A method to replace strings in all URLs (hrefs) of a menu +* @access public +* @param string $menu_name the name of the menu for which the replacement +* has to be performed +* @param string $string the string to be replaced +* @param string $value the replacement string +* @return void +*/ +function replaceStringInUrls($menu_name, $string, $value) +{ + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu + $this->tree[$cnt]['parsed_href'] = str_replace($string, $value, $this->tree[$cnt]['parsed_href']); + } +} + +/** +* A method to set the same target for all links of a menu +* @access public +* @param string $menu_name the name of the menu for which the targets +* have to be set +* @param string $target the target to be set for all links +* of the $menu_name menu +* @return void +*/ +function setLinksTargets($menu_name, $target) +{ + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu + $this->tree[$cnt]['parsed_target'] = ' target="' . $target . '"'; + } +} + +/** +* A method to select the current item of $menu_name in terms of $cnt, i.e., very likely, in terms of its line number in the corresponding menu structure file (excluding from the count commented out lines, if any) +* @access public +* @param string $menu_name the name of the menu for which the current item +* has to be selected +* @param integer $count the line number of the current item +* in the corresponding menu structure file +* (excluding from the count commented out lines, if any) +* @return void +*/ +function setSelectedItemByCount($menu_name, $count) +{ + if ($count < 1) { + $this->error("setSelectedItemByCount: the \$count argument is $count, but \$count can not be lower than 1"); + return; + } + if ($count > $this->_lastItem[$menu_name] - $this->_firstItem[$menu_name] + 1) { + $this->error("setSelectedItemByCount: the \$count argument is $count and is larger than the number of items of the '$menu_name' menu"); + return; + } + $cnt = $this->_firstItem[$menu_name] + $count - 1; + $this->tree[$cnt]['selected'] = true; +} + +/** +* A method to select the current item of $menu_name in terms of the corresponding id (see the DB table structure); obviously, this method can be used only together with the DB support +* @access public +* @param string $menu_name the name of the menu for which the current item +* has to be selected +* @param integer $id the id of the current item in the corresponding DB table +* @return void +*/ +function setSelectedItemById($menu_name, $id) +{ + if (!isset($this->treecnt[$menu_name][$id])) { + $this->error("setSelectedItemById: there is not any item with \$id = $id in the '$menu_name' menu"); + return; + } + $cnt = $this->treecnt[$menu_name][$id]; + $this->tree[$cnt]['selected'] = true; +} + +/** +* A method to select the current item of $menu_name specifying a string that occurs in the current URL +* @access public +* @param string $menu_name the name of the menu for which the current item +* has to be selected +* @param string $url a string that occurs in the current URL +* @return void +*/ +function setSelectedItemByUrl($menu_name, $url) +{ + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu + if (!(strpos($this->tree[$cnt]['parsed_href'], $url) === false)) { + $this->tree[$cnt]['selected'] = true; + break; + } + } +} + +/** +* A method to select the current item of $menu_name specifying a regular expression that matches (a substring of) the current URL; just the same as the setSelectedItemByUrl() method, but using eregi() instead of strpos() +* @access public +* @param string $menu_name the name of the menu for which the current item +* has to be selected +* @param string $url_eregi the regular expression that matches +* (a substring of) the current URL +* @return void +*/ +function setSelectedItemByUrlEregi($menu_name, $url_eregi) +{ + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu + if (eregi($url_eregi, $this->tree[$cnt]['parsed_href'])) { + $this->tree[$cnt]['selected'] = true; + break; + } + } +} + +/** +* Method to handle errors +* @access private +* @param string $errormsg the error message +* @return void +*/ +function error($errormsg) +{ + print "LayersMenu Error: $errormsg
\n"; + if ($this->haltOnError == 'yes') { + die("Halted.
\n"); + } +} + +} /* END OF CLASS */ + +?> diff --git a/include/php_layers_menu/lib/layersmenu-process.inc.php b/include/php_layers_menu/lib/layersmenu-process.inc.php new file mode 100644 index 000000000..13033c945 --- /dev/null +++ b/include/php_layers_menu/lib/layersmenu-process.inc.php @@ -0,0 +1,158 @@ +LayersMenuCommon(); +} + +/** +* The method to set the dirroot directory +* @access public +* @return boolean +*/ +function setDirroot($dirroot) +{ + return $this->setDirrootCommon($dirroot); +} + +/** +* Method to output a menu structure corresponding to items of a menu +* @access public +* @param string $menu_name the name of the menu for which a menu structure +* has to be returned +* @param string $separator the character used in the menu structure format +* to separate fields of each item +* @return string +*/ +function getMenuStructure( + $menu_name = '', // non consistent default... + $separator = '|' + ) +{ + $menuStructure = ''; + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the menu + $menuStructure .= str_repeat('.', $this->tree[$cnt]['level']); + $menuStructure .= $separator; + $menuStructure .= $this->tree[$cnt]['text']; + $menuStructure .= $separator; + $menuStructure .= $this->tree[$cnt]['href']; + $menuStructure .= $separator; + $menuStructure .= $this->tree[$cnt]['title']; + $menuStructure .= $separator; + $menuStructure .= $this->tree[$cnt]['icon']; + $menuStructure .= $separator; + $menuStructure .= $this->tree[$cnt]['target']; + $menuStructure .= $separator; + $menuStructure .= $this->tree[$cnt]['expanded']; + $menuStructure .= "\n"; + } + return $menuStructure; +} + +/** +* Method to output a DB SQL dump corresponding to items of a menu +* @access public +* @param string $menu_name the name of the menu for which a DB SQL dump +* has to be returned +* @param string $db_type the type of DB to dump for; +* leave it either empty or not specified if you are using PHP < 5, +* as sqlite_escape_string() has been added in PHP 5; +* it has to be specified and set to 'sqlite' only if the dump +* has to be prepared for SQLite; it is not significant if != 'sqlite' +* @return string +*/ +function getSQLDump( + $menu_name = '', // non consistent default... + $db_type = '' + ) +{ + $SQLDump = ''; + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the menu + $current_node[$this->tree[$cnt]['level']] = $cnt; + if (!$this->tree[$cnt]['child_of_root_node']) { + $this->tree[$cnt]['father_node'] = $current_node[$this->tree[$cnt]['level']-1]; + } + $VALUES = ''; + $SQLDump .= 'INSERT INTO '; + $SQLDump .= $this->tableName; + $SQLDump .= ' ('; + $SQLDump .= $this->tableFields['id'] . ', '; + $VALUES .= "'" . 10*$cnt . "', "; + $SQLDump .= $this->tableFields['parent_id'] . ', '; + if (isset($this->tree[$cnt]['father_node']) && $this->tree[$cnt]['father_node'] != 0) { + $VALUES .= "'" . 10*$this->tree[$cnt]['father_node'] . "', "; + } else { + $VALUES .= "'1', "; + } + $SQLDump .= $this->tableFields['text'] . ', '; + $foobar = $this->tree[$cnt]['text']; + if ($foobar != '') { + if ($db_type != 'sqlite') { + $foobar = addslashes($foobar); + } else { + $foobar = sqlite_escape_string($foobar); + } + } + $VALUES .= "'$foobar', "; + $SQLDump .= $this->tableFields['href'] . ', '; + $VALUES .= "'" . $this->tree[$cnt]['href'] . "', "; + if ($this->tableFields['title'] != "''") { + $SQLDump .= $this->tableFields['title'] . ', '; + $foobar = $this->tree[$cnt]['title']; + if ($foobar != '') { + if ($db_type != 'sqlite') { + $foobar = addslashes($foobar); + } else { + $foobar = sqlite_escape_string($foobar); + } + } + $VALUES .= "'$foobar', "; + } + if ($this->tableFields['icon'] != "''") { + $SQLDump .= $this->tableFields['icon'] . ', '; + $VALUES .= "'" . $this->tree[$cnt]['icon'] . "', "; + } + if ($this->tableFields['target'] != "''") { + $SQLDump .= $this->tableFields['target'] . ', '; + $VALUES .= "'" . $this->tree[$cnt]['target'] . "', "; + } + if ($this->tableFields['orderfield'] != "''") { + $SQLDump .= $this->tableFields['orderfield'] . ', '; + $VALUES .= "'" . 10*$cnt . "', "; + } + if ($this->tableFields['expanded'] != "''") { + $SQLDump .= $this->tableFields['expanded'] . ', '; + $this->tree[$cnt]['expanded'] = (int) $this->tree[$cnt]['expanded']; + $VALUES .= "'" . $this->tree[$cnt]['expanded'] . "', "; + } + $SQLDump = substr($SQLDump, 0, -2); + $VALUES = substr($VALUES, 0, -2); + $SQLDump .= ") VALUES ($VALUES);\n"; + } + return $SQLDump; +} + +} /* END OF CLASS */ + +?> diff --git a/include/php_layers_menu/lib/layersmenu.inc.php b/include/php_layers_menu/lib/layersmenu.inc.php new file mode 100644 index 000000000..b110e9cf6 --- /dev/null +++ b/include/php_layers_menu/lib/layersmenu.inc.php @@ -0,0 +1,942 @@ +LayersMenuCommon(); + + $this->horizontalMenuTpl = $this->tpldir . 'layersmenu-horizontal_menu.ihtml'; + $this->verticalMenuTpl = $this->tpldir . 'layersmenu-vertical_menu.ihtml'; + $this->subMenuTpl = $this->tpldir . 'layersmenu-sub_menu.ihtml'; + + $this->header = ''; + $this->listl = ''; + $this->father_keys = ''; + $this->father_vals = ''; + $this->moveLayers = ''; + $this->_firstLevelMenu = array(); + $this->footer = ''; + + $this->transparentIcon = 'transparent.png'; + $this->_hasIcons = array(); + $this->forwardArrowImg['src'] = 'forward-arrow.png'; + $this->forwardArrowImg['width'] = 4; + $this->forwardArrowImg['height'] = 7; + $this->downArrowImg['src'] = 'down-arrow.png'; + $this->downArrowImg['width'] = 9; + $this->downArrowImg['height'] = 5; + $this->menuTopShift = $menuTopShift; + $this->menuRightShift = $menuRightShift; + $this->menuLeftShift = $menuLeftShift; + $this->thresholdY = $thresholdY; + $this->abscissaStep = $abscissaStep; +} + +/** +* The method to set the value of menuTopShift +* @access public +* @return void +*/ +function setMenuTopShift($menuTopShift) +{ + $this->menuTopShift = $menuTopShift; +} + +/** +* The method to set the value of menuRightShift +* @access public +* @return void +*/ +function setMenuRightShift($menuRightShift) +{ + $this->menuRightShift = $menuRightShift; +} + +/** +* The method to set the value of menuLeftShift +* @access public +* @return void +*/ +function setMenuLeftShift($menuLeftShift) +{ + $this->menuLeftShift = $menuLeftShift; +} + +/** +* The method to set the value of thresholdY +* @access public +* @return void +*/ +function setThresholdY($thresholdY) +{ + $this->thresholdY = $thresholdY; +} + +/** +* The method to set the value of abscissaStep +* @access public +* @return void +*/ +function setAbscissaStep($abscissaStep) +{ + $this->abscissaStep = $abscissaStep; +} + +/** +* The method to set the dirroot directory +* @access public +* @return boolean +*/ +function setDirroot($dirroot) +{ + $oldtpldir = $this->tpldir; + if ($foobar = $this->setDirrootCommon($dirroot)) { + $this->updateTpldir($oldtpldir); + } + return $foobar; +} + +/** +* The method to set the tpldir directory +* @access public +* @return boolean +*/ +function setTpldir($tpldir) +{ + $oldtpldir = $this->tpldir; + if ($foobar = $this->setTpldirCommon($tpldir)) { + $this->updateTpldir($oldtpldir); + } + return $foobar; +} + +/** +* The method to update the templates directory path to the new tpldir +* @access private +* @return void +*/ +function updateTpldir($oldtpldir) +{ + $oldlength = strlen($oldtpldir); + $foobar = strpos($this->horizontalMenuTpl, $oldtpldir); + if (!($foobar === false || $foobar != 0)) { + $this->horizontalMenuTpl = $this->tpldir . substr($this->horizontalMenuTpl, $oldlength); + } + $foobar = strpos($this->verticalMenuTpl, $oldtpldir); + if (!($foobar === false || $foobar != 0)) { + $this->verticalMenuTpl = $this->tpldir . substr($this->verticalMenuTpl, $oldlength); + } + $foobar = strpos($this->subMenuTpl, $oldtpldir); + if (!($foobar === false || $foobar != 0)) { + $this->subMenuTpl = $this->tpldir . substr($this->subMenuTpl, $oldlength); + } +} + +/** +* The method to set horizontalMenuTpl +* @access public +* @return boolean +*/ +function setHorizontalMenuTpl($horizontalMenuTpl) +{ + if (str_replace('/', '', $horizontalMenuTpl) == $horizontalMenuTpl) { + $horizontalMenuTpl = $this->tpldir . $horizontalMenuTpl; + } + if (!file_exists($horizontalMenuTpl)) { + $this->error("setHorizontalMenuTpl: file $horizontalMenuTpl does not exist."); + return false; + } + $this->horizontalMenuTpl = $horizontalMenuTpl; + return true; +} + +/** +* The method to set verticalMenuTpl +* @access public +* @return boolean +*/ +function setVerticalMenuTpl($verticalMenuTpl) +{ + if (str_replace('/', '', $verticalMenuTpl) == $verticalMenuTpl) { + $verticalMenuTpl = $this->tpldir . $verticalMenuTpl; + } + if (!file_exists($verticalMenuTpl)) { + $this->error("setVerticalMenuTpl: file $verticalMenuTpl does not exist."); + return false; + } + $this->verticalMenuTpl = $verticalMenuTpl; + return true; +} + +/** +* The method to set subMenuTpl +* @access public +* @return boolean +*/ +function setSubMenuTpl($subMenuTpl) +{ + if (str_replace('/', '', $subMenuTpl) == $subMenuTpl) { + $subMenuTpl = $this->tpldir . $subMenuTpl; + } + if (!file_exists($subMenuTpl)) { + $this->error("setSubMenuTpl: file $subMenuTpl does not exist."); + return false; + } + $this->subMenuTpl = $subMenuTpl; + return true; +} + +/** +* A method to set transparentIcon +* @access public +* @param string $transparentIcon a transparentIcon filename (without the path) +* @return void +*/ +function setTransparentIcon($transparentIcon) +{ + $this->transparentIcon = $transparentIcon; +} + +/** +* The method to set an image to be used for the forward arrow +* @access public +* @param string $forwardArrowImg the forward arrow image filename +* @return boolean +*/ +function setForwardArrowImg($forwardArrowImg) +{ + if (!file_exists($this->imgdir . $forwardArrowImg)) { + $this->error('setForwardArrowImg: file ' . $this->imgdir . $forwardArrowImg . ' does not exist.'); + return false; + } + $foobar = getimagesize($this->imgdir . $forwardArrowImg); + $this->forwardArrowImg['src'] = $forwardArrowImg; + $this->forwardArrowImg['width'] = $foobar[0]; + $this->forwardArrowImg['height'] = $foobar[1]; + return true; +} + +/** +* The method to set an image to be used for the down arrow +* @access public +* @param string $downArrowImg the down arrow image filename +* @return boolean +*/ +function setDownArrowImg($downArrowImg) +{ + if (!file_exists($this->imgdir . $downArrowImg)) { + $this->error('setDownArrowImg: file ' . $this->imgdir . $downArrowImg . ' does not exist.'); + return false; + } + $foobar = getimagesize($this->imgdir . $downArrowImg); + $this->downArrowImg['src'] = $downArrowImg; + $this->downArrowImg['width'] = $foobar[0]; + $this->downArrowImg['height'] = $foobar[1]; + return true; +} + +/** +* A method providing parsing needed both for horizontal and vertical menus; it can be useful also with the ProcessLayersMenu extended class +* @access public +* @param string $menu_name the name of the menu for which the parsing +* has to be performed +* @return void +*/ +function parseCommon( + $menu_name = '' // non consistent default... + ) +{ + $this->_hasIcons[$menu_name] = false; + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu + $this->_hasIcons[$cnt] = false; + $this->tree[$cnt]['layer_label'] = "L$cnt"; + $current_node[$this->tree[$cnt]['level']] = $cnt; + if (!$this->tree[$cnt]['child_of_root_node']) { + $this->tree[$cnt]['father_node'] = $current_node[$this->tree[$cnt]['level']-1]; + $this->father_keys .= ",'L$cnt'"; + $this->father_vals .= ",'" . $this->tree[$this->tree[$cnt]['father_node']]['layer_label'] . "'"; + } + $this->tree[$cnt]['not_a_leaf'] = ($this->tree[$cnt+1]['level']>$this->tree[$cnt]['level'] && $cnt<$this->_lastItem[$menu_name]); + // if the above condition is true, the node is not a leaf, + // hence it has at least a child; if it is false, the node is a leaf + if ($this->tree[$cnt]['not_a_leaf']) { + // initialize the corresponding layer content trought a void string + $this->tree[$cnt]['layer_content'] = ''; + // the new layer is accounted for in the layers list + $this->listl .= ",'" . $this->tree[$cnt]['layer_label'] . "'"; + } +/* + if ($this->tree[$cnt]['not_a_leaf']) { + $this->tree[$cnt]['parsed_href'] = '#'; + } +*/ + if ($this->tree[$cnt]['parsed_icon'] == '') { + $this->tree[$cnt]['iconsrc'] = $this->imgwww . $this->transparentIcon; + $this->tree[$cnt]['iconwidth'] = 16; + $this->tree[$cnt]['iconheight'] = 16; + $this->tree[$cnt]['iconalt'] = ' '; + } else { + if ($this->tree[$cnt]['level'] > 1) { + $this->_hasIcons[$this->tree[$cnt]['father_node']] = true; + } else { + $this->_hasIcons[$menu_name] = true; + } + $this->tree[$cnt]['iconsrc'] = $this->tree[$cnt]['parsed_icon']; + $this->tree[$cnt]['iconalt'] = 'O'; + } + } +} + +/** +* A method needed to update the footer both for horizontal and vertical menus +* @access private +* @param string $menu_name the name of the menu for which the updating +* has to be performed +* @return void +*/ +function _updateFooter( + $menu_name = '' // non consistent default... + ) +{ + $t = new Template_PHPLIB(); + $t->setFile('tplfile', $this->subMenuTpl); + $t->setBlock('tplfile', 'template', 'template_blck'); + $t->setBlock('template', 'sub_menu_cell', 'sub_menu_cell_blck'); + $t->setVar('sub_menu_cell_blck', ''); + $t->setBlock('template', 'separator', 'separator_blck'); + $t->setVar('separator_blck', ''); + $t->setVar('abscissaStep', $this->abscissaStep); + + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { + if ($this->tree[$cnt]['not_a_leaf']) { + $t->setVar(array( + 'layer_label' => $this->tree[$cnt]['layer_label'], + 'layer_title' => $this->tree[$cnt]['text'], + 'sub_menu_cell_blck' => $this->tree[$cnt]['layer_content'] + )); + $this->footer .= $t->parse('template_blck', 'template'); + } + } +} + +/** +* Method to preparare a horizontal menu. +* +* This method processes items of a menu to prepare the corresponding +* horizontal menu code updating many variables; it returns the code +* of the corresponding _firstLevelMenu +* +* @access public +* @param string $menu_name the name of the menu whose items have to be processed +* @return string +*/ +function newHorizontalMenu( + $menu_name = '' // non consistent default... + ) +{ + if (!isset($this->_firstItem[$menu_name]) || !isset($this->_lastItem[$menu_name])) { + $this->error("newHorizontalMenu: the first/last item of the menu '$menu_name' is not defined; please check if you have parsed its menu data."); + return 0; + } + + $this->parseCommon($menu_name); + + $t = new Template_PHPLIB(); + $t->setFile('tplfile', $this->horizontalMenuTpl); + $t->setBlock('tplfile', 'template', 'template_blck'); + $t->setBlock('template', 'horizontal_menu_cell', 'horizontal_menu_cell_blck'); + $t->setVar('horizontal_menu_cell_blck', ''); + $t->setBlock('horizontal_menu_cell', 'cell_link', 'cell_link_blck'); + $t->setVar('cell_link_blck', ''); + $t->setBlock('cell_link', 'cell_icon', 'cell_icon_blck'); + $t->setVar('cell_icon_blck', ''); + $t->setBlock('cell_link', 'cell_arrow', 'cell_arrow_blck'); + $t->setVar('cell_arrow_blck', ''); + + $t_sub = new Template_PHPLIB(); + $t_sub->setFile('tplfile', $this->subMenuTpl); + $t_sub->setBlock('tplfile', 'sub_menu_cell', 'sub_menu_cell_blck'); + $t_sub->setVar('sub_menu_cell_blck', ''); + $t_sub->setBlock('sub_menu_cell', 'cell_icon', 'cell_icon_blck'); + $t_sub->setVar('cell_icon_blck', ''); + $t_sub->setBlock('sub_menu_cell', 'cell_arrow', 'cell_arrow_blck'); + $t_sub->setVar('cell_arrow_blck', ''); + $t_sub->setBlock('tplfile', 'separator', 'separator_blck'); + $t_sub->setVar('separator_blck', ''); + + $this->_firstLevelMenu[$menu_name] = ''; + + $foobar = $this->_firstItem[$menu_name]; + $this->moveLayers .= "\tvar " . $menu_name . "TOP = getOffsetTop('" . $menu_name . "L" . $foobar . "');\n"; + $this->moveLayers .= "\tvar " . $menu_name . "HEIGHT = getOffsetHeight('" . $menu_name . "L" . $foobar . "');\n"; + + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu + if ($this->tree[$cnt]['not_a_leaf']) { + // geometrical parameters are assigned to the new layer, related to the above mentioned children + if ($this->tree[$cnt]['child_of_root_node']) { + $this->moveLayers .= "\tsetTop('" . $this->tree[$cnt]['layer_label'] . "', " . $menu_name . "TOP + " . $menu_name . "HEIGHT);\n"; + $this->moveLayers .= "\tmoveLayerX1('" . $this->tree[$cnt]['layer_label'] . "', '" . $menu_name . "');\n"; + } + } + + if ($this->tree[$cnt]['child_of_root_node']) { + if ($this->tree[$cnt]['text'] == '---') { + continue; + } + if ($this->tree[$cnt]['not_a_leaf']) { + $this->tree[$cnt]['onmouseover'] = ' onmouseover="moveLayerX1(' . "'" . $this->tree[$cnt]['layer_label'] . "', '" . $menu_name . "') ; LMPopUp('" . $this->tree[$cnt]['layer_label'] . "'" . ', false);"'; + } else { + $this->tree[$cnt]['onmouseover'] = ' onmouseover="shutdown();"'; + } + $t->setVar(array( + 'menu_layer_label' => $menu_name . $this->tree[$cnt]['layer_label'], + 'imgwww' => $this->imgwww, + 'transparent' => $this->transparentIcon, + 'href' => $this->tree[$cnt]['parsed_href'], + 'onmouseover' => $this->tree[$cnt]['onmouseover'], + 'title' => $this->tree[$cnt]['parsed_title'], + 'target' => $this->tree[$cnt]['parsed_target'], + 'text' => $this->tree[$cnt]['text'], + 'downsrc' => $this->downArrowImg['src'], + 'downwidth' => $this->downArrowImg['width'], + 'downheight' => $this->downArrowImg['height'] + )); + if ($this->tree[$cnt]['parsed_icon'] != '') { + $t->setVar(array( + 'iconsrc' => $this->tree[$cnt]['iconsrc'], + 'iconwidth' => $this->tree[$cnt]['iconwidth'], + 'iconheight' => $this->tree[$cnt]['iconheight'], + 'iconalt' => $this->tree[$cnt]['iconalt'], + )); + $t->parse('cell_icon_blck', 'cell_icon'); + } else { + $t->setVar('cell_icon_blck', ''); + } + if ($this->tree[$cnt]['not_a_leaf']) { + $t->parse('cell_arrow_blck', 'cell_arrow'); + } else { + $t->setVar('cell_arrow_blck', ''); + } + $foobar = $t->parse('cell_link_blck', 'cell_link'); + $t->setVar(array( + 'cellwidth' => $this->abscissaStep, + 'cell_link_blck' => $foobar + )); + $t->parse('horizontal_menu_cell_blck', 'horizontal_menu_cell', true); + } else { + if ($this->tree[$cnt]['text'] == '---') { + $this->tree[$this->tree[$cnt]['father_node']]['layer_content'] .= $t_sub->parse('separator_blck', 'separator'); + continue; + } + if ($this->tree[$cnt]['not_a_leaf']) { + $this->tree[$cnt]['onmouseover'] = ' onmouseover="moveLayerX(' . "'" . $this->tree[$cnt]['layer_label'] . "') ; moveLayerY('" . $this->tree[$cnt]['layer_label'] . "') ; LMPopUp('" . $this->tree[$cnt]['layer_label'] . "'". ', false);"'; + } else { + $this->tree[$cnt]['onmouseover'] = ' onmouseover="LMPopUp(' . "'" . $this->tree[$this->tree[$cnt]['father_node']]['layer_label'] . "'" . ', true);"'; + } + $t_sub->setVar(array( + 'imgwww' => $this->imgwww, + 'transparent' => $this->transparentIcon, + 'href' => $this->tree[$cnt]['parsed_href'], + 'refid' => 'ref' . $this->tree[$cnt]['layer_label'], + 'onmouseover' => $this->tree[$cnt]['onmouseover'], + 'title' => $this->tree[$cnt]['parsed_title'], + 'target' => $this->tree[$cnt]['parsed_target'], + 'text' => $this->tree[$cnt]['text'], + 'arrowsrc' => $this->forwardArrowImg['src'], + 'arrowwidth' => $this->forwardArrowImg['width'], + 'arrowheight' => $this->forwardArrowImg['height'] + )); + if ($this->_hasIcons[$this->tree[$cnt]['father_node']]) { + $t_sub->setVar(array( + 'iconsrc' => $this->tree[$cnt]['iconsrc'], + 'iconwidth' => $this->tree[$cnt]['iconwidth'], + 'iconheight' => $this->tree[$cnt]['iconheight'], + 'iconalt' => $this->tree[$cnt]['iconalt'] + )); + $t_sub->parse('cell_icon_blck', 'cell_icon'); + } else { + $t_sub->setVar('cell_icon_blck', ''); + } + if ($this->tree[$cnt]['not_a_leaf']) { + $t_sub->parse('cell_arrow_blck', 'cell_arrow'); + } else { + $t_sub->setVar('cell_arrow_blck', ''); + } + $this->tree[$this->tree[$cnt]['father_node']]['layer_content'] .= $t_sub->parse('sub_menu_cell_blck', 'sub_menu_cell'); + } + } // end of the "for" cycle scanning all nodes + + $foobar = $this->_firstLevelCnt[$menu_name] * $this->abscissaStep; + $t->setVar('menuwidth', $foobar); + $t->setVar(array( + 'layer_label' => $menu_name, + 'menubody' => $this->_firstLevelMenu[$menu_name] + )); + $this->_firstLevelMenu[$menu_name] = $t->parse('template_blck', 'template'); + + $this->_updateFooter($menu_name); + + return $this->_firstLevelMenu[$menu_name]; +} + +/** +* Method to preparare a vertical menu. +* +* This method processes items of a menu to prepare the corresponding +* vertical menu code updating many variables; it returns the code +* of the corresponding _firstLevelMenu +* +* @access public +* @param string $menu_name the name of the menu whose items have to be processed +* @return string +*/ +function newVerticalMenu( + $menu_name = '' // non consistent default... + ) +{ + if (!isset($this->_firstItem[$menu_name]) || !isset($this->_lastItem[$menu_name])) { + $this->error("newVerticalMenu: the first/last item of the menu '$menu_name' is not defined; please check if you have parsed its menu data."); + return 0; + } + + $this->parseCommon($menu_name); + + $t = new Template_PHPLIB(); + $t->setFile('tplfile', $this->verticalMenuTpl); + $t->setBlock('tplfile', 'template', 'template_blck'); + $t->setBlock('template', 'vertical_menu_box', 'vertical_menu_box_blck'); + $t->setVar('vertical_menu_box_blck', ''); + $t->setBlock('vertical_menu_box', 'vertical_menu_cell', 'vertical_menu_cell_blck'); + $t->setVar('vertical_menu_cell_blck', ''); + $t->setBlock('vertical_menu_cell', 'cell_icon', 'cell_icon_blck'); + $t->setVar('cell_icon_blck', ''); + $t->setBlock('vertical_menu_cell', 'cell_arrow', 'cell_arrow_blck'); + $t->setVar('cell_arrow_blck', ''); + $t->setBlock('vertical_menu_box', 'separator', 'separator_blck'); + $t->setVar('separator_blck', ''); + + $t_sub = new Template_PHPLIB(); + $t_sub->setFile('tplfile', $this->subMenuTpl); + $t_sub->setBlock('tplfile', 'sub_menu_cell', 'sub_menu_cell_blck'); + $t_sub->setVar('sub_menu_cell_blck', ''); + $t_sub->setBlock('sub_menu_cell', 'cell_icon', 'cell_icon_blck'); + $t_sub->setVar('cell_icon_blck', ''); + $t_sub->setBlock('sub_menu_cell', 'cell_arrow', 'cell_arrow_blck'); + $t_sub->setVar('cell_arrow_blck', ''); + $t_sub->setBlock('tplfile', 'separator', 'separator_blck'); + $t_sub->setVar('separator_blck', ''); + + $this->_firstLevelMenu[$menu_name] = ''; + + $this->moveLayers .= "\tvar " . $menu_name . "TOP = getOffsetTop('" . $menu_name . "');\n"; + $this->moveLayers .= "\tvar " . $menu_name . "LEFT = getOffsetLeft('" . $menu_name . "');\n"; + $this->moveLayers .= "\tvar " . $menu_name . "WIDTH = getOffsetWidth('" . $menu_name . "');\n"; + + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu + if ($this->tree[$cnt]['not_a_leaf']) { + // geometrical parameters are assigned to the new layer, related to the above mentioned children + if ($this->tree[$cnt]['child_of_root_node']) { + $this->moveLayers .= "\tsetLeft('" . $this->tree[$cnt]['layer_label'] . "', " . $menu_name . "LEFT + " . $menu_name . "WIDTH - menuRightShift);\n"; + } + } + + if ($this->tree[$cnt]['child_of_root_node']) { + if ($this->tree[$cnt]['text'] == '---') { + $this->_firstLevelMenu[$menu_name] .= $t->parse('separator_blck', 'separator'); + continue; + } + if ($this->tree[$cnt]['not_a_leaf']) { + $this->tree[$cnt]['onmouseover'] = ' onmouseover="moveLayerX(' . "'" . $this->tree[$cnt]['layer_label'] . "') ; moveLayerY('" . $this->tree[$cnt]['layer_label'] . "') ; LMPopUp('" . $this->tree[$cnt]['layer_label'] . "'" . ', false);"'; + } else { + $this->tree[$cnt]['onmouseover'] = ' onmouseover="shutdown();"'; + } + $t->setVar(array( + 'imgwww' => $this->imgwww, + 'transparent' => $this->transparentIcon, + 'href' => $this->tree[$cnt]['parsed_href'], + 'refid' => 'ref' . $this->tree[$cnt]['layer_label'], + 'onmouseover' => $this->tree[$cnt]['onmouseover'], + 'title' => $this->tree[$cnt]['parsed_title'], + 'target' => $this->tree[$cnt]['parsed_target'], + 'text' => $this->tree[$cnt]['text'], + 'arrowsrc' => $this->forwardArrowImg['src'], + 'arrowwidth' => $this->forwardArrowImg['width'], + 'arrowheight' => $this->forwardArrowImg['height'] + )); + if ($this->_hasIcons[$menu_name]) { + $t->setVar(array( + 'iconsrc' => $this->tree[$cnt]['iconsrc'], + 'iconwidth' => $this->tree[$cnt]['iconwidth'], + 'iconheight' => $this->tree[$cnt]['iconheight'], + 'iconalt' => $this->tree[$cnt]['iconalt'] + )); + $t->parse('cell_icon_blck', 'cell_icon'); + } else { + $t->setVar('cell_icon_blck', ''); + } + if ($this->tree[$cnt]['not_a_leaf']) { + $t->parse('cell_arrow_blck', 'cell_arrow'); + } else { + $t->setVar('cell_arrow_blck', ''); + } + $this->_firstLevelMenu[$menu_name] .= $t->parse('vertical_menu_cell_blck', 'vertical_menu_cell'); + } else { + if ($this->tree[$cnt]['text'] == '---') { + $this->tree[$this->tree[$cnt]['father_node']]['layer_content'] .= $t_sub->parse('separator_blck', 'separator'); + continue; + } + if ($this->tree[$cnt]['not_a_leaf']) { + $this->tree[$cnt]['onmouseover'] = ' onmouseover="moveLayerX(' . "'" . $this->tree[$cnt]['layer_label'] . "') ; moveLayerY('" . $this->tree[$cnt]['layer_label'] . "') ; LMPopUp('" . $this->tree[$cnt]['layer_label'] . "'" . ', false);"'; + } else { + $this->tree[$cnt]['onmouseover'] = ' onmouseover="LMPopUp(' . "'" . $this->tree[$this->tree[$cnt]['father_node']]['layer_label'] . "'" . ', true);"'; + } + $t_sub->setVar(array( + 'imgwww' => $this->imgwww, + 'transparent' => $this->transparentIcon, + 'href' => $this->tree[$cnt]['parsed_href'], + 'refid' => 'ref' . $this->tree[$cnt]['layer_label'], + 'onmouseover' => $this->tree[$cnt]['onmouseover'], + 'title' => $this->tree[$cnt]['parsed_title'], + 'target' => $this->tree[$cnt]['parsed_target'], + 'text' => $this->tree[$cnt]['text'], + 'arrowsrc' => $this->forwardArrowImg['src'], + 'arrowwidth' => $this->forwardArrowImg['width'], + 'arrowheight' => $this->forwardArrowImg['height'] + )); + if ($this->_hasIcons[$this->tree[$cnt]['father_node']]) { + $t_sub->setVar(array( + 'iconsrc' => $this->tree[$cnt]['iconsrc'], + 'iconwidth' => $this->tree[$cnt]['iconwidth'], + 'iconheight' => $this->tree[$cnt]['iconheight'], + 'iconalt' => $this->tree[$cnt]['iconalt'] + )); + $t_sub->parse('cell_icon_blck', 'cell_icon'); + } else { + $t_sub->setVar('cell_icon_blck', ''); + } + if ($this->tree[$cnt]['not_a_leaf']) { + $t_sub->parse('cell_arrow_blck', 'cell_arrow'); + } else { + $t_sub->setVar('cell_arrow_blck', ''); + } + $this->tree[$this->tree[$cnt]['father_node']]['layer_content'] .= $t_sub->parse('sub_menu_cell_blck', 'sub_menu_cell'); + } + } // end of the "for" cycle scanning all nodes + + $t->setVar(array( + 'menu_name' => $menu_name, + 'vertical_menu_cell_blck' => $this->_firstLevelMenu[$menu_name], + 'separator_blck' => '' + )); + $this->_firstLevelMenu[$menu_name] = $t->parse('vertical_menu_box_blck', 'vertical_menu_box'); + $t->setVar('abscissaStep', $this->abscissaStep); + $t->setVar(array( + 'layer_label' => $menu_name, + 'vertical_menu_box_blck' => $this->_firstLevelMenu[$menu_name] + )); + $this->_firstLevelMenu[$menu_name] = $t->parse('template_blck', 'template'); + + $this->_updateFooter($menu_name); + + return $this->_firstLevelMenu[$menu_name]; +} + +/** +* Method to prepare the header. +* +* This method obtains the header using collected informations +* and the suited JavaScript template; it returns the code of the header +* +* @access public +* @return string +*/ +function makeHeader() +{ + $t = new Template_PHPLIB(); + $this->listl = 'listl = [' . substr($this->listl, 1) . '];'; + $this->father_keys = 'father_keys = [' . substr($this->father_keys, 1) . '];'; + $this->father_vals = 'father_vals = [' . substr($this->father_vals, 1) . '];'; + $t->setFile('tplfile', $this->libjsdir . 'layersmenu-header.ijs'); + $t->setVar(array( + 'packageName' => $this->_packageName, + 'version' => $this->version, + 'copyright' => $this->copyright, + 'author' => $this->author, + 'menuTopShift' => $this->menuTopShift, + 'menuRightShift'=> $this->menuRightShift, + 'menuLeftShift' => $this->menuLeftShift, + 'thresholdY' => $this->thresholdY, + 'abscissaStep' => $this->abscissaStep, + 'listl' => $this->listl, + 'nodesCount' => $this->_nodesCount, + 'father_keys' => $this->father_keys, + 'father_vals' => $this->father_vals, + 'moveLayers' => $this->moveLayers + )); + $this->header = $t->parse('out', 'tplfile'); + $this->_headerHasBeenMade = true; + return $this->header; +} + +/** +* Method that returns the code of the header +* @access public +* @return string +*/ +function getHeader() +{ + if (!$this->_headerHasBeenMade) { + $this->makeHeader(); + } + return $this->header; +} + +/** +* Method that prints the code of the header +* @access public +* @return void +*/ +function printHeader() +{ + print $this->getHeader(); +} + +/** +* Method that returns the code of the requested _firstLevelMenu +* @access public +* @param string $menu_name the name of the menu whose _firstLevelMenu +* has to be returned +* @return string +*/ +function getMenu($menu_name) +{ + return $this->_firstLevelMenu[$menu_name]; +} + +/** +* Method that prints the code of the requested _firstLevelMenu +* @access public +* @param string $menu_name the name of the menu whose _firstLevelMenu +* has to be printed +* @return void +*/ +function printMenu($menu_name) +{ + print $this->_firstLevelMenu[$menu_name]; +} + +/** +* Method to prepare the footer. +* +* This method obtains the footer using collected informations +* and the suited JavaScript template; it returns the code of the footer +* +* @access public +* @return string +*/ +function makeFooter() +{ + $t = new Template_PHPLIB(); + $t->setFile('tplfile', $this->libjsdir . 'layersmenu-footer.ijs'); + $t->setVar(array( + 'packageName' => $this->_packageName, + 'version' => $this->version, + 'copyright' => $this->copyright, + 'author' => $this->author, + 'footer' => $this->footer + + )); + $this->footer = $t->parse('out', 'tplfile'); + $this->_footerHasBeenMade = true; + return $this->footer; +} + +/** +* Method that returns the code of the footer +* @access public +* @return string +*/ +function getFooter() +{ + if (!$this->_footerHasBeenMade) { + $this->makeFooter(); + } + return $this->footer; +} + +/** +* Method that prints the code of the footer +* @access public +* @return void +*/ +function printFooter() +{ + print $this->getFooter(); +} + +} /* END OF CLASS */ + +?> diff --git a/include/php_layers_menu/lib/phptreemenu.inc.php b/include/php_layers_menu/lib/phptreemenu.inc.php new file mode 100644 index 000000000..fb43d3599 --- /dev/null +++ b/include/php_layers_menu/lib/phptreemenu.inc.php @@ -0,0 +1,448 @@ +LayersMenuCommon(); + + $this->phpTreeMenuSeparator = '|'; + $this->phpTreeMenuDefaultExpansion = ''; + $this->phpTreeMenuImagesType = 'png'; + $this->phpTreeMenuTheme = ''; + $this->_phpTreeMenu = array(); +} + +/** +* The method to set the dirroot directory +* @access public +* @return boolean +*/ +function setDirroot($dirroot) +{ + return $this->setDirrootCommon($dirroot); +} + +/** +* The method to set the value of separator for the Tree Menu query string +* @access public +* @return void +*/ +function setPHPTreeMenuSeparator($phpTreeMenuSeparator) +{ + $this->phpTreeMenuSeparator = $phpTreeMenuSeparator; +} + +/** +* The method to set the default value of the expansion string for the PHP Tree Menu +* @access public +* @return void +*/ +function setPHPTreeMenuDefaultExpansion($phpTreeMenuDefaultExpansion) +{ + $this->phpTreeMenuDefaultExpansion = $phpTreeMenuDefaultExpansion; +} + +/** +* The method to set the type of images used for the Tree Menu +* @access public +* @return void +*/ +function setPHPTreeMenuImagesType($phpTreeMenuImagesType) +{ + $this->phpTreeMenuImagesType = $phpTreeMenuImagesType; +} + +/** +* The method to set the prefix for filenames of images of a theme +* @access public +* @return void +*/ +function setPHPTreeMenuTheme($phpTreeMenuTheme) +{ + $this->phpTreeMenuTheme = $phpTreeMenuTheme; +} + +/** +* Method to prepare a new PHP Tree Menu. +* +* This method processes items of a menu and parameters submitted +* through GET (i.e. nodes to be expanded) to prepare and return +* the corresponding Tree Menu code. +* +* @access public +* @param string $menu_name the name of the menu whose items have to be processed +* @return string +*/ +function newPHPTreeMenu( + $menu_name = '' // non consistent default... + ) +{ + $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://'; + $this_host = (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']; + if (isset($_SERVER['SCRIPT_NAME'])) { + $me = $_SERVER['SCRIPT_NAME']; + } elseif (isset($_SERVER['REQUEST_URI'])) { + $me = $_SERVER['REQUEST_URI']; + } elseif (isset($_SERVER['PHP_SELF'])) { + $me = $_SERVER['PHP_SELF']; + } elseif (isset($_SERVER['PATH_INFO'])) { + $me = $_SERVER['PATH_INFO']; + } + $url = $protocol . $this_host . $me; + $query = ''; + reset($_GET); + while (list($key, $value) = each($_GET)) { + if ($key != 'p' && $value != '') { + $query .= '&' . $key . '=' . $value; + } + } + if ($query != '') { + $query = '?' . substr($query, 5) . '&p='; + } else { + $query = '?p='; + } + $p = (isset($_GET['p'])) ? $_GET['p'] : $this->phpTreeMenuDefaultExpansion; + +/* ********************************************************* */ +/* Based on TreeMenu 1.1 by Bjorge Dijkstra (bjorge@gmx.net) */ +/* ********************************************************* */ + $this->_phpTreeMenu[$menu_name] = ''; + + $img_collapse = $this->imgwww . $this->phpTreeMenuTheme . 'tree_collapse.' . $this->phpTreeMenuImagesType; + $alt_collapse = '--'; + $img_collapse_corner = $this->imgwww . $this->phpTreeMenuTheme . 'tree_collapse_corner.' . $this->phpTreeMenuImagesType; + $alt_collapse_corner = '--'; + $img_collapse_corner_first = $this->imgwww . $this->phpTreeMenuTheme . 'tree_collapse_corner_first.' . $this->phpTreeMenuImagesType; + $alt_collapse_corner_first = '--'; + $img_collapse_first = $this->imgwww . $this->phpTreeMenuTheme . 'tree_collapse_first.' . $this->phpTreeMenuImagesType; + $alt_collapse_first = '--'; + $img_corner = $this->imgwww . $this->phpTreeMenuTheme . 'tree_corner.' . $this->phpTreeMenuImagesType; + $alt_corner = '`-'; + $img_expand = $this->imgwww . $this->phpTreeMenuTheme . 'tree_expand.' . $this->phpTreeMenuImagesType; + $alt_expand = '+-'; + $img_expand_corner = $this->imgwww . $this->phpTreeMenuTheme . 'tree_expand_corner.' . $this->phpTreeMenuImagesType; + $alt_expand_corner = '+-'; + $img_expand_corner_first = $this->imgwww . $this->phpTreeMenuTheme . 'tree_expand_corner_first.' . $this->phpTreeMenuImagesType; + $alt_expand_corner_first = '+-'; + $img_expand_first = $this->imgwww . $this->phpTreeMenuTheme . 'tree_expand_first.' . $this->phpTreeMenuImagesType; + $alt_expand_first = '+-'; + $img_folder_closed = $this->imgwww . $this->phpTreeMenuTheme . 'tree_folder_closed.' . $this->phpTreeMenuImagesType; + $alt_folder_closed = '->'; + $img_folder_open = $this->imgwww . $this->phpTreeMenuTheme . 'tree_folder_open.' . $this->phpTreeMenuImagesType; + $alt_folder_open = '->'; + $img_leaf = $this->imgwww . $this->phpTreeMenuTheme . 'tree_leaf.' . $this->phpTreeMenuImagesType; + $alt_leaf = '->'; + $img_space = $this->imgwww . $this->phpTreeMenuTheme . 'tree_space.' . $this->phpTreeMenuImagesType; + $alt_space = ' '; + $img_split = $this->imgwww . $this->phpTreeMenuTheme . 'tree_split.' . $this->phpTreeMenuImagesType; + $alt_split = '|-'; + $img_split_first = $this->imgwww . $this->phpTreeMenuTheme . 'tree_split_first.' . $this->phpTreeMenuImagesType; + $alt_split_first = '|-'; + $img_vertline = $this->imgwww . $this->phpTreeMenuTheme . 'tree_vertline.' . $this->phpTreeMenuImagesType; + $alt_vertline = '| '; + + for ($i=$this->_firstItem[$menu_name]; $i<=$this->_lastItem[$menu_name]; $i++) { + $expand[$i] = 0; + $visible[$i] = 0; + $this->tree[$i]['last_item'] = 0; + } + for ($i=0; $i<=$this->_maxLevel[$menu_name]; $i++) { + $levels[$i] = 0; + } + + // Get numbers of nodes to be expanded + if ($p != '') { + $explevels = explode($this->phpTreeMenuSeparator, $p); + $explevels_count = count($explevels); + for ($i=0; $i<$explevels_count; $i++) { + $expand[$explevels[$i]] = 1; + } + } + + // Find last nodes of subtrees + $last_level = $this->_maxLevel[$menu_name]; + for ($i=$this->_lastItem[$menu_name]; $i>=$this->_firstItem[$menu_name]; $i--) { + if ($this->tree[$i]['level'] < $last_level) { + for ($j=$this->tree[$i]['level']+1; $j<=$this->_maxLevel[$menu_name]; $j++) { + $levels[$j] = 0; + } + } + if ($levels[$this->tree[$i]['level']] == 0) { + $levels[$this->tree[$i]['level']] = 1; + $this->tree[$i]['last_item'] = 1; + } else { + $this->tree[$i]['last_item'] = 0; + } + $last_level = $this->tree[$i]['level']; + } + + // Determine visible nodes + // all root nodes are always visible + for ($i=$this->_firstItem[$menu_name]; $i<=$this->_lastItem[$menu_name]; $i++) { + if ($this->tree[$i]['level'] == 1) { + $visible[$i] = 1; + } + } + if (isset($explevels)) { + for ($i=0; $i<$explevels_count; $i++) { + $n = $explevels[$i]; + if ($n >= $this->_firstItem[$menu_name] && $n <= $this->_lastItem[$menu_name] && $visible[$n] == 1 && $expand[$n] == 1) { + $j = $n + 1; + while ($j<=$this->_lastItem[$menu_name] && $this->tree[$j]['level']>$this->tree[$n]['level']) { + if ($this->tree[$j]['level'] == $this->tree[$n]['level']+1) { + $visible[$j] = 1; + } + $j++; + } + } + } + } + + // Output nicely formatted tree + for ($i=0; $i<$this->_maxLevel[$menu_name]; $i++) { + $levels[$i] = 1; + } + $max_visible_level = 0; + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { + if ($visible[$cnt]) { + $max_visible_level = max($max_visible_level, $this->tree[$cnt]['level']); + } + } + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { + if ($this->tree[$cnt]['text'] == '---') { + continue; // separators are significant only for layers-based menus + } + + if (isset($this->tree[$cnt]['selected']) && $this->tree[$cnt]['selected']) { + $linkstyle = 'phplmselected'; + } else { + $linkstyle = 'phplm'; + } + + if ($visible[$cnt]) { + $this->_phpTreeMenu[$menu_name] .= '
' . "\n"; + + // vertical lines from higher levels + for ($i=0; $i<$this->tree[$cnt]['level']-1; $i++) { + if ($levels[$i] == 1) { + $img = $img_vertline; + $alt = $alt_vertline; + } else { + $img = $img_space; + $alt = $alt_space; + } + $this->_phpTreeMenu[$menu_name] .= '' . $alt . ''; + } + + $not_a_leaf = $cnt<$this->_lastItem[$menu_name] && $this->tree[$cnt+1]['level']>$this->tree[$cnt]['level']; + + if ($not_a_leaf) { + // Create expand/collapse parameters + $params = ''; + for ($i=$this->_firstItem[$menu_name]; $i<=$this->_lastItem[$menu_name]; $i++) { + if ($expand[$i] == 1 && $cnt!= $i || ($expand[$i] == 0 && $cnt == $i)) { + $params .= $this->phpTreeMenuSeparator . $i; + } + } + if ($params != '') { + $params = substr($params, 1); + } + } + + if ($this->tree[$cnt]['last_item'] == 1) { + // corner at end of subtree or t-split + if ($not_a_leaf) { + if ($expand[$cnt] == 0) { + if ($cnt == $this->_firstItem[$menu_name]) { + $img = $img_expand_corner_first; + $alt = $alt_expand_corner_first; + } else { + $img = $img_expand_corner; + $alt = $alt_expand_corner; + } + } else { + if ($cnt == $this->_firstItem[$menu_name]) { + $img = $img_collapse_corner_first; + $alt = $alt_collapse_corner_first; + } else { + $img = $img_collapse_corner; + $alt = $alt_collapse_corner; + } + } + $this->_phpTreeMenu[$menu_name] .= '' . $alt . ''; + } else { + $this->_phpTreeMenu[$menu_name] .= '' . $alt_corner . ''; + } + $levels[$this->tree[$cnt]['level']-1] = 0; + } else { + if ($not_a_leaf) { + if ($expand[$cnt] == 0) { + if ($cnt == $this->_firstItem[$menu_name]) { + $img = $img_expand_first; + $alt = $alt_expand_first; + } else { + $img = $img_expand; + $alt = $alt_expand; + } + } else { + if ($cnt == $this->_firstItem[$menu_name]) { + $img = $img_collapse_first; + $alt = $alt_collapse_first; + } else { + $img = $img_collapse; + $alt = $alt_collapse; + } + } + $this->_phpTreeMenu[$menu_name] .= '' . $alt . ''; + } else { + if ($cnt == $this->_firstItem[$menu_name]) { + $img = $img_split_first; + $alt = $alt_split_first; + } else { + $img = $img_split; + $alt = $alt_split; + } + $this->_phpTreeMenu[$menu_name] .= '' . $alt . ''; + } + $levels[$this->tree[$cnt]['level']-1] = 1; + } + + if ($this->tree[$cnt]['parsed_href'] == '' || $this->tree[$cnt]['parsed_href'] == '#') { + $a_href_open_img = ''; + $a_href_close_img = ''; + $a_href_open = ''; + $a_href_close = ''; + } else { + $a_href_open_img = 'tree[$cnt]['parsed_title'] . $this->tree[$cnt]['parsed_target'] . '>'; + $a_href_close_img = ''; + $a_href_open = 'tree[$cnt]['parsed_title'] . $this->tree[$cnt]['parsed_target'] . ' class="' . $linkstyle . '">'; + $a_href_close = ''; + } + + if ($not_a_leaf) { + if ($expand[$cnt] == 1) { + $img = $img_folder_open; + $alt = $alt_folder_open; + } else { + $img = $img_folder_closed; + $alt = $alt_folder_closed; + } + $this->_phpTreeMenu[$menu_name] .= $a_href_open_img . '' . $alt . '' . $a_href_close_img; + } else { + if ($this->tree[$cnt]['parsed_icon'] != '') { + $this->_phpTreeMenu[$menu_name] .= $a_href_open_img . '' . $alt_leaf . '' . $a_href_close_img; + } else { + $this->_phpTreeMenu[$menu_name] .= $a_href_open_img . '' . $alt_leaf . '' . $a_href_close_img; + } + } + + // output item text + $foobar = $max_visible_level - $this->tree[$cnt]['level'] + 1; + if ($foobar > 1) { + $colspan = ' colspan="' . $foobar . '"'; + } else { + $colspan = ''; + } + $this->_phpTreeMenu[$menu_name] .= ' ' . $a_href_open . $this->tree[$cnt]['parsed_text'] . $a_href_close . "\n"; + $this->_phpTreeMenu[$menu_name] .= '
' . "\n"; + } + } +/* ********************************************************* */ + +/* + $this->_phpTreeMenu[$menu_name] = + '
' . "\n" . + $this->_phpTreeMenu[$menu_name] . + '
' . "\n"; +*/ + // Some (old) browsers do not support the "white-space: nowrap;" CSS property... + $this->_phpTreeMenu[$menu_name] = + '' . "\n" . + '' . "\n" . + '' . "\n" . + '' . "\n" . + '
' . "\n" . + $this->_phpTreeMenu[$menu_name] . + '
' . "\n"; + + return $this->_phpTreeMenu[$menu_name]; +} + +/** +* Method that returns the code of the requested PHP Tree Menu +* @access public +* @param string $menu_name the name of the menu whose PHP Tree Menu code +* has to be returned +* @return string +*/ +function getPHPTreeMenu($menu_name) +{ + return $this->_phpTreeMenu[$menu_name]; +} + +/** +* Method that prints the code of the requested PHP Tree Menu +* @access public +* @param string $menu_name the name of the menu whose PHP Tree Menu code +* has to be printed +* @return void +*/ +function printPHPTreeMenu($menu_name) +{ + print $this->_phpTreeMenu[$menu_name]; +} + +} /* END OF CLASS */ + +?> diff --git a/include/php_layers_menu/lib/plainmenu.inc.php b/include/php_layers_menu/lib/plainmenu.inc.php new file mode 100644 index 000000000..0580f509b --- /dev/null +++ b/include/php_layers_menu/lib/plainmenu.inc.php @@ -0,0 +1,281 @@ +LayersMenuCommon(); + + $this->plainMenuTpl = $this->tpldir . 'layersmenu-plain_menu.ihtml'; + $this->_plainMenu = array(); + + $this->horizontalPlainMenuTpl = $this->tpldir . 'layersmenu-horizontal_plain_menu.ihtml'; + $this->_horizontalPlainMenu = array(); +} + +/** +* The method to set the dirroot directory +* @access public +* @return boolean +*/ +function setDirroot($dirroot) +{ + $oldtpldir = $this->tpldir; + if ($foobar = $this->setDirrootCommon($dirroot)) { + $this->updateTpldir($oldtpldir); + } + return $foobar; +} + +/** +* The method to set the tpldir directory +* @access public +* @return boolean +*/ +function setTpldir($tpldir) +{ + $oldtpldir = $this->tpldir; + if ($foobar = $this->setTpldirCommon($tpldir)) { + $this->updateTpldir($oldtpldir); + } + return $foobar; +} + +/** +* The method to update the templates directory path to the new tpldir +* @access private +* @return void +*/ +function updateTpldir($oldtpldir) +{ + $oldlength = strlen($oldtpldir); + $foobar = strpos($this->plainMenuTpl, $oldtpldir); + if (!($foobar === false || $foobar != 0)) { + $this->plainMenuTpl = $this->tpldir . substr($this->plainMenuTpl, $oldlength); + } + $foobar = strpos($this->horizontalPlainMenuTpl, $oldtpldir); + if (!($foobar === false || $foobar != 0)) { + $this->horizontalPlainMenuTpl = $this->tpldir . substr($this->horizontalPlainMenuTpl, $oldlength); + } +} + +/** +* The method to set plainMenuTpl +* @access public +* @return boolean +*/ +function setPlainMenuTpl($plainMenuTpl) +{ + if (str_replace('/', '', $plainMenuTpl) == $plainMenuTpl) { + $plainMenuTpl = $this->tpldir . $plainMenuTpl; + } + if (!file_exists($plainMenuTpl)) { + $this->error("setPlainMenuTpl: file $plainMenuTpl does not exist."); + return false; + } + $this->plainMenuTpl = $plainMenuTpl; + return true; +} + +/** +* Method to prepare a new Plain Menu. +* +* This method processes items of a menu to prepare and return +* the corresponding Plain Menu code. +* +* @access public +* @param string $menu_name the name of the menu whose items have to be processed +* @return string +*/ +function newPlainMenu( + $menu_name = '' // non consistent default... + ) +{ + $plain_menu_blck = ''; + $t = new Template_PHPLIB(); + $t->setFile('tplfile', $this->plainMenuTpl); + $t->setBlock('tplfile', 'template', 'template_blck'); + $t->setBlock('template', 'plain_menu_cell', 'plain_menu_cell_blck'); + $t->setVar('plain_menu_cell_blck', ''); + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { + if ($this->tree[$cnt]['text'] == '---') { + continue; // separators are significant only for layers-based menus + } + $nbsp = ''; + for ($i=1; $i<$this->tree[$cnt]['level']; $i++) { + $nbsp .= '   '; + } + $t->setVar(array( + 'nbsp' => $nbsp, + 'href' => $this->tree[$cnt]['parsed_href'], + 'title' => $this->tree[$cnt]['parsed_title'], + 'target' => $this->tree[$cnt]['parsed_target'], + 'text' => $this->tree[$cnt]['parsed_text'] + )); + $plain_menu_blck .= $t->parse('plain_menu_cell_blck', 'plain_menu_cell', false); + } + $t->setVar('plain_menu_cell_blck', $plain_menu_blck); + $this->_plainMenu[$menu_name] = $t->parse('template_blck', 'template'); + + return $this->_plainMenu[$menu_name]; +} + +/** +* Method that returns the code of the requested Plain Menu +* @access public +* @param string $menu_name the name of the menu whose Plain Menu code +* has to be returned +* @return string +*/ +function getPlainMenu($menu_name) +{ + return $this->_plainMenu[$menu_name]; +} + +/** +* Method that prints the code of the requested Plain Menu +* @access public +* @param string $menu_name the name of the menu whose Plain Menu code +* has to be printed +* @return void +*/ +function printPlainMenu($menu_name) +{ + print $this->_plainMenu[$menu_name]; +} + +/** +* The method to set horizontalPlainMenuTpl +* @access public +* @return boolean +*/ +function setHorizontalPlainMenuTpl($horizontalPlainMenuTpl) +{ + if (str_replace('/', '', $horizontalPlainMenuTpl) == $horizontalPlainMenuTpl) { + $horizontalPlainMenuTpl = $this->tpldir . $horizontalPlainMenuTpl; + } + if (!file_exists($horizontalPlainMenuTpl)) { + $this->error("setHorizontalPlainMenuTpl: file $horizontalPlainMenuTpl does not exist."); + return false; + } + $this->horizontalPlainMenuTpl = $horizontalPlainMenuTpl; + return true; +} + +/** +* Method to prepare a new Horizontal Plain Menu. +* +* This method processes items of a menu to prepare and return +* the corresponding Horizontal Plain Menu code. +* +* @access public +* @param string $menu_name the name of the menu whose items have to be processed +* @return string +*/ +function newHorizontalPlainMenu( + $menu_name = '' // non consistent default... + ) +{ + $horizontal_plain_menu_blck = ''; + $t = new Template_PHPLIB(); + $t->setFile('tplfile', $this->horizontalPlainMenuTpl); + $t->setBlock('tplfile', 'template', 'template_blck'); + $t->setBlock('template', 'horizontal_plain_menu_cell', 'horizontal_plain_menu_cell_blck'); + $t->setVar('horizontal_plain_menu_cell_blck', ''); + $t->setBlock('horizontal_plain_menu_cell', 'plain_menu_cell', 'plain_menu_cell_blck'); + $t->setVar('plain_menu_cell_blck', ''); + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { + if ($this->tree[$cnt]['text'] == '---') { + continue; // separators are significant only for layers-based menus + } + if ($this->tree[$cnt]['level'] == 1 && $cnt > $this->_firstItem[$menu_name]) { + $t->parse('horizontal_plain_menu_cell_blck', 'horizontal_plain_menu_cell', true); + $t->setVar('plain_menu_cell_blck', ''); + } + $nbsp = ''; + for ($i=1; $i<$this->tree[$cnt]['level']; $i++) { + $nbsp .= '   '; + } + $t->setVar(array( + 'nbsp' => $nbsp, + 'href' => $this->tree[$cnt]['parsed_href'], + 'title' => $this->tree[$cnt]['parsed_title'], + 'target' => $this->tree[$cnt]['parsed_target'], + 'text' => $this->tree[$cnt]['parsed_text'] + )); + $t->parse('plain_menu_cell_blck', 'plain_menu_cell', true); + } + $t->parse('horizontal_plain_menu_cell_blck', 'horizontal_plain_menu_cell', true); + $this->_horizontalPlainMenu[$menu_name] = $t->parse('template_blck', 'template'); + + return $this->_horizontalPlainMenu[$menu_name]; +} + +/** +* Method that returns the code of the requested Horizontal Plain Menu +* @access public +* @param string $menu_name the name of the menu whose Horizontal Plain Menu code +* has to be returned +* @return string +*/ +function getHorizontalPlainMenu($menu_name) +{ + return $this->_horizontalPlainMenu[$menu_name]; +} + +/** +* Method that prints the code of the requested Horizontal Plain Menu +* @access public +* @param string $menu_name the name of the menu whose Horizontal Plain Menu code +* has to be printed +* @return void +*/ +function printHorizontalPlainMenu($menu_name) +{ + print $this->_horizontalPlainMenu[$menu_name]; +} + +} /* END OF CLASS */ + +?> diff --git a/include/php_layers_menu/lib/treemenu.inc.php b/include/php_layers_menu/lib/treemenu.inc.php new file mode 100644 index 000000000..a15a5f83f --- /dev/null +++ b/include/php_layers_menu/lib/treemenu.inc.php @@ -0,0 +1,352 @@ +LayersMenuCommon(); + + $this->treeMenuImagesType = 'png'; + $this->treeMenuTheme = ''; + $this->_treeMenu = array(); + + $this->_nodesCount = 0; + $this->tree = array(); + $this->_maxLevel = array(); + $this->_firstLevelCnt = array(); + $this->_firstItem = array(); + $this->_lastItem = array(); +} + +/** +* The method to set the dirroot directory +* @access public +* @return boolean +*/ +function setDirroot($dirroot) +{ + return $this->setDirrootCommon($dirroot); +} + +/** +* The method to set the type of images used for the Tree Menu +* @access public +* @return void +*/ +function setTreeMenuImagesType($treeMenuImagesType) +{ + $this->treeMenuImagesType = $treeMenuImagesType; +} + +/** +* The method to set the prefix for filenames of images of a theme +* @access public +* @return void +*/ +function setTreeMenuTheme($treeMenuTheme) +{ + $this->treeMenuTheme = $treeMenuTheme; +} + +/** +* Method to prepare a new Tree Menu. +* +* This method processes items of a menu to prepare and return +* the corresponding Tree Menu code. +* +* @access public +* @param string $menu_name the name of the menu whose items have to be processed +* @return string +*/ +function newTreeMenu( + $menu_name = '' // non consistent default... + ) +{ + if (!isset($this->_firstItem[$menu_name]) || !isset($this->_lastItem[$menu_name])) { + $this->error("newTreeMenu: the first/last item of the menu '$menu_name' is not defined; please check if you have parsed its menu data."); + return 0; + } + + $this->_treeMenu[$menu_name] = ''; + + $img_collapse = $this->imgwww . $this->treeMenuTheme . 'tree_collapse.' . $this->treeMenuImagesType; + $alt_collapse = '--'; + $img_collapse_corner = $this->imgwww . $this->treeMenuTheme . 'tree_collapse_corner.' . $this->treeMenuImagesType; + $alt_collapse_corner = '--'; + $img_collapse_corner_first = $this->imgwww . $this->treeMenuTheme . 'tree_collapse_corner_first.' . $this->treeMenuImagesType; + $alt_collapse_corner_first = '--'; + $img_collapse_first = $this->imgwww . $this->treeMenuTheme . 'tree_collapse_first.' . $this->treeMenuImagesType; + $alt_collapse_first = '--'; + $img_corner = $this->imgwww . $this->treeMenuTheme . 'tree_corner.' . $this->treeMenuImagesType; + $alt_corner = '`-'; + $img_expand = $this->imgwww . $this->treeMenuTheme . 'tree_expand.' . $this->treeMenuImagesType; + $alt_expand = '+-'; + $img_expand_corner = $this->imgwww . $this->treeMenuTheme . 'tree_expand_corner.' . $this->treeMenuImagesType; + $alt_expand_corner = '+-'; + $img_expand_corner_first = $this->imgwww . $this->treeMenuTheme . 'tree_expand_corner_first.' . $this->treeMenuImagesType; + $alt_expand_corner_first = '+-'; + $img_expand_first = $this->imgwww . $this->treeMenuTheme . 'tree_expand_first.' . $this->treeMenuImagesType; + $alt_expand_first = '+-'; + $img_folder_closed = $this->imgwww . $this->treeMenuTheme . 'tree_folder_closed.' . $this->treeMenuImagesType; + $alt_folder_closed = '->'; + $img_folder_open = $this->imgwww . $this->treeMenuTheme . 'tree_folder_open.' . $this->treeMenuImagesType; + $alt_folder_open = '->'; + $img_leaf = $this->imgwww . $this->treeMenuTheme . 'tree_leaf.' . $this->treeMenuImagesType; + $alt_leaf = '->'; + $img_space = $this->imgwww . $this->treeMenuTheme . 'tree_space.' . $this->treeMenuImagesType; + $alt_space = ' '; + $img_split = $this->imgwww . $this->treeMenuTheme . 'tree_split.' . $this->treeMenuImagesType; + $alt_split = '|-'; + $img_split_first = $this->imgwww . $this->treeMenuTheme . 'tree_split_first.' . $this->treeMenuImagesType; + $alt_split_first = '|-'; + $img_vertline = $this->imgwww . $this->treeMenuTheme . 'tree_vertline.' . $this->treeMenuImagesType; + $alt_vertline = '| '; + + for ($i=0; $i<=$this->_maxLevel[$menu_name]; $i++) { + $levels[$i] = 0; + } + + // Find last nodes of subtrees + $last_level = $this->_maxLevel[$menu_name]; + for ($i=$this->_lastItem[$menu_name]; $i>=$this->_firstItem[$menu_name]; $i--) { + if ($this->tree[$i]['level'] < $last_level) { + for ($j=$this->tree[$i]['level']+1; $j<=$this->_maxLevel[$menu_name]; $j++) { + $levels[$j] = 0; + } + } + if ($levels[$this->tree[$i]['level']] == 0) { + $levels[$this->tree[$i]['level']] = 1; + $this->tree[$i]['last_item'] = 1; + } else { + $this->tree[$i]['last_item'] = 0; + } + $last_level = $this->tree[$i]['level']; + } + + $toggle = ''; + $toggle_function_name = 'toggle' . $menu_name; + + for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { + if ($this->tree[$cnt]['text'] == '---') { + continue; // separators are significant only for layers-based menus + } + + if (isset($this->tree[$cnt]['selected']) && $this->tree[$cnt]['selected']) { + $linkstyle = 'phplmselected'; + } else { + $linkstyle = 'phplm'; + } + + $this->_treeMenu[$menu_name] .= '
' . "\n"; + + // vertical lines from higher levels + for ($i=0; $i<$this->tree[$cnt]['level']-1; $i++) { + if ($levels[$i] == 1) { + $img = $img_vertline; + $alt = $alt_vertline; + } else { + $img = $img_space; + $alt = $alt_space; + } + $this->_treeMenu[$menu_name] .= '' . $alt . ''; + } + + $not_a_leaf = $cnt<$this->_lastItem[$menu_name] && $this->tree[$cnt+1]['level']>$this->tree[$cnt]['level']; + + if ($this->tree[$cnt]['last_item'] == 1) { + // corner at end of subtree or t-split + if ($not_a_leaf) { + if ($cnt == $this->_firstItem[$menu_name]) { + $img = $img_collapse_corner_first; + $alt = $alt_collapse_corner_first; + } else { + $img = $img_collapse_corner; + $alt = $alt_collapse_corner; + } + $this->_treeMenu[$menu_name] .= '' . $alt . ''; + } else { + $this->_treeMenu[$menu_name] .= '' . $alt_corner . ''; + } + $levels[$this->tree[$cnt]['level']-1] = 0; + } else { + if ($not_a_leaf) { + if ($cnt == $this->_firstItem[$menu_name]) { + $img = $img_collapse_first; + $alt = $alt_collapse_first; + } else { + $img = $img_collapse; + $alt = $alt_collapse; + } + $this->_treeMenu[$menu_name] .= '' . $alt . ''; + } else { + if ($cnt == $this->_firstItem[$menu_name]) { + $img = $img_split_first; + $alt = $alt_split_first; + } else { + $img = $img_split; + $alt = $alt_split; + } + $this->_treeMenu[$menu_name] .= '' . $alt . ''; + } + $levels[$this->tree[$cnt]['level']-1] = 1; + } + + if ($this->tree[$cnt]['parsed_href'] == '' || $this->tree[$cnt]['parsed_href'] == '#') { + $a_href_open_img = ''; + $a_href_close_img = ''; + $a_href_open = ''; + $a_href_close = ''; + } else { + $a_href_open_img = 'tree[$cnt]['parsed_title'] . $this->tree[$cnt]['parsed_target'] . '>'; + $a_href_close_img = ''; + $a_href_open = 'tree[$cnt]['parsed_title'] . $this->tree[$cnt]['parsed_target'] . ' class="' . $linkstyle . '">'; + $a_href_close = ''; + } + + if ($not_a_leaf) { + $this->_treeMenu[$menu_name] .= $a_href_open_img . '' . $alt_folder_open . '' . $a_href_close_img; + } else { + if ($this->tree[$cnt]['parsed_icon'] != '') { + $this->_treeMenu[$menu_name] .= $a_href_open_img . '' . $alt_leaf . '' . $a_href_close_img; + } else { + $this->_treeMenu[$menu_name] .= $a_href_open_img . '' . $alt_leaf . '' . $a_href_close_img; + } + } + $this->_treeMenu[$menu_name] .= ' ' . $a_href_open . $this->tree[$cnt]['text'] . $a_href_close . "\n"; + $this->_treeMenu[$menu_name] .= '
' . "\n"; + + if ($cnt<$this->_lastItem[$menu_name] && $this->tree[$cnt]['level']<$this->tree[$cnt+1]['level']) { + $this->_treeMenu[$menu_name] .= '
' . "\n"; + if ($this->tree[$cnt]['expanded'] != 1) { + $toggle .= 'if (phplm_expand[' . $cnt . '] != 1) ' . $toggle_function_name . "('" . $cnt . "');\n"; + } else { + $toggle .= 'if (phplm_collapse[' . $cnt . '] == 1) ' . $toggle_function_name . "('" . $cnt . "');\n"; + } + } + + if ($cnt>$this->_firstItem[$menu_name] && $this->tree[$cnt]['level']>$this->tree[$cnt+1]['level']) { + for ($i=max(1, $this->tree[$cnt+1]['level']); $i<$this->tree[$cnt]['level']; $i++) { + $this->_treeMenu[$menu_name] .= '
' . "\n"; + } + } + } + +/* + $this->_treeMenu[$menu_name] = + '
' . "\n" . + $this->_treeMenu[$menu_name] . + '
' . "\n"; +*/ + // Some (old) browsers do not support the "white-space: nowrap;" CSS property... + $this->_treeMenu[$menu_name] = + '' . "\n" . + '' . "\n" . + '' . "\n" . + '' . "\n" . + '
' . "\n" . + $this->_treeMenu[$menu_name] . + '
' . "\n"; + + $t = new Template_PHPLIB(); + $t->setFile('tplfile', $this->libjsdir . 'layerstreemenu.ijs'); + $t->setVar(array( + 'toggle_function_name' => $toggle_function_name, + 'img_collapse' => $img_collapse, + 'img_collapse_corner' => $img_collapse_corner, + 'img_collapse_corner_first' => $img_collapse_corner_first, + 'img_collapse_first' => $img_collapse_first, + 'img_expand' => $img_expand, + 'img_expand_corner' => $img_expand_corner, + 'img_expand_corner_first' => $img_expand_corner_first, + 'img_expand_first' => $img_expand_first, + 'img_folder_closed' => $img_folder_closed, + 'img_folder_open' => $img_folder_open + )); + $toggle_function = $t->parse('out', 'tplfile'); + $toggle_function = + '' . "\n"; + + $toggle = + '' . "\n"; + + $this->_treeMenu[$menu_name] = $toggle_function . "\n" . $this->_treeMenu[$menu_name] . "\n" . $toggle; + + return $this->_treeMenu[$menu_name]; +} + +/** +* Method that returns the code of the requested Tree Menu +* @access public +* @param string $menu_name the name of the menu whose Tree Menu code +* has to be returned +* @return string +*/ +function getTreeMenu($menu_name) +{ + return $this->_treeMenu[$menu_name]; +} + +/** +* Method that prints the code of the requested Tree Menu +* @access public +* @param string $menu_name the name of the menu whose Tree Menu code +* has to be printed +* @return void +*/ +function printTreeMenu($menu_name) +{ + print $this->_treeMenu[$menu_name]; +} + +} /* END OF CLASS */ + +?> diff --git a/include/php_layers_menu/libjs/layersmenu-browser_detection.js b/include/php_layers_menu/libjs/layersmenu-browser_detection.js new file mode 100644 index 000000000..79896a001 --- /dev/null +++ b/include/php_layers_menu/libjs/layersmenu-browser_detection.js @@ -0,0 +1,33 @@ +// PHP Layers Menu 3.2.0-rc (C) 2001-2004 Marco Pratesi - http://www.marcopratesi.it/ + +DOM = (document.getElementById) ? 1 : 0; +NS4 = (document.layers) ? 1 : 0; +// We need to explicitly detect Konqueror +// because Konqueror 3 sets IE = 1 ... AAAAAAAAAARGHHH!!! +Konqueror = (navigator.userAgent.indexOf('Konqueror') > -1) ? 1 : 0; +// We need to detect Konqueror 2.2 as it does not handle the window.onresize event +Konqueror22 = (navigator.userAgent.indexOf('Konqueror 2.2') > -1 || navigator.userAgent.indexOf('Konqueror/2.2') > -1) ? 1 : 0; +Konqueror30 = + ( + navigator.userAgent.indexOf('Konqueror 3.0') > -1 + || navigator.userAgent.indexOf('Konqueror/3.0') > -1 + || navigator.userAgent.indexOf('Konqueror 3;') > -1 + || navigator.userAgent.indexOf('Konqueror/3;') > -1 + || navigator.userAgent.indexOf('Konqueror 3)') > -1 + || navigator.userAgent.indexOf('Konqueror/3)') > -1 + ) + ? 1 : 0; +Konqueror31 = (navigator.userAgent.indexOf('Konqueror 3.1') > -1 || navigator.userAgent.indexOf('Konqueror/3.1') > -1) ? 1 : 0; +// We need to detect Konqueror 3.2 and 3.3 as they are affected by the see-through effect only for 2 form elements +Konqueror32 = (navigator.userAgent.indexOf('Konqueror 3.2') > -1 || navigator.userAgent.indexOf('Konqueror/3.2') > -1) ? 1 : 0; +Konqueror33 = (navigator.userAgent.indexOf('Konqueror 3.3') > -1 || navigator.userAgent.indexOf('Konqueror/3.3') > -1) ? 1 : 0; +Opera = (navigator.userAgent.indexOf('Opera') > -1) ? 1 : 0; +Opera5 = (navigator.userAgent.indexOf('Opera 5') > -1 || navigator.userAgent.indexOf('Opera/5') > -1) ? 1 : 0; +Opera6 = (navigator.userAgent.indexOf('Opera 6') > -1 || navigator.userAgent.indexOf('Opera/6') > -1) ? 1 : 0; +Opera56 = Opera5 || Opera6; +IE = (navigator.userAgent.indexOf('MSIE') > -1) ? 1 : 0; +IE = IE && !Opera; +IE5 = IE && DOM; +IE4 = (document.all) ? 1 : 0; +IE4 = IE4 && IE && !DOM; + diff --git a/include/php_layers_menu/libjs/layersmenu-footer.ijs b/include/php_layers_menu/libjs/layersmenu-footer.ijs new file mode 100644 index 000000000..42bb0ad10 --- /dev/null +++ b/include/php_layers_menu/libjs/layersmenu-footer.ijs @@ -0,0 +1,11 @@ + + +{footer} + + + + diff --git a/include/php_layers_menu/libjs/layersmenu-header.ijs b/include/php_layers_menu/libjs/layersmenu-header.ijs new file mode 100644 index 000000000..128078bed --- /dev/null +++ b/include/php_layers_menu/libjs/layersmenu-header.ijs @@ -0,0 +1,57 @@ + + + + + diff --git a/include/php_layers_menu/libjs/layersmenu-library.js b/include/php_layers_menu/libjs/layersmenu-library.js new file mode 100644 index 000000000..049abf89d --- /dev/null +++ b/include/php_layers_menu/libjs/layersmenu-library.js @@ -0,0 +1,248 @@ +// PHP Layers Menu 3.2.0-rc (C) 2001-2004 Marco Pratesi - http://www.marcopratesi.it/ + +layerLeft = new Array(); +layerTop = new Array(); + +function setVisibility(layer, on) +{ + if (on) { + if (DOM) { + document.getElementById(layer).style.visibility = 'visible'; + } else if (NS4) { + document.layers[layer].visibility = 'show'; + } else { + document.all[layer].style.visibility = 'visible'; + } + } else { + if (DOM) { + document.getElementById(layer).style.visibility = 'hidden'; + } else if (NS4) { + document.layers[layer].visibility = 'hide'; + } else { + document.all[layer].style.visibility = 'hidden'; + } + } +} + +function isVisible(layer) +{ + if (DOM) { + return (document.getElementById(layer).style.visibility == 'visible'); + } else if (NS4) { + return (document.layers[layer].visibility == 'show'); + } else { + return (document.all[layer].style.visibility == 'visible'); + } +} + +function setLeft(layer, x) +{ +layerLeft[layer] = x; + if (DOM && !Opera5) { + document.getElementById(layer).style.left = x + 'px'; + } else if (Opera5) { + document.getElementById(layer).style.left = x; + } else if (NS4) { + document.layers[layer].left = x; + } else { + document.all[layer].style.pixelLeft = x; + } +} + +function getOffsetLeft(layer) +{ + var value = 0; + if (DOM) { // Mozilla, Konqueror >= 2.2, Opera >= 5, IE + object = document.getElementById(layer); + value = object.offsetLeft; +//alert (object.tagName + ' --- ' + object.offsetLeft); + while (object.tagName != 'BODY' && object.offsetParent) { + object = object.offsetParent; +//alert (object.tagName + ' --- ' + object.offsetLeft); + value += object.offsetLeft; + } + } else if (NS4) { + value = document.layers[layer].pageX; + } else { // IE4 IS SIMPLY A BASTARD !!! + if (document.all['IE4' + layer]) { + layer = 'IE4' + layer; + } + object = document.all[layer]; + value = object.offsetLeft; + while (object.tagName != 'BODY') { + object = object.offsetParent; + value += object.offsetLeft; + } + } + return (value); +} + +function setTop(layer, y) +{ +layerTop[layer] = y; + if (DOM && !Opera5) { + document.getElementById(layer).style.top = y + 'px'; + } else if (Opera5) { + document.getElementById(layer).style.top = y; + } else if (NS4) { + document.layers[layer].top = y; + } else { + document.all[layer].style.pixelTop = y; + } +} + +function getOffsetTop(layer) +{ +// IE 5.5 and 6.0 behaviour with this function is really strange: +// in some cases, they return a really too large value... +// ... after all, IE is buggy, nothing new + var value = 0; + if (DOM) { + object = document.getElementById(layer); + value = object.offsetTop; + while (object.tagName != 'BODY' && object.offsetParent) { + object = object.offsetParent; + value += object.offsetTop; + } + } else if (NS4) { + value = document.layers[layer].pageY; + } else { // IE4 IS SIMPLY A BASTARD !!! + if (document.all['IE4' + layer]) { + layer = 'IE4' + layer; + } + object = document.all[layer]; + value = object.offsetTop; + while (object.tagName != 'BODY') { + object = object.offsetParent; + value += object.offsetTop; + } + } + return (value); +} + +function setWidth(layer, w) +{ + if (DOM) { + document.getElementById(layer).style.width = w; + } else if (NS4) { +// document.layers[layer].width = w; + } else { + document.all[layer].style.pixelWidth = w; + } +} + +function getOffsetWidth(layer) +{ + var value = 0; + if (DOM && !Opera56) { + value = document.getElementById(layer).offsetWidth; + } else if (NS4) { + value = document.layers[layer].document.width; + } else if (Opera56) { + value = document.getElementById(layer).style.pixelWidth; + } else { // IE4 IS SIMPLY A BASTARD !!! + if (document.all['IE4' + layer]) { + layer = 'IE4' + layer; + } + value = document.all[layer].offsetWidth; + } + return (value); +} + +function setHeight(layer, h) // unused, not tested +{ + if (DOM) { + document.getElementById(layer).style.height = h; + } else if (NS4) { +// document.layers[layer].height = h; + } else { + document.all[layer].style.pixelHeight = h; + } +} + +function getOffsetHeight(layer) +{ + var value = 0; + if (DOM && !Opera56) { + value = document.getElementById(layer).offsetHeight; + } else if (NS4) { + value = document.layers[layer].document.height; + } else if (Opera56) { + value = document.getElementById(layer).style.pixelHeight; + } else { // IE4 IS SIMPLY A BASTARD !!! + if (document.all['IE4' + layer]) { + layer = 'IE4' + layer; + } + value = document.all[layer].offsetHeight; + } + return (value); +} + +function getWindowWidth() +{ + var value = 0; + if ((DOM && !IE) || NS4 || Konqueror || Opera) { + value = window.innerWidth; +// } else if (NS4) { +// value = document.width; + } else { // IE + if (document.documentElement && document.documentElement.clientWidth) { + value = document.documentElement.clientWidth; + } else if (document.body) { + value = document.body.clientWidth; + } + } + if (isNaN(value)) { + value = window.innerWidth; + } + return (value); +} + +function getWindowXOffset() +{ + var value = 0; + if ((DOM && !IE) || NS4 || Konqueror || Opera) { + value = window.pageXOffset; + } else { // IE + if (document.documentElement && document.documentElement.scrollLeft) { + value = document.documentElement.scrollLeft; + } else if (document.body) { + value = document.body.scrollLeft; + } + } + return (value); +} + +function getWindowHeight() +{ + var value = 0; + if ((DOM && !IE) || NS4 || Konqueror || Opera) { + value = window.innerHeight; + } else { // IE + if (document.documentElement && document.documentElement.clientHeight) { + value = document.documentElement.clientHeight; + } else if (document.body) { + value = document.body.clientHeight; + } + } + if (isNaN(value)) { + value = window.innerHeight; + } + return (value); +} + +function getWindowYOffset() +{ + var value = 0; + if ((DOM && !IE) || NS4 || Konqueror || Opera) { + value = window.pageYOffset; + } else { // IE + if (document.documentElement && document.documentElement.scrollTop) { + value = document.documentElement.scrollTop; + } else if (document.body) { + value = document.body.scrollTop; + } + } + return (value); +} + diff --git a/include/php_layers_menu/libjs/layersmenu-see-through.js b/include/php_layers_menu/libjs/layersmenu-see-through.js new file mode 100644 index 000000000..7ca94550b --- /dev/null +++ b/include/php_layers_menu/libjs/layersmenu-see-through.js @@ -0,0 +1,65 @@ +// PHP Layers Menu 3.2.0-rc (C) 2001-2004 Marco Pratesi - http://www.marcopratesi.it/ + +function scanChildren(element) +{ + var counter = element.childNodes.length; + for (var i=0; i 1) + || foobar.nodeName == 'TEXTAREA' || foobar.nodeName == 'textarea' + ) + ) + || + ( IE && + ( foobar.nodeName == 'SELECT' || foobar.nodeName == 'select' ) + ) + ) { + toBeHidden[toBeHidden.length] = foobar; + } + if (foobar.childNodes.length > 0) { + scanChildren(foobar); + } + } +} + +function seeThroughCoordinatesDetection() +{ + if (!((Konqueror && !Konqueror22) || IE5)) { + return; + } + for (i=0; i\nSCANNING STARTED
\n"); +//scanChildren(document.getElementsByTagName('BODY').item(0)); +if ((Konqueror || IE5) && document.getElementById('phplmseethrough')) { + scanChildren(document.getElementById('phplmseethrough')); +} +//document.write("
\nSCANNING COMPLETED
\n"); + +seeThroughCoordinatesDetection(); + diff --git a/include/php_layers_menu/libjs/layersmenu.js b/include/php_layers_menu/libjs/layersmenu.js new file mode 100644 index 000000000..5d29e5bf0 --- /dev/null +++ b/include/php_layers_menu/libjs/layersmenu.js @@ -0,0 +1,316 @@ +// PHP Layers Menu 3.2.0-rc (C) 2001-2004 Marco Pratesi - http://www.marcopratesi.it/ + +useTimeouts = 1; +timeoutLength = 1000; // time in ms; not significant if useTimeouts = 0; +shutdownOnClick = 0; + +loaded = 0; +layersMoved = 0; +layerPoppedUp = ''; + +timeoutFlag = 0; +if (Opera56 || IE4) { + useTimeouts = 0; +} +if (NS4 || Opera56 || IE4) { + shutdownOnClick = 1; +} + +currentY = 0; +function grabMouse(e) // for NS4 +{ + currentY = e.pageY; +} +if (NS4) { + document.captureEvents(Event.MOUSEDOWN | Event.MOUSEMOVE); + document.onmousemove = grabMouse; +} + +function seeThroughElements(show) +{ + if (show) { + foobar = 'visible'; + } else { + foobar = 'hidden'; + } + for (i=0; i windowWidth + windowXOffset) { + if (onRight + width1 - windowWidth - windowXOffset > windowXOffset - onLeft) { + onLeft = windowXOffset; + } else { + onRight = windowWidth + windowXOffset - width1; + } + } + if (back[father[menuName]]) { + if (onLeft < windowXOffset) { + back[menuName] = 0; + } else { + back[menuName] = 1; + } + } else { +//alert(onRight + ' - ' + width1 + ' - ' + windowWidth + ' - ' + windowXOffset); + if (onRight + width1 > windowWidth + windowXOffset) { + back[menuName] = 1; + } else { + back[menuName] = 0; + } + } + if (back[menuName]) { + setLeft(menuName, onLeft); + } else { + setLeft(menuName, onRight); + } + } + moveLayerY(menuName); // workaround needed for Mozilla < 1.4 for MS Windows +} + +function moveLayerY(menuName) +{ + if (!loaded || (isVisible(menuName) && menuName != layerPoppedUp)) { + return; + } + if (!layersMoved) { + moveLayers(); + layersMoved = 1; + } + if (!NS4) { + newY = getOffsetTop('ref' + menuName); + } else { + newY = currentY; + } + newY += menuTopShift; + layerHeight = getOffsetHeight(menuName); + windowHeight = getWindowHeight(); + windowYOffset = getWindowYOffset(); + if (newY + layerHeight > windowHeight + windowYOffset) { + if (layerHeight > windowHeight) { + newY = windowYOffset; + } else { + newY = windowHeight + windowYOffset - layerHeight; + } + } + if (Math.abs(getOffsetTop(menuName) - newY) > thresholdY) { + setTop(menuName, newY); + } +} + +function moveLayerX1(menuName, father) +{ + if (!lwidthDetected) { + return; + } + if (!Opera5 && !IE4) { + width1 = lwidth[menuName]; + } else if (Opera5) { + // Opera 5 stupidly and exaggeratedly overestimates layers widths + // hence we consider a default value equal to $abscissaStep + width1 = abscissaStep; + } + foobar = getOffsetLeft(father + menuName); +if (!IE4) { + windowWidth = getWindowWidth(); + windowXOffset = getWindowXOffset(); + if (foobar + width1 > windowWidth + windowXOffset) { + foobar = windowWidth + windowXOffset - width1; + } + if (foobar < windowXOffset) { + foobar = windowXOffset; + } +} + setLeft(menuName, foobar); +} + +function layersOverlap(layer, i) +{ + if (Konqueror22) { + return true; + } + +// xa1 = getOffsetLeft(layer); +//setLeft(layer, xa1); + xa1 = layerLeft[layer]; + xa2 = xa1 + getOffsetWidth(layer); +//setWidth(layer, xa2-xa1); +// ya1 = getOffsetTop(layer); +//setTop(layer, ya1); + ya1 = layerTop[layer]; + ya2 = ya1 + getOffsetHeight(layer); +//setHeight(layer, ya2-ya1); +//alert(':' + xa1 + ':' + xa2 + ':' + ya1 + ':' + ya2 + ':'); + + xb1 = toBeHiddenLeft[i]; + xb2 = xb1 + toBeHidden[i].offsetWidth; + yb1 = toBeHiddenTop[i]; + yb2 = yb1 + toBeHidden[i].offsetHeight; +//alert(':' + xb1 + ':' + xb2 + ':' + yb1 + ':' + yb2 + ':'); + + if(xb1>xa1) xa1=xb1; if(xb2ya1) ya1=yb1; if(yb2xa1 && ya2>ya1); +} + +function seeThroughWorkaround(menuName, on) +{ + for (i=0; i 0) { + seeThroughCoordinatesDetection(); + } +// moveLayers(); + layersMoved = 0; +} +window.onresize = resizeHandler; + +function yaresizeHandler() +{ + if (window.innerWidth != origWidth || window.innerHeight != origHeight) { + if (Konqueror22 || Opera5) { + window.location.reload(); // Opera 5 often fails this + } + origWidth = window.innerWidth; + origHeight = window.innerHeight; + resizeHandler(); + } + setTimeout('yaresizeHandler()', 500); +} +function loadHandler() +{ + if (Konqueror22 || Opera56) { + origWidth = window.innerWidth; + origHeight = window.innerHeight; + yaresizeHandler(); + } +} +window.onload = loadHandler; + +function fixieflm(menuName) +{ + if (DOM) { + setWidth(menuName, '100%'); + } else { // IE4 IS SIMPLY A BASTARD !!! + document.write('
'); + document.write('"; - + + $s= ".|"._("Actions")."|\n"; + $s.= "..|"._("Create")."|\n"; + $s.= "...|"._("Terminal")."|\n"; + $s.= "...|"._("Workstation")."|\n"; + $s.= "...|"._("Server")."|\n"; + $s.= "...|"._("Phone")."|\n"; + $s.= "...|"._("Printer")."|\n"; + $s.= "...|"._("Component")."|\n"; + $s.= "..|"._("Remove all")."|\n"; + $s.= "..|"._("Copy all")."|\n"; + $s.= "..|"._("Cut all")."|\n"; + + $this->SetDropDownHeaderMenu($s); $this->SetListHeader($listhead); } @@ -250,7 +262,6 @@ class divListSystem extends MultiSelectWindow $this->GenHeader(); } - function setEntries($terminals) { $img1 = "C";