OSDN Git Service

68f5a0dc4ed738695556625c78868316ae8570aa
[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.50SVN';\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 // added for 3.5 sql_* wrapper\r
118 global $MYSQL_HANDLER;\r
119 if (!isset($MYSQL_HANDLER))\r
120         $MYSQL_HANDLER = array('mysql','');\r
121 if ($MYSQL_HANDLER[0] == '')\r
122         $MYSQL_HANDLER[0] = 'mysql';\r
123 include_once($DIR_LIBS . 'sql/'.$MYSQL_HANDLER[0].'.php');\r
124 // end new for 3.5 sql_* wrapper\r
125 include_once($DIR_LIBS . 'mysql.php');\r
126 include($DIR_LIBS . 'MEMBER.php');\r
127 include($DIR_LIBS . 'ACTIONLOG.php');\r
128 include($DIR_LIBS . 'MANAGER.php');\r
129 include($DIR_LIBS . 'PLUGIN.php');\r
130 \r
131 $manager =& MANAGER::instance();\r
132 \r
133 // make sure there's no unnecessary escaping:\r
134 set_magic_quotes_runtime(0);\r
135 \r
136 // Avoid notices\r
137 if (!isset($CONF['UsingAdminArea'])) {\r
138         $CONF['UsingAdminArea'] = 0;\r
139 }\r
140 \r
141 // only needed when updating logs\r
142 if ($CONF['UsingAdminArea']) {\r
143         include($DIR_LIBS . 'xmlrpc.inc.php');  // XML-RPC client classes\r
144         include_once($DIR_LIBS . 'ADMIN.php');\r
145 }\r
146 \r
147 // connect to database\r
148 sql_connect();\r
149 $SQLCount = 0;\r
150 \r
151 // logs sanitized result if need\r
152 if ($orgRequestURI!==serverVar('REQUEST_URI')) {\r
153         $msg = "Sanitized [" . serverVar('REMOTE_ADDR') . "] ";\r
154         $msg .= $orgRequestURI . " -> " . serverVar('REQUEST_URI');\r
155     if ($bLoggingSanitizedResult) {\r
156         addToLog(WARNING, $msg);\r
157     }\r
158     if (!$bSanitizeAndContinue) {\r
159         die("");\r
160     }\r
161 }\r
162 \r
163 // makes sure database connection gets closed on script termination\r
164 register_shutdown_function('sql_disconnect');\r
165 \r
166 // read config\r
167 getConfig();\r
168 \r
169 // Properly set $CONF['Self'] and others if it's not set... usually when we are access from admin menu\r
170 if (!isset($CONF['Self'])) {\r
171         $CONF['Self'] = $CONF['IndexURL'];\r
172         // strip trailing /\r
173         if ($CONF['Self'][strlen($CONF['Self']) -1] == "/") {\r
174                 $CONF['Self'] = substr($CONF['Self'], 0, strlen($CONF['Self']) -1);\r
175         }\r
176 \r
177 /*      $CONF['ItemURL']        = $CONF['Self'];\r
178         $CONF['ArchiveURL']     = $CONF['Self'];\r
179         $CONF['ArchiveListURL'] = $CONF['Self'];\r
180         $CONF['MemberURL']      = $CONF['Self'];\r
181         $CONF['SearchURL']      = $CONF['Self'];\r
182         $CONF['BlogURL']        = $CONF['Self'];\r
183         $CONF['CategoryURL']    = $CONF['Self'];*/\r
184 }\r
185 \r
186 $CONF['ItemURL'] = $CONF['Self'];\r
187 $CONF['ArchiveURL'] = $CONF['Self'];\r
188 $CONF['ArchiveListURL'] = $CONF['Self'];\r
189 $CONF['MemberURL'] = $CONF['Self'];\r
190 $CONF['SearchURL'] = $CONF['Self'];\r
191 $CONF['BlogURL'] = $CONF['Self'];\r
192 $CONF['CategoryURL'] = $CONF['Self'];\r
193 \r
194 // switch URLMode back to normal when $CONF['Self'] ends in .php\r
195 // this avoids urls like index.php/item/13/index.php/item/15\r
196 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {\r
197         $CONF['URLMode'] = 'normal';\r
198 }\r
199 \r
200 // automatically use simpler toolbar for mozilla\r
201 if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'), 'Gecko') ) {\r
202         $CONF['DisableJsTools'] = 2;\r
203 }\r
204 \r
205 // login if cookies set\r
206 $member = new MEMBER();\r
207 \r
208 // secure cookie key settings (either 'none', 0, 8, 16, 24, or 32)\r
209 if (!isset($CONF['secureCookieKey'])) $CONF['secureCookieKey']=24;\r
210 switch($CONF['secureCookieKey']){\r
211 case 8:\r
212         $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));\r
213         break;\r
214 case 16:\r
215         $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));\r
216         break;\r
217 case 24:\r
218         $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+$/','',serverVar('REMOTE_ADDR'));\r
219         break;\r
220 case 32:\r
221         $CONF['secureCookieKeyIP']=serverVar('REMOTE_ADDR');\r
222         break;\r
223 default:\r
224         $CONF['secureCookieKeyIP']='';\r
225 }\r
226 \r
227 // login/logout when required or renew cookies\r
228 if ($action == 'login') {\r
229         // Form Authentication\r
230         $login = postVar('login');\r
231         $pw = postVar('password');\r
232         $shared = intPostVar('shared'); // shared computer or not\r
233 \r
234         $pw=substr($pw,0,40); // avoid md5 collision by using a long key\r
235 \r
236         if ($member->login($login, $pw) ) {\r
237 \r
238                 $member->newCookieKey();\r
239                 $member->setCookies($shared);\r
240 \r
241                 if ($CONF['secureCookieKey']!=='none') {\r
242                         // secure cookie key\r
243                         $member->setCookieKey(md5($member->getCookieKey().$CONF['secureCookieKeyIP']));\r
244                         $member->write();\r
245                 }\r
246 \r
247                 // allows direct access to parts of the admin area after logging in\r
248                 if ($nextaction) {\r
249                         $action = $nextaction;\r
250                 }\r
251 \r
252                 $manager->notify('LoginSuccess', array('member' => &$member, 'username' => $login) );\r
253                 $errormessage = '';\r
254                 ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");\r
255         } else {\r
256                 // errormessage for [%errordiv%]\r
257                 $errormessage = 'Login failed for ' . $login;\r
258 \r
259                 $manager->notify('LoginFailed', array('username' => $login) );\r
260                 ACTIONLOG::add(INFO, $errormessage);\r
261         }\r
262 /*\r
263 \r
264 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details\r
265 \r
266 } elseif (serverVar('PHP_AUTH_USER') && serverVar('PHP_AUTH_PW')) {\r
267         // HTTP Authentication\r
268         $login  = serverVar('PHP_AUTH_USER');\r
269         $pw     = serverVar('PHP_AUTH_PW');\r
270 \r
271         if ($member->login($login, $pw) ) {\r
272                 $manager->notify('LoginSuccess',array('member' => &$member));\r
273                 ACTIONLOG::add(INFO, "HTTP authentication successful for $login");\r
274         } else {\r
275                 $manager->notify('LoginFailed',array('username' => $login));\r
276                 ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);\r
277 \r
278                 //Since bad credentials, generate an apropriate error page\r
279                 header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");\r
280                 header('HTTP/1.0 401 Unauthorized');\r
281                 echo 'Invalid username or password';\r
282                 exit;\r
283         }\r
284 */\r
285 \r
286 } elseif (($action == 'logout') && (!headers_sent() ) && cookieVar($CONF['CookiePrefix'] . 'user') ) {\r
287         // remove cookies on logout\r
288         setcookie($CONF['CookiePrefix'] . 'user', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);\r
289         setcookie($CONF['CookiePrefix'] . 'loginkey', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);\r
290         $manager->notify('Logout', array('username' => cookieVar($CONF['CookiePrefix'] . 'user') ) );\r
291 } elseif (cookieVar($CONF['CookiePrefix'] . 'user') ) {\r
292         // Cookie Authentication\r
293         $ck=cookieVar($CONF['CookiePrefix'] . 'loginkey');\r
294         // secure cookie key\r
295         $ck=substr($ck,0,32); // avoid md5 collision by using a long key\r
296         if ($CONF['secureCookieKey']!=='none') $ck=md5($ck.$CONF['secureCookieKeyIP']);\r
297         $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), $ck );\r
298         unset($ck);\r
299 \r
300         // renew cookies when not on a shared computer\r
301         if ($res && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) && (!headers_sent() ) ) {\r
302                 $member->setCookieKey(cookieVar($CONF['CookiePrefix'] . 'loginkey'));\r
303                 $member->setCookies();\r
304         }\r
305 }\r
306 \r
307 // login completed\r
308 $manager->notify('PostAuthentication', array('loggedIn' => $member->isLoggedIn() ) );\r
309 ticketForPlugin();\r
310 \r
311 // first, let's see if the site is disabled or not. always allow admin area access.\r
312 if ($CONF['DisableSite'] && !$member->isAdmin() && !$CONF['UsingAdminArea']) {\r
313         redirect($CONF['DisableSiteURL']);\r
314         exit;\r
315 }\r
316 \r
317 // load other classes\r
318 include($DIR_LIBS . 'PARSER.php');\r
319 include($DIR_LIBS . 'SKIN.php');\r
320 include($DIR_LIBS . 'TEMPLATE.php');\r
321 include($DIR_LIBS . 'BLOG.php');\r
322 include($DIR_LIBS . 'BODYACTIONS.php');\r
323 include($DIR_LIBS . 'COMMENTS.php');\r
324 include($DIR_LIBS . 'COMMENT.php');\r
325 //include($DIR_LIBS . 'ITEM.php');\r
326 include($DIR_LIBS . 'NOTIFICATION.php');\r
327 include($DIR_LIBS . 'BAN.php');\r
328 include($DIR_LIBS . 'PAGEFACTORY.php');\r
329 include($DIR_LIBS . 'SEARCH.php');\r
330 include($DIR_LIBS . 'entity.php');\r
331 \r
332 \r
333 // set lastVisit cookie (if allowed)\r
334 if (!headers_sent() ) {\r
335         if ($CONF['LastVisit']) {\r
336                 setcookie($CONF['CookiePrefix'] . 'lastVisit', time(), time() + 2592000, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);\r
337         } else {\r
338                 setcookie($CONF['CookiePrefix'] . 'lastVisit', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);\r
339         }\r
340 }\r
341 \r
342 // read language file, only after user has been initialized\r
343 $language = getLanguageName();\r
344 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');\r
345 \r
346 // check if valid charset\r
347 if (!encoding_check(false, false, _CHARSET)) {\r
348         foreach(array($_GET, $_POST) as $input) {\r
349                 array_walk($input, 'encoding_check');\r
350         }\r
351 }\r
352 \r
353 /*\r
354         Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details\r
355 \r
356 // To remove after v2.5 is released and language files have been updated.\r
357 // Including this makes sure that language files for v2.5beta can still be used for v2.5final\r
358 // without having weird _SETTINGS_EXTAUTH string showing up in the admin area.\r
359 if (!defined('_MEMBERS_BYPASS'))\r
360 {\r
361         define('_SETTINGS_EXTAUTH',                     'Enable External Authentication');\r
362         define('_WARNING_EXTAUTH',                      'Warning: Enable only if needed.');\r
363         define('_MEMBERS_BYPASS',                       'Use External Authentication');\r
364 }\r
365 \r
366 */\r
367 \r
368 // make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined\r
369 if (!defined('_ARCHIVETYPE_MONTH') ) {\r
370         define('_ARCHIVETYPE_DAY', 'day');\r
371         define('_ARCHIVETYPE_MONTH', 'month');\r
372         define('_ARCHIVETYPE_YEAR', 'year');\r
373 }\r
374 \r
375 // decode path_info\r
376 if ($CONF['URLMode'] == 'pathinfo') {\r
377         // initialize keywords if this hasn't been done before\r
378         if (!isset($CONF['ItemKey']) || $CONF['ItemKey'] == '') {\r
379                 $CONF['ItemKey'] = 'item';\r
380         }\r
381 \r
382         if (!isset($CONF['ArchiveKey']) || $CONF['ArchiveKey'] == '') {\r
383                 $CONF['ArchiveKey'] = 'archive';\r
384         }\r
385 \r
386         if (!isset($CONF['ArchivesKey']) || $CONF['ArchivesKey'] == '') {\r
387                 $CONF['ArchivesKey'] = 'archives';\r
388         }\r
389 \r
390         if (!isset($CONF['MemberKey']) || $CONF['MemberKey'] == '') {\r
391                 $CONF['MemberKey'] = 'member';\r
392         }\r
393 \r
394         if (!isset($CONF['BlogKey']) || $CONF['BlogKey'] == '') {\r
395                 $CONF['BlogKey'] = 'blog';\r
396         }\r
397 \r
398         if (!isset($CONF['CategoryKey']) || $CONF['CategoryKey'] == '') {\r
399                 $CONF['CategoryKey'] = 'category';\r
400         }\r
401 \r
402         if (!isset($CONF['SpecialskinKey']) || $CONF['SpecialskinKey'] == '') {\r
403                 $CONF['SpecialskinKey'] = 'special';\r
404         }\r
405 \r
406         $parsed = false;\r
407         $manager->notify(\r
408                 'ParseURL',\r
409                 array(\r
410                         'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...\r
411                         'info' => $virtualpath,\r
412                         'complete' => &$parsed\r
413                 )\r
414         );\r
415 \r
416         if (!$parsed) {\r
417                 // default implementation\r
418                 $data = explode("/", $virtualpath );\r
419                 for ($i = 0; $i < sizeof($data); $i++) {\r
420                         switch ($data[$i]) {\r
421                                 case $CONF['ItemKey']: // item/1 (blogid)\r
422                                         $i++;\r
423 \r
424                                         if ($i < sizeof($data) ) {\r
425                                                 $itemid = intval($data[$i]);\r
426                                         }\r
427                                         break;\r
428 \r
429                                 case $CONF['ArchivesKey']: // archives/1 (blogid)\r
430                                         $i++;\r
431 \r
432                                         if ($i < sizeof($data) ) {\r
433                                                 $archivelist = intval($data[$i]);\r
434                                         }\r
435                                         break;\r
436 \r
437                                 case $CONF['ArchiveKey']: // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)\r
438                                         if ((($i + 1) < sizeof($data) ) && (!strstr($data[$i + 1], '-') ) ) {\r
439                                                 $blogid = intval($data[++$i]);\r
440                                         }\r
441 \r
442                                         $i++;\r
443 \r
444                                         if ($i < sizeof($data) ) {\r
445                                                 $archive = $data[$i];\r
446                                         }\r
447                                         break;\r
448 \r
449                                 case 'blogid': // blogid/1\r
450                                 case $CONF['BlogKey']: // blog/1\r
451                                         $i++;\r
452 \r
453                                         if ($i < sizeof($data) ) {\r
454                                                 $blogid = intval($data[$i]);\r
455                                         }\r
456                                         break;\r
457 \r
458                                 case $CONF['CategoryKey']: // category/1 (catid)\r
459                                 case 'catid':\r
460                                         $i++;\r
461 \r
462                                         if ($i < sizeof($data) ) {\r
463                                                 $catid = intval($data[$i]);\r
464                                         }\r
465                                         break;\r
466 \r
467                                 case $CONF['MemberKey']:\r
468                                         $i++;\r
469 \r
470                                         if ($i < sizeof($data) ) {\r
471                                                 $memberid = intval($data[$i]);\r
472                                         }\r
473                                         break;\r
474 \r
475                 case $CONF['SpecialskinKey']:\r
476                     $i++;\r
477 \r
478                                         if ($i < sizeof($data) ) {\r
479                         $_REQUEST['special'] = $data[$i];\r
480                     }\r
481                     break;\r
482 \r
483                                 default:\r
484                                         // skip...\r
485                         }\r
486                 }\r
487         }\r
488 }\r
489 \r
490 function intPostVar($name) {\r
491         return intval(postVar($name) );\r
492 }\r
493 \r
494 function intGetVar($name) {\r
495         return intval(getVar($name) );\r
496 }\r
497 \r
498 function intRequestVar($name) {\r
499         return intval(requestVar($name) );\r
500 }\r
501 \r
502 function intCookieVar($name) {\r
503         return intval(cookieVar($name) );\r
504 }\r
505 \r
506 /**\r
507   * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)\r
508   */\r
509 function getNucleusVersion() {\r
510         return 341;\r
511 }\r
512 \r
513 /**\r
514  * power users can install patches in between nucleus releases. These patches\r
515  * usually add new functionality in the plugin API and allow those to\r
516  * be tested without having to install CVS.\r
517  */\r
518 function getNucleusPatchLevel() {\r
519         return 0;\r
520 }\r
521 \r
522 /**\r
523  * returns the latest version available for download from nucleuscms.org \r
524  * or false if unable to attain data\r
525  * format will be major.minor/patachlevel\r
526  * e.g. 3.41 or 3.41/02\r
527  */\r
528 function getLatestVersion() {\r
529         if (!function_exists('curl_init')) return false;\r
530         $crl = curl_init();\r
531         $timeout = 5;\r
532         curl_setopt ($crl, CURLOPT_URL,'http://nucleuscms.org/version_check.php');\r
533         curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);\r
534         curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);\r
535         $ret = curl_exec($crl);\r
536         curl_close($crl);\r
537         return $ret;\r
538 \r
539 }\r
540 \r
541 /**\r
542   * Connects to mysql server\r
543   */\r
544 /* moved to $DIR_LIBS/sql/*.php handler files\r
545 function sql_connect() {\r
546         global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE, $MYSQL_CONN;\r
547 \r
548         $MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>', 'Connect Error');\r
549         mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: ' . mysql_error() . '</p>', 'Connect Error');\r
550 \r
551         return $MYSQL_CONN;\r
552 }*/\r
553 \r
554 /**\r
555  * returns a prefixed nucleus table name\r
556  */\r
557 function sql_table($name) {\r
558         global $MYSQL_PREFIX;\r
559 \r
560         if ($MYSQL_PREFIX) {\r
561                 return $MYSQL_PREFIX . 'nucleus_' . $name;\r
562         } else {\r
563                 return 'nucleus_' . $name;\r
564         }\r
565 }\r
566 \r
567 function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {\r
568         global $manager, $CONF;\r
569 \r
570         if (!headers_sent() ) {\r
571                 // if content type is application/xhtml+xml, only send it to browsers\r
572                 // that can handle it (IE6 cannot). Otherwise, send text/html\r
573 \r
574                 // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)\r
575                 //       application/xhtml+xml still causes too much problems with the javascript implementations\r
576 \r
577                 // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,\r
578                 //       application/xhtml+xml seems to be working, so we're going to use it if we can.\r
579                 //\r
580                 // Note: reverted the following function in JP version\r
581                 //\r
582         /*\r
583                 // v3.3 code\r
584                 if (\r
585                                 ($contenttype == 'application/xhtml+xml')\r
586                         &&      (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )\r
587                         ) {\r
588                         $contenttype = 'text/html';\r
589                 }\r
590         */\r
591                 // v3.2x code\r
592                 if (\r
593                                 ($contenttype == 'application/xhtml+xml')\r
594                         &&      (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))\r
595                         )\r
596                 {\r
597                         $contenttype = 'text/html';\r
598                 }\r
599 \r
600                 $manager->notify(\r
601                         'PreSendContentType',\r
602                         array(\r
603                                 'contentType' => &$contenttype,\r
604                                 'charset' => &$charset,\r
605                                 'pageType' => $pagetype\r
606                         )\r
607                 );\r
608 \r
609                 // strip strange characters\r
610                 $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);\r
611                 $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);\r
612 \r
613                 if ($charset != '') {\r
614                         header('Content-Type: ' . $contenttype . '; charset=' . $charset);\r
615                 } else {\r
616                         header('Content-Type: ' . $contenttype);\r
617                 }\r
618 \r
619                 // check if valid charset\r
620                 if (!encoding_check(false,false,$charset)) {\r
621                         foreach(array($_GET, $_POST) as $input) {\r
622                                 array_walk($input, 'encoding_check');\r
623                         }\r
624                 }\r
625         }\r
626 }\r
627 \r
628 /**\r
629  * Errors before the database connection has been made - moved to\r
630  */\r
631 /* moved to $DIR_LIBS/sql/*.php handler files\r
632 function startUpError($msg, $title) {\r
633         if (!defined('_CHARSET')) define('_CHARSET', 'iso-8859-1');\r
634         header('Content-Type: text/html; charset=' . _CHARSET);\r
635         ?>\r
636         <html <?php echo _HTML_XML_NAME_SPACE_AND_LANG_CODE; ?>>\r
637                 <head><meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET?>" />\r
638                 <title><?php echo htmlspecialchars($title)?></title></head>\r
639                 <body>\r
640                         <h1><?php echo htmlspecialchars($title)?></h1>\r
641                         <?php echo $msg?>\r
642                 </body>\r
643         </html>\r
644         <?php   exit;\r
645 }*/\r
646 \r
647 /**\r
648   * disconnects from SQL server\r
649   */\r
650 /* moved to $DIR_LIBS/sql/*.php handler files\r
651 function sql_disconnect() {\r
652         @mysql_close();\r
653 }*/\r
654 \r
655 /**\r
656   * executes an SQL query\r
657   */\r
658 /* moved to $DIR_LIBS/sql/*.php handler files\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 = sql_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 = sql_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 = sprintf(_GFUNCTIONS_HEADERSALREADYSENT_FILE,$hsFile,$hsLine);\r
825                 } else {\r
826                         $extraInfo = '';\r
827                 }\r
828 \r
829                 startUpError(\r
830                         sprintf(_GFUNCTIONS_HEADERSALREADYSENT_TXT,$extraInfo),\r
831                         _GFUNCTIONS_HEADERSALREADYSENT_TITLE\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 = sql_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 = sql_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 = sql_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                 switch(strtolower(_CHARSET)){\r
1021                         case 'utf-8':\r
1022                                 $order = 'ASCII, UTF-8, EUC-JP, JIS, SJIS, EUC-CN, ISO-8859-1';\r
1023                                 break;\r
1024                         case 'gb2312':\r
1025                                 $order = 'ASCII, EUC-CN, EUC-JP, UTF-8, JIS, SJIS, ISO-8859-1';\r
1026                                 break;\r
1027                         case 'shift_jis':\r
1028                                 // Note that shift_jis is only supported for output.\r
1029                                 // Using shift_jis in DB is prohibited.\r
1030                                 $order = 'ASCII, SJIS, EUC-JP, UTF-8, JIS, EUC-CN, ISO-8859-1';\r
1031                                 break;\r
1032                         default:\r
1033                                 // euc-jp,iso-8859-x,windows-125x\r
1034                                 $order = 'ASCII, EUC-JP, UTF-8, JIS, SJIS, EUC-CN, ISO-8859-1';\r
1035                                 break;\r
1036                 }\r
1037                 $query = mb_convert_encoding($query, _CHARSET, $order);\r
1038                 if (is_numeric($blogid)) {\r
1039                         $blogid = intVal($blogid);\r
1040                 } else {\r
1041                         $blogid = getBlogIDFromName($blogid);\r
1042                 }\r
1043 \r
1044                 if (!$blogid) {\r
1045                         doError(_ERROR_NOSUCHBLOG);\r
1046                 }\r
1047 \r
1048         } elseif ($memberid) {\r
1049                 $type = 'member';\r
1050 \r
1051                 if (!MEMBER::existsID($memberid) ) {\r
1052                         doError(_ERROR_NOSUCHMEMBER);\r
1053                 }\r
1054 \r
1055                 $memberinfo = $manager->getMember($memberid);\r
1056 \r
1057         } elseif ($imagepopup) {\r
1058                 // media object (images etc.)\r
1059                 $type = 'imagepopup';\r
1060 \r
1061                 // TODO: check if media-object exists\r
1062                 // TODO: set some vars?\r
1063         } else {\r
1064                 // show regular index page\r
1065                 global $startpos;\r
1066                 $type = 'index';\r
1067         }\r
1068 \r
1069         // any type of skin with catid\r
1070         if ($catid && !$blogid) {\r
1071                 $blogid = getBlogIDFromCatID($catid);\r
1072         }\r
1073 \r
1074         // decide which blog should be displayed\r
1075         if (!$blogid) {\r
1076                 $blogid = $CONF['DefaultBlog'];\r
1077         }\r
1078 \r
1079         $b =& $manager->getBlog($blogid);\r
1080         $blog = $b;     // references can't be placed in global variables?\r
1081 \r
1082         if (!$blog->isValid) {\r
1083                 doError(_ERROR_NOSUCHBLOG);\r
1084         }\r
1085 \r
1086         // set catid if necessary\r
1087         if ($catid) {\r
1088                 // check if the category is valid\r
1089                 if (!$blog->isValidCategory($catid)) {\r
1090                         doError(_ERROR_NOSUCHCATEGORY);\r
1091                 } else {\r
1092                         $blog->setSelectedCategory($catid);\r
1093                 }\r
1094         }\r
1095 \r
1096         // decide which skin should be used\r
1097         if ($skinid != '' && ($skinid == 0) ) {\r
1098                 selectSkin($skinid);\r
1099         }\r
1100 \r
1101         if (!$skinid) {\r
1102                 $skinid = $blog->getDefaultSkin();\r
1103         }\r
1104 \r
1105         //$special = requestVar('special'); //get at top of file as global\r
1106         if (!empty($special) && isValidShortName($special)) {\r
1107                 $type = strtolower($special);\r
1108         }\r
1109 \r
1110         $skin = new SKIN($skinid);\r
1111 \r
1112         if (!$skin->isValid) {\r
1113                 doError(_ERROR_NOSUCHSKIN);\r
1114         }\r
1115 \r
1116         // parse the skin\r
1117         $skin->parse($type);\r
1118 \r
1119         // check to see we should throw JustPosted event\r
1120         $blog->checkJustPosted();\r
1121 }\r
1122 \r
1123 /**\r
1124   * Show error skin with given message. An optional skin-object to use can be given\r
1125   */\r
1126 function doError($msg, $skin = '') {\r
1127         global $errormessage, $CONF, $skinid, $blogid, $manager;\r
1128 \r
1129         if ($skin == '') {\r
1130 \r
1131                 if (SKIN::existsID($skinid) ) {\r
1132                         $skin = new SKIN($skinid);\r
1133                 } elseif ($manager->existsBlogID($blogid) ) {\r
1134                         $blog =& $manager->getBlog($blogid);\r
1135                         $skin = new SKIN($blog->getDefaultSkin() );\r
1136                 } elseif ($CONF['DefaultBlog']) {\r
1137                         $blog =& $manager->getBlog($CONF['DefaultBlog']);\r
1138                         $skin = new SKIN($blog->getDefaultSkin() );\r
1139                 } else {\r
1140                         // this statement should actually never be executed\r
1141                         $skin = new SKIN($CONF['BaseSkin']);\r
1142                 }\r
1143 \r
1144         }\r
1145 \r
1146         $skinid = $skin->id;\r
1147         $errormessage = $msg;\r
1148         $skin->parse('error');\r
1149         exit;\r
1150 }\r
1151 \r
1152 function getConfig() {\r
1153         global $CONF;\r
1154 \r
1155         $query = 'SELECT * FROM ' . sql_table('config');\r
1156         $res = sql_query($query);\r
1157 \r
1158         while ($obj = sql_fetch_object($res) ) {\r
1159                 $CONF[$obj->name] = $obj->value;\r
1160         }\r
1161 }\r
1162 \r
1163 // some checks for names of blogs, categories, templates, members, ...\r
1164 function isValidShortName($name) {\r
1165         return eregi('^[a-z0-9]+$', $name);\r
1166 }\r
1167 \r
1168 function isValidDisplayName($name) {\r
1169         return eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name);\r
1170 }\r
1171 \r
1172 function isValidCategoryName($name) {\r
1173         return 1;\r
1174 }\r
1175 \r
1176 function isValidTemplateName($name) {\r
1177         return eregi('^[a-z0-9/]+$', $name);\r
1178 }\r
1179 \r
1180 function isValidSkinName($name) {\r
1181         return eregi('^[a-z0-9/]+$', $name);\r
1182 }\r
1183 \r
1184 // add and remove linebreaks\r
1185 function addBreaks($var) {\r
1186         return nl2br($var);\r
1187 }\r
1188 \r
1189 function removeBreaks($var) {\r
1190         return preg_replace("/<br \/>([\r\n])/", "$1", $var);\r
1191 }\r
1192 \r
1193 // shortens a text string to maxlength ($toadd) is what needs to be added\r
1194 // at the end (end length is <= $maxlength)\r
1195 function shorten($text, $maxlength, $toadd) {\r
1196         // 1. remove entities...\r
1197 //      $trans = get_html_translation_table(HTML_ENTITIES);\r
1198         $trans = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese\r
1199         $trans = array_flip($trans);\r
1200         $text  = strtr($text, $trans);\r
1201 \r
1202         // 2. the actual shortening\r
1203         if (strlen($text) > $maxlength) {\r
1204 //              $text = substr($text, 0, $maxlength - strlen($toadd) ) . $toadd;\r
1205                 $text = mb_strimwidth($text, 0, $maxlength, $toadd, _CHARSET); // for Japanese\r
1206         }\r
1207         return $text;\r
1208 }\r
1209 \r
1210 /**\r
1211   * Converts a unix timestamp to a mysql DATETIME format, and places\r
1212   * quotes around it.\r
1213   */\r
1214 function mysqldate($timestamp) {\r
1215         return '"' . date('Y-m-d H:i:s', $timestamp) . '"';\r
1216 }\r
1217 \r
1218 /**\r
1219   * functions for use in index.php\r
1220   */\r
1221 function selectBlog($shortname) {\r
1222         global $blogid, $archivelist;\r
1223         $blogid = getBlogIDFromName($shortname);\r
1224 \r
1225         // also force archivelist variable, if it is set\r
1226         if ($archivelist) {\r
1227                 $archivelist = $blogid;\r
1228         }\r
1229 }\r
1230 \r
1231 function selectSkin($skinname) {\r
1232         global $skinid;\r
1233         $skinid = SKIN::getIdFromName($skinname);\r
1234 }\r
1235 \r
1236 /**\r
1237  * Can take either a category ID or a category name (be aware that\r
1238  * multiple categories can have the same name)\r
1239  */\r
1240 function selectCategory($cat) {\r
1241         global $catid;\r
1242         if (is_numeric($cat) ) {\r
1243                 $catid = intval($cat);\r
1244         } else {\r
1245                 $catid = getCatIDFromName($cat);\r
1246         }\r
1247 }\r
1248 \r
1249 function selectItem($id) {\r
1250         global $itemid;\r
1251         $itemid = intval($id);\r
1252 }\r
1253 \r
1254 // force the use of a language file (warning: can cause warnings)\r
1255 function selectLanguage($language) {\r
1256         global $DIR_LANG;\r
1257         include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');\r
1258 }\r
1259 \r
1260 function parseFile($filename, $includeMode = 'normal', $includePrefix = '') {\r
1261         $handler = new ACTIONS('fileparser');\r
1262         $parser = new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);\r
1263         $handler->parser =& $parser;\r
1264 \r
1265         // set IncludeMode properties of parser\r
1266         PARSER::setProperty('IncludeMode', $includeMode);\r
1267         PARSER::setProperty('IncludePrefix', $includePrefix);\r
1268 \r
1269         if (!file_exists($filename) ) {\r
1270                 doError(_GFUNCTIONS_PARSEFILE_FILEMISSING);\r
1271         }\r
1272 \r
1273         $fsize = filesize($filename);\r
1274 \r
1275         if ($fsize <= 0) {\r
1276                 return;\r
1277         }\r
1278 \r
1279         // read file\r
1280         $fd = fopen ($filename, 'r');\r
1281         $contents = fread ($fd, $fsize);\r
1282         fclose ($fd);\r
1283 \r
1284         // parse file contents\r
1285         $parser->parse($contents);\r
1286 }\r
1287 \r
1288 /**\r
1289   * Outputs a debug message\r
1290   */\r
1291 function debug($msg) {\r
1292         echo '<p><b>' . $msg . "</b></p>\n";\r
1293 }\r
1294 \r
1295 // shortcut\r
1296 function addToLog($level, $msg) {\r
1297         ACTIONLOG::add($level, $msg);\r
1298 }\r
1299 \r
1300 // shows a link to help file\r
1301 function help($id) {\r
1302         echo helpHtml($id);\r
1303 }\r
1304 \r
1305 function helpHtml($id) {\r
1306         global $CONF;\r
1307         return helplink($id) . '<img src="' . $CONF['AdminURL'] . 'documentation/icon-help.gif" width="15" height="15" alt="' . _HELP_TT . '" title="' . _HELP_TT . '" /></a>';\r
1308 }\r
1309 \r
1310 function helplink($id) {\r
1311         global $CONF;\r
1312         return '<a href="' . $CONF['AdminURL'] . 'documentation/help.html#'. $id . '" onclick="if (event &amp;&amp; event.preventDefault) event.preventDefault(); return help(this.href);">';\r
1313 }\r
1314 \r
1315 function getMailFooter() {\r
1316         $message = "\n\n-----------------------------";\r
1317         $message .=  "\n   Powered by Nucleus CMS";\r
1318         $message .=  "\n(http://www.nucleuscms.org/)";\r
1319         return $message;\r
1320 }\r
1321 \r
1322 /**\r
1323   * Returns the name of the language to use\r
1324   * preference priority: member - site\r
1325   * defaults to english when no good language found\r
1326   *\r
1327   * checks if file exists, etc...\r
1328   */\r
1329 function getLanguageName() {\r
1330         global $CONF, $member;\r
1331 \r
1332         if ($member && $member->isLoggedIn() ) {\r
1333                 // try to use members language\r
1334                 $memlang = $member->getLanguage();\r
1335 \r
1336                 if (($memlang != '') && (checkLanguage($memlang) ) ) {\r
1337                         return $memlang;\r
1338                 }\r
1339         }\r
1340 \r
1341         // use default language\r
1342         if (checkLanguage($CONF['Language']) ) {\r
1343                 return $CONF['Language'];\r
1344         } else {\r
1345                 return 'english';\r
1346         }\r
1347 }\r
1348 \r
1349 /**\r
1350   * Includes a PHP file. This method can be called while parsing templates and skins\r
1351   */\r
1352 function includephp($filename) {\r
1353         // make predefined variables global, so most simple scripts can be used here\r
1354 \r
1355         // apache (names taken from PHP doc)\r
1356         global $GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE, $SERVER_PROTOCOL;\r
1357         global $REQUEST_METHOD, $QUERY_STRING, $DOCUMENT_ROOT, $HTTP_ACCEPT;\r
1358         global $HTTP_ACCEPT_CHARSET, $HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE;\r
1359         global $HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER, $HTTP_USER_AGENT;\r
1360         global $REMOTE_ADDR, $REMOTE_PORT, $SCRIPT_FILENAME, $SERVER_ADMIN;\r
1361         global $SERVER_PORT, $SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME;\r
1362         global $REQUEST_URI;\r
1363 \r
1364         // php (taken from PHP doc)\r
1365         global $argv, $argc, $PHP_SELF, $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS;\r
1366         global $HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS, $HTTP_SESSION_VARS;\r
1367 \r
1368         // other\r
1369         global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;\r
1370 \r
1371         if (@file_exists($filename) ) {\r
1372                 include($filename);\r
1373         }\r
1374 }\r
1375 \r
1376 /**\r
1377   * Checks if a certain language/plugin exists\r
1378   */\r
1379 function checkLanguage($lang) {\r
1380         global $DIR_LANG ;\r
1381         return file_exists($DIR_LANG . ereg_replace( '[\\|/]', '', $lang) . '.php');\r
1382 }\r
1383 \r
1384 function checkPlugin($plug) {\r
1385         global $DIR_PLUGINS;\r
1386         return file_exists($DIR_PLUGINS . ereg_replace( '[\\|/]', '', $plug) . '.php');\r
1387 }\r
1388 \r
1389 /**\r
1390   * Centralisation of the functions that generate links\r
1391   */\r
1392 function createItemLink($itemid, $extra = '') {\r
1393         return createLink('item', array('itemid' => $itemid, 'extra' => $extra) );\r
1394 }\r
1395 \r
1396 function createMemberLink($memberid, $extra = '') {\r
1397         return createLink('member', array('memberid' => $memberid, 'extra' => $extra) );\r
1398 }\r
1399 \r
1400 function createCategoryLink($catid, $extra = '') {\r
1401         return createLink('category', array('catid' => $catid, 'extra' => $extra) );\r
1402 }\r
1403 \r
1404 function createArchiveListLink($blogid = '', $extra = '') {\r
1405         return createLink('archivelist', array('blogid' => $blogid, 'extra' => $extra) );\r
1406 }\r
1407 \r
1408 function createArchiveLink($blogid, $archive, $extra = '') {\r
1409         return createLink('archive', array('blogid' => $blogid, 'archive' => $archive, 'extra' => $extra) );\r
1410 }\r
1411 \r
1412 function createBlogidLink($blogid, $params = '') {\r
1413         return createLink('blog', array('blogid' => $blogid, 'extra' => $params) );\r
1414 }\r
1415 \r
1416 function createLink($type, $params) {\r
1417         global $manager, $CONF;\r
1418 \r
1419         $generatedURL = '';\r
1420         $usePathInfo = ($CONF['URLMode'] == 'pathinfo');\r
1421 \r
1422         // ask plugins first\r
1423         $created = false;\r
1424 \r
1425         if ($usePathInfo) {\r
1426                 $manager->notify(\r
1427                         'GenerateURL',\r
1428                         array(\r
1429                                 'type' => $type,\r
1430                                 'params' => $params,\r
1431                                 'completed' => &$created,\r
1432                                 'url' => &$url\r
1433                         )\r
1434                 );\r
1435         }\r
1436 \r
1437         // if a plugin created the URL, return it\r
1438         if ($created) {\r
1439                 return $url;\r
1440         }\r
1441 \r
1442         // default implementation\r
1443         switch ($type) {\r
1444                 case 'item':\r
1445                         if ($usePathInfo) {\r
1446                                 $url = $CONF['ItemURL'] . '/' . $CONF['ItemKey'] . '/' . $params['itemid'];\r
1447                         } else {\r
1448                                 $url = $CONF['ItemURL'] . '?itemid=' . $params['itemid'];\r
1449                         }\r
1450                         break;\r
1451 \r
1452                 case 'member':\r
1453                         if ($usePathInfo) {\r
1454                                 $url = $CONF['MemberURL'] . '/' . $CONF['MemberKey'] . '/' . $params['memberid'];\r
1455                         } else {\r
1456                                 $url = $CONF['MemberURL'] . '?memberid=' . $params['memberid'];\r
1457                         }\r
1458                         break;\r
1459 \r
1460                 case 'category':\r
1461                         if ($usePathInfo) {\r
1462                                 $url = $CONF['CategoryURL'] . '/' . $CONF['CategoryKey'] . '/' . $params['catid'];\r
1463                         } else {\r
1464                                 $url = $CONF['CategoryURL'] . '?catid=' . $params['catid'];\r
1465                         }\r
1466                         break;\r
1467 \r
1468                 case 'archivelist':\r
1469                         if (!$params['blogid']) {\r
1470                                 $params['blogid'] = $CONF['DefaultBlog'];\r
1471                         }\r
1472 \r
1473                         if ($usePathInfo) {\r
1474                                 $url = $CONF['ArchiveListURL'] . '/' . $CONF['ArchivesKey'] . '/' . $params['blogid'];\r
1475                         } else {\r
1476                                 $url = $CONF['ArchiveListURL'] . '?archivelist=' . $params['blogid'];\r
1477                         }\r
1478                         break;\r
1479 \r
1480                 case 'archive':\r
1481                         if ($usePathInfo) {\r
1482                                 $url = $CONF['ArchiveURL'] . '/' . $CONF['ArchiveKey'] . '/'.$params['blogid'].'/' . $params['archive'];\r
1483                         } else {\r
1484                                 $url = $CONF['ArchiveURL'] . '?blogid='.$params['blogid'].'&amp;archive=' . $params['archive'];\r
1485                         }\r
1486                         break;\r
1487 \r
1488                 case 'blog':\r
1489                         if ($usePathInfo) {\r
1490                                 $url = $CONF['BlogURL'] . '/' . $CONF['BlogKey'] . '/' . $params['blogid'];\r
1491                         } else {\r
1492                                 $url = $CONF['BlogURL'] . '?blogid=' . $params['blogid'];\r
1493                         }\r
1494                         break;\r
1495         }\r
1496 \r
1497         return addLinkParams($url, (isset($params['extra'])? $params['extra'] : null));\r
1498 }\r
1499 \r
1500 function createBlogLink($url, $params) {\r
1501     global $CONF;\r
1502     if ($CONF['URLMode'] == 'normal') {\r
1503         if (strpos($url, '?') === FALSE && is_array($params)) {\r
1504             $fParam = reset($params);\r
1505             $fKey   = key($params);\r
1506             array_shift($params);\r
1507             $url .= '?' . $fKey . '=' . $fParam;\r
1508         }\r
1509     } elseif ($CONF['URLMode'] == 'pathinfo' && substr($url, -1) == '/') {\r
1510         $url = substr($url, 0, -1);\r
1511     }\r
1512         return addLinkParams($url, $params);\r
1513 }\r
1514 \r
1515 function addLinkParams($link, $params) {\r
1516         global $CONF;\r
1517 \r
1518         if (is_array($params) ) {\r
1519 \r
1520                 if ($CONF['URLMode'] == 'pathinfo')     {\r
1521 \r
1522                         foreach ($params as $param => $value) {\r
1523                                 $link .= '/' . $param . '/' . urlencode($value);\r
1524                         }\r
1525 \r
1526                 } else {\r
1527 \r
1528                         foreach ($params as $param => $value) {\r
1529                                 $link .= '&amp;' . $param . '=' . urlencode($value);\r
1530                         }\r
1531 \r
1532                 }\r
1533         }\r
1534 \r
1535         return $link;\r
1536 }\r
1537 \r
1538 /**\r
1539  * @param $querystr\r
1540  *              querystring to alter (e.g. foo=1&bar=2&x=y)\r
1541  * @param $param\r
1542  *              name of parameter to change (e.g. 'foo')\r
1543  * @param $value\r
1544  *              New value for that parameter (e.g. 3)\r
1545  * @result\r
1546  *              altered query string (for the examples above: foo=3&bar=2&x=y)\r
1547  */\r
1548 function alterQueryStr($querystr, $param, $value) {\r
1549         $vars = explode('&', $querystr);\r
1550         $set  = false;\r
1551 \r
1552         for ($i = 0; $i < count($vars); $i++) {\r
1553                 $v = explode('=', $vars[$i]);\r
1554 \r
1555                 if ($v[0] == $param) {\r
1556                         $v[1] = $value;\r
1557                         $vars[$i] = implode('=', $v);\r
1558                         $set = true;\r
1559                         break;\r
1560                 }\r
1561         }\r
1562 \r
1563         if (!$set) {\r
1564                 $vars[] = $param . '=' . $value;\r
1565         }\r
1566 \r
1567         return ltrim(implode('&', $vars), '&');\r
1568 }\r
1569 \r
1570 // passes one variable as hidden input field (multiple fields for arrays)\r
1571 // @see passRequestVars in varsx.x.x.php\r
1572 function passVar($key, $value) {\r
1573         // array ?\r
1574         if (is_array($value) ) {\r
1575                 for ($i = 0; $i < sizeof($value); $i++) {\r
1576                         passVar($key . '[' . $i . ']', $value[$i]);\r
1577                 }\r
1578 \r
1579                 return;\r
1580         }\r
1581 \r
1582         // other values: do stripslashes if needed\r
1583         ?><input type="hidden" name="<?php echo htmlspecialchars($key)?>" value="<?php echo htmlspecialchars(undoMagic($value) )?>" /><?php\r
1584 }\r
1585 \r
1586 /*\r
1587         Date format functions (to be used from [%date(..)%] skinvars\r
1588 */\r
1589 function formatDate($format, $timestamp, $defaultFormat, &$blog) {\r
1590         // apply blog offset (#42)\r
1591         $boffset = $blog ? $blog->getTimeOffset() * 3600 : 0;\r
1592         $offset = date('Z', $timestamp) + $boffset;\r
1593 \r
1594         switch ($format) {\r
1595                 case 'rfc822':\r
1596                         if ($offset >= 0) {\r
1597                                 $tz = '+';\r
1598                         } else {\r
1599                                 $tz = '-';\r
1600                                 $offset = -$offset;\r
1601                         }\r
1602 \r
1603                         $tz .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );\r
1604                         return date('D, j M Y H:i:s ', $timestamp) . $tz;\r
1605 \r
1606                 case 'rfc822GMT':\r
1607                         $timestamp -= $offset;\r
1608                         return date('D, j M Y H:i:s ', $timestamp) . 'GMT';\r
1609 \r
1610                 case 'utc':\r
1611                         $timestamp -= $offset;\r
1612                         return date('Y-m-d\TH:i:s\Z', $timestamp);\r
1613 \r
1614                 case 'iso8601':\r
1615                         if ($offset >= 0) {\r
1616                                 $tz = '+';\r
1617                         } else {\r
1618                                 $tz = '-';\r
1619                                 $offset = -$offset;\r
1620                         }\r
1621 \r
1622                         $tz .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );\r
1623                         return date('Y-m-d\TH:i:s', $timestamp) . $tz;\r
1624 \r
1625                 default :\r
1626                         return strftime($format ? $format : $defaultFormat, $timestamp);\r
1627         }\r
1628 }\r
1629 \r
1630 function encoding_check($val, $key, $encoding=false, $exclude=false) {\r
1631         /*\r
1632           When 3rd argument is set, return if checked already.\r
1633           When 4th argument is set, set the excluded key(s).\r
1634         */\r
1635         static $search=false, $checked=array(), $excludes=array();\r
1636         if ($exclude!==false) {\r
1637                 if (is_array($exclude)) {\r
1638                         foreach($exclude as $v) $excludes[$v]=true;\r
1639                 } else $excludes[$exclude]=true;\r
1640                 return;\r
1641         }\r
1642         if ($encoding!==false) {\r
1643                 switch($encoding=strtolower($encoding)){\r
1644                         case 'utf-8':\r
1645                                 $search='/([\x00-\x7F]+'.\r
1646                                         '|[\xC2-\xDF][\x80-\xBF]'.\r
1647                                         '|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]'.\r
1648                                         '|[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.\r
1649                                         '|[\xF8-\xFB][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.\r
1650                                         '|[\xFC-\xFD][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF])/';\r
1651                                         break;\r
1652                         case 'euc-jp':\r
1653                                 $search='/([\x00-\x7F]+'.\r
1654                                         '|[\x8E][\xA0-\xDF]'.\r
1655                                         '|[\x8F]?[\xA1-\xFE][\xA1-\xFE])/';\r
1656                                 break;\r
1657                         case 'gb2312':\r
1658                                 $search='/([\x00-\x7F]+'.\r
1659                                         '|[\xA1-\xF7][\xA1-\xFE])/';\r
1660                                 break;\r
1661                         case 'shift_jis':\r
1662                                 // Note that shift_jis is only supported for output.\r
1663                                 // Using shift_jis in DB is prohibited.\r
1664                                 $search='/([\x00-\x7F\xA1-\xDF]+'.\r
1665                                         '|[\x81-\x9F\xE0-\xFC][\x40-\xFC])/';\r
1666                                 break;\r
1667                         default:\r
1668                                 $search=false;\r
1669                                 if (preg_match('/^iso\-8859\-[0-9]{1,2}$/',$encoding)) break;\r
1670                                 if (preg_match('/^windows\-125[0-8]$/',$encoding)) break;\r
1671                                 startUpError('<p>Unknown or non-supported encoding.</p>', 'Encoding Error');\r
1672                                 exit;\r
1673                 }\r
1674                 if (isset($checked[$encoding])) return true; // Already checked.\r
1675                 $checked[$encoding]=true;\r
1676         }\r
1677         if ($key===false) return false; // Not yet checked.\r
1678         if ($search===false) return true; // non-multibyte encoding\r
1679         if (isset($excludes[$key])) return true; // This key isn't checked.\r
1680         if (is_array($val)) {\r
1681                 array_walk($val, 'encoding_check');\r
1682         } else {\r
1683                 $result=preg_replace($search,'',$val);\r
1684                 if (strlen($result)!=0) {\r
1685                         startUpError('<p>Invalid input.</p>', 'Input Error');\r
1686                         exit;\r
1687                 }\r
1688         }\r
1689         $result=preg_replace($search,'',$key);\r
1690         if (strlen($result)!=0) {\r
1691                 startUpError('<p>Invalid input.</p>', 'Input Error');\r
1692                 exit;\r
1693         }\r
1694         return true;\r
1695 }\r
1696 \r
1697 function checkVars($aVars) {\r
1698         global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;\r
1699 \r
1700         foreach ($aVars as $varName) {\r
1701 \r
1702                 if (phpversion() >= '4.1.0') {\r
1703 \r
1704                         if (   isset($_GET[$varName])\r
1705                                 || isset($_POST[$varName])\r
1706                                 || isset($_COOKIE[$varName])\r
1707                                 || isset($_ENV[$varName])\r
1708                                 || isset($_SESSION[$varName])\r
1709                                 || isset($_FILES[$varName])\r
1710                         ) {\r
1711                                 die('Sorry. An error occurred.');\r
1712                         }\r
1713 \r
1714                 } else {\r
1715 \r
1716                         if (   isset($HTTP_GET_VARS[$varName])\r
1717                                 || isset($HTTP_POST_VARS[$varName])\r
1718                                 || isset($HTTP_COOKIE_VARS[$varName])\r
1719                                 || isset($HTTP_ENV_VARS[$varName])\r
1720                                 || isset($HTTP_SESSION_VARS[$varName])\r
1721                                 || isset($HTTP_POST_FILES[$varName])\r
1722                         ) {\r
1723                                 die('Sorry. An error occurred.');\r
1724                         }\r
1725 \r
1726                 }\r
1727         }\r
1728 }\r
1729 \r
1730 \r
1731 /**\r
1732  * Sanitize parameters such as $_GET and $_SERVER['REQUEST_URI'] etc.\r
1733  * to avoid XSS\r
1734  */\r
1735 function sanitizeParams()\r
1736 {\r
1737         global $HTTP_SERVER_VARS;\r
1738 \r
1739         $array = array();\r
1740         $str = '';\r
1741         $frontParam = '';\r
1742 \r
1743         // REQUEST_URI of $HTTP_SERVER_VARS\r
1744         $str =& $HTTP_SERVER_VARS["REQUEST_URI"];\r
1745         serverStringToArray($str, $array, $frontParam);\r
1746         sanitizeArray($array);\r
1747         arrayToServerString($array, $frontParam, $str);\r
1748 \r
1749         // QUERY_STRING of $HTTP_SERVER_VARS\r
1750         $str =& $HTTP_SERVER_VARS["QUERY_STRING"];\r
1751         serverStringToArray($str, $array, $frontParam);\r
1752         sanitizeArray($array);\r
1753         arrayToServerString($array, $frontParam, $str);\r
1754 \r
1755         if (phpversion() >= '4.1.0') {\r
1756                 // REQUEST_URI of $_SERVER\r
1757                 $str =& $_SERVER["REQUEST_URI"];\r
1758                 serverStringToArray($str, $array, $frontParam);\r
1759                 sanitizeArray($array);\r
1760                 arrayToServerString($array, $frontParam, $str);\r
1761 \r
1762                 // QUERY_STRING of $_SERVER\r
1763                 $str =& $_SERVER["QUERY_STRING"];\r
1764                 serverStringToArray($str, $array, $frontParam);\r
1765                 sanitizeArray($array);\r
1766                 arrayToServerString($array, $frontParam, $str);\r
1767         }\r
1768 \r
1769         // $_GET\r
1770         convArrayForSanitizing($_GET, $array);\r
1771         sanitizeArray($array);\r
1772         revertArrayForSanitizing($array, $_GET);\r
1773 \r
1774         // $_REQUEST (only GET param)\r
1775         convArrayForSanitizing($_REQUEST, $array);\r
1776         sanitizeArray($array);\r
1777         revertArrayForSanitizing($array, $_REQUEST);\r
1778 }\r
1779 \r
1780 /**\r
1781  * Check ticket when not checked in plugin's admin page\r
1782  * to avoid CSRF.\r
1783  * Also avoid the access to plugin/index.php by guest user.\r
1784  */\r
1785 function ticketForPlugin(){\r
1786         global $CONF,$DIR_PLUGINS,$member,$ticketforplugin;\r
1787 \r
1788         /* initialize */\r
1789         $ticketforplugin=array();\r
1790         $ticketforplugin['ticket']=false;\r
1791 \r
1792         /* Check if using plugin's php file. */\r
1793         if ($p_translated=serverVar('PATH_TRANSLATED')) {\r
1794                 if (!file_exists($p_translated)) $p_translated='';\r
1795         }\r
1796         if (!$p_translated) {\r
1797                 $p_translated=serverVar('SCRIPT_FILENAME');\r
1798                 if (!file_exists($p_translated)) {\r
1799                         header("HTTP/1.0 404 Not Found");\r
1800                         exit('');\r
1801                 }\r
1802         }\r
1803         $p_translated=str_replace('\\','/',$p_translated);\r
1804         $d_plugins=str_replace('\\','/',$DIR_PLUGINS);\r
1805         if (strpos($p_translated,$d_plugins)!==0) return;// This isn't plugin php file.\r
1806 \r
1807         /* Solve the plugin php file or admin directory */\r
1808         $phppath=substr($p_translated,strlen($d_plugins));\r
1809         $phppath=preg_replace('!^/!','',$phppath);// Remove the first "/" if exists.\r
1810         $path=preg_replace('/^NP_(.*)\.php$/','$1',$phppath); // Remove the first "NP_" and the last ".php" if exists.\r
1811         $path=preg_replace('!^([^/]*)/(.*)$!','$1',$path); // Remove the "/" and beyond.\r
1812 \r
1813         /* Solve the plugin name. */\r
1814         $plugins=array();\r
1815         $query='SELECT pfile FROM '.sql_table('plugin');\r
1816         $res=sql_query($query);\r
1817         while($row=sql_fetch_row($res)) {\r
1818                 $name=substr($row[0],3);\r
1819                 $plugins[strtolower($name)]=$name;\r
1820         }\r
1821         sql_free_result($res);\r
1822         if ($plugins[$path]) $plugin_name=$plugins[$path];\r
1823         else if (in_array($path,$plugins)) $plugin_name=$path;\r
1824         else {\r
1825                 header("HTTP/1.0 404 Not Found");\r
1826                 exit('');\r
1827         }\r
1828 \r
1829         /* Return if not index.php */\r
1830         if ( $phppath!=strtolower($plugin_name).'/'\r
1831                 && $phppath!=strtolower($plugin_name).'/index.php' ) return;\r
1832 \r
1833         /* Exit if not logged in. */\r
1834         if ( !$member->isLoggedIn() ) exit(_GFUNCTIONS_YOU_AERNT_LOGGEDIN);\r
1835 \r
1836         global $manager,$DIR_LIBS,$DIR_LANG,$HTTP_GET_VARS,$HTTP_POST_VARS;\r
1837 \r
1838         /* Check if this feature is needed (ie, if "$manager->checkTicket()" is not included in the script). */\r
1839         if (!($p_translated=serverVar('PATH_TRANSLATED'))) $p_translated=serverVar('SCRIPT_FILENAME');\r
1840         if ($file=@file($p_translated)) {\r
1841                 $prevline='';\r
1842                 foreach($file as $line) {\r
1843                         if (preg_match('/[\$]manager([\s]*)[\-]>([\s]*)checkTicket([\s]*)[\(]/i',$prevline.$line)) return;\r
1844                         $prevline=$line;\r
1845                 }\r
1846         }\r
1847 \r
1848         /* Show a form if not valid ticket */\r
1849         if ( ( strstr(serverVar('REQUEST_URI'),'?') || serverVar('QUERY_STRING')\r
1850                         || strtoupper(serverVar('REQUEST_METHOD'))=='POST' )\r
1851                                 && (!$manager->checkTicket()) ){\r
1852 \r
1853                 if (!class_exists('PluginAdmin')) {\r
1854                         $language = getLanguageName();\r
1855                         include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');\r
1856                         include($DIR_LIBS . 'PLUGINADMIN.php');\r
1857                 }\r
1858                 if (!(function_exists('mb_strimwidth') || extension_loaded('mbstring'))) {\r
1859                         if (file_exists($DIR_LIBS.'mb_emulator/mb-emulator.php')) {\r
1860                                 global $mbemu_internals;\r
1861                                 include_once($DIR_LIBS.'mb_emulator/mb-emulator.php');\r
1862                         }\r
1863                 }\r
1864                 $oPluginAdmin = new PluginAdmin($plugin_name);\r
1865                 $oPluginAdmin->start();\r
1866                 echo '<p>' . _ERROR_BADTICKET . "</p>\n";\r
1867 \r
1868                 /* Show the form to confirm action */\r
1869                 // PHP 4.0.x support\r
1870                 $get=  (isset($_GET))  ? $_GET  : $HTTP_GET_VARS;\r
1871                 $post= (isset($_POST)) ? $_POST : $HTTP_POST_VARS;\r
1872                 // Resolve URI and QUERY_STRING\r
1873                 if ($uri=serverVar('REQUEST_URI')) {\r
1874                         list($uri,$qstring)=explode('?',$uri);\r
1875                 } else {\r
1876                         if ( !($uri=serverVar('PHP_SELF')) ) $uri=serverVar('SCRIPT_NAME');\r
1877                         $qstring=serverVar('QUERY_STRING');\r
1878                 }\r
1879                 if ($qstring) $qstring='?'.$qstring;\r
1880                 echo '<p>'._SETTINGS_UPDATE.' : '._QMENU_PLUGINS.' <span style="color:red;">'.\r
1881                         htmlspecialchars($plugin_name)."</span> ?</p>\n";\r
1882                 switch(strtoupper(serverVar('REQUEST_METHOD'))){\r
1883                 case 'POST':\r
1884                         echo '<form method="POST" action="'.htmlspecialchars($uri.$qstring).'">';\r
1885                         $manager->addTicketHidden();\r
1886                         _addInputTags($post);\r
1887                         break;\r
1888                 case 'GET':\r
1889                         echo '<form method="GET" action="'.htmlspecialchars($uri).'">';\r
1890                         $manager->addTicketHidden();\r
1891                         _addInputTags($get);\r
1892                 default:\r
1893                         break;\r
1894                 }\r
1895                 echo '<input type="submit" value="'._YES.'" />&nbsp;&nbsp;&nbsp;&nbsp;';\r
1896                 echo '<input type="button" value="'._NO.'" onclick="history.back(); return false;" />';\r
1897                 echo "</form>\n";\r
1898 \r
1899                 $oPluginAdmin->end();\r
1900                 exit;\r
1901         }\r
1902 \r
1903         /* Create new ticket */\r
1904         $ticket=$manager->addTicketToUrl('');\r
1905         $ticketforplugin['ticket']=substr($ticket,strpos($ticket,'ticket=')+7);\r
1906 }\r
1907 function _addInputTags(&$keys,$prefix=''){\r
1908         foreach($keys as $key=>$value){\r
1909                 if ($prefix) $key=$prefix.'['.$key.']';\r
1910                 if (is_array($value)) _addInputTags($value,$key);\r
1911                 else {\r
1912                         if (get_magic_quotes_gpc()) $value=stripslashes($value);\r
1913                         if ($key=='ticket') continue;\r
1914                         echo '<input type="hidden" name="'.htmlspecialchars($key).\r
1915                                 '" value="'.htmlspecialchars($value).'" />'."\n";\r
1916                 }\r
1917         }\r
1918 }\r
1919 \r
1920 /**\r
1921  * Convert the server string such as $_SERVER['REQUEST_URI']\r
1922  * to arry like arry['blogid']=1 and array['page']=2 etc.\r
1923  */\r
1924 function serverStringToArray($str, &$array, &$frontParam)\r
1925 {\r
1926         // init param\r
1927         $array = array();\r
1928         $fronParam = "";\r
1929 \r
1930         // split front param, e.g. /index.php, and others, e.g. blogid=1&page=2\r
1931         if (strstr($str, "?")){\r
1932                 list($frontParam, $args) = preg_split("/\?/", $str, 2);\r
1933         }\r
1934         else {\r
1935                 $args = $str;\r
1936                 $frontParam = "";\r
1937         }\r
1938 \r
1939         // If there is no args like blogid=1&page=2, return\r
1940         if (!strstr($str, "=") && !strlen($frontParam)) {\r
1941                 $frontParam = $str;\r
1942                 return;\r
1943         }\r
1944 \r
1945         $array = explode("&", $args);\r
1946 }\r
1947 \r
1948 /**\r
1949  * Convert array like array['blogid'] to server string\r
1950  * such as $_SERVER['REQUEST_URI']\r
1951  */\r
1952 function arrayToServerString($array, $frontParam, &$str)\r
1953 {\r
1954         if (strstr($str, "?")) {\r
1955                 $str = $frontParam . "?";\r
1956         } else {\r
1957                 $str = $frontParam;\r
1958         }\r
1959         if (count($array)) {\r
1960                 $str .= implode("&", $array);\r
1961         }\r
1962 }\r
1963 \r
1964 /**\r
1965  * Sanitize array parameters.\r
1966  * This function checks both key and value.\r
1967  * - check key if it inclues " (double quote),  remove from array\r
1968  * - check value if it includes \ (escape sequece), remove remaining string\r
1969  */\r
1970 function sanitizeArray(&$array)\r
1971 {\r
1972         $excludeListForSanitization = array('query');\r
1973 //      $excludeListForSanitization = array();\r
1974 \r
1975         foreach ($array as $k => $v) {\r
1976 \r
1977                 // split to key and value\r
1978                 list($key, $val) = preg_split("/=/", $v, 2);\r
1979                 if (!isset($val)) {\r
1980                         continue;\r
1981                 }\r
1982 \r
1983                 // when magic quotes is on, need to use stripslashes,\r
1984                 // and then addslashes\r
1985                 if (get_magic_quotes_gpc()) {\r
1986                         $val = stripslashes($val);\r
1987                 }\r
1988                 $val = addslashes($val);\r
1989 \r
1990                 // if $key is included in exclude list, skip this param\r
1991                 if (!in_array($key, $excludeListForSanitization)) {\r
1992 \r
1993                         // check value\r
1994                         if (strpos($val, '\\')) {\r
1995                                 list($val, $tmp) = explode('\\', $val);\r
1996                         }\r
1997 \r
1998                         // remove control code etc.\r
1999                         $val = strtr($val, "\0\r\n<>'\"", "       ");\r
2000 \r
2001                         // check key\r
2002                         if (preg_match('/\"/i', $key)) {\r
2003                                 unset($array[$k]);\r
2004                                 continue;\r
2005                         }\r
2006 \r
2007                         // set sanitized info\r
2008                         $array[$k] = sprintf("%s=%s", $key, $val);\r
2009                 }\r
2010         }\r
2011 }\r
2012 \r
2013 /**\r
2014  * Convert array for sanitizeArray function\r
2015  */\r
2016 function convArrayForSanitizing($src, &$array)\r
2017 {\r
2018         $array = array();\r
2019         foreach ($src as $key => $val) {\r
2020                 if (key_exists($key, $_GET)) {\r
2021                         array_push($array, sprintf("%s=%s", $key, $val));\r
2022                 }\r
2023         }\r
2024 }\r
2025 \r
2026 /**\r
2027  * Revert array after sanitizeArray function\r
2028  */\r
2029 function revertArrayForSanitizing($array, &$dst)\r
2030 {\r
2031         foreach ($array as $v) {\r
2032                 list($key, $val) = preg_split("/=/", $v, 2);\r
2033                 $dst[$key] = $val;\r
2034         }\r
2035 }\r
2036 \r
2037 /**\r
2038  * Stops processing the request and redirects to the given URL.\r
2039  * - no actual contents should have been sent to the output yet\r
2040  * - the URL will be stripped of illegal or dangerous characters\r
2041  */\r
2042 function redirect($url) {\r
2043         $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%*]|i', '', $url);\r
2044         header('Location: ' . $url);\r
2045         exit;\r
2046 }\r
2047 \r
2048 /**\r
2049  * Strip HTML tags from a string\r
2050  * This function is a bit more intelligent than a regular call to strip_tags(),\r
2051  * because it also deletes the contents of certain tags and cleans up any\r
2052  * unneeded whitespace.\r
2053  */\r
2054 function stringStripTags ($string) {\r
2055         $string = preg_replace("/<del[^>]*>.+<\/del[^>]*>/isU", '', $string);\r
2056         $string = preg_replace("/<script[^>]*>.+<\/script[^>]*>/isU", '', $string);\r
2057         $string = preg_replace("/<style[^>]*>.+<\/style[^>]*>/isU", '', $string);\r
2058         $string = str_replace('>', '> ', $string);\r
2059         $string = str_replace('<', ' <', $string);\r
2060         $string = strip_tags($string);\r
2061         $string = preg_replace("/\s+/", " ", $string);\r
2062         $string = trim($string);\r
2063         return $string;\r
2064 }\r
2065 \r
2066 /**\r
2067  * Make a string containing HTML safe for use in a HTML attribute\r
2068  * Tags are stripped and entities are normalized\r
2069  */\r
2070 function stringToAttribute ($string) {\r
2071         $string = stringStripTags($string);\r
2072         $string = entity::named_to_numeric($string);\r
2073         $string = entity::normalize_numeric($string);\r
2074 \r
2075         if (strtoupper(_CHARSET) == 'UTF-8') {\r
2076                 $string = entity::numeric_to_utf8($string);\r
2077         }\r
2078 \r
2079         $string = entity::specialchars($string, 'html');\r
2080         $string = entity::numeric_to_named($string);\r
2081         return $string;\r
2082 }\r
2083 \r
2084 /**\r
2085  * Make a string containing HTML safe for use in a XML document\r
2086  * Tags are stripped, entities are normalized and named entities are\r
2087  * converted to numeric entities.\r
2088  */\r
2089 function stringToXML ($string) {\r
2090         $string = stringStripTags($string);\r
2091         $string = entity::named_to_numeric($string);\r
2092         $string = entity::normalize_numeric($string);\r
2093 \r
2094         if (strtoupper(_CHARSET) == 'UTF-8') {\r
2095                 $string = entity::numeric_to_utf8($string);\r
2096         }\r
2097 \r
2098         $string = entity::specialchars($string, 'xml');\r
2099         return $string;\r
2100 }\r
2101 \r
2102 // START: functions from the end of file BLOG.php\r
2103 // used for mail notification (html -> text)\r
2104 function toAscii($html) {\r
2105         // strip off most tags\r
2106         $html = strip_tags($html,'<a>');\r
2107         $to_replace = "/<a[^>]*href=[\"\']([^\"^']*)[\"\'][^>]*>([^<]*)<\/a>/i";\r
2108         _links_init();\r
2109         $ascii = preg_replace_callback ($to_replace, '_links_add', $html);\r
2110         $ascii .= "\n\n" . _links_list();\r
2111         return strip_tags($ascii);\r
2112 }\r
2113 \r
2114 function _links_init() {\r
2115    global $tmp_links;\r
2116    $tmp_links = array();\r
2117 }\r
2118 \r
2119 function _links_add($match) {\r
2120    global $tmp_links;\r
2121    array_push($tmp_links, $match[1]);\r
2122    return $match[2] . ' [' . sizeof($tmp_links) .']';\r
2123 }\r
2124 \r
2125 function _links_list() {\r
2126    global $tmp_links;\r
2127    $output = '';\r
2128    $i = 1;\r
2129    foreach ($tmp_links as $current) {\r
2130           $output .= "[$i] $current\n";\r
2131           $i++;\r
2132    }\r
2133    return $output;\r
2134 }\r
2135 // END: functions from the end of file BLOG.php\r
2136 \r
2137 // START: functions from the end of file ADMIN.php\r
2138 /**\r
2139  * @todo document this\r
2140  */\r
2141 function encode_desc(&$data)\r
2142 {\r
2143 //      _$to_entities = get_html_translation_table(HTML_ENTITIES);\r
2144         $to_entities = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese\r
2145         $from_entities = array_flip($to_entities);\r
2146         $data = str_replace('<br />', '\n', $data); //hack\r
2147         $data = strtr($data,$from_entities);\r
2148         $data = strtr($data,$to_entities);\r
2149         $data = str_replace('\n', '<br />', $data); //hack\r
2150         return $data;\r
2151 }\r
2152 \r
2153 /**\r
2154  * Returns the Javascript code for a bookmarklet that works on most modern browsers\r
2155  *\r
2156  * @param blogid\r
2157  */\r
2158 function getBookmarklet($blogid) {\r
2159         global $CONF;\r
2160 \r
2161         // normal\r
2162         $document = 'document';\r
2163         $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
2164         $bookmarkletline .= $CONF['AdminURL'] . "bookmarklet.php?blogid=$blogid";\r
2165         $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
2166 \r
2167         return $bookmarkletline;\r
2168 }\r
2169 // END: functions from the end of file ADMIN.php\r
2170 \r
2171 /**\r
2172  * Returns a variable or null if not set\r
2173  *\r
2174  * @param mixed Variable\r
2175  * @return mixed Variable\r
2176  */\r
2177 function ifset(&$var) {\r
2178         if (isset($var)) {\r
2179                 return $var;\r
2180         }\r
2181 \r
2182         return null;\r
2183 }\r
2184 \r
2185 /**\r
2186  * Returns number of subscriber to an event\r
2187  *\r
2188  * @param event\r
2189  * @return number of subscriber(s)\r
2190  */\r
2191 function numberOfEventSubscriber($event) {\r
2192         $query = 'SELECT COUNT(*) as count FROM ' . sql_table('plugin_event') . ' WHERE event=\'' . $event . '\'';\r
2193         $res = sql_query($query);\r
2194         $obj = sql_fetch_object($res);\r
2195         return $obj->count;\r
2196 }\r
2197 \r
2198 function selectSpecialSkinType($id) {\r
2199         global $special;\r
2200         $special = strtolower($id);\r
2201 }\r
2202 \r
2203 ?>