Release diogenes-0.9.22
[diogenes.git] / include / Barrel / Page.php
1 <?php
2 /*
3 * Copyright (C) 2003-2004 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 require_once 'Barrel/File.php';
22
23
24 /** This class describes a Barrel Page.
25 */
26 class Diogenes_Barrel_Page
27 {
28 /** The Barrel this Page belongs to. */
29 var $barrel;
30
31 /** The Page's properties */
32 var $props = array();
33
34
35 /** Construct a Barrel Page object.
36 *
37 * @param $barrel
38 * @param $props
39 */
40 function Diogenes_Barrel_Page(&$barrel, $props)
41 {
42 if (!is_object($barrel))
43 {
44 trigger_error("\$barrel is not an object!", E_USER_ERROR);
45 }
46
47 $this->barrel =& $barrel;
48 $this->props = array(
49 'PID' => 0,
50 'parent' => 0,
51 'location' => '',
52 'title' => '',
53 'perms' => 'public',
54 'wperms' => 'admin',
55 'status' => 0,
56 'template' => ''
57 );
58
59 if (is_array($props))
60 {
61 foreach (array_keys($props) as $key)
62 {
63 $this->props[$key] = $props[$key];
64 }
65 }
66 //echo "[" . $this->props['PID'] . "][". $this->props['location'] . "], parent : [".$this->props['parent']."]<br/>";
67 }
68
69
70 /** Delete a Barrel Page.
71 *
72 * @param $barrel
73 * @param $dir
74 * @param $caller
75 */
76 function delete(&$barrel, $dir, &$caller)
77 {
78 global $globals;
79
80 $loc = $barrel->getLocation($dir);
81 if (!$loc)
82 {
83 $caller->info("Error : not deleting page $dir\n");
84 return false;
85 }
86
87 $caller->info(__("Deleting page"). " '$loc'");
88
89 // check there are no child pages
90 $res = $globals->db->query("select PID from {$barrel->table_page} where parent=$dir");
91 $num = mysql_num_rows($res);
92 mysql_free_result($res);
93 if ($num > 0)
94 {
95 $caller->info(__("Not deleting page, it has child pages!"));
96 return false;
97 }
98
99 $rcs = $caller->getRcs();
100 $globals->db->query("delete from {$barrel->table_page} where PID=$dir");
101 $caller->log("page_delete","{$barrel->alias}:$loc");
102 system("rm -rf ". escapeshellarg($rcs->rcsPath($dir)));
103 system("rm -rf ". escapeshellarg($rcs->spoolPath($dir)));
104 $barrel->compileTree();
105 $barrel->readTree();
106 return true;
107 }
108
109
110 /** Read a Page's properties from database.
111 *
112 * @param $barrel
113 * @param $dir
114 */
115 function fromDb(&$barrel, $dir)
116 {
117 global $globals;
118 $retval = '';
119
120 $res = $globals->db->query("select * from {$barrel->table_page} where PID='$dir'");
121 if ($props = mysql_fetch_assoc($res)) {
122 $retval = new Diogenes_Barrel_Page($barrel, $props);
123 }
124 mysql_free_result($res);
125 return $retval;
126 }
127
128
129 /** Returns the location of a given file
130 *
131 * @param $file
132 */
133 function getLocation($file = '')
134 {
135 $dirloc = $this->barrel->getLocation($this->props['PID']);
136 $floc = (strlen($dirloc) ? "$dirloc/" : '') . $file;
137 return $floc;
138 }
139
140
141 /** Return the list of action applicable to the page
142 */
143 function make_actions()
144 {
145 global $globals;
146 $props = $this->props;
147
148 $actions = array(
149 array( __("view"), "../". $this->getLocation(), "view" ),
150 array( __("edit"), "edit?dir={$props['PID']}&amp;file=page.html", "edit"),
151 array( __("properties"), "pages?action=edit&amp;dir={$props['PID']}", "properties"),
152 array( __("revisions"), "files?action=revs&amp;dir={$props['PID']}&amp;target={$globals->htmlfile}","revisions")
153 );
154
155 if ($this->barrel->flags->hasFlag('plug'))
156 {
157 array_push($actions, array( __("plugins"), "plugins?plug_page={$props['PID']}", "plugins"));
158 }
159 if ($props['location'] != '')
160 array_push($actions, array( __("delete"), "javascript:page_delete('{$props['PID']}','{$props['location']}');","delete"));
161
162 return $globals->icons->get_action_icons($actions);
163 }
164
165
166 /** Build the 'Page' toolbar
167 */
168 function make_toolbar(&$caller)
169 {
170 global $globals;
171 $props = $this->props;
172
173 $topbar = array ();
174 $from = htmlentities($caller->script_uri(), ENT_COMPAT | ENT_HTML401, "ISO-8859-1");
175
176 if ($props['PID']) {
177 $hp = $this->barrel->getPID('');
178 array_push($topbar, array(__("home"), ($props['PID'] == $hp) ? "" : "files?dir=$hp"));
179 array_push($topbar, array(__("parent page"), $props['parent'] ? "files?dir=".$props['parent'] : ""));
180
181 array_push($topbar, array( __("browse files"), "files?dir={$props['PID']}" ));
182 array_push($topbar, array( __("page properties"), "pages?dir={$props['PID']}" ));
183 array_push($topbar, array( __("view page"), "../". $this->getLocation()));
184 array_push($topbar, array(__("add a page"), "pages?action=edit&amp;parent=".$props['PID']."&amp;from=$from") );
185 if ($this->barrel->flags->hasFlag("plug")) {
186 array_push($topbar, array( __("plugins"), "plugins?plug_page={$props['PID']}" ) );
187 }
188 }
189
190 return $topbar;
191
192 }
193
194
195 /** Build the 'File' toolbar
196 */
197 function make_doc_toolbar(&$rcs)
198 {
199 global $globals;
200
201 if ($globals->word_import && file_exists($rcs->spoolPath($this->props['PID'],$globals->wordfile)) ) {
202 $bfile = new Diogenes_Barrel_File($this, $globals->wordfile);
203 $toolbar = $bfile->make_toolbar(0);
204 } else {
205 $bfile = new Diogenes_Barrel_File($this, $globals->htmlfile);
206 $toolbar = $bfile->make_toolbar(1);
207 }
208 return $toolbar;
209 }
210
211
212 /** Write the page's properties to database and returns the PID of that page.
213 *
214 * @param $homepage
215 * @param $caller
216 */
217 function toDb($homepage, &$caller)
218 {
219 global $globals;
220
221 $props = $this->props;
222 // check we are not creating a publicly writable page
223 // on a barrel with PHP execution enabled!
224 if ($props['PID'])
225 {
226 $cache = $globals->plugins->readCache($this->barrel->pluginsCacheFile, $this->barrel->alias);
227 $plugs_active = $globals->plugins->cachedActive($cache, $this->barrel->alias, $props['PID']);
228 foreach($plugs_active as $plugentry)
229 {
230 $plug_h = $globals->plugins->load($plugentry);
231 if (!is_object($plug_h))
232 {
233 $caller->info("failed to load plugin '{$plugentry['plugin']}'");
234 return;
235 }
236 if (!$plug_h->allow_wperms($props['wperms']))
237 {
238 $caller->info("plugin '{$plugentry['plugin']}' is not allowed with write permissions '{$props['wperms']}'!");
239 return;
240 }
241 }
242 }
243
244 // check that the location is valid
245 if ($homepage)
246 {
247 // homepage
248 $props['location'] = '';
249
250 } else {
251
252 // check the location is well formatted
253 if (!preg_match("/^[a-zA-Z0-9_\-]*$/",$props['location']))
254 {
255 $caller->info(__("the page location cannot contain spaces or special characters"));
256 return;
257 }
258
259 // check this is not a forbidden location
260 if (in_array($props['location'], $globals->invalidlocations))
261 {
262 $caller->info(__("this location cannot be used, it is reserved by Diogenes"));
263 return;
264 }
265
266 }
267
268 // this is a new entry, initialise
269 if (!$props['PID']) {
270 // new entry
271 $globals->db->query("insert into {$this->barrel->table_page} set location='temp'");
272 $props['PID'] = mysql_insert_id();
273 $caller->info(__("Creating new page")." {$props['PID']}");
274
275 $caller->log("page_create","{$this->barrel->alias}:{$props['PID']}");
276
277 // initialise the page
278 $rcs = $caller->getRcs();
279 $rcs->newdir("",$props['PID']);
280 $rcs->commit($props['PID'],$globals->htmlfile,"");
281 } else {
282 $caller->log("page_props","{$this->barrel->alias}:{$props['PID']}");
283 }
284
285
286 // check we have a location
287 if (!$homepage and !strlen($props['location']))
288 {
289 $props['location'] = $props['PID'];
290 }
291
292
293 // check that the filiation is valid
294 if ($props['parent'])
295 {
296 // we need to insure that the parent is not already a child of the current page
297 $parent = $props['parent'];
298 while ($parent)
299 {
300 $oldparent = $parent;
301 $res = $globals->db->query("select parent from {$this->barrel->table_page} where PID=$parent");
302 list($parent) = mysql_fetch_row($res);
303 mysql_free_result($res);
304 if ($parent == $props['PID'])
305 {
306 $caller->info(__("A page cannot be its own parent (page $oldparent is a child of $parent)!"));
307 break;
308 }
309 }
310 }
311
312 // $caller->info("setting parent to {$props['parent']}");
313
314 // update data fields
315 $sql =
316 "update {$this->barrel->table_page} set ".
317 "parent='{$props['parent']}',".
318 "location='{$props['location']}',".
319 "title='{$props['title']}',".
320 "perms='{$props['perms']}',".
321 "wperms='{$props['wperms']}',".
322 "status='{$props['status']}',".
323 "template='{$props['template']}' ".
324 "where PID='{$props['PID']}'";
325 //$caller->info($sql);
326 $globals->db->query($sql);
327
328 // order by location
329 $globals->db->query("alter table {$this->barrel->table_page} order by parent,location");
330
331 // recompile tree
332 $this->barrel->compileTree();
333 $this->barrel->readTree();
334
335 return $props['PID'];
336 }
337
338 }
339
340 ?>