4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
\r
5 * Copyright (C) 2002-2009 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-2009 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.50SVN';
\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 error_reporting(E_ERROR | E_WARNING | E_PARSE);
\r
36 Indicates when Nucleus should display startup errors. Set to 1 if you want
\r
37 the error enabled (default), false otherwise
\r
40 Displays an error when visiting a public Nucleus page and headers have
\r
41 been sent out to early. This usually indicates an error in either a
\r
42 configuration file or a language file, and could cause Nucleus to
\r
45 Displays an error only when visiting the admin area, and when one or
\r
46 more of the installation files (install.php, install.sql, upgrades/
\r
47 directory) are still on the server.
\r
50 $CONF['alertOnHeadersSent'] = 1;
\r
51 $CONF['alertOnSecurityRisk'] = 1;
\r
52 /*$CONF['ItemURL'] = $CONF['Self'];
\r
53 $CONF['ArchiveURL'] = $CONF['Self'];
\r
54 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
55 $CONF['MemberURL'] = $CONF['Self'];
\r
56 $CONF['SearchURL'] = $CONF['Self'];
\r
57 $CONF['BlogURL'] = $CONF['Self'];
\r
58 $CONF['CategoryURL'] = $CONF['Self'];
\r
60 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
61 // this avoids urls like index.php/item/13/index.php/item/15
\r
62 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
\r
63 $CONF['URLMode'] = 'normal';
\r
66 if (getNucleusPatchLevel() > 0) {
\r
67 $nucleus['version'] .= '/' . getNucleusPatchLevel();
\r
71 if (!isset($CONF['installscript'])) {
\r
72 $CONF['installscript'] = 0;
\r
75 // we will use postVar, getVar, ... methods instead of HTTP_GET_VARS or _GET
\r
76 if ($CONF['installscript'] != 1) { // vars were already included in install.php
\r
77 if (phpversion() >= '4.1.0') {
\r
78 include_once($DIR_LIBS . 'vars4.1.0.php');
\r
80 include_once($DIR_LIBS . 'vars4.0.6.php');
\r
85 $bLoggingSanitizedResult=0;
\r
86 $bSanitizeAndContinue=0;
\r
88 $orgRequestURI = serverVar('REQUEST_URI');
\r
91 // get all variables that can come from the request and put them in the global scope
\r
92 $blogid = requestVar('blogid');
\r
93 $itemid = intRequestVar('itemid');
\r
94 $catid = intRequestVar('catid');
\r
95 $skinid = requestVar('skinid');
\r
96 $memberid = requestVar('memberid');
\r
97 $archivelist = requestVar('archivelist');
\r
98 $imagepopup = requestVar('imagepopup');
\r
99 $archive = requestVar('archive');
\r
100 $query = requestVar('query');
\r
101 $highlight = requestVar('highlight');
\r
102 $amount = requestVar('amount');
\r
103 $action = requestVar('action');
\r
104 $nextaction = requestVar('nextaction');
\r
105 $maxresults = requestVar('maxresults');
\r
106 $startpos = intRequestVar('startpos');
\r
107 $errormessage = '';
\r
109 $special = requestVar('special');
\r
110 $virtualpath = ((getVar('virtualpath') != null) ? getVar('virtualpath') : serverVar('PATH_INFO'));
\r
112 if (!headers_sent() ) {
\r
113 header('Generator: Nucleus CMS ' . $nucleus['version']);
\r
116 // include core classes that are needed for login & plugin handling
\r
117 // added for 3.5 sql_* wrapper
\r
118 global $MYSQL_HANDLER;
\r
119 if (!isset($MYSQL_HANDLER))
\r
120 $MYSQL_HANDLER = array('mysql','');
\r
121 if ($MYSQL_HANDLER[0] == '')
\r
122 $MYSQL_HANDLER[0] = 'mysql';
\r
123 include_once($DIR_LIBS . 'sql/'.$MYSQL_HANDLER[0].'.php');
\r
124 // end new for 3.5 sql_* wrapper
\r
125 include_once($DIR_LIBS . 'mysql.php');
\r
126 include($DIR_LIBS . 'MEMBER.php');
\r
127 include($DIR_LIBS . 'ACTIONLOG.php');
\r
128 include($DIR_LIBS . 'MANAGER.php');
\r
129 include($DIR_LIBS . 'PLUGIN.php');
\r
131 $manager =& MANAGER::instance();
\r
133 // make sure there's no unnecessary escaping:
\r
134 set_magic_quotes_runtime(0);
\r
137 if (!isset($CONF['UsingAdminArea'])) {
\r
138 $CONF['UsingAdminArea'] = 0;
\r
141 // only needed when updating logs
\r
142 if ($CONF['UsingAdminArea']) {
\r
143 include($DIR_LIBS . 'xmlrpc.inc.php'); // XML-RPC client classes
\r
144 include_once($DIR_LIBS . 'ADMIN.php');
\r
147 // connect to database
\r
151 // logs sanitized result if need
\r
152 if ($orgRequestURI!==serverVar('REQUEST_URI')) {
\r
153 $msg = "Sanitized [" . serverVar('REMOTE_ADDR') . "] ";
\r
154 $msg .= $orgRequestURI . " -> " . serverVar('REQUEST_URI');
\r
155 if ($bLoggingSanitizedResult) {
\r
156 addToLog(WARNING, $msg);
\r
158 if (!$bSanitizeAndContinue) {
\r
163 // makes sure database connection gets closed on script termination
\r
164 register_shutdown_function('sql_disconnect');
\r
169 // Properly set $CONF['Self'] and others if it's not set... usually when we are access from admin menu
\r
170 if (!isset($CONF['Self'])) {
\r
171 $CONF['Self'] = $CONF['IndexURL'];
\r
172 // strip trailing /
\r
173 if ($CONF['Self'][strlen($CONF['Self']) -1] == "/") {
\r
174 $CONF['Self'] = substr($CONF['Self'], 0, strlen($CONF['Self']) -1);
\r
177 /* $CONF['ItemURL'] = $CONF['Self'];
\r
178 $CONF['ArchiveURL'] = $CONF['Self'];
\r
179 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
180 $CONF['MemberURL'] = $CONF['Self'];
\r
181 $CONF['SearchURL'] = $CONF['Self'];
\r
182 $CONF['BlogURL'] = $CONF['Self'];
\r
183 $CONF['CategoryURL'] = $CONF['Self'];*/
\r
186 $CONF['ItemURL'] = $CONF['Self'];
\r
187 $CONF['ArchiveURL'] = $CONF['Self'];
\r
188 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
189 $CONF['MemberURL'] = $CONF['Self'];
\r
190 $CONF['SearchURL'] = $CONF['Self'];
\r
191 $CONF['BlogURL'] = $CONF['Self'];
\r
192 $CONF['CategoryURL'] = $CONF['Self'];
\r
194 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
195 // this avoids urls like index.php/item/13/index.php/item/15
\r
196 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
\r
197 $CONF['URLMode'] = 'normal';
\r
200 // automatically use simpler toolbar for mozilla
\r
201 if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'), 'Gecko') ) {
\r
202 $CONF['DisableJsTools'] = 2;
\r
205 // login if cookies set
\r
206 $member = new MEMBER();
\r
208 // secure cookie key settings (either 'none', 0, 8, 16, 24, or 32)
\r
209 if (!isset($CONF['secureCookieKey'])) $CONF['secureCookieKey']=24;
\r
210 switch($CONF['secureCookieKey']){
\r
212 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
215 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
218 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
221 $CONF['secureCookieKeyIP']=serverVar('REMOTE_ADDR');
\r
224 $CONF['secureCookieKeyIP']='';
\r
227 // login/logout when required or renew cookies
\r
228 if ($action == 'login') {
\r
229 // Form Authentication
\r
230 $login = postVar('login');
\r
231 $pw = postVar('password');
\r
232 $shared = intPostVar('shared'); // shared computer or not
\r
234 $pw=substr($pw,0,40); // avoid md5 collision by using a long key
\r
236 if ($member->login($login, $pw) ) {
\r
238 $member->newCookieKey();
\r
239 $member->setCookies($shared);
\r
241 if ($CONF['secureCookieKey']!=='none') {
\r
242 // secure cookie key
\r
243 $member->setCookieKey(md5($member->getCookieKey().$CONF['secureCookieKeyIP']));
\r
247 // allows direct access to parts of the admin area after logging in
\r
249 $action = $nextaction;
\r
252 $manager->notify('LoginSuccess', array('member' => &$member, 'username' => $login) );
\r
253 $errormessage = '';
\r
254 ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");
\r
256 // errormessage for [%errordiv%]
\r
257 $errormessage = 'Login failed for ' . $login;
\r
259 $manager->notify('LoginFailed', array('username' => $login) );
\r
260 ACTIONLOG::add(INFO, $errormessage);
\r
264 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
266 } elseif (serverVar('PHP_AUTH_USER') && serverVar('PHP_AUTH_PW')) {
\r
267 // HTTP Authentication
\r
268 $login = serverVar('PHP_AUTH_USER');
\r
269 $pw = serverVar('PHP_AUTH_PW');
\r
271 if ($member->login($login, $pw) ) {
\r
272 $manager->notify('LoginSuccess',array('member' => &$member));
\r
273 ACTIONLOG::add(INFO, "HTTP authentication successful for $login");
\r
275 $manager->notify('LoginFailed',array('username' => $login));
\r
276 ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);
\r
278 //Since bad credentials, generate an apropriate error page
\r
279 header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");
\r
280 header('HTTP/1.0 401 Unauthorized');
\r
281 echo 'Invalid username or password';
\r
286 } elseif (($action == 'logout') && (!headers_sent() ) && cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
287 // remove cookies on logout
\r
288 setcookie($CONF['CookiePrefix'] . 'user', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
289 setcookie($CONF['CookiePrefix'] . 'loginkey', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
290 $manager->notify('Logout', array('username' => cookieVar($CONF['CookiePrefix'] . 'user') ) );
\r
291 } elseif (cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
292 // Cookie Authentication
\r
293 $ck=cookieVar($CONF['CookiePrefix'] . 'loginkey');
\r
294 // secure cookie key
\r
295 $ck=substr($ck,0,32); // avoid md5 collision by using a long key
\r
296 if ($CONF['secureCookieKey']!=='none') $ck=md5($ck.$CONF['secureCookieKeyIP']);
\r
297 $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), $ck );
\r
300 // renew cookies when not on a shared computer
\r
301 if ($res && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) && (!headers_sent() ) ) {
\r
302 $member->setCookieKey(cookieVar($CONF['CookiePrefix'] . 'loginkey'));
\r
303 $member->setCookies();
\r
308 $manager->notify('PostAuthentication', array('loggedIn' => $member->isLoggedIn() ) );
\r
311 // first, let's see if the site is disabled or not. always allow admin area access.
\r
312 if ($CONF['DisableSite'] && !$member->isAdmin() && !$CONF['UsingAdminArea']) {
\r
313 redirect($CONF['DisableSiteURL']);
\r
317 // load other classes
\r
318 include($DIR_LIBS . 'PARSER.php');
\r
319 include($DIR_LIBS . 'SKIN.php');
\r
320 include($DIR_LIBS . 'TEMPLATE.php');
\r
321 include($DIR_LIBS . 'BLOG.php');
\r
322 include($DIR_LIBS . 'BODYACTIONS.php');
\r
323 include($DIR_LIBS . 'COMMENTS.php');
\r
324 include($DIR_LIBS . 'COMMENT.php');
\r
325 //include($DIR_LIBS . 'ITEM.php');
\r
326 include($DIR_LIBS . 'NOTIFICATION.php');
\r
327 include($DIR_LIBS . 'BAN.php');
\r
328 include($DIR_LIBS . 'PAGEFACTORY.php');
\r
329 include($DIR_LIBS . 'SEARCH.php');
\r
330 include($DIR_LIBS . 'entity.php');
\r
333 // set lastVisit cookie (if allowed)
\r
334 if (!headers_sent() ) {
\r
335 if ($CONF['LastVisit']) {
\r
336 setcookie($CONF['CookiePrefix'] . 'lastVisit', time(), time() + 2592000, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
338 setcookie($CONF['CookiePrefix'] . 'lastVisit', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
342 // read language file, only after user has been initialized
\r
343 $language = getLanguageName();
\r
344 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
\r
346 // check if valid charset
\r
347 if (!encoding_check(false, false, _CHARSET)) {
\r
348 foreach(array($_GET, $_POST) as $input) {
\r
349 array_walk($input, 'encoding_check');
\r
354 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
356 // To remove after v2.5 is released and language files have been updated.
\r
357 // Including this makes sure that language files for v2.5beta can still be used for v2.5final
\r
358 // without having weird _SETTINGS_EXTAUTH string showing up in the admin area.
\r
359 if (!defined('_MEMBERS_BYPASS'))
\r
361 define('_SETTINGS_EXTAUTH', 'Enable External Authentication');
\r
362 define('_WARNING_EXTAUTH', 'Warning: Enable only if needed.');
\r
363 define('_MEMBERS_BYPASS', 'Use External Authentication');
\r
368 // make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined
\r
369 if (!defined('_ARCHIVETYPE_MONTH') ) {
\r
370 define('_ARCHIVETYPE_DAY', 'day');
\r
371 define('_ARCHIVETYPE_MONTH', 'month');
\r
372 define('_ARCHIVETYPE_YEAR', 'year');
\r
375 // decode path_info
\r
376 if ($CONF['URLMode'] == 'pathinfo') {
\r
377 // initialize keywords if this hasn't been done before
\r
378 if (!isset($CONF['ItemKey']) || $CONF['ItemKey'] == '') {
\r
379 $CONF['ItemKey'] = 'item';
\r
382 if (!isset($CONF['ArchiveKey']) || $CONF['ArchiveKey'] == '') {
\r
383 $CONF['ArchiveKey'] = 'archive';
\r
386 if (!isset($CONF['ArchivesKey']) || $CONF['ArchivesKey'] == '') {
\r
387 $CONF['ArchivesKey'] = 'archives';
\r
390 if (!isset($CONF['MemberKey']) || $CONF['MemberKey'] == '') {
\r
391 $CONF['MemberKey'] = 'member';
\r
394 if (!isset($CONF['BlogKey']) || $CONF['BlogKey'] == '') {
\r
395 $CONF['BlogKey'] = 'blog';
\r
398 if (!isset($CONF['CategoryKey']) || $CONF['CategoryKey'] == '') {
\r
399 $CONF['CategoryKey'] = 'category';
\r
402 if (!isset($CONF['SpecialskinKey']) || $CONF['SpecialskinKey'] == '') {
\r
403 $CONF['SpecialskinKey'] = 'special';
\r
410 'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...
\r
411 'info' => $virtualpath,
\r
412 'complete' => &$parsed
\r
417 // default implementation
\r
418 $data = explode("/", $virtualpath );
\r
419 for ($i = 0; $i < sizeof($data); $i++) {
\r
420 switch ($data[$i]) {
\r
421 case $CONF['ItemKey']: // item/1 (blogid)
\r
424 if ($i < sizeof($data) ) {
\r
425 $itemid = intval($data[$i]);
\r
429 case $CONF['ArchivesKey']: // archives/1 (blogid)
\r
432 if ($i < sizeof($data) ) {
\r
433 $archivelist = intval($data[$i]);
\r
437 case $CONF['ArchiveKey']: // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)
\r
438 if ((($i + 1) < sizeof($data) ) && (!strstr($data[$i + 1], '-') ) ) {
\r
439 $blogid = intval($data[++$i]);
\r
444 if ($i < sizeof($data) ) {
\r
445 $archive = $data[$i];
\r
449 case 'blogid': // blogid/1
\r
450 case $CONF['BlogKey']: // blog/1
\r
453 if ($i < sizeof($data) ) {
\r
454 $blogid = intval($data[$i]);
\r
458 case $CONF['CategoryKey']: // category/1 (catid)
\r
462 if ($i < sizeof($data) ) {
\r
463 $catid = intval($data[$i]);
\r
467 case $CONF['MemberKey']:
\r
470 if ($i < sizeof($data) ) {
\r
471 $memberid = intval($data[$i]);
\r
475 case $CONF['SpecialskinKey']:
\r
478 if ($i < sizeof($data) ) {
\r
479 $_REQUEST['special'] = $data[$i];
\r
490 function intPostVar($name) {
\r
491 return intval(postVar($name) );
\r
494 function intGetVar($name) {
\r
495 return intval(getVar($name) );
\r
498 function intRequestVar($name) {
\r
499 return intval(requestVar($name) );
\r
502 function intCookieVar($name) {
\r
503 return intval(cookieVar($name) );
\r
507 * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)
\r
509 function getNucleusVersion() {
\r
514 * power users can install patches in between nucleus releases. These patches
\r
515 * usually add new functionality in the plugin API and allow those to
\r
516 * be tested without having to install CVS.
\r
518 function getNucleusPatchLevel() {
\r
523 * returns the latest version available for download from nucleuscms.org
\r
524 * or false if unable to attain data
\r
525 * format will be major.minor/patachlevel
\r
526 * e.g. 3.41 or 3.41/02
\r
528 function getLatestVersion() {
\r
529 if (!function_exists('curl_init')) return false;
\r
530 $crl = curl_init();
\r
532 curl_setopt ($crl, CURLOPT_URL,'http://nucleuscms.org/version_check.php');
\r
533 curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);
\r
534 curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);
\r
535 $ret = curl_exec($crl);
\r
542 * Connects to mysql server
\r
544 /* moved to $DIR_LIBS/sql/*.php handler files
\r
545 function sql_connect() {
\r
546 global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE, $MYSQL_CONN;
\r
548 $MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>', 'Connect Error');
\r
549 mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: ' . mysql_error() . '</p>', 'Connect Error');
\r
551 return $MYSQL_CONN;
\r
555 * returns a prefixed nucleus table name
\r
557 function sql_table($name) {
\r
558 global $MYSQL_PREFIX;
\r
560 if ($MYSQL_PREFIX) {
\r
561 return $MYSQL_PREFIX . 'nucleus_' . $name;
\r
563 return 'nucleus_' . $name;
\r
567 function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
\r
568 global $manager, $CONF;
\r
570 if (!headers_sent() ) {
\r
571 // if content type is application/xhtml+xml, only send it to browsers
\r
572 // that can handle it (IE6 cannot). Otherwise, send text/html
\r
574 // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)
\r
575 // application/xhtml+xml still causes too much problems with the javascript implementations
\r
577 // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,
\r
578 // application/xhtml+xml seems to be working, so we're going to use it if we can.
\r
580 // Note: reverted the following function in JP version
\r
585 ($contenttype == 'application/xhtml+xml')
\r
586 && (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )
\r
588 $contenttype = 'text/html';
\r
593 ($contenttype == 'application/xhtml+xml')
\r
594 && (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))
\r
597 $contenttype = 'text/html';
\r
601 'PreSendContentType',
\r
603 'contentType' => &$contenttype,
\r
604 'charset' => &$charset,
\r
605 'pageType' => $pagetype
\r
609 // strip strange characters
\r
610 $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);
\r
611 $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);
\r
613 if ($charset != '') {
\r
614 header('Content-Type: ' . $contenttype . '; charset=' . $charset);
\r
616 header('Content-Type: ' . $contenttype);
\r
619 // check if valid charset
\r
620 if (!encoding_check(false,false,$charset)) {
\r
621 foreach(array($_GET, $_POST) as $input) {
\r
622 array_walk($input, 'encoding_check');
\r
629 * Errors before the database connection has been made - moved to
\r
631 /* moved to $DIR_LIBS/sql/*.php handler files
\r
632 function startUpError($msg, $title) {
\r
633 if (!defined('_CHARSET')) define('_CHARSET', 'iso-8859-1');
\r
634 header('Content-Type: text/html; charset=' . _CHARSET);
\r
636 <html <?php echo _HTML_XML_NAME_SPACE_AND_LANG_CODE; ?>>
\r
637 <head><meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET?>" />
\r
638 <title><?php echo htmlspecialchars($title)?></title></head>
\r
640 <h1><?php echo htmlspecialchars($title)?></h1>
\r
648 * disconnects from SQL server
\r
650 /* moved to $DIR_LIBS/sql/*.php handler files
\r
651 function sql_disconnect() {
\r
656 * executes an SQL query
\r
658 /* moved to $DIR_LIBS/sql/*.php handler files
\r
659 function sql_query($query) {
\r
662 $res = mysql_query($query) or print("mySQL error with query $query: " . mysql_error() . '<p />');
\r
668 * Highlights a specific query in a given HTML text (not within HTML tags) and returns it
\r
671 * text to be highlighted
\r
672 * @param $expression
\r
673 * regular expression to be matched (can be an array of expressions as well)
\r
674 * @param $highlight
\r
675 * highlight to be used (use \\0 to indicate the matched expression)
\r
678 function highlight($text, $expression, $highlight) {
\r
679 if (!$highlight || !$expression) {
\r
683 if (is_array($expression) && (count($expression) == 0) ) {
\r
687 // add a tag in front (is needed for preg_match_all to work correct)
\r
688 $text = '<!--h-->' . $text;
\r
690 // split the HTML up so we have HTML tags
\r
691 // $matches[0][i] = HTML + text
\r
692 // $matches[1][i] = HTML
\r
693 // $matches[2][i] = text
\r
694 preg_match_all('/(<[^>]+>)([^<>]*)/', $text, $matches);
\r
696 // throw it all together again while applying the highlight to the text pieces
\r
698 for ($i = 0; $i < sizeof($matches[2]); $i++) {
\r
700 $result .= $matches[1][$i];
\r
703 if (is_array($expression) ) {
\r
704 foreach ($expression as $regex) {
\r
706 $matches[2][$i] = @eregi_replace($regex, $highlight, $matches[2][$i]);
\r
710 $result .= $matches[2][$i];
\r
712 $result .= @eregi_replace($expression, $highlight, $matches[2][$i]);
\r
720 * Parses a query into an array of expressions that can be passed on to the highlight method
\r
722 function parseHighlight($query) {
\r
723 // TODO: add more intelligent splitting logic
\r
725 // get rid of quotes
\r
726 $query = preg_replace('/\'|"/', '', $query);
\r
732 $aHighlight = explode(' ', $query);
\r
734 for ($i = 0; $i < count($aHighlight); $i++) {
\r
735 $aHighlight[$i] = trim($aHighlight[$i]);
\r
737 // if (strlen($aHighlight[$i]) < 3) {
\r
738 // unset($aHighlight[$i]);
\r
742 if (count($aHighlight) == 1) {
\r
743 return $aHighlight[0];
\r
745 return $aHighlight;
\r
750 * Checks if email address is valid
\r
752 function isValidMailAddress($address) {
\r
753 if (preg_match('/^[a-zA-Z+0-9\._-]+@[a-zA-Z0-9\._-]+\.[A-Za-z]{2,5}$/', $address)) {
\r
761 // some helper functions
\r
762 function getBlogIDFromName($name) {
\r
763 return quickQuery('SELECT bnumber as result FROM ' . sql_table('blog') . ' WHERE bshortname="' . addslashes($name) . '"');
\r
766 function getBlogNameFromID($id) {
\r
767 return quickQuery('SELECT bname as result FROM ' . sql_table('blog') . ' WHERE bnumber=' . intval($id) );
\r
770 function getBlogIDFromItemID($itemid) {
\r
771 return quickQuery('SELECT iblog as result FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid) );
\r
774 function getBlogIDFromCommentID($commentid) {
\r
775 return quickQuery('SELECT cblog as result FROM ' . sql_table('comment') . ' WHERE cnumber=' . intval($commentid) );
\r
778 function getBlogIDFromCatID($catid) {
\r
779 return quickQuery('SELECT cblog as result FROM ' . sql_table('category') . ' WHERE catid=' . intval($catid) );
\r
782 function getCatIDFromName($name) {
\r
783 return quickQuery('SELECT catid as result FROM ' . sql_table('category') . ' WHERE cname="' . addslashes($name) . '"');
\r
786 function quickQuery($q) {
\r
787 $res = sql_query($q);
\r
788 $obj = sql_fetch_object($res);
\r
789 return $obj->result;
\r
792 function getPluginNameFromPid($pid) {
\r
793 $res = sql_query('SELECT pfile FROM ' . sql_table('plugin') . ' WHERE pid=' . intval($pid) );
\r
794 $obj = sql_fetch_object($res);
\r
795 return $obj->pfile;
\r
798 function selector() {
\r
799 global $itemid, $blogid, $memberid, $query, $amount, $archivelist, $maxresults;
\r
800 global $archive, $skinid, $blog, $memberinfo, $CONF, $member;
\r
801 global $imagepopup, $catid, $special;
\r
804 $actionNames = array('addcomment', 'sendmessage', 'createaccount', 'forgotpassword', 'votepositive', 'votenegative', 'plugin');
\r
805 $action = requestVar('action');
\r
807 if (in_array($action, $actionNames) ) {
\r
808 global $DIR_LIBS, $errormessage;
\r
809 include_once($DIR_LIBS . 'ACTION.php');
\r
811 $errorInfo = $a->doAction($action);
\r
814 $errormessage = $errorInfo['message'];
\r
818 // show error when headers already sent out
\r
819 if (headers_sent() && $CONF['alertOnHeadersSent']) {
\r
821 // try to get line number/filename (extra headers_sent params only exists in PHP 4.3+)
\r
822 if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=') ) {
\r
823 headers_sent($hsFile, $hsLine);
\r
824 $extraInfo = sprintf(_GFUNCTIONS_HEADERSALREADYSENT_FILE,$hsFile,$hsLine);
\r
830 sprintf(_GFUNCTIONS_HEADERSALREADYSENT_TXT,$extraInfo),
\r
831 _GFUNCTIONS_HEADERSALREADYSENT_TITLE
\r
836 // make is so ?archivelist without blogname or blogid shows the archivelist
\r
837 // for the default weblog
\r
838 if (serverVar('QUERY_STRING') == 'archivelist') {
\r
839 $archivelist = $CONF['DefaultBlog'];
\r
842 // now decide which type of skin we need
\r
844 // itemid given -> only show that item
\r
847 if (!$manager->existsItem($itemid,0,0) ) {
\r
848 doError(_ERROR_NOSUCHITEM);
\r
851 global $itemidprev, $itemidnext, $catid, $itemtitlenext, $itemtitleprev;
\r
853 // 1. get timestamp, blogid and catid for item
\r
854 $query = 'SELECT itime, iblog, icat FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid);
\r
855 $res = sql_query($query);
\r
856 $obj = sql_fetch_object($res);
\r
858 // if a different blog id has been set through the request or selectBlog(),
\r
860 // if ($blogid && (intval($blogid) != $obj->iblog) ) {
\r
861 // doError(_ERROR_NOSUCHITEM);
\r
863 if ($blogid && (intval($blogid) != $obj->iblog) ) {
\r
864 if (!headers_sent()) {
\r
865 $b =& $manager->getBlog($obj->iblog);
\r
866 $CONF['ItemURL'] = $b->getURL();
\r
867 if ($CONF['URLMode'] == 'pathinfo' and substr($CONF['ItemURL'],-1) == '/')
\r
868 $CONF['ItemURL'] = substr($CONF['ItemURL'], 0, -1);
\r
869 $correctURL = createItemLink($itemid, '');
\r
870 redirect($correctURL);
\r
873 doError(_ERROR_NOSUCHITEM);
\r
877 // if a category has been selected which doesn't match the item, ignore the
\r
879 if (($catid != 0) && ($catid != $obj->icat) ) {
\r
883 $blogid = $obj->iblog;
\r
884 $timestamp = strtotime($obj->itime);
\r
886 $b =& $manager->getBlog($blogid);
\r
888 if ($b->isValidCategory($catid) ) {
\r
889 $catextra = ' and icat=' . $catid;
\r
894 // get previous itemid and title
\r
895 $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
896 $res = sql_query($query);
\r
898 $obj = sql_fetch_object($res);
\r
901 $itemidprev = $obj->inumber;
\r
902 $itemtitleprev = $obj->ititle;
\r
905 // get next itemid and title
\r
906 $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
907 $res = sql_query($query);
\r
909 $obj = sql_fetch_object($res);
\r
912 $itemidnext = $obj->inumber;
\r
913 $itemtitlenext = $obj->ititle;
\r
916 } elseif ($archive) {
\r
920 // get next and prev month links ...
\r
921 global $archivenext, $archiveprev, $archivetype, $archivenextexists, $archiveprevexists;
\r
923 // sql queries for the timestamp of the first and the last published item
\r
924 $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
925 $first_timestamp=quickQuery ($query);
\r
926 $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
927 $last_timestamp=quickQuery ($query);
\r
929 sscanf($archive, '%d-%d-%d', $y, $m, $d);
\r
932 $archivetype = _ARCHIVETYPE_DAY;
\r
933 $t = mktime(0, 0, 0, $m, $d, $y);
\r
934 // one day has 24 * 60 * 60 = 86400 seconds
\r
935 $archiveprev = strftime('%Y-%m-%d', $t - 86400 );
\r
936 // check for published items
\r
937 if ($t > $first_timestamp) {
\r
938 $archiveprevexists = true;
\r
941 $archiveprevexists = false;
\r
946 $archivenext = strftime('%Y-%m-%d', $t);
\r
947 if ($t < $last_timestamp) {
\r
948 $archivenextexists = true;
\r
951 $archivenextexists = false;
\r
954 } elseif ($m == 0) {
\r
955 $archivetype = _ARCHIVETYPE_YEAR;
\r
956 $t = mktime(0, 0, 0, 12, 31, $y - 1);
\r
957 // one day before is in the previous year
\r
958 $archiveprev = strftime('%Y', $t);
\r
959 if ($t > $first_timestamp) {
\r
960 $archiveprevexists = true;
\r
963 $archiveprevexists = false;
\r
966 // timestamp for the next year
\r
967 $t = mktime(0, 0, 0, 1, 1, $y + 1);
\r
968 $archivenext = strftime('%Y', $t);
\r
969 if ($t < $last_timestamp) {
\r
970 $archivenextexists = true;
\r
973 $archivenextexists = false;
\r
976 $archivetype = _ARCHIVETYPE_MONTH;
\r
977 $t = mktime(0, 0, 0, $m, 1, $y);
\r
978 // one day before is in the previous month
\r
979 $archiveprev = strftime('%Y-%m', $t - 86400);
\r
980 if ($t > $first_timestamp) {
\r
981 $archiveprevexists = true;
\r
984 $archiveprevexists = false;
\r
987 // timestamp for the next month
\r
988 $t = mktime(0, 0, 0, $m+1, 1, $y);
\r
989 $archivenext = strftime('%Y-%m', $t);
\r
990 if ($t < $last_timestamp) {
\r
991 $archivenextexists = true;
\r
994 $archivenextexists = false;
\r
998 } elseif ($archivelist) {
\r
999 $type = 'archivelist';
\r
1001 if (is_numeric($archivelist)) {
\r
1002 $blogid = intVal($archivelist);
\r
1004 $blogid = getBlogIDFromName($archivelist);
\r
1008 doError(_ERROR_NOSUCHBLOG);
\r
1011 } elseif ($query) {
\r
1014 $query = stripslashes($query);
\r
1015 if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/", $query)){
\r
1018 // $order = (_CHARSET == 'EUC-JP') ? 'EUC-JP, UTF-8,' : 'UTF-8, EUC-JP,';
\r
1019 // $query = mb_convert_encoding($query, _CHARSET, $order . ' JIS, SJIS, ASCII');
\r
1020 switch(strtolower(_CHARSET)){
\r
1022 $order = 'ASCII, UTF-8, EUC-JP, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1025 $order = 'ASCII, EUC-CN, EUC-JP, UTF-8, JIS, SJIS, ISO-8859-1';
\r
1028 // Note that shift_jis is only supported for output.
\r
1029 // Using shift_jis in DB is prohibited.
\r
1030 $order = 'ASCII, SJIS, EUC-JP, UTF-8, JIS, EUC-CN, ISO-8859-1';
\r
1033 // euc-jp,iso-8859-x,windows-125x
\r
1034 $order = 'ASCII, EUC-JP, UTF-8, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1037 $query = mb_convert_encoding($query, _CHARSET, $order);
\r
1038 if (is_numeric($blogid)) {
\r
1039 $blogid = intVal($blogid);
\r
1041 $blogid = getBlogIDFromName($blogid);
\r
1045 doError(_ERROR_NOSUCHBLOG);
\r
1048 } elseif ($memberid) {
\r
1051 if (!MEMBER::existsID($memberid) ) {
\r
1052 doError(_ERROR_NOSUCHMEMBER);
\r
1055 $memberinfo = $manager->getMember($memberid);
\r
1057 } elseif ($imagepopup) {
\r
1058 // media object (images etc.)
\r
1059 $type = 'imagepopup';
\r
1061 // TODO: check if media-object exists
\r
1062 // TODO: set some vars?
\r
1064 // show regular index page
\r
1069 // any type of skin with catid
\r
1070 if ($catid && !$blogid) {
\r
1071 $blogid = getBlogIDFromCatID($catid);
\r
1074 // decide which blog should be displayed
\r
1076 $blogid = $CONF['DefaultBlog'];
\r
1079 $b =& $manager->getBlog($blogid);
\r
1080 $blog = $b; // references can't be placed in global variables?
\r
1082 if (!$blog->isValid) {
\r
1083 doError(_ERROR_NOSUCHBLOG);
\r
1086 // set catid if necessary
\r
1088 // check if the category is valid
\r
1089 if (!$blog->isValidCategory($catid)) {
\r
1090 doError(_ERROR_NOSUCHCATEGORY);
\r
1092 $blog->setSelectedCategory($catid);
\r
1096 // decide which skin should be used
\r
1097 if ($skinid != '' && ($skinid == 0) ) {
\r
1098 selectSkin($skinid);
\r
1102 $skinid = $blog->getDefaultSkin();
\r
1105 //$special = requestVar('special'); //get at top of file as global
\r
1106 if (!empty($special) && isValidShortName($special)) {
\r
1107 $type = strtolower($special);
\r
1110 $skin = new SKIN($skinid);
\r
1112 if (!$skin->isValid) {
\r
1113 doError(_ERROR_NOSUCHSKIN);
\r
1117 $skin->parse($type);
\r
1119 // check to see we should throw JustPosted event
\r
1120 $blog->checkJustPosted();
\r
1124 * Show error skin with given message. An optional skin-object to use can be given
\r
1126 function doError($msg, $skin = '') {
\r
1127 global $errormessage, $CONF, $skinid, $blogid, $manager;
\r
1129 if ($skin == '') {
\r
1131 if (SKIN::existsID($skinid) ) {
\r
1132 $skin = new SKIN($skinid);
\r
1133 } elseif ($manager->existsBlogID($blogid) ) {
\r
1134 $blog =& $manager->getBlog($blogid);
\r
1135 $skin = new SKIN($blog->getDefaultSkin() );
\r
1136 } elseif ($CONF['DefaultBlog']) {
\r
1137 $blog =& $manager->getBlog($CONF['DefaultBlog']);
\r
1138 $skin = new SKIN($blog->getDefaultSkin() );
\r
1140 // this statement should actually never be executed
\r
1141 $skin = new SKIN($CONF['BaseSkin']);
\r
1146 $skinid = $skin->id;
\r
1147 $errormessage = $msg;
\r
1148 $skin->parse('error');
\r
1152 function getConfig() {
\r
1155 $query = 'SELECT * FROM ' . sql_table('config');
\r
1156 $res = sql_query($query);
\r
1158 while ($obj = sql_fetch_object($res) ) {
\r
1159 $CONF[$obj->name] = $obj->value;
\r
1163 // some checks for names of blogs, categories, templates, members, ...
\r
1164 function isValidShortName($name) {
\r
1165 return eregi('^[a-z0-9]+$', $name);
\r
1168 function isValidDisplayName($name) {
\r
1169 return eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name);
\r
1172 function isValidCategoryName($name) {
\r
1176 function isValidTemplateName($name) {
\r
1177 return eregi('^[a-z0-9/]+$', $name);
\r
1180 function isValidSkinName($name) {
\r
1181 return eregi('^[a-z0-9/]+$', $name);
\r
1184 // add and remove linebreaks
\r
1185 function addBreaks($var) {
\r
1186 return nl2br($var);
\r
1189 function removeBreaks($var) {
\r
1190 return preg_replace("/<br \/>([\r\n])/", "$1", $var);
\r
1193 // shortens a text string to maxlength ($toadd) is what needs to be added
\r
1194 // at the end (end length is <= $maxlength)
\r
1195 function shorten($text, $maxlength, $toadd) {
\r
1196 // 1. remove entities...
\r
1197 // $trans = get_html_translation_table(HTML_ENTITIES);
\r
1198 $trans = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
1199 $trans = array_flip($trans);
\r
1200 $text = strtr($text, $trans);
\r
1202 // 2. the actual shortening
\r
1203 if (strlen($text) > $maxlength) {
\r
1204 // $text = substr($text, 0, $maxlength - strlen($toadd) ) . $toadd;
\r
1205 $text = mb_strimwidth($text, 0, $maxlength, $toadd, _CHARSET); // for Japanese
\r
1211 * Converts a unix timestamp to a mysql DATETIME format, and places
\r
1212 * quotes around it.
\r
1214 function mysqldate($timestamp) {
\r
1215 return '"' . date('Y-m-d H:i:s', $timestamp) . '"';
\r
1219 * functions for use in index.php
\r
1221 function selectBlog($shortname) {
\r
1222 global $blogid, $archivelist;
\r
1223 $blogid = getBlogIDFromName($shortname);
\r
1225 // also force archivelist variable, if it is set
\r
1226 if ($archivelist) {
\r
1227 $archivelist = $blogid;
\r
1231 function selectSkin($skinname) {
\r
1233 $skinid = SKIN::getIdFromName($skinname);
\r
1237 * Can take either a category ID or a category name (be aware that
\r
1238 * multiple categories can have the same name)
\r
1240 function selectCategory($cat) {
\r
1242 if (is_numeric($cat) ) {
\r
1243 $catid = intval($cat);
\r
1245 $catid = getCatIDFromName($cat);
\r
1249 function selectItem($id) {
\r
1251 $itemid = intval($id);
\r
1254 // force the use of a language file (warning: can cause warnings)
\r
1255 function selectLanguage($language) {
\r
1257 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
\r
1260 function parseFile($filename, $includeMode = 'normal', $includePrefix = '') {
\r
1261 $handler = new ACTIONS('fileparser');
\r
1262 $parser = new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);
\r
1263 $handler->parser =& $parser;
\r
1265 // set IncludeMode properties of parser
\r
1266 PARSER::setProperty('IncludeMode', $includeMode);
\r
1267 PARSER::setProperty('IncludePrefix', $includePrefix);
\r
1269 if (!file_exists($filename) ) {
\r
1270 doError(_GFUNCTIONS_PARSEFILE_FILEMISSING);
\r
1273 $fsize = filesize($filename);
\r
1275 if ($fsize <= 0) {
\r
1280 $fd = fopen ($filename, 'r');
\r
1281 $contents = fread ($fd, $fsize);
\r
1284 // parse file contents
\r
1285 $parser->parse($contents);
\r
1289 * Outputs a debug message
\r
1291 function debug($msg) {
\r
1292 echo '<p><b>' . $msg . "</b></p>\n";
\r
1296 function addToLog($level, $msg) {
\r
1297 ACTIONLOG::add($level, $msg);
\r
1300 // shows a link to help file
\r
1301 function help($id) {
\r
1302 echo helpHtml($id);
\r
1305 function helpHtml($id) {
\r
1307 return helplink($id) . '<img src="' . $CONF['AdminURL'] . 'documentation/icon-help.gif" width="15" height="15" alt="' . _HELP_TT . '" title="' . _HELP_TT . '" /></a>';
\r
1310 function helplink($id) {
\r
1312 return '<a href="' . $CONF['AdminURL'] . 'documentation/help.html#'. $id . '" onclick="if (event && event.preventDefault) event.preventDefault(); return help(this.href);">';
\r
1315 function getMailFooter() {
\r
1316 $message = "\n\n-----------------------------";
\r
1317 $message .= "\n Powered by Nucleus CMS";
\r
1318 $message .= "\n(http://www.nucleuscms.org/)";
\r
1323 * Returns the name of the language to use
\r
1324 * preference priority: member - site
\r
1325 * defaults to english when no good language found
\r
1327 * checks if file exists, etc...
\r
1329 function getLanguageName() {
\r
1330 global $CONF, $member;
\r
1332 if ($member && $member->isLoggedIn() ) {
\r
1333 // try to use members language
\r
1334 $memlang = $member->getLanguage();
\r
1336 if (($memlang != '') && (checkLanguage($memlang) ) ) {
\r
1341 // use default language
\r
1342 if (checkLanguage($CONF['Language']) ) {
\r
1343 return $CONF['Language'];
\r
1350 * Includes a PHP file. This method can be called while parsing templates and skins
\r
1352 function includephp($filename) {
\r
1353 // make predefined variables global, so most simple scripts can be used here
\r
1355 // apache (names taken from PHP doc)
\r
1356 global $GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE, $SERVER_PROTOCOL;
\r
1357 global $REQUEST_METHOD, $QUERY_STRING, $DOCUMENT_ROOT, $HTTP_ACCEPT;
\r
1358 global $HTTP_ACCEPT_CHARSET, $HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE;
\r
1359 global $HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER, $HTTP_USER_AGENT;
\r
1360 global $REMOTE_ADDR, $REMOTE_PORT, $SCRIPT_FILENAME, $SERVER_ADMIN;
\r
1361 global $SERVER_PORT, $SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME;
\r
1362 global $REQUEST_URI;
\r
1364 // php (taken from PHP doc)
\r
1365 global $argv, $argc, $PHP_SELF, $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS;
\r
1366 global $HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS, $HTTP_SESSION_VARS;
\r
1369 global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;
\r
1371 if (@file_exists($filename) ) {
\r
1372 include($filename);
\r
1377 * Checks if a certain language/plugin exists
\r
1379 function checkLanguage($lang) {
\r
1380 global $DIR_LANG ;
\r
1381 return file_exists($DIR_LANG . ereg_replace( '[\\|/]', '', $lang) . '.php');
\r
1384 function checkPlugin($plug) {
\r
1385 global $DIR_PLUGINS;
\r
1386 return file_exists($DIR_PLUGINS . ereg_replace( '[\\|/]', '', $plug) . '.php');
\r
1390 * Centralisation of the functions that generate links
\r
1392 function createItemLink($itemid, $extra = '') {
\r
1393 return createLink('item', array('itemid' => $itemid, 'extra' => $extra) );
\r
1396 function createMemberLink($memberid, $extra = '') {
\r
1397 return createLink('member', array('memberid' => $memberid, 'extra' => $extra) );
\r
1400 function createCategoryLink($catid, $extra = '') {
\r
1401 return createLink('category', array('catid' => $catid, 'extra' => $extra) );
\r
1404 function createArchiveListLink($blogid = '', $extra = '') {
\r
1405 return createLink('archivelist', array('blogid' => $blogid, 'extra' => $extra) );
\r
1408 function createArchiveLink($blogid, $archive, $extra = '') {
\r
1409 return createLink('archive', array('blogid' => $blogid, 'archive' => $archive, 'extra' => $extra) );
\r
1412 function createBlogidLink($blogid, $params = '') {
\r
1413 return createLink('blog', array('blogid' => $blogid, 'extra' => $params) );
\r
1416 function createLink($type, $params) {
\r
1417 global $manager, $CONF;
\r
1419 $generatedURL = '';
\r
1420 $usePathInfo = ($CONF['URLMode'] == 'pathinfo');
\r
1422 // ask plugins first
\r
1425 if ($usePathInfo) {
\r
1430 'params' => $params,
\r
1431 'completed' => &$created,
\r
1437 // if a plugin created the URL, return it
\r
1442 // default implementation
\r
1445 if ($usePathInfo) {
\r
1446 $url = $CONF['ItemURL'] . '/' . $CONF['ItemKey'] . '/' . $params['itemid'];
\r
1448 $url = $CONF['ItemURL'] . '?itemid=' . $params['itemid'];
\r
1453 if ($usePathInfo) {
\r
1454 $url = $CONF['MemberURL'] . '/' . $CONF['MemberKey'] . '/' . $params['memberid'];
\r
1456 $url = $CONF['MemberURL'] . '?memberid=' . $params['memberid'];
\r
1461 if ($usePathInfo) {
\r
1462 $url = $CONF['CategoryURL'] . '/' . $CONF['CategoryKey'] . '/' . $params['catid'];
\r
1464 $url = $CONF['CategoryURL'] . '?catid=' . $params['catid'];
\r
1468 case 'archivelist':
\r
1469 if (!$params['blogid']) {
\r
1470 $params['blogid'] = $CONF['DefaultBlog'];
\r
1473 if ($usePathInfo) {
\r
1474 $url = $CONF['ArchiveListURL'] . '/' . $CONF['ArchivesKey'] . '/' . $params['blogid'];
\r
1476 $url = $CONF['ArchiveListURL'] . '?archivelist=' . $params['blogid'];
\r
1481 if ($usePathInfo) {
\r
1482 $url = $CONF['ArchiveURL'] . '/' . $CONF['ArchiveKey'] . '/'.$params['blogid'].'/' . $params['archive'];
\r
1484 $url = $CONF['ArchiveURL'] . '?blogid='.$params['blogid'].'&archive=' . $params['archive'];
\r
1489 if ($usePathInfo) {
\r
1490 $url = $CONF['BlogURL'] . '/' . $CONF['BlogKey'] . '/' . $params['blogid'];
\r
1492 $url = $CONF['BlogURL'] . '?blogid=' . $params['blogid'];
\r
1497 return addLinkParams($url, (isset($params['extra'])? $params['extra'] : null));
\r
1500 function createBlogLink($url, $params) {
\r
1502 if ($CONF['URLMode'] == 'normal') {
\r
1503 if (strpos($url, '?') === FALSE && is_array($params)) {
\r
1504 $fParam = reset($params);
\r
1505 $fKey = key($params);
\r
1506 array_shift($params);
\r
1507 $url .= '?' . $fKey . '=' . $fParam;
\r
1509 } elseif ($CONF['URLMode'] == 'pathinfo' && substr($url, -1) == '/') {
\r
1510 $url = substr($url, 0, -1);
\r
1512 return addLinkParams($url, $params);
\r
1515 function addLinkParams($link, $params) {
\r
1518 if (is_array($params) ) {
\r
1520 if ($CONF['URLMode'] == 'pathinfo') {
\r
1522 foreach ($params as $param => $value) {
\r
1523 $link .= '/' . $param . '/' . urlencode($value);
\r
1528 foreach ($params as $param => $value) {
\r
1529 $link .= '&' . $param . '=' . urlencode($value);
\r
1539 * @param $querystr
\r
1540 * querystring to alter (e.g. foo=1&bar=2&x=y)
\r
1542 * name of parameter to change (e.g. 'foo')
\r
1544 * New value for that parameter (e.g. 3)
\r
1546 * altered query string (for the examples above: foo=3&bar=2&x=y)
\r
1548 function alterQueryStr($querystr, $param, $value) {
\r
1549 $vars = explode('&', $querystr);
\r
1552 for ($i = 0; $i < count($vars); $i++) {
\r
1553 $v = explode('=', $vars[$i]);
\r
1555 if ($v[0] == $param) {
\r
1557 $vars[$i] = implode('=', $v);
\r
1564 $vars[] = $param . '=' . $value;
\r
1567 return ltrim(implode('&', $vars), '&');
\r
1570 // passes one variable as hidden input field (multiple fields for arrays)
\r
1571 // @see passRequestVars in varsx.x.x.php
\r
1572 function passVar($key, $value) {
\r
1574 if (is_array($value) ) {
\r
1575 for ($i = 0; $i < sizeof($value); $i++) {
\r
1576 passVar($key . '[' . $i . ']', $value[$i]);
\r
1582 // other values: do stripslashes if needed
\r
1583 ?><input type="hidden" name="<?php echo htmlspecialchars($key)?>" value="<?php echo htmlspecialchars(undoMagic($value) )?>" /><?php
\r
1587 Date format functions (to be used from [%date(..)%] skinvars
\r
1589 function formatDate($format, $timestamp, $defaultFormat, &$blog) {
\r
1590 // apply blog offset (#42)
\r
1591 $boffset = $blog ? $blog->getTimeOffset() * 3600 : 0;
\r
1592 $offset = date('Z', $timestamp) + $boffset;
\r
1594 switch ($format) {
\r
1596 if ($offset >= 0) {
\r
1600 $offset = -$offset;
\r
1603 $tz .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1604 return date('D, j M Y H:i:s ', $timestamp) . $tz;
\r
1607 $timestamp -= $offset;
\r
1608 return date('D, j M Y H:i:s ', $timestamp) . 'GMT';
\r
1611 $timestamp -= $offset;
\r
1612 return date('Y-m-d\TH:i:s\Z', $timestamp);
\r
1615 if ($offset >= 0) {
\r
1619 $offset = -$offset;
\r
1622 $tz .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1623 return date('Y-m-d\TH:i:s', $timestamp) . $tz;
\r
1626 return strftime($format ? $format : $defaultFormat, $timestamp);
\r
1630 function encoding_check($val, $key, $encoding=false, $exclude=false) {
\r
1632 When 3rd argument is set, return if checked already.
\r
1633 When 4th argument is set, set the excluded key(s).
\r
1635 static $search=false, $checked=array(), $excludes=array();
\r
1636 if ($exclude!==false) {
\r
1637 if (is_array($exclude)) {
\r
1638 foreach($exclude as $v) $excludes[$v]=true;
\r
1639 } else $excludes[$exclude]=true;
\r
1642 if ($encoding!==false) {
\r
1643 switch($encoding=strtolower($encoding)){
\r
1645 $search='/([\x00-\x7F]+'.
\r
1646 '|[\xC2-\xDF][\x80-\xBF]'.
\r
1647 '|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]'.
\r
1648 '|[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1649 '|[\xF8-\xFB][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1650 '|[\xFC-\xFD][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF])/';
\r
1653 $search='/([\x00-\x7F]+'.
\r
1654 '|[\x8E][\xA0-\xDF]'.
\r
1655 '|[\x8F]?[\xA1-\xFE][\xA1-\xFE])/';
\r
1658 $search='/([\x00-\x7F]+'.
\r
1659 '|[\xA1-\xF7][\xA1-\xFE])/';
\r
1662 // Note that shift_jis is only supported for output.
\r
1663 // Using shift_jis in DB is prohibited.
\r
1664 $search='/([\x00-\x7F\xA1-\xDF]+'.
\r
1665 '|[\x81-\x9F\xE0-\xFC][\x40-\xFC])/';
\r
1669 if (preg_match('/^iso\-8859\-[0-9]{1,2}$/',$encoding)) break;
\r
1670 if (preg_match('/^windows\-125[0-8]$/',$encoding)) break;
\r
1671 startUpError('<p>Unknown or non-supported encoding.</p>', 'Encoding Error');
\r
1674 if (isset($checked[$encoding])) return true; // Already checked.
\r
1675 $checked[$encoding]=true;
\r
1677 if ($key===false) return false; // Not yet checked.
\r
1678 if ($search===false) return true; // non-multibyte encoding
\r
1679 if (isset($excludes[$key])) return true; // This key isn't checked.
\r
1680 if (is_array($val)) {
\r
1681 array_walk($val, 'encoding_check');
\r
1683 $result=preg_replace($search,'',$val);
\r
1684 if (strlen($result)!=0) {
\r
1685 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1689 $result=preg_replace($search,'',$key);
\r
1690 if (strlen($result)!=0) {
\r
1691 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1697 function checkVars($aVars) {
\r
1698 global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;
\r
1700 foreach ($aVars as $varName) {
\r
1702 if (phpversion() >= '4.1.0') {
\r
1704 if ( isset($_GET[$varName])
\r
1705 || isset($_POST[$varName])
\r
1706 || isset($_COOKIE[$varName])
\r
1707 || isset($_ENV[$varName])
\r
1708 || isset($_SESSION[$varName])
\r
1709 || isset($_FILES[$varName])
\r
1711 die('Sorry. An error occurred.');
\r
1716 if ( isset($HTTP_GET_VARS[$varName])
\r
1717 || isset($HTTP_POST_VARS[$varName])
\r
1718 || isset($HTTP_COOKIE_VARS[$varName])
\r
1719 || isset($HTTP_ENV_VARS[$varName])
\r
1720 || isset($HTTP_SESSION_VARS[$varName])
\r
1721 || isset($HTTP_POST_FILES[$varName])
\r
1723 die('Sorry. An error occurred.');
\r
1732 * Sanitize parameters such as $_GET and $_SERVER['REQUEST_URI'] etc.
\r
1735 function sanitizeParams()
\r
1737 global $HTTP_SERVER_VARS;
\r
1743 // REQUEST_URI of $HTTP_SERVER_VARS
\r
1744 $str =& $HTTP_SERVER_VARS["REQUEST_URI"];
\r
1745 serverStringToArray($str, $array, $frontParam);
\r
1746 sanitizeArray($array);
\r
1747 arrayToServerString($array, $frontParam, $str);
\r
1749 // QUERY_STRING of $HTTP_SERVER_VARS
\r
1750 $str =& $HTTP_SERVER_VARS["QUERY_STRING"];
\r
1751 serverStringToArray($str, $array, $frontParam);
\r
1752 sanitizeArray($array);
\r
1753 arrayToServerString($array, $frontParam, $str);
\r
1755 if (phpversion() >= '4.1.0') {
\r
1756 // REQUEST_URI of $_SERVER
\r
1757 $str =& $_SERVER["REQUEST_URI"];
\r
1758 serverStringToArray($str, $array, $frontParam);
\r
1759 sanitizeArray($array);
\r
1760 arrayToServerString($array, $frontParam, $str);
\r
1762 // QUERY_STRING of $_SERVER
\r
1763 $str =& $_SERVER["QUERY_STRING"];
\r
1764 serverStringToArray($str, $array, $frontParam);
\r
1765 sanitizeArray($array);
\r
1766 arrayToServerString($array, $frontParam, $str);
\r
1770 convArrayForSanitizing($_GET, $array);
\r
1771 sanitizeArray($array);
\r
1772 revertArrayForSanitizing($array, $_GET);
\r
1774 // $_REQUEST (only GET param)
\r
1775 convArrayForSanitizing($_REQUEST, $array);
\r
1776 sanitizeArray($array);
\r
1777 revertArrayForSanitizing($array, $_REQUEST);
\r
1781 * Check ticket when not checked in plugin's admin page
\r
1783 * Also avoid the access to plugin/index.php by guest user.
\r
1785 function ticketForPlugin(){
\r
1786 global $CONF,$DIR_PLUGINS,$member,$ticketforplugin;
\r
1789 $ticketforplugin=array();
\r
1790 $ticketforplugin['ticket']=false;
\r
1792 /* Check if using plugin's php file. */
\r
1793 if ($p_translated=serverVar('PATH_TRANSLATED')) {
\r
1794 if (!file_exists($p_translated)) $p_translated='';
\r
1796 if (!$p_translated) {
\r
1797 $p_translated=serverVar('SCRIPT_FILENAME');
\r
1798 if (!file_exists($p_translated)) {
\r
1799 header("HTTP/1.0 404 Not Found");
\r
1803 $p_translated=str_replace('\\','/',$p_translated);
\r
1804 $d_plugins=str_replace('\\','/',$DIR_PLUGINS);
\r
1805 if (strpos($p_translated,$d_plugins)!==0) return;// This isn't plugin php file.
\r
1807 /* Solve the plugin php file or admin directory */
\r
1808 $phppath=substr($p_translated,strlen($d_plugins));
\r
1809 $phppath=preg_replace('!^/!','',$phppath);// Remove the first "/" if exists.
\r
1810 $path=preg_replace('/^NP_(.*)\.php$/','$1',$phppath); // Remove the first "NP_" and the last ".php" if exists.
\r
1811 $path=preg_replace('!^([^/]*)/(.*)$!','$1',$path); // Remove the "/" and beyond.
\r
1813 /* Solve the plugin name. */
\r
1815 $query='SELECT pfile FROM '.sql_table('plugin');
\r
1816 $res=sql_query($query);
\r
1817 while($row=sql_fetch_row($res)) {
\r
1818 $name=substr($row[0],3);
\r
1819 $plugins[strtolower($name)]=$name;
\r
1821 sql_free_result($res);
\r
1822 if ($plugins[$path]) $plugin_name=$plugins[$path];
\r
1823 else if (in_array($path,$plugins)) $plugin_name=$path;
\r
1825 header("HTTP/1.0 404 Not Found");
\r
1829 /* Return if not index.php */
\r
1830 if ( $phppath!=strtolower($plugin_name).'/'
\r
1831 && $phppath!=strtolower($plugin_name).'/index.php' ) return;
\r
1833 /* Exit if not logged in. */
\r
1834 if ( !$member->isLoggedIn() ) exit(_GFUNCTIONS_YOU_AERNT_LOGGEDIN);
\r
1836 global $manager,$DIR_LIBS,$DIR_LANG,$HTTP_GET_VARS,$HTTP_POST_VARS;
\r
1838 /* Check if this feature is needed (ie, if "$manager->checkTicket()" is not included in the script). */
\r
1839 if (!($p_translated=serverVar('PATH_TRANSLATED'))) $p_translated=serverVar('SCRIPT_FILENAME');
\r
1840 if ($file=@file($p_translated)) {
\r
1842 foreach($file as $line) {
\r
1843 if (preg_match('/[\$]manager([\s]*)[\-]>([\s]*)checkTicket([\s]*)[\(]/i',$prevline.$line)) return;
\r
1848 /* Show a form if not valid ticket */
\r
1849 if ( ( strstr(serverVar('REQUEST_URI'),'?') || serverVar('QUERY_STRING')
\r
1850 || strtoupper(serverVar('REQUEST_METHOD'))=='POST' )
\r
1851 && (!$manager->checkTicket()) ){
\r
1853 if (!class_exists('PluginAdmin')) {
\r
1854 $language = getLanguageName();
\r
1855 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
\r
1856 include($DIR_LIBS . 'PLUGINADMIN.php');
\r
1858 if (!(function_exists('mb_strimwidth') || extension_loaded('mbstring'))) {
\r
1859 if (file_exists($DIR_LIBS.'mb_emulator/mb-emulator.php')) {
\r
1860 global $mbemu_internals;
\r
1861 include_once($DIR_LIBS.'mb_emulator/mb-emulator.php');
\r
1864 $oPluginAdmin = new PluginAdmin($plugin_name);
\r
1865 $oPluginAdmin->start();
\r
1866 echo '<p>' . _ERROR_BADTICKET . "</p>\n";
\r
1868 /* Show the form to confirm action */
\r
1869 // PHP 4.0.x support
\r
1870 $get= (isset($_GET)) ? $_GET : $HTTP_GET_VARS;
\r
1871 $post= (isset($_POST)) ? $_POST : $HTTP_POST_VARS;
\r
1872 // Resolve URI and QUERY_STRING
\r
1873 if ($uri=serverVar('REQUEST_URI')) {
\r
1874 list($uri,$qstring)=explode('?',$uri);
\r
1876 if ( !($uri=serverVar('PHP_SELF')) ) $uri=serverVar('SCRIPT_NAME');
\r
1877 $qstring=serverVar('QUERY_STRING');
\r
1879 if ($qstring) $qstring='?'.$qstring;
\r
1880 echo '<p>'._SETTINGS_UPDATE.' : '._QMENU_PLUGINS.' <span style="color:red;">'.
\r
1881 htmlspecialchars($plugin_name)."</span> ?</p>\n";
\r
1882 switch(strtoupper(serverVar('REQUEST_METHOD'))){
\r
1884 echo '<form method="POST" action="'.htmlspecialchars($uri.$qstring).'">';
\r
1885 $manager->addTicketHidden();
\r
1886 _addInputTags($post);
\r
1889 echo '<form method="GET" action="'.htmlspecialchars($uri).'">';
\r
1890 $manager->addTicketHidden();
\r
1891 _addInputTags($get);
\r
1895 echo '<input type="submit" value="'._YES.'" /> ';
\r
1896 echo '<input type="button" value="'._NO.'" onclick="history.back(); return false;" />';
\r
1899 $oPluginAdmin->end();
\r
1903 /* Create new ticket */
\r
1904 $ticket=$manager->addTicketToUrl('');
\r
1905 $ticketforplugin['ticket']=substr($ticket,strpos($ticket,'ticket=')+7);
\r
1907 function _addInputTags(&$keys,$prefix=''){
\r
1908 foreach($keys as $key=>$value){
\r
1909 if ($prefix) $key=$prefix.'['.$key.']';
\r
1910 if (is_array($value)) _addInputTags($value,$key);
\r
1912 if (get_magic_quotes_gpc()) $value=stripslashes($value);
\r
1913 if ($key=='ticket') continue;
\r
1914 echo '<input type="hidden" name="'.htmlspecialchars($key).
\r
1915 '" value="'.htmlspecialchars($value).'" />'."\n";
\r
1921 * Convert the server string such as $_SERVER['REQUEST_URI']
\r
1922 * to arry like arry['blogid']=1 and array['page']=2 etc.
\r
1924 function serverStringToArray($str, &$array, &$frontParam)
\r
1930 // split front param, e.g. /index.php, and others, e.g. blogid=1&page=2
\r
1931 if (strstr($str, "?")){
\r
1932 list($frontParam, $args) = preg_split("/\?/", $str, 2);
\r
1939 // If there is no args like blogid=1&page=2, return
\r
1940 if (!strstr($str, "=") && !strlen($frontParam)) {
\r
1941 $frontParam = $str;
\r
1945 $array = explode("&", $args);
\r
1949 * Convert array like array['blogid'] to server string
\r
1950 * such as $_SERVER['REQUEST_URI']
\r
1952 function arrayToServerString($array, $frontParam, &$str)
\r
1954 if (strstr($str, "?")) {
\r
1955 $str = $frontParam . "?";
\r
1957 $str = $frontParam;
\r
1959 if (count($array)) {
\r
1960 $str .= implode("&", $array);
\r
1965 * Sanitize array parameters.
\r
1966 * This function checks both key and value.
\r
1967 * - check key if it inclues " (double quote), remove from array
\r
1968 * - check value if it includes \ (escape sequece), remove remaining string
\r
1970 function sanitizeArray(&$array)
\r
1972 $excludeListForSanitization = array('query');
\r
1973 // $excludeListForSanitization = array();
\r
1975 foreach ($array as $k => $v) {
\r
1977 // split to key and value
\r
1978 list($key, $val) = preg_split("/=/", $v, 2);
\r
1979 if (!isset($val)) {
\r
1983 // when magic quotes is on, need to use stripslashes,
\r
1984 // and then addslashes
\r
1985 if (get_magic_quotes_gpc()) {
\r
1986 $val = stripslashes($val);
\r
1988 $val = addslashes($val);
\r
1990 // if $key is included in exclude list, skip this param
\r
1991 if (!in_array($key, $excludeListForSanitization)) {
\r
1994 if (strpos($val, '\\')) {
\r
1995 list($val, $tmp) = explode('\\', $val);
\r
1998 // remove control code etc.
\r
1999 $val = strtr($val, "\0\r\n<>'\"", " ");
\r
2002 if (preg_match('/\"/i', $key)) {
\r
2003 unset($array[$k]);
\r
2007 // set sanitized info
\r
2008 $array[$k] = sprintf("%s=%s", $key, $val);
\r
2014 * Convert array for sanitizeArray function
\r
2016 function convArrayForSanitizing($src, &$array)
\r
2019 foreach ($src as $key => $val) {
\r
2020 if (key_exists($key, $_GET)) {
\r
2021 array_push($array, sprintf("%s=%s", $key, $val));
\r
2027 * Revert array after sanitizeArray function
\r
2029 function revertArrayForSanitizing($array, &$dst)
\r
2031 foreach ($array as $v) {
\r
2032 list($key, $val) = preg_split("/=/", $v, 2);
\r
2033 $dst[$key] = $val;
\r
2038 * Stops processing the request and redirects to the given URL.
\r
2039 * - no actual contents should have been sent to the output yet
\r
2040 * - the URL will be stripped of illegal or dangerous characters
\r
2042 function redirect($url) {
\r
2043 $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%*]|i', '', $url);
\r
2044 header('Location: ' . $url);
\r
2049 * Strip HTML tags from a string
\r
2050 * This function is a bit more intelligent than a regular call to strip_tags(),
\r
2051 * because it also deletes the contents of certain tags and cleans up any
\r
2052 * unneeded whitespace.
\r
2054 function stringStripTags ($string) {
\r
2055 $string = preg_replace("/<del[^>]*>.+<\/del[^>]*>/isU", '', $string);
\r
2056 $string = preg_replace("/<script[^>]*>.+<\/script[^>]*>/isU", '', $string);
\r
2057 $string = preg_replace("/<style[^>]*>.+<\/style[^>]*>/isU", '', $string);
\r
2058 $string = str_replace('>', '> ', $string);
\r
2059 $string = str_replace('<', ' <', $string);
\r
2060 $string = strip_tags($string);
\r
2061 $string = preg_replace("/\s+/", " ", $string);
\r
2062 $string = trim($string);
\r
2067 * Make a string containing HTML safe for use in a HTML attribute
\r
2068 * Tags are stripped and entities are normalized
\r
2070 function stringToAttribute ($string) {
\r
2071 $string = stringStripTags($string);
\r
2072 $string = entity::named_to_numeric($string);
\r
2073 $string = entity::normalize_numeric($string);
\r
2075 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2076 $string = entity::numeric_to_utf8($string);
\r
2079 $string = entity::specialchars($string, 'html');
\r
2080 $string = entity::numeric_to_named($string);
\r
2085 * Make a string containing HTML safe for use in a XML document
\r
2086 * Tags are stripped, entities are normalized and named entities are
\r
2087 * converted to numeric entities.
\r
2089 function stringToXML ($string) {
\r
2090 $string = stringStripTags($string);
\r
2091 $string = entity::named_to_numeric($string);
\r
2092 $string = entity::normalize_numeric($string);
\r
2094 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2095 $string = entity::numeric_to_utf8($string);
\r
2098 $string = entity::specialchars($string, 'xml');
\r
2102 // START: functions from the end of file BLOG.php
\r
2103 // used for mail notification (html -> text)
\r
2104 function toAscii($html) {
\r
2105 // strip off most tags
\r
2106 $html = strip_tags($html,'<a>');
\r
2107 $to_replace = "/<a[^>]*href=[\"\']([^\"^']*)[\"\'][^>]*>([^<]*)<\/a>/i";
\r
2109 $ascii = preg_replace_callback ($to_replace, '_links_add', $html);
\r
2110 $ascii .= "\n\n" . _links_list();
\r
2111 return strip_tags($ascii);
\r
2114 function _links_init() {
\r
2115 global $tmp_links;
\r
2116 $tmp_links = array();
\r
2119 function _links_add($match) {
\r
2120 global $tmp_links;
\r
2121 array_push($tmp_links, $match[1]);
\r
2122 return $match[2] . ' [' . sizeof($tmp_links) .']';
\r
2125 function _links_list() {
\r
2126 global $tmp_links;
\r
2129 foreach ($tmp_links as $current) {
\r
2130 $output .= "[$i] $current\n";
\r
2135 // END: functions from the end of file BLOG.php
\r
2137 // START: functions from the end of file ADMIN.php
\r
2139 * @todo document this
\r
2141 function encode_desc(&$data)
\r
2143 // _$to_entities = get_html_translation_table(HTML_ENTITIES);
\r
2144 $to_entities = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
2145 $from_entities = array_flip($to_entities);
\r
2146 $data = str_replace('<br />', '\n', $data); //hack
\r
2147 $data = strtr($data,$from_entities);
\r
2148 $data = strtr($data,$to_entities);
\r
2149 $data = str_replace('\n', '<br />', $data); //hack
\r
2154 * Returns the Javascript code for a bookmarklet that works on most modern browsers
\r
2158 function getBookmarklet($blogid) {
\r
2162 $document = 'document';
\r
2163 $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
2164 $bookmarkletline .= $CONF['AdminURL'] . "bookmarklet.php?blogid=$blogid";
\r
2165 $bookmarkletline .="&logtext='+escape(Q)+'&loglink='+escape(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
2167 return $bookmarkletline;
\r
2169 // END: functions from the end of file ADMIN.php
\r
2172 * Returns a variable or null if not set
\r
2174 * @param mixed Variable
\r
2175 * @return mixed Variable
\r
2177 function ifset(&$var) {
\r
2178 if (isset($var)) {
\r
2186 * Returns number of subscriber to an event
\r
2189 * @return number of subscriber(s)
\r
2191 function numberOfEventSubscriber($event) {
\r
2192 $query = 'SELECT COUNT(*) as count FROM ' . sql_table('plugin_event') . ' WHERE event=\'' . $event . '\'';
\r
2193 $res = sql_query($query);
\r
2194 $obj = sql_fetch_object($res);
\r
2195 return $obj->count;
\r
2198 function selectSpecialSkinType($id) {
\r
2200 $special = strtolower($id);
\r