OSDN Git Service

b2bc1aa97a1fa48cc3c8bdb55fe2ffd860c79aa2
[nucleus-jp/nucleus-jp-ancient.git] / utf8 / nucleus / libs / globalfunctions.php
1 <?php\r
2 \r
3 /*\r
4  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
5  * Copyright (C) 2002-2009 The Nucleus Group\r
6  *\r
7  * This program is free software; you can redistribute it and/or\r
8  * modify it under the terms of the GNU General Public License\r
9  * as published by the Free Software Foundation; either version 2\r
10  * of the License, or (at your option) any later version.\r
11  * (see nucleus/documentation/index.html#license for more info)\r
12  */\r
13 /**\r
14  * @license http://nucleuscms.org/license.txt GNU General Public License\r
15  * @copyright Copyright (C) 2002-2009 The Nucleus Group\r
16  * @version $Id$\r
17  * $NucleusJP: globalfunctions.php,v 1.23.2.7 2008/02/05 08:30:08 kimitake Exp $\r
18  */\r
19 \r
20 // needed if we include globalfunctions from install.php\r
21 global $nucleus, $CONF, $DIR_LIBS, $DIR_LANG, $manager, $member;\r
22 \r
23 $nucleus['version'] = 'v3.41RC';\r
24 $nucleus['codename'] = '';\r
25 \r
26 checkVars(array('nucleus', 'CONF', 'DIR_LIBS', 'MYSQL_HOST', 'MYSQL_USER', 'MYSQL_PASSWORD', 'MYSQL_DATABASE', 'DIR_LANG', 'DIR_PLUGINS', 'HTTP_GET_VARS', 'HTTP_POST_VARS', 'HTTP_COOKIE_VARS', 'HTTP_ENV_VARS', 'HTTP_SESSION_VARS', 'HTTP_POST_FILES', 'HTTP_SERVER_VARS', 'GLOBALS', 'argv', 'argc', '_GET', '_POST', '_COOKIE', '_ENV', '_SESSION', '_SERVER', '_FILES'));\r
27 \r
28 $CONF['debug'] = 0;\r
29 if ($CONF['debug']) {\r
30         error_reporting(E_ALL); // report all errors!\r
31 } else {\r
32         error_reporting(E_ERROR | E_WARNING | E_PARSE);\r
33 }\r
34 \r
35 /*\r
36         Indicates when Nucleus should display startup errors. Set to 1 if you want\r
37         the error enabled (default), false otherwise\r
38 \r
39         alertOnHeadersSent\r
40                 Displays an error when visiting a public Nucleus page and headers have\r
41                 been sent out to early. This usually indicates an error in either a\r
42                 configuration file or a language file, and could cause Nucleus to\r
43                 malfunction\r
44         alertOnSecurityRisk\r
45                 Displays an error only when visiting the admin area, and when one or\r
46                 more of the installation files (install.php, install.sql, upgrades/\r
47                 directory) are still on the server.\r
48 */\r
49 \r
50 $CONF['alertOnHeadersSent']  = 1;\r
51 $CONF['alertOnSecurityRisk'] = 1;\r
52 /*$CONF['ItemURL']             = $CONF['Self'];\r
53 $CONF['ArchiveURL']          = $CONF['Self'];\r
54 $CONF['ArchiveListURL']      = $CONF['Self'];\r
55 $CONF['MemberURL']           = $CONF['Self'];\r
56 $CONF['SearchURL']           = $CONF['Self'];\r
57 $CONF['BlogURL']             = $CONF['Self'];\r
58 $CONF['CategoryURL']         = $CONF['Self'];\r
59 \r
60 // switch URLMode back to normal when $CONF['Self'] ends in .php\r
61 // this avoids urls like index.php/item/13/index.php/item/15\r
62 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {\r
63         $CONF['URLMode'] = 'normal';\r
64 }*/\r
65 \r
66 if (getNucleusPatchLevel() > 0) {\r
67         $nucleus['version'] .= '/' . getNucleusPatchLevel();\r
68 }\r
69 \r
70 // Avoid notices\r
71 if (!isset($CONF['installscript'])) {\r
72         $CONF['installscript'] = 0;\r
73 }\r
74 \r
75 // we will use postVar, getVar, ... methods instead of HTTP_GET_VARS or _GET\r
76 if ($CONF['installscript'] != 1) { // vars were already included in install.php\r
77         if (phpversion() >= '4.1.0') {\r
78                 include_once($DIR_LIBS . 'vars4.1.0.php');\r
79         } else {\r
80                 include_once($DIR_LIBS . 'vars4.0.6.php');\r
81         }\r
82 }\r
83 \r
84 // sanitize option\r
85 $bLoggingSanitizedResult=0;\r
86 $bSanitizeAndContinue=0;\r
87 \r
88 $orgRequestURI = serverVar('REQUEST_URI');\r
89 sanitizeParams();\r
90 \r
91 // get all variables that can come from the request and put them in the global scope\r
92 $blogid       = requestVar('blogid');\r
93 $itemid       = intRequestVar('itemid');\r
94 $catid        = intRequestVar('catid');\r
95 $skinid       = requestVar('skinid');\r
96 $memberid     = requestVar('memberid');\r
97 $archivelist  = requestVar('archivelist');\r
98 $imagepopup   = requestVar('imagepopup');\r
99 $archive      = requestVar('archive');\r
100 $query        = requestVar('query');\r
101 $highlight    = requestVar('highlight');\r
102 $amount       = requestVar('amount');\r
103 $action       = requestVar('action');\r
104 $nextaction   = requestVar('nextaction');\r
105 $maxresults   = requestVar('maxresults');\r
106 $startpos     = intRequestVar('startpos');\r
107 $errormessage = '';\r
108 $error        = '';\r
109 $special = requestVar('special');\r
110 $virtualpath  = ((getVar('virtualpath') != null) ? getVar('virtualpath') : serverVar('PATH_INFO'));\r
111 \r
112 if (!headers_sent() ) {\r
113         header('Generator: Nucleus CMS ' . $nucleus['version']);\r
114 }\r
115 \r
116 // include core classes that are needed for login & plugin handling\r
117 include($DIR_LIBS . 'mysql.php');\r
118 include($DIR_LIBS . 'MEMBER.php');\r
119 include($DIR_LIBS . 'ACTIONLOG.php');\r
120 include($DIR_LIBS . 'MANAGER.php');\r
121 include($DIR_LIBS . 'PLUGIN.php');\r
122 \r
123 $manager =& MANAGER::instance();\r
124 \r
125 // make sure there's no unnecessary escaping:\r
126 set_magic_quotes_runtime(0);\r
127 \r
128 // Avoid notices\r
129 if (!isset($CONF['UsingAdminArea'])) {\r
130         $CONF['UsingAdminArea'] = 0;\r
131 }\r
132 \r
133 // only needed when updating logs\r
134 if ($CONF['UsingAdminArea']) {\r
135         include($DIR_LIBS . 'xmlrpc.inc.php');  // XML-RPC client classes\r
136         include_once($DIR_LIBS . 'ADMIN.php');\r
137 }\r
138 \r
139 // connect to database\r
140 sql_connect();\r
141 $SQLCount = 0;\r
142 \r
143 // logs sanitized result if need\r
144 if ($orgRequestURI!==serverVar('REQUEST_URI')) {\r
145         $msg = "Sanitized [" . serverVar('REMOTE_ADDR') . "] ";\r
146         $msg .= $orgRequestURI . " -> " . serverVar('REQUEST_URI');\r
147     if ($bLoggingSanitizedResult) {\r
148         addToLog(WARNING, $msg);\r
149     }\r
150     if (!$bSanitizeAndContinue) {\r
151         die("");\r
152     }\r
153 }\r
154 \r
155 // makes sure database connection gets closed on script termination\r
156 register_shutdown_function('sql_disconnect');\r
157 \r
158 // read config\r
159 getConfig();\r
160 \r
161 // Properly set $CONF['Self'] and others if it's not set... usually when we are access from admin menu\r
162 if (!isset($CONF['Self'])) {\r
163         $CONF['Self'] = $CONF['IndexURL'];\r
164         // strip trailing /\r
165         if ($CONF['Self'][strlen($CONF['Self']) -1] == "/") {\r
166                 $CONF['Self'] = substr($CONF['Self'], 0, strlen($CONF['Self']) -1);\r
167         }\r
168 \r
169 /*      $CONF['ItemURL']        = $CONF['Self'];\r
170         $CONF['ArchiveURL']     = $CONF['Self'];\r
171         $CONF['ArchiveListURL'] = $CONF['Self'];\r
172         $CONF['MemberURL']      = $CONF['Self'];\r
173         $CONF['SearchURL']      = $CONF['Self'];\r
174         $CONF['BlogURL']        = $CONF['Self'];\r
175         $CONF['CategoryURL']    = $CONF['Self'];*/\r
176 }\r
177 \r
178 $CONF['ItemURL'] = $CONF['Self'];\r
179 $CONF['ArchiveURL'] = $CONF['Self'];\r
180 $CONF['ArchiveListURL'] = $CONF['Self'];\r
181 $CONF['MemberURL'] = $CONF['Self'];\r
182 $CONF['SearchURL'] = $CONF['Self'];\r
183 $CONF['BlogURL'] = $CONF['Self'];\r
184 $CONF['CategoryURL'] = $CONF['Self'];\r
185 \r
186 // switch URLMode back to normal when $CONF['Self'] ends in .php\r
187 // this avoids urls like index.php/item/13/index.php/item/15\r
188 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {\r
189         $CONF['URLMode'] = 'normal';\r
190 }\r
191 \r
192 // automatically use simpler toolbar for mozilla\r
193 if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'), 'Gecko') ) {\r
194         $CONF['DisableJsTools'] = 2;\r
195 }\r
196 \r
197 // login if cookies set\r
198 $member = new MEMBER();\r
199 \r
200 // secure cookie key settings (either 'none', 0, 8, 16, 24, or 32)\r
201 if (!isset($CONF['secureCookieKey'])) $CONF['secureCookieKey']=24;\r
202 switch($CONF['secureCookieKey']){\r
203 case 8:\r
204         $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));\r
205         break;\r
206 case 16:\r
207         $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));\r
208         break;\r
209 case 24:\r
210         $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+$/','',serverVar('REMOTE_ADDR'));\r
211         break;\r
212 case 32:\r
213         $CONF['secureCookieKeyIP']=serverVar('REMOTE_ADDR');\r
214         break;\r
215 default:\r
216         $CONF['secureCookieKeyIP']='';\r
217 }\r
218 \r
219 // login/logout when required or renew cookies\r
220 if ($action == 'login') {\r
221         // Form Authentication\r
222         $login = postVar('login');\r
223         $pw = postVar('password');\r
224         $shared = intPostVar('shared'); // shared computer or not\r
225 \r
226         $pw=substr($pw,0,40); // avoid md5 collision by using a long key\r
227 \r
228         if ($member->login($login, $pw) ) {\r
229 \r
230                 $member->newCookieKey();\r
231                 $member->setCookies($shared);\r
232 \r
233                 if ($CONF['secureCookieKey']!=='none') {\r
234                         // secure cookie key\r
235                         $member->setCookieKey(md5($member->getCookieKey().$CONF['secureCookieKeyIP']));\r
236                         $member->write();\r
237                 }\r
238 \r
239                 // allows direct access to parts of the admin area after logging in\r
240                 if ($nextaction) {\r
241                         $action = $nextaction;\r
242                 }\r
243 \r
244                 $manager->notify('LoginSuccess', array('member' => &$member, 'username' => $login) );\r
245                 $errormessage = '';\r
246                 ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");\r
247         } else {\r
248                 // errormessage for [%errordiv%]\r
249                 $errormessage = 'Login failed for ' . $login;\r
250 \r
251                 $manager->notify('LoginFailed', array('username' => $login) );\r
252                 ACTIONLOG::add(INFO, $errormessage);\r
253         }\r
254 /*\r
255 \r
256 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details\r
257 \r
258 } elseif (serverVar('PHP_AUTH_USER') && serverVar('PHP_AUTH_PW')) {\r
259         // HTTP Authentication\r
260         $login  = serverVar('PHP_AUTH_USER');\r
261         $pw     = serverVar('PHP_AUTH_PW');\r
262 \r
263         if ($member->login($login, $pw) ) {\r
264                 $manager->notify('LoginSuccess',array('member' => &$member));\r
265                 ACTIONLOG::add(INFO, "HTTP authentication successful for $login");\r
266         } else {\r
267                 $manager->notify('LoginFailed',array('username' => $login));\r
268                 ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);\r
269 \r
270                 //Since bad credentials, generate an apropriate error page\r
271                 header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");\r
272                 header('HTTP/1.0 401 Unauthorized');\r
273                 echo 'Invalid username or password';\r
274                 exit;\r
275         }\r
276 */\r
277 \r
278 } elseif (($action == 'logout') && (!headers_sent() ) && cookieVar($CONF['CookiePrefix'] . 'user') ) {\r
279         // remove cookies on logout\r
280         setcookie($CONF['CookiePrefix'] . 'user', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);\r
281         setcookie($CONF['CookiePrefix'] . 'loginkey', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);\r
282         $manager->notify('Logout', array('username' => cookieVar($CONF['CookiePrefix'] . 'user') ) );\r
283 } elseif (cookieVar($CONF['CookiePrefix'] . 'user') ) {\r
284         // Cookie Authentication\r
285         $ck=cookieVar($CONF['CookiePrefix'] . 'loginkey');\r
286         // secure cookie key\r
287         $ck=substr($ck,0,32); // avoid md5 collision by using a long key\r
288         if ($CONF['secureCookieKey']!=='none') $ck=md5($ck.$CONF['secureCookieKeyIP']);\r
289         $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), $ck );\r
290         unset($ck);\r
291 \r
292         // renew cookies when not on a shared computer\r
293         if ($res && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) && (!headers_sent() ) ) {\r
294                 $member->setCookieKey(cookieVar($CONF['CookiePrefix'] . 'loginkey'));\r
295                 $member->setCookies();\r
296         }\r
297 }\r
298 \r
299 // login completed\r
300 $manager->notify('PostAuthentication', array('loggedIn' => $member->isLoggedIn() ) );\r
301 ticketForPlugin();\r
302 \r
303 // first, let's see if the site is disabled or not. always allow admin area access.\r
304 if ($CONF['DisableSite'] && !$member->isAdmin() && !$CONF['UsingAdminArea']) {\r
305         redirect($CONF['DisableSiteURL']);\r
306         exit;\r
307 }\r
308 \r
309 // load other classes\r
310 include($DIR_LIBS . 'PARSER.php');\r
311 include($DIR_LIBS . 'SKIN.php');\r
312 include($DIR_LIBS . 'TEMPLATE.php');\r
313 include($DIR_LIBS . 'BLOG.php');\r
314 include($DIR_LIBS . 'BODYACTIONS.php');\r
315 include($DIR_LIBS . 'COMMENTS.php');\r
316 include($DIR_LIBS . 'COMMENT.php');\r
317 //include($DIR_LIBS . 'ITEM.php');\r
318 include($DIR_LIBS . 'NOTIFICATION.php');\r
319 include($DIR_LIBS . 'BAN.php');\r
320 include($DIR_LIBS . 'PAGEFACTORY.php');\r
321 include($DIR_LIBS . 'SEARCH.php');\r
322 include($DIR_LIBS . 'entity.php');\r
323 \r
324 \r
325 // set lastVisit cookie (if allowed)\r
326 if (!headers_sent() ) {\r
327         if ($CONF['LastVisit']) {\r
328                 setcookie($CONF['CookiePrefix'] . 'lastVisit', time(), time() + 2592000, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);\r
329         } else {\r
330                 setcookie($CONF['CookiePrefix'] . 'lastVisit', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);\r
331         }\r
332 }\r
333 \r
334 // read language file, only after user has been initialized\r
335 $language = getLanguageName();\r
336 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');\r
337 \r
338 // check if valid charset\r
339 if (!encoding_check(false, false, _CHARSET)) {\r
340         foreach(array($_GET, $_POST) as $input) {\r
341                 array_walk($input, 'encoding_check');\r
342         }\r
343 }\r
344 \r
345 /*\r
346         Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details\r
347 \r
348 // To remove after v2.5 is released and language files have been updated.\r
349 // Including this makes sure that language files for v2.5beta can still be used for v2.5final\r
350 // without having weird _SETTINGS_EXTAUTH string showing up in the admin area.\r
351 if (!defined('_MEMBERS_BYPASS'))\r
352 {\r
353         define('_SETTINGS_EXTAUTH',                     'Enable External Authentication');\r
354         define('_WARNING_EXTAUTH',                      'Warning: Enable only if needed.');\r
355         define('_MEMBERS_BYPASS',                       'Use External Authentication');\r
356 }\r
357 \r
358 */\r
359 \r
360 // make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined\r
361 if (!defined('_ARCHIVETYPE_MONTH') ) {\r
362         define('_ARCHIVETYPE_DAY', 'day');\r
363         define('_ARCHIVETYPE_MONTH', 'month');\r
364         define('_ARCHIVETYPE_YEAR', 'year');\r
365 }\r
366 \r
367 // decode path_info\r
368 if ($CONF['URLMode'] == 'pathinfo') {\r
369         // initialize keywords if this hasn't been done before\r
370         if (!isset($CONF['ItemKey']) || $CONF['ItemKey'] == '') {\r
371                 $CONF['ItemKey'] = 'item';\r
372         }\r
373 \r
374         if (!isset($CONF['ArchiveKey']) || $CONF['ArchiveKey'] == '') {\r
375                 $CONF['ArchiveKey'] = 'archive';\r
376         }\r
377 \r
378         if (!isset($CONF['ArchivesKey']) || $CONF['ArchivesKey'] == '') {\r
379                 $CONF['ArchivesKey'] = 'archives';\r
380         }\r
381 \r
382         if (!isset($CONF['MemberKey']) || $CONF['MemberKey'] == '') {\r
383                 $CONF['MemberKey'] = 'member';\r
384         }\r
385 \r
386         if (!isset($CONF['BlogKey']) || $CONF['BlogKey'] == '') {\r
387                 $CONF['BlogKey'] = 'blog';\r
388         }\r
389 \r
390         if (!isset($CONF['CategoryKey']) || $CONF['CategoryKey'] == '') {\r
391                 $CONF['CategoryKey'] = 'category';\r
392         }\r
393 \r
394         if (!isset($CONF['SpecialskinKey']) || $CONF['SpecialskinKey'] == '') {\r
395                 $CONF['SpecialskinKey'] = 'special';\r
396         }\r
397 \r
398         $parsed = false;\r
399         $manager->notify(\r
400                 'ParseURL',\r
401                 array(\r
402                         'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...\r
403                         'info' => $virtualpath,\r
404                         'complete' => &$parsed\r
405                 )\r
406         );\r
407 \r
408         if (!$parsed) {\r
409                 // default implementation\r
410                 $data = explode("/", $virtualpath );\r
411                 for ($i = 0; $i < sizeof($data); $i++) {\r
412                         switch ($data[$i]) {\r
413                                 case $CONF['ItemKey']: // item/1 (blogid)\r
414                                         $i++;\r
415 \r
416                                         if ($i < sizeof($data) ) {\r
417                                                 $itemid = intval($data[$i]);\r
418                                         }\r
419                                         break;\r
420 \r
421                                 case $CONF['ArchivesKey']: // archives/1 (blogid)\r
422                                         $i++;\r
423 \r
424                                         if ($i < sizeof($data) ) {\r
425                                                 $archivelist = intval($data[$i]);\r
426                                         }\r
427                                         break;\r
428 \r
429                                 case $CONF['ArchiveKey']: // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)\r
430                                         if ((($i + 1) < sizeof($data) ) && (!strstr($data[$i + 1], '-') ) ) {\r
431                                                 $blogid = intval($data[++$i]);\r
432                                         }\r
433 \r
434                                         $i++;\r
435 \r
436                                         if ($i < sizeof($data) ) {\r
437                                                 $archive = $data[$i];\r
438                                         }\r
439                                         break;\r
440 \r
441                                 case 'blogid': // blogid/1\r
442                                 case $CONF['BlogKey']: // blog/1\r
443                                         $i++;\r
444 \r
445                                         if ($i < sizeof($data) ) {\r
446                                                 $blogid = intval($data[$i]);\r
447                                         }\r
448                                         break;\r
449 \r
450                                 case $CONF['CategoryKey']: // category/1 (catid)\r
451                                 case 'catid':\r
452                                         $i++;\r
453 \r
454                                         if ($i < sizeof($data) ) {\r
455                                                 $catid = intval($data[$i]);\r
456                                         }\r
457                                         break;\r
458 \r
459                                 case $CONF['MemberKey']:\r
460                                         $i++;\r
461 \r
462                                         if ($i < sizeof($data) ) {\r
463                                                 $memberid = intval($data[$i]);\r
464                                         }\r
465                                         break;\r
466 \r
467                 case $CONF['SpecialskinKey']:\r
468                     $i++;\r
469 \r
470                                         if ($i < sizeof($data) ) {\r
471                         $_REQUEST['special'] = $data[$i];\r
472                     }\r
473                     break;\r
474 \r
475                                 default:\r
476                                         // skip...\r
477                         }\r
478                 }\r
479         }\r
480 }\r
481 \r
482 function intPostVar($name) {\r
483         return intval(postVar($name) );\r
484 }\r
485 \r
486 function intGetVar($name) {\r
487         return intval(getVar($name) );\r
488 }\r
489 \r
490 function intRequestVar($name) {\r
491         return intval(requestVar($name) );\r
492 }\r
493 \r
494 function intCookieVar($name) {\r
495         return intval(cookieVar($name) );\r
496 }\r
497 \r
498 /**\r
499   * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)\r
500   */\r
501 function getNucleusVersion() {\r
502         return 341;\r
503 }\r
504 \r
505 /**\r
506  * power users can install patches in between nucleus releases. These patches\r
507  * usually add new functionality in the plugin API and allow those to\r
508  * be tested without having to install CVS.\r
509  */\r
510 function getNucleusPatchLevel() {\r
511         return 0;\r
512 }\r
513 \r
514 /**\r
515  * returns the latest version available for download from nucleuscms.org \r
516  * or false if unable to attain data\r
517  * format will be major.minor/patachlevel\r
518  * e.g. 3.41 or 3.41/02\r
519  */\r
520 function getLatestVersion() {\r
521         if (!function_exists('curl_init')) return false;\r
522         $crl = curl_init();\r
523         $timeout = 5;\r
524         curl_setopt ($crl, CURLOPT_URL,'http://nucleuscms.org/version_check.php');\r
525         curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);\r
526         curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);\r
527         $ret = curl_exec($crl);\r
528         curl_close($crl);\r
529         return $ret;\r
530 \r
531 }\r
532 \r
533 /**\r
534   * Connects to mysql server\r
535   */\r
536 function sql_connect() {\r
537         global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE, $MYSQL_CONN;\r
538 \r
539         $MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>', 'Connect Error');\r
540         mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: ' . mysql_error() . '</p>', 'Connect Error');\r
541 \r
542 /*/ <add for garble measure>\r
543         $resource = sql_query("show variables LIKE 'character_set_database'");\r
544         $fetchDat = mysql_fetch_assoc($resource);\r
545         $charset  = $fetchDat['Value'];\r
546         $mySqlVer = implode('.', array_map('intval', explode('.', mysql_get_server_info($MYSQL_CONN))));\r
547         if ($mySqlVer >= '5.0.7' && phpversion() >= '5.2.3') {\r
548                 mysql_set_charset($charset);\r
549         } else {\r
550                 sql_query("SET NAMES " . $charset);\r
551         }\r
552 // </add for garble measure>*/\r
553 \r
554         return $MYSQL_CONN;\r
555 }\r
556 \r
557 /**\r
558  * returns a prefixed nucleus table name\r
559  */\r
560 function sql_table($name) {\r
561         global $MYSQL_PREFIX;\r
562 \r
563         if ($MYSQL_PREFIX) {\r
564                 return $MYSQL_PREFIX . 'nucleus_' . $name;\r
565         } else {\r
566                 return 'nucleus_' . $name;\r
567         }\r
568 }\r
569 \r
570 function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {\r
571         global $manager, $CONF;\r
572 \r
573         if (!headers_sent() ) {\r
574                 // if content type is application/xhtml+xml, only send it to browsers\r
575                 // that can handle it (IE6 cannot). Otherwise, send text/html\r
576 \r
577                 // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)\r
578                 //       application/xhtml+xml still causes too much problems with the javascript implementations\r
579 \r
580                 // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,\r
581                 //       application/xhtml+xml seems to be working, so we're going to use it if we can.\r
582                 //\r
583                 // Note: reverted the following function in JP version\r
584                 //\r
585         /*\r
586                 // v3.3 code\r
587                 if (\r
588                                 ($contenttype == 'application/xhtml+xml')\r
589                         &&      (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )\r
590                         ) {\r
591                         $contenttype = 'text/html';\r
592                 }\r
593         */\r
594                 // v3.2x code\r
595                 if (\r
596                                 ($contenttype == 'application/xhtml+xml')\r
597                         &&      (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))\r
598                         )\r
599                 {\r
600                         $contenttype = 'text/html';\r
601                 }\r
602 \r
603                 $manager->notify(\r
604                         'PreSendContentType',\r
605                         array(\r
606                                 'contentType' => &$contenttype,\r
607                                 'charset' => &$charset,\r
608                                 'pageType' => $pagetype\r
609                         )\r
610                 );\r
611 \r
612                 // strip strange characters\r
613                 $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);\r
614                 $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);\r
615 \r
616                 if ($charset != '') {\r
617                         header('Content-Type: ' . $contenttype . '; charset=' . $charset);\r
618                 } else {\r
619                         header('Content-Type: ' . $contenttype);\r
620                 }\r
621 \r
622                 // check if valid charset\r
623                 if (!encoding_check(false,false,$charset)) {\r
624                         foreach(array($_GET, $_POST) as $input) {\r
625                                 array_walk($input, 'encoding_check');\r
626                         }\r
627                 }\r
628         }\r
629 }\r
630 \r
631 /**\r
632  * Errors before the database connection has been made\r
633  */\r
634 function startUpError($msg, $title) {\r
635         if (!defined('_CHARSET')) define('_CHARSET', 'iso-8859-1');\r
636         header('Content-Type: text/html; charset=' . _CHARSET);\r
637         ?>\r
638         <html <?php echo _HTML_XML_NAME_SPACE_AND_LANG_CODE; ?>>\r
639                 <head><meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET?>" />\r
640                 <title><?php echo htmlspecialchars($title)?></title></head>\r
641                 <body>\r
642                         <h1><?php echo htmlspecialchars($title)?></h1>\r
643                         <?php echo $msg?>\r
644                 </body>\r
645         </html>\r
646         <?php   exit;\r
647 }\r
648 \r
649 /**\r
650   * disconnects from SQL server\r
651   */\r
652 function sql_disconnect() {\r
653         @mysql_close();\r
654 }\r
655 \r
656 /**\r
657   * executes an SQL query\r
658   */\r
659 function sql_query($query) {\r
660         global $SQLCount;\r
661         $SQLCount++;\r
662         $res = mysql_query($query) or print("mySQL error with query $query: " . mysql_error() . '<p />');\r
663         return $res;\r
664 }\r
665 \r
666 \r
667 /**\r
668  * Highlights a specific query in a given HTML text (not within HTML tags) and returns it\r
669  *\r
670  * @param $text\r
671  *              text to be highlighted\r
672  * @param $expression\r
673  *              regular expression to be matched (can be an array of expressions as well)\r
674  * @param $highlight\r
675  *              highlight to be used (use \\0 to indicate the matched expression)\r
676  *\r
677  */\r
678 function highlight($text, $expression, $highlight) {\r
679         if (!$highlight || !$expression) {\r
680                 return $text;\r
681         }\r
682 \r
683         if (is_array($expression) && (count($expression) == 0) ) {\r
684                 return $text;\r
685         }\r
686 \r
687         // add a tag in front (is needed for preg_match_all to work correct)\r
688         $text = '<!--h-->' . $text;\r
689 \r
690         // split the HTML up so we have HTML tags\r
691         // $matches[0][i] = HTML + text\r
692         // $matches[1][i] = HTML\r
693         // $matches[2][i] = text\r
694         preg_match_all('/(<[^>]+>)([^<>]*)/', $text, $matches);\r
695 \r
696         // throw it all together again while applying the highlight to the text pieces\r
697         $result = '';\r
698         for ($i = 0; $i < sizeof($matches[2]); $i++) {\r
699                 if ($i != 0) {\r
700                         $result .= $matches[1][$i];\r
701                 }\r
702 \r
703                 if (is_array($expression) ) {\r
704                         foreach ($expression as $regex) {\r
705                                 if ($regex) {\r
706                                         $matches[2][$i] = @eregi_replace($regex, $highlight, $matches[2][$i]);\r
707                                 }\r
708                         }\r
709 \r
710                         $result .= $matches[2][$i];\r
711                 } else {\r
712                         $result .= @eregi_replace($expression, $highlight, $matches[2][$i]);\r
713                 }\r
714         }\r
715 \r
716         return $result;\r
717 }\r
718 \r
719 /**\r
720  * Parses a query into an array of expressions that can be passed on to the highlight method\r
721  */\r
722 function parseHighlight($query) {\r
723         // TODO: add more intelligent splitting logic\r
724 \r
725         // get rid of quotes\r
726         $query = preg_replace('/\'|"/', '', $query);\r
727 \r
728         if (!$query) {\r
729                 return array();\r
730         }\r
731 \r
732         $aHighlight = explode(' ', $query);\r
733 \r
734         for ($i = 0; $i < count($aHighlight); $i++) {\r
735                 $aHighlight[$i] = trim($aHighlight[$i]);\r
736 \r
737                 if (strlen($aHighlight[$i]) < 3) {\r
738                         unset($aHighlight[$i]);\r
739                 }\r
740         }\r
741 \r
742         if (count($aHighlight) == 1) {\r
743                 return $aHighlight[0];\r
744         } else {\r
745                 return $aHighlight;\r
746         }\r
747 }\r
748 \r
749 /**\r
750   * Checks if email address is valid\r
751   */\r
752 function isValidMailAddress($address) {\r
753         if (preg_match('/^[a-zA-Z+0-9\._-]+@[a-zA-Z0-9\._-]+\.[A-Za-z]{2,5}$/', $address)) {\r
754                 return 1;\r
755         } else {\r
756                 return 0;\r
757         }\r
758 }\r
759 \r
760 \r
761 // some helper functions\r
762 function getBlogIDFromName($name) {\r
763         return quickQuery('SELECT bnumber as result FROM ' . sql_table('blog') . ' WHERE bshortname="' . addslashes($name) . '"');\r
764 }\r
765 \r
766 function getBlogNameFromID($id) {\r
767         return quickQuery('SELECT bname as result FROM ' . sql_table('blog') . ' WHERE bnumber=' . intval($id) );\r
768 }\r
769 \r
770 function getBlogIDFromItemID($itemid) {\r
771         return quickQuery('SELECT iblog as result FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid) );\r
772 }\r
773 \r
774 function getBlogIDFromCommentID($commentid) {\r
775         return quickQuery('SELECT cblog as result FROM ' . sql_table('comment') . ' WHERE cnumber=' . intval($commentid) );\r
776 }\r
777 \r
778 function getBlogIDFromCatID($catid) {\r
779         return quickQuery('SELECT cblog as result FROM ' . sql_table('category') . ' WHERE catid=' . intval($catid) );\r
780 }\r
781 \r
782 function getCatIDFromName($name) {\r
783         return quickQuery('SELECT catid as result FROM ' . sql_table('category') . ' WHERE cname="' . addslashes($name) . '"');\r
784 }\r
785 \r
786 function quickQuery($q) {\r
787         $res = sql_query($q);\r
788         $obj = mysql_fetch_object($res);\r
789         return $obj->result;\r
790 }\r
791 \r
792 function getPluginNameFromPid($pid) {\r
793         $res = sql_query('SELECT pfile FROM ' . sql_table('plugin') . ' WHERE pid=' . intval($pid) );\r
794         $obj = mysql_fetch_object($res);\r
795         return $obj->pfile;\r
796 }\r
797 \r
798 function selector() {\r
799         global $itemid, $blogid, $memberid, $query, $amount, $archivelist, $maxresults;\r
800         global $archive, $skinid, $blog, $memberinfo, $CONF, $member;\r
801         global $imagepopup, $catid, $special;\r
802         global $manager;\r
803 \r
804         $actionNames = array('addcomment', 'sendmessage', 'createaccount', 'forgotpassword', 'votepositive', 'votenegative', 'plugin');\r
805         $action = requestVar('action');\r
806 \r
807         if (in_array($action, $actionNames) ) {\r
808                 global $DIR_LIBS, $errormessage;\r
809                 include_once($DIR_LIBS . 'ACTION.php');\r
810                 $a = new ACTION();\r
811                 $errorInfo = $a->doAction($action);\r
812 \r
813                 if ($errorInfo) {\r
814                         $errormessage = $errorInfo['message'];\r
815                 }\r
816         }\r
817 \r
818         // show error when headers already sent out\r
819         if (headers_sent() && $CONF['alertOnHeadersSent']) {\r
820 \r
821                 // try to get line number/filename (extra headers_sent params only exists in PHP 4.3+)\r
822                 if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=') ) {\r
823                         headers_sent($hsFile, $hsLine);\r
824                         $extraInfo = ' in <code>' . $hsFile . '</code> line <code>' . $hsLine . '</code>';\r
825                 } else {\r
826                         $extraInfo = '';\r
827                 }\r
828 \r
829                 startUpError(\r
830                         '<p>The page headers have already been sent out' . $extraInfo . '. This could cause Nucleus not to work in the expected way.</p><p>Usually, this is caused by spaces or newlines at the end of the <code>config.php</code> file, at the end of the language file or at the end of a plugin file. Please check this and try again.</p><p>If you don\'t want to see this error message again, without solving the problem, set <code>$CONF[\'alertOnHeadersSent\']</code> in <code>globalfunctions.php</code> to <code>0</code></p>',\r
831                         'Page headers already sent'\r
832                 );\r
833                 exit;\r
834         }\r
835 \r
836         // make is so ?archivelist without blogname or blogid shows the archivelist\r
837         // for the default weblog\r
838         if (serverVar('QUERY_STRING') == 'archivelist') {\r
839                 $archivelist = $CONF['DefaultBlog'];\r
840         }\r
841 \r
842         // now decide which type of skin we need\r
843         if ($itemid) {\r
844                 // itemid given -> only show that item\r
845                 $type = 'item';\r
846 \r
847                 if (!$manager->existsItem($itemid,0,0) ) {\r
848                         doError(_ERROR_NOSUCHITEM);\r
849                 }\r
850 \r
851                 global $itemidprev, $itemidnext, $catid, $itemtitlenext, $itemtitleprev;\r
852 \r
853                 // 1. get timestamp, blogid and catid for item\r
854                 $query = 'SELECT itime, iblog, icat FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid);\r
855                 $res = sql_query($query);\r
856                 $obj = mysql_fetch_object($res);\r
857 \r
858                 // if a different blog id has been set through the request or selectBlog(),\r
859                 // deny access\r
860 //              if ($blogid && (intval($blogid) != $obj->iblog) ) {\r
861 //                      doError(_ERROR_NOSUCHITEM);\r
862 //              }\r
863                 if ($blogid && (intval($blogid) != $obj->iblog) ) {\r
864                         if (!headers_sent()) {\r
865                                 $b =& $manager->getBlog($obj->iblog);\r
866                                 $CONF['ItemURL'] = $b->getURL();\r
867                                 if ($CONF['URLMode'] == 'pathinfo' and substr($CONF['ItemURL'],-1) == '/')\r
868                                         $CONF['ItemURL'] = substr($CONF['ItemURL'], 0, -1);\r
869                                 $correctURL = createItemLink($itemid, '');\r
870                                 redirect($correctURL);\r
871                                 exit;\r
872                         } else {\r
873                                 doError(_ERROR_NOSUCHITEM);\r
874                         }\r
875                 }\r
876 \r
877                 // if a category has been selected which doesn't match the item, ignore the\r
878                 // category. #85\r
879                 if (($catid != 0) && ($catid != $obj->icat) ) {\r
880                         $catid = 0;\r
881                 }\r
882 \r
883                 $blogid = $obj->iblog;\r
884                 $timestamp = strtotime($obj->itime);\r
885 \r
886                 $b =& $manager->getBlog($blogid);\r
887 \r
888                 if ($b->isValidCategory($catid) ) {\r
889                         $catextra = ' and icat=' . $catid;\r
890                 } else {\r
891                         $catextra = '';\r
892                 }\r
893 \r
894                 // get previous itemid and title\r
895                 $query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE itime<' . mysqldate($timestamp) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime DESC LIMIT 1';\r
896                 $res = sql_query($query);\r
897 \r
898                 $obj = mysql_fetch_object($res);\r
899 \r
900                 if ($obj) {\r
901                         $itemidprev = $obj->inumber;\r
902                         $itemtitleprev = $obj->ititle;\r
903                 }\r
904 \r
905                 // get next itemid and title\r
906                 $query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE itime>' . mysqldate($timestamp) . ' and itime <= ' . mysqldate($b->getCorrectTime()) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime ASC LIMIT 1';\r
907                 $res = sql_query($query);\r
908 \r
909                 $obj = mysql_fetch_object($res);\r
910 \r
911                 if ($obj) {\r
912                         $itemidnext = $obj->inumber;\r
913                         $itemtitlenext = $obj->ititle;\r
914                 }\r
915 \r
916         } elseif ($archive) {\r
917                 // show archive\r
918                 $type = 'archive';\r
919 \r
920                 // get next and prev month links ...\r
921                 global $archivenext, $archiveprev, $archivetype, $archivenextexists, $archiveprevexists;\r
922 \r
923                 // sql queries for the timestamp of the first and the last published item\r
924                 $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 AND iblog=".(int)($blogid ? $blogid : $CONF['DefaultBlog'])." ORDER BY itime ASC";\r
925                 $first_timestamp=quickQuery ($query);\r
926                 $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 AND iblog=".(int)($blogid ? $blogid : $CONF['DefaultBlog'])." ORDER BY itime DESC";\r
927                 $last_timestamp=quickQuery ($query);\r
928 \r
929                 sscanf($archive, '%d-%d-%d', $y, $m, $d);\r
930 \r
931                 if ($d != 0) {\r
932                         $archivetype = _ARCHIVETYPE_DAY;\r
933                         $t = mktime(0, 0, 0, $m, $d, $y);\r
934                         // one day has 24 * 60 * 60 = 86400 seconds\r
935                         $archiveprev = strftime('%Y-%m-%d', $t - 86400 );\r
936                         // check for published items\r
937                         if ($t > $first_timestamp) {\r
938                                 $archiveprevexists = true;\r
939                         }\r
940                         else {\r
941                                 $archiveprevexists = false;\r
942                         }\r
943 \r
944                         // one day later\r
945                         $t += 86400;\r
946                         $archivenext = strftime('%Y-%m-%d', $t);\r
947                         if ($t < $last_timestamp) {\r
948                                 $archivenextexists = true;\r
949                         }\r
950                         else {\r
951                                 $archivenextexists = false;\r
952                         }\r
953 \r
954                 } elseif ($m == 0) {\r
955                         $archivetype = _ARCHIVETYPE_YEAR;\r
956                         $t = mktime(0, 0, 0, 12, 31, $y - 1);\r
957                         // one day before is in the previous year\r
958                         $archiveprev = strftime('%Y', $t);\r
959                         if ($t > $first_timestamp) {\r
960                                 $archiveprevexists = true;\r
961                         }\r
962                         else {\r
963                                 $archiveprevexists = false;\r
964                         }\r
965 \r
966                         // timestamp for the next year\r
967                         $t = mktime(0, 0, 0, 1, 1, $y + 1);\r
968                         $archivenext = strftime('%Y', $t);\r
969                         if ($t < $last_timestamp) {\r
970                                 $archivenextexists = true;\r
971                         }\r
972                         else {\r
973                                 $archivenextexists = false;\r
974                         }\r
975                 } else {\r
976                         $archivetype = _ARCHIVETYPE_MONTH;\r
977                         $t = mktime(0, 0, 0, $m, 1, $y);\r
978                         // one day before is in the previous month\r
979                         $archiveprev = strftime('%Y-%m', $t - 86400);\r
980                         if ($t > $first_timestamp) {\r
981                                 $archiveprevexists = true;\r
982                         }\r
983                         else {\r
984                                 $archiveprevexists = false;\r
985                         }\r
986 \r
987                         // timestamp for the next month\r
988                         $t = mktime(0, 0, 0, $m+1, 1, $y);\r
989                         $archivenext = strftime('%Y-%m', $t);\r
990                         if ($t < $last_timestamp) {\r
991                                 $archivenextexists = true;\r
992                         }\r
993                         else {\r
994                                 $archivenextexists = false;\r
995                         }\r
996                 }\r
997 \r
998         } elseif ($archivelist) {\r
999                 $type = 'archivelist';\r
1000 \r
1001                 if (is_numeric($archivelist)) {\r
1002                         $blogid = intVal($archivelist);\r
1003                 } else {\r
1004                         $blogid = getBlogIDFromName($archivelist);\r
1005                 }\r
1006 \r
1007                 if (!$blogid) {\r
1008                         doError(_ERROR_NOSUCHBLOG);\r
1009                 }\r
1010 \r
1011         } elseif ($query) {\r
1012                 global $startpos;\r
1013                 $type = 'search';\r
1014                 $query = stripslashes($query);\r
1015                 if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/", $query)){\r
1016                                         $type = 'index';\r
1017                 }\r
1018                 $order = (_CHARSET == 'EUC-JP') ? 'EUC-JP, UTF-8,' : 'UTF-8, EUC-JP,';\r
1019                 $query = mb_convert_encoding($query, _CHARSET, $order . ' JIS, SJIS, ASCII');\r
1020                 if (is_numeric($blogid)) {\r
1021                         $blogid = intVal($blogid);\r
1022                 } else {\r
1023                         $blogid = getBlogIDFromName($blogid);\r
1024                 }\r
1025 \r
1026                 if (!$blogid) {\r
1027                         doError(_ERROR_NOSUCHBLOG);\r
1028                 }\r
1029 \r
1030         } elseif ($memberid) {\r
1031                 $type = 'member';\r
1032 \r
1033                 if (!MEMBER::existsID($memberid) ) {\r
1034                         doError(_ERROR_NOSUCHMEMBER);\r
1035                 }\r
1036 \r
1037                 $memberinfo = $manager->getMember($memberid);\r
1038 \r
1039         } elseif ($imagepopup) {\r
1040                 // media object (images etc.)\r
1041                 $type = 'imagepopup';\r
1042 \r
1043                 // TODO: check if media-object exists\r
1044                 // TODO: set some vars?\r
1045         } else {\r
1046                 // show regular index page\r
1047                 global $startpos;\r
1048                 $type = 'index';\r
1049         }\r
1050 \r
1051         // decide which blog should be displayed\r
1052         if (!$blogid) {\r
1053                 $blogid = $CONF['DefaultBlog'];\r
1054         }\r
1055 \r
1056         $b =& $manager->getBlog($blogid);\r
1057         $blog = $b;     // references can't be placed in global variables?\r
1058 \r
1059         if (!$blog->isValid) {\r
1060                 doError(_ERROR_NOSUCHBLOG);\r
1061         }\r
1062 \r
1063         // set catid if necessary\r
1064         if ($catid) {\r
1065                 $blog->setSelectedCategory($catid);\r
1066         }\r
1067 \r
1068         // decide which skin should be used\r
1069         if ($skinid != '' && ($skinid == 0) ) {\r
1070                 selectSkin($skinid);\r
1071         }\r
1072 \r
1073         if (!$skinid) {\r
1074                 $skinid = $blog->getDefaultSkin();\r
1075         }\r
1076 \r
1077         //$special = requestVar('special'); //get at top of file as global\r
1078         if (!empty($special) && isValidShortName($special)) {\r
1079                 $type = strtolower($special);\r
1080         }\r
1081 \r
1082         $skin = new SKIN($skinid);\r
1083 \r
1084         if (!$skin->isValid) {\r
1085                 doError(_ERROR_NOSUCHSKIN);\r
1086         }\r
1087 \r
1088         // parse the skin\r
1089         $skin->parse($type);\r
1090 \r
1091         // check to see we should throw JustPosted event\r
1092         $blog->checkJustPosted();\r
1093 }\r
1094 \r
1095 /**\r
1096   * Show error skin with given message. An optional skin-object to use can be given\r
1097   */\r
1098 function doError($msg, $skin = '') {\r
1099         global $errormessage, $CONF, $skinid, $blogid, $manager;\r
1100 \r
1101         if ($skin == '') {\r
1102 \r
1103                 if (SKIN::existsID($skinid) ) {\r
1104                         $skin = new SKIN($skinid);\r
1105                 } elseif ($manager->existsBlogID($blogid) ) {\r
1106                         $blog =& $manager->getBlog($blogid);\r
1107                         $skin = new SKIN($blog->getDefaultSkin() );\r
1108                 } elseif ($CONF['DefaultBlog']) {\r
1109                         $blog =& $manager->getBlog($CONF['DefaultBlog']);\r
1110                         $skin = new SKIN($blog->getDefaultSkin() );\r
1111                 } else {\r
1112                         // this statement should actually never be executed\r
1113                         $skin = new SKIN($CONF['BaseSkin']);\r
1114                 }\r
1115 \r
1116         }\r
1117 \r
1118         $skinid = $skin->id;\r
1119         $errormessage = $msg;\r
1120         $skin->parse('error');\r
1121         exit;\r
1122 }\r
1123 \r
1124 function getConfig() {\r
1125         global $CONF;\r
1126 \r
1127         $query = 'SELECT * FROM ' . sql_table('config');\r
1128         $res = sql_query($query);\r
1129 \r
1130         while ($obj = mysql_fetch_object($res) ) {\r
1131                 $CONF[$obj->name] = $obj->value;\r
1132         }\r
1133 }\r
1134 \r
1135 // some checks for names of blogs, categories, templates, members, ...\r
1136 function isValidShortName($name) {\r
1137         return eregi('^[a-z0-9]+$', $name);\r
1138 }\r
1139 \r
1140 function isValidDisplayName($name) {\r
1141         return eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name);\r
1142 }\r
1143 \r
1144 function isValidCategoryName($name) {\r
1145         return 1;\r
1146 }\r
1147 \r
1148 function isValidTemplateName($name) {\r
1149         return eregi('^[a-z0-9/]+$', $name);\r
1150 }\r
1151 \r
1152 function isValidSkinName($name) {\r
1153         return eregi('^[a-z0-9/]+$', $name);\r
1154 }\r
1155 \r
1156 // add and remove linebreaks\r
1157 function addBreaks($var) {\r
1158         return nl2br($var);\r
1159 }\r
1160 \r
1161 function removeBreaks($var) {\r
1162         return preg_replace("/<br \/>([\r\n])/", "$1", $var);\r
1163 }\r
1164 \r
1165 // shortens a text string to maxlength ($toadd) is what needs to be added\r
1166 // at the end (end length is <= $maxlength)\r
1167 function shorten($text, $maxlength, $toadd) {\r
1168         // 1. remove entities...\r
1169 //      $trans = get_html_translation_table(HTML_ENTITIES);\r
1170         $trans = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese\r
1171         $trans = array_flip($trans);\r
1172         $text  = strtr($text, $trans);\r
1173 \r
1174         // 2. the actual shortening\r
1175         if (strlen($text) > $maxlength) {\r
1176 //              $text = substr($text, 0, $maxlength - strlen($toadd) ) . $toadd;\r
1177                 $text = mb_strimwidth($text, 0, $maxlength, $toadd, _CHARSET); // for Japanese\r
1178         }\r
1179         return $text;\r
1180 }\r
1181 \r
1182 /**\r
1183   * Converts a unix timestamp to a mysql DATETIME format, and places\r
1184   * quotes around it.\r
1185   */\r
1186 function mysqldate($timestamp) {\r
1187         return '"' . date('Y-m-d H:i:s', $timestamp) . '"';\r
1188 }\r
1189 \r
1190 /**\r
1191   * functions for use in index.php\r
1192   */\r
1193 function selectBlog($shortname) {\r
1194         global $blogid, $archivelist;\r
1195         $blogid = getBlogIDFromName($shortname);\r
1196 \r
1197         // also force archivelist variable, if it is set\r
1198         if ($archivelist) {\r
1199                 $archivelist = $blogid;\r
1200         }\r
1201 }\r
1202 \r
1203 function selectSkin($skinname) {\r
1204         global $skinid;\r
1205         $skinid = SKIN::getIdFromName($skinname);\r
1206 }\r
1207 \r
1208 /**\r
1209  * Can take either a category ID or a category name (be aware that\r
1210  * multiple categories can have the same name)\r
1211  */\r
1212 function selectCategory($cat) {\r
1213         global $catid;\r
1214         if (is_numeric($cat) ) {\r
1215                 $catid = intval($cat);\r
1216         } else {\r
1217                 $catid = getCatIDFromName($cat);\r
1218         }\r
1219 }\r
1220 \r
1221 function selectItem($id) {\r
1222         global $itemid;\r
1223         $itemid = intval($id);\r
1224 }\r
1225 \r
1226 // force the use of a language file (warning: can cause warnings)\r
1227 function selectLanguage($language) {\r
1228         global $DIR_LANG;\r
1229         include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');\r
1230 }\r
1231 \r
1232 function parseFile($filename, $includeMode = 'normal', $includePrefix = '') {\r
1233         $handler = new ACTIONS('fileparser');\r
1234         $parser = new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);\r
1235         $handler->parser =& $parser;\r
1236 \r
1237         // set IncludeMode properties of parser\r
1238         PARSER::setProperty('IncludeMode', $includeMode);\r
1239         PARSER::setProperty('IncludePrefix', $includePrefix);\r
1240 \r
1241         if (!file_exists($filename) ) {\r
1242                 doError('A file is missing');\r
1243         }\r
1244 \r
1245         $fsize = filesize($filename);\r
1246 \r
1247         if ($fsize <= 0) {\r
1248                 return;\r
1249         }\r
1250 \r
1251         // read file\r
1252         $fd = fopen ($filename, 'r');\r
1253         $contents = fread ($fd, $fsize);\r
1254         fclose ($fd);\r
1255 \r
1256         // parse file contents\r
1257         $parser->parse($contents);\r
1258 }\r
1259 \r
1260 /**\r
1261   * Outputs a debug message\r
1262   */\r
1263 function debug($msg) {\r
1264         echo '<p><b>' . $msg . "</b></p>\n";\r
1265 }\r
1266 \r
1267 // shortcut\r
1268 function addToLog($level, $msg) {\r
1269         ACTIONLOG::add($level, $msg);\r
1270 }\r
1271 \r
1272 // shows a link to help file\r
1273 function help($id) {\r
1274         echo helpHtml($id);\r
1275 }\r
1276 \r
1277 function helpHtml($id) {\r
1278         global $CONF;\r
1279         return helplink($id) . '<img src="' . $CONF['AdminURL'] . 'documentation/icon-help.gif" width="15" height="15" alt="' . _HELP_TT . '" title="' . _HELP_TT . '" /></a>';\r
1280 }\r
1281 \r
1282 function helplink($id) {\r
1283         global $CONF;\r
1284         return '<a href="' . $CONF['AdminURL'] . 'documentation/help.html#'. $id . '" onclick="if (event &amp;&amp; event.preventDefault) event.preventDefault(); return help(this.href);">';\r
1285 }\r
1286 \r
1287 function getMailFooter() {\r
1288         $message = "\n\n-----------------------------";\r
1289         $message .=  "\n   Powered by Nucleus CMS";\r
1290         $message .=  "\n(http://www.nucleuscms.org/)";\r
1291         return $message;\r
1292 }\r
1293 \r
1294 /**\r
1295   * Returns the name of the language to use\r
1296   * preference priority: member - site\r
1297   * defaults to english when no good language found\r
1298   *\r
1299   * checks if file exists, etc...\r
1300   */\r
1301 function getLanguageName() {\r
1302         global $CONF, $member;\r
1303 \r
1304         if ($member && $member->isLoggedIn() ) {\r
1305                 // try to use members language\r
1306                 $memlang = $member->getLanguage();\r
1307 \r
1308                 if (($memlang != '') && (checkLanguage($memlang) ) ) {\r
1309                         return $memlang;\r
1310                 }\r
1311         }\r
1312 \r
1313         // use default language\r
1314         if (checkLanguage($CONF['Language']) ) {\r
1315                 return $CONF['Language'];\r
1316         } else {\r
1317                 return 'english';\r
1318         }\r
1319 }\r
1320 \r
1321 /**\r
1322   * Includes a PHP file. This method can be called while parsing templates and skins\r
1323   */\r
1324 function includephp($filename) {\r
1325         // make predefined variables global, so most simple scripts can be used here\r
1326 \r
1327         // apache (names taken from PHP doc)\r
1328         global $GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE, $SERVER_PROTOCOL;\r
1329         global $REQUEST_METHOD, $QUERY_STRING, $DOCUMENT_ROOT, $HTTP_ACCEPT;\r
1330         global $HTTP_ACCEPT_CHARSET, $HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE;\r
1331         global $HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER, $HTTP_USER_AGENT;\r
1332         global $REMOTE_ADDR, $REMOTE_PORT, $SCRIPT_FILENAME, $SERVER_ADMIN;\r
1333         global $SERVER_PORT, $SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME;\r
1334         global $REQUEST_URI;\r
1335 \r
1336         // php (taken from PHP doc)\r
1337         global $argv, $argc, $PHP_SELF, $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS;\r
1338         global $HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS, $HTTP_SESSION_VARS;\r
1339 \r
1340         // other\r
1341         global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;\r
1342 \r
1343         if (@file_exists($filename) ) {\r
1344                 include($filename);\r
1345         }\r
1346 }\r
1347 \r
1348 /**\r
1349   * Checks if a certain language/plugin exists\r
1350   */\r
1351 function checkLanguage($lang) {\r
1352         global $DIR_LANG ;\r
1353         return file_exists($DIR_LANG . ereg_replace( '[\\|/]', '', $lang) . '.php');\r
1354 }\r
1355 \r
1356 function checkPlugin($plug) {\r
1357         global $DIR_PLUGINS;\r
1358         return file_exists($DIR_PLUGINS . ereg_replace( '[\\|/]', '', $plug) . '.php');\r
1359 }\r
1360 \r
1361 /**\r
1362   * Centralisation of the functions that generate links\r
1363   */\r
1364 function createItemLink($itemid, $extra = '') {\r
1365         return createLink('item', array('itemid' => $itemid, 'extra' => $extra) );\r
1366 }\r
1367 \r
1368 function createMemberLink($memberid, $extra = '') {\r
1369         return createLink('member', array('memberid' => $memberid, 'extra' => $extra) );\r
1370 }\r
1371 \r
1372 function createCategoryLink($catid, $extra = '') {\r
1373         return createLink('category', array('catid' => $catid, 'extra' => $extra) );\r
1374 }\r
1375 \r
1376 function createArchiveListLink($blogid = '', $extra = '') {\r
1377         return createLink('archivelist', array('blogid' => $blogid, 'extra' => $extra) );\r
1378 }\r
1379 \r
1380 function createArchiveLink($blogid, $archive, $extra = '') {\r
1381         return createLink('archive', array('blogid' => $blogid, 'archive' => $archive, 'extra' => $extra) );\r
1382 }\r
1383 \r
1384 function createBlogidLink($blogid, $params = '') {\r
1385         return createLink('blog', array('blogid' => $blogid, 'extra' => $params) );\r
1386 }\r
1387 \r
1388 function createLink($type, $params) {\r
1389         global $manager, $CONF;\r
1390 \r
1391         $generatedURL = '';\r
1392         $usePathInfo = ($CONF['URLMode'] == 'pathinfo');\r
1393 \r
1394         // ask plugins first\r
1395         $created = false;\r
1396 \r
1397         if ($usePathInfo) {\r
1398                 $manager->notify(\r
1399                         'GenerateURL',\r
1400                         array(\r
1401                                 'type' => $type,\r
1402                                 'params' => $params,\r
1403                                 'completed' => &$created,\r
1404                                 'url' => &$url\r
1405                         )\r
1406                 );\r
1407         }\r
1408 \r
1409         // if a plugin created the URL, return it\r
1410         if ($created) {\r
1411                 return $url;\r
1412         }\r
1413 \r
1414         // default implementation\r
1415         switch ($type) {\r
1416                 case 'item':\r
1417                         if ($usePathInfo) {\r
1418                                 $url = $CONF['ItemURL'] . '/' . $CONF['ItemKey'] . '/' . $params['itemid'];\r
1419                         } else {\r
1420                                 $url = $CONF['ItemURL'] . '?itemid=' . $params['itemid'];\r
1421                         }\r
1422                         break;\r
1423 \r
1424                 case 'member':\r
1425                         if ($usePathInfo) {\r
1426                                 $url = $CONF['MemberURL'] . '/' . $CONF['MemberKey'] . '/' . $params['memberid'];\r
1427                         } else {\r
1428                                 $url = $CONF['MemberURL'] . '?memberid=' . $params['memberid'];\r
1429                         }\r
1430                         break;\r
1431 \r
1432                 case 'category':\r
1433                         if ($usePathInfo) {\r
1434                                 $url = $CONF['CategoryURL'] . '/' . $CONF['CategoryKey'] . '/' . $params['catid'];\r
1435                         } else {\r
1436                                 $url = $CONF['CategoryURL'] . '?catid=' . $params['catid'];\r
1437                         }\r
1438                         break;\r
1439 \r
1440                 case 'archivelist':\r
1441                         if (!$params['blogid']) {\r
1442                                 $params['blogid'] = $CONF['DefaultBlog'];\r
1443                         }\r
1444 \r
1445                         if ($usePathInfo) {\r
1446                                 $url = $CONF['ArchiveListURL'] . '/' . $CONF['ArchivesKey'] . '/' . $params['blogid'];\r
1447                         } else {\r
1448                                 $url = $CONF['ArchiveListURL'] . '?archivelist=' . $params['blogid'];\r
1449                         }\r
1450                         break;\r
1451 \r
1452                 case 'archive':\r
1453                         if ($usePathInfo) {\r
1454                                 $url = $CONF['ArchiveURL'] . '/' . $CONF['ArchiveKey'] . '/'.$params['blogid'].'/' . $params['archive'];\r
1455                         } else {\r
1456                                 $url = $CONF['ArchiveURL'] . '?blogid='.$params['blogid'].'&amp;archive=' . $params['archive'];\r
1457                         }\r
1458                         break;\r
1459 \r
1460                 case 'blog':\r
1461                         if ($usePathInfo) {\r
1462                                 $url = $CONF['BlogURL'] . '/' . $CONF['BlogKey'] . '/' . $params['blogid'];\r
1463                         } else {\r
1464                                 $url = $CONF['BlogURL'] . '?blogid=' . $params['blogid'];\r
1465                         }\r
1466                         break;\r
1467         }\r
1468 \r
1469         return addLinkParams($url, (isset($params['extra'])? $params['extra'] : null));\r
1470 }\r
1471 \r
1472 function createBlogLink($url, $params) {\r
1473     global $CONF;\r
1474     if ($CONF['URLMode'] == 'normal') {\r
1475         if (strpos($url, '?') === FALSE && is_array($params)) {\r
1476             $fParam = reset($params);\r
1477             $fKey   = key($params);\r
1478             array_shift($params);\r
1479             $url .= '?' . $fKey . '=' . $fParam;\r
1480         }\r
1481     } elseif ($CONF['URLMode'] == 'pathinfo' && substr($url, -1) == '/') {\r
1482         $url = substr($url, 0, -1);\r
1483     }\r
1484         return addLinkParams($url, $params);\r
1485 }\r
1486 \r
1487 function addLinkParams($link, $params) {\r
1488         global $CONF;\r
1489 \r
1490         if (is_array($params) ) {\r
1491 \r
1492                 if ($CONF['URLMode'] == 'pathinfo')     {\r
1493 \r
1494                         foreach ($params as $param => $value) {\r
1495                                 $link .= '/' . $param . '/' . urlencode($value);\r
1496                         }\r
1497 \r
1498                 } else {\r
1499 \r
1500                         foreach ($params as $param => $value) {\r
1501                                 $link .= '&amp;' . $param . '=' . urlencode($value);\r
1502                         }\r
1503 \r
1504                 }\r
1505         }\r
1506 \r
1507         return $link;\r
1508 }\r
1509 \r
1510 /**\r
1511  * @param $querystr\r
1512  *              querystring to alter (e.g. foo=1&bar=2&x=y)\r
1513  * @param $param\r
1514  *              name of parameter to change (e.g. 'foo')\r
1515  * @param $value\r
1516  *              New value for that parameter (e.g. 3)\r
1517  * @result\r
1518  *              altered query string (for the examples above: foo=3&bar=2&x=y)\r
1519  */\r
1520 function alterQueryStr($querystr, $param, $value) {\r
1521         $vars = explode('&', $querystr);\r
1522         $set  = false;\r
1523 \r
1524         for ($i = 0; $i < count($vars); $i++) {\r
1525                 $v = explode('=', $vars[$i]);\r
1526 \r
1527                 if ($v[0] == $param) {\r
1528                         $v[1] = $value;\r
1529                         $vars[$i] = implode('=', $v);\r
1530                         $set = true;\r
1531                         break;\r
1532                 }\r
1533         }\r
1534 \r
1535         if (!$set) {\r
1536                 $vars[] = $param . '=' . $value;\r
1537         }\r
1538 \r
1539         return ltrim(implode('&', $vars), '&');\r
1540 }\r
1541 \r
1542 // passes one variable as hidden input field (multiple fields for arrays)\r
1543 // @see passRequestVars in varsx.x.x.php\r
1544 function passVar($key, $value) {\r
1545         // array ?\r
1546         if (is_array($value) ) {\r
1547                 for ($i = 0; $i < sizeof($value); $i++) {\r
1548                         passVar($key . '[' . $i . ']', $value[$i]);\r
1549                 }\r
1550 \r
1551                 return;\r
1552         }\r
1553 \r
1554         // other values: do stripslashes if needed\r
1555         ?><input type="hidden" name="<?php echo htmlspecialchars($key)?>" value="<?php echo htmlspecialchars(undoMagic($value) )?>" /><?php\r
1556 }\r
1557 \r
1558 /*\r
1559         Date format functions (to be used from [%date(..)%] skinvars\r
1560 */\r
1561 function formatDate($format, $timestamp, $defaultFormat, &$blog) {\r
1562         // apply blog offset (#42)\r
1563         $boffset = $blog ? $blog->getTimeOffset() * 3600 : 0;\r
1564         $offset = date('Z', $timestamp) + $boffset;\r
1565 \r
1566         switch ($format) {\r
1567                 case 'rfc822':\r
1568                         if ($offset >= 0) {\r
1569                                 $tz = '+';\r
1570                         } else {\r
1571                                 $tz = '-';\r
1572                                 $offset = -$offset;\r
1573                         }\r
1574 \r
1575                         $tz .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );\r
1576                         return date('D, j M Y H:i:s ', $timestamp) . $tz;\r
1577 \r
1578                 case 'rfc822GMT':\r
1579                         $timestamp -= $offset;\r
1580                         return date('D, j M Y H:i:s ', $timestamp) . 'GMT';\r
1581 \r
1582                 case 'utc':\r
1583                         $timestamp -= $offset;\r
1584                         return date('Y-m-d\TH:i:s\Z', $timestamp);\r
1585 \r
1586                 case 'iso8601':\r
1587                         if ($offset >= 0) {\r
1588                                 $tz = '+';\r
1589                         } else {\r
1590                                 $tz = '-';\r
1591                                 $offset = -$offset;\r
1592                         }\r
1593 \r
1594                         $tz .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );\r
1595                         return date('Y-m-d\TH:i:s', $timestamp) . $tz;\r
1596 \r
1597                 default :\r
1598                         return strftime($format ? $format : $defaultFormat, $timestamp);\r
1599         }\r
1600 }\r
1601 \r
1602 function encoding_check($val, $key, $encoding=false, $exclude=false) {\r
1603         /*\r
1604           When 3rd argument is set, return if checked already.\r
1605           When 4th argument is set, set the excluded key(s).\r
1606         */\r
1607         static $search=false, $checked=array(), $excludes=array();\r
1608         if ($exclude!==false) {\r
1609                 if (is_array($exclude)) {\r
1610                         foreach($exclude as $v) $excludes[$v]=true;\r
1611                 } else $excludes[$exclude]=true;\r
1612                 return;\r
1613         }\r
1614         if ($encoding!==false) {\r
1615                 switch($encoding=strtolower($encoding)){\r
1616                         case 'utf-8':\r
1617                                 $search='/([\x00-\x7F]+'.\r
1618                                         '|[\xC2-\xDF][\x80-\xBF]'.\r
1619                                         '|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]'.\r
1620                                         '|[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.\r
1621                                         '|[\xF8-\xFB][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.\r
1622                                         '|[\xFC-\xFD][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF])/';\r
1623                                         break;\r
1624                         case 'euc-jp':\r
1625                                 $search='/([\x00-\x7F]+'.\r
1626                                         '|[\x8E][\xA0-\xDF]'.\r
1627                                         '|[\x8F]?[\xA1-\xFE][\xA1-\xFE])/';\r
1628                                 break;\r
1629                         case 'gb2312':\r
1630                                 $search='/([\x00-\x7F]+'.\r
1631                                         '|[\xA1-\xF7][\xA1-\xFE])/';\r
1632                                 break;\r
1633                         case 'shift_jis':\r
1634                                 // Note that shift_jis is only supported for output.\r
1635                                 // Using shift_jis in DB is prohibited.\r
1636                                 $search='/([\x00-\x7F\xA1-\xDF]+'.\r
1637                                         '|[\x81-\x9F\xE0-\xFC][\x40-\xFC])/';\r
1638                                 break;\r
1639                         default:\r
1640                                 $search=false;\r
1641                                 if (preg_match('/^iso\-8859\-[0-9]{1,2}$/',$encoding)) break;\r
1642                                 if (preg_match('/^windows\-125[0-8]$/',$encoding)) break;\r
1643                                 startUpError('<p>Unknown or non-supported encoding.</p>', 'Encoding Error');\r
1644                                 exit;\r
1645                 }\r
1646                 if (isset($checked[$encoding])) return true; // Already checked.\r
1647                 $checked[$encoding]=true;\r
1648         }\r
1649         if ($key===false) return false; // Not yet checked.\r
1650         if ($search===false) return true; // non-multibyte encoding\r
1651         if (isset($excludes[$key])) return true; // This key isn't checked.\r
1652         if (is_array($val)) {\r
1653                 array_walk($val, 'encoding_check');\r
1654         } else {\r
1655                 $result=preg_replace($search,'',$val);\r
1656                 if (strlen($result)!=0) {\r
1657                         startUpError('<p>Invalid input.</p>', 'Input Error');\r
1658                         exit;\r
1659                 }\r
1660         }\r
1661         $result=preg_replace($search,'',$key);\r
1662         if (strlen($result)!=0) {\r
1663                 startUpError('<p>Invalid input.</p>', 'Input Error');\r
1664                 exit;\r
1665         }\r
1666         return true;\r
1667 }\r
1668 \r
1669 function checkVars($aVars) {\r
1670         global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;\r
1671 \r
1672         foreach ($aVars as $varName) {\r
1673 \r
1674                 if (phpversion() >= '4.1.0') {\r
1675 \r
1676                         if (   isset($_GET[$varName])\r
1677                                 || isset($_POST[$varName])\r
1678                                 || isset($_COOKIE[$varName])\r
1679                                 || isset($_ENV[$varName])\r
1680                                 || isset($_SESSION[$varName])\r
1681                                 || isset($_FILES[$varName])\r
1682                         ) {\r
1683                                 die('Sorry. An error occurred.');\r
1684                         }\r
1685 \r
1686                 } else {\r
1687 \r
1688                         if (   isset($HTTP_GET_VARS[$varName])\r
1689                                 || isset($HTTP_POST_VARS[$varName])\r
1690                                 || isset($HTTP_COOKIE_VARS[$varName])\r
1691                                 || isset($HTTP_ENV_VARS[$varName])\r
1692                                 || isset($HTTP_SESSION_VARS[$varName])\r
1693                                 || isset($HTTP_POST_FILES[$varName])\r
1694                         ) {\r
1695                                 die('Sorry. An error occurred.');\r
1696                         }\r
1697 \r
1698                 }\r
1699         }\r
1700 }\r
1701 \r
1702 \r
1703 /**\r
1704  * Sanitize parameters such as $_GET and $_SERVER['REQUEST_URI'] etc.\r
1705  * to avoid XSS\r
1706  */\r
1707 function sanitizeParams()\r
1708 {\r
1709         global $HTTP_SERVER_VARS;\r
1710 \r
1711         $array = array();\r
1712         $str = '';\r
1713         $frontParam = '';\r
1714 \r
1715         // REQUEST_URI of $HTTP_SERVER_VARS\r
1716         $str =& $HTTP_SERVER_VARS["REQUEST_URI"];\r
1717         serverStringToArray($str, $array, $frontParam);\r
1718         sanitizeArray($array);\r
1719         arrayToServerString($array, $frontParam, $str);\r
1720 \r
1721         // QUERY_STRING of $HTTP_SERVER_VARS\r
1722         $str =& $HTTP_SERVER_VARS["QUERY_STRING"];\r
1723         serverStringToArray($str, $array, $frontParam);\r
1724         sanitizeArray($array);\r
1725         arrayToServerString($array, $frontParam, $str);\r
1726 \r
1727         if (phpversion() >= '4.1.0') {\r
1728                 // REQUEST_URI of $_SERVER\r
1729                 $str =& $_SERVER["REQUEST_URI"];\r
1730                 serverStringToArray($str, $array, $frontParam);\r
1731                 sanitizeArray($array);\r
1732                 arrayToServerString($array, $frontParam, $str);\r
1733 \r
1734                 // QUERY_STRING of $_SERVER\r
1735                 $str =& $_SERVER["QUERY_STRING"];\r
1736                 serverStringToArray($str, $array, $frontParam);\r
1737                 sanitizeArray($array);\r
1738                 arrayToServerString($array, $frontParam, $str);\r
1739         }\r
1740 \r
1741         // $_GET\r
1742         convArrayForSanitizing($_GET, $array);\r
1743         sanitizeArray($array);\r
1744         revertArrayForSanitizing($array, $_GET);\r
1745 \r
1746         // $_REQUEST (only GET param)\r
1747         convArrayForSanitizing($_REQUEST, $array);\r
1748         sanitizeArray($array);\r
1749         revertArrayForSanitizing($array, $_REQUEST);\r
1750 }\r
1751 \r
1752 /**\r
1753  * Check ticket when not checked in plugin's admin page\r
1754  * to avoid CSRF.\r
1755  * Also avoid the access to plugin/index.php by guest user.\r
1756  */\r
1757 function ticketForPlugin(){\r
1758         global $CONF,$DIR_PLUGINS,$member,$ticketforplugin;\r
1759 \r
1760         /* initialize */\r
1761         $ticketforplugin=array();\r
1762         $ticketforplugin['ticket']=false;\r
1763 \r
1764         /* Check if using plugin's php file. */\r
1765         if ($p_translated=serverVar('PATH_TRANSLATED')) {\r
1766                 if (!file_exists($p_translated)) $p_translated='';\r
1767         }\r
1768         if (!$p_translated) {\r
1769                 $p_translated=serverVar('SCRIPT_FILENAME');\r
1770                 if (!file_exists($p_translated)) {\r
1771                         header("HTTP/1.0 404 Not Found");\r
1772                         exit('');\r
1773                 }\r
1774         }\r
1775         $p_translated=str_replace('\\','/',$p_translated);\r
1776         $d_plugins=str_replace('\\','/',$DIR_PLUGINS);\r
1777         if (strpos($p_translated,$d_plugins)!==0) return;// This isn't plugin php file.\r
1778 \r
1779         /* Solve the plugin php file or admin directory */\r
1780         $phppath=substr($p_translated,strlen($d_plugins));\r
1781         $phppath=preg_replace('!^/!','',$phppath);// Remove the first "/" if exists.\r
1782         $path=preg_replace('/^NP_(.*)\.php$/','$1',$phppath); // Remove the first "NP_" and the last ".php" if exists.\r
1783         $path=preg_replace('!^([^/]*)/(.*)$!','$1',$path); // Remove the "/" and beyond.\r
1784 \r
1785         /* Solve the plugin name. */\r
1786         $plugins=array();\r
1787         $query='SELECT pfile FROM '.sql_table('plugin');\r
1788         $res=sql_query($query);\r
1789         while($row=mysql_fetch_row($res)) {\r
1790                 $name=substr($row[0],3);\r
1791                 $plugins[strtolower($name)]=$name;\r
1792         }\r
1793         mysql_free_result($res);\r
1794         if ($plugins[$path]) $plugin_name=$plugins[$path];\r
1795         else if (in_array($path,$plugins)) $plugin_name=$path;\r
1796         else {\r
1797                 header("HTTP/1.0 404 Not Found");\r
1798                 exit('');\r
1799         }\r
1800 \r
1801         /* Return if not index.php */\r
1802         if ( $phppath!=strtolower($plugin_name).'/'\r
1803                 && $phppath!=strtolower($plugin_name).'/index.php' ) return;\r
1804 \r
1805         /* Exit if not logged in. */\r
1806         if ( !$member->isLoggedIn() ) exit("You aren't logged in.");\r
1807 \r
1808         global $manager,$DIR_LIBS,$DIR_LANG,$HTTP_GET_VARS,$HTTP_POST_VARS;\r
1809 \r
1810         /* Check if this feature is needed (ie, if "$manager->checkTicket()" is not included in the script). */\r
1811         if (!($p_translated=serverVar('PATH_TRANSLATED'))) $p_translated=serverVar('SCRIPT_FILENAME');\r
1812         if ($file=@file($p_translated)) {\r
1813                 $prevline='';\r
1814                 foreach($file as $line) {\r
1815                         if (preg_match('/[\$]manager([\s]*)[\-]>([\s]*)checkTicket([\s]*)[\(]/i',$prevline.$line)) return;\r
1816                         $prevline=$line;\r
1817                 }\r
1818         }\r
1819 \r
1820         /* Show a form if not valid ticket */\r
1821         if ( ( strstr(serverVar('REQUEST_URI'),'?') || serverVar('QUERY_STRING')\r
1822                         || strtoupper(serverVar('REQUEST_METHOD'))=='POST' )\r
1823                                 && (!$manager->checkTicket()) ){\r
1824 \r
1825                 if (!class_exists('PluginAdmin')) {\r
1826                         $language = getLanguageName();\r
1827                         include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');\r
1828                         include($DIR_LIBS . 'PLUGINADMIN.php');\r
1829                 }\r
1830                 if (!(function_exists('mb_strimwidth') || extension_loaded('mbstring'))) {\r
1831                         if (file_exists($DIR_LIBS.'mb_emulator/mb-emulator.php')) {\r
1832                                 global $mbemu_internals;\r
1833                                 include_once($DIR_LIBS.'mb_emulator/mb-emulator.php');\r
1834                         }\r
1835                 }\r
1836                 $oPluginAdmin = new PluginAdmin($plugin_name);\r
1837                 $oPluginAdmin->start();\r
1838                 echo '<p>' . _ERROR_BADTICKET . "</p>\n";\r
1839 \r
1840                 /* Show the form to confirm action */\r
1841                 // PHP 4.0.x support\r
1842                 $get=  (isset($_GET))  ? $_GET  : $HTTP_GET_VARS;\r
1843                 $post= (isset($_POST)) ? $_POST : $HTTP_POST_VARS;\r
1844                 // Resolve URI and QUERY_STRING\r
1845                 if ($uri=serverVar('REQUEST_URI')) {\r
1846                         list($uri,$qstring)=explode('?',$uri);\r
1847                 } else {\r
1848                         if ( !($uri=serverVar('PHP_SELF')) ) $uri=serverVar('SCRIPT_NAME');\r
1849                         $qstring=serverVar('QUERY_STRING');\r
1850                 }\r
1851                 if ($qstring) $qstring='?'.$qstring;\r
1852                 echo '<p>'._SETTINGS_UPDATE.' : '._QMENU_PLUGINS.' <span style="color:red;">'.\r
1853                         htmlspecialchars($plugin_name)."</span> ?</p>\n";\r
1854                 switch(strtoupper(serverVar('REQUEST_METHOD'))){\r
1855                 case 'POST':\r
1856                         echo '<form method="POST" action="'.htmlspecialchars($uri.$qstring).'">';\r
1857                         $manager->addTicketHidden();\r
1858                         _addInputTags($post);\r
1859                         break;\r
1860                 case 'GET':\r
1861                         echo '<form method="GET" action="'.htmlspecialchars($uri).'">';\r
1862                         $manager->addTicketHidden();\r
1863                         _addInputTags($get);\r
1864                 default:\r
1865                         break;\r
1866                 }\r
1867                 echo '<input type="submit" value="'._YES.'" />&nbsp;&nbsp;&nbsp;&nbsp;';\r
1868                 echo '<input type="button" value="'._NO.'" onclick="history.back(); return false;" />';\r
1869                 echo "</form>\n";\r
1870 \r
1871                 $oPluginAdmin->end();\r
1872                 exit;\r
1873         }\r
1874 \r
1875         /* Create new ticket */\r
1876         $ticket=$manager->addTicketToUrl('');\r
1877         $ticketforplugin['ticket']=substr($ticket,strpos($ticket,'ticket=')+7);\r
1878 }\r
1879 function _addInputTags(&$keys,$prefix=''){\r
1880         foreach($keys as $key=>$value){\r
1881                 if ($prefix) $key=$prefix.'['.$key.']';\r
1882                 if (is_array($value)) _addInputTags($value,$key);\r
1883                 else {\r
1884                         if (get_magic_quotes_gpc()) $value=stripslashes($value);\r
1885                         if ($key=='ticket') continue;\r
1886                         echo '<input type="hidden" name="'.htmlspecialchars($key).\r
1887                                 '" value="'.htmlspecialchars($value).'" />'."\n";\r
1888                 }\r
1889         }\r
1890 }\r
1891 \r
1892 /**\r
1893  * Convert the server string such as $_SERVER['REQUEST_URI']\r
1894  * to arry like arry['blogid']=1 and array['page']=2 etc.\r
1895  */\r
1896 function serverStringToArray($str, &$array, &$frontParam)\r
1897 {\r
1898         // init param\r
1899         $array = array();\r
1900         $fronParam = "";\r
1901 \r
1902         // split front param, e.g. /index.php, and others, e.g. blogid=1&page=2\r
1903         if (strstr($str, "?")){\r
1904                 list($frontParam, $args) = preg_split("/\?/", $str, 2);\r
1905         }\r
1906         else {\r
1907                 $args = $str;\r
1908                 $frontParam = "";\r
1909         }\r
1910 \r
1911         // If there is no args like blogid=1&page=2, return\r
1912         if (!strstr($str, "=") && !strlen($frontParam)) {\r
1913                 $frontParam = $str;\r
1914                 return;\r
1915         }\r
1916 \r
1917         $array = explode("&", $args);\r
1918 }\r
1919 \r
1920 /**\r
1921  * Convert array like array['blogid'] to server string\r
1922  * such as $_SERVER['REQUEST_URI']\r
1923  */\r
1924 function arrayToServerString($array, $frontParam, &$str)\r
1925 {\r
1926         if (strstr($str, "?")) {\r
1927                 $str = $frontParam . "?";\r
1928         } else {\r
1929                 $str = $frontParam;\r
1930         }\r
1931         if (count($array)) {\r
1932                 $str .= implode("&", $array);\r
1933         }\r
1934 }\r
1935 \r
1936 /**\r
1937  * Sanitize array parameters.\r
1938  * This function checks both key and value.\r
1939  * - check key if it inclues " (double quote),  remove from array\r
1940  * - check value if it includes \ (escape sequece), remove remaining string\r
1941  */\r
1942 function sanitizeArray(&$array)\r
1943 {\r
1944         $excludeListForSanitization = array('query');\r
1945 //      $excludeListForSanitization = array();\r
1946 \r
1947         foreach ($array as $k => $v) {\r
1948 \r
1949                 // split to key and value\r
1950                 list($key, $val) = preg_split("/=/", $v, 2);\r
1951                 if (!isset($val)) {\r
1952                         continue;\r
1953                 }\r
1954 \r
1955                 // when magic quotes is on, need to use stripslashes,\r
1956                 // and then addslashes\r
1957                 if (get_magic_quotes_gpc()) {\r
1958                         $val = stripslashes($val);\r
1959                 }\r
1960                 $val = addslashes($val);\r
1961 \r
1962                 // if $key is included in exclude list, skip this param\r
1963                 if (!in_array($key, $excludeListForSanitization)) {\r
1964 \r
1965                         // check value\r
1966                         if (strpos($val, '\\')) {\r
1967                                 list($val, $tmp) = explode('\\', $val);\r
1968                         }\r
1969 \r
1970                         // remove control code etc.\r
1971                         $val = strtr($val, "\0\r\n<>'\"", "       ");\r
1972 \r
1973                         // check key\r
1974                         if (preg_match('/\"/i', $key)) {\r
1975                                 unset($array[$k]);\r
1976                                 continue;\r
1977                         }\r
1978 \r
1979                         // set sanitized info\r
1980                         $array[$k] = sprintf("%s=%s", $key, $val);\r
1981                 }\r
1982         }\r
1983 }\r
1984 \r
1985 /**\r
1986  * Convert array for sanitizeArray function\r
1987  */\r
1988 function convArrayForSanitizing($src, &$array)\r
1989 {\r
1990         $array = array();\r
1991         foreach ($src as $key => $val) {\r
1992                 if (key_exists($key, $_GET)) {\r
1993                         array_push($array, sprintf("%s=%s", $key, $val));\r
1994                 }\r
1995         }\r
1996 }\r
1997 \r
1998 /**\r
1999  * Revert array after sanitizeArray function\r
2000  */\r
2001 function revertArrayForSanitizing($array, &$dst)\r
2002 {\r
2003         foreach ($array as $v) {\r
2004                 list($key, $val) = preg_split("/=/", $v, 2);\r
2005                 $dst[$key] = $val;\r
2006         }\r
2007 }\r
2008 \r
2009 /**\r
2010  * Stops processing the request and redirects to the given URL.\r
2011  * - no actual contents should have been sent to the output yet\r
2012  * - the URL will be stripped of illegal or dangerous characters\r
2013  */\r
2014 function redirect($url) {\r
2015         $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%*]|i', '', $url);\r
2016         header('Location: ' . $url);\r
2017         exit;\r
2018 }\r
2019 \r
2020 /**\r
2021  * Strip HTML tags from a string\r
2022  * This function is a bit more intelligent than a regular call to strip_tags(),\r
2023  * because it also deletes the contents of certain tags and cleans up any\r
2024  * unneeded whitespace.\r
2025  */\r
2026 function stringStripTags ($string) {\r
2027         $string = preg_replace("/<del[^>]*>.+<\/del[^>]*>/isU", '', $string);\r
2028         $string = preg_replace("/<script[^>]*>.+<\/script[^>]*>/isU", '', $string);\r
2029         $string = preg_replace("/<style[^>]*>.+<\/style[^>]*>/isU", '', $string);\r
2030         $string = str_replace('>', '> ', $string);\r
2031         $string = str_replace('<', ' <', $string);\r
2032         $string = strip_tags($string);\r
2033         $string = preg_replace("/\s+/", " ", $string);\r
2034         $string = trim($string);\r
2035         return $string;\r
2036 }\r
2037 \r
2038 /**\r
2039  * Make a string containing HTML safe for use in a HTML attribute\r
2040  * Tags are stripped and entities are normalized\r
2041  */\r
2042 function stringToAttribute ($string) {\r
2043         $string = stringStripTags($string);\r
2044         $string = entity::named_to_numeric($string);\r
2045         $string = entity::normalize_numeric($string);\r
2046 \r
2047         if (_CHARSET == 'UTF-8') {\r
2048                 $string = entity::numeric_to_utf8($string);\r
2049         }\r
2050 \r
2051         $string = entity::specialchars($string, 'html');\r
2052         $string = entity::numeric_to_named($string);\r
2053         return $string;\r
2054 }\r
2055 \r
2056 /**\r
2057  * Make a string containing HTML safe for use in a XML document\r
2058  * Tags are stripped, entities are normalized and named entities are\r
2059  * converted to numeric entities.\r
2060  */\r
2061 function stringToXML ($string) {\r
2062         $string = stringStripTags($string);\r
2063         $string = entity::named_to_numeric($string);\r
2064         $string = entity::normalize_numeric($string);\r
2065 \r
2066         if (_CHARSET == 'UTF-8') {\r
2067                 $string = entity::numeric_to_utf8($string);\r
2068         }\r
2069 \r
2070         $string = entity::specialchars($string, 'xml');\r
2071         return $string;\r
2072 }\r
2073 \r
2074 // START: functions from the end of file BLOG.php\r
2075 // used for mail notification (html -> text)\r
2076 function toAscii($html) {\r
2077         // strip off most tags\r
2078         $html = strip_tags($html,'<a>');\r
2079         $to_replace = "/<a[^>]*href=[\"\']([^\"^']*)[\"\'][^>]*>([^<]*)<\/a>/i";\r
2080         _links_init();\r
2081         $ascii = preg_replace_callback ($to_replace, '_links_add', $html);\r
2082         $ascii .= "\n\n" . _links_list();\r
2083         return strip_tags($ascii);\r
2084 }\r
2085 \r
2086 function _links_init() {\r
2087    global $tmp_links;\r
2088    $tmp_links = array();\r
2089 }\r
2090 \r
2091 function _links_add($match) {\r
2092    global $tmp_links;\r
2093    array_push($tmp_links, $match[1]);\r
2094    return $match[2] . ' [' . sizeof($tmp_links) .']';\r
2095 }\r
2096 \r
2097 function _links_list() {\r
2098    global $tmp_links;\r
2099    $output = '';\r
2100    $i = 1;\r
2101    foreach ($tmp_links as $current) {\r
2102           $output .= "[$i] $current\n";\r
2103           $i++;\r
2104    }\r
2105    return $output;\r
2106 }\r
2107 // END: functions from the end of file BLOG.php\r
2108 \r
2109 // START: functions from the end of file ADMIN.php\r
2110 /**\r
2111  * @todo document this\r
2112  */\r
2113 function encode_desc(&$data)\r
2114 {\r
2115 //      _$to_entities = get_html_translation_table(HTML_ENTITIES);\r
2116         $to_entities = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese\r
2117         $from_entities = array_flip($to_entities);\r
2118         $data = str_replace('<br />', '\n', $data); //hack\r
2119         $data = strtr($data,$from_entities);\r
2120         $data = strtr($data,$to_entities);\r
2121         $data = str_replace('\n', '<br />', $data); //hack\r
2122         return $data;\r
2123 }\r
2124 \r
2125 /**\r
2126  * Returns the Javascript code for a bookmarklet that works on most modern browsers\r
2127  *\r
2128  * @param blogid\r
2129  */\r
2130 function getBookmarklet($blogid) {\r
2131         global $CONF;\r
2132 \r
2133         // normal\r
2134         $document = 'document';\r
2135         $bookmarkletline = "javascript:Q='';x=".$document.";y=window;if(x.selection){Q=x.selection.createRange().text;}else if(y.getSelection){Q=y.getSelection();}else if(x.getSelection){Q=x.getSelection();}wingm=window.open('";\r
2136         $bookmarkletline .= $CONF['AdminURL'] . "bookmarklet.php?blogid=$blogid";\r
2137         $bookmarkletline .="&logtext='+escape(Q)+'&loglink='+escape(x.location.href)+'&loglinktitle='+escape(x.title),'nucleusbm','toolbar=no,scrollbars=no,width=600,height=550,left=10,top=10,status=no,resizable=yes');wingm.focus();";\r
2138 \r
2139         return $bookmarkletline;\r
2140 }\r
2141 // END: functions from the end of file ADMIN.php\r
2142 \r
2143 /**\r
2144  * Returns a variable or null if not set\r
2145  *\r
2146  * @param mixed Variable\r
2147  * @return mixed Variable\r
2148  */\r
2149 function ifset(&$var) {\r
2150         if (isset($var)) {\r
2151                 return $var;\r
2152         }\r
2153 \r
2154         return null;\r
2155 }\r
2156 \r
2157 /**\r
2158  * Returns number of subscriber to an event\r
2159  *\r
2160  * @param event\r
2161  * @return number of subscriber(s)\r
2162  */\r
2163 function numberOfEventSubscriber($event) {\r
2164         $query = 'SELECT COUNT(*) as count FROM ' . sql_table('plugin_event') . ' WHERE event=\'' . $event . '\'';\r
2165         $res = sql_query($query);\r
2166         $obj = mysql_fetch_object($res);\r
2167         return $obj->count;\r
2168 }\r
2169 \r
2170 function selectSpecialSkinType($id) {\r
2171         global $special;\r
2172         $special = strtolower($id);\r
2173 }\r
2174 \r
2175 ?>