4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
\r
5 * Copyright (C) 2002-2011 The Nucleus Group
\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
14 * @license http://nucleuscms.org/license.txt GNU General Public License
\r
15 * @copyright Copyright (C) 2002-2011 The Nucleus Group
\r
17 * $NucleusJP: globalfunctions.php,v 1.23.2.7 2008/02/05 08:30:08 kimitake Exp $
\r
20 // needed if we include globalfunctions from install.php
\r
21 global $nucleus, $CONF, $DIR_LIBS, $DIR_LANG, $manager, $member;
\r
23 $nucleus['version'] = 'v3.62';
\r
24 $nucleus['codename'] = '';
\r
26 // check and die if someone is trying to override internal globals (when register_globals turn on)
\r
27 checkVars(array('nucleus', 'CONF', 'DIR_LIBS', 'MYSQL_HOST', 'MYSQL_USER', 'MYSQL_PASSWORD', 'MYSQL_DATABASE', 'DIR_LANG', 'DIR_PLUGINS', 'HTTP_GET_VARS', 'HTTP_POST_VARS', 'HTTP_COOKIE_VARS', 'HTTP_ENV_VARS', 'HTTP_SESSION_VARS', 'HTTP_POST_FILES', 'HTTP_SERVER_VARS', 'GLOBALS', 'argv', 'argc', '_GET', '_POST', '_COOKIE', '_ENV', '_SESSION', '_SERVER', '_FILES'));
\r
30 if ($CONF['debug']) {
\r
31 error_reporting(E_ALL); // report all errors!
\r
33 ini_set('display_errors','0');
\r
34 error_reporting(E_ERROR | E_WARNING | E_PARSE);
\r
38 * Set default time zone
\r
39 * By Japanese Packaging Team, Jan.27, 2011
\r
40 * For private server which has no condition for default time zone
\r
43 if (function_exists('date_default_timezone_get')) {
\r
44 if (FALSE == ($timezone = @date_default_timezone_get())) {
\r
48 if (function_exists('date_default_timezone_set')) {
\r
49 @date_default_timezone_set($timezone);
\r
53 Indicates when Nucleus should display startup errors. Set to 1 if you want
\r
54 the error enabled (default), false otherwise
\r
57 Displays an error when visiting a public Nucleus page and headers have
\r
58 been sent out to early. This usually indicates an error in either a
\r
59 configuration file or a language file, and could cause Nucleus to
\r
62 Displays an error only when visiting the admin area, and when one or
\r
63 more of the installation files (install.php, install.sql, upgrades/
\r
64 directory) are still on the server.
\r
67 $CONF['alertOnHeadersSent'] = 1;
\r
68 $CONF['alertOnSecurityRisk'] = 1;
\r
69 /*$CONF['ItemURL'] = $CONF['Self'];
\r
70 $CONF['ArchiveURL'] = $CONF['Self'];
\r
71 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
72 $CONF['MemberURL'] = $CONF['Self'];
\r
73 $CONF['SearchURL'] = $CONF['Self'];
\r
74 $CONF['BlogURL'] = $CONF['Self'];
\r
75 $CONF['CategoryURL'] = $CONF['Self'];
\r
77 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
78 // this avoids urls like index.php/item/13/index.php/item/15
\r
79 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
\r
80 $CONF['URLMode'] = 'normal';
\r
84 Set these to 1 to allow viewing of future items or draft items
\r
85 Should really never do this, but can be useful for some plugins that might need to
\r
86 Could cause some other issues if you use future posts otr drafts
\r
89 $CONF['allowDrafts'] = 0;
\r
90 $CONF['allowFuture'] = 0;
\r
92 if (getNucleusPatchLevel() > 0) {
\r
93 $nucleus['version'] .= '/' . getNucleusPatchLevel();
\r
97 if (!isset($CONF['installscript'])) {
\r
98 $CONF['installscript'] = 0;
\r
102 * Include multibyte function if some functions related to mbstring are not loaded.
\r
103 * By Japanese Packaging Team, Jan.31, 2011
\r
105 if (!function_exists('mb_convert_encoding')){
\r
106 global $mbemu_internals;
\r
107 include_once($DIR_LIBS.'mb_emulator/mb-emulator.php');
\r
110 // we will use postVar, getVar, ... methods instead of HTTP_GET_VARS or _GET
\r
111 if ($CONF['installscript'] != 1) { // vars were already included in install.php
\r
112 if (phpversion() >= '4.1.0') {
\r
113 include_once($DIR_LIBS . 'vars4.1.0.php');
\r
115 include_once($DIR_LIBS . 'vars4.0.6.php');
\r
120 $bLoggingSanitizedResult=0;
\r
121 $bSanitizeAndContinue=0;
\r
123 $orgRequestURI = serverVar('REQUEST_URI');
\r
126 // get all variables that can come from the request and put them in the global scope
\r
127 $blogid = requestVar('blogid');
\r
128 $itemid = intRequestVar('itemid');
\r
129 $catid = intRequestVar('catid');
\r
130 $skinid = requestVar('skinid');
\r
131 $memberid = requestVar('memberid');
\r
132 $archivelist = requestVar('archivelist');
\r
133 $imagepopup = requestVar('imagepopup');
\r
134 $archive = requestVar('archive');
\r
135 $query = requestVar('query');
\r
136 $highlight = requestVar('highlight');
\r
137 $amount = requestVar('amount');
\r
138 $action = requestVar('action');
\r
139 $nextaction = requestVar('nextaction');
\r
140 $maxresults = requestVar('maxresults');
\r
141 $startpos = intRequestVar('startpos');
\r
142 $errormessage = '';
\r
144 $special = requestVar('special');
\r
145 $virtualpath = ((getVar('virtualpath') != null) ? getVar('virtualpath') : serverVar('PATH_INFO'));
\r
147 if (!headers_sent() ) {
\r
148 header('Generator: Nucleus CMS ' . $nucleus['version']);
\r
151 // include core classes that are needed for login & plugin handling
\r
152 include_once($DIR_LIBS . 'mysql.php');
\r
153 // added for 3.5 sql_* wrapper
\r
154 global $MYSQL_HANDLER;
\r
155 if (!isset($MYSQL_HANDLER))
\r
156 $MYSQL_HANDLER = array('mysql','');
\r
157 if ($MYSQL_HANDLER[0] == '')
\r
158 $MYSQL_HANDLER[0] = 'mysql';
\r
159 include_once($DIR_LIBS . 'sql/'.$MYSQL_HANDLER[0].'.php');
\r
160 // end new for 3.5 sql_* wrapper
\r
161 include($DIR_LIBS . 'MEMBER.php');
\r
162 include($DIR_LIBS . 'ACTIONLOG.php');
\r
163 include($DIR_LIBS . 'MANAGER.php');
\r
164 include($DIR_LIBS . 'PLUGIN.php');
\r
166 $manager =& MANAGER::instance();
\r
168 // make sure there's no unnecessary escaping:
\r
169 //set_magic_quotes_runtime(0);
\r
170 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
\r
171 ini_set('magic_quotes_runtime', '0');
\r
175 if (!isset($CONF['UsingAdminArea'])) {
\r
176 $CONF['UsingAdminArea'] = 0;
\r
179 // only needed when updating logs
\r
180 if ($CONF['UsingAdminArea']) {
\r
181 include($DIR_LIBS . 'xmlrpc.inc.php'); // XML-RPC client classes
\r
182 include_once($DIR_LIBS . 'ADMIN.php');
\r
185 // connect to database
\r
189 // logs sanitized result if need
\r
190 if ($orgRequestURI!==serverVar('REQUEST_URI')) {
\r
191 $msg = "Sanitized [" . serverVar('REMOTE_ADDR') . "] ";
\r
192 $msg .= $orgRequestURI . " -> " . serverVar('REQUEST_URI');
\r
193 if ($bLoggingSanitizedResult) {
\r
194 addToLog(WARNING, $msg);
\r
196 if (!$bSanitizeAndContinue) {
\r
201 // makes sure database connection gets closed on script termination
\r
202 register_shutdown_function('sql_disconnect');
\r
207 // Properly set $CONF['Self'] and others if it's not set... usually when we are access from admin menu
\r
208 if (!isset($CONF['Self'])) {
\r
209 $CONF['Self'] = $CONF['IndexURL'];
\r
210 // strip trailing /
\r
211 if ($CONF['Self'][strlen($CONF['Self']) -1] == "/") {
\r
212 $CONF['Self'] = substr($CONF['Self'], 0, strlen($CONF['Self']) -1);
\r
215 /* $CONF['ItemURL'] = $CONF['Self'];
\r
216 $CONF['ArchiveURL'] = $CONF['Self'];
\r
217 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
218 $CONF['MemberURL'] = $CONF['Self'];
\r
219 $CONF['SearchURL'] = $CONF['Self'];
\r
220 $CONF['BlogURL'] = $CONF['Self'];
\r
221 $CONF['CategoryURL'] = $CONF['Self'];*/
\r
224 $CONF['ItemURL'] = $CONF['Self'];
\r
225 $CONF['ArchiveURL'] = $CONF['Self'];
\r
226 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
227 $CONF['MemberURL'] = $CONF['Self'];
\r
228 $CONF['SearchURL'] = $CONF['Self'];
\r
229 $CONF['BlogURL'] = $CONF['Self'];
\r
230 $CONF['CategoryURL'] = $CONF['Self'];
\r
232 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
233 // this avoids urls like index.php/item/13/index.php/item/15
\r
234 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
\r
235 $CONF['URLMode'] = 'normal';
\r
238 // automatically use simpler toolbar for mozilla
\r
239 if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'), 'Gecko') ) {
\r
240 $CONF['DisableJsTools'] = 2;
\r
243 // login if cookies set
\r
244 $member = new MEMBER();
\r
246 // secure cookie key settings (either 'none', 0, 8, 16, 24, or 32)
\r
247 if (!isset($CONF['secureCookieKey'])) $CONF['secureCookieKey']=24;
\r
248 switch($CONF['secureCookieKey']){
\r
250 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
253 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
256 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
259 $CONF['secureCookieKeyIP']=serverVar('REMOTE_ADDR');
\r
262 $CONF['secureCookieKeyIP']='';
\r
265 // login/logout when required or renew cookies
\r
266 if ($action == 'login') {
\r
267 // Form Authentication
\r
268 $login = postVar('login');
\r
269 $pw = postVar('password');
\r
270 $shared = intPostVar('shared'); // shared computer or not
\r
272 $pw=substr($pw,0,40); // avoid md5 collision by using a long key
\r
274 if ($member->login($login, $pw) ) {
\r
276 $member->newCookieKey();
\r
277 $member->setCookies($shared);
\r
279 if ($CONF['secureCookieKey']!=='none') {
\r
280 // secure cookie key
\r
281 $member->setCookieKey(md5($member->getCookieKey().$CONF['secureCookieKeyIP']));
\r
285 // allows direct access to parts of the admin area after logging in
\r
287 $action = $nextaction;
\r
290 $manager->notify('LoginSuccess', array('member' => &$member, 'username' => $login) );
\r
291 $errormessage = '';
\r
292 ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");
\r
294 // errormessage for [%errordiv%]
\r
295 $trimlogin = trim($login);
\r
296 if (empty($trimlogin))
\r
298 $errormessage = "Please enter a username.";
\r
302 $errormessage = 'Login failed for ' . $login;
\r
304 $manager->notify('LoginFailed', array('username' => $login) );
\r
305 ACTIONLOG::add(INFO, $errormessage);
\r
309 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
311 } elseif (serverVar('PHP_AUTH_USER') && serverVar('PHP_AUTH_PW')) {
\r
312 // HTTP Authentication
\r
313 $login = serverVar('PHP_AUTH_USER');
\r
314 $pw = serverVar('PHP_AUTH_PW');
\r
316 if ($member->login($login, $pw) ) {
\r
317 $manager->notify('LoginSuccess',array('member' => &$member));
\r
318 ACTIONLOG::add(INFO, "HTTP authentication successful for $login");
\r
320 $manager->notify('LoginFailed',array('username' => $login));
\r
321 ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);
\r
323 //Since bad credentials, generate an apropriate error page
\r
324 header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");
\r
325 header('HTTP/1.0 401 Unauthorized');
\r
326 echo 'Invalid username or password';
\r
331 } elseif (($action == 'logout') && (!headers_sent() ) && cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
332 // remove cookies on logout
\r
333 setcookie($CONF['CookiePrefix'] . 'user', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
334 setcookie($CONF['CookiePrefix'] . 'loginkey', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
335 $manager->notify('Logout', array('username' => cookieVar($CONF['CookiePrefix'] . 'user') ) );
\r
336 } elseif (cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
337 // Cookie Authentication
\r
338 $ck=cookieVar($CONF['CookiePrefix'] . 'loginkey');
\r
339 // secure cookie key
\r
340 $ck=substr($ck,0,32); // avoid md5 collision by using a long key
\r
341 if ($CONF['secureCookieKey']!=='none') $ck=md5($ck.$CONF['secureCookieKeyIP']);
\r
342 $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), $ck );
\r
345 // renew cookies when not on a shared computer
\r
346 if ($res && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) && (!headers_sent() ) ) {
\r
347 $member->setCookieKey(cookieVar($CONF['CookiePrefix'] . 'loginkey'));
\r
348 $member->setCookies();
\r
353 $manager->notify('PostAuthentication', array('loggedIn' => $member->isLoggedIn() ) );
\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 redirect($CONF['DisableSiteURL']);
\r
362 // load other classes
\r
363 include($DIR_LIBS . 'PARSER.php');
\r
364 include($DIR_LIBS . 'SKIN.php');
\r
365 include($DIR_LIBS . 'TEMPLATE.php');
\r
366 include($DIR_LIBS . 'BLOG.php');
\r
367 include($DIR_LIBS . 'BODYACTIONS.php');
\r
368 include($DIR_LIBS . 'COMMENTS.php');
\r
369 include($DIR_LIBS . 'COMMENT.php');
\r
370 //include($DIR_LIBS . 'ITEM.php');
\r
371 include($DIR_LIBS . 'NOTIFICATION.php');
\r
372 include($DIR_LIBS . 'BAN.php');
\r
373 include($DIR_LIBS . 'PAGEFACTORY.php');
\r
374 include($DIR_LIBS . 'SEARCH.php');
\r
375 include($DIR_LIBS . 'entity.php');
\r
378 // set lastVisit cookie (if allowed)
\r
379 if (!headers_sent() ) {
\r
380 if ($CONF['LastVisit']) {
\r
381 setcookie($CONF['CookiePrefix'] . 'lastVisit', time(), time() + 2592000, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
383 setcookie($CONF['CookiePrefix'] . 'lastVisit', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
387 // read language file, only after user has been initialized
\r
388 $language = getLanguageName();
\r
390 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
391 # original ereg_replace: ereg_replace( '[\\|/]', '', $language) . '.php')
\r
392 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
393 include($DIR_LANG . preg_replace('#[\\\\|/]#', '', $language) . '.php');
\r
395 // check if valid charset
\r
396 if (!encoding_check(false, false, _CHARSET)) {
\r
397 foreach(array($_GET, $_POST) as $input) {
\r
398 array_walk($input, 'encoding_check');
\r
403 * for preventing I/O strings from auto-detecting the charactor encodings by MySQL
\r
404 * since 3.62_beta-jp
\r
405 * Jan.20, 2011 by kotorisan and cacher
\r
406 * refering to their conversation below,
\r
407 * http://japan.nucleuscms.org/bb/viewtopic.php?p=26581
\r
409 * NOTE: shift_jis is only supported for output. Using shift_jis in DB is prohibited.
\r
410 * NOTE: iso-8859-x,windows-125x if _CHARSET is unset.
\r
412 if (in_array('mysql',$MYSQL_HANDLER)) {
\r
413 switch(strtolower(_CHARSET)){
\r
421 $charset = 'gb2312';
\r
427 $resource = sql_query("show variables LIKE 'character_set_database'");
\r
428 $fetchDat = sql_fetch_assoc($resource);
\r
429 $charset = $fetchDat['Value'];
\r
432 $mySqlVer = implode('.', array_map('intval', explode('.', sql_get_server_info($MYSQL_CONN))));
\r
433 if ($mySqlVer >= '5.0.7' && function_exists('mysql_set_charset')) {
\r
434 mysql_set_charset($charset);
\r
435 } elseif ($mySqlVer >= '4.1.0') {
\r
436 sql_query("SET CHARACTER SET " . $charset);
\r
441 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
443 // To remove after v2.5 is released and language files have been updated.
\r
444 // Including this makes sure that language files for v2.5beta can still be used for v2.5final
\r
445 // without having weird _SETTINGS_EXTAUTH string showing up in the admin area.
\r
446 if (!defined('_MEMBERS_BYPASS'))
\r
448 define('_SETTINGS_EXTAUTH', 'Enable External Authentication');
\r
449 define('_WARNING_EXTAUTH', 'Warning: Enable only if needed.');
\r
450 define('_MEMBERS_BYPASS', 'Use External Authentication');
\r
455 // make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined
\r
456 if (!defined('_ARCHIVETYPE_MONTH') )
\r
458 define('_ARCHIVETYPE_DAY', 'day');
\r
459 define('_ARCHIVETYPE_MONTH', 'month');
\r
460 define('_ARCHIVETYPE_YEAR', 'year');
\r
463 // decode path_info
\r
464 if ($CONF['URLMode'] == 'pathinfo') {
\r
465 // initialize keywords if this hasn't been done before
\r
466 if (!isset($CONF['ItemKey']) || $CONF['ItemKey'] == '') {
\r
467 $CONF['ItemKey'] = 'item';
\r
470 if (!isset($CONF['ArchiveKey']) || $CONF['ArchiveKey'] == '') {
\r
471 $CONF['ArchiveKey'] = 'archive';
\r
474 if (!isset($CONF['ArchivesKey']) || $CONF['ArchivesKey'] == '') {
\r
475 $CONF['ArchivesKey'] = 'archives';
\r
478 if (!isset($CONF['MemberKey']) || $CONF['MemberKey'] == '') {
\r
479 $CONF['MemberKey'] = 'member';
\r
482 if (!isset($CONF['BlogKey']) || $CONF['BlogKey'] == '') {
\r
483 $CONF['BlogKey'] = 'blog';
\r
486 if (!isset($CONF['CategoryKey']) || $CONF['CategoryKey'] == '') {
\r
487 $CONF['CategoryKey'] = 'category';
\r
490 if (!isset($CONF['SpecialskinKey']) || $CONF['SpecialskinKey'] == '') {
\r
491 $CONF['SpecialskinKey'] = 'special';
\r
498 'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...
\r
499 'info' => $virtualpath,
\r
500 'complete' => &$parsed
\r
505 // default implementation
\r
506 $data = explode("/", $virtualpath );
\r
507 for ($i = 0; $i < sizeof($data); $i++) {
\r
508 switch ($data[$i]) {
\r
509 case $CONF['ItemKey']: // item/1 (blogid)
\r
512 if ($i < sizeof($data) ) {
\r
513 $itemid = intval($data[$i]);
\r
517 case $CONF['ArchivesKey']: // archives/1 (blogid)
\r
520 if ($i < sizeof($data) ) {
\r
521 $archivelist = intval($data[$i]);
\r
525 case $CONF['ArchiveKey']: // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)
\r
526 if ((($i + 1) < sizeof($data) ) && (!strstr($data[$i + 1], '-') ) ) {
\r
527 $blogid = intval($data[++$i]);
\r
532 if ($i < sizeof($data) ) {
\r
533 $archive = $data[$i];
\r
537 case 'blogid': // blogid/1
\r
538 case $CONF['BlogKey']: // blog/1
\r
541 if ($i < sizeof($data) ) {
\r
542 $blogid = intval($data[$i]);
\r
546 case $CONF['CategoryKey']: // category/1 (catid)
\r
550 if ($i < sizeof($data) ) {
\r
551 $catid = intval($data[$i]);
\r
555 case $CONF['MemberKey']:
\r
558 if ($i < sizeof($data) ) {
\r
559 $memberid = intval($data[$i]);
\r
563 case $CONF['SpecialskinKey']:
\r
566 if ($i < sizeof($data) ) {
\r
567 $special = $data[$i];
\r
568 $_REQUEST['special'] = $special;
\r
578 /* PostParseURL is a place to cleanup any of the path-related global variables before the selector function is run.
\r
579 It has 2 values in the data in case the original virtualpath is needed, but most the use will be in tweaking
\r
580 global variables to clean up (scrub out catid or add catid) or to set someother global variable based on
\r
581 the values of something like catid or itemid
\r
587 'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...
\r
588 'info' => $virtualpath
\r
592 function include_libs($file,$once=true,$require=true){
\r
594 if (!is_dir($DIR_LIBS)) exit;
\r
595 if ($once && $require) require_once($DIR_LIBS.$file);
\r
596 elseif ($once && !$require) include_once($DIR_LIBS.$file);
\r
597 elseif ($require) require($DIR_LIBS.$file);
\r
598 else include($DIR_LIBS.$file);
\r
601 function include_plugins($file,$once=true,$require=true){
\r
602 global $DIR_PLUGINS;
\r
603 if (!is_dir($DIR_PLUGINS)) exit;
\r
604 if ($once && $require) require_once($DIR_PLUGINS.$file);
\r
605 elseif ($once && !$require) include_once($DIR_PLUGINS.$file);
\r
606 elseif ($require) require($DIR_PLUGINS.$file);
\r
607 else include($DIR_PLUGINS.$file);
\r
610 function intPostVar($name) {
\r
611 return intval(postVar($name) );
\r
614 function intGetVar($name) {
\r
615 return intval(getVar($name) );
\r
618 function intRequestVar($name) {
\r
619 return intval(requestVar($name) );
\r
622 function intCookieVar($name) {
\r
623 return intval(cookieVar($name) );
\r
627 * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)
\r
629 function getNucleusVersion() {
\r
634 * power users can install patches in between nucleus releases. These patches
\r
635 * usually add new functionality in the plugin API and allow those to
\r
636 * be tested without having to install CVS.
\r
638 function getNucleusPatchLevel() {
\r
643 * returns the latest version available for download from nucleuscms.org
\r
644 * or false if unable to attain data
\r
645 * format will be major.minor/patachlevel
\r
646 * e.g. 3.41 or 3.41/02
\r
648 function getLatestVersion() {
\r
649 if (!function_exists('curl_init')) return false;
\r
650 $crl = curl_init();
\r
652 curl_setopt ($crl, CURLOPT_URL,'http://nucleuscms.org/version_check.php');
\r
653 curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);
\r
654 curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);
\r
655 $ret = curl_exec($crl);
\r
662 * Connects to mysql server
\r
664 /* moved to $DIR_LIBS/sql/*.php handler files
\r
665 function sql_connect() {
\r
666 global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE, $MYSQL_CONN;
\r
668 $MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>', 'Connect Error');
\r
669 mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: ' . mysql_error() . '</p>', 'Connect Error');
\r
671 return $MYSQL_CONN;
\r
675 * returns a prefixed nucleus table name
\r
677 function sql_table($name) {
\r
678 global $MYSQL_PREFIX;
\r
680 if ($MYSQL_PREFIX) {
\r
681 return $MYSQL_PREFIX . 'nucleus_' . $name;
\r
683 return 'nucleus_' . $name;
\r
687 function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
\r
688 global $manager, $CONF;
\r
690 if (!headers_sent() ) {
\r
691 // if content type is application/xhtml+xml, only send it to browsers
\r
692 // that can handle it (IE6 cannot). Otherwise, send text/html
\r
694 // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)
\r
695 // application/xhtml+xml still causes too much problems with the javascript implementations
\r
697 // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,
\r
698 // application/xhtml+xml seems to be working, so we're going to use it if we can.
\r
700 // Note: reverted the following function in JP version
\r
705 ($contenttype == 'application/xhtml+xml')
\r
706 && (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )
\r
708 $contenttype = 'text/html';
\r
713 ($contenttype == 'application/xhtml+xml')
\r
714 && (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))
\r
717 $contenttype = 'text/html';
\r
721 'PreSendContentType',
\r
723 'contentType' => &$contenttype,
\r
724 'charset' => &$charset,
\r
725 'pageType' => $pagetype
\r
729 // strip strange characters
\r
730 $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);
\r
731 $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);
\r
733 if ($charset != '') {
\r
734 header('Content-Type: ' . $contenttype . '; charset=' . $charset);
\r
736 header('Content-Type: ' . $contenttype);
\r
739 // check if valid charset
\r
740 if (!encoding_check(false,false,$charset)) {
\r
741 foreach(array($_GET, $_POST) as $input) {
\r
742 array_walk($input, 'encoding_check');
\r
749 * Errors before the database connection has been made - moved to
\r
751 /* moved to $DIR_LIBS/sql/*.php handler files
\r
752 function startUpError($msg, $title) {
\r
753 if (!defined('_CHARSET')) define('_CHARSET', 'iso-8859-1');
\r
754 header('Content-Type: text/html; charset=' . _CHARSET);
\r
756 <html <?php echo _HTML_XML_NAME_SPACE_AND_LANG_CODE; ?>>
\r
757 <head><meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET?>" />
\r
758 <title><?php echo htmlspecialchars($title)?></title></head>
\r
760 <h1><?php echo htmlspecialchars($title)?></h1>
\r
768 * disconnects from SQL server
\r
770 /* moved to $DIR_LIBS/sql/*.php handler files
\r
771 function sql_disconnect() {
\r
776 * executes an SQL query
\r
778 /* moved to $DIR_LIBS/sql/*.php handler files
\r
779 function sql_query($query) {
\r
782 $res = mysql_query($query) or print("mySQL error with query $query: " . mysql_error() . '<p />');
\r
787 * Highlights a specific query in a given HTML text (not within HTML tags) and returns it
\r
788 * @param string $text text to be highlighted
\r
789 * @param string $expression regular expression to be matched (can be an array of expressions as well)
\r
790 * @param string $highlight highlight to be used (use \\0 to indicate the matched expression)
\r
793 function highlight($text, $expression, $highlight) {
\r
794 if (!$highlight || !$expression)
\r
799 if (is_array($expression) && (count($expression) == 0) )
\r
804 // add a tag in front (is needed for preg_match_all to work correct)
\r
805 $text = '<!--h-->' . $text;
\r
807 // split the HTML up so we have HTML tags
\r
808 // $matches[0][i] = HTML + text
\r
809 // $matches[1][i] = HTML
\r
810 // $matches[2][i] = text
\r
811 preg_match_all('/(<[^>]+>)([^<>]*)/', $text, $matches);
\r
813 // throw it all together again while applying the highlight to the text pieces
\r
815 $count_matches = count($matches[2]);
\r
816 for ($i = 0; $i < $count_matches; $i++) {
\r
819 $result .= $matches[1][$i];
\r
822 if (is_array($expression) )
\r
824 foreach ($expression as $regex)
\r
828 //$matches[2][$i] = @eregi_replace($regex, $highlight, $matches[2][$i]);
\r
829 $matches[2][$i] = @preg_replace("#".$regex."#i", $highlight, $matches[2][$i]);
\r
833 $result .= $matches[2][$i];
\r
837 //$result .= @eregi_replace($expression, $highlight, $matches[2][$i]);
\r
838 $result .= @preg_replace("#".$expression."#i", $highlight, $matches[2][$i]);
\r
846 * Parses a query into an array of expressions that can be passed on to the highlight method
\r
848 function parseHighlight($query) {
\r
849 // TODO: add more intelligent splitting logic
\r
851 // get rid of quotes
\r
852 $query = preg_replace('/\'|"/', '', $query);
\r
858 $aHighlight = explode(' ', $query);
\r
860 for ($i = 0; $i < count($aHighlight); $i++) {
\r
861 $aHighlight[$i] = trim($aHighlight[$i]);
\r
863 // if (strlen($aHighlight[$i]) < 3) {
\r
864 // unset($aHighlight[$i]);
\r
868 if (count($aHighlight) == 1) {
\r
869 return $aHighlight[0];
\r
871 return $aHighlight;
\r
876 * Checks if email address is valid
\r
878 function isValidMailAddress($address) {
\r
879 // enhancement made in 3.6x based on code by Quandary.
\r
880 if (preg_match('/^(?!\\.)(?:\\.?[-a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~]+)+@(?!\\.)(?:\\.?(?!-)[-a-zA-Z0-9]+(?<!-)){2,}$/', $address)) {
\r
887 // some helper functions
\r
888 function getBlogIDFromName($name) {
\r
889 return quickQuery('SELECT bnumber as result FROM ' . sql_table('blog') . ' WHERE bshortname="' . sql_real_escape_string($name) . '"');
\r
892 function getBlogNameFromID($id) {
\r
893 return quickQuery('SELECT bname as result FROM ' . sql_table('blog') . ' WHERE bnumber=' . intval($id) );
\r
896 function getBlogIDFromItemID($itemid) {
\r
897 return quickQuery('SELECT iblog as result FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid) );
\r
900 function getBlogIDFromCommentID($commentid) {
\r
901 return quickQuery('SELECT cblog as result FROM ' . sql_table('comment') . ' WHERE cnumber=' . intval($commentid) );
\r
904 function getBlogIDFromCatID($catid) {
\r
905 return quickQuery('SELECT cblog as result FROM ' . sql_table('category') . ' WHERE catid=' . intval($catid) );
\r
908 function getCatIDFromName($name) {
\r
909 return quickQuery('SELECT catid as result FROM ' . sql_table('category') . ' WHERE cname="' . sql_real_escape_string($name) . '"');
\r
912 function quickQuery($q) {
\r
913 $res = sql_query($q);
\r
914 $obj = sql_fetch_object($res);
\r
915 return $obj->result;
\r
918 function getPluginNameFromPid($pid) {
\r
919 $res = sql_query('SELECT pfile FROM ' . sql_table('plugin') . ' WHERE pid=' . intval($pid) );
\r
920 $obj = sql_fetch_object($res);
\r
921 return $obj->pfile;
\r
924 function selector() {
\r
925 global $itemid, $blogid, $memberid, $query, $amount, $archivelist, $maxresults;
\r
926 global $archive, $skinid, $blog, $memberinfo, $CONF, $member;
\r
927 global $imagepopup, $catid, $special;
\r
930 $actionNames = array('addcomment', 'sendmessage', 'createaccount', 'forgotpassword', 'votepositive', 'votenegative', 'plugin');
\r
931 $action = requestVar('action');
\r
933 if (in_array($action, $actionNames) ) {
\r
934 global $DIR_LIBS, $errormessage;
\r
935 include_once($DIR_LIBS . 'ACTION.php');
\r
937 $errorInfo = $a->doAction($action);
\r
940 $errormessage = $errorInfo['message'];
\r
944 // show error when headers already sent out
\r
945 if (headers_sent() && $CONF['alertOnHeadersSent']) {
\r
947 // try to get line number/filename (extra headers_sent params only exists in PHP 4.3+)
\r
948 if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=') ) {
\r
949 headers_sent($hsFile, $hsLine);
\r
950 $extraInfo = sprintf(_GFUNCTIONS_HEADERSALREADYSENT_FILE,$hsFile,$hsLine);
\r
956 sprintf(_GFUNCTIONS_HEADERSALREADYSENT_TXT,$extraInfo),
\r
957 _GFUNCTIONS_HEADERSALREADYSENT_TITLE
\r
962 // make is so ?archivelist without blogname or blogid shows the archivelist
\r
963 // for the default weblog
\r
964 if (serverVar('QUERY_STRING') == 'archivelist') {
\r
965 $archivelist = $CONF['DefaultBlog'];
\r
968 // now decide which type of skin we need
\r
970 // itemid given -> only show that item
\r
973 if (!$manager->existsItem($itemid,intval($CONF['allowFuture']),intval($CONF['allowDrafts']))) {
\r
974 doError(_ERROR_NOSUCHITEM);
\r
977 global $itemidprev, $itemidnext, $catid, $itemtitlenext, $itemtitleprev;
\r
979 // 1. get timestamp, blogid and catid for item
\r
980 $query = 'SELECT itime, iblog, icat FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid);
\r
981 $res = sql_query($query);
\r
982 $obj = sql_fetch_object($res);
\r
984 // if a different blog id has been set through the request or selectBlog(),
\r
987 if ($blogid && (intval($blogid) != $obj->iblog) ) {
\r
988 if (!headers_sent()) {
\r
989 $b =& $manager->getBlog($obj->iblog);
\r
990 $CONF['ItemURL'] = $b->getURL();
\r
991 if ($CONF['URLMode'] == 'pathinfo' and substr($CONF['ItemURL'],-1) == '/')
\r
992 $CONF['ItemURL'] = substr($CONF['ItemURL'], 0, -1);
\r
993 $correctURL = createItemLink($itemid, '');
\r
994 redirect($correctURL);
\r
997 doError(_ERROR_NOSUCHITEM);
\r
1001 // if a category has been selected which doesn't match the item, ignore the
\r
1003 if (($catid != 0) && ($catid != $obj->icat) ) {
\r
1007 $blogid = $obj->iblog;
\r
1008 $timestamp = strtotime($obj->itime);
\r
1010 $b =& $manager->getBlog($blogid);
\r
1012 if ($b->isValidCategory($catid) ) {
\r
1013 $catextra = ' and icat=' . $catid;
\r
1018 // get previous itemid and title
\r
1019 $query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE itime<' . mysqldate($timestamp) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime DESC LIMIT 1';
\r
1020 $res = sql_query($query);
\r
1022 $obj = sql_fetch_object($res);
\r
1025 $itemidprev = $obj->inumber;
\r
1026 $itemtitleprev = $obj->ititle;
\r
1029 // get next itemid and title
\r
1030 $query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE itime>' . mysqldate($timestamp) . ' and itime <= ' . mysqldate($b->getCorrectTime()) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime ASC LIMIT 1';
\r
1031 $res = sql_query($query);
\r
1033 $obj = sql_fetch_object($res);
\r
1036 $itemidnext = $obj->inumber;
\r
1037 $itemtitlenext = $obj->ititle;
\r
1040 } elseif ($archive) {
\r
1042 $type = 'archive';
\r
1044 // get next and prev month links ...
\r
1045 global $archivenext, $archiveprev, $archivetype, $archivenextexists, $archiveprevexists;
\r
1047 // sql queries for the timestamp of the first and the last published item
\r
1048 $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 AND iblog=".(int)($blogid ? $blogid : $CONF['DefaultBlog'])." ORDER BY itime ASC";
\r
1049 $first_timestamp=quickQuery ($query);
\r
1050 $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 AND iblog=".(int)($blogid ? $blogid : $CONF['DefaultBlog'])." ORDER BY itime DESC";
\r
1051 $last_timestamp=quickQuery ($query);
\r
1053 sscanf($archive, '%d-%d-%d', $y, $m, $d);
\r
1056 $archivetype = _ARCHIVETYPE_DAY;
\r
1057 $t = mktime(0, 0, 0, $m, $d, $y);
\r
1058 // one day has 24 * 60 * 60 = 86400 seconds
\r
1059 $archiveprev = strftime('%Y-%m-%d', $t - 86400 );
\r
1060 // check for published items
\r
1061 if ($t > $first_timestamp) {
\r
1062 $archiveprevexists = true;
\r
1065 $archiveprevexists = false;
\r
1070 $archivenext = strftime('%Y-%m-%d', $t);
\r
1071 if ($t < $last_timestamp) {
\r
1072 $archivenextexists = true;
\r
1075 $archivenextexists = false;
\r
1078 } elseif ($m == 0) {
\r
1079 $archivetype = _ARCHIVETYPE_YEAR;
\r
1080 $t = mktime(0, 0, 0, 12, 31, $y - 1);
\r
1081 // one day before is in the previous year
\r
1082 $archiveprev = strftime('%Y', $t);
\r
1083 if ($t > $first_timestamp) {
\r
1084 $archiveprevexists = true;
\r
1087 $archiveprevexists = false;
\r
1090 // timestamp for the next year
\r
1091 $t = mktime(0, 0, 0, 1, 1, $y + 1);
\r
1092 $archivenext = strftime('%Y', $t);
\r
1093 if ($t < $last_timestamp) {
\r
1094 $archivenextexists = true;
\r
1097 $archivenextexists = false;
\r
1100 $archivetype = _ARCHIVETYPE_MONTH;
\r
1101 $t = mktime(0, 0, 0, $m, 1, $y);
\r
1102 // one day before is in the previous month
\r
1103 $archiveprev = strftime('%Y-%m', $t - 86400);
\r
1104 if ($t > $first_timestamp) {
\r
1105 $archiveprevexists = true;
\r
1108 $archiveprevexists = false;
\r
1111 // timestamp for the next month
\r
1112 $t = mktime(0, 0, 0, $m+1, 1, $y);
\r
1113 $archivenext = strftime('%Y-%m', $t);
\r
1114 if ($t < $last_timestamp) {
\r
1115 $archivenextexists = true;
\r
1118 $archivenextexists = false;
\r
1122 } elseif ($archivelist) {
\r
1123 $type = 'archivelist';
\r
1125 if (is_numeric($archivelist)) {
\r
1126 $blogid = intVal($archivelist);
\r
1128 $blogid = getBlogIDFromName($archivelist);
\r
1132 doError(_ERROR_NOSUCHBLOG);
\r
1135 } elseif ($query) {
\r
1138 $query = stripslashes($query);
\r
1139 if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/", $query)){
\r
1142 // $order = (_CHARSET == 'EUC-JP') ? 'EUC-JP, UTF-8,' : 'UTF-8, EUC-JP,';
\r
1143 // $query = mb_convert_encoding($query, _CHARSET, $order . ' JIS, SJIS, ASCII');
\r
1144 switch(strtolower(_CHARSET)){
\r
1146 $order = 'ASCII, UTF-8, EUC-JP, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1149 $order = 'ASCII, EUC-CN, EUC-JP, UTF-8, JIS, SJIS, ISO-8859-1';
\r
1152 // Note that shift_jis is only supported for output.
\r
1153 // Using shift_jis in DB is prohibited.
\r
1154 $order = 'ASCII, SJIS, EUC-JP, UTF-8, JIS, EUC-CN, ISO-8859-1';
\r
1157 // euc-jp,iso-8859-x,windows-125x
\r
1158 $order = 'ASCII, EUC-JP, UTF-8, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1161 $query = mb_convert_encoding($query, _CHARSET, $order);
\r
1162 if (is_numeric($blogid)) {
\r
1163 $blogid = intVal($blogid);
\r
1165 $blogid = getBlogIDFromName($blogid);
\r
1169 doError(_ERROR_NOSUCHBLOG);
\r
1172 } elseif ($memberid) {
\r
1175 if (!MEMBER::existsID($memberid) ) {
\r
1176 doError(_ERROR_NOSUCHMEMBER);
\r
1179 $memberinfo = $manager->getMember($memberid);
\r
1181 } elseif ($imagepopup) {
\r
1182 // media object (images etc.)
\r
1183 $type = 'imagepopup';
\r
1185 // TODO: check if media-object exists
\r
1186 // TODO: set some vars?
\r
1188 // show regular index page
\r
1193 // any type of skin with catid
\r
1194 if ($catid && !$blogid) {
\r
1195 $blogid = getBlogIDFromCatID($catid);
\r
1198 // decide which blog should be displayed
\r
1200 $blogid = $CONF['DefaultBlog'];
\r
1203 $b =& $manager->getBlog($blogid);
\r
1204 $blog = $b; // references can't be placed in global variables?
\r
1206 if (!$blog->isValid) {
\r
1207 doError(_ERROR_NOSUCHBLOG);
\r
1210 // set catid if necessary
\r
1212 // check if the category is valid
\r
1213 if (!$blog->isValidCategory($catid)) {
\r
1214 doError(_ERROR_NOSUCHCATEGORY);
\r
1216 $blog->setSelectedCategory($catid);
\r
1220 // decide which skin should be used
\r
1221 if ($skinid != '' && ($skinid == 0) ) {
\r
1222 selectSkin($skinid);
\r
1226 $skinid = $blog->getDefaultSkin();
\r
1229 //$special = requestVar('special'); //get at top of file as global
\r
1230 if (!empty($special) && isValidShortName($special)) {
\r
1231 $type = strtolower($special);
\r
1234 $skin = new SKIN($skinid);
\r
1236 if (!$skin->isValid) {
\r
1237 doError(_ERROR_NOSUCHSKIN);
\r
1240 // set global skinpart variable so can determine quickly what is being parsed from any plugin or phpinclude
\r
1242 $skinpart = $type;
\r
1245 $skin->parse($type);
\r
1247 // check to see we should throw JustPosted event
\r
1248 $blog->checkJustPosted();
\r
1252 * Show error skin with given message. An optional skin-object to use can be given
\r
1254 function doError($msg, $skin = '') {
\r
1255 global $errormessage, $CONF, $skinid, $blogid, $manager;
\r
1257 if ($skin == '') {
\r
1259 if (SKIN::existsID($skinid) ) {
\r
1260 $skin = new SKIN($skinid);
\r
1261 } elseif ($manager->existsBlogID($blogid) ) {
\r
1262 $blog =& $manager->getBlog($blogid);
\r
1263 $skin = new SKIN($blog->getDefaultSkin() );
\r
1264 } elseif ($CONF['DefaultBlog']) {
\r
1265 $blog =& $manager->getBlog($CONF['DefaultBlog']);
\r
1266 $skin = new SKIN($blog->getDefaultSkin() );
\r
1268 // this statement should actually never be executed
\r
1269 $skin = new SKIN($CONF['BaseSkin']);
\r
1274 $skinid = $skin->id;
\r
1275 $errormessage = $msg;
\r
1276 $skin->parse('error');
\r
1280 function getConfig() {
\r
1283 $query = 'SELECT * FROM ' . sql_table('config');
\r
1284 $res = sql_query($query);
\r
1286 while ($obj = sql_fetch_object($res) ) {
\r
1287 $CONF[$obj->name] = $obj->value;
\r
1291 // some checks for names of blogs, categories, templates, members, ...
\r
1292 function isValidShortName($name) {
\r
1293 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
\r
1294 # original eregi: eregi('^[a-z0-9]+$', $name)
\r
1295 return preg_match('#^[a-z0-9]+$#i', $name);
\r
1298 function isValidDisplayName($name) {
\r
1299 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
\r
1300 # original eregi: eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name)
\r
1301 return preg_match('#^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$#i', $name);
\r
1304 function isValidCategoryName($name) {
\r
1308 function isValidTemplateName($name) {
\r
1309 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
\r
1310 # original eregi: eregi('^[a-z0-9/]+$', $name)
\r
1311 return preg_match('#^[a-z0-9/]+$#i', $name);
\r
1314 function isValidSkinName($name) {
\r
1315 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
\r
1316 # original eregi: eregi('^[a-z0-9/]+$', $name);
\r
1317 return preg_match('#^[a-z0-9/]+$#i', $name);
\r
1320 // add and remove linebreaks
\r
1321 function addBreaks($var) {
\r
1322 return nl2br($var);
\r
1325 function removeBreaks($var) {
\r
1326 return preg_replace("/<br \/>([\r\n])/", "$1", $var);
\r
1329 // shortens a text string to maxlength ($toadd) is what needs to be added
\r
1330 // at the end (end length is <= $maxlength)
\r
1331 function shorten($text, $maxlength, $toadd) {
\r
1332 // 1. remove entities...
\r
1333 // $trans = get_html_translation_table(HTML_ENTITIES);
\r
1334 $trans = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
1335 $trans = array_flip($trans);
\r
1336 $text = strtr($text, $trans);
\r
1338 // 2. the actual shortening
\r
1339 if (strlen($text) > $maxlength) {
\r
1340 // $text = substr($text, 0, $maxlength - strlen($toadd) ) . $toadd;
\r
1341 $text = mb_strimwidth($text, 0, $maxlength, $toadd, _CHARSET); // for Japanese
\r
1348 * Converts a unix timestamp to a mysql DATETIME format, and places
\r
1349 * quotes around it.
\r
1351 function mysqldate($timestamp) {
\r
1352 return '"' . date('Y-m-d H:i:s', $timestamp) . '"';
\r
1356 * functions for use in index.php
\r
1358 function selectBlog($shortname) {
\r
1359 global $blogid, $archivelist;
\r
1361 $blogid = getBlogIDFromName($shortname);
\r
1364 // also force archivelist variable, if it is set
\r
1365 if ($archivelist) {
\r
1366 $archivelist = $blogid;
\r
1370 function selectSkin($skinname) {
\r
1373 $skinid = SKIN::getIdFromName($skinname);
\r
1378 * Can take either a category ID or a category name (be aware that
\r
1379 * multiple categories can have the same name)
\r
1381 function selectCategory($cat) {
\r
1384 if (is_numeric($cat) ) {
\r
1385 $catid = intval($cat);
\r
1387 $catid = getCatIDFromName($cat);
\r
1392 function selectItem($id) {
\r
1395 $itemid = intval($id);
\r
1399 // force the use of a language file (warning: can cause warnings)
\r
1400 function selectLanguage($language) {
\r
1404 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
1405 # original ereg_replace: preg_replace( '@\\|/@', '', $language) . '.php')
\r
1406 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
1408 include($DIR_LANG . preg_replace('#[\\\\|/]#', '', $language) . '.php');
\r
1412 function parseFile($filename, $includeMode = 'normal', $includePrefix = '') {
\r
1413 $handler = new ACTIONS('fileparser');
\r
1414 $parser = new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);
\r
1415 $handler->parser =& $parser;
\r
1417 // set IncludeMode properties of parser
\r
1418 PARSER::setProperty('IncludeMode', $includeMode);
\r
1419 PARSER::setProperty('IncludePrefix', $includePrefix);
\r
1421 if (!file_exists($filename) ) {
\r
1422 doError(_GFUNCTIONS_PARSEFILE_FILEMISSING);
\r
1425 $fsize = filesize($filename);
\r
1427 if ($fsize <= 0) {
\r
1432 $fd = fopen ($filename, 'r');
\r
1433 $contents = fread ($fd, $fsize);
\r
1436 // parse file contents
\r
1437 $parser->parse($contents);
\r
1441 * Outputs a debug message
\r
1443 function debug($msg) {
\r
1444 echo '<p><b>' . $msg . "</b></p>\n";
\r
1448 function addToLog($level, $msg) {
\r
1449 ACTIONLOG::add($level, $msg);
\r
1452 // shows a link to help file
\r
1453 function help($id) {
\r
1454 echo helpHtml($id);
\r
1457 function helpHtml($id) {
\r
1459 return helplink($id) . '<img src="' . $CONF['AdminURL'] . 'documentation/icon-help.gif" width="15" height="15" alt="' . _HELP_TT . '" title="' . _HELP_TT . '" /></a>';
\r
1462 function helplink($id) {
\r
1464 return '<a href="' . $CONF['AdminURL'] . 'documentation/help.html#'. $id . '" onclick="if (event && event.preventDefault) event.preventDefault(); return help(this.href);">';
\r
1467 function getMailFooter() {
\r
1468 $message = "\n\n-----------------------------";
\r
1469 $message .= "\n Powered by Nucleus CMS";
\r
1470 $message .= "\n(http://www.nucleuscms.org/)";
\r
1475 * Returns the name of the language to use
\r
1476 * preference priority: member - site
\r
1477 * defaults to english when no good language found
\r
1479 * checks if file exists, etc...
\r
1481 function getLanguageName() {
\r
1482 global $CONF, $member;
\r
1484 if ($member && $member->isLoggedIn() ) {
\r
1485 // try to use members language
\r
1486 $memlang = $member->getLanguage();
\r
1488 if (($memlang != '') && (checkLanguage($memlang) ) ) {
\r
1493 // use default language
\r
1494 if (checkLanguage($CONF['Language']) ) {
\r
1495 return $CONF['Language'];
\r
1502 * Includes a PHP file. This method can be called while parsing templates and skins
\r
1504 function includephp($filename) {
\r
1505 // make predefined variables global, so most simple scripts can be used here
\r
1507 // apache (names taken from PHP doc)
\r
1508 global $GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE, $SERVER_PROTOCOL;
\r
1509 global $REQUEST_METHOD, $QUERY_STRING, $DOCUMENT_ROOT, $HTTP_ACCEPT;
\r
1510 global $HTTP_ACCEPT_CHARSET, $HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE;
\r
1511 global $HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER, $HTTP_USER_AGENT;
\r
1512 global $REMOTE_ADDR, $REMOTE_PORT, $SCRIPT_FILENAME, $SERVER_ADMIN;
\r
1513 global $SERVER_PORT, $SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME;
\r
1514 global $REQUEST_URI;
\r
1516 // php (taken from PHP doc)
\r
1517 global $argv, $argc, $PHP_SELF, $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS;
\r
1518 global $HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS, $HTTP_SESSION_VARS;
\r
1521 global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;
\r
1523 if (@file_exists($filename) ) {
\r
1524 include($filename);
\r
1529 * Checks if a certain language exists
\r
1530 * @param string $lang
\r
1533 function checkLanguage($lang) {
\r
1535 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
1536 # original ereg_replace: ereg_replace( '[\\|/]', '', $lang) . '.php')
\r
1537 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
1538 return file_exists($DIR_LANG . preg_replace('#[\\\\|/]#', '', $lang) . '.php');
\r
1542 * Checks if a certain plugin exists
\r
1543 * @param string $plug
\r
1546 function checkPlugin($plug) {
\r
1548 global $DIR_PLUGINS;
\r
1550 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
1551 # original ereg_replace: ereg_replace( '[\\|/]', '', $plug) . '.php')
\r
1552 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
1554 return file_exists($DIR_PLUGINS . preg_replace('#[\\\\|/]#', '', $plug) . '.php');
\r
1559 * Centralisation of the functions that generate links
\r
1561 function createItemLink($itemid, $extra = '') {
\r
1562 return createLink('item', array('itemid' => $itemid, 'extra' => $extra) );
\r
1565 function createMemberLink($memberid, $extra = '') {
\r
1566 return createLink('member', array('memberid' => $memberid, 'extra' => $extra) );
\r
1569 function createCategoryLink($catid, $extra = '') {
\r
1570 return createLink('category', array('catid' => $catid, 'extra' => $extra) );
\r
1573 function createArchiveListLink($blogid = '', $extra = '') {
\r
1574 return createLink('archivelist', array('blogid' => $blogid, 'extra' => $extra) );
\r
1577 function createArchiveLink($blogid, $archive, $extra = '') {
\r
1578 return createLink('archive', array('blogid' => $blogid, 'archive' => $archive, 'extra' => $extra) );
\r
1581 function createBlogidLink($blogid, $params = '') {
\r
1582 return createLink('blog', array('blogid' => $blogid, 'extra' => $params) );
\r
1585 function createLink($type, $params) {
\r
1586 global $manager, $CONF;
\r
1588 $generatedURL = '';
\r
1589 $usePathInfo = ($CONF['URLMode'] == 'pathinfo');
\r
1591 // ask plugins first
\r
1594 if ($usePathInfo) {
\r
1599 'params' => $params,
\r
1600 'completed' => &$created,
\r
1606 // if a plugin created the URL, return it
\r
1611 // default implementation
\r
1614 if ($usePathInfo) {
\r
1615 $url = $CONF['ItemURL'] . '/' . $CONF['ItemKey'] . '/' . $params['itemid'];
\r
1617 $url = $CONF['ItemURL'] . '?itemid=' . $params['itemid'];
\r
1622 if ($usePathInfo) {
\r
1623 $url = $CONF['MemberURL'] . '/' . $CONF['MemberKey'] . '/' . $params['memberid'];
\r
1625 $url = $CONF['MemberURL'] . '?memberid=' . $params['memberid'];
\r
1630 if ($usePathInfo) {
\r
1631 $url = $CONF['CategoryURL'] . '/' . $CONF['CategoryKey'] . '/' . $params['catid'];
\r
1633 $url = $CONF['CategoryURL'] . '?catid=' . $params['catid'];
\r
1637 case 'archivelist':
\r
1638 if (!$params['blogid']) {
\r
1639 $params['blogid'] = $CONF['DefaultBlog'];
\r
1642 if ($usePathInfo) {
\r
1643 $url = $CONF['ArchiveListURL'] . '/' . $CONF['ArchivesKey'] . '/' . $params['blogid'];
\r
1645 $url = $CONF['ArchiveListURL'] . '?archivelist=' . $params['blogid'];
\r
1650 if ($usePathInfo) {
\r
1651 $url = $CONF['ArchiveURL'] . '/' . $CONF['ArchiveKey'] . '/'.$params['blogid'].'/' . $params['archive'];
\r
1653 $url = $CONF['ArchiveURL'] . '?blogid='.$params['blogid'].'&archive=' . $params['archive'];
\r
1658 if ($usePathInfo) {
\r
1659 $url = $CONF['BlogURL'] . '/' . $CONF['BlogKey'] . '/' . $params['blogid'];
\r
1661 $url = $CONF['BlogURL'] . '?blogid=' . $params['blogid'];
\r
1666 return addLinkParams($url, (isset($params['extra'])? $params['extra'] : null));
\r
1669 function createBlogLink($url, $params) {
\r
1671 if ($CONF['URLMode'] == 'normal') {
\r
1672 if (strpos($url, '?') === FALSE && is_array($params)) {
\r
1673 $fParam = reset($params);
\r
1674 $fKey = key($params);
\r
1675 array_shift($params);
\r
1676 $url .= '?' . $fKey . '=' . $fParam;
\r
1678 } elseif ($CONF['URLMode'] == 'pathinfo' && substr($url, -1) == '/') {
\r
1679 $url = substr($url, 0, -1);
\r
1681 return addLinkParams($url, $params);
\r
1684 function addLinkParams($link, $params) {
\r
1687 if (is_array($params) ) {
\r
1689 if ($CONF['URLMode'] == 'pathinfo') {
\r
1690 foreach ($params as $param => $value) {
\r
1691 // change in 3.63 to fix problem where URL generated with extra params mike look like category/4/blogid/1
\r
1692 // but they should use the URL keys like this: category/4/blog/1
\r
1693 // if user wants old urls back, set $CONF['NoURLKeysInExtraParams'] = 1; in config.php
\r
1694 if (isset($CONF['NoURLKeysInExtraParams']) && $CONF['NoURLKeysInExtraParams'] == 1)
\r
1696 $link .= '/' . $param . '/' . urlencode($value);
\r
1700 $link .= '/' . $CONF['ItemKey'] . '/' . urlencode($value);
\r
1703 $link .= '/' . $CONF['MemberKey'] . '/' . urlencode($value);
\r
1706 $link .= '/' . $CONF['CategoryKey'] . '/' . urlencode($value);
\r
1708 case 'archivelist':
\r
1709 $link .= '/' . $CONF['ArchivesKey'] . '/' . urlencode($value);
\r
1712 $link .= '/' . $CONF['ArchiveKey'] . '/' . urlencode($value);
\r
1715 $link .= '/' . $CONF['BlogKey'] . '/' . urlencode($value);
\r
1718 $link .= '/' . $param . '/' . urlencode($value);
\r
1725 foreach ($params as $param => $value) {
\r
1726 $link .= '&' . $param . '=' . urlencode($value);
\r
1736 * @param $querystr
\r
1737 * querystring to alter (e.g. foo=1&bar=2&x=y)
\r
1739 * name of parameter to change (e.g. 'foo')
\r
1741 * New value for that parameter (e.g. 3)
\r
1743 * altered query string (for the examples above: foo=3&bar=2&x=y)
\r
1745 function alterQueryStr($querystr, $param, $value) {
\r
1746 $vars = explode('&', $querystr);
\r
1749 for ($i = 0; $i < count($vars); $i++) {
\r
1750 $v = explode('=', $vars[$i]);
\r
1752 if ($v[0] == $param) {
\r
1754 $vars[$i] = implode('=', $v);
\r
1761 $vars[] = $param . '=' . $value;
\r
1764 return ltrim(implode('&', $vars), '&');
\r
1767 // passes one variable as hidden input field (multiple fields for arrays)
\r
1768 // @see passRequestVars in varsx.x.x.php
\r
1769 function passVar($key, $value) {
\r
1771 if (is_array($value) ) {
\r
1772 for ($i = 0; $i < sizeof($value); $i++) {
\r
1773 passVar($key . '[' . $i . ']', $value[$i]);
\r
1779 // other values: do stripslashes if needed
\r
1780 ?><input type="hidden" name="<?php echo htmlspecialchars($key)?>" value="<?php echo htmlspecialchars(undoMagic($value) )?>" /><?php
\r
1784 Date format functions (to be used from [%date(..)%] skinvars
\r
1786 function formatDate($format, $timestamp, $defaultFormat, &$blog) {
\r
1787 // apply blog offset (#42)
\r
1788 $boffset = $blog ? $blog->getTimeOffset() * 3600 : 0;
\r
1789 $offset = date('Z', $timestamp) + $boffset;
\r
1791 switch ($format) {
\r
1793 if ($offset >= 0) {
\r
1797 $offset = -$offset;
\r
1800 $tz .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1801 return date('D, j M Y H:i:s ', $timestamp) . $tz;
\r
1804 $timestamp -= $offset;
\r
1805 return date('D, j M Y H:i:s ', $timestamp) . 'GMT';
\r
1808 $timestamp -= $offset;
\r
1809 return date('Y-m-d\TH:i:s\Z', $timestamp);
\r
1812 if ($offset >= 0) {
\r
1816 $offset = -$offset;
\r
1819 $tz .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1820 return date('Y-m-d\TH:i:s', $timestamp) . $tz;
\r
1823 return strftimejp($format ? $format : $defaultFormat, $timestamp);
\r
1827 function encoding_check($val, $key, $encoding=false, $exclude=false) {
\r
1829 When 3rd argument is set, return if checked already.
\r
1830 When 4th argument is set, set the excluded key(s).
\r
1832 static $search=false, $checked=array(), $excludes=array();
\r
1833 if ($exclude!==false) {
\r
1834 if (is_array($exclude)) {
\r
1835 foreach($exclude as $v) $excludes[$v]=true;
\r
1836 } else $excludes[$exclude]=true;
\r
1839 if ($encoding!==false) {
\r
1840 switch($encoding=strtolower($encoding)){
\r
1842 $search='/([\x00-\x7F]+'.
\r
1843 '|[\xC2-\xDF][\x80-\xBF]'.
\r
1844 '|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]'.
\r
1845 '|[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1846 '|[\xF8-\xFB][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1847 '|[\xFC-\xFD][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF])/';
\r
1850 $search='/([\x00-\x7F]+'.
\r
1851 '|[\x8E][\xA0-\xDF]'.
\r
1852 '|[\x8F]?[\xA1-\xFE][\xA1-\xFE])/';
\r
1855 $search='/([\x00-\x7F]+'.
\r
1856 '|[\xA1-\xF7][\xA1-\xFE])/';
\r
1859 // Note that shift_jis is only supported for output.
\r
1860 // Using shift_jis in DB is prohibited.
\r
1861 $search='/([\x00-\x7F\xA1-\xDF]+'.
\r
1862 '|[\x81-\x9F\xE0-\xFC][\x40-\xFC])/';
\r
1866 if (preg_match('/^iso\-8859\-[0-9]{1,2}$/',$encoding)) break;
\r
1867 if (preg_match('/^windows\-125[0-8]$/',$encoding)) break;
\r
1868 startUpError('<p>Unknown or non-supported encoding.</p>', 'Encoding Error');
\r
1871 if (isset($checked[$encoding])) return true; // Already checked.
\r
1872 $checked[$encoding]=true;
\r
1874 if ($key===false) return false; // Not yet checked.
\r
1875 if ($search===false) return true; // non-multibyte encoding
\r
1876 if (isset($excludes[$key])) return true; // This key isn't checked.
\r
1877 if (is_array($val)) {
\r
1878 array_walk($val, 'encoding_check');
\r
1880 $result=preg_replace($search,'',$val);
\r
1881 if (strlen($result)!=0) {
\r
1882 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1886 $result=preg_replace($search,'',$key);
\r
1887 if (strlen($result)!=0) {
\r
1888 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1894 function checkVars($aVars) {
\r
1895 global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;
\r
1897 foreach ($aVars as $varName) {
\r
1899 if (phpversion() >= '4.1.0') {
\r
1901 if ( isset($_GET[$varName])
\r
1902 || isset($_POST[$varName])
\r
1903 || isset($_COOKIE[$varName])
\r
1904 || isset($_ENV[$varName])
\r
1905 || isset($_SESSION[$varName])
\r
1906 || isset($_FILES[$varName])
\r
1908 die('Sorry. An error occurred.');
\r
1913 if ( isset($HTTP_GET_VARS[$varName])
\r
1914 || isset($HTTP_POST_VARS[$varName])
\r
1915 || isset($HTTP_COOKIE_VARS[$varName])
\r
1916 || isset($HTTP_ENV_VARS[$varName])
\r
1917 || isset($HTTP_SESSION_VARS[$varName])
\r
1918 || isset($HTTP_POST_FILES[$varName])
\r
1920 die('Sorry. An error occurred.');
\r
1929 * Sanitize parameters such as $_GET and $_SERVER['REQUEST_URI'] etc.
\r
1932 function sanitizeParams()
\r
1934 global $HTTP_SERVER_VARS;
\r
1940 // REQUEST_URI of $HTTP_SERVER_VARS
\r
1941 $str =& $HTTP_SERVER_VARS["REQUEST_URI"];
\r
1942 serverStringToArray($str, $array, $frontParam);
\r
1943 sanitizeArray($array);
\r
1944 arrayToServerString($array, $frontParam, $str);
\r
1946 // QUERY_STRING of $HTTP_SERVER_VARS
\r
1947 $str =& $HTTP_SERVER_VARS["QUERY_STRING"];
\r
1948 serverStringToArray($str, $array, $frontParam);
\r
1949 sanitizeArray($array);
\r
1950 arrayToServerString($array, $frontParam, $str);
\r
1952 if (phpversion() >= '4.1.0') {
\r
1953 // REQUEST_URI of $_SERVER
\r
1954 $str =& $_SERVER["REQUEST_URI"];
\r
1955 serverStringToArray($str, $array, $frontParam);
\r
1956 sanitizeArray($array);
\r
1957 arrayToServerString($array, $frontParam, $str);
\r
1959 // QUERY_STRING of $_SERVER
\r
1960 $str =& $_SERVER["QUERY_STRING"];
\r
1961 serverStringToArray($str, $array, $frontParam);
\r
1962 sanitizeArray($array);
\r
1963 arrayToServerString($array, $frontParam, $str);
\r
1967 convArrayForSanitizing($_GET, $array);
\r
1968 sanitizeArray($array);
\r
1969 revertArrayForSanitizing($array, $_GET);
\r
1971 // $_REQUEST (only GET param)
\r
1972 convArrayForSanitizing($_REQUEST, $array);
\r
1973 sanitizeArray($array);
\r
1974 revertArrayForSanitizing($array, $_REQUEST);
\r
1978 * Check ticket when not checked in plugin's admin page
\r
1980 * Also avoid the access to plugin/index.php by guest user.
\r
1982 function ticketForPlugin(){
\r
1983 global $CONF,$DIR_PLUGINS,$member,$ticketforplugin;
\r
1986 $ticketforplugin=array();
\r
1987 $ticketforplugin['ticket'] = FALSE;
\r
1989 /* Check if using plugin's php file. */
\r
1990 if ($p_translated = serverVar('PATH_TRANSLATED') )
\r
1992 if (!file_exists($p_translated) )
\r
1994 $p_translated = '';
\r
1998 if (!$p_translated)
\r
2000 $p_translated = serverVar('SCRIPT_FILENAME');
\r
2001 if (!file_exists($p_translated) )
\r
2003 header("HTTP/1.0 404 Not Found");
\r
2008 $p_translated=str_replace('\\','/',$p_translated);
\r
2009 $d_plugins=str_replace('\\','/',$DIR_PLUGINS);
\r
2011 if (strpos($p_translated, $d_plugins) !== 0)
\r
2013 return;// This isn't plugin php file.
\r
2016 /* Solve the plugin php file or admin directory */
\r
2017 $phppath=substr($p_translated,strlen($d_plugins));
\r
2018 $phppath=preg_replace('#^/#','',$phppath);// Remove the first "/" if exists.
\r
2019 $path=preg_replace('#^NP_(.*)\.php$#','$1',$phppath); // Remove the first "NP_" and the last ".php" if exists.
\r
2020 $path=preg_replace('#^([^/]*)/(.*)$#','$1',$path); // Remove the "/" and beyond.
\r
2022 /* Solve the plugin name. */
\r
2024 $query='SELECT `pfile` FROM '.sql_table('plugin');
\r
2025 $res=sql_query($query);
\r
2026 while($row=sql_fetch_row($res))
\r
2028 $name=substr($row[0],3);
\r
2029 $plugins[strtolower($name)]=$name;
\r
2031 sql_free_result($res);
\r
2033 if ($plugins[$path])
\r
2035 $plugin_name = $plugins[$path];
\r
2037 else if (in_array($path, $plugins))
\r
2039 $plugin_name = $path;
\r
2043 header("HTTP/1.0 404 Not Found");
\r
2047 /* Return if not index.php */
\r
2048 if ( ($phppath != strtolower($plugin_name) . '/') && ($phppath != strtolower($plugin_name) . '/index.php') )
\r
2053 /* Exit if not logged in. */
\r
2054 if ( !$member->isLoggedIn() )
\r
2056 exit(_GFUNCTIONS_YOU_AERNT_LOGGEDIN);
\r
2059 global $manager,$DIR_LIBS,$DIR_LANG,$HTTP_GET_VARS,$HTTP_POST_VARS;
\r
2061 /* Check if this feature is needed (ie, if "$manager->checkTicket()" is not included in the script). */
\r
2062 if (!($p_translated=serverVar('PATH_TRANSLATED')))
\r
2064 $p_translated=serverVar('SCRIPT_FILENAME');
\r
2066 if ($file=@file($p_translated))
\r
2069 foreach($file as $line)
\r
2071 if (preg_match('/[\$]manager([\s]*)[\-]>([\s]*)checkTicket([\s]*)[\(]/i',$prevline.$line))
\r
2079 /* Show a form if not valid ticket */
\r
2080 if ( ( strstr(serverVar('REQUEST_URI'),'?') || serverVar('QUERY_STRING')
\r
2081 || strtoupper(serverVar('REQUEST_METHOD'))=='POST' )
\r
2082 && (!$manager->checkTicket()) )
\r
2084 if (!class_exists('PluginAdmin'))
\r
2086 $language = getLanguageName();
\r
2088 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
2089 # original ereg_replace: ereg_replace( '[\\|/]', '', $language) . '.php')
\r
2090 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
2091 include($DIR_LANG . preg_replace('#[\\\\|/]#', '', $language) . '.php');
\r
2092 include($DIR_LIBS . 'PLUGINADMIN.php');
\r
2095 $oPluginAdmin = new PluginAdmin($plugin_name);
\r
2096 $oPluginAdmin->start();
\r
2097 echo '<p>' . _ERROR_BADTICKET . "</p>\n";
\r
2099 /* Show the form to confirm action */
\r
2100 // PHP 4.0.x support
\r
2101 $get= (isset($_GET)) ? $_GET : $HTTP_GET_VARS;
\r
2102 $post= (isset($_POST)) ? $_POST : $HTTP_POST_VARS;
\r
2103 // Resolve URI and QUERY_STRING
\r
2104 if ($uri=serverVar('REQUEST_URI'))
\r
2106 list($uri,$qstring)=explode('?',$uri);
\r
2110 if ( !($uri=serverVar('PHP_SELF')) )
\r
2112 $uri=serverVar('SCRIPT_NAME');
\r
2114 $qstring=serverVar('QUERY_STRING');
\r
2118 $qstring='?'.$qstring;
\r
2120 echo '<p>'._SETTINGS_UPDATE.' : '._QMENU_PLUGINS.' <span style="color:red;">'.htmlspecialchars($plugin_name)."</span> ?</p>\n";
\r
2121 switch(strtoupper(serverVar('REQUEST_METHOD')))
\r
2124 echo '<form method="POST" action="'.htmlspecialchars($uri.$qstring).'">';
\r
2125 $manager->addTicketHidden();
\r
2126 _addInputTags($post);
\r
2129 echo '<form method="GET" action="'.htmlspecialchars($uri).'">';
\r
2130 $manager->addTicketHidden();
\r
2131 _addInputTags($get);
\r
2135 echo '<input type="submit" value="'._YES.'" /> ';
\r
2136 echo '<input type="button" value="'._NO.'" onclick="history.back(); return false;" />';
\r
2139 $oPluginAdmin->end();
\r
2143 /* Create new ticket */
\r
2144 $ticket=$manager->addTicketToUrl('');
\r
2145 $ticketforplugin['ticket']=substr($ticket,strpos($ticket,'ticket=')+7);
\r
2147 function _addInputTags(&$keys,$prefix=''){
\r
2148 foreach($keys as $key=>$value){
\r
2149 if ($prefix) $key=$prefix.'['.$key.']';
\r
2150 if (is_array($value)) _addInputTags($value,$key);
\r
2152 if (get_magic_quotes_gpc()) $value=stripslashes($value);
\r
2153 if ($key=='ticket') continue;
\r
2154 echo '<input type="hidden" name="'.htmlspecialchars($key).
\r
2155 '" value="'.htmlspecialchars($value).'" />'."\n";
\r
2161 * Convert the server string such as $_SERVER['REQUEST_URI']
\r
2162 * to arry like arry['blogid']=1 and array['page']=2 etc.
\r
2164 function serverStringToArray($str, &$array, &$frontParam)
\r
2170 // split front param, e.g. /index.php, and others, e.g. blogid=1&page=2
\r
2171 if (strstr($str, "?")){
\r
2172 list($frontParam, $args) = preg_split("/\?/", $str, 2);
\r
2179 // If there is no args like blogid=1&page=2, return
\r
2180 if (!strstr($str, "=") && !strlen($frontParam)) {
\r
2181 $frontParam = $str;
\r
2185 $array = explode("&", $args);
\r
2189 * Convert array like array['blogid'] to server string
\r
2190 * such as $_SERVER['REQUEST_URI']
\r
2192 function arrayToServerString($array, $frontParam, &$str)
\r
2194 if (strstr($str, "?")) {
\r
2195 $str = $frontParam . "?";
\r
2197 $str = $frontParam;
\r
2199 if (count($array)) {
\r
2200 $str .= implode("&", $array);
\r
2205 * Sanitize array parameters.
\r
2206 * This function checks both key and value.
\r
2207 * - check key if it inclues " (double quote), remove from array
\r
2208 * - check value if it includes \ (escape sequece), remove remaining string
\r
2210 function sanitizeArray(&$array)
\r
2212 $excludeListForSanitization = array('query');
\r
2213 // $excludeListForSanitization = array();
\r
2215 foreach ($array as $k => $v) {
\r
2217 // split to key and value
\r
2218 list($key, $val) = preg_split("/=/", $v, 2);
\r
2219 if (!isset($val)) {
\r
2223 // when magic quotes is on, need to use stripslashes,
\r
2224 // and then addslashes
\r
2225 if (get_magic_quotes_gpc()) {
\r
2226 $val = stripslashes($val);
\r
2228 // note that we must use addslashes here because this function is called before the db connection is made
\r
2229 // and sql_real_escape_string needs a db connection
\r
2230 $val = addslashes($val);
\r
2232 // if $key is included in exclude list, skip this param
\r
2233 if (!in_array($key, $excludeListForSanitization)) {
\r
2236 if (strpos($val, '\\')) {
\r
2237 list($val, $tmp) = explode('\\', $val);
\r
2240 // remove control code etc.
\r
2241 $val = strtr($val, "\0\r\n<>'\"", " ");
\r
2244 if (preg_match('/\"/i', $key)) {
\r
2245 unset($array[$k]);
\r
2249 // set sanitized info
\r
2250 $array[$k] = sprintf("%s=%s", $key, $val);
\r
2256 * Convert array for sanitizeArray function
\r
2258 function convArrayForSanitizing($src, &$array)
\r
2261 foreach ($src as $key => $val) {
\r
2262 if (key_exists($key, $_GET)) {
\r
2263 array_push($array, sprintf("%s=%s", $key, $val));
\r
2269 * Revert array after sanitizeArray function
\r
2271 function revertArrayForSanitizing($array, &$dst)
\r
2273 foreach ($array as $v) {
\r
2274 list($key, $val) = preg_split("/=/", $v, 2);
\r
2275 $dst[$key] = $val;
\r
2280 * Stops processing the request and redirects to the given URL.
\r
2281 * - no actual contents should have been sent to the output yet
\r
2282 * - the URL will be stripped of illegal or dangerous characters
\r
2284 function redirect($url) {
\r
2285 $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%*]|i', '', $url);
\r
2286 header('Location: ' . $url);
\r
2291 * Strip HTML tags from a string
\r
2292 * This function is a bit more intelligent than a regular call to strip_tags(),
\r
2293 * because it also deletes the contents of certain tags and cleans up any
\r
2294 * unneeded whitespace.
\r
2296 function stringStripTags ($string) {
\r
2297 $string = preg_replace("/<del[^>]*>.+<\/del[^>]*>/isU", '', $string);
\r
2298 $string = preg_replace("/<script[^>]*>.+<\/script[^>]*>/isU", '', $string);
\r
2299 $string = preg_replace("/<style[^>]*>.+<\/style[^>]*>/isU", '', $string);
\r
2300 $string = str_replace('>', '> ', $string);
\r
2301 $string = str_replace('<', ' <', $string);
\r
2302 $string = strip_tags($string);
\r
2303 $string = preg_replace("/\s+/", " ", $string);
\r
2304 $string = trim($string);
\r
2309 * Make a string containing HTML safe for use in a HTML attribute
\r
2310 * Tags are stripped and entities are normalized
\r
2312 function stringToAttribute ($string) {
\r
2313 $string = stringStripTags($string);
\r
2314 $string = entity::named_to_numeric($string);
\r
2315 $string = entity::normalize_numeric($string);
\r
2317 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2318 $string = entity::numeric_to_utf8($string);
\r
2321 $string = entity::specialchars($string, 'html');
\r
2322 $string = entity::numeric_to_named($string);
\r
2327 * Make a string containing HTML safe for use in a XML document
\r
2328 * Tags are stripped, entities are normalized and named entities are
\r
2329 * converted to numeric entities.
\r
2331 function stringToXML ($string) {
\r
2332 $string = stringStripTags($string);
\r
2333 $string = entity::named_to_numeric($string);
\r
2334 $string = entity::normalize_numeric($string);
\r
2336 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2337 $string = entity::numeric_to_utf8($string);
\r
2340 $string = entity::specialchars($string, 'xml');
\r
2344 // START: functions from the end of file BLOG.php
\r
2345 // used for mail notification (html -> text)
\r
2346 function toAscii($html) {
\r
2347 // strip off most tags
\r
2348 $html = strip_tags($html,'<a>');
\r
2349 $to_replace = "/<a[^>]*href=[\"\']([^\"^']*)[\"\'][^>]*>([^<]*)<\/a>/i";
\r
2351 $ascii = preg_replace_callback ($to_replace, '_links_add', $html);
\r
2352 $ascii .= "\n\n" . _links_list();
\r
2353 return strip_tags($ascii);
\r
2356 function _links_init() {
\r
2357 global $tmp_links;
\r
2358 $tmp_links = array();
\r
2361 function _links_add($match) {
\r
2362 global $tmp_links;
\r
2363 array_push($tmp_links, $match[1]);
\r
2364 return $match[2] . ' [' . sizeof($tmp_links) .']';
\r
2367 function _links_list() {
\r
2368 global $tmp_links;
\r
2371 foreach ($tmp_links as $current) {
\r
2372 $output .= "[$i] $current\n";
\r
2377 // END: functions from the end of file BLOG.php
\r
2379 // START: functions from the end of file ADMIN.php
\r
2381 * @todo document this
\r
2383 function encode_desc(&$data)
\r
2385 // _$to_entities = get_html_translation_table(HTML_ENTITIES);
\r
2386 $to_entities = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
2387 $from_entities = array_flip($to_entities);
\r
2388 $data = str_replace('<br />', '\n', $data); //hack
\r
2389 $data = strtr($data,$from_entities);
\r
2390 $data = strtr($data,$to_entities);
\r
2391 $data = str_replace('\n', '<br />', $data); //hack
\r
2396 * Returns the Javascript code for a bookmarklet that works on most modern browsers
\r
2400 function getBookmarklet($blogid) {
\r
2404 $document = 'document';
\r
2405 $bookmarkletline = "javascript:Q='';x=".$document.";y=window;if(x.selection){Q=x.selection.createRange().text;}else if(y.getSelection){Q=y.getSelection();}else if(x.getSelection){Q=x.getSelection();}wingm=window.open('";
\r
2406 $bookmarkletline .= $CONF['AdminURL'] . "bookmarklet.php?blogid=$blogid";
\r
2407 $bookmarkletline .="&logtext='+escape(Q)+'&loglink='+encodeURIComponent(x.location.href)+'&loglinktitle='+escape(x.title),'nucleusbm','toolbar=no,scrollbars=no,width=600,height=550,left=10,top=10,status=no,resizable=yes');wingm.focus();";
\r
2409 return $bookmarkletline;
\r
2411 // END: functions from the end of file ADMIN.php
\r
2414 * Returns a variable or null if not set
\r
2416 * @param mixed Variable
\r
2417 * @return mixed Variable
\r
2419 function ifset(&$var) {
\r
2420 if (isset($var)) {
\r
2428 * Returns number of subscriber to an event
\r
2431 * @return number of subscriber(s)
\r
2433 function numberOfEventSubscriber($event) {
\r
2434 $query = 'SELECT COUNT(*) as count FROM ' . sql_table('plugin_event') . ' WHERE event=\'' . $event . '\'';
\r
2435 $res = sql_query($query);
\r
2436 $obj = sql_fetch_object($res);
\r
2437 return $obj->count;
\r
2441 * sets $special global variable for use in index.php before selector()
\r
2443 * @param String id
\r
2446 function selectSpecialSkinType($id) {
\r
2448 $special = strtolower($id);
\r
2452 * cleans filename of uploaded file for writing to file system
\r
2454 * @param String str
\r
2455 * @return String cleaned filename ready for use
\r
2457 function cleanFileName($str) {
\r
2458 $str = strtolower($str);
\r
2459 $ext_point = strrpos($str,".");
\r
2460 if ($ext_point===false) return false;
\r
2461 $ext = substr($str,$ext_point,strlen($str));
\r
2462 $str = substr($str,0,$ext_point);
\r
2464 return preg_replace("/[^a-z0-9-]/","_",$str).$ext;
\r
2468 * generate correct timecode with the format includes Japanese charactors
\r
2470 * @param String $format standard format string. Allowd to include Japanese charactors
\r
2471 * @param Integer $timestamp Unix Timestamp formated integer
\r
2472 * @return String Formatted timestamp
\r
2474 function strftimejp($format,$timestamp = ''){
\r
2475 return (setlocale(LC_CTYPE, 0) == 'Japanese_Japan.932')
\r
2476 ? iconv('CP932', _CHARSET, strftime(iconv(_CHARSET, 'CP932', $format),$timestamp))
\r
2477 : strftime($format,$timestamp)
\r