]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/IncludePage.php
Detect and bail upon recursive inclusions.
[SourceForge/phpwiki.git] / lib / plugin / IncludePage.php
1 <?php // -*-php-*-
2 rcs_id('$Id: IncludePage.php,v 1.2 2001-12-06 18:26:50 dairiki Exp $');
3 /**
4  * IncludePage:  include text from another wiki page in this one
5  * usage:   <?plugin IncludePage page=OtherPage rev=6 quiet=1 words=50 lines=6?>
6  * author:  Joe Edelman <joe@orbis-tertius.net>
7  */
8
9 require_once('lib/transform.php');
10
11 class WikiPlugin_IncludePage
12 extends WikiPlugin
13 {
14     function getDefaultArguments() {
15         return array( 'page'  => false,    // the page to include
16                       'rev'   => false,    // the revision (defaults to most recent)
17                       'quiet' => false,    // if set, inclusion appears as normal content
18                       'words' => false,    // maximum number of words to include
19                       'lines' => false     // maximum number of lines to include
20                                         );
21     }
22
23     function firstNWordsOfContent( $n, $content ) {
24         $wordcount = 0; 
25         $new = array( );
26         foreach ($content as $line) {
27             $words = explode(' ', $line);
28             if ($wordcount + count($words) > $n) {
29                 $new[] = implode(' ', array_slice($words, 0, $n - $wordcount)) 
30                     . "... (first $n words)";
31                 return $new;
32             } else {
33                 $wordcount += count($words);
34                 $new[] = $line;
35             }
36         }
37         return $new;
38     }
39
40     function error($msg) {
41         // FIXME: better error reporting?
42         trigger_error($msg, E_USER_NOTICE);
43     }
44     
45     function run($dbi, $argstr, $request) {
46         
47         extract($this->getArgs($argstr, $request));
48
49         if (!$page) {
50             $this->error(_("no page specified"));
51             return '';
52         }
53
54         static $included_pages = array();
55         if ($page == $request->getArg('pagename')
56             || in_array($page, $included_pages)) {
57             $this->error(sprintf(_("recursive inclusion of page %s"), $page));
58             return '';
59         }
60         
61         $p = $dbi->getPage($page); 
62         
63         if ($rev) {
64             $r = $p->getRevision($rev);
65             if (!$r) {
66                 $this->error(sprintf(_("%s(%d): no such revision"), $page, $rev));
67                 return '';
68             }
69         } else {
70             $r = $p->getCurrentRevision();
71         }
72
73         $c = $r->getContent();
74         
75         if ($lines)
76             $c = array_slice($c, 0, $lines);
77         if ($words) 
78             $c = $this->firstNWordsOfContent($words, $c);
79
80         array_push($included_pages, $page);
81         $content = do_transform($c);
82         array_pop($included_pages);
83         
84         if ($quiet) return $content;
85
86         return Element('p', array('class' => 'transclusion-title'),
87                        sprintf(_("Included from %s"), LinkExistingWikiWord($page)))
88             . Element('div', array('class' => 'transclusion'),
89                       $content);
90     }
91 };
92
93 // This is an excerpt from the css file I use:
94 //
95 // .transclusion-title {
96 //   font-style: oblique;
97 //   font-size: 0.75em;
98 //   text-decoration: underline;
99 //   text-align: right;
100 // } 
101 //
102 // DIV.transclusion { 
103 //   background: lightgreen;
104 //   border: thin;
105 //   border-style: solid;
106 //   padding-left: 0.8em; 
107 //   padding-right: 0.8em; 
108 //   padding-top: 0px;
109 //   padding-bottom: 0px;
110 //   margin: 0.5ex 0px;
111 // }
112
113 // KNOWN ISSUES:
114 //   - line & word limit doesn't work if the included page itself includes a plugin
115 //   - we need an error reporting scheme
116
117 // For emacs users
118 // Local Variables:
119 // mode: php
120 // tab-width: 8
121 // c-basic-offset: 4
122 // c-hanging-comment-ender-p: nil
123 // indent-tabs-mode: nil
124 // End:
125         
126 ?>