OSDN Git Service

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