000b036e167c54913b84465a718e0446cb0a6817
[diogenes.git] / include / Barrel / Menu.php
1 <?php
2 /*
3 * Copyright (C) 2003-2005 Polytechnique.org
4 * http://opensource.polytechnique.org/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21
22 /** This class is used to generate the menu of a Diogenes barrel page.
23 */
24 class Diogenes_Barrel_Menu
25 {
26 /** Database handle */
27 var $dbh;
28
29 /** The database table holding the menus */
30 var $table_menu;
31
32 /** Constructs a Smarty-derived object to display contents within a barrel.
33 *
34 * @param $override_pathinfo
35 */
36 function Diogenes_Barrel_Menu(&$dbh, $table_menu)
37 {
38 $this->dbh =& $dbh;
39 $this->table_menu = $table_menu;
40 }
41
42 /** Delete the specified entry.
43 *
44 * @param $MID
45 * @param $caller
46 */
47 function deleteEntry($MID, &$caller)
48 {
49 if (mysql_num_rows($this->dbh->query("SELECT MID FROM {$this->table_menu} WHERE MIDpere=$MID")) > 0) {
50 $caller->info(__("The selected menu has child items, please remove them first."));
51 return;
52 }
53
54 /* erase the current entry */
55 $this->dbh->query("DELETE FROM {$this->table_menu} WHERE MID=$MID");
56
57 /* renumber the other menu entries so that they are between 1 and the number of entries */
58 $res = $this->dbh->query("SELECT MID FROM {$this->table_menu} WHERE MIDpere=$MIDpere ORDER BY ordre");
59 $i = 0;
60 while (list($MIDtoorder) = mysql_fetch_array($res)) {
61 $i++;
62 $this->dbh->query("UPDATE {$this->table_menu} SET ordre=$i WHERE MID=$MIDtoorder");
63 }
64 mysql_free_result($res);
65 }
66
67
68 /** Get the maximum child index for a given menu entry.
69 */
70 function maxChildIndex($MIDpere)
71 {
72 $res=$this->dbh->query("SELECT MAX(ordre) from {$this->table_menu} where MIDpere=$MIDpere");
73 list($maxOrdre)=mysql_fetch_row($res);
74 mysql_free_result($res);
75 return $maxOrdre;
76 }
77
78
79 /** Build the user-defined part of the menu.
80 *
81 * @param $PID
82 * @param $pid_to_url
83 */
84 function makeMenu($PID, $min_level, $pid_to_url)
85 {
86 // all menu entries from database
87 $mcache = $this->menuRead();
88
89 // try to figure out the current MID from the current PID
90 // and build filiation
91 $filiation = array();
92 foreach ($mcache as $mid => $mentry)
93 {
94 if ($mentry['pid'] == $PID)
95 $filiation = $this->menuToRoot($mcache, $mid, $filiation);
96 }
97
98 $menu = $this->menuRecurse($mcache, 0, $filiation, 0, $min_level, $pid_to_url);
99
100 return $menu;
101 }
102
103
104 /** Return the filiation to get to the root element.
105 *
106 * @param mcache
107 * @param MID
108 * @param path
109 */
110 function menuToRoot($mcache, $MID, $path) {
111 /* add ourself to the path */
112 array_push($path,$MID);
113
114 if ($MID) {
115 /* recursion */
116 return $this->menuToRoot($mcache, $mcache[$MID]['parent'], $path);
117 } else {
118 /* termination */
119 return $path;
120 }
121 }
122
123
124 /** Recursively add menu entries
125 *
126 * @param mcache
127 * @param MIDpere
128 * @param filiation
129 * @param level
130 * @param min_level
131 * @param pid_to_url
132 */
133 function menuRecurse($mcache, $MIDpere, $filiation, $level, $min_level, $pid_to_url) {
134 // the produced output
135 $out = array();
136
137 foreach ($mcache[$MIDpere]['children'] as $mid)
138 {
139 $mentry = $mcache[$mid];
140 // echo "pid : $pid, location : $location<br/>";
141 $entry = htmlentities(stripslashes($mentry['title']), ENT_QUOTES);
142 if ($mentry['pid'])
143 {
144 $link = call_user_func($pid_to_url, $mentry['pid']);
145 } else {
146 $link = $mentry['link'];
147 }
148 // decide whether this menu should be expanded
149 $expanded = ($min_level == 0) ||
150 ($level+1 < $min_level) ||
151 in_array($mid, $filiation);
152 array_push($out, array($level, $entry, $link, $expanded));
153 $out = array_merge($out, $this->menuRecurse($mcache, $mid, $filiation, $level+1, $min_level, $pid_to_url));
154 }
155
156 return $out;
157 }
158
159
160 /** Read this barrel's menu entries from database.
161 */
162 function menuRead()
163 {
164 $menu = array();
165 $res = $this->dbh->query("select MID,MIDpere,title,link,PID from {$this->table_menu} order by ordre");
166 while (list($mid, $parent, $title, $link, $pid) = mysql_fetch_row($res))
167 {
168 $menu[$mid]['parent'] = $parent;
169 $menu[$mid]['title'] = $title;
170 $menu[$mid]['link'] = $link;
171 $menu[$mid]['title'] = $title;
172 $menu[$mid]['pid'] = $pid;
173 if (!is_array($menu[$mid]['children']))
174 $menu[$mid]['children'] = array();
175
176 // register this entry with its parent
177 if (!is_array($menu[$parent]['children']))
178 $menu[$parent]['children'] = array();
179 array_push($menu[$parent]['children'], $mid);
180 }
181 mysql_free_result($res);
182 return $menu;
183 }
184
185
186 /**
187 * Swap entries $a and $b within $parent.
188 *
189 * @param $parent
190 * @param $a
191 * @param $b
192 */
193 function swapEntries($parent, $a, $b)
194 {
195 $res = $this->dbh->query("SELECT MID from {$this->table_menu} where MIDpere=$parent and (ordre=$a or ordre=$b) ORDER BY ordre");
196 /* make sure that $a <= $b */
197 if ($a > $b)
198 {
199 $c = $a;
200 $a = $b;
201 $b = $c;
202 }
203 /* perform swap */
204 list($MIDa) = mysql_fetch_row($res);
205 list($MIDb) = mysql_fetch_row($res);
206 mysql_free_result($res);
207
208 $this->dbh->query("UPDATE {$this->table_menu} SET ordre=$b WHERE MID=$MIDa");
209 $this->dbh->query("UPDATE {$this->table_menu} SET ordre=$a WHERE MID=$MIDb");
210 }
211
212 }
213
214 ?>