OSDN Git Service

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