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 * @license http://nucleuscms.org/license.txt GNU General Public License
\r
15 * @copyright Copyright (C) 2002-2012 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.65';
\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 if (!isset($CONF['alertOnHeadersSent']) || (isset($CONF['alertOnHeadersSent'])&& $CONF['alertOnHeadersSent'] !== 0))
\r
69 $CONF['alertOnHeadersSent'] = 1;
\r
71 $CONF['alertOnSecurityRisk'] = 1;
\r
72 /*$CONF['ItemURL'] = $CONF['Self'];
\r
73 $CONF['ArchiveURL'] = $CONF['Self'];
\r
74 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
75 $CONF['MemberURL'] = $CONF['Self'];
\r
76 $CONF['SearchURL'] = $CONF['Self'];
\r
77 $CONF['BlogURL'] = $CONF['Self'];
\r
78 $CONF['CategoryURL'] = $CONF['Self'];
\r
80 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
81 // this avoids urls like index.php/item/13/index.php/item/15
\r
82 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
\r
83 $CONF['URLMode'] = 'normal';
\r
87 Set these to 1 to allow viewing of future items or draft items
\r
88 Should really never do this, but can be useful for some plugins that might need to
\r
89 Could cause some other issues if you use future posts otr drafts
\r
92 $CONF['allowDrafts'] = 0;
\r
93 $CONF['allowFuture'] = 0;
\r
95 if (getNucleusPatchLevel() > 0) {
\r
96 $nucleus['version'] .= '/' . getNucleusPatchLevel();
\r
100 if (!isset($CONF['installscript'])) {
\r
101 $CONF['installscript'] = 0;
\r
105 * Include multibyte function if some functions related to mbstring are not loaded.
\r
106 * By Japanese Packaging Team, Jan.31, 2011
\r
108 if (!function_exists('mb_convert_encoding')){
\r
109 global $mbemu_internals;
\r
110 include_libs('mb_emulator/mb-emulator.php',true,false);
\r
113 // we will use postVar, getVar, ... methods instead of HTTP_GET_VARS or _GET
\r
114 if ($CONF['installscript'] != 1) { // vars were already included in install.php
\r
115 if (phpversion() >= '4.1.0') {
\r
116 include_once($DIR_LIBS . 'vars4.1.0.php');
\r
118 include_once($DIR_LIBS . 'vars4.0.6.php');
\r
123 $bLoggingSanitizedResult=0;
\r
124 $bSanitizeAndContinue=0;
\r
126 $orgRequestURI = serverVar('REQUEST_URI');
\r
129 // get all variables that can come from the request and put them in the global scope
\r
130 $blogid = requestVar('blogid');
\r
131 $itemid = intRequestVar('itemid');
\r
132 $catid = intRequestVar('catid');
\r
133 $skinid = requestVar('skinid');
\r
134 $memberid = requestVar('memberid');
\r
135 $archivelist = requestVar('archivelist');
\r
136 $imagepopup = requestVar('imagepopup');
\r
137 $archive = requestVar('archive');
\r
138 $query = requestVar('query');
\r
139 $highlight = requestVar('highlight');
\r
140 $amount = requestVar('amount');
\r
141 $action = requestVar('action');
\r
142 $nextaction = requestVar('nextaction');
\r
143 $maxresults = requestVar('maxresults');
\r
144 $startpos = intRequestVar('startpos');
\r
145 $errormessage = '';
\r
147 $special = requestVar('special');
\r
148 $virtualpath = ((getVar('virtualpath') != null) ? getVar('virtualpath') : serverVar('PATH_INFO'));
\r
150 if (!headers_sent() ) {
\r
151 header('Generator: Nucleus CMS ' . $nucleus['version']);
\r
154 // include core classes that are needed for login & plugin handling
\r
155 include_once($DIR_LIBS . 'mysql.php');
\r
156 // added for 3.5 sql_* wrapper
\r
157 global $MYSQL_HANDLER;
\r
158 if (!isset($MYSQL_HANDLER))
\r
159 $MYSQL_HANDLER = array('mysql','');
\r
160 if ($MYSQL_HANDLER[0] == '')
\r
161 $MYSQL_HANDLER[0] = 'mysql';
\r
162 include_once($DIR_LIBS . 'sql/'.$MYSQL_HANDLER[0].'.php');
\r
163 // end new for 3.5 sql_* wrapper
\r
164 include($DIR_LIBS . 'MEMBER.php');
\r
165 include($DIR_LIBS . 'ACTIONLOG.php');
\r
166 include($DIR_LIBS . 'MANAGER.php');
\r
167 include($DIR_LIBS . 'PLUGIN.php');
\r
169 $manager =& MANAGER::instance();
\r
171 // make sure there's no unnecessary escaping:
\r
172 //set_magic_quotes_runtime(0);
\r
173 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
\r
174 ini_set('magic_quotes_runtime', '0');
\r
178 if (!isset($CONF['UsingAdminArea'])) {
\r
179 $CONF['UsingAdminArea'] = 0;
\r
182 // only needed when updating logs
\r
183 if ($CONF['UsingAdminArea']) {
\r
184 include($DIR_LIBS . 'xmlrpc.inc.php'); // XML-RPC client classes
\r
185 include_once($DIR_LIBS . 'ADMIN.php');
\r
188 // connect to database
\r
192 // logs sanitized result if need
\r
193 if ($orgRequestURI!==serverVar('REQUEST_URI')) {
\r
194 $msg = "Sanitized [" . serverVar('REMOTE_ADDR') . "] ";
\r
195 $msg .= $orgRequestURI . " -> " . serverVar('REQUEST_URI');
\r
196 if ($bLoggingSanitizedResult) {
\r
197 addToLog(WARNING, $msg);
\r
199 if (!$bSanitizeAndContinue) {
\r
204 // makes sure database connection gets closed on script termination
\r
205 register_shutdown_function('sql_disconnect');
\r
210 // Properly set $CONF['Self'] and others if it's not set... usually when we are access from admin menu
\r
211 if (!isset($CONF['Self'])) {
\r
212 $CONF['Self'] = $CONF['IndexURL'];
\r
213 // strip trailing /
\r
214 if ($CONF['Self'][strlen($CONF['Self']) -1] == "/") {
\r
215 $CONF['Self'] = substr($CONF['Self'], 0, strlen($CONF['Self']) -1);
\r
218 /* $CONF['ItemURL'] = $CONF['Self'];
\r
219 $CONF['ArchiveURL'] = $CONF['Self'];
\r
220 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
221 $CONF['MemberURL'] = $CONF['Self'];
\r
222 $CONF['SearchURL'] = $CONF['Self'];
\r
223 $CONF['BlogURL'] = $CONF['Self'];
\r
224 $CONF['CategoryURL'] = $CONF['Self'];*/
\r
227 $CONF['ItemURL'] = $CONF['Self'];
\r
228 $CONF['ArchiveURL'] = $CONF['Self'];
\r
229 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
230 $CONF['MemberURL'] = $CONF['Self'];
\r
231 $CONF['SearchURL'] = $CONF['Self'];
\r
232 $CONF['BlogURL'] = $CONF['Self'];
\r
233 $CONF['CategoryURL'] = $CONF['Self'];
\r
235 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
236 // this avoids urls like index.php/item/13/index.php/item/15
\r
237 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
\r
238 $CONF['URLMode'] = 'normal';
\r
241 // automatically use simpler toolbar for mozilla
\r
242 if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'), 'Gecko') ) {
\r
243 $CONF['DisableJsTools'] = 2;
\r
246 // login if cookies set
\r
247 $member = new MEMBER();
\r
249 // secure cookie key settings (either 'none', 0, 8, 16, 24, or 32)
\r
250 if (!isset($CONF['secureCookieKey'])) $CONF['secureCookieKey']=24;
\r
251 switch($CONF['secureCookieKey']){
\r
253 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
256 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
259 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
262 $CONF['secureCookieKeyIP']=serverVar('REMOTE_ADDR');
\r
265 $CONF['secureCookieKeyIP']='';
\r
268 // login/logout when required or renew cookies
\r
269 if ($action == 'login') {
\r
270 // Form Authentication
\r
271 $login = postVar('login');
\r
272 $pw = postVar('password');
\r
273 $shared = intPostVar('shared'); // shared computer or not
\r
275 $pw=substr($pw,0,40); // avoid md5 collision by using a long key
\r
277 if ($member->login($login, $pw) ) {
\r
279 $member->newCookieKey();
\r
280 $member->setCookies($shared);
\r
282 if ($CONF['secureCookieKey']!=='none') {
\r
283 // secure cookie key
\r
284 $member->setCookieKey(md5($member->getCookieKey().$CONF['secureCookieKeyIP']));
\r
288 // allows direct access to parts of the admin area after logging in
\r
290 $action = $nextaction;
\r
294 'member' => &$member,
\r
295 'username' => $login
\r
297 $manager->notify('LoginSuccess', $param);
\r
298 $errormessage = '';
\r
299 ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");
\r
301 // errormessage for [%errordiv%]
\r
302 $trimlogin = trim($login);
\r
303 if (empty($trimlogin))
\r
305 $errormessage = "Please enter a username.";
\r
309 $errormessage = 'Login failed for ' . $login;
\r
311 $param = array('username' => $login);
\r
312 $manager->notify('LoginFailed', $param);
\r
313 ACTIONLOG::add(INFO, $errormessage);
\r
317 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
319 } elseif (serverVar('PHP_AUTH_USER') && serverVar('PHP_AUTH_PW')) {
\r
320 // HTTP Authentication
\r
321 $login = serverVar('PHP_AUTH_USER');
\r
322 $pw = serverVar('PHP_AUTH_PW');
\r
324 if ($member->login($login, $pw) ) {
\r
325 $param = array('member' => &$member);
\r
326 $manager->notify('LoginSuccess', $param);
\r
327 ACTIONLOG::add(INFO, "HTTP authentication successful for $login");
\r
329 $param = array('username' => $login);
\r
330 $manager->notify('LoginFailed', $param);
\r
331 ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);
\r
333 //Since bad credentials, generate an apropriate error page
\r
334 header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");
\r
335 header('HTTP/1.0 401 Unauthorized');
\r
336 echo 'Invalid username or password';
\r
341 } elseif (($action == 'logout') && (!headers_sent() ) && cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
342 // remove cookies on logout
\r
343 setcookie($CONF['CookiePrefix'] . 'user', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
344 setcookie($CONF['CookiePrefix'] . 'loginkey', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
345 $param = array('username' => cookieVar($CONF['CookiePrefix'] . 'user'));
\r
346 $manager->notify('Logout', $param);
\r
347 } elseif (cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
348 // Cookie Authentication
\r
349 $ck=cookieVar($CONF['CookiePrefix'] . 'loginkey');
\r
350 // secure cookie key
\r
351 $ck=substr($ck,0,32); // avoid md5 collision by using a long key
\r
352 if ($CONF['secureCookieKey']!=='none') $ck=md5($ck.$CONF['secureCookieKeyIP']);
\r
353 $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), $ck );
\r
356 // renew cookies when not on a shared computer
\r
357 if ($res && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) && (!headers_sent() ) ) {
\r
358 $member->setCookieKey(cookieVar($CONF['CookiePrefix'] . 'loginkey'));
\r
359 $member->setCookies();
\r
364 $param = array('loggedIn' => $member->isLoggedIn());
\r
365 $manager->notify('PostAuthentication', $param);
\r
368 // first, let's see if the site is disabled or not. always allow admin area access.
\r
369 if ($CONF['DisableSite'] && !$member->isAdmin() && !$CONF['UsingAdminArea']) {
\r
370 redirect($CONF['DisableSiteURL']);
\r
374 // load other classes
\r
375 include($DIR_LIBS . 'PARSER.php');
\r
376 include($DIR_LIBS . 'SKIN.php');
\r
377 include($DIR_LIBS . 'TEMPLATE.php');
\r
378 include($DIR_LIBS . 'BLOG.php');
\r
379 include($DIR_LIBS . 'BODYACTIONS.php');
\r
380 include($DIR_LIBS . 'COMMENTS.php');
\r
381 include($DIR_LIBS . 'COMMENT.php');
\r
382 //include($DIR_LIBS . 'ITEM.php');
\r
383 include($DIR_LIBS . 'NOTIFICATION.php');
\r
384 include($DIR_LIBS . 'BAN.php');
\r
385 include($DIR_LIBS . 'PAGEFACTORY.php');
\r
386 include($DIR_LIBS . 'SEARCH.php');
\r
387 include($DIR_LIBS . 'entity.php');
\r
390 // set lastVisit cookie (if allowed)
\r
391 if (!headers_sent() ) {
\r
392 if ($CONF['LastVisit']) {
\r
393 setcookie($CONF['CookiePrefix'] . 'lastVisit', time(), time() + 2592000, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
395 setcookie($CONF['CookiePrefix'] . 'lastVisit', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
399 // read language file, only after user has been initialized
\r
400 $language = getLanguageName();
\r
402 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
403 # original ereg_replace: ereg_replace( '[\\|/]', '', $language) . '.php')
\r
404 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
405 include($DIR_LANG . preg_replace('#[\\\\|/]#', '', $language) . '.php');
\r
407 // check if valid charset
\r
408 if (!encoding_check(false, false, _CHARSET)) {
\r
409 foreach(array($_GET, $_POST) as $input) {
\r
410 array_walk($input, 'encoding_check');
\r
414 sql_set_charset_jp(_CHARSET);
\r
417 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
419 // To remove after v2.5 is released and language files have been updated.
\r
420 // Including this makes sure that language files for v2.5beta can still be used for v2.5final
\r
421 // without having weird _SETTINGS_EXTAUTH string showing up in the admin area.
\r
422 if (!defined('_MEMBERS_BYPASS'))
\r
424 define('_SETTINGS_EXTAUTH', 'Enable External Authentication');
\r
425 define('_WARNING_EXTAUTH', 'Warning: Enable only if needed.');
\r
426 define('_MEMBERS_BYPASS', 'Use External Authentication');
\r
431 // make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined
\r
432 if (!defined('_ARCHIVETYPE_MONTH') )
\r
434 define('_ARCHIVETYPE_DAY', 'day');
\r
435 define('_ARCHIVETYPE_MONTH', 'month');
\r
436 define('_ARCHIVETYPE_YEAR', 'year');
\r
439 // decode path_info
\r
440 if ($CONF['URLMode'] == 'pathinfo') {
\r
441 // initialize keywords if this hasn't been done before
\r
442 if (!isset($CONF['ItemKey']) || $CONF['ItemKey'] == '') {
\r
443 $CONF['ItemKey'] = 'item';
\r
446 if (!isset($CONF['ArchiveKey']) || $CONF['ArchiveKey'] == '') {
\r
447 $CONF['ArchiveKey'] = 'archive';
\r
450 if (!isset($CONF['ArchivesKey']) || $CONF['ArchivesKey'] == '') {
\r
451 $CONF['ArchivesKey'] = 'archives';
\r
454 if (!isset($CONF['MemberKey']) || $CONF['MemberKey'] == '') {
\r
455 $CONF['MemberKey'] = 'member';
\r
458 if (!isset($CONF['BlogKey']) || $CONF['BlogKey'] == '') {
\r
459 $CONF['BlogKey'] = 'blog';
\r
462 if (!isset($CONF['CategoryKey']) || $CONF['CategoryKey'] == '') {
\r
463 $CONF['CategoryKey'] = 'category';
\r
466 if (!isset($CONF['SpecialskinKey']) || $CONF['SpecialskinKey'] == '') {
\r
467 $CONF['SpecialskinKey'] = 'special';
\r
472 'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...
\r
473 'info' => $virtualpath,
\r
474 'complete' => &$parsed
\r
476 $manager->notify('ParseURL', $param);
\r
479 // default implementation
\r
480 $data = explode("/", $virtualpath );
\r
481 for ($i = 0; $i < sizeof($data); $i++) {
\r
482 switch ($data[$i]) {
\r
483 case $CONF['ItemKey']: // item/1 (blogid)
\r
486 if ($i < sizeof($data) ) {
\r
487 $itemid = intval($data[$i]);
\r
491 case $CONF['ArchivesKey']: // archives/1 (blogid)
\r
494 if ($i < sizeof($data) ) {
\r
495 $archivelist = intval($data[$i]);
\r
499 case $CONF['ArchiveKey']: // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)
\r
500 if ((($i + 1) < sizeof($data) ) && (!strstr($data[$i + 1], '-') ) ) {
\r
501 $blogid = intval($data[++$i]);
\r
506 if ($i < sizeof($data) ) {
\r
507 $archive = $data[$i];
\r
511 case 'blogid': // blogid/1
\r
512 case $CONF['BlogKey']: // blog/1
\r
515 if ($i < sizeof($data) ) {
\r
516 $blogid = intval($data[$i]);
\r
520 case $CONF['CategoryKey']: // category/1 (catid)
\r
524 if ($i < sizeof($data) ) {
\r
525 $catid = intval($data[$i]);
\r
529 case $CONF['MemberKey']:
\r
532 if ($i < sizeof($data) ) {
\r
533 $memberid = intval($data[$i]);
\r
537 case $CONF['SpecialskinKey']:
\r
540 if ($i < sizeof($data) ) {
\r
541 $special = $data[$i];
\r
542 $_REQUEST['special'] = $special;
\r
552 /* PostParseURL is a place to cleanup any of the path-related global variables before the selector function is run.
\r
553 It has 2 values in the data in case the original virtualpath is needed, but most the use will be in tweaking
\r
554 global variables to clean up (scrub out catid or add catid) or to set someother global variable based on
\r
555 the values of something like catid or itemid
\r
559 'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...
\r
560 'info' => $virtualpath
\r
562 $manager->notify('PostParseURL', $param);
\r
564 function include_libs($file,$once=true,$require=true){
\r
566 if (!is_dir($DIR_LIBS)) exit;
\r
567 if ($once && $require) require_once($DIR_LIBS.$file);
\r
568 elseif ($once && !$require) include_once($DIR_LIBS.$file);
\r
569 elseif ($require) require($DIR_LIBS.$file);
\r
570 else include($DIR_LIBS.$file);
\r
573 function include_plugins($file,$once=true,$require=true){
\r
574 global $DIR_PLUGINS;
\r
575 if (!is_dir($DIR_PLUGINS)) exit;
\r
576 if ($once && $require) require_once($DIR_PLUGINS.$file);
\r
577 elseif ($once && !$require) include_once($DIR_PLUGINS.$file);
\r
578 elseif ($require) require($DIR_PLUGINS.$file);
\r
579 else include($DIR_PLUGINS.$file);
\r
582 function intPostVar($name) {
\r
583 return intval(postVar($name) );
\r
586 function intGetVar($name) {
\r
587 return intval(getVar($name) );
\r
590 function intRequestVar($name) {
\r
591 return intval(requestVar($name) );
\r
594 function intCookieVar($name) {
\r
595 return intval(cookieVar($name) );
\r
599 * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)
\r
601 function getNucleusVersion() {
\r
606 * power users can install patches in between nucleus releases. These patches
\r
607 * usually add new functionality in the plugin API and allow those to
\r
608 * be tested without having to install CVS.
\r
610 function getNucleusPatchLevel() {
\r
615 * returns the latest version available for download from nucleuscms.org
\r
616 * or false if unable to attain data
\r
617 * format will be major.minor/patachlevel
\r
618 * e.g. 3.41 or 3.41/02
\r
620 function getLatestVersion() {
\r
621 if (!function_exists('curl_init')) return false;
\r
622 $crl = curl_init();
\r
624 curl_setopt ($crl, CURLOPT_URL,'http://nucleuscms.org/version_check.php');
\r
625 curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);
\r
626 curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);
\r
627 $ret = curl_exec($crl);
\r
634 * Connects to mysql server
\r
636 /* moved to $DIR_LIBS/sql/*.php handler files
\r
637 function sql_connect() {
\r
638 global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE, $MYSQL_CONN;
\r
640 $MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>', 'Connect Error');
\r
641 mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: ' . mysql_error() . '</p>', 'Connect Error');
\r
643 return $MYSQL_CONN;
\r
647 * returns a prefixed nucleus table name
\r
649 function sql_table($name) {
\r
650 global $MYSQL_PREFIX;
\r
652 if ($MYSQL_PREFIX) {
\r
653 return $MYSQL_PREFIX . 'nucleus_' . $name;
\r
655 return 'nucleus_' . $name;
\r
659 function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
\r
660 global $manager, $CONF;
\r
662 if (!headers_sent() ) {
\r
663 // if content type is application/xhtml+xml, only send it to browsers
\r
664 // that can handle it (IE6 cannot). Otherwise, send text/html
\r
666 // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)
\r
667 // application/xhtml+xml still causes too much problems with the javascript implementations
\r
669 // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,
\r
670 // application/xhtml+xml seems to be working, so we're going to use it if we can.
\r
672 // Note: reverted the following function in JP version
\r
677 ($contenttype == 'application/xhtml+xml')
\r
678 && (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )
\r
680 $contenttype = 'text/html';
\r
685 ($contenttype == 'application/xhtml+xml')
\r
686 && (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))
\r
689 $contenttype = 'text/html';
\r
693 'contentType' => &$contenttype,
\r
694 'charset' => &$charset,
\r
695 'pageType' => $pagetype
\r
697 $manager->notify('PreSendContentType', $param);
\r
699 // strip strange characters
\r
700 $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);
\r
701 $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);
\r
703 if ($charset != '') {
\r
704 header('Content-Type: ' . $contenttype . '; charset=' . $charset);
\r
706 header('Content-Type: ' . $contenttype);
\r
709 // check if valid charset
\r
710 if (!encoding_check(false,false,$charset)) {
\r
711 foreach(array($_GET, $_POST) as $input) {
\r
712 array_walk($input, 'encoding_check');
\r
719 * Errors before the database connection has been made - moved to
\r
721 /* moved to $DIR_LIBS/sql/*.php handler files
\r
722 function startUpError($msg, $title) {
\r
723 if (!defined('_CHARSET')) define('_CHARSET', 'iso-8859-1');
\r
724 header('Content-Type: text/html; charset=' . _CHARSET);
\r
726 <html <?php echo _HTML_XML_NAME_SPACE_AND_LANG_CODE; ?>>
\r
727 <head><meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET?>" />
\r
728 <title><?php echo htmlspecialchars($title)?></title></head>
\r
730 <h1><?php echo htmlspecialchars($title)?></h1>
\r
738 * disconnects from SQL server
\r
740 /* moved to $DIR_LIBS/sql/*.php handler files
\r
741 function sql_disconnect() {
\r
746 * executes an SQL query
\r
748 /* moved to $DIR_LIBS/sql/*.php handler files
\r
749 function sql_query($query) {
\r
752 $res = mysql_query($query) or print("mySQL error with query $query: " . mysql_error() . '<p />');
\r
757 * Highlights a specific query in a given HTML text (not within HTML tags) and returns it
\r
758 * @param string $text text to be highlighted
\r
759 * @param string $expression regular expression to be matched (can be an array of expressions as well)
\r
760 * @param string $highlight highlight to be used (use \\0 to indicate the matched expression)
\r
763 function highlight($text, $expression, $highlight) {
\r
764 if (!$highlight || !$expression)
\r
769 if (is_array($expression) && (count($expression) == 0) )
\r
774 // add a tag in front (is needed for preg_match_all to work correct)
\r
775 $text = '<!--h-->' . $text;
\r
777 // split the HTML up so we have HTML tags
\r
778 // $matches[0][i] = HTML + text
\r
779 // $matches[1][i] = HTML
\r
780 // $matches[2][i] = text
\r
781 preg_match_all('/(<[^>]+>)([^<>]*)/', $text, $matches);
\r
783 // throw it all together again while applying the highlight to the text pieces
\r
785 $count_matches = count($matches[2]);
\r
786 for ($i = 0; $i < $count_matches; $i++) {
\r
789 $result .= $matches[1][$i];
\r
792 if (is_array($expression) )
\r
794 foreach ($expression as $regex)
\r
798 //$matches[2][$i] = @eregi_replace($regex, $highlight, $matches[2][$i]);
\r
799 $matches[2][$i] = @preg_replace("#".$regex."#i", $highlight, $matches[2][$i]);
\r
803 $result .= $matches[2][$i];
\r
807 //$result .= @eregi_replace($expression, $highlight, $matches[2][$i]);
\r
808 $result .= @preg_replace("#".$expression."#i", $highlight, $matches[2][$i]);
\r
816 * Parses a query into an array of expressions that can be passed on to the highlight method
\r
818 function parseHighlight($query) {
\r
819 // TODO: add more intelligent splitting logic
\r
821 // get rid of quotes
\r
822 $query = preg_replace('/\'|"/', '', $query);
\r
828 $aHighlight = explode(' ', $query);
\r
830 for ($i = 0; $i < count($aHighlight); $i++) {
\r
831 $aHighlight[$i] = trim($aHighlight[$i]);
\r
833 // if (strlen($aHighlight[$i]) < 3) {
\r
834 // unset($aHighlight[$i]);
\r
838 if (count($aHighlight) == 1) {
\r
839 return $aHighlight[0];
\r
841 return $aHighlight;
\r
846 * Checks if email address is valid
\r
848 function isValidMailAddress($address) {
\r
849 // enhancement made in 3.6x based on code by Quandary.
\r
850 if (preg_match('/^(?!\\.)(?:\\.?[-a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~]+)+@(?!\\.)(?:\\.?(?!-)[-a-zA-Z0-9]+(?<!-)){2,}$/', $address)) {
\r
857 // some helper functions
\r
858 function getBlogIDFromName($name) {
\r
859 return quickQuery('SELECT bnumber as result FROM ' . sql_table('blog') . ' WHERE bshortname="' . sql_real_escape_string($name) . '"');
\r
862 function getBlogNameFromID($id) {
\r
863 return quickQuery('SELECT bname as result FROM ' . sql_table('blog') . ' WHERE bnumber=' . intval($id) );
\r
866 function getBlogIDFromItemID($itemid) {
\r
867 return quickQuery('SELECT iblog as result FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid) );
\r
870 function getBlogIDFromCommentID($commentid) {
\r
871 return quickQuery('SELECT cblog as result FROM ' . sql_table('comment') . ' WHERE cnumber=' . intval($commentid) );
\r
874 function getBlogIDFromCatID($catid) {
\r
875 return quickQuery('SELECT cblog as result FROM ' . sql_table('category') . ' WHERE catid=' . intval($catid) );
\r
878 function getCatIDFromName($name) {
\r
879 return quickQuery('SELECT catid as result FROM ' . sql_table('category') . ' WHERE cname="' . sql_real_escape_string($name) . '"');
\r
882 function quickQuery($q) {
\r
883 $res = sql_query($q);
\r
884 $obj = sql_fetch_object($res);
\r
885 return $obj->result;
\r
888 function getPluginNameFromPid($pid) {
\r
889 $res = sql_query('SELECT pfile FROM ' . sql_table('plugin') . ' WHERE pid=' . intval($pid) );
\r
890 $obj = sql_fetch_object($res);
\r
891 return $obj->pfile;
\r
894 function selector() {
\r
895 global $itemid, $blogid, $memberid, $query, $amount, $archivelist, $maxresults;
\r
896 global $archive, $skinid, $blog, $memberinfo, $CONF, $member;
\r
897 global $imagepopup, $catid, $special;
\r
900 $actionNames = array('addcomment', 'sendmessage', 'createaccount', 'forgotpassword', 'votepositive', 'votenegative', 'plugin');
\r
901 $action = requestVar('action');
\r
903 if (in_array($action, $actionNames) ) {
\r
904 global $DIR_LIBS, $errormessage;
\r
905 include_once($DIR_LIBS . 'ACTION.php');
\r
907 $errorInfo = $a->doAction($action);
\r
910 $errormessage = $errorInfo['message'];
\r
914 // show error when headers already sent out
\r
915 if (headers_sent() && $CONF['alertOnHeadersSent']) {
\r
917 // try to get line number/filename (extra headers_sent params only exists in PHP 4.3+)
\r
918 if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=') ) {
\r
919 headers_sent($hsFile, $hsLine);
\r
920 $extraInfo = sprintf(_GFUNCTIONS_HEADERSALREADYSENT_FILE,$hsFile,$hsLine);
\r
926 sprintf(_GFUNCTIONS_HEADERSALREADYSENT_TXT,$extraInfo),
\r
927 _GFUNCTIONS_HEADERSALREADYSENT_TITLE
\r
932 // make is so ?archivelist without blogname or blogid shows the archivelist
\r
933 // for the default weblog
\r
934 if (serverVar('QUERY_STRING') == 'archivelist') {
\r
935 $archivelist = $CONF['DefaultBlog'];
\r
938 // now decide which type of skin we need
\r
940 // itemid given -> only show that item
\r
943 if (!$manager->existsItem($itemid,intval($CONF['allowFuture']),intval($CONF['allowDrafts']))) {
\r
944 doError(_ERROR_NOSUCHITEM);
\r
947 global $itemidprev, $itemidnext, $catid, $itemtitlenext, $itemtitleprev;
\r
949 // 1. get timestamp, blogid and catid for item
\r
950 $query = 'SELECT itime, iblog, icat FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid);
\r
951 $res = sql_query($query);
\r
952 $obj = sql_fetch_object($res);
\r
954 // if a different blog id has been set through the request or selectBlog(),
\r
957 if ($blogid && (intval($blogid) != $obj->iblog) ) {
\r
958 if (!headers_sent()) {
\r
959 $b =& $manager->getBlog($obj->iblog);
\r
960 $CONF['ItemURL'] = $b->getURL();
\r
961 if ($CONF['URLMode'] == 'pathinfo' and substr($CONF['ItemURL'],-1) == '/')
\r
962 $CONF['ItemURL'] = substr($CONF['ItemURL'], 0, -1);
\r
963 $correctURL = createItemLink($itemid, '');
\r
964 redirect($correctURL);
\r
967 doError(_ERROR_NOSUCHITEM);
\r
971 // if a category has been selected which doesn't match the item, ignore the
\r
973 if (($catid != 0) && ($catid != $obj->icat) ) {
\r
977 $blogid = $obj->iblog;
\r
978 $timestamp = strtotime($obj->itime);
\r
980 $b =& $manager->getBlog($blogid);
\r
982 if ($b->isValidCategory($catid) ) {
\r
983 $catextra = ' and icat=' . $catid;
\r
988 // get previous itemid and title
\r
989 $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
990 $res = sql_query($query);
\r
992 $obj = sql_fetch_object($res);
\r
995 $itemidprev = $obj->inumber;
\r
996 $itemtitleprev = $obj->ititle;
\r
999 // get next itemid and title
\r
1000 $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
1001 $res = sql_query($query);
\r
1003 $obj = sql_fetch_object($res);
\r
1006 $itemidnext = $obj->inumber;
\r
1007 $itemtitlenext = $obj->ititle;
\r
1010 } elseif ($archive) {
\r
1012 $type = 'archive';
\r
1014 // get next and prev month links ...
\r
1015 global $archivenext, $archiveprev, $archivetype, $archivenextexists, $archiveprevexists;
\r
1017 // sql queries for the timestamp of the first and the last published item
\r
1018 $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
1019 $first_timestamp=quickQuery ($query);
\r
1020 $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
1021 $last_timestamp=quickQuery ($query);
\r
1023 sscanf($archive, '%d-%d-%d', $y, $m, $d);
\r
1026 $archivetype = _ARCHIVETYPE_DAY;
\r
1027 $t = mktime(0, 0, 0, $m, $d, $y);
\r
1028 // one day has 24 * 60 * 60 = 86400 seconds
\r
1029 $archiveprev = strftime('%Y-%m-%d', $t - 86400 );
\r
1030 // check for published items
\r
1031 if ($t > $first_timestamp) {
\r
1032 $archiveprevexists = true;
\r
1035 $archiveprevexists = false;
\r
1040 $archivenext = strftime('%Y-%m-%d', $t);
\r
1041 if ($t < $last_timestamp) {
\r
1042 $archivenextexists = true;
\r
1045 $archivenextexists = false;
\r
1048 } elseif ($m == 0) {
\r
1049 $archivetype = _ARCHIVETYPE_YEAR;
\r
1050 $t = mktime(0, 0, 0, 12, 31, $y - 1);
\r
1051 // one day before is in the previous year
\r
1052 $archiveprev = strftime('%Y', $t);
\r
1053 if ($t > $first_timestamp) {
\r
1054 $archiveprevexists = true;
\r
1057 $archiveprevexists = false;
\r
1060 // timestamp for the next year
\r
1061 $t = mktime(0, 0, 0, 1, 1, $y + 1);
\r
1062 $archivenext = strftime('%Y', $t);
\r
1063 if ($t < $last_timestamp) {
\r
1064 $archivenextexists = true;
\r
1067 $archivenextexists = false;
\r
1070 $archivetype = _ARCHIVETYPE_MONTH;
\r
1071 $t = mktime(0, 0, 0, $m, 1, $y);
\r
1072 // one day before is in the previous month
\r
1073 $archiveprev = strftime('%Y-%m', $t - 86400);
\r
1074 if ($t > $first_timestamp) {
\r
1075 $archiveprevexists = true;
\r
1078 $archiveprevexists = false;
\r
1081 // timestamp for the next month
\r
1082 $t = mktime(0, 0, 0, $m+1, 1, $y);
\r
1083 $archivenext = strftime('%Y-%m', $t);
\r
1084 if ($t < $last_timestamp) {
\r
1085 $archivenextexists = true;
\r
1088 $archivenextexists = false;
\r
1092 } elseif ($archivelist) {
\r
1093 $type = 'archivelist';
\r
1095 if (is_numeric($archivelist)) {
\r
1096 $blogid = intVal($archivelist);
\r
1098 $blogid = getBlogIDFromName($archivelist);
\r
1102 doError(_ERROR_NOSUCHBLOG);
\r
1105 } elseif ($query) {
\r
1108 $query = stripslashes($query);
\r
1109 if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/", $query)){
\r
1112 // $order = (_CHARSET == 'EUC-JP') ? 'EUC-JP, UTF-8,' : 'UTF-8, EUC-JP,';
\r
1113 // $query = mb_convert_encoding($query, _CHARSET, $order . ' JIS, SJIS, ASCII');
\r
1114 switch(strtolower(_CHARSET)){
\r
1116 $order = 'ASCII, UTF-8, EUC-JP, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1119 $order = 'ASCII, EUC-CN, EUC-JP, UTF-8, JIS, SJIS, ISO-8859-1';
\r
1122 // Note that shift_jis is only supported for output.
\r
1123 // Using shift_jis in DB is prohibited.
\r
1124 $order = 'ASCII, SJIS, EUC-JP, UTF-8, JIS, EUC-CN, ISO-8859-1';
\r
1127 // euc-jp,iso-8859-x,windows-125x
\r
1128 $order = 'ASCII, EUC-JP, UTF-8, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1131 $query = mb_convert_encoding($query, _CHARSET, $order);
\r
1132 if (is_numeric($blogid)) {
\r
1133 $blogid = intVal($blogid);
\r
1135 $blogid = getBlogIDFromName($blogid);
\r
1139 doError(_ERROR_NOSUCHBLOG);
\r
1142 } elseif ($memberid) {
\r
1145 if (!MEMBER::existsID($memberid) ) {
\r
1146 doError(_ERROR_NOSUCHMEMBER);
\r
1149 $memberinfo = $manager->getMember($memberid);
\r
1151 } elseif ($imagepopup) {
\r
1152 // media object (images etc.)
\r
1153 $type = 'imagepopup';
\r
1155 // TODO: check if media-object exists
\r
1156 // TODO: set some vars?
\r
1158 // show regular index page
\r
1163 // any type of skin with catid
\r
1164 if ($catid && !$blogid) {
\r
1165 $blogid = getBlogIDFromCatID($catid);
\r
1168 // decide which blog should be displayed
\r
1170 $blogid = $CONF['DefaultBlog'];
\r
1173 $b =& $manager->getBlog($blogid);
\r
1174 $blog = $b; // references can't be placed in global variables?
\r
1176 if (!$blog->isValid) {
\r
1177 doError(_ERROR_NOSUCHBLOG);
\r
1180 // set catid if necessary
\r
1182 // check if the category is valid
\r
1183 if (!$blog->isValidCategory($catid)) {
\r
1184 doError(_ERROR_NOSUCHCATEGORY);
\r
1186 $blog->setSelectedCategory($catid);
\r
1190 // decide which skin should be used
\r
1191 if ($skinid != '' && ($skinid == 0) ) {
\r
1192 selectSkin($skinid);
\r
1196 $skinid = $blog->getDefaultSkin();
\r
1199 //$special = requestVar('special'); //get at top of file as global
\r
1200 if (!empty($special) && isValidShortName($special)) {
\r
1201 $type = strtolower($special);
\r
1204 $skin = new SKIN($skinid);
\r
1206 if (!$skin->isValid) {
\r
1207 doError(_ERROR_NOSUCHSKIN);
\r
1210 // set global skinpart variable so can determine quickly what is being parsed from any plugin or phpinclude
\r
1212 $skinpart = $type;
\r
1215 $skin->parse($type);
\r
1217 // check to see we should throw JustPosted event
\r
1218 $blog->checkJustPosted();
\r
1222 * Show error skin with given message. An optional skin-object to use can be given
\r
1224 function doError($msg, $skin = '') {
\r
1225 global $errormessage, $CONF, $skinid, $blogid, $manager;
\r
1227 if ($skin == '') {
\r
1229 if (SKIN::existsID($skinid) ) {
\r
1230 $skin = new SKIN($skinid);
\r
1231 } elseif ($manager->existsBlogID($blogid) ) {
\r
1232 $blog =& $manager->getBlog($blogid);
\r
1233 $skin = new SKIN($blog->getDefaultSkin() );
\r
1234 } elseif ($CONF['DefaultBlog']) {
\r
1235 $blog =& $manager->getBlog($CONF['DefaultBlog']);
\r
1236 $skin = new SKIN($blog->getDefaultSkin() );
\r
1238 // this statement should actually never be executed
\r
1239 $skin = new SKIN($CONF['BaseSkin']);
\r
1244 $skinid = $skin->id;
\r
1245 $errormessage = $msg;
\r
1246 $skin->parse('error');
\r
1250 function getConfig() {
\r
1253 $query = 'SELECT * FROM ' . sql_table('config');
\r
1254 $res = sql_query($query);
\r
1256 while ($obj = sql_fetch_object($res) ) {
\r
1257 $CONF[$obj->name] = $obj->value;
\r
1261 // some checks for names of blogs, categories, templates, members, ...
\r
1262 function isValidShortName($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]+$', $name)
\r
1265 return preg_match('#^[a-z0-9]+$#i', $name);
\r
1268 function isValidDisplayName($name) {
\r
1269 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
\r
1270 # original eregi: eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name)
\r
1271 return preg_match('#^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$#i', $name);
\r
1274 function isValidCategoryName($name) {
\r
1278 function isValidTemplateName($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 function isValidSkinName($name) {
\r
1285 # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0
\r
1286 # original eregi: eregi('^[a-z0-9/]+$', $name);
\r
1287 return preg_match('#^[a-z0-9/]+$#i', $name);
\r
1290 // add and remove linebreaks
\r
1291 function addBreaks($var) {
\r
1292 return nl2br($var);
\r
1295 function removeBreaks($var) {
\r
1296 return preg_replace("/<br \/>([\r\n])/", "$1", $var);
\r
1299 // shortens a text string to maxlength ($toadd) is what needs to be added
\r
1300 // at the end (end length is <= $maxlength)
\r
1301 function shorten($text, $maxlength, $toadd) {
\r
1302 // 1. remove entities...
\r
1303 // $trans = get_html_translation_table(HTML_ENTITIES);
\r
1304 $trans = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
1305 $trans = array_flip($trans);
\r
1306 $text = strtr($text, $trans);
\r
1308 // 2. the actual shortening
\r
1309 if (strlen($text) > $maxlength) {
\r
1310 // $text = substr($text, 0, $maxlength - strlen($toadd) ) . $toadd;
\r
1311 $text = mb_strimwidth($text, 0, $maxlength, $toadd, _CHARSET); // for Japanese
\r
1318 * Converts a unix timestamp to a mysql DATETIME format, and places
\r
1319 * quotes around it.
\r
1321 function mysqldate($timestamp) {
\r
1322 return '"' . date('Y-m-d H:i:s', $timestamp) . '"';
\r
1326 * functions for use in index.php
\r
1328 function selectBlog($shortname) {
\r
1329 global $blogid, $archivelist;
\r
1331 $blogid = getBlogIDFromName($shortname);
\r
1334 // also force archivelist variable, if it is set
\r
1335 if ($archivelist) {
\r
1336 $archivelist = $blogid;
\r
1340 function selectSkin($skinname) {
\r
1343 $skinid = SKIN::getIdFromName($skinname);
\r
1348 * Can take either a category ID or a category name (be aware that
\r
1349 * multiple categories can have the same name)
\r
1351 function selectCategory($cat) {
\r
1354 if (is_numeric($cat) ) {
\r
1355 $catid = intval($cat);
\r
1357 $catid = getCatIDFromName($cat);
\r
1362 function selectItem($id) {
\r
1365 $itemid = intval($id);
\r
1369 // force the use of a language file (warning: can cause warnings)
\r
1370 function selectLanguage($language) {
\r
1374 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
1375 # original ereg_replace: preg_replace( '@\\|/@', '', $language) . '.php')
\r
1376 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
1378 include($DIR_LANG . preg_replace('#[\\\\|/]#', '', $language) . '.php');
\r
1382 function parseFile($filename, $includeMode = 'normal', $includePrefix = '') {
\r
1383 $handler = new ACTIONS('fileparser');
\r
1384 $parser = new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);
\r
1385 $handler->parser =& $parser;
\r
1387 // set IncludeMode properties of parser
\r
1388 PARSER::setProperty('IncludeMode', $includeMode);
\r
1389 PARSER::setProperty('IncludePrefix', $includePrefix);
\r
1391 if (!file_exists($filename) ) {
\r
1392 doError(_GFUNCTIONS_PARSEFILE_FILEMISSING);
\r
1395 $fsize = filesize($filename);
\r
1397 if ($fsize <= 0) {
\r
1402 $fd = fopen ($filename, 'r');
\r
1403 $contents = fread ($fd, $fsize);
\r
1406 // parse file contents
\r
1407 $parser->parse($contents);
\r
1411 * Outputs a debug message
\r
1413 function debug($msg) {
\r
1414 echo '<p><b>' . $msg . "</b></p>\n";
\r
1418 function addToLog($level, $msg) {
\r
1419 ACTIONLOG::add($level, $msg);
\r
1422 // shows a link to help file
\r
1423 function help($id) {
\r
1424 echo helpHtml($id);
\r
1427 function helpHtml($id) {
\r
1429 return helplink($id) . '<img src="' . $CONF['AdminURL'] . 'documentation/icon-help.gif" width="15" height="15" alt="' . _HELP_TT . '" title="' . _HELP_TT . '" /></a>';
\r
1432 function helplink($id) {
\r
1434 return '<a href="' . $CONF['AdminURL'] . 'documentation/help.html#'. $id . '" onclick="if (event && event.preventDefault) event.preventDefault(); return help(this.href);">';
\r
1437 function getMailFooter() {
\r
1438 $message = "\n\n-----------------------------";
\r
1439 $message .= "\n Powered by Nucleus CMS";
\r
1440 $message .= "\n(http://www.nucleuscms.org/)";
\r
1445 * Returns the name of the language to use
\r
1446 * preference priority: member - site
\r
1447 * defaults to english when no good language found
\r
1449 * checks if file exists, etc...
\r
1451 function getLanguageName() {
\r
1452 global $CONF, $member;
\r
1454 if ($member && $member->isLoggedIn() ) {
\r
1455 // try to use members language
\r
1456 $memlang = $member->getLanguage();
\r
1458 if (($memlang != '') && (checkLanguage($memlang) ) ) {
\r
1463 // use default language
\r
1464 if (checkLanguage($CONF['Language']) ) {
\r
1465 return $CONF['Language'];
\r
1472 * Includes a PHP file. This method can be called while parsing templates and skins
\r
1474 function includephp($filename) {
\r
1475 // make predefined variables global, so most simple scripts can be used here
\r
1477 // apache (names taken from PHP doc)
\r
1478 global $GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE, $SERVER_PROTOCOL;
\r
1479 global $REQUEST_METHOD, $QUERY_STRING, $DOCUMENT_ROOT, $HTTP_ACCEPT;
\r
1480 global $HTTP_ACCEPT_CHARSET, $HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE;
\r
1481 global $HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER, $HTTP_USER_AGENT;
\r
1482 global $REMOTE_ADDR, $REMOTE_PORT, $SCRIPT_FILENAME, $SERVER_ADMIN;
\r
1483 global $SERVER_PORT, $SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME;
\r
1484 global $REQUEST_URI;
\r
1486 // php (taken from PHP doc)
\r
1487 global $argv, $argc, $PHP_SELF, $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS;
\r
1488 global $HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS, $HTTP_SESSION_VARS;
\r
1491 global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;
\r
1493 if (@file_exists($filename) ) {
\r
1494 include($filename);
\r
1499 * Checks if a certain language exists
\r
1500 * @param string $lang
\r
1503 function checkLanguage($lang) {
\r
1505 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
1506 # original ereg_replace: ereg_replace( '[\\|/]', '', $lang) . '.php')
\r
1507 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
1508 return file_exists($DIR_LANG . preg_replace('#[\\\\|/]#', '', $lang) . '.php');
\r
1512 * Checks if a certain plugin exists
\r
1513 * @param string $plug
\r
1516 function checkPlugin($plug) {
\r
1518 global $DIR_PLUGINS;
\r
1520 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
1521 # original ereg_replace: ereg_replace( '[\\|/]', '', $plug) . '.php')
\r
1522 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
1524 return file_exists($DIR_PLUGINS . preg_replace('#[\\\\|/]#', '', $plug) . '.php');
\r
1529 * Centralisation of the functions that generate links
\r
1531 function createItemLink($itemid, $extra = '') {
\r
1532 return createLink('item', array('itemid' => $itemid, 'extra' => $extra) );
\r
1535 function createMemberLink($memberid, $extra = '') {
\r
1536 return createLink('member', array('memberid' => $memberid, 'extra' => $extra) );
\r
1539 function createCategoryLink($catid, $extra = '') {
\r
1540 return createLink('category', array('catid' => $catid, 'extra' => $extra) );
\r
1543 function createArchiveListLink($blogid = '', $extra = '') {
\r
1544 return createLink('archivelist', array('blogid' => $blogid, 'extra' => $extra) );
\r
1547 function createArchiveLink($blogid, $archive, $extra = '') {
\r
1548 return createLink('archive', array('blogid' => $blogid, 'archive' => $archive, 'extra' => $extra) );
\r
1551 function createBlogidLink($blogid, $params = '') {
\r
1552 return createLink('blog', array('blogid' => $blogid, 'extra' => $params) );
\r
1555 function createLink($type, $args) {
\r
1556 global $manager, $CONF;
\r
1558 $generatedURL = '';
\r
1559 $usePathInfo = ($CONF['URLMode'] == 'pathinfo');
\r
1561 // ask plugins first
\r
1564 if ($usePathInfo) {
\r
1568 'completed' => &$created,
\r
1571 $manager->notify('GenerateURL', $param);
\r
1574 // if a plugin created the URL, return it
\r
1579 // default implementation
\r
1582 if ($usePathInfo) {
\r
1583 $url = $CONF['ItemURL'] . '/' . $CONF['ItemKey'] . '/' . $args['itemid'];
\r
1585 $url = $CONF['ItemURL'] . '?itemid=' . $args['itemid'];
\r
1590 if ($usePathInfo) {
\r
1591 $url = $CONF['MemberURL'] . '/' . $CONF['MemberKey'] . '/' . $args['memberid'];
\r
1593 $url = $CONF['MemberURL'] . '?memberid=' . $args['memberid'];
\r
1598 if ($usePathInfo) {
\r
1599 $url = $CONF['CategoryURL'] . '/' . $CONF['CategoryKey'] . '/' . $args['catid'];
\r
1601 $url = $CONF['CategoryURL'] . '?catid=' . $args['catid'];
\r
1605 case 'archivelist':
\r
1606 if (!$args['blogid']) {
\r
1607 $args['blogid'] = $CONF['DefaultBlog'];
\r
1610 if ($usePathInfo) {
\r
1611 $url = $CONF['ArchiveListURL'] . '/' . $CONF['ArchivesKey'] . '/' . $args['blogid'];
\r
1613 $url = $CONF['ArchiveListURL'] . '?archivelist=' . $args['blogid'];
\r
1618 if ($usePathInfo) {
\r
1619 $url = $CONF['ArchiveURL'] . '/' . $CONF['ArchiveKey'] . '/'.$args['blogid'].'/' . $args['archive'];
\r
1621 $url = $CONF['ArchiveURL'] . '?blogid='.$args['blogid'].'&archive=' . $args['archive'];
\r
1626 if ($usePathInfo) {
\r
1627 $url = $CONF['BlogURL'] . '/' . $CONF['BlogKey'] . '/' . $args['blogid'];
\r
1629 $url = $CONF['BlogURL'] . '?blogid=' . $args['blogid'];
\r
1634 return addLinkParams($url, (isset($args['extra'])? $args['extra'] : null));
\r
1637 function createBlogLink($url, $params) {
\r
1639 if ($CONF['URLMode'] == 'normal') {
\r
1640 if (strpos($url, '?') === FALSE && is_array($params)) {
\r
1641 $fParam = reset($params);
\r
1642 $fKey = key($params);
\r
1643 array_shift($params);
\r
1644 $url .= '?' . $fKey . '=' . $fParam;
\r
1646 } elseif ($CONF['URLMode'] == 'pathinfo' && substr($url, -1) == '/') {
\r
1647 $url = substr($url, 0, -1);
\r
1649 return addLinkParams($url, $params);
\r
1652 function addLinkParams($link, $params) {
\r
1655 if (is_array($params) ) {
\r
1657 if ($CONF['URLMode'] == 'pathinfo') {
\r
1658 foreach ($params as $param => $value) {
\r
1659 // change in 3.63 to fix problem where URL generated with extra params mike look like category/4/blogid/1
\r
1660 // but they should use the URL keys like this: category/4/blog/1
\r
1661 // if user wants old urls back, set $CONF['NoURLKeysInExtraParams'] = 1; in config.php
\r
1662 if (isset($CONF['NoURLKeysInExtraParams']) && $CONF['NoURLKeysInExtraParams'] == 1)
\r
1664 $link .= '/' . $param . '/' . urlencode($value);
\r
1668 $link .= '/' . $CONF['ItemKey'] . '/' . urlencode($value);
\r
1671 $link .= '/' . $CONF['MemberKey'] . '/' . urlencode($value);
\r
1674 $link .= '/' . $CONF['CategoryKey'] . '/' . urlencode($value);
\r
1676 case 'archivelist':
\r
1677 $link .= '/' . $CONF['ArchivesKey'] . '/' . urlencode($value);
\r
1680 $link .= '/' . $CONF['ArchiveKey'] . '/' . urlencode($value);
\r
1683 $link .= '/' . $CONF['BlogKey'] . '/' . urlencode($value);
\r
1686 $link .= '/' . $param . '/' . urlencode($value);
\r
1693 foreach ($params as $param => $value) {
\r
1694 $link .= '&' . $param . '=' . urlencode($value);
\r
1704 * @param $querystr
\r
1705 * querystring to alter (e.g. foo=1&bar=2&x=y)
\r
1707 * name of parameter to change (e.g. 'foo')
\r
1709 * New value for that parameter (e.g. 3)
\r
1711 * altered query string (for the examples above: foo=3&bar=2&x=y)
\r
1713 function alterQueryStr($querystr, $param, $value) {
\r
1714 $vars = explode('&', $querystr);
\r
1717 for ($i = 0; $i < count($vars); $i++) {
\r
1718 $v = explode('=', $vars[$i]);
\r
1720 if ($v[0] == $param) {
\r
1722 $vars[$i] = implode('=', $v);
\r
1729 $vars[] = $param . '=' . $value;
\r
1732 return ltrim(implode('&', $vars), '&');
\r
1735 // passes one variable as hidden input field (multiple fields for arrays)
\r
1736 // @see passRequestVars in varsx.x.x.php
\r
1737 function passVar($key, $value) {
\r
1739 if (is_array($value) ) {
\r
1740 for ($i = 0; $i < sizeof($value); $i++) {
\r
1741 passVar($key . '[' . $i . ']', $value[$i]);
\r
1747 // other values: do stripslashes if needed
\r
1748 ?><input type="hidden" name="<?php echo htmlspecialchars($key)?>" value="<?php echo htmlspecialchars(undoMagic($value) )?>" /><?php
\r
1752 Date format functions (to be used from [%date(..)%] skinvars
\r
1754 function formatDate($format, $timestamp, $defaultFormat, &$blog) {
\r
1755 // apply blog offset (#42)
\r
1756 $boffset = $blog ? $blog->getTimeOffset() * 3600 : 0;
\r
1757 $offset = date('Z', $timestamp) + $boffset;
\r
1759 switch ($format) {
\r
1761 if ($offset >= 0) {
\r
1765 $offset = -$offset;
\r
1768 $tz .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1769 return date('D, j M Y H:i:s ', $timestamp) . $tz;
\r
1772 $timestamp -= $offset;
\r
1773 return date('D, j M Y H:i:s ', $timestamp) . 'GMT';
\r
1776 $timestamp -= $offset;
\r
1777 return date('Y-m-d\TH:i:s\Z', $timestamp);
\r
1780 if ($offset >= 0) {
\r
1784 $offset = -$offset;
\r
1787 $tz .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1788 return date('Y-m-d\TH:i:s', $timestamp) . $tz;
\r
1791 return strftimejp($format ? $format : $defaultFormat, $timestamp);
\r
1795 function encoding_check($val, $key, $encoding=false, $exclude=false) {
\r
1797 When 3rd argument is set, return if checked already.
\r
1798 When 4th argument is set, set the excluded key(s).
\r
1800 static $search=false, $checked=array(), $excludes=array();
\r
1801 if ($exclude!==false) {
\r
1802 if (is_array($exclude)) {
\r
1803 foreach($exclude as $v) $excludes[$v]=true;
\r
1804 } else $excludes[$exclude]=true;
\r
1807 if ($encoding!==false) {
\r
1808 switch($encoding=strtolower($encoding)){
\r
1810 $search='/([\x00-\x7F]+'.
\r
1811 '|[\xC2-\xDF][\x80-\xBF]'.
\r
1812 '|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]'.
\r
1813 '|[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1814 '|[\xF8-\xFB][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1815 '|[\xFC-\xFD][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF])/';
\r
1818 $search='/([\x00-\x7F]+'.
\r
1819 '|[\x8E][\xA0-\xDF]'.
\r
1820 '|[\x8F]?[\xA1-\xFE][\xA1-\xFE])/';
\r
1823 $search='/([\x00-\x7F]+'.
\r
1824 '|[\xA1-\xF7][\xA1-\xFE])/';
\r
1827 // Note that shift_jis is only supported for output.
\r
1828 // Using shift_jis in DB is prohibited.
\r
1829 $search='/([\x00-\x7F\xA1-\xDF]+'.
\r
1830 '|[\x81-\x9F\xE0-\xFC][\x40-\xFC])/';
\r
1834 if (preg_match('/^iso\-8859\-[0-9]{1,2}$/',$encoding)) break;
\r
1835 if (preg_match('/^windows\-125[0-8]$/',$encoding)) break;
\r
1836 startUpError('<p>Unknown or non-supported encoding.</p>', 'Encoding Error');
\r
1839 if (isset($checked[$encoding])) return true; // Already checked.
\r
1840 $checked[$encoding]=true;
\r
1842 if ($key===false) return false; // Not yet checked.
\r
1843 if ($search===false) return true; // non-multibyte encoding
\r
1844 if (isset($excludes[$key])) return true; // This key isn't checked.
\r
1845 if (is_array($val)) {
\r
1846 array_walk($val, 'encoding_check');
\r
1848 $result=preg_replace($search,'',$val);
\r
1849 if (strlen($result)!=0) {
\r
1850 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1854 $result=preg_replace($search,'',$key);
\r
1855 if (strlen($result)!=0) {
\r
1856 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1862 function checkVars($aVars) {
\r
1863 global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;
\r
1865 foreach ($aVars as $varName) {
\r
1867 if (phpversion() >= '4.1.0') {
\r
1869 if ( isset($_GET[$varName])
\r
1870 || isset($_POST[$varName])
\r
1871 || isset($_COOKIE[$varName])
\r
1872 || isset($_ENV[$varName])
\r
1873 || isset($_SESSION[$varName])
\r
1874 || isset($_FILES[$varName])
\r
1876 die('Sorry. An error occurred.');
\r
1881 if ( isset($HTTP_GET_VARS[$varName])
\r
1882 || isset($HTTP_POST_VARS[$varName])
\r
1883 || isset($HTTP_COOKIE_VARS[$varName])
\r
1884 || isset($HTTP_ENV_VARS[$varName])
\r
1885 || isset($HTTP_SESSION_VARS[$varName])
\r
1886 || isset($HTTP_POST_FILES[$varName])
\r
1888 die('Sorry. An error occurred.');
\r
1897 * Sanitize parameters such as $_GET and $_SERVER['REQUEST_URI'] etc.
\r
1900 function sanitizeParams()
\r
1902 global $HTTP_SERVER_VARS;
\r
1908 // REQUEST_URI of $HTTP_SERVER_VARS
\r
1909 $str =& $HTTP_SERVER_VARS["REQUEST_URI"];
\r
1910 serverStringToArray($str, $array, $frontParam);
\r
1911 sanitizeArray($array);
\r
1912 arrayToServerString($array, $frontParam, $str);
\r
1914 // QUERY_STRING of $HTTP_SERVER_VARS
\r
1915 $str =& $HTTP_SERVER_VARS["QUERY_STRING"];
\r
1916 serverStringToArray($str, $array, $frontParam);
\r
1917 sanitizeArray($array);
\r
1918 arrayToServerString($array, $frontParam, $str);
\r
1920 if (phpversion() >= '4.1.0') {
\r
1921 // REQUEST_URI of $_SERVER
\r
1922 $str =& $_SERVER["REQUEST_URI"];
\r
1923 serverStringToArray($str, $array, $frontParam);
\r
1924 sanitizeArray($array);
\r
1925 arrayToServerString($array, $frontParam, $str);
\r
1927 // QUERY_STRING of $_SERVER
\r
1928 $str =& $_SERVER["QUERY_STRING"];
\r
1929 serverStringToArray($str, $array, $frontParam);
\r
1930 sanitizeArray($array);
\r
1931 arrayToServerString($array, $frontParam, $str);
\r
1935 convArrayForSanitizing($_GET, $array);
\r
1936 sanitizeArray($array);
\r
1937 revertArrayForSanitizing($array, $_GET);
\r
1939 // $_REQUEST (only GET param)
\r
1940 convArrayForSanitizing($_REQUEST, $array);
\r
1941 sanitizeArray($array);
\r
1942 revertArrayForSanitizing($array, $_REQUEST);
\r
1946 * Check ticket when not checked in plugin's admin page
\r
1948 * Also avoid the access to plugin/index.php by guest user.
\r
1950 function ticketForPlugin(){
\r
1951 global $CONF,$DIR_PLUGINS,$member,$ticketforplugin;
\r
1954 $ticketforplugin=array();
\r
1955 $ticketforplugin['ticket'] = FALSE;
\r
1957 /* Check if using plugin's php file. */
\r
1958 if ($p_translated = serverVar('PATH_TRANSLATED') )
\r
1960 if (!file_exists($p_translated) )
\r
1962 $p_translated = '';
\r
1966 if (!$p_translated)
\r
1968 $p_translated = serverVar('SCRIPT_FILENAME');
\r
1969 if (!file_exists($p_translated) )
\r
1971 header("HTTP/1.0 404 Not Found");
\r
1976 $p_translated=str_replace('\\','/',$p_translated);
\r
1977 $d_plugins=str_replace('\\','/',$DIR_PLUGINS);
\r
1979 if (strpos($p_translated, $d_plugins) !== 0)
\r
1981 return;// This isn't plugin php file.
\r
1984 /* Solve the plugin php file or admin directory */
\r
1985 $phppath=substr($p_translated,strlen($d_plugins));
\r
1986 $phppath=preg_replace('#^/#','',$phppath);// Remove the first "/" if exists.
\r
1987 $path=preg_replace('#^NP_(.*)\.php$#','$1',$phppath); // Remove the first "NP_" and the last ".php" if exists.
\r
1988 $path=preg_replace('#^([^/]*)/(.*)$#','$1',$path); // Remove the "/" and beyond.
\r
1990 /* Solve the plugin name. */
\r
1992 $query='SELECT `pfile` FROM '.sql_table('plugin');
\r
1993 $res=sql_query($query);
\r
1994 while($row=sql_fetch_row($res))
\r
1996 $name=substr($row[0],3);
\r
1997 $plugins[strtolower($name)]=$name;
\r
1999 sql_free_result($res);
\r
2001 if ($plugins[$path])
\r
2003 $plugin_name = $plugins[$path];
\r
2005 else if (in_array($path, $plugins))
\r
2007 $plugin_name = $path;
\r
2011 header("HTTP/1.0 404 Not Found");
\r
2015 /* Return if not index.php */
\r
2016 if ( ($phppath != strtolower($plugin_name) . '/') && ($phppath != strtolower($plugin_name) . '/index.php') )
\r
2021 /* Exit if not logged in. */
\r
2022 if ( !$member->isLoggedIn() )
\r
2024 exit(_GFUNCTIONS_YOU_AERNT_LOGGEDIN);
\r
2027 global $manager,$DIR_LIBS,$DIR_LANG,$HTTP_GET_VARS,$HTTP_POST_VARS;
\r
2029 /* Check if this feature is needed (ie, if "$manager->checkTicket()" is not included in the script). */
\r
2030 if (!($p_translated=serverVar('PATH_TRANSLATED')))
\r
2032 $p_translated=serverVar('SCRIPT_FILENAME');
\r
2034 if ($file=@file($p_translated))
\r
2037 foreach($file as $line)
\r
2039 if (preg_match('/[\$]manager([\s]*)[\-]>([\s]*)checkTicket([\s]*)[\(]/i',$prevline.$line))
\r
2047 /* Show a form if not valid ticket */
\r
2048 if ( ( strstr(serverVar('REQUEST_URI'),'?') || serverVar('QUERY_STRING')
\r
2049 || strtoupper(serverVar('REQUEST_METHOD'))=='POST' )
\r
2050 && (!$manager->checkTicket()) )
\r
2052 if (!class_exists('PluginAdmin'))
\r
2054 $language = getLanguageName();
\r
2056 # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0
\r
2057 # original ereg_replace: ereg_replace( '[\\|/]', '', $language) . '.php')
\r
2058 # important note that '\' must be matched with '\\\\' in preg* expressions
\r
2059 include($DIR_LANG . preg_replace('#[\\\\|/]#', '', $language) . '.php');
\r
2060 include($DIR_LIBS . 'PLUGINADMIN.php');
\r
2063 $oPluginAdmin = new PluginAdmin($plugin_name);
\r
2064 $oPluginAdmin->start();
\r
2065 echo '<p>' . _ERROR_BADTICKET . "</p>\n";
\r
2067 /* Show the form to confirm action */
\r
2068 // PHP 4.0.x support
\r
2069 $get= (isset($_GET)) ? $_GET : $HTTP_GET_VARS;
\r
2070 $post= (isset($_POST)) ? $_POST : $HTTP_POST_VARS;
\r
2071 // Resolve URI and QUERY_STRING
\r
2072 if ($uri=serverVar('REQUEST_URI'))
\r
2074 list($uri,$qstring)=explode('?',$uri);
\r
2078 if ( !($uri=serverVar('PHP_SELF')) )
\r
2080 $uri=serverVar('SCRIPT_NAME');
\r
2082 $qstring=serverVar('QUERY_STRING');
\r
2086 $qstring='?'.$qstring;
\r
2088 echo '<p>'._SETTINGS_UPDATE.' : '._QMENU_PLUGINS.' <span style="color:red;">'.htmlspecialchars($plugin_name)."</span> ?</p>\n";
\r
2089 switch(strtoupper(serverVar('REQUEST_METHOD')))
\r
2092 echo '<form method="POST" action="'.htmlspecialchars($uri.$qstring).'">';
\r
2093 $manager->addTicketHidden();
\r
2094 _addInputTags($post);
\r
2097 echo '<form method="GET" action="'.htmlspecialchars($uri).'">';
\r
2098 $manager->addTicketHidden();
\r
2099 _addInputTags($get);
\r
2103 echo '<input type="submit" value="'._YES.'" /> ';
\r
2104 echo '<input type="button" value="'._NO.'" onclick="history.back(); return false;" />';
\r
2107 $oPluginAdmin->end();
\r
2111 /* Create new ticket */
\r
2112 $ticket=$manager->addTicketToUrl('');
\r
2113 $ticketforplugin['ticket']=substr($ticket,strpos($ticket,'ticket=')+7);
\r
2115 function _addInputTags(&$keys,$prefix=''){
\r
2116 foreach($keys as $key=>$value){
\r
2117 if ($prefix) $key=$prefix.'['.$key.']';
\r
2118 if (is_array($value)) _addInputTags($value,$key);
\r
2120 if (get_magic_quotes_gpc()) $value=stripslashes($value);
\r
2121 if ($key=='ticket') continue;
\r
2122 echo '<input type="hidden" name="'.htmlspecialchars($key).
\r
2123 '" value="'.htmlspecialchars($value).'" />'."\n";
\r
2129 * Convert the server string such as $_SERVER['REQUEST_URI']
\r
2130 * to arry like arry['blogid']=1 and array['page']=2 etc.
\r
2132 function serverStringToArray($str, &$array, &$frontParam)
\r
2138 // split front param, e.g. /index.php, and others, e.g. blogid=1&page=2
\r
2139 if (strstr($str, "?")){
\r
2140 list($frontParam, $args) = preg_split("/\?/", $str, 2);
\r
2147 // If there is no args like blogid=1&page=2, return
\r
2148 if (!strstr($str, "=") && !strlen($frontParam)) {
\r
2149 $frontParam = $str;
\r
2153 $array = explode("&", $args);
\r
2157 * Convert array like array['blogid'] to server string
\r
2158 * such as $_SERVER['REQUEST_URI']
\r
2160 function arrayToServerString($array, $frontParam, &$str)
\r
2162 if (strstr($str, "?")) {
\r
2163 $str = $frontParam . "?";
\r
2165 $str = $frontParam;
\r
2167 if (count($array)) {
\r
2168 $str .= implode("&", $array);
\r
2173 * Sanitize array parameters.
\r
2174 * This function checks both key and value.
\r
2175 * - check key if it inclues " (double quote), remove from array
\r
2176 * - check value if it includes \ (escape sequece), remove remaining string
\r
2178 function sanitizeArray(&$array)
\r
2180 $excludeListForSanitization = array('query');
\r
2181 // $excludeListForSanitization = array();
\r
2183 foreach ($array as $k => $v) {
\r
2185 // split to key and value
\r
2186 list($key, $val) = preg_split("/=/", $v, 2);
\r
2187 if (!isset($val)) {
\r
2191 // when magic quotes is on, need to use stripslashes,
\r
2192 // and then addslashes
\r
2193 if (get_magic_quotes_gpc()) {
\r
2194 $val = stripslashes($val);
\r
2196 // note that we must use addslashes here because this function is called before the db connection is made
\r
2197 // and sql_real_escape_string needs a db connection
\r
2198 $val = addslashes($val);
\r
2200 // if $key is included in exclude list, skip this param
\r
2201 if (!in_array($key, $excludeListForSanitization)) {
\r
2204 if (strpos($val, '\\')) {
\r
2205 list($val, $tmp) = explode('\\', $val);
\r
2208 // remove control code etc.
\r
2209 $val = strtr($val, "\0\r\n<>'\"", " ");
\r
2212 if (preg_match('/\"/i', $key)) {
\r
2213 unset($array[$k]);
\r
2217 // set sanitized info
\r
2218 $array[$k] = sprintf("%s=%s", $key, $val);
\r
2224 * Convert array for sanitizeArray function
\r
2226 function convArrayForSanitizing($src, &$array)
\r
2229 foreach ($src as $key => $val) {
\r
2230 if (key_exists($key, $_GET)) {
\r
2231 array_push($array, sprintf("%s=%s", $key, $val));
\r
2237 * Revert array after sanitizeArray function
\r
2239 function revertArrayForSanitizing($array, &$dst)
\r
2241 foreach ($array as $v) {
\r
2242 list($key, $val) = preg_split("/=/", $v, 2);
\r
2243 $dst[$key] = $val;
\r
2248 * Stops processing the request and redirects to the given URL.
\r
2249 * - no actual contents should have been sent to the output yet
\r
2250 * - the URL will be stripped of illegal or dangerous characters
\r
2252 function redirect($url) {
\r
2253 $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%*]|i', '', $url);
\r
2254 header('Location: ' . $url);
\r
2259 * Strip HTML tags from a string
\r
2260 * This function is a bit more intelligent than a regular call to strip_tags(),
\r
2261 * because it also deletes the contents of certain tags and cleans up any
\r
2262 * unneeded whitespace.
\r
2264 function stringStripTags ($string) {
\r
2265 $string = preg_replace("/<del[^>]*>.+<\/del[^>]*>/isU", '', $string);
\r
2266 $string = preg_replace("/<script[^>]*>.+<\/script[^>]*>/isU", '', $string);
\r
2267 $string = preg_replace("/<style[^>]*>.+<\/style[^>]*>/isU", '', $string);
\r
2268 $string = str_replace('>', '> ', $string);
\r
2269 $string = str_replace('<', ' <', $string);
\r
2270 $string = strip_tags($string);
\r
2271 $string = preg_replace("/\s+/", " ", $string);
\r
2272 $string = trim($string);
\r
2277 * Make a string containing HTML safe for use in a HTML attribute
\r
2278 * Tags are stripped and entities are normalized
\r
2280 function stringToAttribute ($string) {
\r
2281 $string = stringStripTags($string);
\r
2282 $string = entity::named_to_numeric($string);
\r
2283 $string = entity::normalize_numeric($string);
\r
2285 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2286 $string = entity::numeric_to_utf8($string);
\r
2289 $string = entity::specialchars($string, 'html');
\r
2290 $string = entity::numeric_to_named($string);
\r
2295 * Make a string containing HTML safe for use in a XML document
\r
2296 * Tags are stripped, entities are normalized and named entities are
\r
2297 * converted to numeric entities.
\r
2299 function stringToXML ($string) {
\r
2300 $string = stringStripTags($string);
\r
2301 $string = entity::named_to_numeric($string);
\r
2302 $string = entity::normalize_numeric($string);
\r
2304 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2305 $string = entity::numeric_to_utf8($string);
\r
2308 $string = entity::specialchars($string, 'xml');
\r
2312 // START: functions from the end of file BLOG.php
\r
2313 // used for mail notification (html -> text)
\r
2314 function toAscii($html) {
\r
2315 // strip off most tags
\r
2316 $html = strip_tags($html,'<a>');
\r
2317 $to_replace = "/<a[^>]*href=[\"\']([^\"^']*)[\"\'][^>]*>([^<]*)<\/a>/i";
\r
2319 $ascii = preg_replace_callback ($to_replace, '_links_add', $html);
\r
2320 $ascii .= "\n\n" . _links_list();
\r
2321 return strip_tags($ascii);
\r
2324 function _links_init() {
\r
2325 global $tmp_links;
\r
2326 $tmp_links = array();
\r
2329 function _links_add($match) {
\r
2330 global $tmp_links;
\r
2331 array_push($tmp_links, $match[1]);
\r
2332 return $match[2] . ' [' . sizeof($tmp_links) .']';
\r
2335 function _links_list() {
\r
2336 global $tmp_links;
\r
2339 foreach ($tmp_links as $current) {
\r
2340 $output .= "[$i] $current\n";
\r
2345 // END: functions from the end of file BLOG.php
\r
2347 // START: functions from the end of file ADMIN.php
\r
2349 * @todo document this
\r
2351 function encode_desc(&$data)
\r
2353 // _$to_entities = get_html_translation_table(HTML_ENTITIES);
\r
2354 $to_entities = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
2355 $from_entities = array_flip($to_entities);
\r
2356 $data = str_replace('<br />', '\n', $data); //hack
\r
2357 $data = strtr($data,$from_entities);
\r
2358 $data = strtr($data,$to_entities);
\r
2359 $data = str_replace('\n', '<br />', $data); //hack
\r
2364 * Returns the Javascript code for a bookmarklet that works on most modern browsers
\r
2368 function getBookmarklet($blogid) {
\r
2372 $document = 'document';
\r
2373 $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
2374 $bookmarkletline .= $CONF['AdminURL'] . "bookmarklet.php?blogid=$blogid";
\r
2375 $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
2377 return $bookmarkletline;
\r
2379 // END: functions from the end of file ADMIN.php
\r
2382 * Returns a variable or null if not set
\r
2384 * @param mixed Variable
\r
2385 * @return mixed Variable
\r
2387 function ifset(&$var) {
\r
2388 if (isset($var)) {
\r
2396 * Returns number of subscriber to an event
\r
2399 * @return number of subscriber(s)
\r
2401 function numberOfEventSubscriber($event) {
\r
2402 $query = 'SELECT COUNT(*) as count FROM ' . sql_table('plugin_event') . ' WHERE event=\'' . $event . '\'';
\r
2403 $res = sql_query($query);
\r
2404 $obj = sql_fetch_object($res);
\r
2405 return $obj->count;
\r
2409 * sets $special global variable for use in index.php before selector()
\r
2411 * @param String id
\r
2414 function selectSpecialSkinType($id) {
\r
2416 $special = strtolower($id);
\r
2420 * cleans filename of uploaded file for writing to file system
\r
2422 * @param String str
\r
2423 * @return String cleaned filename ready for use
\r
2425 function cleanFileName($str) {
\r
2426 $str = strtolower($str);
\r
2427 $ext_point = strrpos($str,".");
\r
2428 if ($ext_point===false) return false;
\r
2429 $ext = substr($str,$ext_point,strlen($str));
\r
2430 $str = substr($str,0,$ext_point);
\r
2432 return preg_replace("/[^a-z0-9-]/","_",$str).$ext;
\r
2436 * generate correct timecode with the format includes Japanese charactors
\r
2438 * @param String $format standard format string. Allowd to include Japanese charactors
\r
2439 * @param Integer $timestamp Unix Timestamp formated integer
\r
2440 * @return String Formatted timestamp
\r
2442 function strftimejp($format,$timestamp = ''){
\r
2443 return (setlocale(LC_CTYPE, 0) == 'Japanese_Japan.932')
\r
2444 ? iconv('CP932', _CHARSET, strftime(iconv(_CHARSET, 'CP932', $format),$timestamp))
\r
2445 : strftime($format,$timestamp)
\r