layersmenu-common.inc.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955
  1. <?php
  2. // PHP Layers Menu 3.2.0-rc (C) 2001-2004 Marco Pratesi - http://www.marcopratesi.it/
  3. /**
  4. * This file contains the code of the LayersMenuCommon class.
  5. * @package PHPLayersMenu
  6. */
  7. /**
  8. * This is the "common" class of the PHP Layers Menu library.
  9. *
  10. * You need to include PEAR.php and DB.php if (and only if) you want to use the DB support provided by ths class.
  11. *
  12. * @version 3.2.0-rc
  13. * @package PHPLayersMenu
  14. */
  15. class LayersMenuCommon
  16. {
  17. /**
  18. * The name of the package
  19. * @access private
  20. * @var string
  21. */
  22. var $_packageName;
  23. /**
  24. * The version of the package
  25. * @access private
  26. * @var string
  27. */
  28. var $version;
  29. /**
  30. * The copyright of the package
  31. * @access private
  32. * @var string
  33. */
  34. var $copyright;
  35. /**
  36. * The author of the package
  37. * @access private
  38. * @var string
  39. */
  40. var $author;
  41. /**
  42. * URL to be prepended to the menu hrefs
  43. * @access private
  44. * @var string
  45. */
  46. var $prependedUrl = '';
  47. /**
  48. * Do you want that code execution halts on error?
  49. * @access private
  50. * @var string
  51. */
  52. var $haltOnError = 'yes';
  53. /**
  54. * The base directory where the package is installed
  55. * @access private
  56. * @var string
  57. */
  58. var $dirroot;
  59. /**
  60. * The "libjs" directory of the package
  61. * @access private
  62. * @var string
  63. */
  64. var $libjsdir;
  65. /**
  66. * The directory where images related to the menu can be found
  67. * @access private
  68. * @var string
  69. */
  70. var $imgdir;
  71. /**
  72. * The http path corresponding to imgdir
  73. * @access private
  74. * @var string
  75. */
  76. var $imgwww;
  77. /**
  78. * The directory where icons of menu items can be found
  79. * @access private
  80. * @var string
  81. */
  82. var $icondir;
  83. /**
  84. * The http path corresponding to icondir
  85. * @access private
  86. * @var string
  87. */
  88. var $iconwww;
  89. /**
  90. * This array may contain width and height of all icons
  91. * @access private
  92. * @var integer
  93. */
  94. var $iconsize = array();
  95. /**
  96. * If this var is false, width and height of icons have to be detected; if this var is true, width and height of icons are not detected and are retrieved from the iconsize array
  97. * @access private
  98. * @var boolean
  99. */
  100. var $issetIconsize = false;
  101. /**
  102. * The directory where templates can be found
  103. * @access private
  104. * @var string
  105. */
  106. var $tpldir;
  107. /**
  108. * The string containing the menu structure
  109. * @access private
  110. * @var string
  111. */
  112. var $menuStructure;
  113. /**
  114. * It counts nodes for all menus
  115. * @access private
  116. * @var integer
  117. */
  118. var $_nodesCount;
  119. /**
  120. * A multi-dimensional array to store informations for each menu entry
  121. * @access private
  122. * @var array
  123. */
  124. var $tree;
  125. /**
  126. * A multi-dimensional array used only with the DB support; for each $menu_name, it stores the $cnt associated to each item id
  127. *
  128. * This array is needed for selection of the current item
  129. * through the corresponding id (see the DB table structure)
  130. * as, internally, items are stored, sorted and addressed in terms of $cnt
  131. *
  132. * @access private
  133. * @var array
  134. */
  135. var $treecnt;
  136. /**
  137. * The maximum hierarchical level of menu items
  138. * @access private
  139. * @var integer
  140. */
  141. var $_maxLevel;
  142. /**
  143. * An array that counts the number of first level items for each menu
  144. * @access private
  145. * @var array
  146. */
  147. var $_firstLevelCnt;
  148. /**
  149. * An array containing the number identifying the first item of each menu
  150. * @access private
  151. * @var array
  152. */
  153. var $_firstItem;
  154. /**
  155. * An array containing the number identifying the last item of each menu
  156. * @access private
  157. * @var array
  158. */
  159. var $_lastItem;
  160. /**
  161. * Data Source Name: the connection string for PEAR DB
  162. * @access private
  163. * @var string
  164. */
  165. var $dsn = 'pgsql://dbuser:dbpass@dbhost/dbname';
  166. /**
  167. * DB connections are either persistent or not persistent
  168. * @access private
  169. * @var boolean
  170. */
  171. var $persistent = false;
  172. /**
  173. * Name of the table storing data describing the menu
  174. * @access private
  175. * @var string
  176. */
  177. var $tableName = 'phplayersmenu';
  178. /**
  179. * Name of the i18n table corresponding to $tableName
  180. * @access private
  181. * @var string
  182. */
  183. var $tableName_i18n = 'phplayersmenu_i18n';
  184. /**
  185. * Names of fields of the table storing data describing the menu
  186. *
  187. * default field names correspond to the same field names foreseen
  188. * by the menu structure format
  189. *
  190. * @access private
  191. * @var array
  192. */
  193. var $tableFields = array(
  194. 'id' => 'id',
  195. 'parent_id' => 'parent_id',
  196. 'text' => 'text',
  197. 'href' => 'href',
  198. 'title' => 'title',
  199. 'icon' => 'icon',
  200. 'target' => 'target',
  201. 'orderfield' => 'orderfield',
  202. 'expanded' => 'expanded'
  203. );
  204. /**
  205. * Names of fields of the i18n table corresponding to $tableName
  206. * @access private
  207. * @var array
  208. */
  209. var $tableFields_i18n = array(
  210. 'language' => 'language',
  211. 'id' => 'id',
  212. 'text' => 'text',
  213. 'title' => 'title'
  214. );
  215. /**
  216. * A temporary array to store data retrieved from the DB and to perform the depth-first search
  217. * @access private
  218. * @var array
  219. */
  220. var $_tmpArray = array();
  221. /**
  222. * The constructor method; it initializates the menu system
  223. * @return void
  224. */
  225. function LayersMenuCommon()
  226. {
  227. $this->_packageName = 'PHP Layers Menu';
  228. $this->version = '3.2.0-rc';
  229. $this->copyright = '(C) 2001-2004';
  230. $this->author = 'Marco Pratesi - http://www.marcopratesi.it/';
  231. $this->prependedUrl = '';
  232. $this->dirroot = './';
  233. $this->libjsdir = './libjs/';
  234. $this->imgdir = './menuimages/';
  235. $this->imgwww = 'menuimages/';
  236. $this->icondir = './menuicons/';
  237. $this->iconwww = 'menuicons/';
  238. $this->tpldir = './templates/';
  239. $this->menuStructure = '';
  240. $this->separator = '|';
  241. $this->_nodesCount = 0;
  242. $this->tree = array();
  243. $this->treecnt = array();
  244. $this->_maxLevel = array();
  245. $this->_firstLevelCnt = array();
  246. $this->_firstItem = array();
  247. $this->_lastItem = array();
  248. }
  249. /**
  250. * The method to set the prepended URL
  251. * @access public
  252. * @return boolean
  253. */
  254. function setPrependedUrl($prependedUrl)
  255. {
  256. // We do not perform any check
  257. $this->prependedUrl = $prependedUrl;
  258. return true;
  259. }
  260. /**
  261. * The method to set the dirroot directory
  262. * @access public
  263. * @return boolean
  264. */
  265. function setDirrootCommon($dirroot)
  266. {
  267. if (!is_dir($dirroot)) {
  268. $this->error("setDirroot: $dirroot is not a directory.");
  269. return false;
  270. }
  271. if (substr($dirroot, -1) != '/') {
  272. $dirroot .= '/';
  273. }
  274. $oldlength = strlen($this->dirroot);
  275. $foobar = strpos($this->libjsdir, $this->dirroot);
  276. if (!($foobar === false || $foobar != 0)) {
  277. $this->libjsdir = $dirroot . substr($this->libjsdir, $oldlength);
  278. }
  279. $foobar = strpos($this->imgdir, $this->dirroot);
  280. if (!($foobar === false || $foobar != 0)) {
  281. $this->imgdir = $dirroot . substr($this->imgdir, $oldlength);
  282. }
  283. $foobar = strpos($this->icondir, $this->dirroot);
  284. if (!($foobar === false || $foobar != 0)) {
  285. $this->icondir = $dirroot . substr($this->icondir, $oldlength);
  286. }
  287. $foobar = strpos($this->tpldir, $this->dirroot);
  288. if (!($foobar === false || $foobar != 0)) {
  289. $this->tpldir = $dirroot . substr($this->tpldir, $oldlength);
  290. }
  291. $this->dirroot = $dirroot;
  292. return true;
  293. }
  294. /**
  295. * The method to set the libjsdir directory
  296. * @access public
  297. * @return boolean
  298. */
  299. function setLibjsdir($libjsdir)
  300. {
  301. if ($libjsdir != '' && substr($libjsdir, -1) != '/') {
  302. $libjsdir .= '/';
  303. }
  304. if ($libjsdir == '' || substr($libjsdir, 0, 1) != '/') {
  305. $foobar = strpos($libjsdir, $this->dirroot);
  306. if ($foobar === false || $foobar != 0) {
  307. $libjsdir = $this->dirroot . $libjsdir;
  308. }
  309. }
  310. if (!is_dir($libjsdir)) {
  311. $this->error("setLibjsdir: $libjsdir is not a directory.");
  312. return false;
  313. }
  314. $this->libjsdir = $libjsdir;
  315. return true;
  316. }
  317. /**
  318. * The method to set the imgdir directory
  319. * @access public
  320. * @return boolean
  321. */
  322. function setImgdir($imgdir)
  323. {
  324. if ($imgdir != '' && substr($imgdir, -1) != '/') {
  325. $imgdir .= '/';
  326. }
  327. if ($imgdir == '' || substr($imgdir, 0, 1) != '/') {
  328. $foobar = strpos($imgdir, $this->dirroot);
  329. if ($foobar === false || $foobar != 0) {
  330. $imgdir = $this->dirroot . $imgdir;
  331. }
  332. }
  333. if (!is_dir($imgdir)) {
  334. $this->error("setImgdir: $imgdir is not a directory.");
  335. return false;
  336. }
  337. $this->imgdir = $imgdir;
  338. return true;
  339. }
  340. /**
  341. * The method to set imgwww
  342. * @access public
  343. * @return void
  344. */
  345. function setImgwww($imgwww)
  346. {
  347. if ($imgwww != '' && substr($imgwww, -1) != '/') {
  348. $imgwww .= '/';
  349. }
  350. $this->imgwww = $imgwww;
  351. }
  352. /**
  353. * The method to set the icondir directory
  354. * @access public
  355. * @return boolean
  356. */
  357. function setIcondir($icondir)
  358. {
  359. if ($icondir != '' && substr($icondir, -1) != '/') {
  360. $icondir .= '/';
  361. }
  362. if ($icondir == '' || substr($icondir, 0, 1) != '/') {
  363. $foobar = strpos($icondir, $this->dirroot);
  364. if ($foobar === false || $foobar != 0) {
  365. $icondir = $this->dirroot . $icondir;
  366. }
  367. }
  368. if (!is_dir($icondir)) {
  369. $this->error("setIcondir: $icondir is not a directory.");
  370. return false;
  371. }
  372. $this->icondir = $icondir;
  373. return true;
  374. }
  375. /**
  376. * The method to set iconwww
  377. * @access public
  378. * @return void
  379. */
  380. function setIconwww($iconwww)
  381. {
  382. if ($iconwww != '' && substr($iconwww, -1) != '/') {
  383. $iconwww .= '/';
  384. }
  385. $this->iconwww = $iconwww;
  386. }
  387. /**
  388. * The method to set the iconsize array
  389. * @access public
  390. * @return void
  391. */
  392. function setIconsize($width, $height)
  393. {
  394. $this->iconsize['width'] = ($width == (int) $width) ? $width : 0;
  395. $this->iconsize['height'] = ($height == (int) $height) ? $height : 0;
  396. $this->issetIconsize = true;
  397. }
  398. /**
  399. * The method to unset the iconsize array
  400. * @access public
  401. * @return void
  402. */
  403. function unsetIconsize()
  404. {
  405. unset($this->iconsize['width']);
  406. unset($this->iconsize['height']);
  407. $this->issetIconsize = false;
  408. }
  409. /**
  410. * The method to set the tpldir directory
  411. * @access public
  412. * @return boolean
  413. */
  414. function setTpldirCommon($tpldir)
  415. {
  416. if ($tpldir != '' && substr($tpldir, -1) != '/') {
  417. $tpldir .= '/';
  418. }
  419. if ($tpldir == '' || substr($tpldir, 0, 1) != '/') {
  420. $foobar = strpos($tpldir, $this->dirroot);
  421. if ($foobar === false || $foobar != 0) {
  422. $tpldir = $this->dirroot . $tpldir;
  423. }
  424. }
  425. if (!is_dir($tpldir)) {
  426. $this->error("setTpldir: $tpldir is not a directory.");
  427. return false;
  428. }
  429. $this->tpldir = $tpldir;
  430. return true;
  431. }
  432. /**
  433. * The method to read the menu structure from a file
  434. * @access public
  435. * @param string $tree_file the menu structure file
  436. * @return boolean
  437. */
  438. function setMenuStructureFile($tree_file)
  439. {
  440. if (!($fd = fopen($tree_file, 'r'))) {
  441. $this->error("setMenuStructureFile: unable to open file $tree_file.");
  442. return false;
  443. }
  444. $this->menuStructure = '';
  445. while ($buffer = fgets($fd, 4096)) {
  446. $buffer = ereg_replace(chr(13), '', $buffer); // Microsoft Stupidity Suppression
  447. $this->menuStructure .= $buffer;
  448. }
  449. fclose($fd);
  450. if ($this->menuStructure == '') {
  451. $this->error("setMenuStructureFile: $tree_file is empty.");
  452. return false;
  453. }
  454. return true;
  455. }
  456. /**
  457. * The method to set the menu structure passing it through a string
  458. * @access public
  459. * @param string $tree_string the menu structure string
  460. * @return boolean
  461. */
  462. function setMenuStructureString($tree_string)
  463. {
  464. $this->menuStructure = ereg_replace(chr(13), '', $tree_string); // Microsoft Stupidity Suppression
  465. if ($this->menuStructure == '') {
  466. $this->error('setMenuStructureString: empty string.');
  467. return false;
  468. }
  469. return true;
  470. }
  471. /**
  472. * The method to set the value of separator
  473. * @access public
  474. * @return void
  475. */
  476. function setSeparator($separator)
  477. {
  478. $this->separator = $separator;
  479. }
  480. /**
  481. * The method to set parameters for the DB connection
  482. * @access public
  483. * @param string $dns Data Source Name: the connection string for PEAR DB
  484. * @param bool $persistent DB connections are either persistent or not persistent
  485. * @return boolean
  486. */
  487. function setDBConnParms($dsn, $persistent=false)
  488. {
  489. if (!is_string($dsn)) {
  490. $this->error('initdb: $dsn is not an string.');
  491. return false;
  492. }
  493. if (!is_bool($persistent)) {
  494. $this->error('initdb: $persistent is not a boolean.');
  495. return false;
  496. }
  497. $this->dsn = $dsn;
  498. $this->persistent = $persistent;
  499. return true;
  500. }
  501. /**
  502. * The method to set the name of the table storing data describing the menu
  503. * @access public
  504. * @param string
  505. * @return boolean
  506. */
  507. function setTableName($tableName)
  508. {
  509. if (!is_string($tableName)) {
  510. $this->error('setTableName: $tableName is not a string.');
  511. return false;
  512. }
  513. $this->tableName = $tableName;
  514. return true;
  515. }
  516. /**
  517. * The method to set the name of the i18n table corresponding to $tableName
  518. * @access public
  519. * @param string
  520. * @return boolean
  521. */
  522. function setTableName_i18n($tableName_i18n)
  523. {
  524. if (!is_string($tableName_i18n)) {
  525. $this->error('setTableName_i18n: $tableName_i18n is not a string.');
  526. return false;
  527. }
  528. $this->tableName_i18n = $tableName_i18n;
  529. return true;
  530. }
  531. /**
  532. * The method to set names of fields of the table storing data describing the menu
  533. * @access public
  534. * @param array
  535. * @return boolean
  536. */
  537. function setTableFields($tableFields)
  538. {
  539. if (!is_array($tableFields)) {
  540. $this->error('setTableFields: $tableFields is not an array.');
  541. return false;
  542. }
  543. if (count($tableFields) == 0) {
  544. $this->error('setTableFields: $tableFields is a zero-length array.');
  545. return false;
  546. }
  547. reset ($tableFields);
  548. while (list($key, $value) = each($tableFields)) {
  549. $this->tableFields[$key] = ($value == '') ? "''" : $value;
  550. }
  551. return true;
  552. }
  553. /**
  554. * The method to set names of fields of the i18n table corresponding to $tableName
  555. * @access public
  556. * @param array
  557. * @return boolean
  558. */
  559. function setTableFields_i18n($tableFields_i18n)
  560. {
  561. if (!is_array($tableFields_i18n)) {
  562. $this->error('setTableFields_i18n: $tableFields_i18n is not an array.');
  563. return false;
  564. }
  565. if (count($tableFields_i18n) == 0) {
  566. $this->error('setTableFields_i18n: $tableFields_i18n is a zero-length array.');
  567. return false;
  568. }
  569. reset ($tableFields_i18n);
  570. while (list($key, $value) = each($tableFields_i18n)) {
  571. $this->tableFields_i18n[$key] = ($value == '') ? "''" : $value;
  572. }
  573. return true;
  574. }
  575. /**
  576. * The method to parse the current menu structure and correspondingly update related variables
  577. * @access public
  578. * @param string $menu_name the name to be attributed to the menu
  579. * whose structure has to be parsed
  580. * @return void
  581. */
  582. function parseStructureForMenu(
  583. $menu_name = '' // non consistent default...
  584. )
  585. {
  586. $this->_maxLevel[$menu_name] = 0;
  587. $this->_firstLevelCnt[$menu_name] = 0;
  588. $this->_firstItem[$menu_name] = $this->_nodesCount + 1;
  589. $cnt = $this->_firstItem[$menu_name];
  590. $menuStructure = $this->menuStructure;
  591. /* *********************************************** */
  592. /* Partially based on a piece of code taken from */
  593. /* TreeMenu 1.1 - Bjorge Dijkstra (bjorge@gmx.net) */
  594. /* *********************************************** */
  595. while ($menuStructure != '') {
  596. $before_cr = strcspn($menuStructure, "\n");
  597. $buffer = substr($menuStructure, 0, $before_cr);
  598. $menuStructure = substr($menuStructure, $before_cr+1);
  599. if (substr($buffer, 0, 1) == '#') {
  600. continue; // commented item line...
  601. }
  602. $tmp = rtrim($buffer);
  603. $node = explode($this->separator, $tmp);
  604. for ($i=count($node); $i<=6; $i++) {
  605. $node[$i] = '';
  606. }
  607. $this->tree[$cnt]['level'] = strlen($node[0]);
  608. $this->tree[$cnt]['text'] = $node[1];
  609. $this->tree[$cnt]['href'] = $node[2];
  610. $this->tree[$cnt]['title'] = $node[3];
  611. $this->tree[$cnt]['icon'] = $node[4];
  612. $this->tree[$cnt]['target'] = $node[5];
  613. $this->tree[$cnt]['expanded'] = $node[6];
  614. $cnt++;
  615. }
  616. /* *********************************************** */
  617. $this->_lastItem[$menu_name] = count($this->tree);
  618. $this->_nodesCount = $this->_lastItem[$menu_name];
  619. $this->tree[$this->_lastItem[$menu_name]+1]['level'] = 0;
  620. $this->_postParse($menu_name);
  621. }
  622. /**
  623. * The method to parse the current menu table and correspondingly update related variables
  624. * @access public
  625. * @param string $menu_name the name to be attributed to the menu
  626. * whose structure has to be parsed
  627. * @param string $language i18n language; either omit it or pass
  628. * an empty string ('') if you do not want to use any i18n table
  629. * @return void
  630. */
  631. function scanTableForMenu(
  632. $menu_name = '', // non consistent default...
  633. $language = ''
  634. )
  635. {
  636. $this->_maxLevel[$menu_name] = 0;
  637. $this->_firstLevelCnt[$menu_name] = 0;
  638. unset($this->tree[$this->_nodesCount+1]);
  639. $this->_firstItem[$menu_name] = $this->_nodesCount + 1;
  640. /* BEGIN BENCHMARK CODE
  641. $time_start = $this->_getmicrotime();
  642. /* END BENCHMARK CODE */
  643. $db = DB::connect($this->dsn, $this->persistent);
  644. if (DB::isError($db)) {
  645. $this->error('scanTableForMenu: ' . $db->getMessage());
  646. }
  647. $dbresult = $db->query('
  648. SELECT ' .
  649. $this->tableFields['id'] . ' AS id, ' .
  650. $this->tableFields['parent_id'] . ' AS parent_id, ' .
  651. $this->tableFields['text'] . ' AS text, ' .
  652. $this->tableFields['href'] . ' AS href, ' .
  653. $this->tableFields['title'] . ' AS title, ' .
  654. $this->tableFields['icon'] . ' AS icon, ' .
  655. $this->tableFields['target'] . ' AS target, ' .
  656. $this->tableFields['expanded'] . ' AS expanded
  657. FROM ' . $this->tableName . '
  658. WHERE ' . $this->tableFields['id'] . ' <> 1
  659. ORDER BY ' . $this->tableFields['orderfield'] . ', ' . $this->tableFields['text'] . ' ASC
  660. ');
  661. $this->_tmpArray = array();
  662. while ($dbresult->fetchInto($row, DB_FETCHMODE_ASSOC)) {
  663. $this->_tmpArray[$row['id']]['parent_id'] = $row['parent_id'];
  664. $this->_tmpArray[$row['id']]['text'] = $row['text'];
  665. $this->_tmpArray[$row['id']]['href'] = $row['href'];
  666. $this->_tmpArray[$row['id']]['title'] = $row['title'];
  667. $this->_tmpArray[$row['id']]['icon'] = $row['icon'];
  668. $this->_tmpArray[$row['id']]['target'] = $row['target'];
  669. $this->_tmpArray[$row['id']]['expanded'] = $row['expanded'];
  670. }
  671. if ($language != '') {
  672. $dbresult = $db->query('
  673. SELECT ' .
  674. $this->tableFields_i18n['id'] . ' AS id, ' .
  675. $this->tableFields_i18n['text'] . ' AS text, ' .
  676. $this->tableFields_i18n['title'] . ' AS title
  677. FROM ' . $this->tableName_i18n . '
  678. WHERE ' . $this->tableFields_i18n['id'] . ' <> 1
  679. AND ' . $this->tableFields_i18n['language'] . ' = ' . "'$language'" . '
  680. ');
  681. while ($dbresult->fetchInto($row, DB_FETCHMODE_ASSOC)) {
  682. if (isset($this->_tmpArray[$row['id']])) {
  683. $this->_tmpArray[$row['id']]['text'] = $row['text'];
  684. $this->_tmpArray[$row['id']]['title'] = $row['title'];
  685. }
  686. }
  687. }
  688. unset($dbresult);
  689. unset($row);
  690. $this->_depthFirstSearch($menu_name, $this->_tmpArray, 1, 1);
  691. /* BEGIN BENCHMARK CODE
  692. $time_end = $this->_getmicrotime();
  693. $time = $time_end - $time_start;
  694. print "TIME ELAPSED = $time\n<br>";
  695. /* END BENCHMARK CODE */
  696. $this->_lastItem[$menu_name] = count($this->tree);
  697. $this->_nodesCount = $this->_lastItem[$menu_name];
  698. $this->tree[$this->_lastItem[$menu_name]+1]['level'] = 0;
  699. $this->_postParse($menu_name);
  700. }
  701. function _getmicrotime()
  702. {
  703. list($usec, $sec) = explode(' ', microtime());
  704. return ((float) $usec + (float) $sec);
  705. }
  706. /**
  707. * Recursive method to perform the depth-first search of the tree data taken from the current menu table
  708. * @access private
  709. * @param string $menu_name the name to be attributed to the menu
  710. * whose structure has to be parsed
  711. * @param array $tmpArray the temporary array that stores data to perform
  712. * the depth-first search
  713. * @param integer $parent_id id of the item whose children have
  714. * to be searched for
  715. * @param integer $level the hierarchical level of children to be searched for
  716. * @return void
  717. */
  718. function _depthFirstSearch($menu_name, $tmpArray, $parent_id=1, $level=1)
  719. {
  720. reset ($tmpArray);
  721. while (list($id, $foobar) = each($tmpArray)) {
  722. if ($foobar['parent_id'] == $parent_id) {
  723. unset($tmpArray[$id]);
  724. unset($this->_tmpArray[$id]);
  725. $cnt = count($this->tree) + 1;
  726. $this->tree[$cnt]['level'] = $level;
  727. $this->tree[$cnt]['text'] = $foobar['text'];
  728. $this->tree[$cnt]['href'] = $foobar['href'];
  729. $this->tree[$cnt]['title'] = $foobar['title'];
  730. $this->tree[$cnt]['icon'] = $foobar['icon'];
  731. $this->tree[$cnt]['target'] = $foobar['target'];
  732. $this->tree[$cnt]['expanded'] = $foobar['expanded'];
  733. $this->treecnt[$menu_name][$id] = $cnt;
  734. unset($foobar);
  735. if ($id != $parent_id) {
  736. $this->_depthFirstSearch($menu_name, $this->_tmpArray, $id, $level+1);
  737. }
  738. }
  739. }
  740. }
  741. /**
  742. * A method providing parsing needed after both file/string parsing and DB table parsing
  743. * @access private
  744. * @param string $menu_name the name of the menu for which the parsing
  745. * has to be performed
  746. * @return void
  747. */
  748. function _postParse(
  749. $menu_name = '' // non consistent default...
  750. )
  751. {
  752. for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu
  753. $this->tree[$cnt]['child_of_root_node'] = ($this->tree[$cnt]['level'] == 1);
  754. $this->tree[$cnt]['parsed_text'] = stripslashes($this->tree[$cnt]['text']);
  755. $this->tree[$cnt]['parsed_href'] = (ereg_replace(' ', '', $this->tree[$cnt]['href']) == '') ? '#' : $this->prependedUrl . $this->tree[$cnt]['href'];
  756. $this->tree[$cnt]['parsed_title'] = ($this->tree[$cnt]['title'] == '') ? '' : ' title="' . stripslashes($this->tree[$cnt]['title']) . '"';
  757. $fooimg = $this->icondir . $this->tree[$cnt]['icon'];
  758. if ($this->tree[$cnt]['icon'] != '' && (substr($this->tree[$cnt]['icon'], 0, 7) == 'http://' || substr($this->tree[$cnt]['icon'], 0, 8) == 'https://')) {
  759. $this->tree[$cnt]['parsed_icon'] = $this->tree[$cnt]['icon'];
  760. if ($this->issetIconsize) {
  761. $this->tree[$cnt]['iconwidth'] = $this->iconsize['width'];
  762. $this->tree[$cnt]['iconheight'] = $this->iconsize['height'];
  763. } else {
  764. $foobar = getimagesize($this->tree[$cnt]['icon']);
  765. $this->tree[$cnt]['iconwidth'] = $foobar[0];
  766. $this->tree[$cnt]['iconheight'] = $foobar[1];
  767. }
  768. } elseif ($this->tree[$cnt]['icon'] != '' && file_exists($fooimg)) {
  769. $this->tree[$cnt]['parsed_icon'] = $this->iconwww . $this->tree[$cnt]['icon'];
  770. if ($this->issetIconsize) {
  771. $this->tree[$cnt]['iconwidth'] = $this->iconsize['width'];
  772. $this->tree[$cnt]['iconheight'] = $this->iconsize['height'];
  773. } else {
  774. $foobar = getimagesize($fooimg);
  775. $this->tree[$cnt]['iconwidth'] = $foobar[0];
  776. $this->tree[$cnt]['iconheight'] = $foobar[1];
  777. }
  778. } else {
  779. $this->tree[$cnt]['parsed_icon'] = '';
  780. }
  781. $this->tree[$cnt]['parsed_target'] = ($this->tree[$cnt]['target'] == '') ? '' : ' target="' . $this->tree[$cnt]['target'] . '"';
  782. // $this->tree[$cnt]['expanded'] = ($this->tree[$cnt]['expanded'] == '') ? 0 : $this->tree[$cnt]['expanded'];
  783. $this->_maxLevel[$menu_name] = max($this->_maxLevel[$menu_name], $this->tree[$cnt]['level']);
  784. if ($this->tree[$cnt]['level'] == 1) {
  785. $this->_firstLevelCnt[$menu_name]++;
  786. }
  787. }
  788. }
  789. /**
  790. * A method to replace strings in all URLs (hrefs) of a menu
  791. * @access public
  792. * @param string $menu_name the name of the menu for which the replacement
  793. * has to be performed
  794. * @param string $string the string to be replaced
  795. * @param string $value the replacement string
  796. * @return void
  797. */
  798. function replaceStringInUrls($menu_name, $string, $value)
  799. {
  800. for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu
  801. $this->tree[$cnt]['parsed_href'] = str_replace($string, $value, $this->tree[$cnt]['parsed_href']);
  802. }
  803. }
  804. /**
  805. * A method to set the same target for all links of a menu
  806. * @access public
  807. * @param string $menu_name the name of the menu for which the targets
  808. * have to be set
  809. * @param string $target the target to be set for all links
  810. * of the $menu_name menu
  811. * @return void
  812. */
  813. function setLinksTargets($menu_name, $target)
  814. {
  815. for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu
  816. $this->tree[$cnt]['parsed_target'] = ' target="' . $target . '"';
  817. }
  818. }
  819. /**
  820. * 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)
  821. * @access public
  822. * @param string $menu_name the name of the menu for which the current item
  823. * has to be selected
  824. * @param integer $count the line number of the current item
  825. * in the corresponding menu structure file
  826. * (excluding from the count commented out lines, if any)
  827. * @return void
  828. */
  829. function setSelectedItemByCount($menu_name, $count)
  830. {
  831. if ($count < 1) {
  832. $this->error("setSelectedItemByCount: the \$count argument is $count, but \$count can not be lower than 1");
  833. return;
  834. }
  835. if ($count > $this->_lastItem[$menu_name] - $this->_firstItem[$menu_name] + 1) {
  836. $this->error("setSelectedItemByCount: the \$count argument is $count and is larger than the number of items of the '$menu_name' menu");
  837. return;
  838. }
  839. $cnt = $this->_firstItem[$menu_name] + $count - 1;
  840. $this->tree[$cnt]['selected'] = true;
  841. }
  842. /**
  843. * 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
  844. * @access public
  845. * @param string $menu_name the name of the menu for which the current item
  846. * has to be selected
  847. * @param integer $id the id of the current item in the corresponding DB table
  848. * @return void
  849. */
  850. function setSelectedItemById($menu_name, $id)
  851. {
  852. if (!isset($this->treecnt[$menu_name][$id])) {
  853. $this->error("setSelectedItemById: there is not any item with \$id = $id in the '$menu_name' menu");
  854. return;
  855. }
  856. $cnt = $this->treecnt[$menu_name][$id];
  857. $this->tree[$cnt]['selected'] = true;
  858. }
  859. /**
  860. * A method to select the current item of $menu_name specifying a string that occurs in the current URL
  861. * @access public
  862. * @param string $menu_name the name of the menu for which the current item
  863. * has to be selected
  864. * @param string $url a string that occurs in the current URL
  865. * @return void
  866. */
  867. function setSelectedItemByUrl($menu_name, $url)
  868. {
  869. for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu
  870. if (!(strpos($this->tree[$cnt]['parsed_href'], $url) === false)) {
  871. $this->tree[$cnt]['selected'] = true;
  872. break;
  873. }
  874. }
  875. }
  876. /**
  877. * 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()
  878. * @access public
  879. * @param string $menu_name the name of the menu for which the current item
  880. * has to be selected
  881. * @param string $url_eregi the regular expression that matches
  882. * (a substring of) the current URL
  883. * @return void
  884. */
  885. function setSelectedItemByUrlEregi($menu_name, $url_eregi)
  886. {
  887. for ($cnt=$this->_firstItem[$menu_name]; $cnt<=$this->_lastItem[$menu_name]; $cnt++) { // this counter scans all nodes of the new menu
  888. if (eregi($url_eregi, $this->tree[$cnt]['parsed_href'])) {
  889. $this->tree[$cnt]['selected'] = true;
  890. break;
  891. }
  892. }
  893. }
  894. /**
  895. * Method to handle errors
  896. * @access private
  897. * @param string $errormsg the error message
  898. * @return void
  899. */
  900. function error($errormsg)
  901. {
  902. print "<b>LayersMenu Error:</b> $errormsg<br />\n";
  903. if ($this->haltOnError == 'yes') {
  904. die("<b>Halted.</b><br />\n");
  905. }
  906. }
  907. } /* END OF CLASS */
  908. ?>