4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
\r
5 * Copyright (C) 2002-2010 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-2010 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.51';
\r
24 $nucleus['codename'] = '';
\r
26 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
29 if ($CONF['debug']) {
\r
30 error_reporting(E_ALL); // report all errors!
\r
32 ini_set('display_errors','0');
\r
33 error_reporting(E_ERROR | E_WARNING | E_PARSE);
\r
37 Indicates when Nucleus should display startup errors. Set to 1 if you want
\r
38 the error enabled (default), false otherwise
\r
41 Displays an error when visiting a public Nucleus page and headers have
\r
42 been sent out to early. This usually indicates an error in either a
\r
43 configuration file or a language file, and could cause Nucleus to
\r
46 Displays an error only when visiting the admin area, and when one or
\r
47 more of the installation files (install.php, install.sql, upgrades/
\r
48 directory) are still on the server.
\r
51 $CONF['alertOnHeadersSent'] = 1;
\r
52 $CONF['alertOnSecurityRisk'] = 1;
\r
53 /*$CONF['ItemURL'] = $CONF['Self'];
\r
54 $CONF['ArchiveURL'] = $CONF['Self'];
\r
55 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
56 $CONF['MemberURL'] = $CONF['Self'];
\r
57 $CONF['SearchURL'] = $CONF['Self'];
\r
58 $CONF['BlogURL'] = $CONF['Self'];
\r
59 $CONF['CategoryURL'] = $CONF['Self'];
\r
61 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
62 // this avoids urls like index.php/item/13/index.php/item/15
\r
63 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
\r
64 $CONF['URLMode'] = 'normal';
\r
67 if (getNucleusPatchLevel() > 0) {
\r
68 $nucleus['version'] .= '/' . getNucleusPatchLevel();
\r
72 if (!isset($CONF['installscript'])) {
\r
73 $CONF['installscript'] = 0;
\r
76 // we will use postVar, getVar, ... methods instead of HTTP_GET_VARS or _GET
\r
77 if ($CONF['installscript'] != 1) { // vars were already included in install.php
\r
78 if (phpversion() >= '4.1.0') {
\r
79 include_once($DIR_LIBS . 'vars4.1.0.php');
\r
81 include_once($DIR_LIBS . 'vars4.0.6.php');
\r
86 $bLoggingSanitizedResult=0;
\r
87 $bSanitizeAndContinue=0;
\r
89 $orgRequestURI = serverVar('REQUEST_URI');
\r
92 // get all variables that can come from the request and put them in the global scope
\r
93 $blogid = requestVar('blogid');
\r
94 $itemid = intRequestVar('itemid');
\r
95 $catid = intRequestVar('catid');
\r
96 $skinid = requestVar('skinid');
\r
97 $memberid = requestVar('memberid');
\r
98 $archivelist = requestVar('archivelist');
\r
99 $imagepopup = requestVar('imagepopup');
\r
100 $archive = requestVar('archive');
\r
101 $query = requestVar('query');
\r
102 $highlight = requestVar('highlight');
\r
103 $amount = requestVar('amount');
\r
104 $action = requestVar('action');
\r
105 $nextaction = requestVar('nextaction');
\r
106 $maxresults = requestVar('maxresults');
\r
107 $startpos = intRequestVar('startpos');
\r
108 $errormessage = '';
\r
110 $special = requestVar('special');
\r
111 $virtualpath = ((getVar('virtualpath') != null) ? getVar('virtualpath') : serverVar('PATH_INFO'));
\r
113 if (!headers_sent() ) {
\r
114 header('Generator: Nucleus CMS ' . $nucleus['version']);
\r
117 // include core classes that are needed for login & plugin handling
\r
118 // added for 3.5 sql_* wrapper
\r
119 global $MYSQL_HANDLER;
\r
120 if (!isset($MYSQL_HANDLER))
\r
121 $MYSQL_HANDLER = array('mysql','');
\r
122 if ($MYSQL_HANDLER[0] == '')
\r
123 $MYSQL_HANDLER[0] = 'mysql';
\r
124 include_once($DIR_LIBS . 'sql/'.$MYSQL_HANDLER[0].'.php');
\r
125 // end new for 3.5 sql_* wrapper
\r
126 include_once($DIR_LIBS . 'mysql.php');
\r
127 include($DIR_LIBS . 'MEMBER.php');
\r
128 include($DIR_LIBS . 'ACTIONLOG.php');
\r
129 include($DIR_LIBS . 'MANAGER.php');
\r
130 include($DIR_LIBS . 'PLUGIN.php');
\r
132 $manager =& MANAGER::instance();
\r
134 // make sure there's no unnecessary escaping:
\r
135 //set_magic_quotes_runtime(0);
\r
136 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
\r
137 ini_set('magic_quotes_runtime', '0');
\r
141 if (!isset($CONF['UsingAdminArea'])) {
\r
142 $CONF['UsingAdminArea'] = 0;
\r
145 // only needed when updating logs
\r
146 if ($CONF['UsingAdminArea']) {
\r
147 include($DIR_LIBS . 'xmlrpc.inc.php'); // XML-RPC client classes
\r
148 include_once($DIR_LIBS . 'ADMIN.php');
\r
151 // connect to database
\r
155 // logs sanitized result if need
\r
156 if ($orgRequestURI!==serverVar('REQUEST_URI')) {
\r
157 $msg = "Sanitized [" . serverVar('REMOTE_ADDR') . "] ";
\r
158 $msg .= $orgRequestURI . " -> " . serverVar('REQUEST_URI');
\r
159 if ($bLoggingSanitizedResult) {
\r
160 addToLog(WARNING, $msg);
\r
162 if (!$bSanitizeAndContinue) {
\r
167 // makes sure database connection gets closed on script termination
\r
168 register_shutdown_function('sql_disconnect');
\r
173 // Properly set $CONF['Self'] and others if it's not set... usually when we are access from admin menu
\r
174 if (!isset($CONF['Self'])) {
\r
175 $CONF['Self'] = $CONF['IndexURL'];
\r
176 // strip trailing /
\r
177 if ($CONF['Self'][strlen($CONF['Self']) -1] == "/") {
\r
178 $CONF['Self'] = substr($CONF['Self'], 0, strlen($CONF['Self']) -1);
\r
181 /* $CONF['ItemURL'] = $CONF['Self'];
\r
182 $CONF['ArchiveURL'] = $CONF['Self'];
\r
183 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
184 $CONF['MemberURL'] = $CONF['Self'];
\r
185 $CONF['SearchURL'] = $CONF['Self'];
\r
186 $CONF['BlogURL'] = $CONF['Self'];
\r
187 $CONF['CategoryURL'] = $CONF['Self'];*/
\r
190 $CONF['ItemURL'] = $CONF['Self'];
\r
191 $CONF['ArchiveURL'] = $CONF['Self'];
\r
192 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
193 $CONF['MemberURL'] = $CONF['Self'];
\r
194 $CONF['SearchURL'] = $CONF['Self'];
\r
195 $CONF['BlogURL'] = $CONF['Self'];
\r
196 $CONF['CategoryURL'] = $CONF['Self'];
\r
198 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
199 // this avoids urls like index.php/item/13/index.php/item/15
\r
200 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
\r
201 $CONF['URLMode'] = 'normal';
\r
204 // automatically use simpler toolbar for mozilla
\r
205 if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'), 'Gecko') ) {
\r
206 $CONF['DisableJsTools'] = 2;
\r
209 // login if cookies set
\r
210 $member = new MEMBER();
\r
212 // secure cookie key settings (either 'none', 0, 8, 16, 24, or 32)
\r
213 if (!isset($CONF['secureCookieKey'])) $CONF['secureCookieKey']=24;
\r
214 switch($CONF['secureCookieKey']){
\r
216 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
219 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
222 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
225 $CONF['secureCookieKeyIP']=serverVar('REMOTE_ADDR');
\r
228 $CONF['secureCookieKeyIP']='';
\r
231 // login/logout when required or renew cookies
\r
232 if ($action == 'login') {
\r
233 // Form Authentication
\r
234 $login = postVar('login');
\r
235 $pw = postVar('password');
\r
236 $shared = intPostVar('shared'); // shared computer or not
\r
238 $pw=substr($pw,0,40); // avoid md5 collision by using a long key
\r
240 if ($member->login($login, $pw) ) {
\r
242 $member->newCookieKey();
\r
243 $member->setCookies($shared);
\r
245 if ($CONF['secureCookieKey']!=='none') {
\r
246 // secure cookie key
\r
247 $member->setCookieKey(md5($member->getCookieKey().$CONF['secureCookieKeyIP']));
\r
251 // allows direct access to parts of the admin area after logging in
\r
253 $action = $nextaction;
\r
256 $manager->notify('LoginSuccess', array('member' => &$member, 'username' => $login) );
\r
257 $errormessage = '';
\r
258 ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");
\r
260 // errormessage for [%errordiv%]
\r
261 $errormessage = 'Login failed for ' . $login;
\r
263 $manager->notify('LoginFailed', array('username' => $login) );
\r
264 ACTIONLOG::add(INFO, $errormessage);
\r
268 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
270 } elseif (serverVar('PHP_AUTH_USER') && serverVar('PHP_AUTH_PW')) {
\r
271 // HTTP Authentication
\r
272 $login = serverVar('PHP_AUTH_USER');
\r
273 $pw = serverVar('PHP_AUTH_PW');
\r
275 if ($member->login($login, $pw) ) {
\r
276 $manager->notify('LoginSuccess',array('member' => &$member));
\r
277 ACTIONLOG::add(INFO, "HTTP authentication successful for $login");
\r
279 $manager->notify('LoginFailed',array('username' => $login));
\r
280 ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);
\r
282 //Since bad credentials, generate an apropriate error page
\r
283 header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");
\r
284 header('HTTP/1.0 401 Unauthorized');
\r
285 echo 'Invalid username or password';
\r
290 } elseif (($action == 'logout') && (!headers_sent() ) && cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
291 // remove cookies on logout
\r
292 setcookie($CONF['CookiePrefix'] . 'user', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
293 setcookie($CONF['CookiePrefix'] . 'loginkey', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
294 $manager->notify('Logout', array('username' => cookieVar($CONF['CookiePrefix'] . 'user') ) );
\r
295 } elseif (cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
296 // Cookie Authentication
\r
297 $ck=cookieVar($CONF['CookiePrefix'] . 'loginkey');
\r
298 // secure cookie key
\r
299 $ck=substr($ck,0,32); // avoid md5 collision by using a long key
\r
300 if ($CONF['secureCookieKey']!=='none') $ck=md5($ck.$CONF['secureCookieKeyIP']);
\r
301 $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), $ck );
\r
304 // renew cookies when not on a shared computer
\r
305 if ($res && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) && (!headers_sent() ) ) {
\r
306 $member->setCookieKey(cookieVar($CONF['CookiePrefix'] . 'loginkey'));
\r
307 $member->setCookies();
\r
312 $manager->notify('PostAuthentication', array('loggedIn' => $member->isLoggedIn() ) );
\r
315 // first, let's see if the site is disabled or not. always allow admin area access.
\r
316 if ($CONF['DisableSite'] && !$member->isAdmin() && !$CONF['UsingAdminArea']) {
\r
317 redirect($CONF['DisableSiteURL']);
\r
321 // load other classes
\r
322 include($DIR_LIBS . 'PARSER.php');
\r
323 include($DIR_LIBS . 'SKIN.php');
\r
324 include($DIR_LIBS . 'TEMPLATE.php');
\r
325 include($DIR_LIBS . 'BLOG.php');
\r
326 include($DIR_LIBS . 'BODYACTIONS.php');
\r
327 include($DIR_LIBS . 'COMMENTS.php');
\r
328 include($DIR_LIBS . 'COMMENT.php');
\r
329 //include($DIR_LIBS . 'ITEM.php');
\r
330 include($DIR_LIBS . 'NOTIFICATION.php');
\r
331 include($DIR_LIBS . 'BAN.php');
\r
332 include($DIR_LIBS . 'PAGEFACTORY.php');
\r
333 include($DIR_LIBS . 'SEARCH.php');
\r
334 include($DIR_LIBS . 'entity.php');
\r
337 // set lastVisit cookie (if allowed)
\r
338 if (!headers_sent() ) {
\r
339 if ($CONF['LastVisit']) {
\r
340 setcookie($CONF['CookiePrefix'] . 'lastVisit', time(), time() + 2592000, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
342 setcookie($CONF['CookiePrefix'] . 'lastVisit', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
346 // read language file, only after user has been initialized
\r
347 $language = getLanguageName();
\r
348 //include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
\r
349 include($DIR_LANG . preg_replace( '@\\|/@', '', $language) . '.php');
\r
351 // check if valid charset
\r
352 if (!encoding_check(false, false, _CHARSET)) {
\r
353 foreach(array($_GET, $_POST) as $input) {
\r
354 array_walk($input, 'encoding_check');
\r
359 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
361 // To remove after v2.5 is released and language files have been updated.
\r
362 // Including this makes sure that language files for v2.5beta can still be used for v2.5final
\r
363 // without having weird _SETTINGS_EXTAUTH string showing up in the admin area.
\r
364 if (!defined('_MEMBERS_BYPASS'))
\r
366 define('_SETTINGS_EXTAUTH', 'Enable External Authentication');
\r
367 define('_WARNING_EXTAUTH', 'Warning: Enable only if needed.');
\r
368 define('_MEMBERS_BYPASS', 'Use External Authentication');
\r
373 // make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined
\r
374 if (!defined('_ARCHIVETYPE_MONTH') ) {
\r
375 define('_ARCHIVETYPE_DAY', 'day');
\r
376 define('_ARCHIVETYPE_MONTH', 'month');
\r
377 define('_ARCHIVETYPE_YEAR', 'year');
\r
380 // decode path_info
\r
381 if ($CONF['URLMode'] == 'pathinfo') {
\r
382 // initialize keywords if this hasn't been done before
\r
383 if (!isset($CONF['ItemKey']) || $CONF['ItemKey'] == '') {
\r
384 $CONF['ItemKey'] = 'item';
\r
387 if (!isset($CONF['ArchiveKey']) || $CONF['ArchiveKey'] == '') {
\r
388 $CONF['ArchiveKey'] = 'archive';
\r
391 if (!isset($CONF['ArchivesKey']) || $CONF['ArchivesKey'] == '') {
\r
392 $CONF['ArchivesKey'] = 'archives';
\r
395 if (!isset($CONF['MemberKey']) || $CONF['MemberKey'] == '') {
\r
396 $CONF['MemberKey'] = 'member';
\r
399 if (!isset($CONF['BlogKey']) || $CONF['BlogKey'] == '') {
\r
400 $CONF['BlogKey'] = 'blog';
\r
403 if (!isset($CONF['CategoryKey']) || $CONF['CategoryKey'] == '') {
\r
404 $CONF['CategoryKey'] = 'category';
\r
407 if (!isset($CONF['SpecialskinKey']) || $CONF['SpecialskinKey'] == '') {
\r
408 $CONF['SpecialskinKey'] = 'special';
\r
415 'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...
\r
416 'info' => $virtualpath,
\r
417 'complete' => &$parsed
\r
422 // default implementation
\r
423 $data = explode("/", $virtualpath );
\r
424 for ($i = 0; $i < sizeof($data); $i++) {
\r
425 switch ($data[$i]) {
\r
426 case $CONF['ItemKey']: // item/1 (blogid)
\r
429 if ($i < sizeof($data) ) {
\r
430 $itemid = intval($data[$i]);
\r
434 case $CONF['ArchivesKey']: // archives/1 (blogid)
\r
437 if ($i < sizeof($data) ) {
\r
438 $archivelist = intval($data[$i]);
\r
442 case $CONF['ArchiveKey']: // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)
\r
443 if ((($i + 1) < sizeof($data) ) && (!strstr($data[$i + 1], '-') ) ) {
\r
444 $blogid = intval($data[++$i]);
\r
449 if ($i < sizeof($data) ) {
\r
450 $archive = $data[$i];
\r
454 case 'blogid': // blogid/1
\r
455 case $CONF['BlogKey']: // blog/1
\r
458 if ($i < sizeof($data) ) {
\r
459 $blogid = intval($data[$i]);
\r
463 case $CONF['CategoryKey']: // category/1 (catid)
\r
467 if ($i < sizeof($data) ) {
\r
468 $catid = intval($data[$i]);
\r
472 case $CONF['MemberKey']:
\r
475 if ($i < sizeof($data) ) {
\r
476 $memberid = intval($data[$i]);
\r
480 case $CONF['SpecialskinKey']:
\r
483 if ($i < sizeof($data) ) {
\r
484 $_REQUEST['special'] = $data[$i];
\r
495 function intPostVar($name) {
\r
496 return intval(postVar($name) );
\r
499 function intGetVar($name) {
\r
500 return intval(getVar($name) );
\r
503 function intRequestVar($name) {
\r
504 return intval(requestVar($name) );
\r
507 function intCookieVar($name) {
\r
508 return intval(cookieVar($name) );
\r
512 * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)
\r
514 function getNucleusVersion() {
\r
519 * power users can install patches in between nucleus releases. These patches
\r
520 * usually add new functionality in the plugin API and allow those to
\r
521 * be tested without having to install CVS.
\r
523 function getNucleusPatchLevel() {
\r
528 * returns the latest version available for download from nucleuscms.org
\r
529 * or false if unable to attain data
\r
530 * format will be major.minor/patachlevel
\r
531 * e.g. 3.41 or 3.41/02
\r
533 function getLatestVersion() {
\r
534 if (!function_exists('curl_init')) return false;
\r
535 $crl = curl_init();
\r
537 curl_setopt ($crl, CURLOPT_URL,'http://nucleuscms.org/version_check.php');
\r
538 curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);
\r
539 curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);
\r
540 $ret = curl_exec($crl);
\r
547 * Connects to mysql server
\r
549 /* moved to $DIR_LIBS/sql/*.php handler files
\r
550 function sql_connect() {
\r
551 global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE, $MYSQL_CONN;
\r
553 $MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>', 'Connect Error');
\r
554 mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: ' . mysql_error() . '</p>', 'Connect Error');
\r
556 return $MYSQL_CONN;
\r
560 * returns a prefixed nucleus table name
\r
562 function sql_table($name) {
\r
563 global $MYSQL_PREFIX;
\r
565 if ($MYSQL_PREFIX) {
\r
566 return $MYSQL_PREFIX . 'nucleus_' . $name;
\r
568 return 'nucleus_' . $name;
\r
572 function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
\r
573 global $manager, $CONF;
\r
575 if (!headers_sent() ) {
\r
576 // if content type is application/xhtml+xml, only send it to browsers
\r
577 // that can handle it (IE6 cannot). Otherwise, send text/html
\r
579 // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)
\r
580 // application/xhtml+xml still causes too much problems with the javascript implementations
\r
582 // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,
\r
583 // application/xhtml+xml seems to be working, so we're going to use it if we can.
\r
585 // Note: reverted the following function in JP version
\r
590 ($contenttype == 'application/xhtml+xml')
\r
591 && (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )
\r
593 $contenttype = 'text/html';
\r
598 ($contenttype == 'application/xhtml+xml')
\r
599 && (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))
\r
602 $contenttype = 'text/html';
\r
606 'PreSendContentType',
\r
608 'contentType' => &$contenttype,
\r
609 'charset' => &$charset,
\r
610 'pageType' => $pagetype
\r
614 // strip strange characters
\r
615 $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);
\r
616 $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);
\r
618 if ($charset != '') {
\r
619 header('Content-Type: ' . $contenttype . '; charset=' . $charset);
\r
621 header('Content-Type: ' . $contenttype);
\r
624 // check if valid charset
\r
625 if (!encoding_check(false,false,$charset)) {
\r
626 foreach(array($_GET, $_POST) as $input) {
\r
627 array_walk($input, 'encoding_check');
\r
634 * Errors before the database connection has been made - moved to
\r
636 /* moved to $DIR_LIBS/sql/*.php handler files
\r
637 function startUpError($msg, $title) {
\r
638 if (!defined('_CHARSET')) define('_CHARSET', 'iso-8859-1');
\r
639 header('Content-Type: text/html; charset=' . _CHARSET);
\r
641 <html <?php echo _HTML_XML_NAME_SPACE_AND_LANG_CODE; ?>>
\r
642 <head><meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET?>" />
\r
643 <title><?php echo htmlspecialchars($title)?></title></head>
\r
645 <h1><?php echo htmlspecialchars($title)?></h1>
\r
653 * disconnects from SQL server
\r
655 /* moved to $DIR_LIBS/sql/*.php handler files
\r
656 function sql_disconnect() {
\r
661 * executes an SQL query
\r
663 /* moved to $DIR_LIBS/sql/*.php handler files
\r
664 function sql_query($query) {
\r
667 $res = mysql_query($query) or print("mySQL error with query $query: " . mysql_error() . '<p />');
\r
673 * Highlights a specific query in a given HTML text (not within HTML tags) and returns it
\r
676 * text to be highlighted
\r
677 * @param $expression
\r
678 * regular expression to be matched (can be an array of expressions as well)
\r
679 * @param $highlight
\r
680 * highlight to be used (use \\0 to indicate the matched expression)
\r
683 function highlight($text, $expression, $highlight) {
\r
684 if (!$highlight || !$expression) {
\r
688 if (is_array($expression) && (count($expression) == 0) ) {
\r
692 // add a tag in front (is needed for preg_match_all to work correct)
\r
693 $text = '<!--h-->' . $text;
\r
695 // split the HTML up so we have HTML tags
\r
696 // $matches[0][i] = HTML + text
\r
697 // $matches[1][i] = HTML
\r
698 // $matches[2][i] = text
\r
699 preg_match_all('/(<[^>]+>)([^<>]*)/', $text, $matches);
\r
701 // throw it all together again while applying the highlight to the text pieces
\r
703 for ($i = 0; $i < sizeof($matches[2]); $i++) {
\r
705 $result .= $matches[1][$i];
\r
708 if (is_array($expression) ) {
\r
709 foreach ($expression as $regex) {
\r
711 $matches[2][$i] = @eregi_replace($regex, $highlight, $matches[2][$i]);
\r
715 $result .= $matches[2][$i];
\r
717 $result .= @eregi_replace($expression, $highlight, $matches[2][$i]);
\r
725 * Parses a query into an array of expressions that can be passed on to the highlight method
\r
727 function parseHighlight($query) {
\r
728 // TODO: add more intelligent splitting logic
\r
730 // get rid of quotes
\r
731 $query = preg_replace('/\'|"/', '', $query);
\r
737 $aHighlight = explode(' ', $query);
\r
739 for ($i = 0; $i < count($aHighlight); $i++) {
\r
740 $aHighlight[$i] = trim($aHighlight[$i]);
\r
742 // if (strlen($aHighlight[$i]) < 3) {
\r
743 // unset($aHighlight[$i]);
\r
747 if (count($aHighlight) == 1) {
\r
748 return $aHighlight[0];
\r
750 return $aHighlight;
\r
755 * Checks if email address is valid
\r
757 function isValidMailAddress($address) {
\r
758 if (preg_match('/^[a-zA-Z+0-9\._-]+@[a-zA-Z0-9\._-]+\.[A-Za-z]{2,5}$/', $address)) {
\r
766 // some helper functions
\r
767 function getBlogIDFromName($name) {
\r
768 return quickQuery('SELECT bnumber as result FROM ' . sql_table('blog') . ' WHERE bshortname="' . addslashes($name) . '"');
\r
771 function getBlogNameFromID($id) {
\r
772 return quickQuery('SELECT bname as result FROM ' . sql_table('blog') . ' WHERE bnumber=' . intval($id) );
\r
775 function getBlogIDFromItemID($itemid) {
\r
776 return quickQuery('SELECT iblog as result FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid) );
\r
779 function getBlogIDFromCommentID($commentid) {
\r
780 return quickQuery('SELECT cblog as result FROM ' . sql_table('comment') . ' WHERE cnumber=' . intval($commentid) );
\r
783 function getBlogIDFromCatID($catid) {
\r
784 return quickQuery('SELECT cblog as result FROM ' . sql_table('category') . ' WHERE catid=' . intval($catid) );
\r
787 function getCatIDFromName($name) {
\r
788 return quickQuery('SELECT catid as result FROM ' . sql_table('category') . ' WHERE cname="' . addslashes($name) . '"');
\r
791 function quickQuery($q) {
\r
792 $res = sql_query($q);
\r
793 $obj = sql_fetch_object($res);
\r
794 return isset($obj->result) ? $obj->result : false;
\r
797 function getPluginNameFromPid($pid) {
\r
798 $res = sql_query('SELECT pfile FROM ' . sql_table('plugin') . ' WHERE pid=' . intval($pid) );
\r
799 $obj = sql_fetch_object($res);
\r
800 return isset($obj->pfile) ? $obj->pfile : false;
\r
803 function selector() {
\r
804 global $itemid, $blogid, $memberid, $query, $amount, $archivelist, $maxresults;
\r
805 global $archive, $skinid, $blog, $memberinfo, $CONF, $member;
\r
806 global $imagepopup, $catid, $special;
\r
809 $actionNames = array('addcomment', 'sendmessage', 'createaccount', 'forgotpassword', 'votepositive', 'votenegative', 'plugin');
\r
810 $action = requestVar('action');
\r
812 if (in_array($action, $actionNames) ) {
\r
813 global $DIR_LIBS, $errormessage;
\r
814 include_once($DIR_LIBS . 'ACTION.php');
\r
816 $errorInfo = $a->doAction($action);
\r
819 $errormessage = $errorInfo['message'];
\r
823 // show error when headers already sent out
\r
824 if (headers_sent() && $CONF['alertOnHeadersSent']) {
\r
826 // try to get line number/filename (extra headers_sent params only exists in PHP 4.3+)
\r
827 if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=') ) {
\r
828 headers_sent($hsFile, $hsLine);
\r
829 $extraInfo = sprintf(_GFUNCTIONS_HEADERSALREADYSENT_FILE,$hsFile,$hsLine);
\r
835 sprintf(_GFUNCTIONS_HEADERSALREADYSENT_TXT,$extraInfo),
\r
836 _GFUNCTIONS_HEADERSALREADYSENT_TITLE
\r
841 // make is so ?archivelist without blogname or blogid shows the archivelist
\r
842 // for the default weblog
\r
843 if (serverVar('QUERY_STRING') == 'archivelist') {
\r
844 $archivelist = $CONF['DefaultBlog'];
\r
847 // now decide which type of skin we need
\r
849 // itemid given -> only show that item
\r
852 if (!$manager->existsItem($itemid,0,0) ) {
\r
853 doError(_ERROR_NOSUCHITEM);
\r
856 global $itemidprev, $itemidnext, $catid, $itemtitlenext, $itemtitleprev;
\r
858 // 1. get timestamp, blogid and catid for item
\r
859 $query = 'SELECT itime, iblog, icat FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid);
\r
860 $res = sql_query($query);
\r
861 $obj = sql_fetch_object($res);
\r
863 // if a different blog id has been set through the request or selectBlog(),
\r
865 // if ($blogid && (intval($blogid) != $obj->iblog) ) {
\r
866 // doError(_ERROR_NOSUCHITEM);
\r
868 if ($blogid && (intval($blogid) != $obj->iblog) ) {
\r
869 if (!headers_sent()) {
\r
870 $b =& $manager->getBlog($obj->iblog);
\r
871 $CONF['ItemURL'] = $b->getURL();
\r
872 if ($CONF['URLMode'] == 'pathinfo' and substr($CONF['ItemURL'],-1) == '/')
\r
873 $CONF['ItemURL'] = substr($CONF['ItemURL'], 0, -1);
\r
874 $correctURL = createItemLink($itemid, '');
\r
875 redirect($correctURL);
\r
878 doError(_ERROR_NOSUCHITEM);
\r
882 // if a category has been selected which doesn't match the item, ignore the
\r
884 if (($catid != 0) && ($catid != $obj->icat) ) {
\r
888 $blogid = $obj->iblog;
\r
889 $timestamp = strtotime($obj->itime);
\r
891 $b =& $manager->getBlog($blogid);
\r
893 if ($b->isValidCategory($catid) ) {
\r
894 $catextra = ' and icat=' . $catid;
\r
899 // get previous itemid and title
\r
900 $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
901 $res = sql_query($query);
\r
903 $obj = sql_fetch_object($res);
\r
906 $itemidprev = $obj->inumber;
\r
907 $itemtitleprev = $obj->ititle;
\r
910 // get next itemid and title
\r
911 $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
912 $res = sql_query($query);
\r
914 $obj = sql_fetch_object($res);
\r
917 $itemidnext = $obj->inumber;
\r
918 $itemtitlenext = $obj->ititle;
\r
921 } elseif ($archive) {
\r
925 // get next and prev month links ...
\r
926 global $archivenext, $archiveprev, $archivetype, $archivenextexists, $archiveprevexists;
\r
928 // sql queries for the timestamp of the first and the last published item
\r
929 $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
930 $first_timestamp=quickQuery ($query);
\r
931 $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
932 $last_timestamp=quickQuery ($query);
\r
934 sscanf($archive, '%d-%d-%d', $y, $m, $d);
\r
937 $archivetype = _ARCHIVETYPE_DAY;
\r
938 $t = mktime(0, 0, 0, $m, $d, $y);
\r
939 // one day has 24 * 60 * 60 = 86400 seconds
\r
940 $archiveprev = strftime('%Y-%m-%d', $t - 86400 );
\r
941 // check for published items
\r
942 if ($t > $first_timestamp) {
\r
943 $archiveprevexists = true;
\r
946 $archiveprevexists = false;
\r
951 $archivenext = strftime('%Y-%m-%d', $t);
\r
952 if ($t < $last_timestamp) {
\r
953 $archivenextexists = true;
\r
956 $archivenextexists = false;
\r
959 } elseif ($m == 0) {
\r
960 $archivetype = _ARCHIVETYPE_YEAR;
\r
961 $t = mktime(0, 0, 0, 12, 31, $y - 1);
\r
962 // one day before is in the previous year
\r
963 $archiveprev = strftime('%Y', $t);
\r
964 if ($t > $first_timestamp) {
\r
965 $archiveprevexists = true;
\r
968 $archiveprevexists = false;
\r
971 // timestamp for the next year
\r
972 $t = mktime(0, 0, 0, 1, 1, $y + 1);
\r
973 $archivenext = strftime('%Y', $t);
\r
974 if ($t < $last_timestamp) {
\r
975 $archivenextexists = true;
\r
978 $archivenextexists = false;
\r
981 $archivetype = _ARCHIVETYPE_MONTH;
\r
982 $t = mktime(0, 0, 0, $m, 1, $y);
\r
983 // one day before is in the previous month
\r
984 $archiveprev = strftime('%Y-%m', $t - 86400);
\r
985 if ($t > $first_timestamp) {
\r
986 $archiveprevexists = true;
\r
989 $archiveprevexists = false;
\r
992 // timestamp for the next month
\r
993 $t = mktime(0, 0, 0, $m+1, 1, $y);
\r
994 $archivenext = strftime('%Y-%m', $t);
\r
995 if ($t < $last_timestamp) {
\r
996 $archivenextexists = true;
\r
999 $archivenextexists = false;
\r
1003 } elseif ($archivelist) {
\r
1004 $type = 'archivelist';
\r
1006 if (is_numeric($archivelist)) {
\r
1007 $blogid = intVal($archivelist);
\r
1009 $blogid = getBlogIDFromName($archivelist);
\r
1013 doError(_ERROR_NOSUCHBLOG);
\r
1016 } elseif ($query) {
\r
1019 $query = stripslashes($query);
\r
1020 if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/", $query)){
\r
1023 // $order = (_CHARSET == 'EUC-JP') ? 'EUC-JP, UTF-8,' : 'UTF-8, EUC-JP,';
\r
1024 // $query = mb_convert_encoding($query, _CHARSET, $order . ' JIS, SJIS, ASCII');
\r
1025 switch(strtolower(_CHARSET)){
\r
1027 $order = 'ASCII, UTF-8, EUC-JP, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1030 $order = 'ASCII, EUC-CN, EUC-JP, UTF-8, JIS, SJIS, ISO-8859-1';
\r
1033 // Note that shift_jis is only supported for output.
\r
1034 // Using shift_jis in DB is prohibited.
\r
1035 $order = 'ASCII, SJIS, EUC-JP, UTF-8, JIS, EUC-CN, ISO-8859-1';
\r
1038 // euc-jp,iso-8859-x,windows-125x
\r
1039 $order = 'ASCII, EUC-JP, UTF-8, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1042 $query = mb_convert_encoding($query, _CHARSET, $order);
\r
1043 if (is_numeric($blogid)) {
\r
1044 $blogid = intVal($blogid);
\r
1046 $blogid = getBlogIDFromName($blogid);
\r
1050 doError(_ERROR_NOSUCHBLOG);
\r
1053 } elseif ($memberid) {
\r
1056 if (!MEMBER::existsID($memberid) ) {
\r
1057 doError(_ERROR_NOSUCHMEMBER);
\r
1060 $memberinfo = $manager->getMember($memberid);
\r
1062 } elseif ($imagepopup) {
\r
1063 // media object (images etc.)
\r
1064 $type = 'imagepopup';
\r
1066 // TODO: check if media-object exists
\r
1067 // TODO: set some vars?
\r
1069 // show regular index page
\r
1074 // any type of skin with catid
\r
1075 if ($catid && !$blogid) {
\r
1076 $blogid = getBlogIDFromCatID($catid);
\r
1079 // decide which blog should be displayed
\r
1081 $blogid = $CONF['DefaultBlog'];
\r
1084 $b =& $manager->getBlog($blogid);
\r
1085 $blog = $b; // references can't be placed in global variables?
\r
1087 if (!$blog->isValid) {
\r
1088 doError(_ERROR_NOSUCHBLOG);
\r
1091 // set catid if necessary
\r
1093 // check if the category is valid
\r
1094 if (!$blog->isValidCategory($catid)) {
\r
1095 doError(_ERROR_NOSUCHCATEGORY);
\r
1097 $blog->setSelectedCategory($catid);
\r
1101 // decide which skin should be used
\r
1102 if ($skinid != '' && ($skinid == 0) ) {
\r
1103 selectSkin($skinid);
\r
1107 $skinid = $blog->getDefaultSkin();
\r
1110 //$special = requestVar('special'); //get at top of file as global
\r
1111 if (!empty($special) && isValidShortName($special)) {
\r
1112 $type = strtolower($special);
\r
1115 $skin = new SKIN($skinid);
\r
1117 if (!$skin->isValid) {
\r
1118 doError(_ERROR_NOSUCHSKIN);
\r
1122 $skin->parse($type);
\r
1124 // check to see we should throw JustPosted event
\r
1125 $blog->checkJustPosted();
\r
1129 * Show error skin with given message. An optional skin-object to use can be given
\r
1131 function doError($msg, $skin = '') {
\r
1132 global $errormessage, $CONF, $skinid, $blogid, $manager;
\r
1134 if ($skin == '') {
\r
1136 if (SKIN::existsID($skinid) ) {
\r
1137 $skin = new SKIN($skinid);
\r
1138 } elseif ($manager->existsBlogID($blogid) ) {
\r
1139 $blog =& $manager->getBlog($blogid);
\r
1140 $skin = new SKIN($blog->getDefaultSkin() );
\r
1141 } elseif ($CONF['DefaultBlog']) {
\r
1142 $blog =& $manager->getBlog($CONF['DefaultBlog']);
\r
1143 $skin = new SKIN($blog->getDefaultSkin() );
\r
1145 // this statement should actually never be executed
\r
1146 $skin = new SKIN($CONF['BaseSkin']);
\r
1151 $skinid = $skin->id;
\r
1152 $errormessage = $msg;
\r
1153 $skin->parse('error');
\r
1157 function getConfig() {
\r
1160 $query = 'SELECT * FROM ' . sql_table('config');
\r
1161 $res = sql_query($query);
\r
1163 while ($obj = sql_fetch_object($res) ) {
\r
1164 $CONF[$obj->name] = $obj->value;
\r
1168 // some checks for names of blogs, categories, templates, members, ...
\r
1169 function isValidShortName($name) {
\r
1170 return eregi('^[a-z0-9]+$', $name);
\r
1173 function isValidDisplayName($name) {
\r
1174 return eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name);
\r
1177 function isValidCategoryName($name) {
\r
1181 function isValidTemplateName($name) {
\r
1182 return eregi('^[a-z0-9/]+$', $name);
\r
1185 function isValidSkinName($name) {
\r
1186 return eregi('^[a-z0-9/]+$', $name);
\r
1189 // add and remove linebreaks
\r
1190 function addBreaks($var) {
\r
1191 return nl2br($var);
\r
1194 function removeBreaks($var) {
\r
1195 return preg_replace("/<br \/>([\r\n])/", "$1", $var);
\r
1198 // shortens a text string to maxlength ($toadd) is what needs to be added
\r
1199 // at the end (end length is <= $maxlength)
\r
1200 function shorten($text, $maxlength, $toadd) {
\r
1201 // 1. remove entities...
\r
1202 // $trans = get_html_translation_table(HTML_ENTITIES);
\r
1203 $trans = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
1204 $trans = array_flip($trans);
\r
1205 $text = strtr($text, $trans);
\r
1207 // 2. the actual shortening
\r
1208 if (strlen($text) > $maxlength) {
\r
1209 // $text = substr($text, 0, $maxlength - strlen($toadd) ) . $toadd;
\r
1210 $text = mb_strimwidth($text, 0, $maxlength, $toadd, _CHARSET); // for Japanese
\r
1217 * Converts a unix timestamp to a mysql DATETIME format, and places
\r
1218 * quotes around it.
\r
1220 function mysqldate($timestamp) {
\r
1221 return '"' . date('Y-m-d H:i:s', $timestamp) . '"';
\r
1225 * functions for use in index.php
\r
1227 function selectBlog($shortname) {
\r
1228 global $blogid, $archivelist;
\r
1229 $blogid = getBlogIDFromName($shortname);
\r
1231 // also force archivelist variable, if it is set
\r
1232 if ($archivelist) {
\r
1233 $archivelist = $blogid;
\r
1237 function selectSkin($skinname) {
\r
1239 $skinid = SKIN::getIdFromName($skinname);
\r
1243 * Can take either a category ID or a category name (be aware that
\r
1244 * multiple categories can have the same name)
\r
1246 function selectCategory($cat) {
\r
1248 if (is_numeric($cat) ) {
\r
1249 $catid = intval($cat);
\r
1251 $catid = getCatIDFromName($cat);
\r
1255 function selectItem($id) {
\r
1257 $itemid = intval($id);
\r
1260 // force the use of a language file (warning: can cause warnings)
\r
1261 function selectLanguage($language) {
\r
1263 // include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
\r
1264 include($DIR_LANG . preg_replace( '@\\|/@', '', $language) . '.php');
\r
1267 function parseFile($filename, $includeMode = 'normal', $includePrefix = '') {
\r
1268 $handler = new ACTIONS('fileparser');
\r
1269 $parser = new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);
\r
1270 $handler->parser =& $parser;
\r
1272 // set IncludeMode properties of parser
\r
1273 PARSER::setProperty('IncludeMode', $includeMode);
\r
1274 PARSER::setProperty('IncludePrefix', $includePrefix);
\r
1276 if (!file_exists($filename) ) {
\r
1277 doError(_GFUNCTIONS_PARSEFILE_FILEMISSING);
\r
1280 $fsize = filesize($filename);
\r
1282 if ($fsize <= 0) {
\r
1287 $fd = fopen ($filename, 'r');
\r
1288 $contents = fread ($fd, $fsize);
\r
1291 // parse file contents
\r
1292 $parser->parse($contents);
\r
1296 * Outputs a debug message
\r
1298 function debug($msg) {
\r
1299 echo '<p><b>' . $msg . "</b></p>\n";
\r
1303 function addToLog($level, $msg) {
\r
1304 ACTIONLOG::add($level, $msg);
\r
1307 // shows a link to help file
\r
1308 function help($id) {
\r
1309 echo helpHtml($id);
\r
1312 function helpHtml($id) {
\r
1314 return helplink($id) . '<img src="' . $CONF['AdminURL'] . 'documentation/icon-help.gif" width="15" height="15" alt="' . _HELP_TT . '" title="' . _HELP_TT . '" /></a>';
\r
1317 function helplink($id) {
\r
1319 return '<a href="' . $CONF['AdminURL'] . 'documentation/help.html#'. $id . '" onclick="if (event && event.preventDefault) event.preventDefault(); return help(this.href);">';
\r
1322 function getMailFooter() {
\r
1323 $message = "\n\n-----------------------------";
\r
1324 $message .= "\n Powered by Nucleus CMS";
\r
1325 $message .= "\n(http://www.nucleuscms.org/)";
\r
1330 * Returns the name of the language to use
\r
1331 * preference priority: member - site
\r
1332 * defaults to english when no good language found
\r
1334 * checks if file exists, etc...
\r
1336 function getLanguageName() {
\r
1337 global $CONF, $member;
\r
1339 if ($member && $member->isLoggedIn() ) {
\r
1340 // try to use members language
\r
1341 $memlang = $member->getLanguage();
\r
1343 if (($memlang != '') && (checkLanguage($memlang) ) ) {
\r
1348 // use default language
\r
1349 if (checkLanguage($CONF['Language']) ) {
\r
1350 return $CONF['Language'];
\r
1357 * Includes a PHP file. This method can be called while parsing templates and skins
\r
1359 function includephp($filename) {
\r
1360 // make predefined variables global, so most simple scripts can be used here
\r
1362 // apache (names taken from PHP doc)
\r
1363 global $GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE, $SERVER_PROTOCOL;
\r
1364 global $REQUEST_METHOD, $QUERY_STRING, $DOCUMENT_ROOT, $HTTP_ACCEPT;
\r
1365 global $HTTP_ACCEPT_CHARSET, $HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE;
\r
1366 global $HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER, $HTTP_USER_AGENT;
\r
1367 global $REMOTE_ADDR, $REMOTE_PORT, $SCRIPT_FILENAME, $SERVER_ADMIN;
\r
1368 global $SERVER_PORT, $SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME;
\r
1369 global $REQUEST_URI;
\r
1371 // php (taken from PHP doc)
\r
1372 global $argv, $argc, $PHP_SELF, $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS;
\r
1373 global $HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS, $HTTP_SESSION_VARS;
\r
1376 global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;
\r
1378 if (@file_exists($filename) ) {
\r
1379 include($filename);
\r
1384 * Checks if a certain language/plugin exists
\r
1386 function checkLanguage($lang) {
\r
1387 global $DIR_LANG ;
\r
1388 // return file_exists($DIR_LANG . ereg_replace( '[\\|/]', '', $lang) . '.php');
\r
1389 return file_exists($DIR_LANG . preg_replace( '@\\|/@', '', $lang) . '.php');
\r
1392 function checkPlugin($plug) {
\r
1393 global $DIR_PLUGINS;
\r
1394 return file_exists($DIR_PLUGINS . ereg_replace( '[\\|/]', '', $plug) . '.php');
\r
1395 // return file_exists($DIR_PLUGINS . preg_replace( '@\\|/@', '', $plug) . '.php');
\r
1399 * Centralisation of the functions that generate links
\r
1401 function createItemLink($itemid, $extra = '') {
\r
1402 return createLink('item', array('itemid' => $itemid, 'extra' => $extra) );
\r
1405 function createMemberLink($memberid, $extra = '') {
\r
1406 return createLink('member', array('memberid' => $memberid, 'extra' => $extra) );
\r
1409 function createCategoryLink($catid, $extra = '') {
\r
1410 return createLink('category', array('catid' => $catid, 'extra' => $extra) );
\r
1413 function createArchiveListLink($blogid = '', $extra = '') {
\r
1414 return createLink('archivelist', array('blogid' => $blogid, 'extra' => $extra) );
\r
1417 function createArchiveLink($blogid, $archive, $extra = '') {
\r
1418 return createLink('archive', array('blogid' => $blogid, 'archive' => $archive, 'extra' => $extra) );
\r
1421 function createBlogidLink($blogid, $params = '') {
\r
1422 return createLink('blog', array('blogid' => $blogid, 'extra' => $params) );
\r
1425 function createLink($type, $params) {
\r
1426 global $manager, $CONF;
\r
1428 $generatedURL = '';
\r
1429 $usePathInfo = ($CONF['URLMode'] == 'pathinfo');
\r
1431 // ask plugins first
\r
1434 if ($usePathInfo) {
\r
1439 'params' => $params,
\r
1440 'completed' => &$created,
\r
1446 // if a plugin created the URL, return it
\r
1451 // default implementation
\r
1454 if ($usePathInfo) {
\r
1455 $url = $CONF['ItemURL'] . '/' . $CONF['ItemKey'] . '/' . $params['itemid'];
\r
1457 $url = $CONF['ItemURL'] . '?itemid=' . $params['itemid'];
\r
1462 if ($usePathInfo) {
\r
1463 $url = $CONF['MemberURL'] . '/' . $CONF['MemberKey'] . '/' . $params['memberid'];
\r
1465 $url = $CONF['MemberURL'] . '?memberid=' . $params['memberid'];
\r
1470 if ($usePathInfo) {
\r
1471 $url = $CONF['CategoryURL'] . '/' . $CONF['CategoryKey'] . '/' . $params['catid'];
\r
1473 $url = $CONF['CategoryURL'] . '?catid=' . $params['catid'];
\r
1477 case 'archivelist':
\r
1478 if (!$params['blogid']) {
\r
1479 $params['blogid'] = $CONF['DefaultBlog'];
\r
1482 if ($usePathInfo) {
\r
1483 $url = $CONF['ArchiveListURL'] . '/' . $CONF['ArchivesKey'] . '/' . $params['blogid'];
\r
1485 $url = $CONF['ArchiveListURL'] . '?archivelist=' . $params['blogid'];
\r
1490 if ($usePathInfo) {
\r
1491 $url = $CONF['ArchiveURL'] . '/' . $CONF['ArchiveKey'] . '/'.$params['blogid'].'/' . $params['archive'];
\r
1493 $url = $CONF['ArchiveURL'] . '?blogid='.$params['blogid'].'&archive=' . $params['archive'];
\r
1498 if ($usePathInfo) {
\r
1499 $url = $CONF['BlogURL'] . '/' . $CONF['BlogKey'] . '/' . $params['blogid'];
\r
1501 $url = $CONF['BlogURL'] . '?blogid=' . $params['blogid'];
\r
1506 return addLinkParams($url, (isset($params['extra'])? $params['extra'] : null));
\r
1509 function createBlogLink($url, $params) {
\r
1511 if ($CONF['URLMode'] == 'normal') {
\r
1512 if (strpos($url, '?') === FALSE && is_array($params)) {
\r
1513 $fParam = reset($params);
\r
1514 $fKey = key($params);
\r
1515 array_shift($params);
\r
1516 $url .= '?' . $fKey . '=' . $fParam;
\r
1518 } elseif ($CONF['URLMode'] == 'pathinfo' && substr($url, -1) == '/') {
\r
1519 $url = substr($url, 0, -1);
\r
1521 return addLinkParams($url, $params);
\r
1524 function addLinkParams($link, $params) {
\r
1527 if (is_array($params) ) {
\r
1529 if ($CONF['URLMode'] == 'pathinfo') {
\r
1531 foreach ($params as $param => $value) {
\r
1532 $link .= '/' . $param . '/' . urlencode($value);
\r
1537 foreach ($params as $param => $value) {
\r
1538 $link .= '&' . $param . '=' . urlencode($value);
\r
1548 * @param $querystr
\r
1549 * querystring to alter (e.g. foo=1&bar=2&x=y)
\r
1551 * name of parameter to change (e.g. 'foo')
\r
1553 * New value for that parameter (e.g. 3)
\r
1555 * altered query string (for the examples above: foo=3&bar=2&x=y)
\r
1557 function alterQueryStr($querystr, $param, $value) {
\r
1558 $vars = explode('&', $querystr);
\r
1561 for ($i = 0; $i < count($vars); $i++) {
\r
1562 $v = explode('=', $vars[$i]);
\r
1564 if ($v[0] == $param) {
\r
1566 $vars[$i] = implode('=', $v);
\r
1573 $vars[] = $param . '=' . $value;
\r
1576 return ltrim(implode('&', $vars), '&');
\r
1579 // passes one variable as hidden input field (multiple fields for arrays)
\r
1580 // @see passRequestVars in varsx.x.x.php
\r
1581 function passVar($key, $value) {
\r
1583 if (is_array($value) ) {
\r
1584 for ($i = 0; $i < sizeof($value); $i++) {
\r
1585 passVar($key . '[' . $i . ']', $value[$i]);
\r
1591 // other values: do stripslashes if needed
\r
1592 ?><input type="hidden" name="<?php echo htmlspecialchars($key)?>" value="<?php echo htmlspecialchars(undoMagic($value) )?>" /><?php
\r
1596 Date format functions (to be used from [%date(..)%] skinvars
\r
1598 function formatDate($format, $timestamp, $defaultFormat, &$blog) {
\r
1599 // apply blog offset (#42)
\r
1600 $boffset = $blog ? $blog->getTimeOffset() * 3600 : 0;
\r
1601 $offset = date('Z', $timestamp) + $boffset;
\r
1603 switch ($format) {
\r
1605 if ($offset >= 0) {
\r
1609 $offset = -$offset;
\r
1612 $tz .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1613 return date('D, j M Y H:i:s ', $timestamp) . $tz;
\r
1616 $timestamp -= $offset;
\r
1617 return date('D, j M Y H:i:s ', $timestamp) . 'GMT';
\r
1620 $timestamp -= $offset;
\r
1621 return date('Y-m-d\TH:i:s\Z', $timestamp);
\r
1624 if ($offset >= 0) {
\r
1628 $offset = -$offset;
\r
1631 $tz .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1632 return date('Y-m-d\TH:i:s', $timestamp) . $tz;
\r
1635 return strftime($format ? $format : $defaultFormat, $timestamp);
\r
1639 function encoding_check($val, $key, $encoding=false, $exclude=false) {
\r
1641 When 3rd argument is set, return if checked already.
\r
1642 When 4th argument is set, set the excluded key(s).
\r
1644 static $search=false, $checked=array(), $excludes=array();
\r
1645 if ($exclude!==false) {
\r
1646 if (is_array($exclude)) {
\r
1647 foreach($exclude as $v) $excludes[$v]=true;
\r
1648 } else $excludes[$exclude]=true;
\r
1651 if ($encoding!==false) {
\r
1652 switch($encoding=strtolower($encoding)){
\r
1654 $search='/([\x00-\x7F]+'.
\r
1655 '|[\xC2-\xDF][\x80-\xBF]'.
\r
1656 '|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]'.
\r
1657 '|[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1658 '|[\xF8-\xFB][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1659 '|[\xFC-\xFD][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF])/';
\r
1662 $search='/([\x00-\x7F]+'.
\r
1663 '|[\x8E][\xA0-\xDF]'.
\r
1664 '|[\x8F]?[\xA1-\xFE][\xA1-\xFE])/';
\r
1667 $search='/([\x00-\x7F]+'.
\r
1668 '|[\xA1-\xF7][\xA1-\xFE])/';
\r
1671 // Note that shift_jis is only supported for output.
\r
1672 // Using shift_jis in DB is prohibited.
\r
1673 $search='/([\x00-\x7F\xA1-\xDF]+'.
\r
1674 '|[\x81-\x9F\xE0-\xFC][\x40-\xFC])/';
\r
1678 if (preg_match('/^iso\-8859\-[0-9]{1,2}$/',$encoding)) break;
\r
1679 if (preg_match('/^windows\-125[0-8]$/',$encoding)) break;
\r
1680 startUpError('<p>Unknown or non-supported encoding.</p>', 'Encoding Error');
\r
1683 if (isset($checked[$encoding])) return true; // Already checked.
\r
1684 $checked[$encoding]=true;
\r
1686 if ($key===false) return false; // Not yet checked.
\r
1687 if ($search===false) return true; // non-multibyte encoding
\r
1688 if (isset($excludes[$key])) return true; // This key isn't checked.
\r
1689 if (is_array($val)) {
\r
1690 array_walk($val, 'encoding_check');
\r
1692 $result=preg_replace($search,'',$val);
\r
1693 if (strlen($result)!=0) {
\r
1694 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1698 $result=preg_replace($search,'',$key);
\r
1699 if (strlen($result)!=0) {
\r
1700 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1706 function checkVars($aVars) {
\r
1707 global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;
\r
1709 foreach ($aVars as $varName) {
\r
1711 if (phpversion() >= '4.1.0') {
\r
1713 if ( isset($_GET[$varName])
\r
1714 || isset($_POST[$varName])
\r
1715 || isset($_COOKIE[$varName])
\r
1716 || isset($_ENV[$varName])
\r
1717 || isset($_SESSION[$varName])
\r
1718 || isset($_FILES[$varName])
\r
1720 die('Sorry. An error occurred.');
\r
1725 if ( isset($HTTP_GET_VARS[$varName])
\r
1726 || isset($HTTP_POST_VARS[$varName])
\r
1727 || isset($HTTP_COOKIE_VARS[$varName])
\r
1728 || isset($HTTP_ENV_VARS[$varName])
\r
1729 || isset($HTTP_SESSION_VARS[$varName])
\r
1730 || isset($HTTP_POST_FILES[$varName])
\r
1732 die('Sorry. An error occurred.');
\r
1741 * Sanitize parameters such as $_GET and $_SERVER['REQUEST_URI'] etc.
\r
1744 function sanitizeParams()
\r
1746 global $HTTP_SERVER_VARS;
\r
1752 // REQUEST_URI of $HTTP_SERVER_VARS
\r
1753 $str =& $HTTP_SERVER_VARS["REQUEST_URI"];
\r
1754 serverStringToArray($str, $array, $frontParam);
\r
1755 sanitizeArray($array);
\r
1756 arrayToServerString($array, $frontParam, $str);
\r
1758 // QUERY_STRING of $HTTP_SERVER_VARS
\r
1759 $str =& $HTTP_SERVER_VARS["QUERY_STRING"];
\r
1760 serverStringToArray($str, $array, $frontParam);
\r
1761 sanitizeArray($array);
\r
1762 arrayToServerString($array, $frontParam, $str);
\r
1764 if (phpversion() >= '4.1.0') {
\r
1765 // REQUEST_URI of $_SERVER
\r
1766 $str =& $_SERVER["REQUEST_URI"];
\r
1767 serverStringToArray($str, $array, $frontParam);
\r
1768 sanitizeArray($array);
\r
1769 arrayToServerString($array, $frontParam, $str);
\r
1771 // QUERY_STRING of $_SERVER
\r
1772 $str =& $_SERVER["QUERY_STRING"];
\r
1773 serverStringToArray($str, $array, $frontParam);
\r
1774 sanitizeArray($array);
\r
1775 arrayToServerString($array, $frontParam, $str);
\r
1779 convArrayForSanitizing($_GET, $array);
\r
1780 sanitizeArray($array);
\r
1781 revertArrayForSanitizing($array, $_GET);
\r
1783 // $_REQUEST (only GET param)
\r
1784 convArrayForSanitizing($_REQUEST, $array);
\r
1785 sanitizeArray($array);
\r
1786 revertArrayForSanitizing($array, $_REQUEST);
\r
1790 * Check ticket when not checked in plugin's admin page
\r
1792 * Also avoid the access to plugin/index.php by guest user.
\r
1794 function ticketForPlugin(){
\r
1795 global $CONF,$DIR_PLUGINS,$member,$ticketforplugin;
\r
1798 $ticketforplugin=array();
\r
1799 $ticketforplugin['ticket']=false;
\r
1801 /* Check if using plugin's php file. */
\r
1802 if ($p_translated=serverVar('PATH_TRANSLATED')) {
\r
1803 if (!file_exists($p_translated)) $p_translated='';
\r
1805 if (!$p_translated) {
\r
1806 $p_translated=serverVar('SCRIPT_FILENAME');
\r
1807 if (!file_exists($p_translated)) {
\r
1808 header("HTTP/1.0 404 Not Found");
\r
1812 $p_translated=str_replace('\\','/',$p_translated);
\r
1813 $d_plugins=str_replace('\\','/',$DIR_PLUGINS);
\r
1814 if (strpos($p_translated,$d_plugins)!==0) return;// This isn't plugin php file.
\r
1816 /* Solve the plugin php file or admin directory */
\r
1817 $phppath=substr($p_translated,strlen($d_plugins));
\r
1818 $phppath=preg_replace('!^/!','',$phppath);// Remove the first "/" if exists.
\r
1819 $path=preg_replace('/^NP_(.*)\.php$/','$1',$phppath); // Remove the first "NP_" and the last ".php" if exists.
\r
1820 $path=preg_replace('!^([^/]*)/(.*)$!','$1',$path); // Remove the "/" and beyond.
\r
1822 /* Solve the plugin name. */
\r
1824 $query='SELECT pfile FROM '.sql_table('plugin');
\r
1825 $res=sql_query($query);
\r
1826 while($row=sql_fetch_row($res)) {
\r
1827 $name=substr($row[0],3);
\r
1828 $plugins[strtolower($name)]=$name;
\r
1830 sql_free_result($res);
\r
1831 if ($plugins[$path]) $plugin_name=$plugins[$path];
\r
1832 else if (in_array($path,$plugins)) $plugin_name=$path;
\r
1834 header("HTTP/1.0 404 Not Found");
\r
1838 /* Return if not index.php */
\r
1839 if ( $phppath!=strtolower($plugin_name).'/'
\r
1840 && $phppath!=strtolower($plugin_name).'/index.php' ) return;
\r
1842 /* Exit if not logged in. */
\r
1843 if ( !$member->isLoggedIn() ) exit(_GFUNCTIONS_YOU_AERNT_LOGGEDIN);
\r
1845 global $manager,$DIR_LIBS,$DIR_LANG,$HTTP_GET_VARS,$HTTP_POST_VARS;
\r
1847 /* Check if this feature is needed (ie, if "$manager->checkTicket()" is not included in the script). */
\r
1848 if (!($p_translated=serverVar('PATH_TRANSLATED'))) $p_translated=serverVar('SCRIPT_FILENAME');
\r
1849 if ($file=@file($p_translated)) {
\r
1851 foreach($file as $line) {
\r
1852 if (preg_match('/[\$]manager([\s]*)[\-]>([\s]*)checkTicket([\s]*)[\(]/i',$prevline.$line)) return;
\r
1857 /* Show a form if not valid ticket */
\r
1858 if ( ( strstr(serverVar('REQUEST_URI'),'?') || serverVar('QUERY_STRING')
\r
1859 || strtoupper(serverVar('REQUEST_METHOD'))=='POST' )
\r
1860 && (!$manager->checkTicket()) ){
\r
1862 if (!class_exists('PluginAdmin')) {
\r
1863 $language = getLanguageName();
\r
1864 // include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
\r
1865 include($DIR_LANG . preg_replace( '@\\|/@', '', $language) . '.php');
\r
1866 include($DIR_LIBS . 'PLUGINADMIN.php');
\r
1868 if (!(function_exists('mb_strimwidth') || extension_loaded('mbstring'))) {
\r
1869 if (file_exists($DIR_LIBS.'mb_emulator/mb-emulator.php')) {
\r
1870 global $mbemu_internals;
\r
1871 include_once($DIR_LIBS.'mb_emulator/mb-emulator.php');
\r
1874 $oPluginAdmin = new PluginAdmin($plugin_name);
\r
1875 $oPluginAdmin->start();
\r
1876 echo '<p>' . _ERROR_BADTICKET . "</p>\n";
\r
1878 /* Show the form to confirm action */
\r
1879 // PHP 4.0.x support
\r
1880 $get= (isset($_GET)) ? $_GET : $HTTP_GET_VARS;
\r
1881 $post= (isset($_POST)) ? $_POST : $HTTP_POST_VARS;
\r
1882 // Resolve URI and QUERY_STRING
\r
1883 if ($uri=serverVar('REQUEST_URI')) {
\r
1884 list($uri,$qstring)=explode('?',$uri);
\r
1886 if ( !($uri=serverVar('PHP_SELF')) ) $uri=serverVar('SCRIPT_NAME');
\r
1887 $qstring=serverVar('QUERY_STRING');
\r
1889 if ($qstring) $qstring='?'.$qstring;
\r
1890 echo '<p>'._SETTINGS_UPDATE.' : '._QMENU_PLUGINS.' <span style="color:red;">'.
\r
1891 htmlspecialchars($plugin_name)."</span> ?</p>\n";
\r
1892 switch(strtoupper(serverVar('REQUEST_METHOD'))){
\r
1894 echo '<form method="POST" action="'.htmlspecialchars($uri.$qstring).'">';
\r
1895 $manager->addTicketHidden();
\r
1896 _addInputTags($post);
\r
1899 echo '<form method="GET" action="'.htmlspecialchars($uri).'">';
\r
1900 $manager->addTicketHidden();
\r
1901 _addInputTags($get);
\r
1905 echo '<input type="submit" value="'._YES.'" /> ';
\r
1906 echo '<input type="button" value="'._NO.'" onclick="history.back(); return false;" />';
\r
1909 $oPluginAdmin->end();
\r
1913 /* Create new ticket */
\r
1914 $ticket=$manager->addTicketToUrl('');
\r
1915 $ticketforplugin['ticket']=substr($ticket,strpos($ticket,'ticket=')+7);
\r
1917 function _addInputTags(&$keys,$prefix=''){
\r
1918 foreach($keys as $key=>$value){
\r
1919 if ($prefix) $key=$prefix.'['.$key.']';
\r
1920 if (is_array($value)) _addInputTags($value,$key);
\r
1922 if (get_magic_quotes_gpc()) $value=stripslashes($value);
\r
1923 if ($key=='ticket') continue;
\r
1924 echo '<input type="hidden" name="'.htmlspecialchars($key).
\r
1925 '" value="'.htmlspecialchars($value).'" />'."\n";
\r
1931 * Convert the server string such as $_SERVER['REQUEST_URI']
\r
1932 * to arry like arry['blogid']=1 and array['page']=2 etc.
\r
1934 function serverStringToArray($str, &$array, &$frontParam)
\r
1940 // split front param, e.g. /index.php, and others, e.g. blogid=1&page=2
\r
1941 if (strstr($str, "?")){
\r
1942 list($frontParam, $args) = preg_split("/\?/", $str, 2);
\r
1949 // If there is no args like blogid=1&page=2, return
\r
1950 if (!strstr($str, "=") && !strlen($frontParam)) {
\r
1951 $frontParam = $str;
\r
1955 $array = explode("&", $args);
\r
1959 * Convert array like array['blogid'] to server string
\r
1960 * such as $_SERVER['REQUEST_URI']
\r
1962 function arrayToServerString($array, $frontParam, &$str)
\r
1964 if (strstr($str, "?")) {
\r
1965 $str = $frontParam . "?";
\r
1967 $str = $frontParam;
\r
1969 if (count($array)) {
\r
1970 $str .= implode("&", $array);
\r
1975 * Sanitize array parameters.
\r
1976 * This function checks both key and value.
\r
1977 * - check key if it inclues " (double quote), remove from array
\r
1978 * - check value if it includes \ (escape sequece), remove remaining string
\r
1980 function sanitizeArray(&$array)
\r
1982 $excludeListForSanitization = array('query');
\r
1983 // $excludeListForSanitization = array();
\r
1985 foreach ($array as $k => $v) {
\r
1987 // split to key and value
\r
1988 list($key, $val) = preg_split("/=/", $v, 2);
\r
1989 if (!isset($val)) {
\r
1993 // when magic quotes is on, need to use stripslashes,
\r
1994 // and then addslashes
\r
1995 if (get_magic_quotes_gpc()) {
\r
1996 $val = stripslashes($val);
\r
1998 $val = addslashes($val);
\r
2000 // if $key is included in exclude list, skip this param
\r
2001 if (!in_array($key, $excludeListForSanitization)) {
\r
2004 if (strpos($val, '\\')) {
\r
2005 list($val, $tmp) = explode('\\', $val);
\r
2008 // remove control code etc.
\r
2009 $val = strtr($val, "\0\r\n<>'\"", " ");
\r
2012 if (preg_match('/\"/i', $key)) {
\r
2013 unset($array[$k]);
\r
2017 // set sanitized info
\r
2018 $array[$k] = sprintf("%s=%s", $key, $val);
\r
2024 * Convert array for sanitizeArray function
\r
2026 function convArrayForSanitizing($src, &$array)
\r
2029 foreach ($src as $key => $val) {
\r
2030 if (key_exists($key, $_GET)) {
\r
2031 array_push($array, sprintf("%s=%s", $key, $val));
\r
2037 * Revert array after sanitizeArray function
\r
2039 function revertArrayForSanitizing($array, &$dst)
\r
2041 foreach ($array as $v) {
\r
2042 list($key, $val) = preg_split("/=/", $v, 2);
\r
2043 $dst[$key] = $val;
\r
2048 * Stops processing the request and redirects to the given URL.
\r
2049 * - no actual contents should have been sent to the output yet
\r
2050 * - the URL will be stripped of illegal or dangerous characters
\r
2052 function redirect($url) {
\r
2053 $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%*]|i', '', $url);
\r
2054 header('Location: ' . $url);
\r
2059 * Strip HTML tags from a string
\r
2060 * This function is a bit more intelligent than a regular call to strip_tags(),
\r
2061 * because it also deletes the contents of certain tags and cleans up any
\r
2062 * unneeded whitespace.
\r
2064 function stringStripTags ($string) {
\r
2065 $string = preg_replace("/<del[^>]*>.+<\/del[^>]*>/isU", '', $string);
\r
2066 $string = preg_replace("/<script[^>]*>.+<\/script[^>]*>/isU", '', $string);
\r
2067 $string = preg_replace("/<style[^>]*>.+<\/style[^>]*>/isU", '', $string);
\r
2068 $string = str_replace('>', '> ', $string);
\r
2069 $string = str_replace('<', ' <', $string);
\r
2070 $string = strip_tags($string);
\r
2071 $string = preg_replace("/\s+/", " ", $string);
\r
2072 $string = trim($string);
\r
2077 * Make a string containing HTML safe for use in a HTML attribute
\r
2078 * Tags are stripped and entities are normalized
\r
2080 function stringToAttribute ($string) {
\r
2081 $string = stringStripTags($string);
\r
2082 $string = entity::named_to_numeric($string);
\r
2083 $string = entity::normalize_numeric($string);
\r
2085 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2086 $string = entity::numeric_to_utf8($string);
\r
2089 $string = entity::specialchars($string, 'html');
\r
2090 $string = entity::numeric_to_named($string);
\r
2095 * Make a string containing HTML safe for use in a XML document
\r
2096 * Tags are stripped, entities are normalized and named entities are
\r
2097 * converted to numeric entities.
\r
2099 function stringToXML ($string) {
\r
2100 $string = stringStripTags($string);
\r
2101 $string = entity::named_to_numeric($string);
\r
2102 $string = entity::normalize_numeric($string);
\r
2104 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2105 $string = entity::numeric_to_utf8($string);
\r
2108 $string = entity::specialchars($string, 'xml');
\r
2112 // START: functions from the end of file BLOG.php
\r
2113 // used for mail notification (html -> text)
\r
2114 function toAscii($html) {
\r
2115 // strip off most tags
\r
2116 $html = strip_tags($html,'<a>');
\r
2117 $to_replace = "/<a[^>]*href=[\"\']([^\"^']*)[\"\'][^>]*>([^<]*)<\/a>/i";
\r
2119 $ascii = preg_replace_callback ($to_replace, '_links_add', $html);
\r
2120 $ascii .= "\n\n" . _links_list();
\r
2121 return strip_tags($ascii);
\r
2124 function _links_init() {
\r
2125 global $tmp_links;
\r
2126 $tmp_links = array();
\r
2129 function _links_add($match) {
\r
2130 global $tmp_links;
\r
2131 array_push($tmp_links, $match[1]);
\r
2132 return $match[2] . ' [' . sizeof($tmp_links) .']';
\r
2135 function _links_list() {
\r
2136 global $tmp_links;
\r
2139 foreach ($tmp_links as $current) {
\r
2140 $output .= "[$i] $current\n";
\r
2145 // END: functions from the end of file BLOG.php
\r
2147 // START: functions from the end of file ADMIN.php
\r
2149 * @todo document this
\r
2151 function encode_desc(&$data)
\r
2153 // _$to_entities = get_html_translation_table(HTML_ENTITIES);
\r
2154 $to_entities = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
2155 $from_entities = array_flip($to_entities);
\r
2156 $data = str_replace('<br />', '\n', $data); //hack
\r
2157 $data = strtr($data,$from_entities);
\r
2158 $data = strtr($data,$to_entities);
\r
2159 $data = str_replace('\n', '<br />', $data); //hack
\r
2164 * Returns the Javascript code for a bookmarklet that works on most modern browsers
\r
2168 function getBookmarklet($blogid) {
\r
2172 $document = 'document';
\r
2173 $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
2174 $bookmarkletline .= $CONF['AdminURL'] . "bookmarklet.php?blogid=$blogid";
\r
2175 $bookmarkletline .="&logtext='+escape(Q)+'&loglink='+escape(x.location.href)+'&loglinktitle='+escape(x.title),'nucleusbm','toolbar=no,scrollbars=no,width=710,height=550,left=10,top=10,status=no,resizable=yes');wingm.focus();";
\r
2177 return $bookmarkletline;
\r
2179 // END: functions from the end of file ADMIN.php
\r
2182 * Returns a variable or null if not set
\r
2184 * @param mixed Variable
\r
2185 * @return mixed Variable
\r
2187 function ifset(&$var) {
\r
2188 if (isset($var)) {
\r
2196 * Returns number of subscriber to an event
\r
2199 * @return number of subscriber(s)
\r
2201 function numberOfEventSubscriber($event) {
\r
2202 $query = 'SELECT COUNT(*) as count FROM ' . sql_table('plugin_event') . ' WHERE event=\'' . $event . '\'';
\r
2203 $res = sql_query($query);
\r
2204 $obj = sql_fetch_object($res);
\r
2205 return $obj->count;
\r
2208 function selectSpecialSkinType($id) {
\r
2210 $special = strtolower($id);
\r