OSDN Git Service

CHANGE: globalfunctioos.phpにおいて、Entityクラスのインクルード位置を変更
[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 /*\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                 }\r
1029                 $res = sql_query($query);\r
1030                 \r
1031                 $obj = sql_fetch_object($res);\r
1032                 \r
1033                 if ( $obj )\r
1034                 {\r
1035                         $itemidnext = $obj->inumber;\r
1036                         $itemtitlenext = $obj->ititle;\r
1037                 }\r
1038         }\r
1039         elseif ( $archive )\r
1040         {\r
1041                 // show archive\r
1042                 $type = 'archive';\r
1043                 \r
1044                 // get next and prev month links ...\r
1045                 global $archivenext, $archiveprev, $archivetype, $archivenextexists, $archiveprevexists;\r
1046                 \r
1047                 // sql queries for the timestamp of the first and the last published item\r
1048                 $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 ORDER BY itime ASC";\r
1049                 $first_timestamp=quickQuery ($query);\r
1050                 $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 ORDER BY itime DESC";\r
1051                 $last_timestamp=quickQuery ($query);\r
1052                 \r
1053                 sscanf($archive, '%d-%d-%d', $y, $m, $d);\r
1054                 \r
1055                 if ( $d != 0 )\r
1056                 {\r
1057                         $archivetype = _ARCHIVETYPE_DAY;\r
1058                         $t = mktime(0, 0, 0, $m, $d, $y);\r
1059                         // one day has 24 * 60 * 60 = 86400 seconds\r
1060                         $archiveprev = i18n::formatted_datetime('%Y-%m-%d', $t - 86400 );\r
1061                         // check for published items\r
1062                         if ( $t > $first_timestamp )\r
1063                         {\r
1064                                 $archiveprevexists = true;\r
1065                         }\r
1066                         else\r
1067                         {\r
1068                                 $archiveprevexists = false;\r
1069                         }\r
1070                         \r
1071                         // one day later\r
1072                         $t += 86400;\r
1073                         $archivenext = i18n::formatted_datetime('%Y-%m-%d', $t);\r
1074                         if ( $t < $last_timestamp )\r
1075                         {\r
1076                                 $archivenextexists = true;\r
1077                         }\r
1078                         else\r
1079                         {\r
1080                                 $archivenextexists = false;\r
1081                         }\r
1082                 }\r
1083                 elseif ( $m == 0 )\r
1084                 {\r
1085                         $archivetype = _ARCHIVETYPE_YEAR;\r
1086                         $t = mktime(0, 0, 0, 12, 31, $y - 1);\r
1087                         // one day before is in the previous year\r
1088                         $archiveprev = i18n::formatted_datetime('%Y', $t);\r
1089                         if ( $t > $first_timestamp )\r
1090                         {\r
1091                                 $archiveprevexists = true;\r
1092                         }\r
1093                         else\r
1094                         {\r
1095                                 $archiveprevexists = false;\r
1096                         }\r
1097 \r
1098                         // timestamp for the next year\r
1099                         $t = mktime(0, 0, 0, 1, 1, $y + 1);\r
1100                         $archivenext = i18n::formatted_datetime('%Y', $t);\r
1101                         if ( $t < $last_timestamp )\r
1102                         {\r
1103                                 $archivenextexists = true;\r
1104                         }\r
1105                         else\r
1106                         {\r
1107                                 $archivenextexists = false;\r
1108                         }\r
1109                 }\r
1110                 else\r
1111                 {\r
1112                         $archivetype = _ARCHIVETYPE_MONTH;\r
1113                         $t = mktime(0, 0, 0, $m, 1, $y);\r
1114                         // one day before is in the previous month\r
1115                         $archiveprev = i18n::formatted_datetime('%Y-%m', $t - 86400);\r
1116                         if ( $t > $first_timestamp )\r
1117                         {\r
1118                                 $archiveprevexists = true;\r
1119                         }\r
1120                         else\r
1121                         {\r
1122                                 $archiveprevexists = false;\r
1123                         }\r
1124                         \r
1125                         // timestamp for the next month\r
1126                         $t = mktime(0, 0, 0, $m+1, 1, $y);\r
1127                         $archivenext = i18n::formatted_datetime('%Y-%m', $t);\r
1128                         if ( $t < $last_timestamp )\r
1129                         {\r
1130                                 $archivenextexists = true;\r
1131                         }\r
1132                         else\r
1133                         {\r
1134                                 $archivenextexists = false;\r
1135                         }\r
1136                 }\r
1137         }\r
1138         elseif ( $archivelist )\r
1139         {\r
1140                 $type = 'archivelist';\r
1141                 \r
1142                 if ( is_numeric($archivelist) )\r
1143                 {\r
1144                         $blogid = intVal($archivelist);\r
1145                 }\r
1146                 else\r
1147                 {\r
1148                         $blogid = getBlogIDFromName($archivelist);\r
1149                 }\r
1150         \r
1151                 if ( !$blogid )\r
1152                 {\r
1153                         doError(_ERROR_NOSUCHBLOG);\r
1154                 }\r
1155         }\r
1156         elseif ( $query )\r
1157         {\r
1158                 global $startpos;\r
1159                 $type = 'search';\r
1160                 $query = stripslashes($query);\r
1161                 \r
1162                 if ( is_numeric($blogid) )\r
1163                 {\r
1164                         $blogid = intVal($blogid);\r
1165                 }\r
1166                 else\r
1167                 {\r
1168                         $blogid = getBlogIDFromName($blogid);\r
1169                 }\r
1170                 \r
1171                 if ( !$blogid )\r
1172                 {\r
1173                         doError(_ERROR_NOSUCHBLOG);\r
1174                 }\r
1175         }\r
1176         elseif ( $memberid )\r
1177         {\r
1178                 $type = 'member';\r
1179                 \r
1180                 if ( !MEMBER::existsID($memberid) )\r
1181                 {\r
1182                         doError(_ERROR_NOSUCHMEMBER);\r
1183                 }\r
1184                 $memberinfo = $manager->getMember($memberid);\r
1185         }\r
1186         elseif ( $imagepopup )\r
1187         {\r
1188                 // media object (images etc.)\r
1189                 $type = 'imagepopup';\r
1190                 \r
1191                 // TODO: check if media-object exists\r
1192                 // TODO: set some vars?\r
1193         }\r
1194         else\r
1195         {\r
1196                 // show regular index page\r
1197                 global $startpos;\r
1198                 $type = 'index';\r
1199         }\r
1200         \r
1201         // any type of skin with catid\r
1202         if ( $catid && !$blogid )\r
1203         {\r
1204                 $blogid = getBlogIDFromCatID($catid);\r
1205         }\r
1206         \r
1207         // decide which blog should be displayed\r
1208         if ( !$blogid )\r
1209         {\r
1210                 $blogid = $CONF['DefaultBlog'];\r
1211         }\r
1212         \r
1213         $b =& $manager->getBlog($blogid);\r
1214         $blog = $b; // references can't be placed in global variables?\r
1215         \r
1216         if ( !$blog->isValid )\r
1217         {\r
1218                 doError(_ERROR_NOSUCHBLOG);\r
1219         }\r
1220         \r
1221         // set catid if necessary\r
1222         if ( $catid )\r
1223         {\r
1224                 // check if the category is valid\r
1225                 if ( !$blog->isValidCategory($catid) )\r
1226                 {\r
1227                         doError(_ERROR_NOSUCHCATEGORY);\r
1228                 }\r
1229                 else\r
1230                 {\r
1231                         $blog->setSelectedCategory($catid);\r
1232                 }\r
1233         }\r
1234         \r
1235         // decide which skin should be used\r
1236         if ( $skinid != '' && ($skinid == 0) )\r
1237         {\r
1238                 selectSkin($skinid);\r
1239         }\r
1240         \r
1241         if ( !$skinid )\r
1242         {\r
1243                 $skinid = $blog->getDefaultSkin();\r
1244         }\r
1245         \r
1246         //$special = requestVar('special'); //get at top of file as global\r
1247         if ( !empty($special) && isValidShortName($special) )\r
1248         {\r
1249                 $type = strtolower($special);\r
1250         }\r
1251         \r
1252         $skin = new SKIN($skinid);\r
1253         \r
1254         if ( !$skin->isValid )\r
1255         {\r
1256                 doError(_ERROR_NOSUCHSKIN);\r
1257         }\r
1258         \r
1259         // set global skinpart variable so can determine quickly what is being parsed from any plugin or phpinclude\r
1260         global $skinpart;\r
1261         $skinpart = $type;\r
1262         \r
1263         // parse the skin\r
1264         $skin->parse($type);\r
1265         \r
1266         // check to see we should throw JustPosted event\r
1267         $blog->checkJustPosted();\r
1268         return;\r
1269 }\r
1270 \r
1271 /**\r
1272   * Show error skin with given message. An optional skin-object to use can be given\r
1273   */\r
1274 function doError($msg, $skin = '') {\r
1275     global $errormessage, $CONF, $skinid, $blogid, $manager;\r
1276 \r
1277     if ($skin == '') {\r
1278 \r
1279         if (SKIN::existsID($skinid) ) {\r
1280             $skin = new SKIN($skinid);\r
1281         } elseif ($manager->existsBlogID($blogid) ) {\r
1282             $blog =& $manager->getBlog($blogid);\r
1283             $skin = new SKIN($blog->getDefaultSkin() );\r
1284         } elseif ($CONF['DefaultBlog']) {\r
1285             $blog =& $manager->getBlog($CONF['DefaultBlog']);\r
1286             $skin = new SKIN($blog->getDefaultSkin() );\r
1287         } else {\r
1288             // this statement should actually never be executed\r
1289             $skin = new SKIN($CONF['BaseSkin']);\r
1290         }\r
1291 \r
1292     }\r
1293 \r
1294     $skinid = $skin->id;\r
1295     $errormessage = $msg;\r
1296     $skin->parse('error');\r
1297     exit;\r
1298 }\r
1299 \r
1300 function getConfig() {\r
1301     global $CONF;\r
1302 \r
1303     $query = 'SELECT * FROM ' . sql_table('config');\r
1304     $res = sql_query($query);\r
1305 \r
1306     while ($obj = sql_fetch_object($res) ) {\r
1307         $CONF[$obj->name] = $obj->value;\r
1308     }\r
1309 }\r
1310 \r
1311 // some checks for names of blogs, categories, templates, members, ...\r
1312 function isValidShortName($name) {\r
1313 \r
1314         # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0\r
1315         # original eregi: eregi('^[a-z0-9]+$', $name)\r
1316 \r
1317         return preg_match('#^[a-z0-9]+$#i', $name);\r
1318 \r
1319 }\r
1320 \r
1321 function isValidDisplayName($name) {\r
1322 \r
1323         # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0\r
1324         # original eregi: eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name)\r
1325 \r
1326         return preg_match('#^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$#i', $name);\r
1327 \r
1328 }\r
1329 \r
1330 function isValidCategoryName($name) {\r
1331     return 1;\r
1332 }\r
1333 \r
1334 function isValidTemplateName($name) {\r
1335 \r
1336         # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0\r
1337         # original eregi: eregi('^[a-z0-9/]+$', $name)\r
1338         // added - and _ to valid characters as of 4.00\r
1339 \r
1340         return preg_match('#^[a-z0-9/_\-]+$#i', $name);\r
1341 \r
1342 }\r
1343 \r
1344 function isValidSkinName($name) {\r
1345 \r
1346         # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0\r
1347         # original eregi: eregi('^[a-z0-9/]+$', $name);\r
1348         // added - and _ to valid characters as of 4.00\r
1349 \r
1350         return preg_match('#^[a-z0-9/_\-]+$#i', $name);\r
1351 \r
1352 }\r
1353 \r
1354 // add and remove linebreaks\r
1355 function addBreaks($var) {\r
1356     return nl2br($var);\r
1357 }\r
1358 \r
1359 function removeBreaks($var) {\r
1360     return preg_replace("/<br \/>([\r\n])/", "$1", $var);\r
1361 }\r
1362 \r
1363 /**\r
1364   * functions for use in index.php\r
1365   */\r
1366 function selectBlog($shortname) {\r
1367     global $blogid, $archivelist;\r
1368     $blogid = getBlogIDFromName($shortname);\r
1369 \r
1370     // also force archivelist variable, if it is set\r
1371     if ($archivelist) {\r
1372         $archivelist = $blogid;\r
1373     }\r
1374 }\r
1375 \r
1376 function selectSkin($skinname) {\r
1377     global $skinid;\r
1378     $skinid = SKIN::getIdFromName($skinname);\r
1379 }\r
1380 \r
1381 /**\r
1382  * Can take either a category ID or a category name (be aware that\r
1383  * multiple categories can have the same name)\r
1384  */\r
1385 function selectCategory($cat) {\r
1386     global $catid;\r
1387     if (is_numeric($cat) ) {\r
1388         $catid = intval($cat);\r
1389     } else {\r
1390         $catid = getCatIDFromName($cat);\r
1391     }\r
1392 }\r
1393 \r
1394 function selectItem($id) {\r
1395     global $itemid;\r
1396     $itemid = intval($id);\r
1397 }\r
1398 \r
1399 // force the use of a translation file (warning: can cause warnings)\r
1400 function selectLanguage($language) {\r
1401 \r
1402         global $DIR_LANG;\r
1403 \r
1404         # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0\r
1405         # original ereg_replace: preg_replace( '@\\|/@', '', $language) . '.php')\r
1406         # important note that '\' must be matched with '\\\\' in preg* expressions\r
1407 \r
1408         include($DIR_LANG . preg_replace('#[\\\\|/]#', '', $language) . '.php');\r
1409 \r
1410 }\r
1411 \r
1412 function parseFile($filename, $includeMode = 'normal', $includePrefix = '') {\r
1413     $handler = new ACTIONS('fileparser');\r
1414     $parser = new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);\r
1415     $handler->parser =& $parser;\r
1416 \r
1417     // set IncludeMode properties of parser\r
1418     PARSER::setProperty('IncludeMode', $includeMode);\r
1419     PARSER::setProperty('IncludePrefix', $includePrefix);\r
1420 \r
1421     if (!file_exists($filename) ) {\r
1422         doError('A file is missing');\r
1423     }\r
1424 \r
1425     $fsize = filesize($filename);\r
1426 \r
1427     if ($fsize <= 0) {\r
1428         return;\r
1429     }\r
1430 \r
1431     // read file\r
1432     $fd = fopen ($filename, 'r');\r
1433     $contents = fread ($fd, $fsize);\r
1434     fclose ($fd);\r
1435 \r
1436     // parse file contents\r
1437     $parser->parse($contents);\r
1438 }\r
1439 \r
1440 /**\r
1441   * Outputs a debug message\r
1442   */\r
1443 function debug($msg) {\r
1444     echo '<p><b>' . $msg . "</b></p>\n";\r
1445 }\r
1446 \r
1447 // shortcut\r
1448 function addToLog($level, $msg) {\r
1449     ACTIONLOG::add($level, $msg);\r
1450 }\r
1451 \r
1452 // shows a link to help file\r
1453 function help($id) {\r
1454     echo helpHtml($id);\r
1455 }\r
1456 \r
1457 function helpHtml($id) {\r
1458     global $CONF;\r
1459     return helplink($id) . '<img src="' . $CONF['AdminURL'] . 'documentation/icon-help.gif" width="15" height="15" alt="' . _HELP_TT . '" title="' . _HELP_TT . '" /></a>';\r
1460 }\r
1461 \r
1462 function helplink($id) {\r
1463     global $CONF;\r
1464     return '<a href="' . $CONF['AdminURL'] . 'documentation/help.html#'. $id . '" onclick="if (event &amp;&amp; event.preventDefault) event.preventDefault(); return help(this.href);">';\r
1465 }\r
1466 \r
1467 /**\r
1468   * Includes a PHP file. This method can be called while parsing templates and skins\r
1469   */\r
1470 function includephp($filename) {\r
1471     // make predefined variables global, so most simple scripts can be used here\r
1472 \r
1473     // apache (names taken from PHP doc)\r
1474     global $GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE, $SERVER_PROTOCOL;\r
1475     global $REQUEST_METHOD, $QUERY_STRING, $DOCUMENT_ROOT, $HTTP_ACCEPT;\r
1476     global $HTTP_ACCEPT_CHARSET, $HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE;\r
1477     global $HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER, $HTTP_USER_AGENT;\r
1478     global $REMOTE_ADDR, $REMOTE_PORT, $SCRIPT_FILENAME, $SERVER_ADMIN;\r
1479     global $SERVER_PORT, $SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME;\r
1480     global $REQUEST_URI;\r
1481 \r
1482     // php (taken from PHP doc)\r
1483     global $argv, $argc, $PHP_SELF, $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS;\r
1484     global $HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS, $HTTP_SESSION_VARS;\r
1485 \r
1486     // other\r
1487     global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;\r
1488 \r
1489     if (@file_exists($filename) ) {\r
1490         include($filename);\r
1491     }\r
1492 }\r
1493 \r
1494 /**\r
1495  * Checks if a certain plugin exists\r
1496  * @param string $plug\r
1497  * @return bool\r
1498  **/\r
1499 function checkPlugin($plug) {\r
1500 \r
1501         global $DIR_PLUGINS;\r
1502 \r
1503         # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0\r
1504         # original ereg_replace: ereg_replace( '[\\|/]', '', $plug) . '.php')\r
1505         # important note that '\' must be matched with '\\\\' in preg* expressions\r
1506 \r
1507         return file_exists($DIR_PLUGINS . preg_replace('#[\\\\|/]#', '', $plug) . '.php');\r
1508 \r
1509 }\r
1510 \r
1511 /**\r
1512  * @param $querystr\r
1513  *              querystring to alter (e.g. foo=1&bar=2&x=y)\r
1514  * @param $param\r
1515  *              name of parameter to change (e.g. 'foo')\r
1516  * @param $value\r
1517  *              New value for that parameter (e.g. 3)\r
1518  * @result\r
1519  *              altered query string (for the examples above: foo=3&bar=2&x=y)\r
1520  */\r
1521 function alterQueryStr($querystr, $param, $value) {\r
1522     $vars = i18n::explode('&', $querystr);\r
1523     $set  = false;\r
1524 \r
1525     for ($i = 0; $i < count($vars); $i++) {\r
1526         $v = i18n::explode('=', $vars[$i]);\r
1527 \r
1528         if ($v[0] == $param) {\r
1529             $v[1] = $value;\r
1530             $vars[$i] = implode('=', $v);\r
1531             $set = true;\r
1532             break;\r
1533         }\r
1534     }\r
1535 \r
1536     if (!$set) {\r
1537         $vars[] = $param . '=' . $value;\r
1538     }\r
1539 \r
1540     return ltrim(implode('&', $vars), '&');\r
1541 }\r
1542 \r
1543 // passes one variable as hidden input field (multiple fields for arrays)\r
1544 // @see passRequestVars in varsx.x.x.php\r
1545 function passVar($key, $value) {\r
1546     // array ?\r
1547     if (is_array($value) ) {\r
1548         for ($i = 0; $i < sizeof($value); $i++) {\r
1549             passVar($key . '[' . $i . ']', $value[$i]);\r
1550         }\r
1551 \r
1552         return;\r
1553     }\r
1554 \r
1555     // other values: do stripslashes if needed\r
1556     ?><input type="hidden" name="<?php echo ENTITY::hsc($key)?>" value="<?php echo ENTITY::hsc(undoMagic($value) )?>" /><?php\r
1557 }\r
1558 \r
1559 function checkVars($aVars) {\r
1560     global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;\r
1561 \r
1562     foreach ($aVars as $varName) {\r
1563 \r
1564         if (phpversion() >= '4.1.0') {\r
1565 \r
1566             if (   isset($_GET[$varName])\r
1567                 || isset($_POST[$varName])\r
1568                 || isset($_COOKIE[$varName])\r
1569                 || isset($_ENV[$varName])\r
1570                 || isset($_SESSION[$varName])\r
1571                 || isset($_FILES[$varName])\r
1572             ) {\r
1573                 die('Sorry. An error occurred.');\r
1574             }\r
1575 \r
1576         } else {\r
1577 \r
1578             if (   isset($HTTP_GET_VARS[$varName])\r
1579                 || isset($HTTP_POST_VARS[$varName])\r
1580                 || isset($HTTP_COOKIE_VARS[$varName])\r
1581                 || isset($HTTP_ENV_VARS[$varName])\r
1582                 || isset($HTTP_SESSION_VARS[$varName])\r
1583                 || isset($HTTP_POST_FILES[$varName])\r
1584             ) {\r
1585                 die('Sorry. An error occurred.');\r
1586             }\r
1587 \r
1588         }\r
1589     }\r
1590 }\r
1591 \r
1592 \r
1593 /**\r
1594  * Sanitize parameters such as $_GET and $_SERVER['REQUEST_URI'] etc.\r
1595  * to avoid XSS\r
1596  */\r
1597 function sanitizeParams()\r
1598 {\r
1599     global $HTTP_SERVER_VARS;\r
1600 \r
1601     $array = array();\r
1602     $str = '';\r
1603     $frontParam = '';\r
1604 \r
1605     // REQUEST_URI of $HTTP_SERVER_VARS\r
1606     $str =& $HTTP_SERVER_VARS["REQUEST_URI"];\r
1607     serverStringToArray($str, $array, $frontParam);\r
1608     sanitizeArray($array);\r
1609     arrayToServerString($array, $frontParam, $str);\r
1610 \r
1611     // QUERY_STRING of $HTTP_SERVER_VARS\r
1612     $str =& $HTTP_SERVER_VARS["QUERY_STRING"];\r
1613     serverStringToArray($str, $array, $frontParam);\r
1614     sanitizeArray($array);\r
1615     arrayToServerString($array, $frontParam, $str);\r
1616 \r
1617     if (phpversion() >= '4.1.0') {\r
1618         // REQUEST_URI of $_SERVER\r
1619         $str =& $_SERVER["REQUEST_URI"];\r
1620         serverStringToArray($str, $array, $frontParam);\r
1621         sanitizeArray($array);\r
1622         arrayToServerString($array, $frontParam, $str);\r
1623 \r
1624         // QUERY_STRING of $_SERVER\r
1625         $str =& $_SERVER["QUERY_STRING"];\r
1626         serverStringToArray($str, $array, $frontParam);\r
1627         sanitizeArray($array);\r
1628         arrayToServerString($array, $frontParam, $str);\r
1629     }\r
1630 \r
1631     // $_GET\r
1632     convArrayForSanitizing($_GET, $array);\r
1633     sanitizeArray($array);\r
1634     revertArrayForSanitizing($array, $_GET);\r
1635 \r
1636     // $_REQUEST (only GET param)\r
1637     convArrayForSanitizing($_REQUEST, $array);\r
1638     sanitizeArray($array);\r
1639     revertArrayForSanitizing($array, $_REQUEST);\r
1640 }\r
1641 \r
1642 /**\r
1643  * Check ticket when not checked in plugin's admin page\r
1644  * to avoid CSRF.\r
1645  * Also avoid the access to plugin/index.php by guest user.\r
1646  */\r
1647 function ticketForPlugin()\r
1648 {\r
1649         global $CONF, $DIR_PLUGINS, $member, $ticketforplugin;\r
1650         \r
1651         /* initialize */\r
1652         $ticketforplugin = array();\r
1653         $ticketforplugin['ticket'] = FALSE;\r
1654         \r
1655         /* $_SERVER['PATH_TRANSLATED']\r
1656          * http://www.php.net/manual/en/reserved.variables.server.php\r
1657          * Note: As of PHP 4.3.2, PATH_TRANSLATED is no longer set implicitly\r
1658          * under the Apache 2 SAPI in contrast to the situation in Apache 1,\r
1659          * where it's set to the same value as the SCRIPT_FILENAME server variable\r
1660          * when it's not populated by Apache.\r
1661          * This change was made to comply with the CGI specification\r
1662          * that PATH_TRANSLATED should only exist if PATH_INFO is defined.\r
1663          * Apache 2 users may use AcceptPathInfo = On inside httpd.conf to define PATH_INFO. \r
1664          */\r
1665         \r
1666         /* Check if using plugin's php file. */\r
1667         $p_translated = serverVar('SCRIPT_FILENAME');\r
1668         \r
1669         if (!file_exists($p_translated) )\r
1670         {\r
1671                 header("HTTP/1.0 404 Not Found");\r
1672                 exit('');\r
1673         }\r
1674         \r
1675         $p_translated = str_replace('\\', '/', $p_translated);\r
1676         $d_plugins = str_replace('\\', '/', $DIR_PLUGINS);\r
1677         \r
1678         // This isn't plugin php file.\r
1679         if ( i18n::strpos($p_translated, $d_plugins) !== 0 )\r
1680         {\r
1681                 return;\r
1682         }\r
1683 \r
1684         // Solve the plugin php file or admin directory\r
1685         $phppath = i18n::substr($p_translated, i18n::strlen($d_plugins) );\r
1686         // Remove the first "/" if exists.\r
1687         $phppath = preg_replace('#^/#', '', $phppath);\r
1688         // Remove the first "NP_" and the last ".php" if exists.\r
1689         $path = preg_replace('#^NP_(.*)\.php$#', '$1', $phppath);\r
1690         // Remove the "/" and beyond.\r
1691         $path = preg_replace('#^([^/]*)/(.*)$#', '$1', $path);\r
1692         \r
1693         // Solve the plugin name.\r
1694         $plugins = array();\r
1695         $query = 'SELECT `pfile` FROM '.sql_table('plugin');\r
1696         $res = sql_query($query);\r
1697         \r
1698         while($row = sql_fetch_row($res) )\r
1699         {\r
1700                 $name = i18n::substr($row[0], 3);\r
1701                 $plugins[strtolower($name)] = $name;\r
1702         }\r
1703         \r
1704         sql_free_result($res);\r
1705         \r
1706         if (array_key_exists($path, $plugins))\r
1707         {\r
1708                 $plugin_name = $plugins[$path];\r
1709         }\r
1710         else if (in_array($path, $plugins))\r
1711         {\r
1712                 $plugin_name = $path;\r
1713         }\r
1714         else\r
1715         {\r
1716                 header("HTTP/1.0 404 Not Found");\r
1717                 exit('');\r
1718         }\r
1719         \r
1720         /* Return if not index.php */\r
1721         if ( ($phppath != strtolower($plugin_name) . '/') && ($phppath != strtolower($plugin_name) . '/index.php') )\r
1722         {\r
1723                 return;\r
1724         }\r
1725         \r
1726         /* Exit if not logged in. */\r
1727         if ( !$member->isLoggedIn() )\r
1728         {\r
1729                 exit('You aren\'t logged in.');\r
1730         }\r
1731         \r
1732         global $manager, $DIR_LIBS, $DIR_LOCALES, $HTTP_GET_VARS, $HTTP_POST_VARS;\r
1733         \r
1734         /* Check if this feature is needed (ie, if "$manager->checkTicket()" is not included in the script). */\r
1735         if (!($p_translated = serverVar('PATH_TRANSLATED') ) )\r
1736         {\r
1737                 $p_translated = serverVar('SCRIPT_FILENAME');\r
1738         }\r
1739         \r
1740         if ($file = @file($p_translated) )\r
1741         {\r
1742                 $prevline = '';\r
1743                 \r
1744                 foreach($file as $line)\r
1745                 {\r
1746                         if (preg_match('/[\$]manager([\s]*)[\-]>([\s]*)checkTicket([\s]*)[\(]/i', $prevline . $line) )\r
1747                         {\r
1748                                 return;\r
1749                         }\r
1750                         \r
1751                         $prevline = $line;\r
1752                 }\r
1753         }\r
1754         \r
1755         /* Show a form if not valid ticket */\r
1756         if ( ( strstr(serverVar('REQUEST_URI'), '?') || serverVar('QUERY_STRING')\r
1757          || strtoupper(serverVar('REQUEST_METHOD') ) == 'POST')\r
1758          && (!$manager->checkTicket() ) )\r
1759         {\r
1760                 $oPluginAdmin = new PluginAdmin($plugin_name);\r
1761                 $oPluginAdmin->start();\r
1762                 echo '<p>' . _ERROR_BADTICKET . "</p>\n";\r
1763                 \r
1764                 /* Show the form to confirm action */\r
1765                 // PHP 4.0.x support\r
1766                 $get = (isset($_GET) ) ? $_GET : $HTTP_GET_VARS;\r
1767                 $post = (isset($_POST) ) ? $_POST : $HTTP_POST_VARS;\r
1768                 \r
1769                 // Resolve URI and QUERY_STRING\r
1770                 if ($uri = serverVar('REQUEST_URI') )\r
1771                 {\r
1772                         list($uri, $qstring) = i18n::explode('?', $uri);\r
1773                 }\r
1774                 else\r
1775                 {\r
1776                         if ( !($uri = serverVar('PHP_SELF') ) )\r
1777                         {\r
1778                                 $uri = serverVar('SCRIPT_NAME');\r
1779                         }\r
1780                         $qstring = serverVar('QUERY_STRING');\r
1781                 }\r
1782                 if ($qstring)\r
1783                 {\r
1784                         $qstring = '?' . $qstring;\r
1785                 }\r
1786                 \r
1787                 echo '<p>' . _SETTINGS_UPDATE . ' : ' . _QMENU_PLUGINS . ' <span style="color:red;">' . ENTITY::hsc($plugin_name) . "</span> ?</p>\n";\r
1788                 \r
1789                 switch(strtoupper(serverVar('REQUEST_METHOD') ) )\r
1790                 {\r
1791                         case 'POST':\r
1792                                 echo '<form method="POST" action="'.ENTITY::hsc($uri.$qstring).'">';\r
1793                                 $manager->addTicketHidden();\r
1794                                 _addInputTags($post);\r
1795                                 break;\r
1796                         \r
1797                         case 'GET':\r
1798                                 echo '<form method="GET" action="'.ENTITY::hsc($uri).'">';\r
1799                                 $manager->addTicketHidden();\r
1800                                 _addInputTags($get);\r
1801                         \r
1802                         default:\r
1803                                 break;\r
1804                 }\r
1805                 \r
1806                 echo '<input type="submit" value="' . _YES . '" />&nbsp;&nbsp;&nbsp;&nbsp;';\r
1807                 echo '<input type="button" value="' . _NO . '" onclick="history.back(); return false;" />';\r
1808                 echo "</form>\n";\r
1809                 \r
1810                 $oPluginAdmin->end();\r
1811                 exit;\r
1812         }\r
1813         \r
1814         /* Create new ticket */\r
1815         $ticket=$manager->addTicketToUrl('');\r
1816         $ticketforplugin['ticket']=i18n::substr($ticket,i18n::strpos($ticket,'ticket=')+7);\r
1817 }\r
1818 \r
1819 function _addInputTags(&$keys,$prefix=''){\r
1820     foreach($keys as $key=>$value){\r
1821         if ($prefix) $key=$prefix.'['.$key.']';\r
1822         if (is_array($value)) _addInputTags($value,$key);\r
1823         else {\r
1824             if (get_magic_quotes_gpc()) $value=stripslashes($value);\r
1825             if ($key=='ticket') continue;\r
1826             echo '<input type="hidden" name="'.ENTITY::hsc($key).\r
1827                 '" value="'.ENTITY::hsc($value).'" />'."\n";\r
1828         }\r
1829     }\r
1830 }\r
1831 \r
1832 /**\r
1833  * Convert the server string such as $_SERVER['REQUEST_URI']\r
1834  * to arry like arry['blogid']=1 and array['page']=2 etc.\r
1835  */\r
1836 function serverStringToArray($str, &$array, &$frontParam)\r
1837 {\r
1838     // init param\r
1839     $array = array();\r
1840     $frontParam = "";\r
1841 \r
1842     // split front param, e.g. /index.php, and others, e.g. blogid=1&page=2\r
1843     if (strstr($str, "?")){\r
1844         list($frontParam, $args) = preg_split("/\?/", $str, 2);\r
1845     }\r
1846     else {\r
1847         $args = $str;\r
1848         $frontParam = "";\r
1849     }\r
1850 \r
1851     // If there is no args like blogid=1&page=2, return\r
1852     if (!strstr($str, "=") && !i18n::strlen($frontParam)) {\r
1853         $frontParam = $str;\r
1854         return;\r
1855     }\r
1856 \r
1857     $array = i18n::explode("&", $args);\r
1858 }\r
1859 \r
1860 /**\r
1861  * Convert array like array['blogid'] to server string\r
1862  * such as $_SERVER['REQUEST_URI']\r
1863  */\r
1864 function arrayToServerString($array, $frontParam, &$str)\r
1865 {\r
1866     if (strstr($str, "?")) {\r
1867         $str = $frontParam . "?";\r
1868     } else {\r
1869         $str = $frontParam;\r
1870     }\r
1871     if (count($array)) {\r
1872         $str .= implode("&", $array);\r
1873     }\r
1874 }\r
1875 \r
1876 /**\r
1877  * Sanitize array parameters.\r
1878  * This function checks both key and value.\r
1879  * - check key if it inclues " (double quote),  remove from array\r
1880  * - check value if it includes \ (escape sequece), remove remaining string\r
1881  */\r
1882 function sanitizeArray(&$array)\r
1883 {\r
1884     $excludeListForSanitization = array('query');\r
1885 //      $excludeListForSanitization = array();\r
1886 \r
1887     foreach ($array as $k => $v) {\r
1888 \r
1889         // split to key and value\r
1890         list($key, $val) = preg_split("/=/", $v, 2);\r
1891         if (!isset($val)) {\r
1892             continue;\r
1893         }\r
1894 \r
1895         // when magic quotes is on, need to use stripslashes,\r
1896         // and then addslashes\r
1897         if (get_magic_quotes_gpc()) {\r
1898             $val = stripslashes($val);\r
1899         }\r
1900                 // note that we must use addslashes here because this function is called before the db connection is made\r
1901                 // and sql_real_escape_string needs a db connection\r
1902         $val = addslashes($val);\r
1903 \r
1904         // if $key is included in exclude list, skip this param\r
1905         if (!in_array($key, $excludeListForSanitization)) {\r
1906 \r
1907             // check value\r
1908             if (i18n::strpos($val, '\\')) {\r
1909                 list($val, $tmp) = i18n::explode('\\', $val);\r
1910             }\r
1911 \r
1912             // remove control code etc.\r
1913             $val = strtr($val, "\0\r\n<>'\"", "       ");\r
1914 \r
1915             // check key\r
1916             if (preg_match('/\"/i', $key)) {\r
1917                 unset($array[$k]);\r
1918                 continue;\r
1919             }\r
1920 \r
1921             // set sanitized info\r
1922             $array[$k] = sprintf("%s=%s", $key, $val);\r
1923         }\r
1924     }\r
1925 }\r
1926 \r
1927 /**\r
1928  * Convert array for sanitizeArray function\r
1929  */\r
1930 function convArrayForSanitizing($src, &$array)\r
1931 {\r
1932     $array = array();\r
1933     foreach ($src as $key => $val) {\r
1934         if (key_exists($key, $_GET)) {\r
1935             array_push($array, sprintf("%s=%s", $key, $val));\r
1936         }\r
1937     }\r
1938 }\r
1939 \r
1940 /**\r
1941  * Revert array after sanitizeArray function\r
1942  */\r
1943 function revertArrayForSanitizing($array, &$dst)\r
1944 {\r
1945     foreach ($array as $v) {\r
1946         list($key, $val) = preg_split("/=/", $v, 2);\r
1947         $dst[$key] = $val;\r
1948     }\r
1949 }\r
1950 \r
1951 /**\r
1952  * Stops processing the request and redirects to the given URL.\r
1953  * - no actual contents should have been sent to the output yet\r
1954  * - the URL will be stripped of illegal or dangerous characters\r
1955  */\r
1956 function redirect($url) {\r
1957     $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%*]|i', '', $url);\r
1958     header('Location: ' . $url);\r
1959     exit;\r
1960 }\r
1961 \r
1962 /*\r
1963  * Returns the Javascript code for a bookmarklet that works on most modern browsers\r
1964  * @param blogid\r
1965  */\r
1966 function getBookmarklet($blogid) {\r
1967     global $CONF;\r
1968 \r
1969     // normal\r
1970     $document = 'document';\r
1971     $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
1972     $bookmarkletline .= $CONF['AdminURL'] . "bookmarklet.php?blogid=$blogid";\r
1973     $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
1974 \r
1975     return $bookmarkletline;\r
1976 }\r
1977 // END: functions from the end of file ADMIN.php\r
1978 \r
1979 /**\r
1980  * Returns a variable or null if not set\r
1981  *\r
1982  * @param mixed Variable\r
1983  * @return mixed Variable\r
1984  */\r
1985 function ifset(&$var) {\r
1986     if (isset($var)) {\r
1987         return $var;\r
1988     }\r
1989 \r
1990     return null;\r
1991 }\r
1992 \r
1993 /**\r
1994  * Returns number of subscriber to an event\r
1995  *\r
1996  * @param event\r
1997  * @return number of subscriber(s)\r
1998  */\r
1999 function numberOfEventSubscriber($event) {\r
2000     $query = 'SELECT COUNT(*) as count FROM ' . sql_table('plugin_event') . ' WHERE event=\'' . $event . '\'';\r
2001     $res = sql_query($query);\r
2002     $obj = sql_fetch_object($res);\r
2003     return $obj->count;\r
2004 }\r
2005 \r
2006 /**\r
2007  * sets $special global variable for use in index.php before selector()\r
2008  *\r
2009  * @param String id\r
2010  * @return nothing\r
2011  */\r
2012 function selectSpecialSkinType($id) {\r
2013     global $special;\r
2014     $special = strtolower($id);\r
2015 }\r
2016 \r
2017 /**\r
2018  * cleans filename of uploaded file for writing to file system\r
2019  *\r
2020  * @param String str\r
2021  * @return String cleaned filename ready for use\r
2022  */\r
2023 function cleanFileName($str) {\r
2024         $str = strtolower($str);\r
2025         $ext_point = i18n::strrpos($str,".");\r
2026         if ($ext_point===false) return false;\r
2027         $ext = i18n::substr($str,$ext_point,i18n::strlen($str));\r
2028         $str = i18n::substr($str,0,$ext_point);\r
2029 \r
2030         return preg_replace("/[^a-z0-9-]/","_",$str).$ext;\r
2031 }\r
2032 \r
2033 /**\r
2034  * Centralisation of the functions to send mail\r
2035  * Deprecated since 4.0:\r
2036  * Please use functions in NOTIFICATION class instead\r
2037  */\r
2038 function getMailFooter()\r
2039 {\r
2040         NOTIFICATION::get_mail_footer();\r
2041 }\r
2042 function isValidMailAddress($address)\r
2043 {\r
2044         return NOTIFICATION::address_validation($address);\r
2045 }\r
2046 /**\r
2047  * Centralisation of the functions that deals XML entities\r
2048  * Deprecated since 4.0:\r
2049  * Please use ENTITY::FunctionName(...) instead\r
2050  */\r
2051 function highlight($text, $expression, $highlight)\r
2052 {\r
2053         return ENTITY::highlight($text, $expression, $highlight);\r
2054 }\r
2055 function shorten($string, $maxlength, $suffix)\r
2056 {\r
2057         return ENTITY::shorten($string, $maxlength, $suffix);\r
2058 }\r
2059 function stringStripTags ($string)\r
2060 {\r
2061         return ENTITY::strip_tags($string);\r
2062 }\r
2063 function toAscii($string)\r
2064 {\r
2065         return ENTITY::anchor_footnoting($string);\r
2066 }\r
2067 function stringToAttribute ($string)\r
2068 {\r
2069         return ENTITY::hsc($string);\r
2070 }\r
2071 function stringToXML ($string)\r
2072 {\r
2073         return ENTITY::hen($string);\r
2074 }\r
2075 function encode_desc($data)\r
2076 {\r
2077         return ENTITY::hen($data);\r
2078 }\r
2079 /**\r
2080  * Centralisation of the functions that deals with locales\r
2081  * This functions is based on the old way to deal with languages\r
2082  * Deprecated since 4.0:\r
2083  */\r
2084 /* NOTE: use i18n::get_current_locale() directly instead of this */\r
2085 function getLanguageName()\r
2086 {\r
2087         if( ($language = i18n::convert_locale_to_old_language_file_name(i18n::get_current_locale())) === FALSE )\r
2088         {\r
2089                 $language ='english';\r
2090         }\r
2091         return $language;\r
2092 }\r
2093 \r
2094 /* NOTE: use i18n::get_available_locales() directly instead of this */\r
2095 function checkLanguage($lang)\r
2096 {\r
2097         return ( preg_match('#^(.+)_(.+)_(.+)$#', $lang)\r
2098           || i18n::convert_old_language_file_name_to_locale($lang) );\r
2099 }\r
2100 /* NOTE: use i18n::formatted_datetime() directly instead of this */\r
2101 function formatDate($format, $timestamp, $default_format, &$blog)\r
2102 {\r
2103         $offset = date('Z', $timestamp);\r
2104         if ( $blog )\r
2105         {\r
2106                 $offset += $blog->getTimeOffset() * 3600;\r
2107         }\r
2108         return i18n::formatted_datetime($format, $timestamp, $offset, $default_format);\r
2109 }\r
2110 /* NOTE: use i18n::formatted_datetime() directly instead of this */\r
2111 function mysqldate($timestamp)\r
2112 {\r
2113         return '"' . i18n::formatted_datetime('mysql', $timestamp) . '"';\r
2114 }\r
2115 /**\r
2116  * Centralisation of the functions that generate links\r
2117  * Deprecated since 4.0:\r
2118  * Please use LINK::FunctionName(...) instead\r
2119  */\r
2120 function createItemLink($itemid, $extra = '')\r
2121 {\r
2122         return LINK::create_item_link($itemid, $extra);\r
2123 }\r
2124 function createMemberLink($memberid, $extra = '')\r
2125 {\r
2126         return LINK::create_member_link($memberid, $extra);\r
2127 }\r
2128 function createCategoryLink($catid, $extra = '')\r
2129 {\r
2130         return LINK::create_category_link($catid, $extra);\r
2131 }\r
2132 function createArchiveListLink($blogid = '', $extra = '')\r
2133 {\r
2134         return LINK::create_archivelist_link($blogid, $extra);\r
2135 }\r
2136 function createArchiveLink($blogid, $archive, $extra = '')\r
2137 {\r
2138         return LINK::create_archive_link($blogid, $archive, $extra);\r
2139 }\r
2140 function createBlogidLink($blogid, $params = '')\r
2141 {\r
2142         return LINK::create_blogid_link($blogid, $params = '');\r
2143 }\r
2144 function createLink($type, $params)\r
2145 {\r
2146         return LINK::create_link($type, $params);\r
2147 }\r
2148 function createBlogLink($url, $params)\r
2149 {\r
2150         return LINK::create_blog_link($url, $params);\r
2151 }\r