OSDN Git Service

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