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