OSDN Git Service

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