OSDN Git Service

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