OSDN Git Service

bug (lacking default value when DB restore) fix
[nucleus-jp/nucleus-jp-ancient.git] / euc / nucleus / libs / PARSER.php
1 <?php\r
2 /**\r
3   * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
4   * Copyright (C) 2002-2005 The Nucleus Group\r
5   *\r
6   * This program is free software; you can redistribute it and/or\r
7   * modify it under the terms of the GNU General Public License\r
8   * as published by the Free Software Foundation; either version 2\r
9   * of the License, or (at your option) any later version.\r
10   * (see nucleus/documentation/index.html#license for more info)\r
11   *\r
12   * $Id: PARSER.php,v 1.3 2005-03-16 08:10:35 kimitake Exp $\r
13   * $NucleusJP: PARSER.php,v 1.3 2005/03/12 06:19:05 kimitake Exp $\r
14   */\r
15  \r
16 /**\r
17  * This is the parser class of Nucleus. It is used for various things (skin parsing,\r
18  * form generation, ...)\r
19  */\r
20 class PARSER {\r
21 \r
22         // array with the names of all allowed actions\r
23         var $actions;\r
24         \r
25         // reference to actions handler\r
26         var $handler;\r
27         \r
28         // delimiters that can be used for skin/templatevars\r
29         var $delim;\r
30         \r
31         // parameter delimiter (to separate skinvar params)\r
32         var $pdelim;\r
33         \r
34         // usually set to 0. When set to 1, all skinvars are allowed regardless of $actions\r
35         var $norestrictions;\r
36         \r
37         /**\r
38          * Creates a new parser object with the given allowed actions \r
39          * and the given handler\r
40          *\r
41          * @param $allowedActions array\r
42          * @param $handler class object with functions for each action (reference)\r
43          * @param $delim optional delimiter\r
44          * @param $paramdelim optional parameterdelimiter        \r
45          */\r
46         function PARSER($allowedActions, &$handler, $delim = '(<%|%>)', $pdelim = ',') {\r
47                 $this->actions = $allowedActions;\r
48                 $this->handler =& $handler;\r
49                 $this->delim = $delim;\r
50                 $this->pdelim = $pdelim;\r
51                 $this->norestrictions = 0;      // set this to 1 to disable checking for allowedActions\r
52         }\r
53         \r
54         /**\r
55          * Parses the given contents and outputs it\r
56          */\r
57         function parse(&$contents) {\r
58         \r
59                 $pieces = preg_split('/'.$this->delim.'/',$contents);\r
60                 \r
61                 $maxidx = sizeof($pieces);\r
62                 for ($idx = 0;$idx<$maxidx;$idx++) {\r
63                         echo $pieces[$idx];             \r
64                         $idx++;\r
65                         $this->doAction($pieces[$idx]);\r
66                 }\r
67         }\r
68         \r
69 \r
70         /**\r
71           * handle an action \r
72           */\r
73         function doAction($action) {\r
74                 global $manager;\r
75 \r
76                 if (!$action) return;\r
77                 \r
78                 // split into action name + arguments\r
79                 if (strstr($action,'(')) {\r
80                         $paramStartPos = strpos($action, '(');\r
81                         $params = substr($action, $paramStartPos + 1, strlen($action) - $paramStartPos - 2);\r
82                         $action = substr($action, 0, $paramStartPos);\r
83                         $params = explode ($this->pdelim, $params);\r
84                         \r
85                         // trim parameters \r
86                         // for PHP versions lower than 4.0.6:\r
87                         //   - add // before '$params = ...' \r
88                         //   - remove // before 'foreach'\r
89                         $params = array_map('trim',$params);\r
90                         // foreach ($params as $key => $value) { $params[$key] = trim($value); }                        \r
91                 } else {\r
92                         // no parameters\r
93                         $params = array();\r
94                 }\r
95         \r
96                 $actionlc = strtolower($action);\r
97                 \r
98                 // skip execution of skinvars while inside an if condition which hides this part of the page\r
99                 if (!$this->handler->if_currentlevel && ($actionlc != 'else') && ($actionlc != 'endif') && (substr($actionlc,0,2) != 'if'))\r
100                         return;\r
101         \r
102                 if (in_array($actionlc, $this->actions) || $this->norestrictions ) {\r
103                         // when using PHP versions lower than 4.0.5, uncomment the line before\r
104                         // and comment the call_user_func_array call\r
105                         //$this->call_using_array($action, $this->handler, $params);\r
106                         call_user_func_array(array(&$this->handler,'parse_' . $actionlc), $params);\r
107                 } else {\r
108                         // redirect to plugin action if possible\r
109                         if (in_array('plugin', $this->actions) && $manager->pluginInstalled('NP_'.$action))\r
110                                 $this->doAction('plugin('.$action.$this->pdelim.implode($this->pdelim,$params).')');\r
111                         else\r
112                                 echo '<b>DISALLOWED (' , $action , ')</b>';\r
113                 }\r
114                 \r
115         }\r
116         \r
117         /**\r
118           * Calls a method using an array of parameters (for use with PHP versions lower than 4.0.5)\r
119           * ( = call_user_func_array() function )\r
120           */\r
121         function call_using_array($methodname, &$handler, $paramarray) {\r
122 \r
123                 $methodname = 'parse_' . $methodname;\r
124                 \r
125                 if (!method_exists($handler, $methodname)) {\r
126                         return;\r
127                 }\r
128 \r
129                 $command = 'call_user_func(array(&$handler,$methodname)';\r
130                 for ($i = 0; $i<count($paramarray); $i++)\r
131                         $command .= ',$paramarray[' . $i . ']';\r
132                 $command .= ');';\r
133                 eval($command); // execute the correct method\r
134         }\r
135         \r
136         function setProperty($property, $value) {\r
137                 global $manager;\r
138                 $manager->setParserProperty($property, $value);\r
139         }\r
140         \r
141         function getProperty($name) {\r
142                 global $manager;\r
143                 return $manager->getParserProperty($name);\r
144         }\r
145         \r
146         \r
147 }\r
148 \r
149 /**\r
150  * This class contains parse actions that are available in all ACTION classes\r
151  * e.g. include, phpinclude, parsedinclude, skinfile, ...\r
152  *\r
153  * It should never be used on it's own\r
154  */\r
155 class BaseActions {\r
156         \r
157         // depth level for includes (max. level is 3)\r
158         var $level;\r
159         \r
160         // array of evaluated conditions (true/false). The element at the end is the one for the most nested\r
161         // if block.\r
162         var $if_conditions;\r
163         \r
164         // at all times, can be evaluated to either true if the current block needs to be displayed. This \r
165         // variable is used to decide to skip skinvars in parts that will never be outputted.\r
166         var $if_currentlevel;\r
167         \r
168         // contains a search string with keywords that need to be highlighted. These get parsed into $aHighlight\r
169         var $strHighlight;\r
170         \r
171         // array of keywords that need to be highlighted in search results (see the highlight() \r
172         // and parseHighlight() methods)\r
173         var $aHighlight;\r
174         \r
175 \r
176         // reference to the parser object that is using this object as actions-handler\r
177 \r
178         var $parser;\r
179         \r
180 \r
181         function BaseActions() {\r
182                 $this->level = 0; \r
183                 \r
184                 // if nesting level\r
185                 $this->if_conditions = array(); // array on which condition values are pushed/popped\r
186                 $this->if_currentlevel = 1;             // 1 = current level is displayed; 0 = current level not displayed\r
187 \r
188                 // highlights           \r
189                 $this->strHighlight = '';                       // full highlight\r
190                 $this->aHighlight = array();            // parsed highlight\r
191                 \r
192         }\r
193 \r
194         // include file (no parsing of php)\r
195         function parse_include($filename) {\r
196                 @readfile($this->getIncludeFileName($filename));\r
197         }\r
198         \r
199         // php-include file \r
200         function parse_phpinclude($filename) {\r
201                 includephp($this->getIncludeFileName($filename));\r
202         }       \r
203         // parsed include\r
204         function parse_parsedinclude($filename) {\r
205                 // check current level\r
206                 if ($this->level > 3) return;   // max. depth reached (avoid endless loop)\r
207                 $filename = $this->getIncludeFileName($filename);\r
208                 if (!file_exists($filename)) return '';\r
209                 \r
210                 $fsize = filesize($filename);\r
211                 \r
212                 // nothing to include\r
213                 if ($fsize <= 0)\r
214                         return;\r
215                 \r
216                 $this->level = $this->level + 1;\r
217                 \r
218                 // read file \r
219                 $fd = fopen ($filename, 'r');\r
220                 $contents = fread ($fd, $fsize);\r
221                 fclose ($fd);           \r
222                 \r
223                 // parse file contents\r
224                 $this->parser->parse($contents);\r
225                 \r
226                 $this->level = $this->level - 1;                \r
227         }\r
228         \r
229         /**\r
230          * Returns the correct location of the file to be included, according to\r
231          * parser properties\r
232          *\r
233          * IF IncludeMode = 'skindir' => use skindir\r
234          */\r
235         function getIncludeFileName($filename) {\r
236                 // leave absolute filenames and http urls as they are\r
237                 if (\r
238                                 (substr($filename,0,1) == '/')\r
239                         ||      (substr($filename,0,7) == 'http://')\r
240                         ||      (substr($filename,0,6) == 'ftp://')                     \r
241                         )\r
242                         return $filename;\r
243         \r
244                 $filename = PARSER::getProperty('IncludePrefix') . $filename;\r
245                 if (PARSER::getProperty('IncludeMode') == 'skindir') {\r
246                         global $DIR_SKINS;\r
247                         return $DIR_SKINS . $filename;\r
248                 } else {\r
249                         return $filename;\r
250                 }\r
251         }\r
252         \r
253         /**\r
254          * Inserts an url relative to the skindir (useful when doing import/export)\r
255          *\r
256          * e.g. <skinfile(default/myfile.sth)>\r
257          */\r
258         function parse_skinfile($filename) {\r
259                 global $CONF;\r
260                 \r
261                 echo $CONF['SkinsURL'] . PARSER::getProperty('IncludePrefix') . $filename;\r
262         }\r
263         \r
264         /**\r
265          * Sets a property for the parser\r
266          */\r
267         function parse_set($property, $value) {\r
268                 PARSER::setProperty($property, $value);\r
269         }\r
270         \r
271         /**\r
272          * Helper function: add if condition\r
273          */\r
274         function _addIfCondition($condition) {\r
275         \r
276                 array_push($this->if_conditions,$condition);\r
277         \r
278                 $this->_updateTopIfCondition();\r
279                         \r
280                 ob_start();             \r
281         }\r
282         \r
283         function _updateTopIfCondition() {\r
284                 if (sizeof($this->if_conditions) == 0) \r
285                         $this->if_currentlevel = 1;\r
286                 else\r
287                         $this->if_currentlevel = $this->if_conditions[sizeof($this->if_conditions) - 1];\r
288         }\r
289         \r
290         /**\r
291          * returns the currently top if condition\r
292          */\r
293         function _getTopIfCondition() {\r
294                 return $this->if_currentlevel;\r
295         }\r
296         \r
297         /**\r
298          * else\r
299          */\r
300         function parse_else() {\r
301                 if (sizeof($this->if_conditions) == 0) return;\r
302                 $old = $this->if_currentlevel;\r
303                 if (array_pop($this->if_conditions)) {\r
304                         ob_end_flush();\r
305                         $this->_addIfCondition(0);\r
306                 } else {\r
307                         ob_end_clean();\r
308                         $this->_addIfCondition(1);\r
309                 }\r
310         }\r
311         \r
312         /**\r
313          * Ends a conditional if-block \r
314          * see e.g. ifcat (BLOG), ifblogsetting (PAGEFACTORY)\r
315          */\r
316         function parse_endif() {\r
317                 // we can only close what has been opened\r
318                 if (sizeof($this->if_conditions) == 0) return;\r
319                 \r
320                 if (array_pop($this->if_conditions)) {\r
321                         ob_end_flush();\r
322                 } else {\r
323                         ob_end_clean();\r
324                 }\r
325                 \r
326                 $this->_updateTopIfCondition();\r
327         }\r
328         \r
329         \r
330         /** \r
331          * Sets the search terms to be highlighted\r
332          *\r
333          * @param $highlight\r
334          *              A series of search terms\r
335          */\r
336         function setHighlight($highlight) {     \r
337                 $this->strHighlight = $highlight;\r
338                 if ($highlight) {\r
339                         $this->aHighlight = parseHighlight($highlight); \r
340                 }\r
341         }\r
342         \r
343         /**\r
344          * Applies the highlight to the given piece of text\r
345          *\r
346          * @param &$data\r
347          *              Data that needs to be highlighted\r
348          * @see setHighlight\r
349          */\r
350         function highlight(&$data) {\r
351                 if ($this->aHighlight)\r
352                         return highlight($data,$this->aHighlight,$this->template['SEARCH_HIGHLIGHT']);\r
353                 else\r
354                         return $data;\r
355         }\r
356         \r
357         \r
358 \r
359 }\r
360  \r
361 ?>\r