4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
\r
5 * Copyright (C) 2002-2012 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 // needed if we include globalfunctions from install.php
\r
15 global $nucleus, $CONF, $DIR_LIBS, $DIR_LANG, $manager, $member;
\r
17 $nucleus['version'] = 'v3.65';
\r
18 $nucleus['codename'] = '';
\r
20 // check and die if someone is trying to override internal globals (when register_globals turn on)
\r
21 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
24 if ($CONF['debug']) {
\r
25 error_reporting(E_ALL); // report all errors!
\r
27 ini_set('display_errors','0');
\r
28 error_reporting(E_ERROR | E_WARNING | E_PARSE);
\r
32 * Set default time zone
\r
33 * By Japanese Packaging Team, Jan.27, 2011
\r
34 * For private server which has no condition for default time zone
\r
37 if (function_exists('date_default_timezone_get')) {
\r
38 if (FALSE == ($timezone = @date_default_timezone_get())) {
\r
42 if (function_exists('date_default_timezone_set')) {
\r
43 @date_default_timezone_set($timezone);
\r
47 Indicates when Nucleus should display startup errors. Set to 1 if you want
\r
48 the error enabled (default), false otherwise
\r
51 Displays an error when visiting a public Nucleus page and headers have
\r
52 been sent out to early. This usually indicates an error in either a
\r
53 configuration file or a language file, and could cause Nucleus to
\r
56 Displays an error only when visiting the admin area, and when one or
\r
57 more of the installation files (install.php, install.sql, upgrades/
\r
58 directory) are still on the server.
\r
61 if (!isset($CONF['alertOnHeadersSent']) || (isset($CONF['alertOnHeadersSent'])&& $CONF['alertOnHeadersSent'] !== 0))
\r
63 $CONF['alertOnHeadersSent'] = 1;
\r
65 $CONF['alertOnSecurityRisk'] = 1;
\r
66 /*$CONF['ItemURL'] = $CONF['Self'];
\r
67 $CONF['ArchiveURL'] = $CONF['Self'];
\r
68 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
69 $CONF['MemberURL'] = $CONF['Self'];
\r
70 $CONF['SearchURL'] = $CONF['Self'];
\r
71 $CONF['BlogURL'] = $CONF['Self'];
\r
72 $CONF['CategoryURL'] = $CONF['Self'];
\r
74 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
75 // this avoids urls like index.php/item/13/index.php/item/15
\r
76 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
\r
77 $CONF['URLMode'] = 'normal';
\r
81 Set these to 1 to allow viewing of future items or draft items
\r
82 Should really never do this, but can be useful for some plugins that might need to
\r
83 Could cause some other issues if you use future posts otr drafts
\r
86 $CONF['allowDrafts'] = 0;
\r
87 $CONF['allowFuture'] = 0;
\r
89 if (getNucleusPatchLevel() > 0) {
\r
90 $nucleus['version'] .= '/' . getNucleusPatchLevel();
\r
94 if (!isset($CONF['installscript'])) {
\r
95 $CONF['installscript'] = 0;
\r
99 * Include multibyte function if some functions related to mbstring are not loaded.
\r
100 * By Japanese Packaging Team, Jan.31, 2011
\r
102 if (!function_exists('mb_convert_encoding')){
\r
103 global $mbemu_internals;
\r
104 include_libs('mb_emulator/mb-emulator.php',true,false);
\r
107 // we will use postVar, getVar, ... methods instead of HTTP_GET_VARS or _GET
\r
108 if ($CONF['installscript'] != 1) { // vars were already included in install.php
\r
109 if (phpversion() >= '4.1.0') {
\r
110 include_once($DIR_LIBS . 'vars4.1.0.php');
\r
112 include_once($DIR_LIBS . 'vars4.0.6.php');
\r
117 $bLoggingSanitizedResult=0;
\r
118 $bSanitizeAndContinue=0;
\r
120 $orgRequestURI = serverVar('REQUEST_URI');
\r
123 // get all variables that can come from the request and put them in the global scope
\r
124 $blogid = requestVar('blogid');
\r
125 $itemid = intRequestVar('itemid');
\r
126 $catid = intRequestVar('catid');
\r
127 $skinid = requestVar('skinid');
\r
128 $memberid = requestVar('memberid');
\r
129 $archivelist = requestVar('archivelist');
\r
130 $imagepopup = requestVar('imagepopup');
\r
131 $archive = requestVar('archive');
\r
132 $query = requestVar('query');
\r
133 $highlight = requestVar('highlight');
\r
134 $amount = requestVar('amount');
\r
135 $action = requestVar('action');
\r
136 $nextaction = requestVar('nextaction');
\r
137 $maxresults = requestVar('maxresults');
\r
138 $startpos = intRequestVar('startpos');
\r
139 $errormessage = '';
\r
141 $special = requestVar('special');
\r
142 $virtualpath = ((getVar('virtualpath') != null) ? getVar('virtualpath') : serverVar('PATH_INFO'));
\r
144 if (!headers_sent() ) {
\r
145 header('Generator: Nucleus CMS ' . $nucleus['version']);
\r
148 // include core classes that are needed for login & plugin handling
\r
149 include_once($DIR_LIBS . 'mysql.php');
\r
150 // added for 3.5 sql_* wrapper
\r
151 global $MYSQL_HANDLER;
\r
152 if (!isset($MYSQL_HANDLER))
\r
153 $MYSQL_HANDLER = array('mysql','');
\r
154 if ($MYSQL_HANDLER[0] == '')
\r
155 $MYSQL_HANDLER[0] = 'mysql';
\r
156 include_once($DIR_LIBS . 'sql/'.$MYSQL_HANDLER[0].'.php');
\r
157 // end new for 3.5 sql_* wrapper
\r
158 include($DIR_LIBS . 'MEMBER.php');
\r
159 include($DIR_LIBS . 'ACTIONLOG.php');
\r
160 include($DIR_LIBS . 'MANAGER.php');
\r
161 include($DIR_LIBS . 'PLUGIN.php');
\r
163 $manager =& MANAGER::instance();
\r
165 // make sure there's no unnecessary escaping:
\r
166 //set_magic_quotes_runtime(0);
\r
167 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
\r
168 ini_set('magic_quotes_runtime', '0');
\r
172 if (!isset($CONF['UsingAdminArea'])) {
\r
173 $CONF['UsingAdminArea'] = 0;
\r
176 // only needed when updating logs
\r
177 if ($CONF['UsingAdminArea']) {
\r
178 include($DIR_LIBS . 'xmlrpc.inc.php'); // XML-RPC client classes
\r
179 include_once($DIR_LIBS . 'ADMIN.php');
\r
182 // connect to database
\r
186 // logs sanitized result if need
\r
187 if ($orgRequestURI!==serverVar('REQUEST_URI')) {
\r
188 $msg = "Sanitized [" . serverVar('REMOTE_ADDR') . "] ";
\r
189 $msg .= $orgRequestURI . " -> " . serverVar('REQUEST_URI');
\r
190 if ($bLoggingSanitizedResult) {
\r
191 addToLog(WARNING, $msg);
\r
193 if (!$bSanitizeAndContinue) {
\r
198 // makes sure database connection gets closed on script termination
\r
199 register_shutdown_function('sql_disconnect');
\r
204 // Properly set $CONF['Self'] and others if it's not set... usually when we are access from admin menu
\r
205 if (!isset($CONF['Self'])) {
\r
206 $CONF['Self'] = $CONF['IndexURL'];
\r
207 // strip trailing /
\r
208 if ($CONF['Self'][strlen($CONF['Self']) -1] == "/") {
\r
209 $CONF['Self'] = substr($CONF['Self'], 0, strlen($CONF['Self']) -1);
\r
212 /* $CONF['ItemURL'] = $CONF['Self'];
\r
213 $CONF['ArchiveURL'] = $CONF['Self'];
\r
214 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
215 $CONF['MemberURL'] = $CONF['Self'];
\r
216 $CONF['SearchURL'] = $CONF['Self'];
\r
217 $CONF['BlogURL'] = $CONF['Self'];
\r
218 $CONF['CategoryURL'] = $CONF['Self'];*/
\r
221 $CONF['ItemURL'] = $CONF['Self'];
\r
222 $CONF['ArchiveURL'] = $CONF['Self'];
\r
223 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
224 $CONF['MemberURL'] = $CONF['Self'];
\r
225 $CONF['SearchURL'] = $CONF['Self'];
\r
226 $CONF['BlogURL'] = $CONF['Self'];
\r
227 $CONF['CategoryURL'] = $CONF['Self'];
\r
229 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
230 // this avoids urls like index.php/item/13/index.php/item/15
\r
231 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
\r
232 $CONF['URLMode'] = 'normal';
\r
235 // automatically use simpler toolbar for mozilla
\r
236 if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'), 'Gecko') ) {
\r
237 $CONF['DisableJsTools'] = 2;
\r
240 // login if cookies set
\r
241 $member = new MEMBER();
\r
243 // secure cookie key settings (either 'none', 0, 8, 16, 24, or 32)
\r
244 if (!isset($CONF['secureCookieKey'])) $CONF['secureCookieKey']=24;
\r
245 switch($CONF['secureCookieKey']){
\r
247 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
250 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
253 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
256 $CONF['secureCookieKeyIP']=serverVar('REMOTE_ADDR');
\r
259 $CONF['secureCookieKeyIP']='';
\r
262 // login/logout when required or renew cookies
\r
263 if ($action == 'login') {
\r
264 // Form Authentication
\r
265 $login = postVar('login');
\r
266 $pw = postVar('password');
\r
267 $shared = intPostVar('shared'); // shared computer or not
\r
269 $pw=substr($pw,0,40); // avoid md5 collision by using a long key
\r
271 if ($member->login($login, $pw) ) {
\r
273 $member->newCookieKey();
\r
274 $member->setCookies($shared);
\r
276 if ($CONF['secureCookieKey']!=='none') {
\r
277 // secure cookie key
\r
278 $member->setCookieKey(md5($member->getCookieKey().$CONF['secureCookieKeyIP']));
\r
282 // allows direct access to parts of the admin area after logging in
\r
284 $action = $nextaction;
\r
288 'member' => &$member,
\r
289 'username' => $login
\r
291 $manager->notify('LoginSuccess', $param);
\r
292 $errormessage = '';
\r
293 ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");
\r
295 // errormessage for [%errordiv%]
\r
296 $trimlogin = trim($login);
\r
297 if (empty($trimlogin))
\r
299 $errormessage = "Please enter a username.";
\r
303 $errormessage = 'Login failed for ' . $login;
\r
305 $param = array('username' => $login);
\r
306 $manager->notify('LoginFailed', $param);
\r
307 ACTIONLOG::add(INFO, $errormessage);
\r
311 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
313 } elseif (serverVar('PHP_AUTH_USER') && serverVar('PHP_AUTH_PW')) {
\r
314 // HTTP Authentication
\r
315 $login = serverVar('PHP_AUTH_USER');
\r
316 $pw = serverVar('PHP_AUTH_PW');
\r
318 if ($member->login($login, $pw) ) {
\r
319 $param = array('member' => &$member);
\r
320 $manager->notify('LoginSuccess', $param);
\r
321 ACTIONLOG::add(INFO, "HTTP authentication successful for $login");
\r
323 $param = array('username' => $login);
\r
324 $manager->notify('LoginFailed', $param);
\r
325 ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);
\r
327 //Since bad credentials, generate an apropriate error page
\r
328 header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");
\r
329 header('HTTP/1.0 401 Unauthorized');
\r
330 echo 'Invalid username or password';
\r
335 } elseif (($action == 'logout') && (!headers_sent() ) && cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
336 // remove cookies on logout
\r
337 setcookie($CONF['CookiePrefix'] . 'user', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
338 setcookie($CONF['CookiePrefix'] . 'loginkey', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
339 $param = array('username' => cookieVar($CONF['CookiePrefix'] . 'user'));
\r
340 $manager->notify('Logout', $param);
\r
341 } elseif (cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
342 // Cookie Authentication
\r
343 $ck=cookieVar($CONF['CookiePrefix'] . 'loginkey');
\r
344 // secure cookie key
\r
345 $ck=substr($ck,0,32); // avoid md5 collision by using a long key
\r
346 if ($CONF['secureCookieKey']!=='none') $ck=md5($ck.$CONF['secureCookieKeyIP']);
\r
347 $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), $ck );
\r
350 // renew cookies when not on a shared computer
\r
351 if ($res && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) && (!headers_sent() ) ) {
\r
352 $member->setCookieKey(cookieVar($CONF['CookiePrefix'] . 'loginkey'));
\r
353 $member->setCookies();
\r
358 $param = array('loggedIn' => $member->isLoggedIn());
\r
359 $manager->notify('PostAuthentication', $param);
\r
362 // first, let's see if the site is disabled or not. always allow admin area access.
\r
363 if ($CONF['DisableSite'] && !$member->isAdmin() && !$CONF['UsingAdminArea']) {
\r
364 redirect($CONF['DisableSiteURL']);
\r
368 // load other classes
\r
369 include($DIR_LIBS . 'PARSER.php');
\r
370 include($DIR_LIBS . 'SKIN.php');
\r
371 include($DIR_LIBS . 'TEMPLATE.php');
\r
372 include($DIR_LIBS . 'BLOG.php');
\r
373 include($DIR_LIBS . 'BODYACTIONS.php');
\r
374 include($DIR_LIBS . 'COMMENTS.php');
\r
375 include($DIR_LIBS . 'COMMENT.php');
\r
376 //include($DIR_LIBS . 'ITEM.php');
\r
377 include($DIR_LIBS . 'NOTIFICATION.php');
\r
378 include($DIR_LIBS . 'BAN.php');
\r
379 include($DIR_LIBS . 'PAGEFACTORY.php');
\r
380 include($DIR_LIBS . 'SEARCH.php');
\r
381 include($DIR_LIBS . 'entity.php');
\r
384 // set lastVisit cookie (if allowed)
\r
385 if (!headers_sent() ) {
\r
386 if ($CONF['LastVisit']) {
\r
387 setcookie($CONF['CookiePrefix'] . 'lastVisit', time(), time() + 2592000, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
389 setcookie($CONF['CookiePrefix'] . 'lastVisit', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
393 // read language file, only after user has been initialized
\r
394 $language = getLanguageName();
\r
396 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
397 # original ereg_replace: ereg_replace( '[\\|/]', '', $language) . '.php')
\r
398 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
399 include($DIR_LANG . preg_replace('#[\\\\|/]#', '', $language) . '.php');
\r
401 // check if valid charset
\r
402 if (!encoding_check(false, false, _CHARSET)) {
\r
403 foreach(array($_GET, $_POST) as $input) {
\r
404 array_walk($input, 'encoding_check');
\r
408 sql_set_charset_jp(_CHARSET);
\r
411 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
413 // To remove after v2.5 is released and language files have been updated.
\r
414 // Including this makes sure that language files for v2.5beta can still be used for v2.5final
\r
415 // without having weird _SETTINGS_EXTAUTH string showing up in the admin area.
\r
416 if (!defined('_MEMBERS_BYPASS'))
\r
418 define('_SETTINGS_EXTAUTH', 'Enable External Authentication');
\r
419 define('_WARNING_EXTAUTH', 'Warning: Enable only if needed.');
\r
420 define('_MEMBERS_BYPASS', 'Use External Authentication');
\r
425 // make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined
\r
426 if (!defined('_ARCHIVETYPE_MONTH') )
\r
428 define('_ARCHIVETYPE_DAY', 'day');
\r
429 define('_ARCHIVETYPE_MONTH', 'month');
\r
430 define('_ARCHIVETYPE_YEAR', 'year');
\r
433 // decode path_info
\r
434 if ($CONF['URLMode'] == 'pathinfo') {
\r
435 // initialize keywords if this hasn't been done before
\r
436 if (!isset($CONF['ItemKey']) || $CONF['ItemKey'] == '') {
\r
437 $CONF['ItemKey'] = 'item';
\r
440 if (!isset($CONF['ArchiveKey']) || $CONF['ArchiveKey'] == '') {
\r
441 $CONF['ArchiveKey'] = 'archive';
\r
444 if (!isset($CONF['ArchivesKey']) || $CONF['ArchivesKey'] == '') {
\r
445 $CONF['ArchivesKey'] = 'archives';
\r
448 if (!isset($CONF['MemberKey']) || $CONF['MemberKey'] == '') {
\r
449 $CONF['MemberKey'] = 'member';
\r
452 if (!isset($CONF['BlogKey']) || $CONF['BlogKey'] == '') {
\r
453 $CONF['BlogKey'] = 'blog';
\r
456 if (!isset($CONF['CategoryKey']) || $CONF['CategoryKey'] == '') {
\r
457 $CONF['CategoryKey'] = 'category';
\r
460 if (!isset($CONF['SpecialskinKey']) || $CONF['SpecialskinKey'] == '') {
\r
461 $CONF['SpecialskinKey'] = 'special';
\r
466 'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...
\r
467 'info' => $virtualpath,
\r
468 'complete' => &$parsed
\r
470 $manager->notify('ParseURL', $param);
\r
473 // default implementation
\r
474 $data = explode("/", $virtualpath );
\r
475 for ($i = 0; $i < sizeof($data); $i++) {
\r
476 switch ($data[$i]) {
\r
477 case $CONF['ItemKey']: // item/1 (blogid)
\r
480 if ($i < sizeof($data) ) {
\r
481 $itemid = intval($data[$i]);
\r
485 case $CONF['ArchivesKey']: // archives/1 (blogid)
\r
488 if ($i < sizeof($data) ) {
\r
489 $archivelist = intval($data[$i]);
\r
493 case $CONF['ArchiveKey']: // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)
\r
494 if ((($i + 1) < sizeof($data) ) && (!strstr($data[$i + 1], '-') ) ) {
\r
495 $blogid = intval($data[++$i]);
\r
500 if ($i < sizeof($data) ) {
\r
501 $archive = $data[$i];
\r
505 case 'blogid': // blogid/1
\r
506 case $CONF['BlogKey']: // blog/1
\r
509 if ($i < sizeof($data) ) {
\r
510 $blogid = intval($data[$i]);
\r
514 case $CONF['CategoryKey']: // category/1 (catid)
\r
518 if ($i < sizeof($data) ) {
\r
519 $catid = intval($data[$i]);
\r
523 case $CONF['MemberKey']:
\r
526 if ($i < sizeof($data) ) {
\r
527 $memberid = intval($data[$i]);
\r
531 case $CONF['SpecialskinKey']:
\r
534 if ($i < sizeof($data) ) {
\r
535 $special = $data[$i];
\r
536 $_REQUEST['special'] = $special;
\r
546 /* PostParseURL is a place to cleanup any of the path-related global variables before the selector function is run.
\r
547 It has 2 values in the data in case the original virtualpath is needed, but most the use will be in tweaking
\r
548 global variables to clean up (scrub out catid or add catid) or to set someother global variable based on
\r
549 the values of something like catid or itemid
\r
553 'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...
\r
554 'info' => $virtualpath
\r
556 $manager->notify('PostParseURL', $param);
\r
558 function include_libs($file,$once=true,$require=true){
\r
560 if (!is_dir($DIR_LIBS)) exit;
\r
561 if ($once && $require) require_once($DIR_LIBS.$file);
\r
562 elseif ($once && !$require) include_once($DIR_LIBS.$file);
\r
563 elseif ($require) require($DIR_LIBS.$file);
\r
564 else include($DIR_LIBS.$file);
\r
567 function include_plugins($file,$once=true,$require=true){
\r
568 global $DIR_PLUGINS;
\r
569 if (!is_dir($DIR_PLUGINS)) exit;
\r
570 if ($once && $require) require_once($DIR_PLUGINS.$file);
\r
571 elseif ($once && !$require) include_once($DIR_PLUGINS.$file);
\r
572 elseif ($require) require($DIR_PLUGINS.$file);
\r
573 else include($DIR_PLUGINS.$file);
\r
576 function intPostVar($name) {
\r
577 return intval(postVar($name) );
\r
580 function intGetVar($name) {
\r
581 return intval(getVar($name) );
\r
584 function intRequestVar($name) {
\r
585 return intval(requestVar($name) );
\r
588 function intCookieVar($name) {
\r
589 return intval(cookieVar($name) );
\r
593 * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)
\r
595 function getNucleusVersion() {
\r
600 * power users can install patches in between nucleus releases. These patches
\r
601 * usually add new functionality in the plugin API and allow those to
\r
602 * be tested without having to install CVS.
\r
604 function getNucleusPatchLevel() {
\r
609 * returns the latest version available for download from nucleuscms.org
\r
610 * or false if unable to attain data
\r
611 * format will be major.minor/patachlevel
\r
612 * e.g. 3.41 or 3.41/02
\r
614 function getLatestVersion() {
\r
615 if (!function_exists('curl_init')) return false;
\r
616 $crl = curl_init();
\r
618 curl_setopt ($crl, CURLOPT_URL,'http://nucleuscms.org/version_check.php');
\r
619 curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);
\r
620 curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);
\r
621 $ret = curl_exec($crl);
\r
628 * Connects to mysql server
\r
630 /* moved to $DIR_LIBS/sql/*.php handler files
\r
631 function sql_connect() {
\r
632 global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE, $MYSQL_CONN;
\r
634 $MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>', 'Connect Error');
\r
635 mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: ' . mysql_error() . '</p>', 'Connect Error');
\r
637 return $MYSQL_CONN;
\r
641 * returns a prefixed nucleus table name
\r
643 function sql_table($name) {
\r
644 global $MYSQL_PREFIX;
\r
646 if ($MYSQL_PREFIX) {
\r
647 return $MYSQL_PREFIX . 'nucleus_' . $name;
\r
649 return 'nucleus_' . $name;
\r
653 function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
\r
654 global $manager, $CONF;
\r
656 if (!headers_sent() ) {
\r
657 // if content type is application/xhtml+xml, only send it to browsers
\r
658 // that can handle it (IE6 cannot). Otherwise, send text/html
\r
660 // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)
\r
661 // application/xhtml+xml still causes too much problems with the javascript implementations
\r
663 // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,
\r
664 // application/xhtml+xml seems to be working, so we're going to use it if we can.
\r
666 // Note: reverted the following function in JP version
\r
671 ($contenttype == 'application/xhtml+xml')
\r
672 && (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )
\r
674 $contenttype = 'text/html';
\r
679 ($contenttype == 'application/xhtml+xml')
\r
680 && (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))
\r
683 $contenttype = 'text/html';
\r
687 'contentType' => &$contenttype,
\r
688 'charset' => &$charset,
\r
689 'pageType' => $pagetype
\r
691 $manager->notify('PreSendContentType', $param);
\r
693 // strip strange characters
\r
694 $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);
\r
695 $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);
\r
697 if ($charset != '') {
\r
698 header('Content-Type: ' . $contenttype . '; charset=' . $charset);
\r
700 header('Content-Type: ' . $contenttype);
\r
703 // check if valid charset
\r
704 if (!encoding_check(false,false,$charset)) {
\r
705 foreach(array($_GET, $_POST) as $input) {
\r
706 array_walk($input, 'encoding_check');
\r
713 * Errors before the database connection has been made - moved to
\r
715 /* moved to $DIR_LIBS/sql/*.php handler files
\r
716 function startUpError($msg, $title) {
\r
717 if (!defined('_CHARSET')) define('_CHARSET', 'iso-8859-1');
\r
718 header('Content-Type: text/html; charset=' . _CHARSET);
\r
720 <html <?php echo _HTML_XML_NAME_SPACE_AND_LANG_CODE; ?>>
\r
721 <head><meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET?>" />
\r
722 <title><?php echo htmlspecialchars($title)?></title></head>
\r
724 <h1><?php echo htmlspecialchars($title)?></h1>
\r
732 * disconnects from SQL server
\r
734 /* moved to $DIR_LIBS/sql/*.php handler files
\r
735 function sql_disconnect() {
\r
740 * executes an SQL query
\r
742 /* moved to $DIR_LIBS/sql/*.php handler files
\r
743 function sql_query($query) {
\r
746 $res = mysql_query($query) or print("mySQL error with query $query: " . mysql_error() . '<p />');
\r
751 * Highlights a specific query in a given HTML text (not within HTML tags) and returns it
\r
752 * @param string $text text to be highlighted
\r
753 * @param string $expression regular expression to be matched (can be an array of expressions as well)
\r
754 * @param string $highlight highlight to be used (use \\0 to indicate the matched expression)
\r
757 function highlight($text, $expression, $highlight) {
\r
758 if (!$highlight || !$expression)
\r
763 if (is_array($expression) && (count($expression) == 0) )
\r
768 // add a tag in front (is needed for preg_match_all to work correct)
\r
769 $text = '<!--h-->' . $text;
\r
771 // split the HTML up so we have HTML tags
\r
772 // $matches[0][i] = HTML + text
\r
773 // $matches[1][i] = HTML
\r
774 // $matches[2][i] = text
\r
775 preg_match_all('/(<[^>]+>)([^<>]*)/', $text, $matches);
\r
777 // throw it all together again while applying the highlight to the text pieces
\r
779 $count_matches = count($matches[2]);
\r
780 for ($i = 0; $i < $count_matches; $i++) {
\r
783 $result .= $matches[1][$i];
\r
786 if (is_array($expression) )
\r
788 foreach ($expression as $regex)
\r
792 //$matches[2][$i] = @eregi_replace($regex, $highlight, $matches[2][$i]);
\r
793 $matches[2][$i] = @preg_replace("#".$regex."#i", $highlight, $matches[2][$i]);
\r
797 $result .= $matches[2][$i];
\r
801 //$result .= @eregi_replace($expression, $highlight, $matches[2][$i]);
\r
802 $result .= @preg_replace("#".$expression."#i", $highlight, $matches[2][$i]);
\r
810 * Parses a query into an array of expressions that can be passed on to the highlight method
\r
812 function parseHighlight($query) {
\r
813 // TODO: add more intelligent splitting logic
\r
815 // get rid of quotes
\r
816 $query = preg_replace('/\'|"/', '', $query);
\r
822 $aHighlight = explode(' ', $query);
\r
824 for ($i = 0; $i < count($aHighlight); $i++) {
\r
825 $aHighlight[$i] = trim($aHighlight[$i]);
\r
827 // if (strlen($aHighlight[$i]) < 3) {
\r
828 // unset($aHighlight[$i]);
\r
832 if (count($aHighlight) == 1) {
\r
833 return $aHighlight[0];
\r
835 return $aHighlight;
\r
840 * Checks if email address is valid
\r
842 function isValidMailAddress($address) {
\r
843 // enhancement made in 3.6x based on code by Quandary.
\r
844 if (preg_match('/^(?!\\.)(?:\\.?[-a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~]+)+@(?!\\.)(?:\\.?(?!-)[-a-zA-Z0-9]+(?<!-)){2,}$/', $address)) {
\r
851 // some helper functions
\r
852 function getBlogIDFromName($name) {
\r
853 return quickQuery('SELECT bnumber as result FROM ' . sql_table('blog') . ' WHERE bshortname="' . sql_real_escape_string($name) . '"');
\r
856 function getBlogNameFromID($id) {
\r
857 return quickQuery('SELECT bname as result FROM ' . sql_table('blog') . ' WHERE bnumber=' . intval($id) );
\r
860 function getBlogIDFromItemID($itemid) {
\r
861 return quickQuery('SELECT iblog as result FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid) );
\r
864 function getBlogIDFromCommentID($commentid) {
\r
865 return quickQuery('SELECT cblog as result FROM ' . sql_table('comment') . ' WHERE cnumber=' . intval($commentid) );
\r
868 function getBlogIDFromCatID($catid) {
\r
869 return quickQuery('SELECT cblog as result FROM ' . sql_table('category') . ' WHERE catid=' . intval($catid) );
\r
872 function getCatIDFromName($name) {
\r
873 return quickQuery('SELECT catid as result FROM ' . sql_table('category') . ' WHERE cname="' . sql_real_escape_string($name) . '"');
\r
876 function quickQuery($q) {
\r
877 $res = sql_query($q);
\r
878 $obj = sql_fetch_object($res);
\r
879 return $obj->result;
\r
882 function getPluginNameFromPid($pid) {
\r
883 $res = sql_query('SELECT pfile FROM ' . sql_table('plugin') . ' WHERE pid=' . intval($pid) );
\r
884 $obj = sql_fetch_object($res);
\r
885 return $obj->pfile;
\r
888 function selector() {
\r
889 global $itemid, $blogid, $memberid, $query, $amount, $archivelist, $maxresults;
\r
890 global $archive, $skinid, $blog, $memberinfo, $CONF, $member;
\r
891 global $imagepopup, $catid, $special;
\r
894 $actionNames = array('addcomment', 'sendmessage', 'createaccount', 'forgotpassword', 'votepositive', 'votenegative', 'plugin');
\r
895 $action = requestVar('action');
\r
897 if (in_array($action, $actionNames) ) {
\r
898 global $DIR_LIBS, $errormessage;
\r
899 include_once($DIR_LIBS . 'ACTION.php');
\r
901 $errorInfo = $a->doAction($action);
\r
904 $errormessage = $errorInfo['message'];
\r
908 // show error when headers already sent out
\r
909 if (headers_sent() && $CONF['alertOnHeadersSent']) {
\r
911 // try to get line number/filename (extra headers_sent params only exists in PHP 4.3+)
\r
912 if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=') ) {
\r
913 headers_sent($hsFile, $hsLine);
\r
914 $extraInfo = sprintf(_GFUNCTIONS_HEADERSALREADYSENT_FILE,$hsFile,$hsLine);
\r
920 sprintf(_GFUNCTIONS_HEADERSALREADYSENT_TXT,$extraInfo),
\r
921 _GFUNCTIONS_HEADERSALREADYSENT_TITLE
\r
926 // make is so ?archivelist without blogname or blogid shows the archivelist
\r
927 // for the default weblog
\r
928 if (serverVar('QUERY_STRING') == 'archivelist') {
\r
929 $archivelist = $CONF['DefaultBlog'];
\r
932 // now decide which type of skin we need
\r
934 // itemid given -> only show that item
\r
937 if (!$manager->existsItem($itemid,intval($CONF['allowFuture']),intval($CONF['allowDrafts']))) {
\r
938 doError(_ERROR_NOSUCHITEM);
\r
941 global $itemidprev, $itemidnext, $catid, $itemtitlenext, $itemtitleprev;
\r
943 // 1. get timestamp, blogid and catid for item
\r
944 $query = 'SELECT itime, iblog, icat FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid);
\r
945 $res = sql_query($query);
\r
946 $obj = sql_fetch_object($res);
\r
948 // if a different blog id has been set through the request or selectBlog(),
\r
951 if ($blogid && (intval($blogid) != $obj->iblog) ) {
\r
952 if (!headers_sent()) {
\r
953 $b =& $manager->getBlog($obj->iblog);
\r
954 $CONF['ItemURL'] = $b->getURL();
\r
955 if ($CONF['URLMode'] == 'pathinfo' and substr($CONF['ItemURL'],-1) == '/')
\r
956 $CONF['ItemURL'] = substr($CONF['ItemURL'], 0, -1);
\r
957 $correctURL = createItemLink($itemid, '');
\r
958 redirect($correctURL);
\r
961 doError(_ERROR_NOSUCHITEM);
\r
965 // if a category has been selected which doesn't match the item, ignore the
\r
967 if (($catid != 0) && ($catid != $obj->icat) ) {
\r
971 $blogid = $obj->iblog;
\r
972 $timestamp = strtotime($obj->itime);
\r
974 $b =& $manager->getBlog($blogid);
\r
976 if ($b->isValidCategory($catid) ) {
\r
977 $catextra = ' and icat=' . $catid;
\r
982 // get previous itemid and title
\r
983 $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
984 $res = sql_query($query);
\r
986 $obj = sql_fetch_object($res);
\r
989 $itemidprev = $obj->inumber;
\r
990 $itemtitleprev = $obj->ititle;
\r
993 // get next itemid and title
\r
994 $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
995 $res = sql_query($query);
\r
997 $obj = sql_fetch_object($res);
\r
1000 $itemidnext = $obj->inumber;
\r
1001 $itemtitlenext = $obj->ititle;
\r
1004 } elseif ($archive) {
\r
1006 $type = 'archive';
\r
1008 // get next and prev month links ...
\r
1009 global $archivenext, $archiveprev, $archivetype, $archivenextexists, $archiveprevexists;
\r
1011 // sql queries for the timestamp of the first and the last published item
\r
1012 $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
1013 $first_timestamp=quickQuery ($query);
\r
1014 $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
1015 $last_timestamp=quickQuery ($query);
\r
1017 sscanf($archive, '%d-%d-%d', $y, $m, $d);
\r
1020 $archivetype = _ARCHIVETYPE_DAY;
\r
1021 $t = mktime(0, 0, 0, $m, $d, $y);
\r
1022 // one day has 24 * 60 * 60 = 86400 seconds
\r
1023 $archiveprev = strftime('%Y-%m-%d', $t - 86400 );
\r
1024 // check for published items
\r
1025 if ($t > $first_timestamp) {
\r
1026 $archiveprevexists = true;
\r
1029 $archiveprevexists = false;
\r
1034 $archivenext = strftime('%Y-%m-%d', $t);
\r
1035 if ($t < $last_timestamp) {
\r
1036 $archivenextexists = true;
\r
1039 $archivenextexists = false;
\r
1042 } elseif ($m == 0) {
\r
1043 $archivetype = _ARCHIVETYPE_YEAR;
\r
1044 $t = mktime(0, 0, 0, 12, 31, $y - 1);
\r
1045 // one day before is in the previous year
\r
1046 $archiveprev = strftime('%Y', $t);
\r
1047 if ($t > $first_timestamp) {
\r
1048 $archiveprevexists = true;
\r
1051 $archiveprevexists = false;
\r
1054 // timestamp for the next year
\r
1055 $t = mktime(0, 0, 0, 1, 1, $y + 1);
\r
1056 $archivenext = strftime('%Y', $t);
\r
1057 if ($t < $last_timestamp) {
\r
1058 $archivenextexists = true;
\r
1061 $archivenextexists = false;
\r
1064 $archivetype = _ARCHIVETYPE_MONTH;
\r
1065 $t = mktime(0, 0, 0, $m, 1, $y);
\r
1066 // one day before is in the previous month
\r
1067 $archiveprev = strftime('%Y-%m', $t - 86400);
\r
1068 if ($t > $first_timestamp) {
\r
1069 $archiveprevexists = true;
\r
1072 $archiveprevexists = false;
\r
1075 // timestamp for the next month
\r
1076 $t = mktime(0, 0, 0, $m+1, 1, $y);
\r
1077 $archivenext = strftime('%Y-%m', $t);
\r
1078 if ($t < $last_timestamp) {
\r
1079 $archivenextexists = true;
\r
1082 $archivenextexists = false;
\r
1086 } elseif ($archivelist) {
\r
1087 $type = 'archivelist';
\r
1089 if (is_numeric($archivelist)) {
\r
1090 $blogid = intVal($archivelist);
\r
1092 $blogid = getBlogIDFromName($archivelist);
\r
1096 doError(_ERROR_NOSUCHBLOG);
\r
1099 } elseif ($query) {
\r
1102 $query = stripslashes($query);
\r
1103 if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/", $query)){
\r
1106 // $order = (_CHARSET == 'EUC-JP') ? 'EUC-JP, UTF-8,' : 'UTF-8, EUC-JP,';
\r
1107 // $query = mb_convert_encoding($query, _CHARSET, $order . ' JIS, SJIS, ASCII');
\r
1108 switch(strtolower(_CHARSET)){
\r
1110 $order = 'ASCII, UTF-8, EUC-JP, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1113 $order = 'ASCII, EUC-CN, EUC-JP, UTF-8, JIS, SJIS, ISO-8859-1';
\r
1116 // Note that shift_jis is only supported for output.
\r
1117 // Using shift_jis in DB is prohibited.
\r
1118 $order = 'ASCII, SJIS, EUC-JP, UTF-8, JIS, EUC-CN, ISO-8859-1';
\r
1121 // euc-jp,iso-8859-x,windows-125x
\r
1122 $order = 'ASCII, EUC-JP, UTF-8, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1125 $query = mb_convert_encoding($query, _CHARSET, $order);
\r
1126 if (is_numeric($blogid)) {
\r
1127 $blogid = intVal($blogid);
\r
1129 $blogid = getBlogIDFromName($blogid);
\r
1133 doError(_ERROR_NOSUCHBLOG);
\r
1136 } elseif ($memberid) {
\r
1139 if (!MEMBER::existsID($memberid) ) {
\r
1140 doError(_ERROR_NOSUCHMEMBER);
\r
1143 $memberinfo = $manager->getMember($memberid);
\r
1145 } elseif ($imagepopup) {
\r
1146 // media object (images etc.)
\r
1147 $type = 'imagepopup';
\r
1149 // TODO: check if media-object exists
\r
1150 // TODO: set some vars?
\r
1152 // show regular index page
\r
1157 // any type of skin with catid
\r
1158 if ($catid && !$blogid) {
\r
1159 $blogid = getBlogIDFromCatID($catid);
\r
1162 // decide which blog should be displayed
\r
1164 $blogid = $CONF['DefaultBlog'];
\r
1167 $b =& $manager->getBlog($blogid);
\r
1168 $blog = $b; // references can't be placed in global variables?
\r
1170 if (!$blog->isValid) {
\r
1171 doError(_ERROR_NOSUCHBLOG);
\r
1174 // set catid if necessary
\r
1176 // check if the category is valid
\r
1177 if (!$blog->isValidCategory($catid)) {
\r
1178 doError(_ERROR_NOSUCHCATEGORY);
\r
1180 $blog->setSelectedCategory($catid);
\r
1184 // decide which skin should be used
\r
1185 if ($skinid != '' && ($skinid == 0) ) {
\r
1186 selectSkin($skinid);
\r
1190 $skinid = $blog->getDefaultSkin();
\r
1193 //$special = requestVar('special'); //get at top of file as global
\r
1194 if (!empty($special) && isValidShortName($special)) {
\r
1195 $type = strtolower($special);
\r
1198 $skin = new SKIN($skinid);
\r
1200 if (!$skin->isValid) {
\r
1201 doError(_ERROR_NOSUCHSKIN);
\r
1204 // set global skinpart variable so can determine quickly what is being parsed from any plugin or phpinclude
\r
1206 $skinpart = $type;
\r
1209 $skin->parse($type);
\r
1211 // check to see we should throw JustPosted event
\r
1212 $blog->checkJustPosted();
\r
1216 * Show error skin with given message. An optional skin-object to use can be given
\r
1218 function doError($msg, $skin = '') {
\r
1219 global $errormessage, $CONF, $skinid, $blogid, $manager;
\r
1221 if ($skin == '') {
\r
1223 if (SKIN::existsID($skinid) ) {
\r
1224 $skin = new SKIN($skinid);
\r
1225 } elseif ($manager->existsBlogID($blogid) ) {
\r
1226 $blog =& $manager->getBlog($blogid);
\r
1227 $skin = new SKIN($blog->getDefaultSkin() );
\r
1228 } elseif ($CONF['DefaultBlog']) {
\r
1229 $blog =& $manager->getBlog($CONF['DefaultBlog']);
\r
1230 $skin = new SKIN($blog->getDefaultSkin() );
\r
1232 // this statement should actually never be executed
\r
1233 $skin = new SKIN($CONF['BaseSkin']);
\r
1238 $skinid = $skin->id;
\r
1239 $errormessage = $msg;
\r
1240 $skin->parse('error');
\r
1244 function getConfig() {
\r
1247 $query = 'SELECT * FROM ' . sql_table('config');
\r
1248 $res = sql_query($query);
\r
1250 while ($obj = sql_fetch_object($res) ) {
\r
1251 $CONF[$obj->name] = $obj->value;
\r
1255 // some checks for names of blogs, categories, templates, members, ...
\r
1256 function isValidShortName($name) {
\r
1257 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
\r
1258 # original eregi: eregi('^[a-z0-9]+$', $name)
\r
1259 return preg_match('#^[a-z0-9]+$#i', $name);
\r
1262 function isValidDisplayName($name) {
\r
1263 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
\r
1264 # original eregi: eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name)
\r
1265 return preg_match('#^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$#i', $name);
\r
1268 function isValidCategoryName($name) {
\r
1272 function isValidTemplateName($name) {
\r
1273 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
\r
1274 # original eregi: eregi('^[a-z0-9/]+$', $name)
\r
1275 return preg_match('#^[a-z0-9/]+$#i', $name);
\r
1278 function isValidSkinName($name) {
\r
1279 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
\r
1280 # original eregi: eregi('^[a-z0-9/]+$', $name);
\r
1281 return preg_match('#^[a-z0-9/]+$#i', $name);
\r
1284 // add and remove linebreaks
\r
1285 function addBreaks($var) {
\r
1286 return nl2br($var);
\r
1289 function removeBreaks($var) {
\r
1290 return preg_replace("/<br \/>([\r\n])/", "$1", $var);
\r
1293 // shortens a text string to maxlength ($toadd) is what needs to be added
\r
1294 // at the end (end length is <= $maxlength)
\r
1295 function shorten($text, $maxlength, $toadd) {
\r
1296 // 1. remove entities...
\r
1297 // $trans = get_html_translation_table(HTML_ENTITIES);
\r
1298 $trans = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
1299 $trans = array_flip($trans);
\r
1300 $text = strtr($text, $trans);
\r
1302 // 2. the actual shortening
\r
1303 if (strlen($text) > $maxlength) {
\r
1304 // $text = substr($text, 0, $maxlength - strlen($toadd) ) . $toadd;
\r
1305 $text = mb_strimwidth($text, 0, $maxlength, $toadd, _CHARSET); // for Japanese
\r
1312 * Converts a unix timestamp to a mysql DATETIME format, and places
\r
1313 * quotes around it.
\r
1315 function mysqldate($timestamp) {
\r
1316 return '"' . date('Y-m-d H:i:s', $timestamp) . '"';
\r
1320 * functions for use in index.php
\r
1322 function selectBlog($shortname) {
\r
1323 global $blogid, $archivelist;
\r
1325 $blogid = getBlogIDFromName($shortname);
\r
1328 // also force archivelist variable, if it is set
\r
1329 if ($archivelist) {
\r
1330 $archivelist = $blogid;
\r
1334 function selectSkin($skinname) {
\r
1337 $skinid = SKIN::getIdFromName($skinname);
\r
1342 * Can take either a category ID or a category name (be aware that
\r
1343 * multiple categories can have the same name)
\r
1345 function selectCategory($cat) {
\r
1348 if (is_numeric($cat) ) {
\r
1349 $catid = intval($cat);
\r
1351 $catid = getCatIDFromName($cat);
\r
1356 function selectItem($id) {
\r
1359 $itemid = intval($id);
\r
1363 // force the use of a language file (warning: can cause warnings)
\r
1364 function selectLanguage($language) {
\r
1368 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
1369 # original ereg_replace: preg_replace( '@\\|/@', '', $language) . '.php')
\r
1370 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
1372 include($DIR_LANG . preg_replace('#[\\\\|/]#', '', $language) . '.php');
\r
1376 function parseFile($filename, $includeMode = 'normal', $includePrefix = '') {
\r
1377 $handler = new ACTIONS('fileparser');
\r
1378 $parser = new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);
\r
1379 $handler->parser =& $parser;
\r
1381 // set IncludeMode properties of parser
\r
1382 PARSER::setProperty('IncludeMode', $includeMode);
\r
1383 PARSER::setProperty('IncludePrefix', $includePrefix);
\r
1385 if (!file_exists($filename) ) {
\r
1386 doError(_GFUNCTIONS_PARSEFILE_FILEMISSING);
\r
1389 $fsize = filesize($filename);
\r
1391 if ($fsize <= 0) {
\r
1396 $fd = fopen ($filename, 'r');
\r
1397 $contents = fread ($fd, $fsize);
\r
1400 // parse file contents
\r
1401 $parser->parse($contents);
\r
1405 * Outputs a debug message
\r
1407 function debug($msg) {
\r
1408 echo '<p><b>' . $msg . "</b></p>\n";
\r
1412 function addToLog($level, $msg) {
\r
1413 ACTIONLOG::add($level, $msg);
\r
1416 // shows a link to help file
\r
1417 function help($id) {
\r
1418 echo helpHtml($id);
\r
1421 function helpHtml($id) {
\r
1423 return helplink($id) . '<img src="' . $CONF['AdminURL'] . 'documentation/icon-help.gif" width="15" height="15" alt="' . _HELP_TT . '" title="' . _HELP_TT . '" /></a>';
\r
1426 function helplink($id) {
\r
1428 return '<a href="' . $CONF['AdminURL'] . 'documentation/help.html#'. $id . '" onclick="if (event && event.preventDefault) event.preventDefault(); return help(this.href);">';
\r
1431 function getMailFooter() {
\r
1432 $message = "\n\n-----------------------------";
\r
1433 $message .= "\n Powered by Nucleus CMS";
\r
1434 $message .= "\n(http://www.nucleuscms.org/)";
\r
1439 * Returns the name of the language to use
\r
1440 * preference priority: member - site
\r
1441 * defaults to english when no good language found
\r
1443 * checks if file exists, etc...
\r
1445 function getLanguageName() {
\r
1446 global $CONF, $member;
\r
1448 if ($member && $member->isLoggedIn() ) {
\r
1449 // try to use members language
\r
1450 $memlang = $member->getLanguage();
\r
1452 if (($memlang != '') && (checkLanguage($memlang) ) ) {
\r
1457 // use default language
\r
1458 if (checkLanguage($CONF['Language']) ) {
\r
1459 return $CONF['Language'];
\r
1466 * Includes a PHP file. This method can be called while parsing templates and skins
\r
1468 function includephp($filename) {
\r
1469 // make predefined variables global, so most simple scripts can be used here
\r
1471 // apache (names taken from PHP doc)
\r
1472 global $GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE, $SERVER_PROTOCOL;
\r
1473 global $REQUEST_METHOD, $QUERY_STRING, $DOCUMENT_ROOT, $HTTP_ACCEPT;
\r
1474 global $HTTP_ACCEPT_CHARSET, $HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE;
\r
1475 global $HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER, $HTTP_USER_AGENT;
\r
1476 global $REMOTE_ADDR, $REMOTE_PORT, $SCRIPT_FILENAME, $SERVER_ADMIN;
\r
1477 global $SERVER_PORT, $SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME;
\r
1478 global $REQUEST_URI;
\r
1480 // php (taken from PHP doc)
\r
1481 global $argv, $argc, $PHP_SELF, $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS;
\r
1482 global $HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS, $HTTP_SESSION_VARS;
\r
1485 global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;
\r
1487 if (@file_exists($filename) ) {
\r
1488 include($filename);
\r
1493 * Checks if a certain language exists
\r
1494 * @param string $lang
\r
1497 function checkLanguage($lang) {
\r
1499 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
1500 # original ereg_replace: ereg_replace( '[\\|/]', '', $lang) . '.php')
\r
1501 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
1502 return file_exists($DIR_LANG . preg_replace('#[\\\\|/]#', '', $lang) . '.php');
\r
1506 * Checks if a certain plugin exists
\r
1507 * @param string $plug
\r
1510 function checkPlugin($plug) {
\r
1512 global $DIR_PLUGINS;
\r
1514 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
1515 # original ereg_replace: ereg_replace( '[\\|/]', '', $plug) . '.php')
\r
1516 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
1518 return file_exists($DIR_PLUGINS . preg_replace('#[\\\\|/]#', '', $plug) . '.php');
\r
1523 * Centralisation of the functions that generate links
\r
1525 function createItemLink($itemid, $extra = '') {
\r
1526 return createLink('item', array('itemid' => $itemid, 'extra' => $extra) );
\r
1529 function createMemberLink($memberid, $extra = '') {
\r
1530 return createLink('member', array('memberid' => $memberid, 'extra' => $extra) );
\r
1533 function createCategoryLink($catid, $extra = '') {
\r
1534 return createLink('category', array('catid' => $catid, 'extra' => $extra) );
\r
1537 function createArchiveListLink($blogid = '', $extra = '') {
\r
1538 return createLink('archivelist', array('blogid' => $blogid, 'extra' => $extra) );
\r
1541 function createArchiveLink($blogid, $archive, $extra = '') {
\r
1542 return createLink('archive', array('blogid' => $blogid, 'archive' => $archive, 'extra' => $extra) );
\r
1545 function createBlogidLink($blogid, $params = '') {
\r
1546 return createLink('blog', array('blogid' => $blogid, 'extra' => $params) );
\r
1549 function createLink($type, $args) {
\r
1550 global $manager, $CONF;
\r
1552 $generatedURL = '';
\r
1553 $usePathInfo = ($CONF['URLMode'] == 'pathinfo');
\r
1555 // ask plugins first
\r
1558 if ($usePathInfo) {
\r
1562 'completed' => &$created,
\r
1565 $manager->notify('GenerateURL', $param);
\r
1568 // if a plugin created the URL, return it
\r
1573 // default implementation
\r
1576 if ($usePathInfo) {
\r
1577 $url = $CONF['ItemURL'] . '/' . $CONF['ItemKey'] . '/' . $args['itemid'];
\r
1579 $url = $CONF['ItemURL'] . '?itemid=' . $args['itemid'];
\r
1584 if ($usePathInfo) {
\r
1585 $url = $CONF['MemberURL'] . '/' . $CONF['MemberKey'] . '/' . $args['memberid'];
\r
1587 $url = $CONF['MemberURL'] . '?memberid=' . $args['memberid'];
\r
1592 if ($usePathInfo) {
\r
1593 $url = $CONF['CategoryURL'] . '/' . $CONF['CategoryKey'] . '/' . $args['catid'];
\r
1595 $url = $CONF['CategoryURL'] . '?catid=' . $args['catid'];
\r
1599 case 'archivelist':
\r
1600 if (!$args['blogid']) {
\r
1601 $args['blogid'] = $CONF['DefaultBlog'];
\r
1604 if ($usePathInfo) {
\r
1605 $url = $CONF['ArchiveListURL'] . '/' . $CONF['ArchivesKey'] . '/' . $args['blogid'];
\r
1607 $url = $CONF['ArchiveListURL'] . '?archivelist=' . $args['blogid'];
\r
1612 if ($usePathInfo) {
\r
1613 $url = $CONF['ArchiveURL'] . '/' . $CONF['ArchiveKey'] . '/'.$args['blogid'].'/' . $args['archive'];
\r
1615 $url = $CONF['ArchiveURL'] . '?blogid='.$args['blogid'].'&archive=' . $args['archive'];
\r
1620 if ($usePathInfo) {
\r
1621 $url = $CONF['BlogURL'] . '/' . $CONF['BlogKey'] . '/' . $args['blogid'];
\r
1623 $url = $CONF['BlogURL'] . '?blogid=' . $args['blogid'];
\r
1628 return addLinkParams($url, (isset($args['extra'])? $args['extra'] : null));
\r
1631 function createBlogLink($url, $params) {
\r
1633 if ($CONF['URLMode'] == 'normal') {
\r
1634 if (strpos($url, '?') === FALSE && is_array($params)) {
\r
1635 $fParam = reset($params);
\r
1636 $fKey = key($params);
\r
1637 array_shift($params);
\r
1638 $url .= '?' . $fKey . '=' . $fParam;
\r
1640 } elseif ($CONF['URLMode'] == 'pathinfo' && substr($url, -1) == '/') {
\r
1641 $url = substr($url, 0, -1);
\r
1643 return addLinkParams($url, $params);
\r
1646 function addLinkParams($link, $params) {
\r
1649 if (is_array($params) ) {
\r
1651 if ($CONF['URLMode'] == 'pathinfo') {
\r
1652 foreach ($params as $param => $value) {
\r
1653 // change in 3.63 to fix problem where URL generated with extra params mike look like category/4/blogid/1
\r
1654 // but they should use the URL keys like this: category/4/blog/1
\r
1655 // if user wants old urls back, set $CONF['NoURLKeysInExtraParams'] = 1; in config.php
\r
1656 if (isset($CONF['NoURLKeysInExtraParams']) && $CONF['NoURLKeysInExtraParams'] == 1)
\r
1658 $link .= '/' . $param . '/' . urlencode($value);
\r
1662 $link .= '/' . $CONF['ItemKey'] . '/' . urlencode($value);
\r
1665 $link .= '/' . $CONF['MemberKey'] . '/' . urlencode($value);
\r
1668 $link .= '/' . $CONF['CategoryKey'] . '/' . urlencode($value);
\r
1670 case 'archivelist':
\r
1671 $link .= '/' . $CONF['ArchivesKey'] . '/' . urlencode($value);
\r
1674 $link .= '/' . $CONF['ArchiveKey'] . '/' . urlencode($value);
\r
1677 $link .= '/' . $CONF['BlogKey'] . '/' . urlencode($value);
\r
1680 $link .= '/' . $param . '/' . urlencode($value);
\r
1687 foreach ($params as $param => $value) {
\r
1688 $link .= '&' . $param . '=' . urlencode($value);
\r
1698 * @param $querystr
\r
1699 * querystring to alter (e.g. foo=1&bar=2&x=y)
\r
1701 * name of parameter to change (e.g. 'foo')
\r
1703 * New value for that parameter (e.g. 3)
\r
1705 * altered query string (for the examples above: foo=3&bar=2&x=y)
\r
1707 function alterQueryStr($querystr, $param, $value) {
\r
1708 $vars = explode('&', $querystr);
\r
1711 for ($i = 0; $i < count($vars); $i++) {
\r
1712 $v = explode('=', $vars[$i]);
\r
1714 if ($v[0] == $param) {
\r
1716 $vars[$i] = implode('=', $v);
\r
1723 $vars[] = $param . '=' . $value;
\r
1726 return ltrim(implode('&', $vars), '&');
\r
1729 // passes one variable as hidden input field (multiple fields for arrays)
\r
1730 // @see passRequestVars in varsx.x.x.php
\r
1731 function passVar($key, $value) {
\r
1733 if (is_array($value) ) {
\r
1734 for ($i = 0; $i < sizeof($value); $i++) {
\r
1735 passVar($key . '[' . $i . ']', $value[$i]);
\r
1741 // other values: do stripslashes if needed
\r
1742 ?><input type="hidden" name="<?php echo htmlspecialchars($key)?>" value="<?php echo htmlspecialchars(undoMagic($value) )?>" /><?php
\r
1746 Date format functions (to be used from [%date(..)%] skinvars
\r
1748 function formatDate($format, $timestamp, $defaultFormat, &$blog) {
\r
1749 // apply blog offset (#42)
\r
1750 $boffset = $blog ? $blog->getTimeOffset() * 3600 : 0;
\r
1751 $offset = date('Z', $timestamp) + $boffset;
\r
1753 switch ($format) {
\r
1755 if ($offset >= 0) {
\r
1759 $offset = -$offset;
\r
1762 $tz .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1763 return date('D, j M Y H:i:s ', $timestamp) . $tz;
\r
1766 $timestamp -= $offset;
\r
1767 return date('D, j M Y H:i:s ', $timestamp) . 'GMT';
\r
1770 $timestamp -= $offset;
\r
1771 return date('Y-m-d\TH:i:s\Z', $timestamp);
\r
1774 if ($offset >= 0) {
\r
1778 $offset = -$offset;
\r
1781 $tz .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1782 return date('Y-m-d\TH:i:s', $timestamp) . $tz;
\r
1785 return strftimejp($format ? $format : $defaultFormat, $timestamp);
\r
1789 function encoding_check($val, $key, $encoding=false, $exclude=false) {
\r
1791 When 3rd argument is set, return if checked already.
\r
1792 When 4th argument is set, set the excluded key(s).
\r
1794 static $search=false, $checked=array(), $excludes=array();
\r
1795 if ($exclude!==false) {
\r
1796 if (is_array($exclude)) {
\r
1797 foreach($exclude as $v) $excludes[$v]=true;
\r
1798 } else $excludes[$exclude]=true;
\r
1801 if ($encoding!==false) {
\r
1802 switch($encoding=strtolower($encoding)){
\r
1804 $search='/([\x00-\x7F]+'.
\r
1805 '|[\xC2-\xDF][\x80-\xBF]'.
\r
1806 '|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]'.
\r
1807 '|[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1808 '|[\xF8-\xFB][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1809 '|[\xFC-\xFD][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF])/';
\r
1812 $search='/([\x00-\x7F]+'.
\r
1813 '|[\x8E][\xA0-\xDF]'.
\r
1814 '|[\x8F]?[\xA1-\xFE][\xA1-\xFE])/';
\r
1817 $search='/([\x00-\x7F]+'.
\r
1818 '|[\xA1-\xF7][\xA1-\xFE])/';
\r
1821 // Note that shift_jis is only supported for output.
\r
1822 // Using shift_jis in DB is prohibited.
\r
1823 $search='/([\x00-\x7F\xA1-\xDF]+'.
\r
1824 '|[\x81-\x9F\xE0-\xFC][\x40-\xFC])/';
\r
1828 if (preg_match('/^iso\-8859\-[0-9]{1,2}$/',$encoding)) break;
\r
1829 if (preg_match('/^windows\-125[0-8]$/',$encoding)) break;
\r
1830 startUpError('<p>Unknown or non-supported encoding.</p>', 'Encoding Error');
\r
1833 if (isset($checked[$encoding])) return true; // Already checked.
\r
1834 $checked[$encoding]=true;
\r
1836 if ($key===false) return false; // Not yet checked.
\r
1837 if ($search===false) return true; // non-multibyte encoding
\r
1838 if (isset($excludes[$key])) return true; // This key isn't checked.
\r
1839 if (is_array($val)) {
\r
1840 array_walk($val, 'encoding_check');
\r
1842 $result=preg_replace($search,'',$val);
\r
1843 if (strlen($result)!=0) {
\r
1844 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1848 $result=preg_replace($search,'',$key);
\r
1849 if (strlen($result)!=0) {
\r
1850 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1856 function checkVars($aVars) {
\r
1857 global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;
\r
1859 foreach ($aVars as $varName) {
\r
1861 if (phpversion() >= '4.1.0') {
\r
1863 if ( isset($_GET[$varName])
\r
1864 || isset($_POST[$varName])
\r
1865 || isset($_COOKIE[$varName])
\r
1866 || isset($_ENV[$varName])
\r
1867 || isset($_SESSION[$varName])
\r
1868 || isset($_FILES[$varName])
\r
1870 die('Sorry. An error occurred.');
\r
1875 if ( isset($HTTP_GET_VARS[$varName])
\r
1876 || isset($HTTP_POST_VARS[$varName])
\r
1877 || isset($HTTP_COOKIE_VARS[$varName])
\r
1878 || isset($HTTP_ENV_VARS[$varName])
\r
1879 || isset($HTTP_SESSION_VARS[$varName])
\r
1880 || isset($HTTP_POST_FILES[$varName])
\r
1882 die('Sorry. An error occurred.');
\r
1891 * Sanitize parameters such as $_GET and $_SERVER['REQUEST_URI'] etc.
\r
1894 function sanitizeParams()
\r
1896 global $HTTP_SERVER_VARS;
\r
1902 // REQUEST_URI of $HTTP_SERVER_VARS
\r
1903 $str =& $HTTP_SERVER_VARS["REQUEST_URI"];
\r
1904 serverStringToArray($str, $array, $frontParam);
\r
1905 sanitizeArray($array);
\r
1906 arrayToServerString($array, $frontParam, $str);
\r
1908 // QUERY_STRING of $HTTP_SERVER_VARS
\r
1909 $str =& $HTTP_SERVER_VARS["QUERY_STRING"];
\r
1910 serverStringToArray($str, $array, $frontParam);
\r
1911 sanitizeArray($array);
\r
1912 arrayToServerString($array, $frontParam, $str);
\r
1914 if (phpversion() >= '4.1.0') {
\r
1915 // REQUEST_URI of $_SERVER
\r
1916 $str =& $_SERVER["REQUEST_URI"];
\r
1917 serverStringToArray($str, $array, $frontParam);
\r
1918 sanitizeArray($array);
\r
1919 arrayToServerString($array, $frontParam, $str);
\r
1921 // QUERY_STRING of $_SERVER
\r
1922 $str =& $_SERVER["QUERY_STRING"];
\r
1923 serverStringToArray($str, $array, $frontParam);
\r
1924 sanitizeArray($array);
\r
1925 arrayToServerString($array, $frontParam, $str);
\r
1929 convArrayForSanitizing($_GET, $array);
\r
1930 sanitizeArray($array);
\r
1931 revertArrayForSanitizing($array, $_GET);
\r
1933 // $_REQUEST (only GET param)
\r
1934 convArrayForSanitizing($_REQUEST, $array);
\r
1935 sanitizeArray($array);
\r
1936 revertArrayForSanitizing($array, $_REQUEST);
\r
1940 * Check ticket when not checked in plugin's admin page
\r
1942 * Also avoid the access to plugin/index.php by guest user.
\r
1944 function ticketForPlugin(){
\r
1945 global $CONF,$DIR_PLUGINS,$member,$ticketforplugin;
\r
1948 $ticketforplugin=array();
\r
1949 $ticketforplugin['ticket'] = FALSE;
\r
1951 /* Check if using plugin's php file. */
\r
1952 if ($p_translated = serverVar('PATH_TRANSLATED') )
\r
1954 if (!file_exists($p_translated) )
\r
1956 $p_translated = '';
\r
1960 if (!$p_translated)
\r
1962 $p_translated = serverVar('SCRIPT_FILENAME');
\r
1963 if (!file_exists($p_translated) )
\r
1965 header("HTTP/1.0 404 Not Found");
\r
1970 $p_translated=str_replace('\\','/',$p_translated);
\r
1971 $d_plugins=str_replace('\\','/',$DIR_PLUGINS);
\r
1973 if (strpos($p_translated, $d_plugins) !== 0)
\r
1975 return;// This isn't plugin php file.
\r
1978 /* Solve the plugin php file or admin directory */
\r
1979 $phppath=substr($p_translated,strlen($d_plugins));
\r
1980 $phppath=preg_replace('#^/#','',$phppath);// Remove the first "/" if exists.
\r
1981 $path=preg_replace('#^NP_(.*)\.php$#','$1',$phppath); // Remove the first "NP_" and the last ".php" if exists.
\r
1982 $path=preg_replace('#^([^/]*)/(.*)$#','$1',$path); // Remove the "/" and beyond.
\r
1984 /* Solve the plugin name. */
\r
1986 $query='SELECT `pfile` FROM '.sql_table('plugin');
\r
1987 $res=sql_query($query);
\r
1988 while($row=sql_fetch_row($res))
\r
1990 $name=substr($row[0],3);
\r
1991 $plugins[strtolower($name)]=$name;
\r
1993 sql_free_result($res);
\r
1995 if ($plugins[$path])
\r
1997 $plugin_name = $plugins[$path];
\r
1999 else if (in_array($path, $plugins))
\r
2001 $plugin_name = $path;
\r
2005 header("HTTP/1.0 404 Not Found");
\r
2009 /* Return if not index.php */
\r
2010 if ( ($phppath != strtolower($plugin_name) . '/') && ($phppath != strtolower($plugin_name) . '/index.php') )
\r
2015 /* Exit if not logged in. */
\r
2016 if ( !$member->isLoggedIn() )
\r
2018 exit(_GFUNCTIONS_YOU_AERNT_LOGGEDIN);
\r
2021 global $manager,$DIR_LIBS,$DIR_LANG,$HTTP_GET_VARS,$HTTP_POST_VARS;
\r
2023 /* Check if this feature is needed (ie, if "$manager->checkTicket()" is not included in the script). */
\r
2024 if (!($p_translated=serverVar('PATH_TRANSLATED')))
\r
2026 $p_translated=serverVar('SCRIPT_FILENAME');
\r
2028 if ($file=@file($p_translated))
\r
2031 foreach($file as $line)
\r
2033 if (preg_match('/[\$]manager([\s]*)[\-]>([\s]*)checkTicket([\s]*)[\(]/i',$prevline.$line))
\r
2041 /* Show a form if not valid ticket */
\r
2042 if ( ( strstr(serverVar('REQUEST_URI'),'?') || serverVar('QUERY_STRING')
\r
2043 || strtoupper(serverVar('REQUEST_METHOD'))=='POST' )
\r
2044 && (!$manager->checkTicket()) )
\r
2046 if (!class_exists('PluginAdmin'))
\r
2048 $language = getLanguageName();
\r
2050 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
2051 # original ereg_replace: ereg_replace( '[\\|/]', '', $language) . '.php')
\r
2052 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
2053 include($DIR_LANG . preg_replace('#[\\\\|/]#', '', $language) . '.php');
\r
2054 include($DIR_LIBS . 'PLUGINADMIN.php');
\r
2057 $oPluginAdmin = new PluginAdmin($plugin_name);
\r
2058 $oPluginAdmin->start();
\r
2059 echo '<p>' . _ERROR_BADTICKET . "</p>\n";
\r
2061 /* Show the form to confirm action */
\r
2062 // PHP 4.0.x support
\r
2063 $get= (isset($_GET)) ? $_GET : $HTTP_GET_VARS;
\r
2064 $post= (isset($_POST)) ? $_POST : $HTTP_POST_VARS;
\r
2065 // Resolve URI and QUERY_STRING
\r
2066 if ($uri=serverVar('REQUEST_URI'))
\r
2068 list($uri,$qstring)=explode('?',$uri);
\r
2072 if ( !($uri=serverVar('PHP_SELF')) )
\r
2074 $uri=serverVar('SCRIPT_NAME');
\r
2076 $qstring=serverVar('QUERY_STRING');
\r
2080 $qstring='?'.$qstring;
\r
2082 echo '<p>'._SETTINGS_UPDATE.' : '._QMENU_PLUGINS.' <span style="color:red;">'.htmlspecialchars($plugin_name)."</span> ?</p>\n";
\r
2083 switch(strtoupper(serverVar('REQUEST_METHOD')))
\r
2086 echo '<form method="POST" action="'.htmlspecialchars($uri.$qstring).'">';
\r
2087 $manager->addTicketHidden();
\r
2088 _addInputTags($post);
\r
2091 echo '<form method="GET" action="'.htmlspecialchars($uri).'">';
\r
2092 $manager->addTicketHidden();
\r
2093 _addInputTags($get);
\r
2097 echo '<input type="submit" value="'._YES.'" /> ';
\r
2098 echo '<input type="button" value="'._NO.'" onclick="history.back(); return false;" />';
\r
2101 $oPluginAdmin->end();
\r
2105 /* Create new ticket */
\r
2106 $ticket=$manager->addTicketToUrl('');
\r
2107 $ticketforplugin['ticket']=substr($ticket,strpos($ticket,'ticket=')+7);
\r
2109 function _addInputTags(&$keys,$prefix=''){
\r
2110 foreach($keys as $key=>$value){
\r
2111 if ($prefix) $key=$prefix.'['.$key.']';
\r
2112 if (is_array($value)) _addInputTags($value,$key);
\r
2114 if (get_magic_quotes_gpc()) $value=stripslashes($value);
\r
2115 if ($key=='ticket') continue;
\r
2116 echo '<input type="hidden" name="'.htmlspecialchars($key).
\r
2117 '" value="'.htmlspecialchars($value).'" />'."\n";
\r
2123 * Convert the server string such as $_SERVER['REQUEST_URI']
\r
2124 * to arry like arry['blogid']=1 and array['page']=2 etc.
\r
2126 function serverStringToArray($str, &$array, &$frontParam)
\r
2132 // split front param, e.g. /index.php, and others, e.g. blogid=1&page=2
\r
2133 if (strstr($str, "?")){
\r
2134 list($frontParam, $args) = preg_split("/\?/", $str, 2);
\r
2141 // If there is no args like blogid=1&page=2, return
\r
2142 if (!strstr($str, "=") && !strlen($frontParam)) {
\r
2143 $frontParam = $str;
\r
2147 $array = explode("&", $args);
\r
2151 * Convert array like array['blogid'] to server string
\r
2152 * such as $_SERVER['REQUEST_URI']
\r
2154 function arrayToServerString($array, $frontParam, &$str)
\r
2156 if (strstr($str, "?")) {
\r
2157 $str = $frontParam . "?";
\r
2159 $str = $frontParam;
\r
2161 if (count($array)) {
\r
2162 $str .= implode("&", $array);
\r
2167 * Sanitize array parameters.
\r
2168 * This function checks both key and value.
\r
2169 * - check key if it inclues " (double quote), remove from array
\r
2170 * - check value if it includes \ (escape sequece), remove remaining string
\r
2172 function sanitizeArray(&$array)
\r
2174 $excludeListForSanitization = array('query');
\r
2175 // $excludeListForSanitization = array();
\r
2177 foreach ($array as $k => $v) {
\r
2179 // split to key and value
\r
2180 list($key, $val) = preg_split("/=/", $v, 2);
\r
2181 if (!isset($val)) {
\r
2185 // when magic quotes is on, need to use stripslashes,
\r
2186 // and then addslashes
\r
2187 if (get_magic_quotes_gpc()) {
\r
2188 $val = stripslashes($val);
\r
2190 // note that we must use addslashes here because this function is called before the db connection is made
\r
2191 // and sql_real_escape_string needs a db connection
\r
2192 $val = addslashes($val);
\r
2194 // if $key is included in exclude list, skip this param
\r
2195 if (!in_array($key, $excludeListForSanitization)) {
\r
2198 if (strpos($val, '\\')) {
\r
2199 list($val, $tmp) = explode('\\', $val);
\r
2202 // remove control code etc.
\r
2203 $val = strtr($val, "\0\r\n<>'\"", " ");
\r
2206 if (preg_match('/\"/i', $key)) {
\r
2207 unset($array[$k]);
\r
2211 // set sanitized info
\r
2212 $array[$k] = sprintf("%s=%s", $key, $val);
\r
2218 * Convert array for sanitizeArray function
\r
2220 function convArrayForSanitizing($src, &$array)
\r
2223 foreach ($src as $key => $val) {
\r
2224 if (key_exists($key, $_GET)) {
\r
2225 array_push($array, sprintf("%s=%s", $key, $val));
\r
2231 * Revert array after sanitizeArray function
\r
2233 function revertArrayForSanitizing($array, &$dst)
\r
2235 foreach ($array as $v) {
\r
2236 list($key, $val) = preg_split("/=/", $v, 2);
\r
2237 $dst[$key] = $val;
\r
2242 * Stops processing the request and redirects to the given URL.
\r
2243 * - no actual contents should have been sent to the output yet
\r
2244 * - the URL will be stripped of illegal or dangerous characters
\r
2246 function redirect($url) {
\r
2247 $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%*]|i', '', $url);
\r
2248 header('Location: ' . $url);
\r
2253 * Strip HTML tags from a string
\r
2254 * This function is a bit more intelligent than a regular call to strip_tags(),
\r
2255 * because it also deletes the contents of certain tags and cleans up any
\r
2256 * unneeded whitespace.
\r
2258 function stringStripTags ($string) {
\r
2259 $string = preg_replace("/<del[^>]*>.+<\/del[^>]*>/isU", '', $string);
\r
2260 $string = preg_replace("/<script[^>]*>.+<\/script[^>]*>/isU", '', $string);
\r
2261 $string = preg_replace("/<style[^>]*>.+<\/style[^>]*>/isU", '', $string);
\r
2262 $string = str_replace('>', '> ', $string);
\r
2263 $string = str_replace('<', ' <', $string);
\r
2264 $string = strip_tags($string);
\r
2265 $string = preg_replace("/\s+/", " ", $string);
\r
2266 $string = trim($string);
\r
2271 * Make a string containing HTML safe for use in a HTML attribute
\r
2272 * Tags are stripped and entities are normalized
\r
2274 function stringToAttribute ($string) {
\r
2275 $string = stringStripTags($string);
\r
2276 $string = entity::named_to_numeric($string);
\r
2277 $string = entity::normalize_numeric($string);
\r
2279 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2280 $string = entity::numeric_to_utf8($string);
\r
2283 $string = entity::specialchars($string, 'html');
\r
2284 $string = entity::numeric_to_named($string);
\r
2289 * Make a string containing HTML safe for use in a XML document
\r
2290 * Tags are stripped, entities are normalized and named entities are
\r
2291 * converted to numeric entities.
\r
2293 function stringToXML ($string) {
\r
2294 $string = stringStripTags($string);
\r
2295 $string = entity::named_to_numeric($string);
\r
2296 $string = entity::normalize_numeric($string);
\r
2298 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2299 $string = entity::numeric_to_utf8($string);
\r
2302 $string = entity::specialchars($string, 'xml');
\r
2306 // START: functions from the end of file BLOG.php
\r
2307 // used for mail notification (html -> text)
\r
2308 function toAscii($html) {
\r
2309 // strip off most tags
\r
2310 $html = strip_tags($html,'<a>');
\r
2311 $to_replace = "/<a[^>]*href=[\"\']([^\"^']*)[\"\'][^>]*>([^<]*)<\/a>/i";
\r
2313 $ascii = preg_replace_callback ($to_replace, '_links_add', $html);
\r
2314 $ascii .= "\n\n" . _links_list();
\r
2315 return strip_tags($ascii);
\r
2318 function _links_init() {
\r
2319 global $tmp_links;
\r
2320 $tmp_links = array();
\r
2323 function _links_add($match) {
\r
2324 global $tmp_links;
\r
2325 array_push($tmp_links, $match[1]);
\r
2326 return $match[2] . ' [' . sizeof($tmp_links) .']';
\r
2329 function _links_list() {
\r
2330 global $tmp_links;
\r
2333 foreach ($tmp_links as $current) {
\r
2334 $output .= "[$i] $current\n";
\r
2339 // END: functions from the end of file BLOG.php
\r
2341 // START: functions from the end of file ADMIN.php
\r
2343 * @todo document this
\r
2345 function encode_desc(&$data)
\r
2347 // _$to_entities = get_html_translation_table(HTML_ENTITIES);
\r
2348 $to_entities = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
2349 $from_entities = array_flip($to_entities);
\r
2350 $data = str_replace('<br />', '\n', $data); //hack
\r
2351 $data = strtr($data,$from_entities);
\r
2352 $data = strtr($data,$to_entities);
\r
2353 $data = str_replace('\n', '<br />', $data); //hack
\r
2358 * Returns the Javascript code for a bookmarklet that works on most modern browsers
\r
2362 function getBookmarklet($blogid) {
\r
2366 $document = 'document';
\r
2367 $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
2368 $bookmarkletline .= $CONF['AdminURL'] . "bookmarklet.php?blogid=$blogid";
\r
2369 $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
2371 return $bookmarkletline;
\r
2373 // END: functions from the end of file ADMIN.php
\r
2376 * Returns a variable or null if not set
\r
2378 * @param mixed Variable
\r
2379 * @return mixed Variable
\r
2381 function ifset(&$var) {
\r
2382 if (isset($var)) {
\r
2390 * Returns number of subscriber to an event
\r
2393 * @return number of subscriber(s)
\r
2395 function numberOfEventSubscriber($event) {
\r
2396 $query = 'SELECT COUNT(*) as count FROM ' . sql_table('plugin_event') . ' WHERE event=\'' . $event . '\'';
\r
2397 $res = sql_query($query);
\r
2398 $obj = sql_fetch_object($res);
\r
2399 return $obj->count;
\r
2403 * sets $special global variable for use in index.php before selector()
\r
2405 * @param String id
\r
2408 function selectSpecialSkinType($id) {
\r
2410 $special = strtolower($id);
\r
2414 * cleans filename of uploaded file for writing to file system
\r
2416 * @param String str
\r
2417 * @return String cleaned filename ready for use
\r
2419 function cleanFileName($str) {
\r
2420 $str = strtolower($str);
\r
2421 $ext_point = strrpos($str,".");
\r
2422 if ($ext_point===false) return false;
\r
2423 $ext = substr($str,$ext_point,strlen($str));
\r
2424 $str = substr($str,0,$ext_point);
\r
2426 return preg_replace("/[^a-z0-9-]/","_",$str).$ext;
\r
2430 * generate correct timecode with the format includes Japanese charactors
\r
2432 * @param String $format standard format string. Allowd to include Japanese charactors
\r
2433 * @param Integer $timestamp Unix Timestamp formated integer
\r
2434 * @return String Formatted timestamp
\r
2436 function strftimejp($format,$timestamp = ''){
\r
2437 return (setlocale(LC_CTYPE, 0) == 'Japanese_Japan.932')
\r
2438 ? iconv('CP932', _CHARSET, strftime(iconv(_CHARSET, 'CP932', $format),$timestamp))
\r
2439 : strftime($format,$timestamp)
\r