update options menu to for RSS feed options
[diogenes.git] / include / phplayersmenu / layersmenu-common.inc.php
... / ...
CommitLineData
1<?php
2// PHP Layers Menu 3.1.1 (C) 2001-2003 Marco Pratesi (marco at telug dot it)
3
4/**
5* This file contains the code of the LayersMenuCommon class.
6* @package PHPLayersMenu
7*/
8
9
10/**
11* This is the "common" class of the PHP Layers Menu library.
12* @version 3.1.1
13* @package PHPLayersMenu
14*/
15class LayersMenuCommon {
16
17/**
18* The name of the package
19* @access private
20* @var string
21*/
22var $_packageName;
23/**
24* The version of the package
25* @access private
26* @var string
27*/
28var $version;
29/**
30* The copyright of the package
31* @access private
32* @var string
33*/
34var $copyright;
35/**
36* The author of the package
37* @access private
38* @var string
39*/
40var $author;
41
42/**
43* URL to be prepended to the menu hrefs
44* @access private
45* @var string
46*/
47var $prependedUrl = "";
48/**
49* Do you want that code execution halts on error?
50* @access private
51* @var string
52*/
53var $haltOnError = "yes";
54
55/**
56* The base directory where the package is installed
57* @access private
58* @var string
59*/
60var $dirroot;
61/**
62* The "libjs" directory of the package
63* @access private
64* @var string
65*/
66var $libjsdir;
67/**
68* The directory where images related to the menu can be found
69* @access private
70* @var string
71*/
72var $imgdir;
73/**
74* The http path corresponding to imgdir
75* @access private
76* @var string
77*/
78var $imgwww;
79/**
80* The directory where templates can be found
81* @access private
82* @var string
83*/
84var $tpldir;
85/**
86* The string containing the menu structure
87* @access private
88* @var string
89*/
90var $menuStructure;
91
92/**
93* It counts nodes for all menus
94* @access private
95* @var integer
96*/
97var $_nodesCount;
98/**
99* A multi-dimensional array where we store informations for each menu entry
100* @access private
101* @var array
102*/
103var $tree;
104/**
105* The maximum hierarchical level of menu items
106* @access private
107* @var integer
108*/
109var $_maxLevel;
110/**
111* An array that counts the number of first level items for each menu
112* @access private
113* @var array
114*/
115var $_firstLevelCnt;
116/**
117* An array containing the number identifying the first item of each menu
118* @access private
119* @var array
120*/
121var $_firstItem;
122/**
123* An array containing the number identifying the last item of each menu
124* @access private
125* @var array
126*/
127var $_lastItem;
128
129/**
130* Data Source Name: the connection string for PEAR DB
131* @access private
132* @var string
133*/
134var $dsn = "pgsql://dbuser:dbpass@dbhost/dbname";
135/**
136* DB connections are either persistent or not persistent
137* @access private
138* @var boolean
139*/
140var $persistent = false;
141/**
142* Name of the table storing data describing the menu
143* @access private
144* @var string
145*/
146var $tableName = "phplayersmenu";
147/**
148* Name of the i18n table corresponding to $tableName
149* @access private
150* @var string
151*/
152var $tableName_i18n = "phplayersmenu_i18n";
153/**
154* Names of fields of the table storing data describing the menu
155*
156* default field names correspond to the same field names foreseen
157* by the menu structure format
158*
159* @access private
160* @var array
161*/
162var $tableFields = array(
163 "id" => "id",
164 "parent_id" => "parent_id",
165 "text" => "text",
166 "href" => "href",
167 "title" => "title",
168 "icon" => "icon",
169 "target" => "target",
170 "orderfield" => "orderfield",
171 "expanded" => "expanded"
172);
173/**
174* Names of fields of the i18n table corresponding to $tableName
175* @access private
176* @var array
177*/
178var $tableFields_i18n = array(
179 "language" => "language",
180 "id" => "id",
181 "text" => "text",
182 "title" => "title"
183);
184/**
185* A temporary array to store data retrieved from the DB and to perform the depth-first search
186* @access private
187* @var array
188*/
189var $_tmpArray = array();
190
191/**
192* The constructor method; it initializates the menu system
193* @return void
194*/
195function LayersMenuCommon() {
196
197 $this->_packageName = "PHP Layers Menu";
198 $this->version = "3.1.1";
199 $this->copyright = "(C) 2001-2003";
200 $this->author = "Marco Pratesi (marco at telug dot it)";
201
202 $this->prependedUrl = "";
203
204 $this->dirroot = "./";
205 $this->libjsdir = "./libjs/";
206 $this->imgdir = "./images/";
207 $this->imgwww = "images/";
208 $this->tpldir = "./templates/";
209 $this->menuStructure = "";
210 $this->separator = "|";
211
212 $this->_nodesCount = 0;
213 $this->tree = array();
214 $this->_maxLevel = array();
215 $this->_firstLevelCnt = array();
216 $this->_firstItem = array();
217 $this->_lastItem = array();
218}
219
220/**
221* The method to set the prepended URL
222* @access public
223* @return boolean
224*/
225function setPrependedUrl($prependedUrl) {
226 // We do not perform any check
227 $this->prependedUrl = $prependedUrl;
228 return true;
229}
230
231/**
232* The method to set the dirroot directory
233* @access public
234* @return boolean
235*/
236function setDirrootCommon($dirroot) {
237 if (!is_dir($dirroot)) {
238 $this->error("setDirroot: $dirroot is not a directory.");
239 return false;
240 }
241 if (substr($dirroot, -1) != "/") {
242 $dirroot .= "/";
243 }
244 $oldlength = strlen($this->dirroot);
245 $foobar = strpos($this->libjsdir, $this->dirroot);
246 if (!($foobar === false || $foobar != 0)) {
247 $this->libjsdir = $dirroot . substr($this->libjsdir, $oldlength);
248 }
249 $foobar = strpos($this->imgdir, $this->dirroot);
250 if (!($foobar === false || $foobar != 0)) {
251 $this->imgdir = $dirroot . substr($this->imgdir, $oldlength);
252 }
253 $foobar = strpos($this->tpldir, $this->dirroot);
254 if (!($foobar === false || $foobar != 0)) {
255 $this->tpldir = $dirroot . substr($this->tpldir, $oldlength);
256 }
257 $this->dirroot = $dirroot;
258 return true;
259}
260
261/**
262* The method to set the libjsdir directory
263* @access public
264* @return boolean
265*/
266function setLibjsdir($libjsdir) {
267 if ($libjsdir != "" && substr($libjsdir, -1) != "/") {
268 $libjsdir .= "/";
269 }
270 if ($libjsdir == "" || substr($libjsdir, 0, 1) != "/") {
271 $foobar = strpos($libjsdir, $this->dirroot);
272 if ($foobar === false || $foobar != 0) {
273 $libjsdir = $this->dirroot . $libjsdir;
274 }
275 }
276 if (!is_dir($libjsdir)) {
277 $this->error("setLibjsdir: $libjsdir is not a directory.");
278 return false;
279 }
280 $this->libjsdir = $libjsdir;
281 return true;
282}
283
284/**
285* The method to set the imgdir directory
286* @access public
287* @return boolean
288*/
289function setImgdir($imgdir) {
290 if ($imgdir != "" && substr($imgdir, -1) != "/") {
291 $imgdir .= "/";
292 }
293 if ($imgdir == "" || substr($imgdir, 0, 1) != "/") {
294 $foobar = strpos($imgdir, $this->dirroot);
295 if ($foobar === false || $foobar != 0) {
296 $imgdir = $this->dirroot . $imgdir;
297 }
298 }
299 if (!is_dir($imgdir)) {
300 $this->error("setImgdir: $imgdir is not a directory.");
301 return false;
302 }
303 $this->imgdir = $imgdir;
304 return true;
305}
306
307/**
308* The method to set imgwww
309* @access public
310* @return void
311*/
312function setImgwww($imgwww) {
313 if ($imgwww != "" && substr($imgwww, -1) != "/") {
314 $imgwww .= "/";
315 }
316 $this->imgwww = $imgwww;
317}
318
319/**
320* The method to set the tpldir directory
321* @access public
322* @return boolean
323*/
324function setTpldirCommon($tpldir) {
325 if ($tpldir != "" && substr($tpldir, -1) != "/") {
326 $tpldir .= "/";
327 }
328 if ($tpldir == "" || substr($tpldir, 0, 1) != "/") {
329 $foobar = strpos($tpldir, $this->dirroot);
330 if ($foobar === false || $foobar != 0) {
331 $tpldir = $this->dirroot . $tpldir;
332 }
333 }
334 if (!is_dir($tpldir)) {
335 $this->error("setTpldir: $tpldir is not a directory.");
336 return false;
337 }
338 $this->tpldir = $tpldir;
339 return true;
340}
341
342/**
343* The method to read the menu structure from a file
344* @access public
345* @param string $tree_file the menu structure file
346* @return boolean
347*/
348function setMenuStructureFile($tree_file) {
349 if (!($fd = fopen($tree_file, "r"))) {
350 $this->error("setMenuStructureFile: unable to open file $tree_file.");
351 return false;
352 }
353 $this->menuStructure = "";
354 while ($buffer = fgets($fd, 4096)) {
355 $buffer = ereg_replace(chr(13), "", $buffer); // Microsoft Stupidity Suppression
356 $this->menuStructure .= $buffer;
357 }
358 fclose($fd);
359 if ($this->menuStructure == "") {
360 $this->error("setMenuStructureFile: $tree_file is empty.");
361 return false;
362 }
363 return true;
364}
365
366/**
367* The method to set the menu structure passing it through a string
368* @access public
369* @param string $tree_string the menu structure string
370* @return boolean
371*/
372function setMenuStructureString($tree_string) {
373 $this->menuStructure = ereg_replace(chr(13), "", $tree_string); // Microsoft Stupidity Suppression
374 if ($this->menuStructure == "") {
375 $this->error("setMenuStructureString: empty string.");
376 return false;
377 }
378 return true;
379}
380
381/**
382* The method to set the value of separator
383* @access public
384* @return void
385*/
386function setSeparator($separator) {
387 $this->separator = $separator;
388}
389
390/**
391* The method to set parameters for the DB connection
392* @access public
393* @param string $dns Data Source Name: the connection string for PEAR DB
394* @param bool $persistent DB connections are either persistent or not persistent
395* @return boolean
396*/
397function setDBConnParms($dsn, $persistent=false) {
398 if (!is_string($dsn)) {
399 $this->error("initdb: \$dsn is not an string.");
400 return false;
401 }
402 if (!is_bool($persistent)) {
403 $this->error("initdb: \$persistent is not a boolean.");
404 return false;
405 }
406 $this->dsn = $dsn;
407 $this->persistent = $persistent;
408 return true;
409}
410
411/**
412* The method to set the name of the table storing data describing the menu
413* @access public
414* @param string
415* @return boolean
416*/
417function setTableName($tableName) {
418 if (!is_string($tableName)) {
419 $this->error("setTableName: \$tableName is not a string.");
420 return false;
421 }
422 $this->tableName = $tableName;
423 return true;
424}
425
426/**
427* The method to set the name of the i18n table corresponding to $tableName
428* @access public
429* @param string
430* @return boolean
431*/
432function setTableName_i18n($tableName_i18n) {
433 if (!is_string($tableName_i18n)) {
434 $this->error("setTableName_i18n: \$tableName_i18n is not a string.");
435 return false;
436 }
437 $this->tableName_i18n = $tableName_i18n;
438 return true;
439}
440
441/**
442* The method to set names of fields of the table storing data describing the menu
443* @access public
444* @param array
445* @return boolean
446*/
447function setTableFields($tableFields) {
448 if (!is_array($tableFields)) {
449 $this->error("setTableFields: \$tableFields is not an array.");
450 return false;
451 }
452 if (count($tableFields) == 0) {
453 $this->error("setTableFields: \$tableFields is a zero-length array.");
454 return false;
455 }
456 reset ($tableFields);
457 while (list($key, $value) = each($tableFields)) {
458 $this->tableFields[$key] = ($value == "") ? "''" : $value;
459 }
460 return true;
461}
462
463/**
464* The method to set names of fields of the i18n table corresponding to $tableName
465* @access public
466* @param array
467* @return boolean
468*/
469function setTableFields_i18n($tableFields_i18n) {
470 if (!is_array($tableFields_i18n)) {
471 $this->error("setTableFields_i18n: \$tableFields_i18n is not an array.");
472 return false;
473 }
474 if (count($tableFields_i18n) == 0) {
475 $this->error("setTableFields_i18n: \$tableFields_i18n is a zero-length array.");
476 return false;
477 }
478 reset ($tableFields_i18n);
479 while (list($key, $value) = each($tableFields_i18n)) {
480 $this->tableFields_i18n[$key] = ($value == "") ? "''" : $value;
481 }
482 return true;
483}
484
485/**
486* The method to parse the current menu structure and correspondingly update related variables
487* @access public
488* @param string $menu_name the name to be attributed to the menu
489* whose structure has to be parsed
490* @return void
491*/
492function parseStructureForMenu(
493 $menu_name = "" // non consistent default...
494 ) {
495 $this->_maxLevel[$menu_name] = 0;
496 $this->_firstLevelCnt[$menu_name] = 0;
497 $this->_firstItem[$menu_name] = $this->_nodesCount + 1;
498 $cnt = $this->_firstItem[$menu_name];
499 $menuStructure = $this->menuStructure;
500
501 /* *********************************************** */
502 /* Partially based on a piece of code taken from */
503 /* TreeMenu 1.1 - Bjorge Dijkstra (bjorge@gmx.net) */
504 /* *********************************************** */
505
506 while ($menuStructure != "") {
507 $before_cr = strcspn($menuStructure, "\n");
508 $buffer = substr($menuStructure, 0, $before_cr);
509 $menuStructure = substr($menuStructure, $before_cr+1);
510 if (substr($buffer, 0, 1) != "#") { // non commented item line...
511 $tmp = rtrim($buffer);
512 $node = explode($this->separator, $tmp);
513 for ($i=count($node); $i<=6; $i++) {
514 $node[$i] = "";
515 }
516 $this->tree[$cnt]["level"] = strlen($node[0]);
517 $this->tree[$cnt]["text"] = $node[1];
518 $this->tree[$cnt]["href"] = $node[2];
519 $this->tree[$cnt]["title"] = $node[3];
520 $this->tree[$cnt]["icon"] = $node[4];
521 $this->tree[$cnt]["target"] = $node[5];
522 $this->tree[$cnt]["expanded"] = $node[6];
523 $cnt++;
524 }
525 }
526
527 /* *********************************************** */
528
529 $this->_lastItem[$menu_name] = count($this->tree);
530 $this->_nodesCount = $this->_lastItem[$menu_name];
531 $this->tree[$this->_lastItem[$menu_name]+1]["level"] = 0;
532 $this->_postParse($menu_name);
533}
534
535/**
536* The method to parse the current menu table and correspondingly update related variables
537* @access public
538* @param string $menu_name the name to be attributed to the menu
539* whose structure has to be parsed
540* @param string $language i18n language; either omit it or pass
541* an empty string ("") if you do not want to use any i18n table
542* @return void
543*/
544function scanTableForMenu(
545 $menu_name = "", // non consistent default...
546 $language = ""
547 ) {
548 $this->_maxLevel[$menu_name] = 0;
549 $this->_firstLevelCnt[$menu_name] = 0;
550 unset($this->tree[$this->_nodesCount+1]);
551 $this->_firstItem[$menu_name] = $this->_nodesCount + 1;
552/* BEGIN BENCHMARK CODE
553$time_start = $this->_getmicrotime();
554/* END BENCHMARK CODE */
555 $db = DB::connect($this->dsn, $this->persistent);
556 if (DB::isError($db)) {
557 $this->error("scanTableForMenu: " . $db->getMessage());
558 }
559 $dbresult = $db->query("
560 SELECT " .
561 $this->tableFields["id"] . " AS id, " .
562 $this->tableFields["parent_id"] . " AS parent_id, " .
563 $this->tableFields["text"] . " AS text, " .
564 $this->tableFields["href"] . " AS href, " .
565 $this->tableFields["title"] . " AS title, " .
566 $this->tableFields["icon"] . " AS icon, " .
567 $this->tableFields["target"] . " AS target, " .
568 $this->tableFields["expanded"] . " AS expanded
569 FROM " . $this->tableName . "
570 WHERE " . $this->tableFields["id"] . " <> 1
571 ORDER BY " . $this->tableFields["orderfield"] . ", " . $this->tableFields["text"] . " ASC
572 ");
573 $this->_tmpArray = array();
574 while ($dbresult->fetchInto($row, DB_FETCHMODE_ASSOC)) {
575 $this->_tmpArray[$row["id"]]["parent_id"] = $row["parent_id"];
576 $this->_tmpArray[$row["id"]]["text"] = $row["text"];
577 $this->_tmpArray[$row["id"]]["href"] = $row["href"];
578 $this->_tmpArray[$row["id"]]["title"] = $row["title"];
579 $this->_tmpArray[$row["id"]]["icon"] = $row["icon"];
580 $this->_tmpArray[$row["id"]]["target"] = $row["target"];
581 $this->_tmpArray[$row["id"]]["expanded"] = $row["expanded"];
582 }
583 if ($language != "") {
584 $dbresult = $db->query("
585 SELECT " .
586 $this->tableFields_i18n["id"] . " AS id, " .
587 $this->tableFields_i18n["text"] . " AS text, " .
588 $this->tableFields_i18n["title"] . " AS title
589 FROM " . $this->tableName_i18n . "
590 WHERE " . $this->tableFields_i18n["id"] . " <> 1
591 AND " . $this->tableFields_i18n["language"] . " = '$language'
592 ");
593 while ($dbresult->fetchInto($row, DB_FETCHMODE_ASSOC)) {
594 $this->_tmpArray[$row["id"]]["text"] = $row["text"];
595 $this->_tmpArray[$row["id"]]["title"] = $row["title"];
596 }
597 }
598 unset($dbresult);
599 unset($row);
600 $this->_depthFirstSearch($this->_tmpArray, $menu_name, 1, 1);
601/* BEGIN BENCHMARK CODE
602$time_end = $this->_getmicrotime();
603$time = $time_end - $time_start;
604print "TIME ELAPSED = " . $time . "\n<br>";
605/* END BENCHMARK CODE */
606 $this->_lastItem[$menu_name] = count($this->tree);
607 $this->_nodesCount = $this->_lastItem[$menu_name];
608 $this->tree[$this->_lastItem[$menu_name]+1]["level"] = 0;
609 $this->_postParse($menu_name);
610}
611
612function _getmicrotime() {
613 list($usec, $sec) = explode(" ", microtime());
614 return ((float) $usec + (float) $sec);
615}
616
617/**
618* Recursive method to perform the depth-first search of the tree data taken from the current menu table
619* @access private
620* @param array $tmpArray the temporary array that stores data to perform
621* the depth-first search
622* @param string $menu_name the name to be attributed to the menu
623* whose structure has to be parsed
624* @param integer $parent_id id of the item whose children have
625* to be searched for
626* @param integer $level the hierarchical level of children to be searched for
627* @return void
628*/
629function _depthFirstSearch($tmpArray, $menu_name, $parent_id=1, $level) {
630 reset ($tmpArray);
631 while (list($id, $foobar) = each($tmpArray)) {
632 if ($foobar["parent_id"] == $parent_id) {
633 unset($tmpArray[$id]);
634 unset($this->_tmpArray[$id]);
635 $cnt = count($this->tree) + 1;
636 $this->tree[$cnt]["level"] = $level;
637 $this->tree[$cnt]["text"] = $foobar["text"];
638 $this->tree[$cnt]["href"] = $foobar["href"];
639 $this->tree[$cnt]["title"] = $foobar["title"];
640 $this->tree[$cnt]["icon"] = $foobar["icon"];
641 $this->tree[$cnt]["target"] = $foobar["target"];
642 $this->tree[$cnt]["expanded"] = $foobar["expanded"];
643 unset($foobar);
644 if ($id != $parent_id) {
645 $this->_depthFirstSearch($this->_tmpArray, $menu_name, $id, $level+1);
646 }
647 }
648 }
649}
650
651/**
652* A method providing parsing needed after both file/string parsing and DB table parsing
653* @access private
654* @param string $menu_name the name of the menu for which the parsing
655* has to be performed
656* @return void
657*/
658function _postParse(
659 $menu_name = "" // non consistent default...
660 ) {
661 for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu
662 $this->tree[$cnt]["child_of_root_node"] = ($this->tree[$cnt]["level"] == 1);
663 $this->tree[$cnt]["parsed_text"] = stripslashes($this->tree[$cnt]["text"]);
664 $this->tree[$cnt]["parsed_href"] = (ereg_replace(" ", "", $this->tree[$cnt]["href"]) == "") ? "#" : $this->prependedUrl . $this->tree[$cnt]["href"];
665 $this->tree[$cnt]["parsed_title"] = ($this->tree[$cnt]["title"] == "") ? "" : " title=\"" . addslashes($this->tree[$cnt]["title"]) . "\"";
666 $fooimg = $this->imgdir . $this->tree[$cnt]["icon"];
667 if ($this->tree[$cnt]["icon"] == "" || !(file_exists($fooimg))) {
668 $this->tree[$cnt]["parsed_icon"] = "";
669 } else {
670 $this->tree[$cnt]["parsed_icon"] = $this->tree[$cnt]["icon"];
671 $foobar = getimagesize($fooimg);
672 $this->tree[$cnt]["iconwidth"] = $foobar[0];
673 $this->tree[$cnt]["iconheight"] = $foobar[1];
674 }
675 $this->tree[$cnt]["parsed_target"] = ($this->tree[$cnt]["target"] == "") ? "" : " target=\"" . $this->tree[$cnt]["target"] . "\"";
676// $this->tree[$cnt]["expanded"] = ($this->tree[$cnt]["expanded"] == "") ? 0 : $this->tree[$cnt]["expanded"];
677 $this->_maxLevel[$menu_name] = max($this->_maxLevel[$menu_name], $this->tree[$cnt]["level"]);
678 if ($this->tree[$cnt]["level"] == 1) {
679 $this->_firstLevelCnt[$menu_name]++;
680 }
681 }
682}
683
684/**
685* Method to handle errors
686* @access private
687* @param string $errormsg the error message
688* @return void
689*/
690function error($errormsg) {
691 print "<b>LayersMenu Error:</b> " . $errormsg . "<br />\n";
692 if ($this->haltOnError == "yes") {
693 die("<b>Halted.</b><br />\n");
694 }
695}
696
697} /* END OF CLASS */
698
699?>