OSDN Git Service

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