2 /***************************************************************************
3 * Copyright (C) 2003-2011 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 /** Remove the cache for the current page.
69 public function removePageCache()
71 @unlink
($this->cacheFilename());
73 $page = glob($globals->spoolroot
. '/spool/templates_c/*cache_' . $this->name
. '.tpl.php');
74 if (count($page) > 0) {
79 /** Fetch the content of the wiki page.
81 private function fetchContent()
83 if (!is_null($this->content
)) {
86 $file = $this->filename();
87 if (!is_file($file)) {
90 $lines = explode("\n", file_get_contents($file));
91 $this->content
= array();
92 foreach ($lines as $line) {
93 @list
($k, $v) = explode('=', $line, 2);
94 $this->content
[$k] = $v;
98 /** Save the content of the wiki page based on the
101 private function saveContent()
103 if (is_null($this->content
)) {
107 foreach ($this->content
as $k => $v) {
110 return file_put_contents($this->filename(), implode("\n", $lines)) !== false
;
113 /** Get a field from the wiki content.
115 public function getField($name)
117 $this->fetchContent();
118 return @$this->content
[$name];
121 /** Fetch the permissions.
123 private function fetchPerms()
125 if (!is_null($this->perms
)) {
128 $this->fetchContent();
129 if (isset($this->content
['platal_perms'])) {
130 $this->perms
= explode(':', $this->content
['platal_perms']);
132 $this->perms
= self
::$defaulPerms;
136 /** Return read perms.
138 public function readPerms()
140 if (is_null($this->perms
)) {
143 return $this->perms
[0];
146 /** Check if the user can read the page.
148 public function canRead()
150 return self
::havePerms($this->readPerms());
153 /** Return write perms.
155 public function writePerms()
157 if (is_null($this->perms
)) {
160 return $this->perms
[1];
163 /** Check if the user can write the page.
165 public function canWrite()
167 return self
::havePerms($this->writePerms());
170 /** Set the permission level for the page.
172 public function setPerms($read, $write)
174 $this->fetchContent();
175 if (is_null($this->content
)) {
178 $this->content
['platal_perms'] = $read . ':' . $write;
179 $this->perms
= array($read, $write);
180 return $this->saveContent();
184 /** Check permission for RSS feed.
186 public function prepareFeed()
188 if ($this->canRead()) {
191 $uid = Platal
::session()->tokenAuth(Get
::v('user'), Get
::v('hash'));
192 if ($this->canRead()) {
198 /** Apply the read permissions for the current page.
200 public function applyReadPerms()
202 if ($this->canRead()) {
205 $this->applyPerms($this->readPerms());
208 /** Apply the write permissions for the current page.
210 public function applyWritePerms()
212 if ($this->canWrite()) {
215 $this->applyPerms($this->writePerms());
218 /** Build the cache for the page.
220 public function buildCache()
223 if (is_file($this->cacheFilename())) {
226 system('wget --no-check-certificate ' . escapeshellarg($globals->baseurl
. '/' . $this->path
) . ' -O /dev/null');
231 public function delete()
233 $file = $this->filename();
234 $cache = $this->cacheFilename();
235 if (is_file($cache)) {
238 if (!is_file($file)) {
245 /** Return the wiki storage dir.
247 public static function workDir()
250 return $globals->spoolroot
. '/spool/wiki.d';
253 /** Clear wiki cache.
255 public static function clearCache()
257 system('rm -f ' . self
::workDir() . '/cache_*');
261 /** Search links in the a page
263 private static function findLinks($line, $groupname)
266 if (preg_match_all('@\[\[([^~][^\]\|\?#]*)((\?|#)[^\]\|]+)?(\\|[^\]]+)?\]\]@', $line, $matches, PREG_OFFSET_CAPTURE
)) {
267 foreach ($matches[1] as $j => $link) if (!preg_match('@http://@', $link[0])) {
268 $mylink = str_replace('/','.',trim($link[0]));
269 $sup = trim(substr($matches[2][$j][0],1));
270 $alt = trim(substr($matches[4][$j][0],1));
271 $newlink = str_replace(' ','',ucwords($mylink));
272 if (strpos($newlink,'.') === false
) {
273 $newlink = $groupname.'.'.$newlink;
275 if (!$alt && $mylink != $newlink) {
276 $alt = trim($link[0]);
279 'pos' => $matches[0][$j][1],
280 'size' => strlen($matches[0][$j][0]),
284 'group' => substr($mylink, 0, strpos($mylink, '.')));
290 public function rename($newname, $changeLinks = true
)
292 $newpage = new PlWikiPage(str_replace('/', '.', $newname));
293 $cache = $this->cacheFilename();
294 if (is_file($cache)) {
298 list($groupname, ) = explode('.', $this->name
);
299 list($newgroupname, ) = explode('.', $newpage->name
);
301 $file = $this->filename();
302 $newfile = $newpage->filename();
303 if (!is_file($file)) {
304 // old page doesn't exist
307 if (!rename($file, $newfile)) {
308 // impossible to renama page
313 $this->name
= $newpage->name
;
314 $this->path
= $newpage->path
;
319 // change name inside this folder and ingroup links if changing group
320 $lines = explode("\n", file_get_contents($newfile));
322 foreach ($lines as $i => $line) {
323 list($k, $v) = explode('=', $line, 2);
324 if ($k == 'name' && $v == $pagename_dots) {
325 $lines[$i] = 'name=' . $newpage->name
;
327 } else if ($groupname != $newgroupname) {
328 $links = self
::findLinks($line, $groupname);
331 foreach ($links as $link) {
332 if ($link['group'] == $groupname) {
333 $newline .= substr($line, $last, $link['pos']);
334 $newline .= '[['.$link['href'].$link['sup'].($link['alt']?
(' |'.$link['alt']):'').']]';
335 $last = $link['pos']+
$link['size'];
340 $newline .= substr($line, $last);
341 $lines[$i] = $newline;
346 file_put_contents($newfile, join("\n", $lines));
348 // change wiki links in all wiki pages
349 $endname = substr($pagename_dots, strpos($this->name
, '.') +
1);
351 exec('grep ' . $endname . ' ' . self
::workDir() . '/* -sc', $pages);
352 foreach($pages as $line) {
353 if (preg_match('%/([^/:]+):([0-9]+)$%', $line, $vals) && $vals[2] > 0) {
355 $lines = explode("\n", file_get_contents(self
::workDir().'/'.$inpage));
357 // find all wiki links in page and change if linked to this page
358 foreach ($lines as $i => $line) {
359 $links = self
::findLinks($line, substr($inpage, 0, strpos($inpage, '.')));
362 foreach ($links as $link) {
363 if ($link['href'] == $pagename_dots) {
364 $newline .= substr($line, $last, $link['pos']);
365 $newline .= '[[' . $newname_dots . $link['sup'] . ($link['alt'] ?
(' |' . $link['alt']) : '') . ']]';
366 $last = $link['pos'] +
$link['size'];
371 $newline .= substr($line, $last);
372 $lines[$i] = $newline;
377 file_put_contents(self
::workDir() . '/' . $inpage, join("\n", $lines));
381 if ($changedLinks > 0) {
382 return $changedLinks;
384 $this->name
= $newpage->name
;
385 $this->path
= $newpage->path
;
389 /** Return the authentication level translation table.
391 public static function permOptions()
393 return array('public' => 'Public',
394 'logged' => 'Connecté',
395 'mdp' => 'Authentifié',
399 /** Check permissions.
401 public static function havePerms($perm)
409 return S
::identified();
417 /** Apply permissions.
419 public static function applyPerms($perm)
425 $ok = Platal
::session()->start(AUTH_PUBLIC +
1);
428 $ok = Platal
::session()->start(Platal
::session()->sureLevel());
433 $page =& Platal
::page();
434 $platal->force_login($page);
435 } else if ($perm == 'admin' && !S
::admin()) {
441 /** Return the current page.
443 public static function currentPage()
449 $words = explode('/', trim(Get
::v('n'), '/'));
450 if (count($words) == 2) {
451 return new PlWikiPage(join('.', $words));
454 // We are on NameSpace.Page, redirect to NameSpace/Page
455 array_unshift($words, $words[0]);
456 $b = array_pop($words);
457 $a = array_pop($words);
459 pl_redirect($a . '/' . $b);
464 public static function listPages()
466 $wiki_pages = array();
467 $dir = PlWikiPage
::workDir();
469 if ($dh = opendir($dir)) {
470 while (($file = readdir($dh)) !== false
) {
471 if ($file{0} >= 'A' && $file{0} <= 'Z') {
472 $wp = new PlWikiPage($file);
473 $wiki_pages[$file] = array('read' => $wp->readPerms(),
474 'edit' => $wp->writePerms(),
475 'cached' => is_file($wp->cacheFilename()));
485 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: