OSDN Git Service

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