2 /***************************************************************************
3 * Copyright (C) 2003-2008 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
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. *
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. *
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 *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
22 /** This namespace groups all the methods relative to the integration
23 * of PmWiki into plat/al.
25 * pagename: A page name is NameSpace.Page and must be acceed trough
30 static private $permLevels = array('public' => 'Public',
31 'logged' => 'Connecté',
32 'mdp' => 'Authentifié',
34 static private $defaulPerms = array('logged', 'admin');
39 private $content = null
;
40 private $perms = null
;
42 /** Build a new page from a PmWiki page name (ie NameSpace.Page).
44 public function __construct($n)
50 $this->path
= str_replace('.', '/', $n);
53 /** Return the filename.
55 public function filename()
57 return self
::workDir() . '/' . $this->name
;
60 /** Return the filename for the cache file.
62 public function cacheFilename()
64 return self
::workDir() . '/cache_' . $this->name
. '.tpl';
67 /** Fetch the content of the wiki page.
69 private function fetchContent()
71 if (!is_null($this->content
)) {
74 $file = $this->filename();
75 if (!is_file($file)) {
78 $lines = explode("\n", file_get_contents($file));
79 $this->content
= array();
80 foreach ($lines as $line) {
81 @list
($k, $v) = explode('=', $line, 2);
82 $this->content
[$k] = $v;
86 /** Save the content of the wiki page based on the
89 private function saveContent()
91 if (is_null($this->content
)) {
95 foreach ($this->content
as $k => $v) {
98 return file_put_contents($this->filename(), implode("\n", $lines)) !== false
;
101 /** Get a field from the wiki content.
103 public function getField($name)
105 $this->fetchContent();
106 return @$this->content
[$name];
109 /** Fetch the permissions.
111 private function fetchPerms()
113 if (!is_null($this->perms
)) {
116 $this->fetchContent();
117 if (isset($this->content
['platal_perms'])) {
118 $this->perms
= explode(':', $this->content
['platal_perms']);
120 $this->perms
= self
::$defaulPerms;
124 /** Return read perms.
126 public function readPerms()
128 if (is_null($this->perms
)) {
131 return $this->perms
[0];
134 /** Check if the user can read the page.
136 public function canRead()
138 return self
::havePerms($this->readPerms());
141 /** Return write perms.
143 public function writePerms()
145 if (is_null($this->perms
)) {
148 return $this->perms
[1];
151 /** Check if the user can write the page.
153 public function canWrite()
155 return self
::havePerms($this->writePerms());
158 /** Set the permission level for the page.
160 public function setPerms($read, $write)
162 $this->fetchContent();
163 if (is_null($this->content
)) {
166 $this->content
['platal_perms'] = $read . ':' . $write;
167 $this->perms
= array($read, $write);
168 return $this->saveContent();
172 /** Check permission for RSS feed.
174 public function prepareFeed()
176 if ($this->canRead()) {
179 $uid = Platal
::session()->tokenAuth(Get
::v('user'), Get
::v('hash'));
180 if ($this->canRead()) {
186 /** Apply the read permissions for the current page.
188 public function applyReadPerms()
190 if ($this->canRead()) {
193 $this->applyPerms($this->readPerms());
196 /** Apply the write permissions for the current page.
198 public function applyWritePerms()
200 if ($this->canWrite()) {
203 $this->applyPerms($this->writePerms());
206 /** Build the cache for the page.
208 public function buildCache()
211 if (is_file($this->cacheFilename())) {
214 system('wget --no-check-certificate ' . escapeshellarg($globals->baseurl
. '/' . $this->path
) . ' -O /dev/null');
219 public function delete()
221 $file = $this->filename();
222 $cache = $this->cacheFilename();
223 if (is_file($cache)) {
226 if (!is_file($file)) {
233 /** Return the wiki storage dir.
235 public static function workDir()
238 return $globals->spoolroot
. '/spool/wiki.d';
241 /** Clear wiki cache.
243 public static function clearCache()
245 system('rm -f ' . self
::workDir() . '/cache_*');
249 /** Search links in the a page
251 private static function findLinks($line, $groupname)
254 if (preg_match_all('@\[\[([^~][^\]\|\?#]*)((\?|#)[^\]\|]+)?(\\|[^\]]+)?\]\]@', $line, $matches, PREG_OFFSET_CAPTURE
)) {
255 foreach ($matches[1] as $j => $link) if (!preg_match('@http://@', $link[0])) {
256 $mylink = str_replace('/','.',trim($link[0]));
257 $sup = trim(substr($matches[2][$j][0],1));
258 $alt = trim(substr($matches[4][$j][0],1));
259 $newlink = str_replace(' ','',ucwords($mylink));
260 if (strpos($newlink,'.') === false
) {
261 $newlink = $groupname.'.'.$newlink;
263 if (!$alt && $mylink != $newlink) {
264 $alt = trim($link[0]);
267 'pos' => $matches[0][$j][1],
268 'size' => strlen($matches[0][$j][0]),
272 'group' => substr($mylink, 0, strpos($mylink, '.')));
278 public function rename($newname, $changeLinks = true
)
280 $newpage = new PlWikiPage(str_replace('/', '.', $newname));
281 $cache = $this->cacheFilename();
282 if (is_file($cache)) {
286 list($groupname, ) = explode('.', $this->name
);
287 list($newgroupname, ) = explode('.', $newpage->name
);
289 $file = $this->filename();
290 $newfile = $newpage->filename();
291 if (!is_file($file)) {
292 // old page doesn't exist
295 if (!rename($file, $newfile)) {
296 // impossible to renama page
301 $this->name
= $newpage->name
;
302 $this->path
= $newpage->path
;
307 // change name inside this folder and ingroup links if changing group
308 $lines = explode("\n", file_get_contents($newfile));
310 foreach ($lines as $i => $line) {
311 list($k, $v) = explode('=', $line, 2);
312 if ($k == 'name' && $v == $pagename_dots) {
313 $lines[$i] = 'name=' . $newpage->name
;
315 } else if ($groupname != $newgroupname) {
316 $links = self
::findLinks($line, $groupname);
319 foreach ($links as $link) {
320 if ($link['group'] == $groupname) {
321 $newline .= substr($line, $last, $link['pos']);
322 $newline .= '[['.$link['href'].$link['sup'].($link['alt']?
(' |'.$link['alt']):'').']]';
323 $last = $link['pos']+
$link['size'];
328 $newline .= substr($line, $last);
329 $lines[$i] = $newline;
334 file_put_contents($newfile, join("\n", $lines));
336 // change wiki links in all wiki pages
337 $endname = substr($pagename_dots, strpos($this->name
, '.') +
1);
339 exec('grep ' . $endname . ' ' . self
::workDir() . '/* -sc', $pages);
340 foreach($pages as $line) {
341 if (preg_match('%/([^/:]+):([0-9]+)$%', $line, $vals) && $vals[2] > 0) {
343 $lines = explode("\n", file_get_contents(self
::workDir().'/'.$inpage));
345 // find all wiki links in page and change if linked to this page
346 foreach ($lines as $i => $line) {
347 $links = self
::findLinks($line, substr($inpage, 0, strpos($inpage, '.')));
350 foreach ($links as $link) {
351 if ($link['href'] == $pagename_dots) {
352 $newline .= substr($line, $last, $link['pos']);
353 $newline .= '[[' . $newname_dots . $link['sup'] . ($link['alt'] ?
(' |' . $link['alt']) : '') . ']]';
354 $last = $link['pos'] +
$link['size'];
359 $newline .= substr($line, $last);
360 $lines[$i] = $newline;
365 file_put_contents(self
::workDir() . '/' . $inpage, join("\n", $lines));
369 if ($changedLinks > 0) {
370 return $changedLinks;
372 $this->name
= $newpage->name
;
373 $this->path
= $newpage->path
;
377 /** Return the authentication level translation table.
379 public static function permOptions()
381 return array('public' => 'Public',
382 'logged' => 'Connecté',
383 'mdp' => 'Authentifié',
387 /** Check permissions.
389 public static function havePerms($perm)
398 return S
::has_perms();
404 /** Apply permissions.
406 public static function applyPerms($perm)
412 Platal
::session()->start(AUTH_PUBLIC +
1);
415 Platal
::session()->start(Platal
::session()->sureLevel());
420 /** Return the current page.
422 public static function currentPage()
428 $words = explode('/', trim(Get
::v('n'), '/'));
429 if (count($words) == 2) {
430 return new PlWikiPage(join('.', $words));
433 // We are on NameSpace.Page, redirect to NameSpace/Page
434 array_unshift($words, $words[0]);
435 $b = array_pop($words);
436 $a = array_pop($words);
438 pl_redirect($a . '/' . $b);
443 public static function listPages()
445 $wiki_pages = array();
446 $dir = PlWikiPage
::workDir();
448 if ($dh = opendir($dir)) {
449 while (($file = readdir($dh)) !== false
) {
450 if ($file{0} >= 'A' && $file{0} <= 'Z') {
451 $wp = new PlWikiPage($file);
452 $wiki_pages[$file] = array('read' => $wp->readPerms(),
453 'edit' => $wp->writePerms(),
454 'cached' => is_file($wp->cacheFilename()));
464 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: