OSDN Git Service

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