]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/Template.php
Jeff's hacks II.
[SourceForge/phpwiki.git] / lib / Template.php
1 <?php rcs_id('$Id: Template.php,v 1.1 2001-09-18 19:16:23 dairiki Exp $');
2
3 require_once("lib/ErrorManager.php");
4 require_once("lib/WikiPlugin.php");
5
6 //FIXME: This is a mess and needs to be refactored.
7 //  (In other words: this is all in a state of flux, so don't count on any
8 //   of this being the same tomorrow...)
9
10 class Template
11 {
12     function Template($tmpl) {
13         //$this->_tmpl = $this->_munge_input($tmpl);
14         $this->_tmpl = $tmpl;
15         $this->_vars = array();
16     }
17
18     function _munge_input($template) {
19         // Expand "< ?plugin-* ...? >"
20         preg_match_all('/<\?plugin.*?\?>/s', $template, $m);
21         global $dbi, $request;  // FIXME: no globals?
22         $pluginLoader = new WikiPluginLoader;
23         foreach (array_unique($m[0]) as $plugin_pi) {
24             $orig[] = '/' . preg_quote($plugin_pi, '/') . '/s';
25             $repl[] = $pluginLoader->expandPI($plugin_pi, $dbi, $request);
26         }
27
28          // Convert ${VAR} to < ?php echo "$VAR"; ? >
29         //$orig[] = '/\${(\w[\w\d]*)}/';
30         //$repl[] = '<?php echo "$\1"; ? >';
31         $orig[] = '/\${(\w[\w\d]*)}/e';
32         $repl[] = '$this->_getReplacement("\1")';
33
34         // Convert $VAR[ind] to < ?php echo "$VAR[ind]"; ? >
35         $orig[] = '/\$(\w[\w\d]*)\[([\w\d]+)\]/e';
36         $repl[] = '$this->_getReplacement("\1", "\2")';
37
38         return preg_replace($orig, $repl, $template);
39     }
40
41     function _getReplacement($varname, $index = false) {
42         // FIXME: report missing vars.
43         $vars = &$this->_vars;
44         if (isset($vars[$varname])) {
45             $value = $vars[$varname];
46             if ($index !== false)
47                 @$value = (string) $value[$index];
48             return str_replace('?', '&#63;', $value);
49         }
50         return false;
51     }
52     
53     /**
54      * Substitute HTML replacement text for tokens in template. 
55      *
56      * Constructs a new WikiTemplate based upon the named template.
57      *
58      * @access public
59      *
60      * @param $token string Name of token to substitute for.
61      *
62      * @param $replacement string Replacement HTML text.
63      */
64     function replace($varname, $value) {
65         $this->_vars[$varname] = $value;
66     }
67
68     /**
69      * Substitute text for tokens in template. 
70      *
71      * @access public
72      *
73      * @param $token string Name of token to substitute for.
74      *
75      * @param $replacement string Replacement text.
76      * The replacement text is run through htmlspecialchars()
77      * to escape any special characters.
78      */
79     function qreplace($varname, $value) {
80         $this->_vars[$varname] = htmlspecialchars($value);
81     }
82     
83
84     /**
85      * Include/remove conditional text in template.
86      *
87      * @access public
88      *
89      * @param $token string Conditional token name.
90      * The text within any matching if blocks (or single line ifs) will
91      * be included in the template expansion, while the text in matching
92      * negated if blocks will be excluded. 
93      */
94     /*
95     function setConditional($token, $value = true) {
96         $this->_iftoken[$token] = $value;
97     }
98     */
99     
100     function getExpansion($varhash = false) {
101         $savevars = $this->_vars;
102         if (is_array($varhash)) {
103             foreach ($varhash as $key => $val)
104                 $this->_vars[$key] = $val;
105         }
106         extract($this->_vars);
107         if (isset($this->_iftoken))
108             $_iftoken = $this->_iftoken;
109         
110         ob_start();
111
112         //$this->_dump_template();
113
114         global $ErrorManager;
115         $ErrorManager->pushErrorHandler(array($this, '_errorHandler'));
116         eval('?>' . $this->_munge_input($this->_tmpl));
117         $ErrorManager->popErrorHandler();
118
119         $html = ob_get_contents();
120         ob_end_clean();
121
122         return $html;
123     }
124
125     function printExpansion($args = false) {
126         echo $this->getExpansion($args);
127     }
128
129     // Debugging:
130     function _dump_template () {
131         $lines = explode("\n", $this->_munge_input($this->_tmpl));
132         echo "<pre>\n";
133         $n = 1;
134         foreach ($lines as $line)
135             printf("%4d  %s\n", $n++, htmlspecialchars($line));
136         echo "</pre>\n";
137     }
138
139     function _errorHandler($error) {
140         if (!preg_match('/: eval\(\)\'d code$/', $error->errfile))
141             return false;
142         $error->errfile = "In template";
143         $lines = explode("\n", $this->_tmpl);
144         if (isset($lines[$error->errline - 1]))
145             $error->errstr .= ":\n\t" . $lines[$error->errline - 1];
146         return $error;
147     }
148 };
149
150 class TemplateFile
151 extends Template
152 {
153     function TemplateFile($filename) {
154         $this->_template_file = $filename;
155         $fp = fopen($filename, "rb");
156         $data = fread($fp, filesize($filename));
157         fclose($fp);
158         $this->Template($data);
159     }
160 }
161
162 class WikiTemplate
163 extends TemplateFile
164 {
165     /**
166      * Constructor.
167      *
168      * Constructs a new WikiTemplate based upon the named template.
169      *
170      * @access public
171      *
172      * @param $template string Which template.
173      */
174     function WikiTemplate($template, $page_revision = false) {
175         global $templates;
176         
177         $this->TemplateFile(FindLocalizedFile($templates[$template]));
178         $this->_template_name = $template;
179
180         $this->setGlobalTokens();
181         if ($page_revision)
182             $this->setPageRevisionTokens($page_revision);
183     }
184     
185
186     function setPageTokens(&$page) {
187         /*
188         if ($page->get('locked'))
189             $this->setConditional('LOCK');
190         // HACK: note that EDITABLE may also be set in setWikiUserTokens.
191         if (!$page->get('locked'))
192             $this->setConditional('EDITABLE');
193         */
194         
195         $pagename = $page->getName();
196         $this->replace('page', $page);
197         $this->qreplace('PAGE', $pagename);
198         $this->qreplace('PAGEURL', rawurlencode($pagename));
199         $this->qreplace('SPLIT_PAGE', split_pagename($pagename));
200         $this->qreplace('BROWSE_PAGE', WikiURL($pagename));
201
202         // FIXME: this is a bit of dangerous hackage.
203         $this->qreplace('ACTION', WikiURL($pagename, array('action' => '')));
204
205         // FIXME:?
206         //$this->replace_callback('HITS', array($page, 'getHitCount'));
207         //$this->replace_callback('RELATEDPAGES', array($page, 'getHitCount'));
208         //_dotoken('RELATEDPAGES', LinkRelatedPages($dbi, $name), $page);
209     }
210
211     function setPageRevisionTokens(&$revision) {
212         $page = & $revision->getPage();
213         
214         $current = & $page->getCurrentRevision();
215         $previous = & $page->getRevisionBefore($revision->getVersion());
216
217         $this->replace('IS_CURRENT',
218                        $current->getVersion() == $revision->getVersion());
219
220         /*
221         if ($previous && $previous->getVersion() != 0)
222             $this->setConditional('COPY'); // FIXME: should rename HAVE_COPY?
223         */
224         
225         global $datetimeformat;
226         
227         $this->qreplace('LASTMODIFIED',
228                         strftime($datetimeformat, $revision->get('mtime')));
229         $this->qreplace('LASTAUTHOR', $revision->get('author'));
230         $this->qreplace('VERSION', $revision->getVersion());
231         $this->qreplace('CURRENT_VERSION', $current->getVersion());
232
233         $this->setPageTokens($page);
234     }
235
236     function setWikiUserTokens(&$user) {
237         /*
238         if ( $user->is_admin() ) {
239             $this->setConditional('ADMIN');
240             $this->setConditional('EDITABLE');
241         }
242         if ( ! $user->is_authenticated() )
243             $this->setConditional('ANONYMOUS');
244         */
245         $this->replace('user', $user);
246         $this->qreplace('USERID', $user->id());
247         $prefs = $user->getPreferences();
248         $this->qreplace('EDIT_AREA_WIDTH', $prefs['edit_area.width']);
249         $this->qreplace('EDIT_AREA_HEIGHT', $prefs['edit_area.height']);
250     }
251
252     function setGlobalTokens () {
253         global $user, $logo, $RCS_IDS;
254         
255         // FIXME: This a a bit of dangerous hackage.
256         $this->qreplace('BROWSE', WikiURL(''));
257         $this->qreplace('CSS_URL', DataURL(CSS_URL));
258
259         if (isset($user))
260             $this->setWikiUserTokens($user);
261         if (isset($logo))
262             $this->qreplace('LOGO', DataURL($logo));
263         if (isset($RCS_IDS))
264             $this->qreplace('RCS_IDS', $RCS_IDS);
265
266         $this->qreplace('BASE_URL',
267                         // FIXME:
268                         WikiURL($GLOBALS['pagename'], false, 'absolute_url'));
269     }
270 };
271
272
273 /**
274  * Generate page contents using a template.
275  *
276  * This is a convenience function for backwards compatibility with the old
277  * GeneratePage().
278  *
279  * @param $template string name of the template (see config.php for list of names)
280  *
281  * @param $content string html content to put into the page
282  *
283  * @param $title string page title
284  *
285  * @param $page_revision object Current WikiDB_PageRevision, if available.
286  *
287  * @return string HTML expansion of template.
288  */
289 function GeneratePage($template, $content, $title, $page_revision = false) {
290     // require_once("lib/template.php");
291     $t = new WikiTemplate($template);
292     if ($page_revision)
293         $t->setPageRevisionTokens($page_revision);
294     $t->replace('CONTENT', $content);
295     $t->replace('TITLE', $title);
296     return $t->getExpansion();
297 }
298
299 // Local Variables:
300 // mode: php
301 // tab-width: 8
302 // c-basic-offset: 4
303 // c-hanging-comment-ender-p: nil
304 // indent-tabs-mode: nil33
305 // End:   
306 ?>