OSDN Git Service

git-svn-id: https://svn.sourceforge.jp/svnroot/nucleus-jp/plugin@1059 1ca29b6e-896d...
[nucleus-jp/nucleus-plugins.git] / trunk / NP_IncludeEX / NP_IncludeEX.php
1 <?php
2
3 /*
4         NP_IncludeEX
5         by yu (http://nucleus.datoka.jp/)
6
7         This program is free software; you can redistribute it and/or
8         modify it under the terms of the GNU General Public License
9         as published by the Free Software Foundation; either version 2
10         of the License, or (at your option) any later version.
11         (see nucleus/documentation/index.html#license for more info)
12         
13         USAGE
14         -----
15         <%IncludeEX(parsed,{shortname}_{skintype}.txt)%>        --- blogname_archivelist.txt
16         <%IncludeEX(php,info.php?y={y}&m={m})%>                         --- info.php?y=2004&m=01
17         <%IncludeEX(php+parsed,function.php,PARSE_TWICE)%>      --- text is first parsed by php, and then parsed by nucleus
18                                                                                                                         (PARSED_TWICE allow 1-level nesting in "parsed" mode)
19         HISTORY
20         -------
21         Ver 0.32 : Security fix. (2006/09/30)
22                    Check blogid, archivelist and currentSkinName
23         Ver 0.3  : Add parse-type "php+parsed".
24                    Add optional parameter "PARSE_TWICE".
25                    Add vars {version_num}, {random_num}, and {random_alpha}.
26                    Add plugin option "Debug Mode".
27         Ver 0.2  : Add parse-type "parsed+php".
28         Ver 0.1  : First imprementation.
29 */
30
31 // plugin needs to work on Nucleus versions <=2.0 as well
32 if (!function_exists('sql_table')){
33         function sql_table($name) {
34                 return 'nucleus_' . $name;
35         }
36 }
37
38 class NP_IncludeEX extends NucleusPlugin {
39
40         function getName()    { return 'IncludeEX'; }
41         function getAuthor()  { return 'yu'; }
42         function getURL()     { return 'http://works.datoka.jp/index.php?itemid=199'; }
43         function getVersion() { return '0.32'; }
44         function getMinNucleusVersion() { return '200'; }
45         function supportsFeature($what) {
46                 switch($what){
47                         case 'SqlTablePrefix':
48                                 return 1;
49                         default:
50                                 return 0;
51                 }
52         }
53
54         function getDescription() {
55                 return 'Include a file using some valiables for replacement. [USAGE] &lt;%IncludeEX(parsed,{shortname}_{skintype}.txt)%&gt;, &lt;%IncludeEX(php,info.php?y={y}&m={m})%&gt;, etc. First Parameter is parse-type(none/php/parsed/parsed+php/php+parsed). Second is filename. Third is optional flag(PARSE_TWICE only now). Variables in filename are need to be braced. Available variables are: '. join(' ', $this->vars);
56         }
57         
58         function install() {
59                 $desc_incmode = 'Include mode in second parsing(in "parsed+php" parse-type). [file] Make temporary file. Need <?php ?> tag and you can use HTML tags together like "php" parse-type. [memory] Use eval function, maybe faster. Only PHP code(No <?php ?> tag).';
60                 
61                 $this->createOption('debugmode','Debug Mode: print filename only.','yesno','no');
62                 
63                 if(getNucleusVersion() < 220) {
64                         $this->createOption('incmode',$desc_incmode,'text','file');
65                 }
66                 else {
67                         $this->createOption('incmode',$desc_incmode,'select','file','File|file|Memory|memory');
68                 }
69
70         }
71
72         function uninstall() {
73         }
74
75         function init() {
76                 // set var type
77                 $this->vars = array(
78                         '{blogid}',
79                         '{shortname}',
80                         '{catid}',
81                         '{catname}',
82                         '{itemid}',
83                         '{memberid}',
84                         '{skinid}',
85                         '{skinname}',
86                         '{skintype}',
87                         '{date}',
88                         '{y}',
89                         '{m}',
90                         '{d}',
91                         '{archivetype}',
92                         '{archivedate}',
93                         '{archive_y}',
94                         '{archive_m}',
95                         '{archive_d}',
96                         '{version}',
97                         '{version_num}',
98                         '{random_num}',
99                         '{random_alpha}',
100                         );
101         }
102         
103         // helper function
104         function _set_alpha($begin, $end) {
105                 $r_alpha = range($begin, $end);
106                 $random_alpha = $r_alpha[array_rand($r_alpha)];
107                 return $random_alpha;
108         }
109         
110         function doSkinVar($skinType, $parsetype, $filename, $spflag='') {
111                 global $blogid, $catid, $itemid, $memberid, $skinid, $currentSkinName, $archive;
112                 global $blog, $CONF, $nucleus;
113
114                 if ($parsetype) $parsetype = strtolower($parsetype);
115                 if ($spflag) $spflag = strtoupper($spflag);
116                 
117                 // prepare
118                 if ($archive) {
119                         sscanf($archive,'%d-%d-%d',$y,$m,$d);
120                         if ($y && $m && $d) {
121                                 $archive = sprintf('%04d-%02d-%02d',$y,$m,$d);
122                         } elseif ($y && $m && !$d) {
123                                 $archive = sprintf('%04d-%02d',$y,$m);
124                         }
125                         sscanf($archive,'%4c-%2c-%2c',$archive_y,$archive_m,$archive_d);
126                 }
127                 $archivetype = ($archive_d) ? 'date' : 'month';
128                 
129                 if (! isValidSkinName($currentSkinName)) {
130                         $currentSkinName = SKIN::getNameFromId($skinid);
131                 }
132                 
133                 list($usec, $sec) = explode(' ', microtime());
134                 $rseed = (float) $sec + ((float) $usec * 100000);
135                 mt_srand($rseed);
136                 $random_num = mt_rand(0,9);
137                 
138                 $r_alpha = range('a','z');
139                 $random_alpha = $r_alpha[array_rand($r_alpha)];
140                 
141                 // set var value
142                 $replace = array(
143                         intval($blogid),
144                         $blog->getShortName(),
145                         intval($catid),
146                         $blog->getCategoryName($catid),
147                         intval($itemid),
148                         intval($memberid),
149                         intval($skinid),
150                         $currentSkinName,
151                         $skinType,              //this should get like $type in selector@globalfunc *for template use*?
152                         date('Y-m-d'),
153                         date('Y'),
154                         date('m'),
155                         date('d'),
156                         $archivetype,
157                         $archive,
158                         $archive_y,
159                         $archive_m,
160                         $archive_d,
161                         $nucleus['version'],
162                         getNucleusVersion(),
163                         $random_num,
164                         $random_alpha,
165                         );
166
167                 // replace
168                 $filename = str_replace($this->vars, $replace, $filename);
169                 
170                 // replace: random_* with param
171                 $filename = preg_replace('/{random_num:([0-9]+)-([0-9]+)}/e', 'mt_rand($1,$2)', $filename);
172                 $filename = preg_replace('/{random_alpha:([a-z]+)-([a-z]+)}/e', '$this->_set_alpha($1,$2)', $filename);
173
174                 if ($this->getOption('debugmode') == 'yes') {
175                         echo $filename;
176                         return;
177                 }
178                 
179                 $oInc = new PLUG_INCLUDE($skinType);
180                 switch( strtolower($parsetype) ) {
181                         case 'parsed':
182                                 if ($spflag == 'PARSE_TWICE') $oInc->parse_2times_parsedinclude($filename);
183                                 else $oInc->parse_parsedinclude($filename);
184                                 break;
185                         case 'php':
186                                 if ( preg_match('/\.php\?(.+)=(.+)/', $filename) ) { // full url for remote fopen
187                                         $skindir = PARSER::getProperty('IncludePrefix');
188                                         $filename = $CONF['SkinsURL'] .$skindir. $filename;
189                                 }
190                                 $oInc->parse_phpinclude($filename);
191                                 break;
192                         case 'parsed+php':
193                                 ob_start();
194                                 if ($spflag == 'PARSE_TWICE') $oInc->parse_2times_parsedinclude($filename);
195                                 else $oInc->parse_parsedinclude($filename);
196                                 $buff = ob_get_contents();
197                                 ob_end_clean();
198                                 $oInc->parse_buff_phpinclude($buff, $this->getOption('incmode'));
199                                 break;
200                         case 'php+parsed':
201                                 ob_start();
202                                 if ( preg_match('/\.php\?(.+)=(.+)/', $filename) ) { // full url for remote fopen
203                                         $skindir = PARSER::getProperty('IncludePrefix');
204                                         $filename = $CONF['SkinsURL'] .$skindir. $filename;
205                                 }
206                                 $oInc->parse_phpinclude($filename);
207                                 $buff = ob_get_contents();
208                                 ob_end_clean();
209                                 if ($spflag == 'PARSE_TWICE') $oInc->parse_2times_parsedinclude($buff,'buff');
210                                 else $oInc->parse_buff_parsedinclude($buff);
211                                 break;
212                         default:
213                                 $oInc->parse_include($filename);
214                 }
215         }
216         
217 }
218
219 class PLUG_INCLUDE extends BaseActions {
220
221         function PLUG_INCLUDE($type) {
222                 // call constructor of superclass first
223                 $this->BaseActions();
224                 
225                 //$this->skin = new SKIN($type);
226                 //$actions = $this->skin->getAllowedActionsForType($type);
227                 $actions = SKIN::getAllowedActionsForType($type);
228                 $this->handler = new ACTIONS($type);
229                 $this->parser = new PARSER($actions, $this->handler);
230                 $this->handler->setParser($this->parser);
231         }
232         
233         function parse_buff_phpinclude($buff, $mode = 'memory') {
234                 // make predefined variables global, so most simple scripts can be used here
235         
236                 // apache (names taken from PHP doc)
237                 global $GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE, $SERVER_PROTOCOL;
238                 global $REQUEST_METHOD, $QUERY_STRING, $DOCUMENT_ROOT, $HTTP_ACCEPT;
239                 global $HTTP_ACCEPT_CHARSET, $HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE;
240                 global $HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER, $HTTP_USER_AGENT;
241                 global $REMOTE_ADDR, $REMOTE_PORT, $SCRIPT_FILENAME, $SERVER_ADMIN;
242                 global $SERVER_PORT, $SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME;
243                 global $REQUEST_URI;
244         
245                 // php (taken from PHP doc)
246                 global $argv, $argc, $PHP_SELF, $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS;
247                 global $HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS, $HTTP_SESSION_VARS;
248         
249                 // other
250                 global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;
251         
252                 if (strtolower($mode) == 'file') { // make temp file to include
253                         $tmpfname = tempnam("/tmp", "BUFF");
254                         $fp = fopen($tmpfname, "w");
255                         fwrite($fp, $buff);
256                         fclose($fp);
257                         include $tmpfname;
258                         unlink($tmpfname);
259                 }
260                 else {
261                         eval($buff); // use eval function instead of include
262                 }
263                 
264         }
265
266         function parse_buff_parsedinclude($buff) {
267                 // check current level
268                 if ($this->level > 3) return;   // max. depth reached (avoid endless loop)
269                 $this->level = $this->level + 1;
270                 
271                 // parse buffer contents
272                 $this->parser->parse($buff);
273                 
274                 $this->level = $this->level - 1;                
275         }
276
277         function parse_2times_parsedinclude($filename, $mode='file') {
278                 // check current level
279                 if ($this->level > 3) return;   // max. depth reached (avoid endless loop)
280                 
281                 if ($mode == 'file') {
282                         $filename = $this->getIncludeFileName($filename);
283                         if (!file_exists($filename)) return '';
284                 }
285                 
286                 $this->level = $this->level + 1;
287                 
288                 if ($mode == 'file') {
289                         // read file 
290                         $fd = fopen ($filename, 'r');
291                         $contents = fread ($fd, filesize ($filename));
292                         fclose ($fd);
293                 }
294                 else if ($mode == 'buff') {
295                         $contents = $filename;
296                 }
297                 
298                 // modify outer var-tags
299                 $this->_modify_tags($contents);
300                 
301                 ob_start();
302                 
303                 // parse file contents (1st)
304                 $this->parser->parse($contents);
305                 
306                 $buff = ob_get_contents();
307                 ob_end_clean();
308                 
309                 // restore modified var-tags
310                 $this->_restore_tags($buff);
311                 
312                 // parse file contents (2nd)
313                 $this->parser->parse($buff);
314                 
315                 $this->level = $this->level - 1;
316         }
317         
318         // helper function
319         
320         function _modify_tags(&$contents) {
321                 $contents = preg_replace('/<%([^>].*)<%/', '<:$1<%', $contents);
322                 $contents = preg_replace('/%>([^>].*)%>/', '%>$1:>', $contents);
323         }
324         
325         function _restore_tags(&$contents) {
326                 $target = array('/<:/','/:>/');
327                 $replace = array('<%','%>');
328                 $contents = preg_replace($target, $replace, $contents);
329         }
330 }
331 ?>