OSDN Git Service

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