4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
\r
5 * Copyright (C) 2002-2005 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
13 * $Id: globalfunctions.php,v 1.4 2005-03-15 07:59:27 kimitake Exp $
\r
17 // needed if we include globalfunctions from install.php
\r
18 global $nucleus, $CONF, $DIR_LIBS, $DIR_LANG, $manager, $member;
\r
21 checkVars(array('nucleus', 'CONF', 'DIR_LIBS', 'MYSQL_HOST', 'MYSQL_USER', 'MYSQL_PASSWORD', 'MYSQL_DATABASE', 'DIR_LANG', 'DIR_PLUGINS'));
\r
25 $nucleus['version'] = 'v3.2';
\r
26 if (getNucleusPatchLevel() > 0)
\r
28 $nucleus['version'] .= '/' . getNucleusPatchLevel();
\r
32 Indicates when Nucleus should display startup errors. Set to 1 if you want
\r
33 the error enabled (default), false otherwise
\r
36 Displays an error when visiting a public Nucleus page and headers have
\r
37 been sent out to early. This usually indicates an error in either a
\r
38 configuration file or a language file, and could cause Nucleus to
\r
41 Displays an error only when visiting the admin area, and when one or
\r
42 more of the installation files (install.php, install.sql, upgrades/
\r
43 directory) are still on the server.
\r
45 $CONF['alertOnHeadersSent'] = 1;
\r
46 $CONF['alertOnSecurityRisk'] = 1;
\r
49 * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)
\r
51 function getNucleusVersion() {
\r
56 * power users can install patches in between nucleus releases. These patches
\r
57 * usually add new functionality in the plugin API and allow those to
\r
58 * be tested without having to install CVS.
\r
60 function getNucleusPatchLevel() {
\r
65 if ($CONF['debug']) {
\r
66 error_reporting(E_ALL & ~E_NOTICE); // report almost all errors!
\r
67 // (no uninitialized vars and such)
\r
69 error_reporting(E_ERROR | E_WARNING | E_PARSE);
\r
72 // we will use postVar, getVar, ... methods instead of HTTP_GET_VARS or _GET
\r
73 if ($CONF['installscript']!=1){ // vars were already included in install.php
\r
74 if (phpversion() >= '4.1.0')
\r
75 include_once($DIR_LIBS . 'vars4.1.0.php');
\r
77 include_once($DIR_LIBS . 'vars4.0.6.php');
\r
80 function intPostVar($name) { return intval(postVar($name));}
\r
81 function intGetVar($name) { return intval(getVar($name));}
\r
82 function intRequestVar($name) { return intval(requestVar($name)); }
\r
83 function intCookieVar($name) { return intval(cookieVar($name)); }
\r
85 // get all variables that can come from the request and put them in the global scope
\r
86 $blogid = requestVar('blogid');
\r
87 $itemid = intRequestVar('itemid');
\r
88 $catid = intRequestVar('catid');
\r
89 $skinid = requestVar('skinid');
\r
90 $memberid = requestVar('memberid');
\r
91 $archivelist = requestVar('archivelist');
\r
92 $imagepopup = requestVar('imagepopup');
\r
93 $archive = requestVar('archive');
\r
94 $query = requestVar('query');
\r
95 $highlight = requestVar('highlight');
\r
96 $amount = requestVar('amount');
\r
97 $action = requestVar('action');
\r
98 $nextaction = requestVar('nextaction');
\r
99 $maxresults = requestVar('maxresults');
\r
100 $startpos = intRequestVar('startpos');
\r
101 $errormessage = '';
\r
104 if (!headers_sent())
\r
105 header('Generator: Nucleus CMS ' . $nucleus['version']);
\r
107 // include core classes that are needed for login & plugin handling
\r
108 include($DIR_LIBS . 'MEMBER.php');
\r
109 include($DIR_LIBS . 'ACTIONLOG.php');
\r
110 include($DIR_LIBS . 'MANAGER.php');
\r
111 include($DIR_LIBS . 'PLUGIN.php');
\r
113 $manager =& MANAGER::instance();
\r
115 // make sure there's no unnecessary escaping:
\r
116 set_magic_quotes_runtime(0);
\r
118 // only needed when updating logs
\r
119 if ($CONF['UsingAdminArea']) {
\r
120 include($DIR_LIBS . 'xmlrpc.inc.php'); // XML-RPC client classes
\r
121 include_once($DIR_LIBS . 'ADMIN.php');
\r
128 // makes sure database connection gets closed on script termination
\r
129 register_shutdown_function('sql_disconnect');
\r
134 // automatically use simpler toolbar for mozilla
\r
135 if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'),'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'),'Gecko'))
\r
136 $CONF['DisableJsTools'] = 2;
\r
138 // login if cookies set
\r
140 $member =& new MEMBER();
\r
142 // login/logout when required or renew cookies
\r
143 if ($action == 'login') {
\r
144 // Form Authentication
\r
145 $login = postVar('login');
\r
146 $pw = postVar('password');
\r
147 $shared = intPostVar('shared'); // shared computer or not
\r
149 if ($member->login($login,$pw)) {
\r
151 $member->newCookieKey();
\r
152 $member->setCookies($shared);
\r
154 // allows direct access to parts of the admin area after logging in
\r
156 $action = $nextaction;
\r
158 $manager->notify('LoginSuccess',array('member' => &$member));
\r
159 ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");
\r
161 $manager->notify('LoginFailed',array('username' => $login));
\r
162 ACTIONLOG::add(INFO, 'Login failed for ' . $login);
\r
166 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
168 } elseif (serverVar('PHP_AUTH_USER') && serverVar('PHP_AUTH_PW')) {
\r
169 // HTTP Authentication
\r
170 $login = serverVar('PHP_AUTH_USER');
\r
171 $pw = serverVar('PHP_AUTH_PW');
\r
173 if ($member->login($login,$pw)) {
\r
174 $manager->notify('LoginSuccess',array('member' => &$member));
\r
175 ACTIONLOG::add(INFO, "HTTP authentication successful for $login");
\r
177 $manager->notify('LoginFailed',array('username' => $login));
\r
178 ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);
\r
180 //Since bad credentials, generate an apropriate error page
\r
181 header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");
\r
182 header('HTTP/1.0 401 Unauthorized');
\r
183 echo 'Invalid username or password';
\r
188 } elseif (($action == 'logout') && (!headers_sent()) && cookieVar($CONF['CookiePrefix'] . 'user')){
\r
189 // remove cookies on logout
\r
190 setcookie($CONF['CookiePrefix'] .'user','',(time()-2592000),$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
\r
191 setcookie($CONF['CookiePrefix'] .'loginkey','',(time()-2592000),$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
\r
192 $manager->notify('Logout',array('username' => cookieVar($CONF['CookiePrefix'] .'user')));
\r
193 } elseif (cookieVar($CONF['CookiePrefix'] .'user')) {
\r
194 // Cookie Authentication
\r
195 $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] .'user'), cookieVar($CONF['CookiePrefix'] .'loginkey'));
\r
197 // renew cookies when not on a shared computer
\r
198 if ($res && (cookieVar($CONF['CookiePrefix'] .'sharedpc') != 1) && (!headers_sent()))
\r
199 $member->setCookies();
\r
203 $manager->notify('PostAuthentication',array('loggedIn' => $member->isLoggedIn()));
\r
205 // first, let's see if the site is disabled or not
\r
206 if ($CONF['DisableSite'] && !$member->isAdmin()) {
\r
207 redirect($CONF['DisableSiteURL']);
\r
211 // load other classes
\r
212 include($DIR_LIBS . 'PARSER.php');
\r
213 include($DIR_LIBS . 'SKIN.php');
\r
214 include($DIR_LIBS . 'TEMPLATE.php');
\r
215 include($DIR_LIBS . 'BLOG.php');
\r
216 include($DIR_LIBS . 'COMMENTS.php');
\r
217 include($DIR_LIBS . 'COMMENT.php');
\r
218 //include($DIR_LIBS . 'ITEM.php');
\r
219 include($DIR_LIBS . 'NOTIFICATION.php');
\r
220 include($DIR_LIBS . 'BAN.php');
\r
221 include($DIR_LIBS . 'PAGEFACTORY.php');
\r
222 include($DIR_LIBS . 'SEARCH.php');
\r
225 // set lastVisit cookie (if allowed)
\r
226 if (!headers_sent()) {
\r
227 if ($CONF['LastVisit'])
\r
228 setcookie($CONF['CookiePrefix'] .'lastVisit',time(),time()+2592000,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
\r
230 setcookie($CONF['CookiePrefix'] .'lastVisit','',(time()-2592000),$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
\r
233 // read language file, only after user has been initialized
\r
234 $language = getLanguageName();
\r
235 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
\r
238 Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
\r
240 // To remove after v2.5 is released and language files have been updated.
\r
241 // Including this makes sure that language files for v2.5beta can still be used for v2.5final
\r
242 // without having weird _SETTINGS_EXTAUTH string showing up in the admin area.
\r
243 if (!defined('_MEMBERS_BYPASS'))
\r
245 define('_SETTINGS_EXTAUTH', 'Enable External Authentication');
\r
246 define('_WARNING_EXTAUTH', 'Warning: Enable only if needed.');
\r
247 define('_MEMBERS_BYPASS', 'Use External Authentication');
\r
252 // make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined
\r
253 if (!defined('_ARCHIVETYPE_MONTH'))
\r
255 define('_ARCHIVETYPE_DAY','day');
\r
256 define('_ARCHIVETYPE_MONTH','month');
\r
260 // decode path_info
\r
261 if ($CONF['URLMode'] == 'pathinfo') {
\r
262 $data = explode("/",serverVar('PATH_INFO'));
\r
263 for ($i=0;$i<sizeof($data);$i++) {
\r
264 switch ($data[$i]) {
\r
265 case 'item': // item/1 (blogid)
\r
267 if ($i<sizeof($data)) $itemid = intval($data[$i]);
\r
269 case 'archives': // archives/1 (blogid)
\r
271 if ($i<sizeof($data)) $archivelist = intval($data[$i]);
\r
273 case 'archive': // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)
\r
274 if ((($i+1)<sizeof($data)) && (!strstr($data[$i+1],'-')) ){
\r
275 $blogid = intval($data[++$i]);
\r
278 if ($i<sizeof($data)) $archive = $data[$i];
\r
280 case 'blogid': // blogid/1
\r
281 case 'blog': // blog/1
\r
283 if ($i<sizeof($data)) $blogid = intval($data[$i]);
\r
285 case 'category': // category/1 (catid)
\r
288 if ($i<sizeof($data)) $catid = intval($data[$i]);
\r
292 if ($i<sizeof($data)) $memberid = intval($data[$i]);
\r
301 * Connects to mysql server
\r
303 function sql_connect() {
\r
304 global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE;
\r
306 $connection = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>','Connect Error');
\r
307 mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: '. mysql_error().'</p>', 'Connect Error');
\r
309 return $connection;
\r
313 * returns a prefixed nucleus table name
\r
315 function sql_table($name)
\r
317 global $MYSQL_PREFIX;
\r
320 return $MYSQL_PREFIX . 'nucleus_' . $name;
\r
322 return 'nucleus_' . $name;
\r
325 function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
\r
326 global $manager, $CONF;
\r
328 if (!headers_sent()) {
\r
329 // if content type is application/xhtml+xml, only send it to browsers
\r
330 // that can handle it (IE6 cannot). Otherwise, send text/html
\r
332 // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)
\r
333 // application/xhtml+xml still causes too much problems with the javascript implementations
\r
335 ($contenttype == 'application/xhtml+xml')
\r
336 && (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))
\r
339 $contenttype = 'text/html';
\r
343 'PreSendContentType',
\r
345 'contentType' => &$contenttype,
\r
346 'charset' => &$charset,
\r
347 'pageType' => $pagetype
\r
351 // strip strange characters
\r
352 $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);
\r
353 $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);
\r
355 header('Content-Type: ' . $contenttype . '; charset=' . $charset);
\r
364 * Errors before the database connection has been made
\r
366 function startUpError($msg, $title) {
\r
368 <html xmlns="http://www.w3.org/1999/xhtml">
\r
369 <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title><?php echo htmlspecialchars($title)?></title></head>
\r
371 <h1><?php echo htmlspecialchars($title)?></h1>
\r
379 * disconnects from SQL server
\r
381 function sql_disconnect() {
\r
386 * executes an SQL query
\r
388 function sql_query($query) {
\r
389 $res = mysql_query($query) or print("mySQL error with query $query: " . mysql_error() . '<p />');
\r
395 * Highlights a specific query in a given HTML text (not within HTML tags) and returns it
\r
398 * text to be highlighted
\r
399 * @param $expression
\r
400 * regular expression to be matched (can be an array of expressions as well)
\r
401 * @param $highlight
\r
402 * highlight to be used (use \\0 to indicate the matched expression)
\r
405 function highlight($text, $expression, $highlight) {
\r
406 if (!$highlight || !$expression) return $text;
\r
407 if (is_array($expression) && (count($expression) == 0))
\r
410 // add a tag in front (is needed for preg_match_all to work correct)
\r
411 $text = '<!--h-->'.$text;
\r
413 // split the HTML up so we have HTML tags
\r
414 // $matches[0][i] = HTML + text
\r
415 // $matches[1][i] = HTML
\r
416 // $matches[2][i] = text
\r
417 preg_match_all('/(<[^>]+>)([^<>]*)/', $text, $matches);
\r
419 // throw it all together again while applying the highlight to the text pieces
\r
421 for ($i = 0; $i < sizeof($matches[2]); $i++) {
\r
422 if ($i != 0) $result .= $matches[1][$i];
\r
424 if (is_array($expression)) {
\r
425 foreach ($expression as $regex)
\r
427 $matches[2][$i] = @eregi_replace($regex,$highlight,$matches[2][$i]);
\r
428 $result .= $matches[2][$i];
\r
430 $result .= @eregi_replace($expression,$highlight,$matches[2][$i]);
\r
438 * Parses a query into an array of expressions that can be passed on to the highlight method
\r
440 function parseHighlight($query) {
\r
441 // TODO: add more intelligent splitting logic
\r
443 // get rid of quotes
\r
444 $query = preg_replace('/\'|"/','',$query);
\r
446 if (!query) return array();
\r
448 $aHighlight = explode(' ', $query);
\r
450 for ($i = 0; $i<count($aHighlight); $i++) {
\r
451 $aHighlight[$i] = trim($aHighlight[$i]);
\r
452 if (strlen($aHighlight[$i]) < 3)
\r
453 unset($aHighlight[$i]);
\r
456 if (count($aHighlight) == 1)
\r
457 return $aHighlight[0];
\r
459 return $aHighlight;
\r
463 * Checks if email address is valid
\r
465 function isValidMailAddress($address) {
\r
466 if (preg_match('/^[a-zA-Z0-9\._-]+@[a-zA-Z0-9\._-]+\.[A-Za-z]{2,5}$/', $address))
\r
473 // some helper functions
\r
474 function getBlogIDFromName($name) {
\r
475 return quickQuery('SELECT bnumber as result FROM '.sql_table('blog').' WHERE bshortname="'.addslashes($name).'"');
\r
477 function getBlogNameFromID($id) {
\r
478 return quickQuery('SELECT bname as result FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
\r
480 function getBlogIDFromItemID($itemid) {
\r
481 return quickQuery('SELECT iblog as result FROM '.sql_table('item').' WHERE inumber='.intval($itemid));
\r
483 function getBlogIDFromCommentID($commentid) {
\r
484 return quickQuery('SELECT cblog as result FROM '.sql_table('comment').' WHERE cnumber='.intval($commentid));
\r
486 function getBlogIDFromCatID($catid) {
\r
487 return quickQuery('SELECT cblog as result FROM '.sql_table('category').' WHERE catid='.intval($catid));
\r
489 function getCatIDFromName($name) {
\r
490 return quickQuery('SELECT catid as result FROM '.sql_table('category').' WHERE cname="'.addslashes($name).'"');
\r
492 function quickQuery($q) {
\r
493 $res = sql_query($q);
\r
494 $obj = mysql_fetch_object($res);
\r
495 return $obj->result;
\r
498 function getPluginNameFromPid($pid) {
\r
499 $obj = mysql_fetch_object(sql_query('SELECT pfile FROM '.sql_table('plugin').' WHERE pid='.intval($pid)));
\r
500 return $obj->pfile;
\r
503 function selector() {
\r
504 global $itemid, $blogid, $memberid, $query, $amount, $archivelist, $maxresults;
\r
505 global $archive, $skinid, $blog, $memberinfo, $CONF, $member;
\r
506 global $imagepopup, $catid;
\r
509 $actionNames = array('addcomment', 'sendmessage', 'createaccount', 'forgotpassword', 'votepositive', 'votenegative', 'plugin');
\r
510 $action = requestVar('action');
\r
511 if (in_array($action, $actionNames))
\r
513 global $DIR_LIBS, $errormessage;
\r
514 include_once($DIR_LIBS . 'ACTION.php');
\r
515 $a =& new ACTION();
\r
516 $errorInfo = $a->doAction($action);
\r
518 $errormessage = $errorInfo['message'];
\r
521 // show error when headers already sent out
\r
522 if (headers_sent() && $CONF['alertOnHeadersSent']) {
\r
524 // try to get line number/filename (extra headers_sent params only exists in PHP 4.3+)
\r
525 if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=')) {
\r
526 headers_sent($hsFile, $hsLine);
\r
527 $extraInfo = ' in <code>'.$hsFile.'</code> line <code>'.$hsLine.'</code>';
\r
534 '<p>The page headers have already been sent out'.$extraInfo.'. This could cause Nucleus not to work in the expected way.</p><p>Usually, this is caused by spaces or newlines at the end of the <code>config.php</code> file, at the end of the language file or at the end of a plugin file. Please check this and try again.</p><p>If you don\'t want to see this error message again, without solving the problem, set <code>$CONF[\'alertOnHeadersSent\']</code> in <code>globalfunctions.php</code> to <code>0</code></p>',
\r
535 'Page headers already sent'
\r
540 // make is so ?archivelist without blogname or blogid shows the archivelist
\r
541 // for the default weblog
\r
542 if (serverVar('QUERY_STRING') == 'archivelist')
\r
543 $archivelist = $CONF['DefaultBlog'];
\r
545 // now decide which type of skin we need
\r
547 // itemid given -> only show that item
\r
549 if (!$manager->existsItem($itemid,0,0))
\r
550 doError(_ERROR_NOSUCHITEM);
\r
553 global $itemidprev, $itemidnext, $catid, $itemtitlenext, $itemtitleprev;
\r
555 // 1. get timestamp and blogid for item
\r
556 $query = 'SELECT itime, iblog FROM '.sql_table('item').' WHERE inumber=' . intval($itemid);
\r
557 $res = sql_query($query);
\r
558 $obj = mysql_fetch_object($res);
\r
560 // if a different blog id has been set through the request or selectBlog(),
\r
562 if ($blogid && (intval($blogid) != $obj->iblog))
\r
563 doError(_ERROR_NOSUCHITEM);
\r
565 $blogid = $obj->iblog;
\r
566 $timestamp = strtotime($obj->itime);
\r
568 $b =& $manager->getBlog($blogid);
\r
569 if ($b->isValidCategory($catid))
\r
570 $catextra = ' and icat=' . $catid;
\r
572 // get previous itemid and title
\r
573 $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
574 $res = sql_query($query);
\r
576 $obj = mysql_fetch_object($res);
\r
578 $itemidprev = $obj->inumber;
\r
579 $itemtitleprev = $obj->ititle;
\r
582 // get next itemid and title
\r
583 $query = 'SELECT inumber, ititle FROM '.sql_table('item').' WHERE itime>' . mysqldate($timestamp) . ' and itime <= ' . mysqldate(time()) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime ASC LIMIT 1';
\r
584 $res = sql_query($query);
\r
586 $obj = mysql_fetch_object($res);
\r
588 $itemidnext = $obj->inumber;
\r
589 $itemtitlenext = $obj->ititle;
\r
592 } elseif ($archive) {
\r
596 // get next and prev month links
\r
597 global $archivenext, $archiveprev, $archivetype;
\r
599 sscanf($archive,'%d-%d-%d',$y,$m,$d);
\r
601 $archivetype = _ARCHIVETYPE_DAY;
\r
602 $t = mktime(0,0,0,$m,$d,$y);
\r
603 $archiveprev = strftime('%Y-%m-%d',$t - (24*60*60));
\r
604 $archivenext = strftime('%Y-%m-%d',$t + (24*60*60));
\r
607 $archivetype = _ARCHIVETYPE_MONTH;
\r
608 $t = mktime(0,0,0,$m,1,$y);
\r
609 $archiveprev = strftime('%Y-%m',$t - (1*24*60*60));
\r
610 $archivenext = strftime('%Y-%m',$t + (32*24*60*60));
\r
614 } elseif ($archivelist) {
\r
615 $type = 'archivelist';
\r
616 if (intval($archivelist) != 0)
\r
617 $blogid = $archivelist;
\r
619 $blogid = getBlogIDFromName($archivelist);
\r
620 if (!$blogid) doError(_ERROR_NOSUCHBLOG);
\r
621 } elseif ($query) {
\r
624 $query = stripslashes($query);
\r
625 if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/",$query)){
\r
628 $order = (_CHARSET == 'EUC-JP') ? 'EUC-JP, UTF-8,' : 'UTF-8, EUC-JP,';
\r
629 $query = mb_convert_encoding($query, _CHARSET, $order.' JIS, SJIS, ASCII');
\r
630 if (intval($blogid)==0)
\r
631 $blogid = getBlogIDFromName($blogid);
\r
632 if (!$blogid) doError(_ERROR_NOSUCHBLOG);
\r
633 } elseif ($memberid) {
\r
635 if (!MEMBER::existsID($memberid))
\r
636 doError(_ERROR_NOSUCHMEMBER);
\r
637 $memberinfo = MEMBER::createFromID($memberid);
\r
639 } elseif ($imagepopup) {
\r
640 // media object (images etc.)
\r
641 $type = 'imagepopup';
\r
643 // TODO: check if media-object exists
\r
644 // TODO: set some vars?
\r
646 // show regular index page
\r
651 // decide which blog should be displayed
\r
653 $blogid = $CONF['DefaultBlog'];
\r
655 $b =& $manager->getBlog($blogid);
\r
656 $blog = $b; // references can't be placed in global variables?
\r
657 if (!$blog->isValid)
\r
658 doError(_ERROR_NOSUCHBLOG);
\r
660 // set catid if necessary
\r
662 $blog->setSelectedCategory($catid);
\r
664 // decide which skin should be used
\r
665 if ($skinid != '' && ($skinid == 0))
\r
666 selectSkin($skinid);
\r
668 $skinid = $blog->getDefaultSkin();
\r
671 $skin =& new SKIN($skinid);
\r
672 if (!$skin->isValid)
\r
673 doError(_ERROR_NOSUCHSKIN);
\r
676 $skin->parse($type);
\r
680 * Show error skin with given message. An optional skin-object to use can be given
\r
682 function doError($msg, $skin = '') {
\r
683 global $errormessage, $CONF, $skinid, $blogid, $manager;
\r
686 if (SKIN::existsID($skinid)) {
\r
687 $skin =& new SKIN($skinid);
\r
688 } elseif ($manager->existsBlogID($blogid)) {
\r
689 $blog =& $manager->getBlog($blogid);
\r
690 $skin =& new SKIN($blog->getDefaultSkin());
\r
691 } elseif ($CONF['DefaultBlog']) {
\r
692 $blog =& $manager->getBlog($CONF['DefaultBlog']);
\r
693 $skin =& new SKIN($blog->getDefaultSkin());
\r
695 // this statement should actually never be executed
\r
696 $skin =& new SKIN($CONF['BaseSkin']);
\r
700 $errormessage = $msg;
\r
701 $skin->parse('error');
\r
705 function getConfig() {
\r
708 $query = 'SELECT * FROM '.sql_table('config');
\r
709 $res = sql_query($query);
\r
710 while ($obj = mysql_fetch_object($res)) {
\r
711 $CONF[$obj->name] = $obj->value;
\r
715 // some checks for names of blogs, categories, templates, members, ...
\r
716 function isValidShortName($name) { return eregi('^[a-z0-9]+$', $name); }
\r
717 function isValidDisplayName($name) { return eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name); }
\r
718 function isValidCategoryName($name) { return 1; }
\r
719 function isValidTemplateName($name) { return eregi('^[a-z0-9/]+$', $name); }
\r
720 function isValidSkinName($name) { return eregi('^[a-z0-9/]+$', $name); }
\r
722 // add and remove linebreaks
\r
723 function addBreaks($var) { return nl2br($var); }
\r
724 function removeBreaks($var) { return preg_replace("/<br \/>([\r\n])/","$1",$var); }
\r
726 // shortens a text string to maxlength ($toadd) is what needs to be added
\r
727 // at the end (end length is <= $maxlength)
\r
728 function shorten($text, $maxlength, $toadd) {
\r
729 // 1. remove entities...
\r
730 $trans = get_html_translation_table(HTML_ENTITIES);
\r
731 $trans = array_flip($trans);
\r
732 $text = strtr($text, $trans);
\r
733 // 2. the actual shortening
\r
734 if (strlen($text) > $maxlength)
\r
735 $text = mb_strimwidth($text, 0, $maxlength, $toadd, _CHARSET);
\r
740 * Converts a unix timestamp to a mysql DATETIME format, and places
\r
741 * quotes around it.
\r
743 function mysqldate($timestamp) {
\r
744 return '"' . date('Y-m-d H:i:s',$timestamp) . '"';
\r
748 * functions for use in index.php
\r
750 function selectBlog($shortname) {
\r
751 global $blogid, $archivelist;
\r
752 $blogid = getBlogIDFromName($shortname);
\r
754 // also force archivelist variable, if it is set
\r
756 $archivelist = $blogid;
\r
759 function selectSkin($skinname) {
\r
761 $skinid = SKIN::getIdFromName($skinname);
\r
765 * Can take either a category ID or a category name (be aware that
\r
766 * multiple categories can have the same name)
\r
768 function selectCategory($cat) {
\r
770 if (is_numeric($cat))
\r
771 $catid = intval($cat);
\r
773 $catid = getCatIDFromName($cat);
\r
776 function selectItem($id){
\r
778 $itemid = intval($id);
\r
781 // force the use of a language file (warning: can cause warnings)
\r
782 function selectLanguage($language) {
\r
784 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
\r
787 function parseFile($filename) {
\r
788 $handler =& new ACTIONS('fileparser');
\r
789 $parser =& new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);
\r
790 $handler->parser =& $parser;
\r
792 if (!file_exists($filename)) doError('A file is missing');
\r
794 $fsize = filesize($filename);
\r
799 $fd = fopen ($filename, 'r');
\r
800 $contents = fread ($fd, $fsize);
\r
803 // parse file contents
\r
804 $parser->parse($contents);
\r
808 * Outputs a debug message
\r
810 function debug($msg) {
\r
811 echo '<p><b>' . $msg . "</b></p>\n";
\r
815 function addToLog($level, $msg) { ACTIONLOG::add($level, $msg); }
\r
817 // shows a link to help file
\r
818 function help($id) {
\r
819 echo helpHtml($id);
\r
822 function helpHtml($id) {
\r
823 return helplink($id) . '<img src="documentation/icon-help.gif" width="15" height="15" alt="'._HELP_TT.'" /></a>';
\r
826 function helplink($id) {
\r
827 return '<a href="documentation/help.html#'. $id . '" onclick="if (event && event.preventDefault) event.preventDefault(); return help(this.href);">';
\r
830 function getMailFooter() {
\r
831 $message = "\n\n-----------------------------";
\r
832 $message .= "\n Powered by Nucleus CMS";
\r
833 $message .= "\n(http://www.nucleuscms.org/)";
\r
838 * Returns the name of the language to use
\r
839 * preference priority: member - site
\r
840 * defaults to english when no good language found
\r
842 * checks if file exists, etc...
\r
844 function getLanguageName() {
\r
845 global $CONF, $member;
\r
848 // try to use members language
\r
849 $memlang = $member->getLanguage();
\r
851 if (($memlang != '') && (checkLanguage($memlang)))
\r
855 // use default language
\r
856 if (checkLanguage($CONF['Language']))
\r
857 return $CONF['Language'];
\r
863 * Includes a PHP file. This method can be called while parsing templates and skins
\r
865 function includephp($filename) {
\r
866 // make predefined variables global, so most simple scripts can be used here
\r
868 // apache (names taken from PHP doc)
\r
869 global $GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE, $SERVER_PROTOCOL;
\r
870 global $REQUEST_METHOD, $QUERY_STRING, $DOCUMENT_ROOT, $HTTP_ACCEPT;
\r
871 global $HTTP_ACCEPT_CHARSET, $HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE;
\r
872 global $HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER, $HTTP_USER_AGENT;
\r
873 global $REMOTE_ADDR, $REMOTE_PORT, $SCRIPT_FILENAME, $SERVER_ADMIN;
\r
874 global $SERVER_PORT, $SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME;
\r
875 global $REQUEST_URI;
\r
877 // php (taken from PHP doc)
\r
878 global $argv, $argc, $PHP_SELF, $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS;
\r
879 global $HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS, $HTTP_SESSION_VARS;
\r
882 global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;
\r
884 if (@file_exists($filename)) include($filename);
\r
888 * Checks if a certain language/plugin exists
\r
890 function checkLanguage($lang) {
\r
892 return file_exists($DIR_LANG . ereg_replace( '[\\|/]', '', $lang) . '.php');
\r
894 function checkPlugin($plug) {
\r
895 global $DIR_PLUGINS;
\r
896 return file_exists($DIR_PLUGINS . ereg_replace( '[\\|/]', '', $plug) . '.php');
\r
900 $CONF['ItemURL'] = $CONF['Self'];
\r
901 $CONF['ArchiveURL'] = $CONF['Self'];
\r
902 $CONF['ArchiveListURL'] = $CONF['Self'];
\r
903 $CONF['MemberURL'] = $CONF['Self'];
\r
904 $CONF['SearchURL'] = $CONF['Self'];
\r
905 $CONF['BlogURL'] = $CONF['Self'];
\r
906 $CONF['CategoryURL'] = $CONF['Self'];
\r
908 // switch URLMode back to normal when $CONF['Self'] ends in .php
\r
909 // this avoids urls like index.php/item/13/index.php/item/15
\r
910 if ( ($CONF['URLMode'] == 'pathinfo')
\r
911 && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php')
\r
913 $CONF['URLMode'] = 'normal';
\r
917 * Centralisation of the functions that generate links
\r
919 function createItemLink($itemid, $extra = '') {
\r
921 if ($CONF['URLMode'] == 'pathinfo')
\r
922 $link = $CONF['ItemURL'] . '/item/' . $itemid;
\r
924 $link = $CONF['ItemURL'] . '?itemid=' . $itemid;
\r
925 return addLinkParams($link, $extra);
\r
927 function createMemberLink($memberid, $extra = '') {
\r
929 if ($CONF['URLMode'] == 'pathinfo')
\r
930 $link = $CONF['MemberURL'] . '/member/' . $memberid;
\r
932 $link = $CONF['MemberURL'] . '?memberid=' . $memberid;
\r
933 return addLinkParams($link, $extra);
\r
935 function createCategoryLink($catid, $extra = '') {
\r
937 if ($CONF['URLMode'] == 'pathinfo')
\r
938 $link = $CONF['CategoryURL'] . '/category/' . $catid;
\r
940 $link = $CONF['CategoryURL'] . '?catid=' . $catid;
\r
941 return addLinkParams($link, $extra);
\r
943 function createArchiveListLink($blogid = '', $extra = '') {
\r
946 $blogid = $CONF['DefaultBlog'];
\r
947 if ($CONF['URLMode'] == 'pathinfo')
\r
948 $link = $CONF['ArchiveListURL'] . '/archives/' . $blogid;
\r
950 $link = $CONF['ArchiveListURL'] . '?archivelist=' . $blogid;
\r
951 return addLinkParams($link, $extra);
\r
953 function createArchiveLink($blogid, $archive, $extra = '') {
\r
955 if ($CONF['URLMode'] == 'pathinfo')
\r
956 $link = $CONF['ArchiveURL'] . '/archive/'.$blogid.'/' . $archive;
\r
958 $link = $CONF['ArchiveURL'] . '?blogid='.$blogid.'&archive=' . $archive;
\r
959 return addLinkParams($link, $extra);
\r
961 function createBlogLink($url, $params) {
\r
962 return addLinkParams($url . '?', $params);
\r
964 function createBlogidLink($blogid, $params = '') {
\r
966 if ($CONF['URLMode'] == 'pathinfo')
\r
967 $link = $CONF['BlogURL'] . '/blog/' . $blogid;
\r
969 $link = $CONF['BlogURL'] . '?blogid=' . $blogid;
\r
970 return addLinkParams($link, $params);
\r
974 function addLinkParams($link, $params) {
\r
976 if (is_array($params)) {
\r
977 if ($CONF['URLMode'] == 'pathinfo') {
\r
978 foreach ($params as $param => $value) {
\r
979 $link .= '/' . $param . '/' . urlencode($value);
\r
982 foreach ($params as $param => $value) {
\r
983 $link .= '&' . $param . '=' . urlencode($value);
\r
992 * querystring to alter (e.g. foo=1&bar=2&x=y)
\r
994 * name of parameter to change (e.g. 'foo')
\r
996 * New value for that parameter (e.g. 3)
\r
998 * altered query string (for the examples above: foo=3&bar=2&x=y)
\r
1000 function alterQueryStr($querystr, $param, $value) {
\r
1001 $vars = explode("&", $querystr);
\r
1003 for ($i=0;$i<count($vars);$i++) {
\r
1004 $v = explode('=',$vars[$i]);
\r
1005 if ($v[0] == $param) {
\r
1007 $vars[$i] = implode('=', $v);
\r
1012 if (!$set) {$vars[] = $param . '=' . $value;}
\r
1013 return ltrim(implode('&', $vars), '&');
\r
1016 // passes one variable as hidden input field (multiple fields for arrays)
\r
1017 // @see passRequestVars in varsx.x.x.php
\r
1018 function passVar($key, $value) {
\r
1020 if (is_array($value)) {
\r
1021 for ($i=0;$i<sizeof($value);$i++)
\r
1022 passVar($key.'['.$i.']',$value[$i]);
\r
1026 // other values: do stripslashes if needed
\r
1027 ?><input type="hidden" name="<?php echo htmlspecialchars($key)?>" value="<?php echo htmlspecialchars(undoMagic($value))?>" /><?php
\r
1031 Date format functions (to be used from [%date(..)%] skinvars
\r
1033 function formatDate($format, $timestamp, $defaultFormat) {
\r
1034 if ($format == 'rfc822') {
\r
1035 return date('r', $timestamp);
\r
1036 } else if ($format == 'rfc822GMT') {
\r
1037 return gmdate('r', $timestamp);
\r
1038 } else if ($format == 'utc') {
\r
1039 return gmdate('Y-m-d\TH:i:s\Z', $timestamp);
\r
1040 } else if ($format == 'iso8601') {
\r
1041 $tz = date('O', $timestamp);
\r
1042 $tz = substr($tz, 0, 3) . ':' . substr($tz, 3, 2);
\r
1043 return gmdate('Y-m-d\TH:i:s', $timestamp) . $tz;
\r
1045 return strftime($format ? $format : $defaultFormat,$timestamp);
\r
1050 function checkVars($aVars)
\r
1052 global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;
\r
1053 foreach ($aVars as $varName)
\r
1055 if (phpversion() >= '4.1.0')
\r
1057 if ( isset($_GET[$varName])
\r
1058 || isset($_POST[$varName])
\r
1059 || isset($_COOKIE[$varName])
\r
1060 || isset($_ENV[$varName])
\r
1061 || isset($_SESSION[$varName])
\r
1062 || isset($_FILES[$varName])
\r
1064 die('Sorry. An error occurred.');
\r
1067 if ( isset($HTTP_GET_VARS[$varName])
\r
1068 || isset($HTTP_POST_VARS[$varName])
\r
1069 || isset($HTTP_COOKIE_VARS[$varName])
\r
1070 || isset($HTTP_ENV_VARS[$varName])
\r
1071 || isset($HTTP_SESSION_VARS[$varName])
\r
1072 || isset($HTTP_POST_FILES[$varName])
\r
1074 die('Sorry. An error occurred.');
\r
1081 * Stops processing the request and redirects to the given URL.
\r
1082 * - no actual contents should have been sent to the output yet
\r
1083 * - the URL will be stripped of illegal or dangerous characters
\r
1085 function redirect($url)
\r
1087 $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%]|i', '', $url);
\r
1088 header('Location: ' . $url);
\r