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.5SVN';
\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 include_once($DIR_LIBS . 'sql/'.$MYSQL_HANDLER[0].'.php');
\r
122 // end new for 3.5 sql_* wrapper
\r
123 include_once($DIR_LIBS . 'mysql.php');
\r
124 include($DIR_LIBS . 'MEMBER.php');
\r
125 include($DIR_LIBS . 'ACTIONLOG.php');
\r
126 include($DIR_LIBS . 'MANAGER.php');
\r
127 include($DIR_LIBS . 'PLUGIN.php');
\r
129 $manager =& MANAGER::instance();
\r
131 // make sure there's no unnecessary escaping:
\r
132 set_magic_quotes_runtime(0);
\r
135 if (!isset($CONF['UsingAdminArea'])) {
\r
136 $CONF['UsingAdminArea'] = 0;
\r
139 // only needed when updating logs
\r
140 if ($CONF['UsingAdminArea']) {
\r
141 include($DIR_LIBS . 'xmlrpc.inc.php'); // XML-RPC client classes
\r
142 include_once($DIR_LIBS . 'ADMIN.php');
\r
145 // connect to database
\r
149 // logs sanitized result if need
\r
150 if ($orgRequestURI!==serverVar('REQUEST_URI')) {
\r
151 $msg = "Sanitized [" . serverVar('REMOTE_ADDR') . "] ";
\r
152 $msg .= $orgRequestURI . " -> " . serverVar('REQUEST_URI');
\r
153 if ($bLoggingSanitizedResult) {
\r
154 addToLog(WARNING, $msg);
\r
156 if (!$bSanitizeAndContinue) {
\r
161 // makes sure database connection gets closed on script termination
\r
162 register_shutdown_function('sql_disconnect');
\r
167 // Properly set $CONF['Self'] and others if it's not set... usually when we are access from admin menu
\r
168 if (!isset($CONF['Self'])) {
\r
169 $CONF['Self'] = $CONF['IndexURL'];
\r
170 // strip trailing /
\r
171 if ($CONF['Self'][strlen($CONF['Self']) -1] == "/") {
\r
172 $CONF['Self'] = substr($CONF['Self'], 0, strlen($CONF['Self']) -1);
\r
175 /* $CONF['ItemURL'] = $CONF['Self'];
\r
176 $CONF['ArchiveURL'] = $CONF['Self'];
\r
177 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
178 $CONF['MemberURL'] = $CONF['Self'];
\r
179 $CONF['SearchURL'] = $CONF['Self'];
\r
180 $CONF['BlogURL'] = $CONF['Self'];
\r
181 $CONF['CategoryURL'] = $CONF['Self'];*/
\r
184 $CONF['ItemURL'] = $CONF['Self'];
\r
185 $CONF['ArchiveURL'] = $CONF['Self'];
\r
186 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
187 $CONF['MemberURL'] = $CONF['Self'];
\r
188 $CONF['SearchURL'] = $CONF['Self'];
\r
189 $CONF['BlogURL'] = $CONF['Self'];
\r
190 $CONF['CategoryURL'] = $CONF['Self'];
\r
192 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
193 // this avoids urls like index.php/item/13/index.php/item/15
\r
194 if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
\r
195 $CONF['URLMode'] = 'normal';
\r
198 // automatically use simpler toolbar for mozilla
\r
199 if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'), 'Gecko') ) {
\r
200 $CONF['DisableJsTools'] = 2;
\r
203 // login if cookies set
\r
204 $member = new MEMBER();
\r
206 // secure cookie key settings (either 'none', 0, 8, 16, 24, or 32)
\r
207 if (!isset($CONF['secureCookieKey'])) $CONF['secureCookieKey']=24;
\r
208 switch($CONF['secureCookieKey']){
\r
210 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
213 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
216 $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
\r
219 $CONF['secureCookieKeyIP']=serverVar('REMOTE_ADDR');
\r
222 $CONF['secureCookieKeyIP']='';
\r
225 // login/logout when required or renew cookies
\r
226 if ($action == 'login') {
\r
227 // Form Authentication
\r
228 $login = postVar('login');
\r
229 $pw = postVar('password');
\r
230 $shared = intPostVar('shared'); // shared computer or not
\r
232 $pw=substr($pw,0,40); // avoid md5 collision by using a long key
\r
234 if ($member->login($login, $pw) ) {
\r
236 $member->newCookieKey();
\r
237 $member->setCookies($shared);
\r
239 if ($CONF['secureCookieKey']!=='none') {
\r
240 // secure cookie key
\r
241 $member->setCookieKey(md5($member->getCookieKey().$CONF['secureCookieKeyIP']));
\r
245 // allows direct access to parts of the admin area after logging in
\r
247 $action = $nextaction;
\r
250 $manager->notify('LoginSuccess', array('member' => &$member, 'username' => $login) );
\r
251 $errormessage = '';
\r
252 ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");
\r
254 // errormessage for [%errordiv%]
\r
255 $errormessage = 'Login failed for ' . $login;
\r
257 $manager->notify('LoginFailed', array('username' => $login) );
\r
258 ACTIONLOG::add(INFO, $errormessage);
\r
262 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
264 } elseif (serverVar('PHP_AUTH_USER') && serverVar('PHP_AUTH_PW')) {
\r
265 // HTTP Authentication
\r
266 $login = serverVar('PHP_AUTH_USER');
\r
267 $pw = serverVar('PHP_AUTH_PW');
\r
269 if ($member->login($login, $pw) ) {
\r
270 $manager->notify('LoginSuccess',array('member' => &$member));
\r
271 ACTIONLOG::add(INFO, "HTTP authentication successful for $login");
\r
273 $manager->notify('LoginFailed',array('username' => $login));
\r
274 ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);
\r
276 //Since bad credentials, generate an apropriate error page
\r
277 header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");
\r
278 header('HTTP/1.0 401 Unauthorized');
\r
279 echo 'Invalid username or password';
\r
284 } elseif (($action == 'logout') && (!headers_sent() ) && cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
285 // remove cookies on logout
\r
286 setcookie($CONF['CookiePrefix'] . 'user', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
287 setcookie($CONF['CookiePrefix'] . 'loginkey', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
288 $manager->notify('Logout', array('username' => cookieVar($CONF['CookiePrefix'] . 'user') ) );
\r
289 } elseif (cookieVar($CONF['CookiePrefix'] . 'user') ) {
\r
290 // Cookie Authentication
\r
291 $ck=cookieVar($CONF['CookiePrefix'] . 'loginkey');
\r
292 // secure cookie key
\r
293 $ck=substr($ck,0,32); // avoid md5 collision by using a long key
\r
294 if ($CONF['secureCookieKey']!=='none') $ck=md5($ck.$CONF['secureCookieKeyIP']);
\r
295 $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), $ck );
\r
298 // renew cookies when not on a shared computer
\r
299 if ($res && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) && (!headers_sent() ) ) {
\r
300 $member->setCookieKey(cookieVar($CONF['CookiePrefix'] . 'loginkey'));
\r
301 $member->setCookies();
\r
306 $manager->notify('PostAuthentication', array('loggedIn' => $member->isLoggedIn() ) );
\r
309 // first, let's see if the site is disabled or not. always allow admin area access.
\r
310 if ($CONF['DisableSite'] && !$member->isAdmin() && !$CONF['UsingAdminArea']) {
\r
311 redirect($CONF['DisableSiteURL']);
\r
315 // load other classes
\r
316 include($DIR_LIBS . 'PARSER.php');
\r
317 include($DIR_LIBS . 'SKIN.php');
\r
318 include($DIR_LIBS . 'TEMPLATE.php');
\r
319 include($DIR_LIBS . 'BLOG.php');
\r
320 include($DIR_LIBS . 'BODYACTIONS.php');
\r
321 include($DIR_LIBS . 'COMMENTS.php');
\r
322 include($DIR_LIBS . 'COMMENT.php');
\r
323 //include($DIR_LIBS . 'ITEM.php');
\r
324 include($DIR_LIBS . 'NOTIFICATION.php');
\r
325 include($DIR_LIBS . 'BAN.php');
\r
326 include($DIR_LIBS . 'PAGEFACTORY.php');
\r
327 include($DIR_LIBS . 'SEARCH.php');
\r
328 include($DIR_LIBS . 'entity.php');
\r
331 // set lastVisit cookie (if allowed)
\r
332 if (!headers_sent() ) {
\r
333 if ($CONF['LastVisit']) {
\r
334 setcookie($CONF['CookiePrefix'] . 'lastVisit', time(), time() + 2592000, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
336 setcookie($CONF['CookiePrefix'] . 'lastVisit', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
\r
340 // read language file, only after user has been initialized
\r
341 $language = getLanguageName();
\r
342 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
\r
344 // check if valid charset
\r
345 if (!encoding_check(false, false, _CHARSET)) {
\r
346 foreach(array($_GET, $_POST) as $input) {
\r
347 array_walk($input, 'encoding_check');
\r
352 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
354 // To remove after v2.5 is released and language files have been updated.
\r
355 // Including this makes sure that language files for v2.5beta can still be used for v2.5final
\r
356 // without having weird _SETTINGS_EXTAUTH string showing up in the admin area.
\r
357 if (!defined('_MEMBERS_BYPASS'))
\r
359 define('_SETTINGS_EXTAUTH', 'Enable External Authentication');
\r
360 define('_WARNING_EXTAUTH', 'Warning: Enable only if needed.');
\r
361 define('_MEMBERS_BYPASS', 'Use External Authentication');
\r
366 // make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined
\r
367 if (!defined('_ARCHIVETYPE_MONTH') ) {
\r
368 define('_ARCHIVETYPE_DAY', 'day');
\r
369 define('_ARCHIVETYPE_MONTH', 'month');
\r
370 define('_ARCHIVETYPE_YEAR', 'year');
\r
373 // decode path_info
\r
374 if ($CONF['URLMode'] == 'pathinfo') {
\r
375 // initialize keywords if this hasn't been done before
\r
376 if (!isset($CONF['ItemKey']) || $CONF['ItemKey'] == '') {
\r
377 $CONF['ItemKey'] = 'item';
\r
380 if (!isset($CONF['ArchiveKey']) || $CONF['ArchiveKey'] == '') {
\r
381 $CONF['ArchiveKey'] = 'archive';
\r
384 if (!isset($CONF['ArchivesKey']) || $CONF['ArchivesKey'] == '') {
\r
385 $CONF['ArchivesKey'] = 'archives';
\r
388 if (!isset($CONF['MemberKey']) || $CONF['MemberKey'] == '') {
\r
389 $CONF['MemberKey'] = 'member';
\r
392 if (!isset($CONF['BlogKey']) || $CONF['BlogKey'] == '') {
\r
393 $CONF['BlogKey'] = 'blog';
\r
396 if (!isset($CONF['CategoryKey']) || $CONF['CategoryKey'] == '') {
\r
397 $CONF['CategoryKey'] = 'category';
\r
400 if (!isset($CONF['SpecialskinKey']) || $CONF['SpecialskinKey'] == '') {
\r
401 $CONF['SpecialskinKey'] = 'special';
\r
408 'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...
\r
409 'info' => $virtualpath,
\r
410 'complete' => &$parsed
\r
415 // default implementation
\r
416 $data = explode("/", $virtualpath );
\r
417 for ($i = 0; $i < sizeof($data); $i++) {
\r
418 switch ($data[$i]) {
\r
419 case $CONF['ItemKey']: // item/1 (blogid)
\r
422 if ($i < sizeof($data) ) {
\r
423 $itemid = intval($data[$i]);
\r
427 case $CONF['ArchivesKey']: // archives/1 (blogid)
\r
430 if ($i < sizeof($data) ) {
\r
431 $archivelist = intval($data[$i]);
\r
435 case $CONF['ArchiveKey']: // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)
\r
436 if ((($i + 1) < sizeof($data) ) && (!strstr($data[$i + 1], '-') ) ) {
\r
437 $blogid = intval($data[++$i]);
\r
442 if ($i < sizeof($data) ) {
\r
443 $archive = $data[$i];
\r
447 case 'blogid': // blogid/1
\r
448 case $CONF['BlogKey']: // blog/1
\r
451 if ($i < sizeof($data) ) {
\r
452 $blogid = intval($data[$i]);
\r
456 case $CONF['CategoryKey']: // category/1 (catid)
\r
460 if ($i < sizeof($data) ) {
\r
461 $catid = intval($data[$i]);
\r
465 case $CONF['MemberKey']:
\r
468 if ($i < sizeof($data) ) {
\r
469 $memberid = intval($data[$i]);
\r
473 case $CONF['SpecialskinKey']:
\r
476 if ($i < sizeof($data) ) {
\r
477 $_REQUEST['special'] = $data[$i];
\r
488 function intPostVar($name) {
\r
489 return intval(postVar($name) );
\r
492 function intGetVar($name) {
\r
493 return intval(getVar($name) );
\r
496 function intRequestVar($name) {
\r
497 return intval(requestVar($name) );
\r
500 function intCookieVar($name) {
\r
501 return intval(cookieVar($name) );
\r
505 * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)
\r
507 function getNucleusVersion() {
\r
512 * power users can install patches in between nucleus releases. These patches
\r
513 * usually add new functionality in the plugin API and allow those to
\r
514 * be tested without having to install CVS.
\r
516 function getNucleusPatchLevel() {
\r
521 * returns the latest version available for download from nucleuscms.org
\r
522 * or false if unable to attain data
\r
523 * format will be major.minor/patachlevel
\r
524 * e.g. 3.41 or 3.41/02
\r
526 function getLatestVersion() {
\r
527 if (!function_exists('curl_init')) return false;
\r
528 $crl = curl_init();
\r
530 curl_setopt ($crl, CURLOPT_URL,'http://nucleuscms.org/version_check.php');
\r
531 curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);
\r
532 curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);
\r
533 $ret = curl_exec($crl);
\r
540 * Connects to mysql server
\r
542 /* moved to $DIR_LIBS/sql/*.php handler files
\r
543 function sql_connect() {
\r
544 global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE, $MYSQL_CONN;
\r
546 $MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>', 'Connect Error');
\r
547 mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: ' . mysql_error() . '</p>', 'Connect Error');
\r
549 return $MYSQL_CONN;
\r
553 * returns a prefixed nucleus table name
\r
555 function sql_table($name) {
\r
556 global $MYSQL_PREFIX;
\r
558 if ($MYSQL_PREFIX) {
\r
559 return $MYSQL_PREFIX . 'nucleus_' . $name;
\r
561 return 'nucleus_' . $name;
\r
565 function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
\r
566 global $manager, $CONF;
\r
568 if (!headers_sent() ) {
\r
569 // if content type is application/xhtml+xml, only send it to browsers
\r
570 // that can handle it (IE6 cannot). Otherwise, send text/html
\r
572 // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)
\r
573 // application/xhtml+xml still causes too much problems with the javascript implementations
\r
575 // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,
\r
576 // application/xhtml+xml seems to be working, so we're going to use it if we can.
\r
578 // Note: reverted the following function in JP version
\r
583 ($contenttype == 'application/xhtml+xml')
\r
584 && (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )
\r
586 $contenttype = 'text/html';
\r
591 ($contenttype == 'application/xhtml+xml')
\r
592 && (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))
\r
595 $contenttype = 'text/html';
\r
599 'PreSendContentType',
\r
601 'contentType' => &$contenttype,
\r
602 'charset' => &$charset,
\r
603 'pageType' => $pagetype
\r
607 // strip strange characters
\r
608 $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);
\r
609 $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);
\r
611 if ($charset != '') {
\r
612 header('Content-Type: ' . $contenttype . '; charset=' . $charset);
\r
614 header('Content-Type: ' . $contenttype);
\r
617 // check if valid charset
\r
618 if (!encoding_check(false,false,$charset)) {
\r
619 foreach(array($_GET, $_POST) as $input) {
\r
620 array_walk($input, 'encoding_check');
\r
627 * Errors before the database connection has been made - moved to
\r
629 /* moved to $DIR_LIBS/sql/*.php handler files
\r
630 function startUpError($msg, $title) {
\r
631 if (!defined('_CHARSET')) define('_CHARSET', 'iso-8859-1');
\r
632 header('Content-Type: text/html; charset=' . _CHARSET);
\r
634 <html <?php echo _HTML_XML_NAME_SPACE_AND_LANG_CODE; ?>>
\r
635 <head><meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET?>" />
\r
636 <title><?php echo htmlspecialchars($title)?></title></head>
\r
638 <h1><?php echo htmlspecialchars($title)?></h1>
\r
646 * disconnects from SQL server
\r
648 /* moved to $DIR_LIBS/sql/*.php handler files
\r
649 function sql_disconnect() {
\r
654 * executes an SQL query
\r
656 /* moved to $DIR_LIBS/sql/*.php handler files
\r
657 function sql_query($query) {
\r
660 $res = mysql_query($query) or print("mySQL error with query $query: " . mysql_error() . '<p />');
\r
666 * Highlights a specific query in a given HTML text (not within HTML tags) and returns it
\r
669 * text to be highlighted
\r
670 * @param $expression
\r
671 * regular expression to be matched (can be an array of expressions as well)
\r
672 * @param $highlight
\r
673 * highlight to be used (use \\0 to indicate the matched expression)
\r
676 function highlight($text, $expression, $highlight) {
\r
677 if (!$highlight || !$expression) {
\r
681 if (is_array($expression) && (count($expression) == 0) ) {
\r
685 // add a tag in front (is needed for preg_match_all to work correct)
\r
686 $text = '<!--h-->' . $text;
\r
688 // split the HTML up so we have HTML tags
\r
689 // $matches[0][i] = HTML + text
\r
690 // $matches[1][i] = HTML
\r
691 // $matches[2][i] = text
\r
692 preg_match_all('/(<[^>]+>)([^<>]*)/', $text, $matches);
\r
694 // throw it all together again while applying the highlight to the text pieces
\r
696 for ($i = 0; $i < sizeof($matches[2]); $i++) {
\r
698 $result .= $matches[1][$i];
\r
701 if (is_array($expression) ) {
\r
702 foreach ($expression as $regex) {
\r
704 $matches[2][$i] = @eregi_replace($regex, $highlight, $matches[2][$i]);
\r
708 $result .= $matches[2][$i];
\r
710 $result .= @eregi_replace($expression, $highlight, $matches[2][$i]);
\r
718 * Parses a query into an array of expressions that can be passed on to the highlight method
\r
720 function parseHighlight($query) {
\r
721 // TODO: add more intelligent splitting logic
\r
723 // get rid of quotes
\r
724 $query = preg_replace('/\'|"/', '', $query);
\r
730 $aHighlight = explode(' ', $query);
\r
732 for ($i = 0; $i < count($aHighlight); $i++) {
\r
733 $aHighlight[$i] = trim($aHighlight[$i]);
\r
735 // if (strlen($aHighlight[$i]) < 3) {
\r
736 // unset($aHighlight[$i]);
\r
740 if (count($aHighlight) == 1) {
\r
741 return $aHighlight[0];
\r
743 return $aHighlight;
\r
748 * Checks if email address is valid
\r
750 function isValidMailAddress($address) {
\r
751 if (preg_match('/^[a-zA-Z+0-9\._-]+@[a-zA-Z0-9\._-]+\.[A-Za-z]{2,5}$/', $address)) {
\r
759 // some helper functions
\r
760 function getBlogIDFromName($name) {
\r
761 return quickQuery('SELECT bnumber as result FROM ' . sql_table('blog') . ' WHERE bshortname="' . addslashes($name) . '"');
\r
764 function getBlogNameFromID($id) {
\r
765 return quickQuery('SELECT bname as result FROM ' . sql_table('blog') . ' WHERE bnumber=' . intval($id) );
\r
768 function getBlogIDFromItemID($itemid) {
\r
769 return quickQuery('SELECT iblog as result FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid) );
\r
772 function getBlogIDFromCommentID($commentid) {
\r
773 return quickQuery('SELECT cblog as result FROM ' . sql_table('comment') . ' WHERE cnumber=' . intval($commentid) );
\r
776 function getBlogIDFromCatID($catid) {
\r
777 return quickQuery('SELECT cblog as result FROM ' . sql_table('category') . ' WHERE catid=' . intval($catid) );
\r
780 function getCatIDFromName($name) {
\r
781 return quickQuery('SELECT catid as result FROM ' . sql_table('category') . ' WHERE cname="' . addslashes($name) . '"');
\r
784 function quickQuery($q) {
\r
785 $res = sql_query($q);
\r
786 $obj = sql_fetch_object($res);
\r
787 return $obj->result;
\r
790 function getPluginNameFromPid($pid) {
\r
791 $res = sql_query('SELECT pfile FROM ' . sql_table('plugin') . ' WHERE pid=' . intval($pid) );
\r
792 $obj = sql_fetch_object($res);
\r
793 return $obj->pfile;
\r
796 function selector() {
\r
797 global $itemid, $blogid, $memberid, $query, $amount, $archivelist, $maxresults;
\r
798 global $archive, $skinid, $blog, $memberinfo, $CONF, $member;
\r
799 global $imagepopup, $catid, $special;
\r
802 $actionNames = array('addcomment', 'sendmessage', 'createaccount', 'forgotpassword', 'votepositive', 'votenegative', 'plugin');
\r
803 $action = requestVar('action');
\r
805 if (in_array($action, $actionNames) ) {
\r
806 global $DIR_LIBS, $errormessage;
\r
807 include_once($DIR_LIBS . 'ACTION.php');
\r
809 $errorInfo = $a->doAction($action);
\r
812 $errormessage = $errorInfo['message'];
\r
816 // show error when headers already sent out
\r
817 if (headers_sent() && $CONF['alertOnHeadersSent']) {
\r
819 // try to get line number/filename (extra headers_sent params only exists in PHP 4.3+)
\r
820 if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=') ) {
\r
821 headers_sent($hsFile, $hsLine);
\r
822 $extraInfo = sprintf(_GFUNCTIONS_HEADERSALREADYSENT_FILE,$hsFile,$hsLine);
\r
828 sprintf(_GFUNCTIONS_HEADERSALREADYSENT_TXT,$extraInfo),
\r
829 _GFUNCTIONS_HEADERSALREADYSENT_TITLE
\r
834 // make is so ?archivelist without blogname or blogid shows the archivelist
\r
835 // for the default weblog
\r
836 if (serverVar('QUERY_STRING') == 'archivelist') {
\r
837 $archivelist = $CONF['DefaultBlog'];
\r
840 // now decide which type of skin we need
\r
842 // itemid given -> only show that item
\r
845 if (!$manager->existsItem($itemid,0,0) ) {
\r
846 doError(_ERROR_NOSUCHITEM);
\r
849 global $itemidprev, $itemidnext, $catid, $itemtitlenext, $itemtitleprev;
\r
851 // 1. get timestamp, blogid and catid for item
\r
852 $query = 'SELECT itime, iblog, icat FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid);
\r
853 $res = sql_query($query);
\r
854 $obj = sql_fetch_object($res);
\r
856 // if a different blog id has been set through the request or selectBlog(),
\r
858 // if ($blogid && (intval($blogid) != $obj->iblog) ) {
\r
859 // doError(_ERROR_NOSUCHITEM);
\r
861 if ($blogid && (intval($blogid) != $obj->iblog) ) {
\r
862 if (!headers_sent()) {
\r
863 $b =& $manager->getBlog($obj->iblog);
\r
864 $CONF['ItemURL'] = $b->getURL();
\r
865 if ($CONF['URLMode'] == 'pathinfo' and substr($CONF['ItemURL'],-1) == '/')
\r
866 $CONF['ItemURL'] = substr($CONF['ItemURL'], 0, -1);
\r
867 $correctURL = createItemLink($itemid, '');
\r
868 redirect($correctURL);
\r
871 doError(_ERROR_NOSUCHITEM);
\r
875 // if a category has been selected which doesn't match the item, ignore the
\r
877 if (($catid != 0) && ($catid != $obj->icat) ) {
\r
881 $blogid = $obj->iblog;
\r
882 $timestamp = strtotime($obj->itime);
\r
884 $b =& $manager->getBlog($blogid);
\r
886 if ($b->isValidCategory($catid) ) {
\r
887 $catextra = ' and icat=' . $catid;
\r
892 // get previous itemid and title
\r
893 $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
894 $res = sql_query($query);
\r
896 $obj = sql_fetch_object($res);
\r
899 $itemidprev = $obj->inumber;
\r
900 $itemtitleprev = $obj->ititle;
\r
903 // get next itemid and title
\r
904 $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
905 $res = sql_query($query);
\r
907 $obj = sql_fetch_object($res);
\r
910 $itemidnext = $obj->inumber;
\r
911 $itemtitlenext = $obj->ititle;
\r
914 } elseif ($archive) {
\r
918 // get next and prev month links ...
\r
919 global $archivenext, $archiveprev, $archivetype, $archivenextexists, $archiveprevexists;
\r
921 // sql queries for the timestamp of the first and the last published item
\r
922 $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
923 $first_timestamp=quickQuery ($query);
\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 DESC";
\r
925 $last_timestamp=quickQuery ($query);
\r
927 sscanf($archive, '%d-%d-%d', $y, $m, $d);
\r
930 $archivetype = _ARCHIVETYPE_DAY;
\r
931 $t = mktime(0, 0, 0, $m, $d, $y);
\r
932 // one day has 24 * 60 * 60 = 86400 seconds
\r
933 $archiveprev = strftime('%Y-%m-%d', $t - 86400 );
\r
934 // check for published items
\r
935 if ($t > $first_timestamp) {
\r
936 $archiveprevexists = true;
\r
939 $archiveprevexists = false;
\r
944 $archivenext = strftime('%Y-%m-%d', $t);
\r
945 if ($t < $last_timestamp) {
\r
946 $archivenextexists = true;
\r
949 $archivenextexists = false;
\r
952 } elseif ($m == 0) {
\r
953 $archivetype = _ARCHIVETYPE_YEAR;
\r
954 $t = mktime(0, 0, 0, 12, 31, $y - 1);
\r
955 // one day before is in the previous year
\r
956 $archiveprev = strftime('%Y', $t);
\r
957 if ($t > $first_timestamp) {
\r
958 $archiveprevexists = true;
\r
961 $archiveprevexists = false;
\r
964 // timestamp for the next year
\r
965 $t = mktime(0, 0, 0, 1, 1, $y + 1);
\r
966 $archivenext = strftime('%Y', $t);
\r
967 if ($t < $last_timestamp) {
\r
968 $archivenextexists = true;
\r
971 $archivenextexists = false;
\r
974 $archivetype = _ARCHIVETYPE_MONTH;
\r
975 $t = mktime(0, 0, 0, $m, 1, $y);
\r
976 // one day before is in the previous month
\r
977 $archiveprev = strftime('%Y-%m', $t - 86400);
\r
978 if ($t > $first_timestamp) {
\r
979 $archiveprevexists = true;
\r
982 $archiveprevexists = false;
\r
985 // timestamp for the next month
\r
986 $t = mktime(0, 0, 0, $m+1, 1, $y);
\r
987 $archivenext = strftime('%Y-%m', $t);
\r
988 if ($t < $last_timestamp) {
\r
989 $archivenextexists = true;
\r
992 $archivenextexists = false;
\r
996 } elseif ($archivelist) {
\r
997 $type = 'archivelist';
\r
999 if (is_numeric($archivelist)) {
\r
1000 $blogid = intVal($archivelist);
\r
1002 $blogid = getBlogIDFromName($archivelist);
\r
1006 doError(_ERROR_NOSUCHBLOG);
\r
1009 } elseif ($query) {
\r
1012 $query = stripslashes($query);
\r
1013 if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/", $query)){
\r
1016 // $order = (_CHARSET == 'EUC-JP') ? 'EUC-JP, UTF-8,' : 'UTF-8, EUC-JP,';
\r
1017 // $query = mb_convert_encoding($query, _CHARSET, $order . ' JIS, SJIS, ASCII');
\r
1018 switch(strtolower(_CHARSET)){
\r
1020 $order = 'ASCII, UTF-8, EUC-JP, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1023 $order = 'ASCII, EUC-CN, EUC-JP, UTF-8, JIS, SJIS, ISO-8859-1';
\r
1026 // Note that shift_jis is only supported for output.
\r
1027 // Using shift_jis in DB is prohibited.
\r
1028 $order = 'ASCII, SJIS, EUC-JP, UTF-8, JIS, EUC-CN, ISO-8859-1';
\r
1031 // euc-jp,iso-8859-x,windows-125x
\r
1032 $order = 'ASCII, EUC-JP, UTF-8, JIS, SJIS, EUC-CN, ISO-8859-1';
\r
1035 $query = mb_convert_encoding($query, _CHARSET, $order);
\r
1036 if (is_numeric($blogid)) {
\r
1037 $blogid = intVal($blogid);
\r
1039 $blogid = getBlogIDFromName($blogid);
\r
1043 doError(_ERROR_NOSUCHBLOG);
\r
1046 } elseif ($memberid) {
\r
1049 if (!MEMBER::existsID($memberid) ) {
\r
1050 doError(_ERROR_NOSUCHMEMBER);
\r
1053 $memberinfo = $manager->getMember($memberid);
\r
1055 } elseif ($imagepopup) {
\r
1056 // media object (images etc.)
\r
1057 $type = 'imagepopup';
\r
1059 // TODO: check if media-object exists
\r
1060 // TODO: set some vars?
\r
1062 // show regular index page
\r
1067 // any type of skin with catid
\r
1068 if ($catid && !$blogid) {
\r
1069 $blogid = getBlogIDFromCatID($catid);
\r
1072 // decide which blog should be displayed
\r
1074 $blogid = $CONF['DefaultBlog'];
\r
1077 $b =& $manager->getBlog($blogid);
\r
1078 $blog = $b; // references can't be placed in global variables?
\r
1080 if (!$blog->isValid) {
\r
1081 doError(_ERROR_NOSUCHBLOG);
\r
1084 // set catid if necessary
\r
1086 // check if the category is valid
\r
1087 if (!$blog->isValidCategory($catid)) {
\r
1088 doError(_ERROR_NOSUCHCATEGORY);
\r
1090 $blog->setSelectedCategory($catid);
\r
1094 // decide which skin should be used
\r
1095 if ($skinid != '' && ($skinid == 0) ) {
\r
1096 selectSkin($skinid);
\r
1100 $skinid = $blog->getDefaultSkin();
\r
1103 //$special = requestVar('special'); //get at top of file as global
\r
1104 if (!empty($special) && isValidShortName($special)) {
\r
1105 $type = strtolower($special);
\r
1108 $skin = new SKIN($skinid);
\r
1110 if (!$skin->isValid) {
\r
1111 doError(_ERROR_NOSUCHSKIN);
\r
1115 $skin->parse($type);
\r
1117 // check to see we should throw JustPosted event
\r
1118 $blog->checkJustPosted();
\r
1122 * Show error skin with given message. An optional skin-object to use can be given
\r
1124 function doError($msg, $skin = '') {
\r
1125 global $errormessage, $CONF, $skinid, $blogid, $manager;
\r
1127 if ($skin == '') {
\r
1129 if (SKIN::existsID($skinid) ) {
\r
1130 $skin = new SKIN($skinid);
\r
1131 } elseif ($manager->existsBlogID($blogid) ) {
\r
1132 $blog =& $manager->getBlog($blogid);
\r
1133 $skin = new SKIN($blog->getDefaultSkin() );
\r
1134 } elseif ($CONF['DefaultBlog']) {
\r
1135 $blog =& $manager->getBlog($CONF['DefaultBlog']);
\r
1136 $skin = new SKIN($blog->getDefaultSkin() );
\r
1138 // this statement should actually never be executed
\r
1139 $skin = new SKIN($CONF['BaseSkin']);
\r
1144 $skinid = $skin->id;
\r
1145 $errormessage = $msg;
\r
1146 $skin->parse('error');
\r
1150 function getConfig() {
\r
1153 $query = 'SELECT * FROM ' . sql_table('config');
\r
1154 $res = sql_query($query);
\r
1156 while ($obj = sql_fetch_object($res) ) {
\r
1157 $CONF[$obj->name] = $obj->value;
\r
1161 // some checks for names of blogs, categories, templates, members, ...
\r
1162 function isValidShortName($name) {
\r
1163 return eregi('^[a-z0-9]+$', $name);
\r
1166 function isValidDisplayName($name) {
\r
1167 return eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name);
\r
1170 function isValidCategoryName($name) {
\r
1174 function isValidTemplateName($name) {
\r
1175 return eregi('^[a-z0-9/]+$', $name);
\r
1178 function isValidSkinName($name) {
\r
1179 return eregi('^[a-z0-9/]+$', $name);
\r
1182 // add and remove linebreaks
\r
1183 function addBreaks($var) {
\r
1184 return nl2br($var);
\r
1187 function removeBreaks($var) {
\r
1188 return preg_replace("/<br \/>([\r\n])/", "$1", $var);
\r
1191 // shortens a text string to maxlength ($toadd) is what needs to be added
\r
1192 // at the end (end length is <= $maxlength)
\r
1193 function shorten($text, $maxlength, $toadd) {
\r
1194 // 1. remove entities...
\r
1195 // $trans = get_html_translation_table(HTML_ENTITIES);
\r
1196 $trans = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
1197 $trans = array_flip($trans);
\r
1198 $text = strtr($text, $trans);
\r
1200 // 2. the actual shortening
\r
1201 if (strlen($text) > $maxlength) {
\r
1202 // $text = substr($text, 0, $maxlength - strlen($toadd) ) . $toadd;
\r
1203 $text = mb_strimwidth($text, 0, $maxlength, $toadd, _CHARSET); // for Japanese
\r
1209 * Converts a unix timestamp to a mysql DATETIME format, and places
\r
1210 * quotes around it.
\r
1212 function mysqldate($timestamp) {
\r
1213 return '"' . date('Y-m-d H:i:s', $timestamp) . '"';
\r
1217 * functions for use in index.php
\r
1219 function selectBlog($shortname) {
\r
1220 global $blogid, $archivelist;
\r
1221 $blogid = getBlogIDFromName($shortname);
\r
1223 // also force archivelist variable, if it is set
\r
1224 if ($archivelist) {
\r
1225 $archivelist = $blogid;
\r
1229 function selectSkin($skinname) {
\r
1231 $skinid = SKIN::getIdFromName($skinname);
\r
1235 * Can take either a category ID or a category name (be aware that
\r
1236 * multiple categories can have the same name)
\r
1238 function selectCategory($cat) {
\r
1240 if (is_numeric($cat) ) {
\r
1241 $catid = intval($cat);
\r
1243 $catid = getCatIDFromName($cat);
\r
1247 function selectItem($id) {
\r
1249 $itemid = intval($id);
\r
1252 // force the use of a language file (warning: can cause warnings)
\r
1253 function selectLanguage($language) {
\r
1255 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
\r
1258 function parseFile($filename, $includeMode = 'normal', $includePrefix = '') {
\r
1259 $handler = new ACTIONS('fileparser');
\r
1260 $parser = new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);
\r
1261 $handler->parser =& $parser;
\r
1263 // set IncludeMode properties of parser
\r
1264 PARSER::setProperty('IncludeMode', $includeMode);
\r
1265 PARSER::setProperty('IncludePrefix', $includePrefix);
\r
1267 if (!file_exists($filename) ) {
\r
1268 doError(_GFUNCTIONS_PARSEFILE_FILEMISSING);
\r
1271 $fsize = filesize($filename);
\r
1273 if ($fsize <= 0) {
\r
1278 $fd = fopen ($filename, 'r');
\r
1279 $contents = fread ($fd, $fsize);
\r
1282 // parse file contents
\r
1283 $parser->parse($contents);
\r
1287 * Outputs a debug message
\r
1289 function debug($msg) {
\r
1290 echo '<p><b>' . $msg . "</b></p>\n";
\r
1294 function addToLog($level, $msg) {
\r
1295 ACTIONLOG::add($level, $msg);
\r
1298 // shows a link to help file
\r
1299 function help($id) {
\r
1300 echo helpHtml($id);
\r
1303 function helpHtml($id) {
\r
1305 return helplink($id) . '<img src="' . $CONF['AdminURL'] . 'documentation/icon-help.gif" width="15" height="15" alt="' . _HELP_TT . '" title="' . _HELP_TT . '" /></a>';
\r
1308 function helplink($id) {
\r
1310 return '<a href="' . $CONF['AdminURL'] . 'documentation/help.html#'. $id . '" onclick="if (event && event.preventDefault) event.preventDefault(); return help(this.href);">';
\r
1313 function getMailFooter() {
\r
1314 $message = "\n\n-----------------------------";
\r
1315 $message .= "\n Powered by Nucleus CMS";
\r
1316 $message .= "\n(http://www.nucleuscms.org/)";
\r
1321 * Returns the name of the language to use
\r
1322 * preference priority: member - site
\r
1323 * defaults to english when no good language found
\r
1325 * checks if file exists, etc...
\r
1327 function getLanguageName() {
\r
1328 global $CONF, $member;
\r
1330 if ($member && $member->isLoggedIn() ) {
\r
1331 // try to use members language
\r
1332 $memlang = $member->getLanguage();
\r
1334 if (($memlang != '') && (checkLanguage($memlang) ) ) {
\r
1339 // use default language
\r
1340 if (checkLanguage($CONF['Language']) ) {
\r
1341 return $CONF['Language'];
\r
1348 * Includes a PHP file. This method can be called while parsing templates and skins
\r
1350 function includephp($filename) {
\r
1351 // make predefined variables global, so most simple scripts can be used here
\r
1353 // apache (names taken from PHP doc)
\r
1354 global $GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE, $SERVER_PROTOCOL;
\r
1355 global $REQUEST_METHOD, $QUERY_STRING, $DOCUMENT_ROOT, $HTTP_ACCEPT;
\r
1356 global $HTTP_ACCEPT_CHARSET, $HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE;
\r
1357 global $HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER, $HTTP_USER_AGENT;
\r
1358 global $REMOTE_ADDR, $REMOTE_PORT, $SCRIPT_FILENAME, $SERVER_ADMIN;
\r
1359 global $SERVER_PORT, $SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME;
\r
1360 global $REQUEST_URI;
\r
1362 // php (taken from PHP doc)
\r
1363 global $argv, $argc, $PHP_SELF, $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS;
\r
1364 global $HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS, $HTTP_SESSION_VARS;
\r
1367 global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;
\r
1369 if (@file_exists($filename) ) {
\r
1370 include($filename);
\r
1375 * Checks if a certain language/plugin exists
\r
1377 function checkLanguage($lang) {
\r
1378 global $DIR_LANG ;
\r
1379 return file_exists($DIR_LANG . ereg_replace( '[\\|/]', '', $lang) . '.php');
\r
1382 function checkPlugin($plug) {
\r
1383 global $DIR_PLUGINS;
\r
1384 return file_exists($DIR_PLUGINS . ereg_replace( '[\\|/]', '', $plug) . '.php');
\r
1388 * Centralisation of the functions that generate links
\r
1390 function createItemLink($itemid, $extra = '') {
\r
1391 return createLink('item', array('itemid' => $itemid, 'extra' => $extra) );
\r
1394 function createMemberLink($memberid, $extra = '') {
\r
1395 return createLink('member', array('memberid' => $memberid, 'extra' => $extra) );
\r
1398 function createCategoryLink($catid, $extra = '') {
\r
1399 return createLink('category', array('catid' => $catid, 'extra' => $extra) );
\r
1402 function createArchiveListLink($blogid = '', $extra = '') {
\r
1403 return createLink('archivelist', array('blogid' => $blogid, 'extra' => $extra) );
\r
1406 function createArchiveLink($blogid, $archive, $extra = '') {
\r
1407 return createLink('archive', array('blogid' => $blogid, 'archive' => $archive, 'extra' => $extra) );
\r
1410 function createBlogidLink($blogid, $params = '') {
\r
1411 return createLink('blog', array('blogid' => $blogid, 'extra' => $params) );
\r
1414 function createLink($type, $params) {
\r
1415 global $manager, $CONF;
\r
1417 $generatedURL = '';
\r
1418 $usePathInfo = ($CONF['URLMode'] == 'pathinfo');
\r
1420 // ask plugins first
\r
1423 if ($usePathInfo) {
\r
1428 'params' => $params,
\r
1429 'completed' => &$created,
\r
1435 // if a plugin created the URL, return it
\r
1440 // default implementation
\r
1443 if ($usePathInfo) {
\r
1444 $url = $CONF['ItemURL'] . '/' . $CONF['ItemKey'] . '/' . $params['itemid'];
\r
1446 $url = $CONF['ItemURL'] . '?itemid=' . $params['itemid'];
\r
1451 if ($usePathInfo) {
\r
1452 $url = $CONF['MemberURL'] . '/' . $CONF['MemberKey'] . '/' . $params['memberid'];
\r
1454 $url = $CONF['MemberURL'] . '?memberid=' . $params['memberid'];
\r
1459 if ($usePathInfo) {
\r
1460 $url = $CONF['CategoryURL'] . '/' . $CONF['CategoryKey'] . '/' . $params['catid'];
\r
1462 $url = $CONF['CategoryURL'] . '?catid=' . $params['catid'];
\r
1466 case 'archivelist':
\r
1467 if (!$params['blogid']) {
\r
1468 $params['blogid'] = $CONF['DefaultBlog'];
\r
1471 if ($usePathInfo) {
\r
1472 $url = $CONF['ArchiveListURL'] . '/' . $CONF['ArchivesKey'] . '/' . $params['blogid'];
\r
1474 $url = $CONF['ArchiveListURL'] . '?archivelist=' . $params['blogid'];
\r
1479 if ($usePathInfo) {
\r
1480 $url = $CONF['ArchiveURL'] . '/' . $CONF['ArchiveKey'] . '/'.$params['blogid'].'/' . $params['archive'];
\r
1482 $url = $CONF['ArchiveURL'] . '?blogid='.$params['blogid'].'&archive=' . $params['archive'];
\r
1487 if ($usePathInfo) {
\r
1488 $url = $CONF['BlogURL'] . '/' . $CONF['BlogKey'] . '/' . $params['blogid'];
\r
1490 $url = $CONF['BlogURL'] . '?blogid=' . $params['blogid'];
\r
1495 return addLinkParams($url, (isset($params['extra'])? $params['extra'] : null));
\r
1498 function createBlogLink($url, $params) {
\r
1500 if ($CONF['URLMode'] == 'normal') {
\r
1501 if (strpos($url, '?') === FALSE && is_array($params)) {
\r
1502 $fParam = reset($params);
\r
1503 $fKey = key($params);
\r
1504 array_shift($params);
\r
1505 $url .= '?' . $fKey . '=' . $fParam;
\r
1507 } elseif ($CONF['URLMode'] == 'pathinfo' && substr($url, -1) == '/') {
\r
1508 $url = substr($url, 0, -1);
\r
1510 return addLinkParams($url, $params);
\r
1513 function addLinkParams($link, $params) {
\r
1516 if (is_array($params) ) {
\r
1518 if ($CONF['URLMode'] == 'pathinfo') {
\r
1520 foreach ($params as $param => $value) {
\r
1521 $link .= '/' . $param . '/' . urlencode($value);
\r
1526 foreach ($params as $param => $value) {
\r
1527 $link .= '&' . $param . '=' . urlencode($value);
\r
1537 * @param $querystr
\r
1538 * querystring to alter (e.g. foo=1&bar=2&x=y)
\r
1540 * name of parameter to change (e.g. 'foo')
\r
1542 * New value for that parameter (e.g. 3)
\r
1544 * altered query string (for the examples above: foo=3&bar=2&x=y)
\r
1546 function alterQueryStr($querystr, $param, $value) {
\r
1547 $vars = explode('&', $querystr);
\r
1550 for ($i = 0; $i < count($vars); $i++) {
\r
1551 $v = explode('=', $vars[$i]);
\r
1553 if ($v[0] == $param) {
\r
1555 $vars[$i] = implode('=', $v);
\r
1562 $vars[] = $param . '=' . $value;
\r
1565 return ltrim(implode('&', $vars), '&');
\r
1568 // passes one variable as hidden input field (multiple fields for arrays)
\r
1569 // @see passRequestVars in varsx.x.x.php
\r
1570 function passVar($key, $value) {
\r
1572 if (is_array($value) ) {
\r
1573 for ($i = 0; $i < sizeof($value); $i++) {
\r
1574 passVar($key . '[' . $i . ']', $value[$i]);
\r
1580 // other values: do stripslashes if needed
\r
1581 ?><input type="hidden" name="<?php echo htmlspecialchars($key)?>" value="<?php echo htmlspecialchars(undoMagic($value) )?>" /><?php
\r
1585 Date format functions (to be used from [%date(..)%] skinvars
\r
1587 function formatDate($format, $timestamp, $defaultFormat, &$blog) {
\r
1588 // apply blog offset (#42)
\r
1589 $boffset = $blog ? $blog->getTimeOffset() * 3600 : 0;
\r
1590 $offset = date('Z', $timestamp) + $boffset;
\r
1592 switch ($format) {
\r
1594 if ($offset >= 0) {
\r
1598 $offset = -$offset;
\r
1601 $tz .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1602 return date('D, j M Y H:i:s ', $timestamp) . $tz;
\r
1605 $timestamp -= $offset;
\r
1606 return date('D, j M Y H:i:s ', $timestamp) . 'GMT';
\r
1609 $timestamp -= $offset;
\r
1610 return date('Y-m-d\TH:i:s\Z', $timestamp);
\r
1613 if ($offset >= 0) {
\r
1617 $offset = -$offset;
\r
1620 $tz .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
\r
1621 return date('Y-m-d\TH:i:s', $timestamp) . $tz;
\r
1624 return strftime($format ? $format : $defaultFormat, $timestamp);
\r
1628 function encoding_check($val, $key, $encoding=false, $exclude=false) {
\r
1630 When 3rd argument is set, return if checked already.
\r
1631 When 4th argument is set, set the excluded key(s).
\r
1633 static $search=false, $checked=array(), $excludes=array();
\r
1634 if ($exclude!==false) {
\r
1635 if (is_array($exclude)) {
\r
1636 foreach($exclude as $v) $excludes[$v]=true;
\r
1637 } else $excludes[$exclude]=true;
\r
1640 if ($encoding!==false) {
\r
1641 switch($encoding=strtolower($encoding)){
\r
1643 $search='/([\x00-\x7F]+'.
\r
1644 '|[\xC2-\xDF][\x80-\xBF]'.
\r
1645 '|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]'.
\r
1646 '|[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1647 '|[\xF8-\xFB][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.
\r
1648 '|[\xFC-\xFD][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF])/';
\r
1651 $search='/([\x00-\x7F]+'.
\r
1652 '|[\x8E][\xA0-\xDF]'.
\r
1653 '|[\x8F]?[\xA1-\xFE][\xA1-\xFE])/';
\r
1656 $search='/([\x00-\x7F]+'.
\r
1657 '|[\xA1-\xF7][\xA1-\xFE])/';
\r
1660 // Note that shift_jis is only supported for output.
\r
1661 // Using shift_jis in DB is prohibited.
\r
1662 $search='/([\x00-\x7F\xA1-\xDF]+'.
\r
1663 '|[\x81-\x9F\xE0-\xFC][\x40-\xFC])/';
\r
1667 if (preg_match('/^iso\-8859\-[0-9]{1,2}$/',$encoding)) break;
\r
1668 if (preg_match('/^windows\-125[0-8]$/',$encoding)) break;
\r
1669 startUpError('<p>Unknown or non-supported encoding.</p>', 'Encoding Error');
\r
1672 if (isset($checked[$encoding])) return true; // Already checked.
\r
1673 $checked[$encoding]=true;
\r
1675 if ($key===false) return false; // Not yet checked.
\r
1676 if ($search===false) return true; // non-multibyte encoding
\r
1677 if (isset($excludes[$key])) return true; // This key isn't checked.
\r
1678 if (is_array($val)) {
\r
1679 array_walk($val, 'encoding_check');
\r
1681 $result=preg_replace($search,'',$val);
\r
1682 if (strlen($result)!=0) {
\r
1683 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1687 $result=preg_replace($search,'',$key);
\r
1688 if (strlen($result)!=0) {
\r
1689 startUpError('<p>Invalid input.</p>', 'Input Error');
\r
1695 function checkVars($aVars) {
\r
1696 global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;
\r
1698 foreach ($aVars as $varName) {
\r
1700 if (phpversion() >= '4.1.0') {
\r
1702 if ( isset($_GET[$varName])
\r
1703 || isset($_POST[$varName])
\r
1704 || isset($_COOKIE[$varName])
\r
1705 || isset($_ENV[$varName])
\r
1706 || isset($_SESSION[$varName])
\r
1707 || isset($_FILES[$varName])
\r
1709 die('Sorry. An error occurred.');
\r
1714 if ( isset($HTTP_GET_VARS[$varName])
\r
1715 || isset($HTTP_POST_VARS[$varName])
\r
1716 || isset($HTTP_COOKIE_VARS[$varName])
\r
1717 || isset($HTTP_ENV_VARS[$varName])
\r
1718 || isset($HTTP_SESSION_VARS[$varName])
\r
1719 || isset($HTTP_POST_FILES[$varName])
\r
1721 die('Sorry. An error occurred.');
\r
1730 * Sanitize parameters such as $_GET and $_SERVER['REQUEST_URI'] etc.
\r
1733 function sanitizeParams()
\r
1735 global $HTTP_SERVER_VARS;
\r
1741 // REQUEST_URI of $HTTP_SERVER_VARS
\r
1742 $str =& $HTTP_SERVER_VARS["REQUEST_URI"];
\r
1743 serverStringToArray($str, $array, $frontParam);
\r
1744 sanitizeArray($array);
\r
1745 arrayToServerString($array, $frontParam, $str);
\r
1747 // QUERY_STRING of $HTTP_SERVER_VARS
\r
1748 $str =& $HTTP_SERVER_VARS["QUERY_STRING"];
\r
1749 serverStringToArray($str, $array, $frontParam);
\r
1750 sanitizeArray($array);
\r
1751 arrayToServerString($array, $frontParam, $str);
\r
1753 if (phpversion() >= '4.1.0') {
\r
1754 // REQUEST_URI of $_SERVER
\r
1755 $str =& $_SERVER["REQUEST_URI"];
\r
1756 serverStringToArray($str, $array, $frontParam);
\r
1757 sanitizeArray($array);
\r
1758 arrayToServerString($array, $frontParam, $str);
\r
1760 // QUERY_STRING of $_SERVER
\r
1761 $str =& $_SERVER["QUERY_STRING"];
\r
1762 serverStringToArray($str, $array, $frontParam);
\r
1763 sanitizeArray($array);
\r
1764 arrayToServerString($array, $frontParam, $str);
\r
1768 convArrayForSanitizing($_GET, $array);
\r
1769 sanitizeArray($array);
\r
1770 revertArrayForSanitizing($array, $_GET);
\r
1772 // $_REQUEST (only GET param)
\r
1773 convArrayForSanitizing($_REQUEST, $array);
\r
1774 sanitizeArray($array);
\r
1775 revertArrayForSanitizing($array, $_REQUEST);
\r
1779 * Check ticket when not checked in plugin's admin page
\r
1781 * Also avoid the access to plugin/index.php by guest user.
\r
1783 function ticketForPlugin(){
\r
1784 global $CONF,$DIR_PLUGINS,$member,$ticketforplugin;
\r
1787 $ticketforplugin=array();
\r
1788 $ticketforplugin['ticket']=false;
\r
1790 /* Check if using plugin's php file. */
\r
1791 if ($p_translated=serverVar('PATH_TRANSLATED')) {
\r
1792 if (!file_exists($p_translated)) $p_translated='';
\r
1794 if (!$p_translated) {
\r
1795 $p_translated=serverVar('SCRIPT_FILENAME');
\r
1796 if (!file_exists($p_translated)) {
\r
1797 header("HTTP/1.0 404 Not Found");
\r
1801 $p_translated=str_replace('\\','/',$p_translated);
\r
1802 $d_plugins=str_replace('\\','/',$DIR_PLUGINS);
\r
1803 if (strpos($p_translated,$d_plugins)!==0) return;// This isn't plugin php file.
\r
1805 /* Solve the plugin php file or admin directory */
\r
1806 $phppath=substr($p_translated,strlen($d_plugins));
\r
1807 $phppath=preg_replace('!^/!','',$phppath);// Remove the first "/" if exists.
\r
1808 $path=preg_replace('/^NP_(.*)\.php$/','$1',$phppath); // Remove the first "NP_" and the last ".php" if exists.
\r
1809 $path=preg_replace('!^([^/]*)/(.*)$!','$1',$path); // Remove the "/" and beyond.
\r
1811 /* Solve the plugin name. */
\r
1813 $query='SELECT pfile FROM '.sql_table('plugin');
\r
1814 $res=sql_query($query);
\r
1815 while($row=sql_fetch_row($res)) {
\r
1816 $name=substr($row[0],3);
\r
1817 $plugins[strtolower($name)]=$name;
\r
1819 sql_free_result($res);
\r
1820 if ($plugins[$path]) $plugin_name=$plugins[$path];
\r
1821 else if (in_array($path,$plugins)) $plugin_name=$path;
\r
1823 header("HTTP/1.0 404 Not Found");
\r
1827 /* Return if not index.php */
\r
1828 if ( $phppath!=strtolower($plugin_name).'/'
\r
1829 && $phppath!=strtolower($plugin_name).'/index.php' ) return;
\r
1831 /* Exit if not logged in. */
\r
1832 if ( !$member->isLoggedIn() ) exit(_GFUNCTIONS_YOU_AERNT_LOGGEDIN);
\r
1834 global $manager,$DIR_LIBS,$DIR_LANG,$HTTP_GET_VARS,$HTTP_POST_VARS;
\r
1836 /* Check if this feature is needed (ie, if "$manager->checkTicket()" is not included in the script). */
\r
1837 if (!($p_translated=serverVar('PATH_TRANSLATED'))) $p_translated=serverVar('SCRIPT_FILENAME');
\r
1838 if ($file=@file($p_translated)) {
\r
1840 foreach($file as $line) {
\r
1841 if (preg_match('/[\$]manager([\s]*)[\-]>([\s]*)checkTicket([\s]*)[\(]/i',$prevline.$line)) return;
\r
1846 /* Show a form if not valid ticket */
\r
1847 if ( ( strstr(serverVar('REQUEST_URI'),'?') || serverVar('QUERY_STRING')
\r
1848 || strtoupper(serverVar('REQUEST_METHOD'))=='POST' )
\r
1849 && (!$manager->checkTicket()) ){
\r
1851 if (!class_exists('PluginAdmin')) {
\r
1852 $language = getLanguageName();
\r
1853 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
\r
1854 include($DIR_LIBS . 'PLUGINADMIN.php');
\r
1856 if (!(function_exists('mb_strimwidth') || extension_loaded('mbstring'))) {
\r
1857 if (file_exists($DIR_LIBS.'mb_emulator/mb-emulator.php')) {
\r
1858 global $mbemu_internals;
\r
1859 include_once($DIR_LIBS.'mb_emulator/mb-emulator.php');
\r
1862 $oPluginAdmin = new PluginAdmin($plugin_name);
\r
1863 $oPluginAdmin->start();
\r
1864 echo '<p>' . _ERROR_BADTICKET . "</p>\n";
\r
1866 /* Show the form to confirm action */
\r
1867 // PHP 4.0.x support
\r
1868 $get= (isset($_GET)) ? $_GET : $HTTP_GET_VARS;
\r
1869 $post= (isset($_POST)) ? $_POST : $HTTP_POST_VARS;
\r
1870 // Resolve URI and QUERY_STRING
\r
1871 if ($uri=serverVar('REQUEST_URI')) {
\r
1872 list($uri,$qstring)=explode('?',$uri);
\r
1874 if ( !($uri=serverVar('PHP_SELF')) ) $uri=serverVar('SCRIPT_NAME');
\r
1875 $qstring=serverVar('QUERY_STRING');
\r
1877 if ($qstring) $qstring='?'.$qstring;
\r
1878 echo '<p>'._SETTINGS_UPDATE.' : '._QMENU_PLUGINS.' <span style="color:red;">'.
\r
1879 htmlspecialchars($plugin_name)."</span> ?</p>\n";
\r
1880 switch(strtoupper(serverVar('REQUEST_METHOD'))){
\r
1882 echo '<form method="POST" action="'.htmlspecialchars($uri.$qstring).'">';
\r
1883 $manager->addTicketHidden();
\r
1884 _addInputTags($post);
\r
1887 echo '<form method="GET" action="'.htmlspecialchars($uri).'">';
\r
1888 $manager->addTicketHidden();
\r
1889 _addInputTags($get);
\r
1893 echo '<input type="submit" value="'._YES.'" /> ';
\r
1894 echo '<input type="button" value="'._NO.'" onclick="history.back(); return false;" />';
\r
1897 $oPluginAdmin->end();
\r
1901 /* Create new ticket */
\r
1902 $ticket=$manager->addTicketToUrl('');
\r
1903 $ticketforplugin['ticket']=substr($ticket,strpos($ticket,'ticket=')+7);
\r
1905 function _addInputTags(&$keys,$prefix=''){
\r
1906 foreach($keys as $key=>$value){
\r
1907 if ($prefix) $key=$prefix.'['.$key.']';
\r
1908 if (is_array($value)) _addInputTags($value,$key);
\r
1910 if (get_magic_quotes_gpc()) $value=stripslashes($value);
\r
1911 if ($key=='ticket') continue;
\r
1912 echo '<input type="hidden" name="'.htmlspecialchars($key).
\r
1913 '" value="'.htmlspecialchars($value).'" />'."\n";
\r
1919 * Convert the server string such as $_SERVER['REQUEST_URI']
\r
1920 * to arry like arry['blogid']=1 and array['page']=2 etc.
\r
1922 function serverStringToArray($str, &$array, &$frontParam)
\r
1928 // split front param, e.g. /index.php, and others, e.g. blogid=1&page=2
\r
1929 if (strstr($str, "?")){
\r
1930 list($frontParam, $args) = preg_split("/\?/", $str, 2);
\r
1937 // If there is no args like blogid=1&page=2, return
\r
1938 if (!strstr($str, "=") && !strlen($frontParam)) {
\r
1939 $frontParam = $str;
\r
1943 $array = explode("&", $args);
\r
1947 * Convert array like array['blogid'] to server string
\r
1948 * such as $_SERVER['REQUEST_URI']
\r
1950 function arrayToServerString($array, $frontParam, &$str)
\r
1952 if (strstr($str, "?")) {
\r
1953 $str = $frontParam . "?";
\r
1955 $str = $frontParam;
\r
1957 if (count($array)) {
\r
1958 $str .= implode("&", $array);
\r
1963 * Sanitize array parameters.
\r
1964 * This function checks both key and value.
\r
1965 * - check key if it inclues " (double quote), remove from array
\r
1966 * - check value if it includes \ (escape sequece), remove remaining string
\r
1968 function sanitizeArray(&$array)
\r
1970 $excludeListForSanitization = array('query');
\r
1971 // $excludeListForSanitization = array();
\r
1973 foreach ($array as $k => $v) {
\r
1975 // split to key and value
\r
1976 list($key, $val) = preg_split("/=/", $v, 2);
\r
1977 if (!isset($val)) {
\r
1981 // when magic quotes is on, need to use stripslashes,
\r
1982 // and then addslashes
\r
1983 if (get_magic_quotes_gpc()) {
\r
1984 $val = stripslashes($val);
\r
1986 $val = addslashes($val);
\r
1988 // if $key is included in exclude list, skip this param
\r
1989 if (!in_array($key, $excludeListForSanitization)) {
\r
1992 if (strpos($val, '\\')) {
\r
1993 list($val, $tmp) = explode('\\', $val);
\r
1996 // remove control code etc.
\r
1997 $val = strtr($val, "\0\r\n<>'\"", " ");
\r
2000 if (preg_match('/\"/i', $key)) {
\r
2001 unset($array[$k]);
\r
2005 // set sanitized info
\r
2006 $array[$k] = sprintf("%s=%s", $key, $val);
\r
2012 * Convert array for sanitizeArray function
\r
2014 function convArrayForSanitizing($src, &$array)
\r
2017 foreach ($src as $key => $val) {
\r
2018 if (key_exists($key, $_GET)) {
\r
2019 array_push($array, sprintf("%s=%s", $key, $val));
\r
2025 * Revert array after sanitizeArray function
\r
2027 function revertArrayForSanitizing($array, &$dst)
\r
2029 foreach ($array as $v) {
\r
2030 list($key, $val) = preg_split("/=/", $v, 2);
\r
2031 $dst[$key] = $val;
\r
2036 * Stops processing the request and redirects to the given URL.
\r
2037 * - no actual contents should have been sent to the output yet
\r
2038 * - the URL will be stripped of illegal or dangerous characters
\r
2040 function redirect($url) {
\r
2041 $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%*]|i', '', $url);
\r
2042 header('Location: ' . $url);
\r
2047 * Strip HTML tags from a string
\r
2048 * This function is a bit more intelligent than a regular call to strip_tags(),
\r
2049 * because it also deletes the contents of certain tags and cleans up any
\r
2050 * unneeded whitespace.
\r
2052 function stringStripTags ($string) {
\r
2053 $string = preg_replace("/<del[^>]*>.+<\/del[^>]*>/isU", '', $string);
\r
2054 $string = preg_replace("/<script[^>]*>.+<\/script[^>]*>/isU", '', $string);
\r
2055 $string = preg_replace("/<style[^>]*>.+<\/style[^>]*>/isU", '', $string);
\r
2056 $string = str_replace('>', '> ', $string);
\r
2057 $string = str_replace('<', ' <', $string);
\r
2058 $string = strip_tags($string);
\r
2059 $string = preg_replace("/\s+/", " ", $string);
\r
2060 $string = trim($string);
\r
2065 * Make a string containing HTML safe for use in a HTML attribute
\r
2066 * Tags are stripped and entities are normalized
\r
2068 function stringToAttribute ($string) {
\r
2069 $string = stringStripTags($string);
\r
2070 $string = entity::named_to_numeric($string);
\r
2071 $string = entity::normalize_numeric($string);
\r
2073 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2074 $string = entity::numeric_to_utf8($string);
\r
2077 $string = entity::specialchars($string, 'html');
\r
2078 $string = entity::numeric_to_named($string);
\r
2083 * Make a string containing HTML safe for use in a XML document
\r
2084 * Tags are stripped, entities are normalized and named entities are
\r
2085 * converted to numeric entities.
\r
2087 function stringToXML ($string) {
\r
2088 $string = stringStripTags($string);
\r
2089 $string = entity::named_to_numeric($string);
\r
2090 $string = entity::normalize_numeric($string);
\r
2092 if (strtoupper(_CHARSET) == 'UTF-8') {
\r
2093 $string = entity::numeric_to_utf8($string);
\r
2096 $string = entity::specialchars($string, 'xml');
\r
2100 // START: functions from the end of file BLOG.php
\r
2101 // used for mail notification (html -> text)
\r
2102 function toAscii($html) {
\r
2103 // strip off most tags
\r
2104 $html = strip_tags($html,'<a>');
\r
2105 $to_replace = "/<a[^>]*href=[\"\']([^\"^']*)[\"\'][^>]*>([^<]*)<\/a>/i";
\r
2107 $ascii = preg_replace_callback ($to_replace, '_links_add', $html);
\r
2108 $ascii .= "\n\n" . _links_list();
\r
2109 return strip_tags($ascii);
\r
2112 function _links_init() {
\r
2113 global $tmp_links;
\r
2114 $tmp_links = array();
\r
2117 function _links_add($match) {
\r
2118 global $tmp_links;
\r
2119 array_push($tmp_links, $match[1]);
\r
2120 return $match[2] . ' [' . sizeof($tmp_links) .']';
\r
2123 function _links_list() {
\r
2124 global $tmp_links;
\r
2127 foreach ($tmp_links as $current) {
\r
2128 $output .= "[$i] $current\n";
\r
2133 // END: functions from the end of file BLOG.php
\r
2135 // START: functions from the end of file ADMIN.php
\r
2137 * @todo document this
\r
2139 function encode_desc(&$data)
\r
2141 // _$to_entities = get_html_translation_table(HTML_ENTITIES);
\r
2142 $to_entities = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
\r
2143 $from_entities = array_flip($to_entities);
\r
2144 $data = str_replace('<br />', '\n', $data); //hack
\r
2145 $data = strtr($data,$from_entities);
\r
2146 $data = strtr($data,$to_entities);
\r
2147 $data = str_replace('\n', '<br />', $data); //hack
\r
2152 * Returns the Javascript code for a bookmarklet that works on most modern browsers
\r
2156 function getBookmarklet($blogid) {
\r
2160 $document = 'document';
\r
2161 $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
2162 $bookmarkletline .= $CONF['AdminURL'] . "bookmarklet.php?blogid=$blogid";
\r
2163 $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
2165 return $bookmarkletline;
\r
2167 // END: functions from the end of file ADMIN.php
\r
2170 * Returns a variable or null if not set
\r
2172 * @param mixed Variable
\r
2173 * @return mixed Variable
\r
2175 function ifset(&$var) {
\r
2176 if (isset($var)) {
\r
2184 * Returns number of subscriber to an event
\r
2187 * @return number of subscriber(s)
\r
2189 function numberOfEventSubscriber($event) {
\r
2190 $query = 'SELECT COUNT(*) as count FROM ' . sql_table('plugin_event') . ' WHERE event=\'' . $event . '\'';
\r
2191 $res = sql_query($query);
\r
2192 $obj = sql_fetch_object($res);
\r
2193 return $obj->count;
\r
2196 function selectSpecialSkinType($id) {
\r
2198 $special = strtolower($id);
\r