OSDN Git Service

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