+/*\r
+ Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details\r
+\r
+// To remove after v2.5 is released and language files have been updated.\r
+// Including this makes sure that language files for v2.5beta can still be used for v2.5final\r
+// without having weird _SETTINGS_EXTAUTH string showing up in the admin area.\r
+if (!defined('_MEMBERS_BYPASS'))\r
+{\r
+ define('_SETTINGS_EXTAUTH', 'Enable External Authentication');\r
+ define('_WARNING_EXTAUTH', 'Warning: Enable only if needed.');\r
+ define('_MEMBERS_BYPASS', 'Use External Authentication');\r
+}\r
+\r
+*/\r
+\r
+// make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined\r
+if (!defined('_ARCHIVETYPE_MONTH') )\r
+{\r
+ define('_ARCHIVETYPE_DAY', 'day');\r
+ define('_ARCHIVETYPE_MONTH', 'month');\r
+ define('_ARCHIVETYPE_YEAR', 'year');\r
+}\r
+\r
+// decode path_info\r
+if ($CONF['URLMode'] == 'pathinfo') {\r
+ // initialize keywords if this hasn't been done before\r
+ if (!isset($CONF['ItemKey']) || $CONF['ItemKey'] == '') {\r
+ $CONF['ItemKey'] = 'item';\r
+ }\r
+\r
+ if (!isset($CONF['ArchiveKey']) || $CONF['ArchiveKey'] == '') {\r
+ $CONF['ArchiveKey'] = 'archive';\r
+ }\r
+\r
+ if (!isset($CONF['ArchivesKey']) || $CONF['ArchivesKey'] == '') {\r
+ $CONF['ArchivesKey'] = 'archives';\r
+ }\r
+\r
+ if (!isset($CONF['MemberKey']) || $CONF['MemberKey'] == '') {\r
+ $CONF['MemberKey'] = 'member';\r
+ }\r
+\r
+ if (!isset($CONF['BlogKey']) || $CONF['BlogKey'] == '') {\r
+ $CONF['BlogKey'] = 'blog';\r
+ }\r
+\r
+ if (!isset($CONF['CategoryKey']) || $CONF['CategoryKey'] == '') {\r
+ $CONF['CategoryKey'] = 'category';\r
+ }\r
+\r
+ if (!isset($CONF['SpecialskinKey']) || $CONF['SpecialskinKey'] == '') {\r
+ $CONF['SpecialskinKey'] = 'special';\r
+ }\r
+\r
+ $parsed = false;\r
+ $manager->notify(\r
+ 'ParseURL',\r
+ array(\r
+ 'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...\r
+ 'info' => $virtualpath,\r
+ 'complete' => &$parsed\r
+ )\r
+ );\r
+\r
+ if (!$parsed) {\r
+ // default implementation\r
+ $data = explode("/", $virtualpath );\r
+ for ($i = 0; $i < sizeof($data); $i++) {\r
+ switch ($data[$i]) {\r
+ case $CONF['ItemKey']: // item/1 (blogid)\r
+ $i++;\r
+\r
+ if ($i < sizeof($data) ) {\r
+ $itemid = intval($data[$i]);\r
+ }\r
+ break;\r
+\r
+ case $CONF['ArchivesKey']: // archives/1 (blogid)\r
+ $i++;\r
+\r
+ if ($i < sizeof($data) ) {\r
+ $archivelist = intval($data[$i]);\r
+ }\r
+ break;\r
+\r
+ case $CONF['ArchiveKey']: // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)\r
+ if ((($i + 1) < sizeof($data) ) && (!strstr($data[$i + 1], '-') ) ) {\r
+ $blogid = intval($data[++$i]);\r
+ }\r
+\r
+ $i++;\r
+\r
+ if ($i < sizeof($data) ) {\r
+ $archive = $data[$i];\r
+ }\r
+ break;\r
+\r
+ case 'blogid': // blogid/1\r
+ case $CONF['BlogKey']: // blog/1\r
+ $i++;\r
+\r
+ if ($i < sizeof($data) ) {\r
+ $blogid = intval($data[$i]);\r
+ }\r
+ break;\r
+\r
+ case $CONF['CategoryKey']: // category/1 (catid)\r
+ case 'catid':\r
+ $i++;\r
+\r
+ if ($i < sizeof($data) ) {\r
+ $catid = intval($data[$i]);\r
+ }\r
+ break;\r
+\r
+ case $CONF['MemberKey']:\r
+ $i++;\r
+\r
+ if ($i < sizeof($data) ) {\r
+ $memberid = intval($data[$i]);\r
+ }\r
+ break;\r
+\r
+ case $CONF['SpecialskinKey']:\r
+ $i++;\r
+\r
+ if ($i < sizeof($data) ) {\r
+ $_REQUEST['special'] = $data[$i];\r
+ }\r
+ break;\r
+\r
+ default:\r
+ // skip...\r
+ }\r
+ }\r
+ }\r
+}\r
+/* PostParseURL is a place to cleanup any of the path-related global variables before the selector function is run.\r
+ It has 2 values in the data in case the original virtualpath is needed, but most the use will be in tweaking\r
+ global variables to clean up (scrub out catid or add catid) or to set someother global variable based on\r
+ the values of something like catid or itemid\r
+ New in 3.60\r
+*/\r
+$manager->notify(\r
+ 'PostParseURL',\r
+ array(\r
+ 'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...\r
+ 'info' => $virtualpath\r
+ )\r
+);\r
+\r
+function include_libs($file,$once=true,$require=true){\r
+ global $DIR_LIBS;\r
+ if (!is_dir($DIR_LIBS)) exit;\r
+ if ($once && $require) require_once($DIR_LIBS.$file);\r
+ elseif ($once && !$require) include_once($DIR_LIBS.$file);\r
+ elseif ($require) require($DIR_LIBS.$file);\r
+ else include($DIR_LIBS.$file);\r
+}\r
+\r
+function include_plugins($file,$once=true,$require=true){\r
+ global $DIR_PLUGINS;\r
+ if (!is_dir($DIR_PLUGINS)) exit;\r
+ if ($once && $require) require_once($DIR_PLUGINS.$file);\r
+ elseif ($once && !$require) include_once($DIR_PLUGINS.$file);\r
+ elseif ($require) require($DIR_PLUGINS.$file);\r
+ else include($DIR_PLUGINS.$file);\r
+}\r
+\r
+function intPostVar($name) {\r
+ return intval(postVar($name) );\r
+}\r
+\r
+function intGetVar($name) {\r
+ return intval(getVar($name) );\r
+}\r
+\r
+function intRequestVar($name) {\r
+ return intval(requestVar($name) );\r
+}\r
+\r
+function intCookieVar($name) {\r
+ return intval(cookieVar($name) );\r
+}\r
+\r
+/**\r
+ * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)\r
+ */\r
+function getNucleusVersion() {\r
+ return 362;\r
+}\r
+\r
+/**\r
+ * power users can install patches in between nucleus releases. These patches\r
+ * usually add new functionality in the plugin API and allow those to\r
+ * be tested without having to install CVS.\r
+ */\r
+function getNucleusPatchLevel() {\r
+ return 0;\r
+}\r
+\r
+/**\r
+ * returns the latest version available for download from nucleuscms.org \r
+ * or false if unable to attain data\r
+ * format will be major.minor/patachlevel\r
+ * e.g. 3.41 or 3.41/02\r
+ */\r
+function getLatestVersion() {\r
+ if (!function_exists('curl_init')) return false;\r
+ $crl = curl_init();\r
+ $timeout = 5;\r
+ curl_setopt ($crl, CURLOPT_URL,'http://nucleuscms.org/version_check.php');\r
+ curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);\r
+ curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);\r
+ $ret = curl_exec($crl);\r
+ curl_close($crl);\r
+ return $ret;\r
+\r
+}\r
+\r
+/**\r
+ * Connects to mysql server\r
+ */\r
+/* moved to $DIR_LIBS/sql/*.php handler files\r
+function sql_connect() {\r
+ global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE, $MYSQL_CONN;\r
+\r
+ $MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>', 'Connect Error');\r
+ mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: ' . mysql_error() . '</p>', 'Connect Error');\r
+\r
+ return $MYSQL_CONN;\r
+}*/\r
+\r
+/**\r
+ * returns a prefixed nucleus table name\r
+ */\r
+function sql_table($name) {\r
+ global $MYSQL_PREFIX;\r
+\r
+ if ($MYSQL_PREFIX) {\r
+ return $MYSQL_PREFIX . 'nucleus_' . $name;\r
+ } else {\r
+ return 'nucleus_' . $name;\r
+ }\r
+}\r
+\r
+function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {\r
+ global $manager, $CONF;\r
+\r
+ if (!headers_sent() ) {\r
+ // if content type is application/xhtml+xml, only send it to browsers\r
+ // that can handle it (IE6 cannot). Otherwise, send text/html\r
+\r
+ // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)\r
+ // application/xhtml+xml still causes too much problems with the javascript implementations\r
+\r
+ // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,\r
+ // application/xhtml+xml seems to be working, so we're going to use it if we can.\r
+ //\r
+ // Note: reverted the following function in JP version\r
+ //\r
+ /*\r
+ // v3.3 code\r
+ if (\r
+ ($contenttype == 'application/xhtml+xml')\r
+ && (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )\r
+ ) {\r
+ $contenttype = 'text/html';\r
+ }\r
+ */\r
+ // v3.2x code\r
+ if (\r
+ ($contenttype == 'application/xhtml+xml')\r
+ && (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))\r
+ )\r
+ {\r
+ $contenttype = 'text/html';\r
+ }\r
+\r
+ $manager->notify(\r
+ 'PreSendContentType',\r
+ array(\r
+ 'contentType' => &$contenttype,\r
+ 'charset' => &$charset,\r
+ 'pageType' => $pagetype\r
+ )\r
+ );\r
+\r
+ // strip strange characters\r
+ $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);\r
+ $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);\r
+\r
+ if ($charset != '') {\r
+ header('Content-Type: ' . $contenttype . '; charset=' . $charset);\r
+ } else {\r
+ header('Content-Type: ' . $contenttype);\r
+ }\r
+\r
+ // check if valid charset\r
+ if (!encoding_check(false,false,$charset)) {\r
+ foreach(array($_GET, $_POST) as $input) {\r
+ array_walk($input, 'encoding_check');\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * Errors before the database connection has been made - moved to\r
+ */\r
+/* moved to $DIR_LIBS/sql/*.php handler files\r
+function startUpError($msg, $title) {\r
+ if (!defined('_CHARSET')) define('_CHARSET', 'iso-8859-1');\r
+ header('Content-Type: text/html; charset=' . _CHARSET);\r
+ ?>\r
+ <html <?php echo _HTML_XML_NAME_SPACE_AND_LANG_CODE; ?>>\r
+ <head><meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET?>" />\r
+ <title><?php echo htmlspecialchars($title)?></title></head>\r
+ <body>\r
+ <h1><?php echo htmlspecialchars($title)?></h1>\r
+ <?php echo $msg?>\r
+ </body>\r
+ </html>\r
+ <?php exit;\r
+}*/\r
+\r
+/**\r
+ * disconnects from SQL server\r
+ */\r
+/* moved to $DIR_LIBS/sql/*.php handler files\r
+function sql_disconnect() {\r
+ @mysql_close();\r
+}*/\r
+\r
+/**\r
+ * executes an SQL query\r
+ */\r
+/* moved to $DIR_LIBS/sql/*.php handler files\r
+function sql_query($query) {\r
+ global $SQLCount;\r
+ $SQLCount++;\r
+ $res = mysql_query($query) or print("mySQL error with query $query: " . mysql_error() . '<p />');\r
+ return $res;\r
+}*/\r
+\r
+/**\r
+ * Highlights a specific query in a given HTML text (not within HTML tags) and returns it\r
+ * @param string $text text to be highlighted\r
+ * @param string $expression regular expression to be matched (can be an array of expressions as well)\r
+ * @param string $highlight highlight to be used (use \\0 to indicate the matched expression)\r
+ * @return string\r
+ **/\r
+function highlight($text, $expression, $highlight) {\r
+ if (!$highlight || !$expression)\r
+ {\r
+ return $text;\r
+ }\r
+ \r
+ if (is_array($expression) && (count($expression) == 0) )\r
+ {\r
+ return $text;\r
+ }\r
+ \r
+ // add a tag in front (is needed for preg_match_all to work correct)\r
+ $text = '<!--h-->' . $text;\r
+ \r
+ // split the HTML up so we have HTML tags\r
+ // $matches[0][i] = HTML + text\r
+ // $matches[1][i] = HTML\r
+ // $matches[2][i] = text\r
+ preg_match_all('/(<[^>]+>)([^<>]*)/', $text, $matches);\r
+ \r
+ // throw it all together again while applying the highlight to the text pieces\r
+ $result = '';\r
+ $count_matches = count($matches[2]);\r
+ for ($i = 0; $i < $count_matches; $i++) {\r
+ if ($i != 0)\r
+ {\r
+ $result .= $matches[1][$i];\r
+ }\r
+ \r
+ if (is_array($expression) )\r
+ {\r
+ foreach ($expression as $regex)\r
+ {\r
+ if ($regex)\r
+ {\r
+ //$matches[2][$i] = @eregi_replace($regex, $highlight, $matches[2][$i]);\r
+ $matches[2][$i] = @preg_replace("#".$regex."#i", $highlight, $matches[2][$i]);\r
+ }\r
+ }\r
+ \r
+ $result .= $matches[2][$i];\r
+ }\r
+ else\r
+ {\r
+ //$result .= @eregi_replace($expression, $highlight, $matches[2][$i]);\r
+ $result .= @preg_replace("#".$expression."#i", $highlight, $matches[2][$i]);\r
+ }\r
+ }\r
+ \r
+ return $result;\r
+}\r
+\r
+/**\r
+ * Parses a query into an array of expressions that can be passed on to the highlight method\r
+ */\r
+function parseHighlight($query) {\r
+ // TODO: add more intelligent splitting logic\r
+\r
+ // get rid of quotes\r
+ $query = preg_replace('/\'|"/', '', $query);\r
+\r
+ if (!$query) {\r
+ return array();\r
+ }\r
+\r
+ $aHighlight = explode(' ', $query);\r
+\r
+ for ($i = 0; $i < count($aHighlight); $i++) {\r
+ $aHighlight[$i] = trim($aHighlight[$i]);\r
+\r
+// if (strlen($aHighlight[$i]) < 3) {\r
+// unset($aHighlight[$i]);\r
+// }\r
+ }\r
+\r
+ if (count($aHighlight) == 1) {\r
+ return $aHighlight[0];\r
+ } else {\r
+ return $aHighlight;\r
+ }\r
+}\r
+\r
+/**\r
+ * Checks if email address is valid\r
+ */\r
+function isValidMailAddress($address) {\r
+ // enhancement made in 3.6x based on code by Quandary.\r
+ if (preg_match('/^(?!\\.)(?:\\.?[-a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~]+)+@(?!\\.)(?:\\.?(?!-)[-a-zA-Z0-9]+(?<!-)){2,}$/', $address)) {\r
+ return 1;\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+\r
+// some helper functions\r
+function getBlogIDFromName($name) {\r
+ return quickQuery('SELECT bnumber as result FROM ' . sql_table('blog') . ' WHERE bshortname="' . sql_real_escape_string($name) . '"');\r
+}\r
+\r
+function getBlogNameFromID($id) {\r
+ return quickQuery('SELECT bname as result FROM ' . sql_table('blog') . ' WHERE bnumber=' . intval($id) );\r
+}\r
+\r
+function getBlogIDFromItemID($itemid) {\r
+ return quickQuery('SELECT iblog as result FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid) );\r
+}\r
+\r
+function getBlogIDFromCommentID($commentid) {\r
+ return quickQuery('SELECT cblog as result FROM ' . sql_table('comment') . ' WHERE cnumber=' . intval($commentid) );\r
+}\r
+\r
+function getBlogIDFromCatID($catid) {\r
+ return quickQuery('SELECT cblog as result FROM ' . sql_table('category') . ' WHERE catid=' . intval($catid) );\r
+}\r
+\r
+function getCatIDFromName($name) {\r
+ return quickQuery('SELECT catid as result FROM ' . sql_table('category') . ' WHERE cname="' . sql_real_escape_string($name) . '"');\r
+}\r
+\r
+function quickQuery($q) {\r
+ $res = sql_query($q);\r
+ $obj = sql_fetch_object($res);\r
+ return $obj->result;\r
+}\r
+\r
+function getPluginNameFromPid($pid) {\r
+ $res = sql_query('SELECT pfile FROM ' . sql_table('plugin') . ' WHERE pid=' . intval($pid) );\r
+ $obj = sql_fetch_object($res);\r
+ return $obj->pfile;\r
+}\r
+\r
+function selector() {\r
+ global $itemid, $blogid, $memberid, $query, $amount, $archivelist, $maxresults;\r
+ global $archive, $skinid, $blog, $memberinfo, $CONF, $member;\r
+ global $imagepopup, $catid, $special;\r
+ global $manager;\r
+\r
+ $actionNames = array('addcomment', 'sendmessage', 'createaccount', 'forgotpassword', 'votepositive', 'votenegative', 'plugin');\r
+ $action = requestVar('action');\r
+\r
+ if (in_array($action, $actionNames) ) {\r
+ global $DIR_LIBS, $errormessage;\r
+ include_once($DIR_LIBS . 'ACTION.php');\r
+ $a = new ACTION();\r
+ $errorInfo = $a->doAction($action);\r
+\r
+ if ($errorInfo) {\r
+ $errormessage = $errorInfo['message'];\r
+ }\r
+ }\r
+\r
+ // show error when headers already sent out\r
+ if (headers_sent() && $CONF['alertOnHeadersSent']) {\r
+\r
+ // try to get line number/filename (extra headers_sent params only exists in PHP 4.3+)\r
+ if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=') ) {\r
+ headers_sent($hsFile, $hsLine);\r
+ $extraInfo = ' in <code>' . $hsFile . '</code> line <code>' . $hsLine . '</code>';\r
+ } else {\r
+ $extraInfo = '';\r
+ }\r
+\r
+ startUpError(\r
+ sprintf(_GFUNCTIONS_HEADERSALREADYSENT_TXT,$extraInfo),\r
+ _GFUNCTIONS_HEADERSALREADYSENT_TITLE\r
+ );\r
+ exit;\r
+ }\r
+\r
+ // make is so ?archivelist without blogname or blogid shows the archivelist\r
+ // for the default weblog\r
+ if (serverVar('QUERY_STRING') == 'archivelist') {\r
+ $archivelist = $CONF['DefaultBlog'];\r
+ }\r
+\r
+ // now decide which type of skin we need\r
+ if ($itemid) {\r
+ // itemid given -> only show that item\r
+ $type = 'item';\r
+\r
+ if (!$manager->existsItem($itemid,intval($CONF['allowFuture']),intval($CONF['allowDrafts']))) {\r
+ doError(_ERROR_NOSUCHITEM);\r
+ }\r
+\r
+ global $itemidprev, $itemidnext, $catid, $itemtitlenext, $itemtitleprev;\r
+\r
+ // 1. get timestamp, blogid and catid for item\r
+ $query = 'SELECT itime, iblog, icat FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid);\r
+ $res = sql_query($query);\r
+ $obj = sql_fetch_object($res);\r
+\r
+ // if a different blog id has been set through the request or selectBlog(),\r
+ // deny access\r
+ \r
+ if ($blogid && (intval($blogid) != $obj->iblog) ) {\r
+ if (!headers_sent()) {\r
+ $b =& $manager->getBlog($obj->iblog);\r
+ $CONF['ItemURL'] = $b->getURL();\r
+ if ($CONF['URLMode'] == 'pathinfo' and substr($CONF['ItemURL'],-1) == '/')\r
+ $CONF['ItemURL'] = substr($CONF['ItemURL'], 0, -1);\r
+ $correctURL = createItemLink($itemid, '');\r
+ redirect($correctURL);\r
+ exit;\r
+ } else {\r
+ doError(_ERROR_NOSUCHITEM);\r
+ }\r
+ }\r
+\r
+ // if a category has been selected which doesn't match the item, ignore the\r
+ // category. #85\r
+ if (($catid != 0) && ($catid != $obj->icat) ) {\r
+ $catid = 0;\r
+ }\r
+\r
+ $blogid = $obj->iblog;\r
+ $timestamp = strtotime($obj->itime);\r
+\r
+ $b =& $manager->getBlog($blogid);\r
+\r
+ if ($b->isValidCategory($catid) ) {\r
+ $catextra = ' and icat=' . $catid;\r
+ } else {\r
+ $catextra = '';\r
+ }\r
+\r
+ // get previous itemid and title\r
+ $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
+ $res = sql_query($query);\r
+\r
+ $obj = sql_fetch_object($res);\r
+\r
+ if ($obj) {\r
+ $itemidprev = $obj->inumber;\r
+ $itemtitleprev = $obj->ititle;\r
+ }\r
+\r
+ // get next itemid and title\r
+ $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
+ $res = sql_query($query);\r
+\r
+ $obj = sql_fetch_object($res);\r
+\r
+ if ($obj) {\r
+ $itemidnext = $obj->inumber;\r
+ $itemtitlenext = $obj->ititle;\r
+ }\r
+\r
+ } elseif ($archive) {\r
+ // show archive\r
+ $type = 'archive';\r
+\r
+ // get next and prev month links ...\r
+ global $archivenext, $archiveprev, $archivetype, $archivenextexists, $archiveprevexists;\r
+\r
+ // sql queries for the timestamp of the first and the last published item\r
+ $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
+ $first_timestamp=quickQuery ($query);\r
+ $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
+ $last_timestamp=quickQuery ($query);\r
+\r
+ sscanf($archive, '%d-%d-%d', $y, $m, $d);\r
+\r
+ if ($d != 0) {\r
+ $archivetype = _ARCHIVETYPE_DAY;\r
+ $t = mktime(0, 0, 0, $m, $d, $y);\r
+ // one day has 24 * 60 * 60 = 86400 seconds\r
+ $archiveprev = strftime('%Y-%m-%d', $t - 86400 );\r
+ // check for published items\r
+ if ($t > $first_timestamp) {\r
+ $archiveprevexists = true;\r
+ }\r
+ else {\r
+ $archiveprevexists = false;\r
+ }\r
+\r
+ // one day later\r
+ $t += 86400;\r
+ $archivenext = strftime('%Y-%m-%d', $t);\r
+ if ($t < $last_timestamp) {\r
+ $archivenextexists = true;\r
+ }\r
+ else {\r
+ $archivenextexists = false;\r
+ }\r
+\r
+ } elseif ($m == 0) {\r
+ $archivetype = _ARCHIVETYPE_YEAR;\r
+ $t = mktime(0, 0, 0, 12, 31, $y - 1);\r
+ // one day before is in the previous year\r
+ $archiveprev = strftime('%Y', $t);\r
+ if ($t > $first_timestamp) {\r
+ $archiveprevexists = true;\r
+ }\r
+ else {\r
+ $archiveprevexists = false;\r
+ }\r
+\r
+ // timestamp for the next year\r
+ $t = mktime(0, 0, 0, 1, 1, $y + 1);\r
+ $archivenext = strftime('%Y', $t);\r
+ if ($t < $last_timestamp) {\r
+ $archivenextexists = true;\r
+ }\r
+ else {\r
+ $archivenextexists = false;\r
+ }\r
+ } else {\r
+ $archivetype = _ARCHIVETYPE_MONTH;\r
+ $t = mktime(0, 0, 0, $m, 1, $y);\r
+ // one day before is in the previous month\r
+ $archiveprev = strftime('%Y-%m', $t - 86400);\r
+ if ($t > $first_timestamp) {\r
+ $archiveprevexists = true;\r
+ }\r
+ else {\r
+ $archiveprevexists = false;\r
+ }\r
+\r
+ // timestamp for the next month\r
+ $t = mktime(0, 0, 0, $m+1, 1, $y);\r
+ $archivenext = strftime('%Y-%m', $t);\r
+ if ($t < $last_timestamp) {\r
+ $archivenextexists = true;\r
+ }\r
+ else {\r
+ $archivenextexists = false;\r
+ }\r
+ }\r
+\r
+ } elseif ($archivelist) {\r
+ $type = 'archivelist';\r
+\r
+ if (is_numeric($archivelist)) {\r
+ $blogid = intVal($archivelist);\r
+ } else {\r
+ $blogid = getBlogIDFromName($archivelist);\r
+ }\r
+\r
+ if (!$blogid) {\r
+ doError(_ERROR_NOSUCHBLOG);\r
+ }\r
+\r
+ } elseif ($query) {\r
+ global $startpos;\r
+ $type = 'search';\r
+ $query = stripslashes($query);\r
+ if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/", $query)){\r
+ $type = 'index';\r
+ }\r
+// $order = (_CHARSET == 'EUC-JP') ? 'EUC-JP, UTF-8,' : 'UTF-8, EUC-JP,';\r
+// $query = mb_convert_encoding($query, _CHARSET, $order . ' JIS, SJIS, ASCII');\r
+ switch(strtolower(_CHARSET)){\r
+ case 'utf-8':\r
+ $order = 'ASCII, UTF-8, EUC-JP, JIS, SJIS, EUC-CN, ISO-8859-1';\r
+ break;\r
+ case 'gb2312':\r
+ $order = 'ASCII, EUC-CN, EUC-JP, UTF-8, JIS, SJIS, ISO-8859-1';\r
+ break;\r
+ case 'shift_jis':\r
+ // Note that shift_jis is only supported for output.\r
+ // Using shift_jis in DB is prohibited.\r
+ $order = 'ASCII, SJIS, EUC-JP, UTF-8, JIS, EUC-CN, ISO-8859-1';\r
+ break;\r
+ default:\r
+ // euc-jp,iso-8859-x,windows-125x\r
+ $order = 'ASCII, EUC-JP, UTF-8, JIS, SJIS, EUC-CN, ISO-8859-1';\r
+ break;\r
+ }\r
+ $query = mb_convert_encoding($query, _CHARSET, $order);\r
+ if (is_numeric($blogid)) {\r
+ $blogid = intVal($blogid);\r
+ } else {\r
+ $blogid = getBlogIDFromName($blogid);\r
+ }\r
+\r
+ if (!$blogid) {\r
+ doError(_ERROR_NOSUCHBLOG);\r
+ }\r
+\r
+ } elseif ($memberid) {\r
+ $type = 'member';\r
+\r
+ if (!MEMBER::existsID($memberid) ) {\r
+ doError(_ERROR_NOSUCHMEMBER);\r
+ }\r
+\r
+ $memberinfo = $manager->getMember($memberid);\r
+\r
+ } elseif ($imagepopup) {\r
+ // media object (images etc.)\r
+ $type = 'imagepopup';\r
+\r
+ // TODO: check if media-object exists\r
+ // TODO: set some vars?\r
+ } else {\r
+ // show regular index page\r
+ global $startpos;\r
+ $type = 'index';\r
+ }\r
+\r
+ // any type of skin with catid\r
+ if ($catid && !$blogid) {\r
+ $blogid = getBlogIDFromCatID($catid);\r
+ }\r
+\r
+ // decide which blog should be displayed\r
+ if (!$blogid) {\r
+ $blogid = $CONF['DefaultBlog'];\r
+ }\r
+\r
+ $b =& $manager->getBlog($blogid);\r
+ $blog = $b; // references can't be placed in global variables?\r
+\r
+ if (!$blog->isValid) {\r
+ doError(_ERROR_NOSUCHBLOG);\r
+ }\r
+\r
+ // set catid if necessary\r
+ if ($catid) {\r
+ // check if the category is valid\r
+ if (!$blog->isValidCategory($catid)) {\r
+ doError(_ERROR_NOSUCHCATEGORY);\r
+ } else {\r
+ $blog->setSelectedCategory($catid);\r
+ }\r
+ }\r
+\r
+ // decide which skin should be used\r
+ if ($skinid != '' && ($skinid == 0) ) {\r
+ selectSkin($skinid);\r
+ }\r
+\r
+ if (!$skinid) {\r
+ $skinid = $blog->getDefaultSkin();\r
+ }\r
+\r
+ //$special = requestVar('special'); //get at top of file as global\r
+ if (!empty($special) && isValidShortName($special)) {\r
+ $type = strtolower($special);\r
+ }\r
+\r
+ $skin = new SKIN($skinid);\r
+\r
+ if (!$skin->isValid) {\r
+ doError(_ERROR_NOSUCHSKIN);\r
+ }\r
+ \r
+ // set global skinpart variable so can determine quickly what is being parsed from any plugin or phpinclude\r
+ global $skinpart;\r
+ $skinpart = $type;\r
+ \r
+ // parse the skin\r
+ $skin->parse($type);\r
+\r
+ // check to see we should throw JustPosted event\r
+ $blog->checkJustPosted();\r
+}\r
+\r
+/**\r
+ * Show error skin with given message. An optional skin-object to use can be given\r
+ */\r
+function doError($msg, $skin = '') {\r
+ global $errormessage, $CONF, $skinid, $blogid, $manager;\r
+\r
+ if ($skin == '') {\r
+\r
+ if (SKIN::existsID($skinid) ) {\r
+ $skin = new SKIN($skinid);\r
+ } elseif ($manager->existsBlogID($blogid) ) {\r
+ $blog =& $manager->getBlog($blogid);\r
+ $skin = new SKIN($blog->getDefaultSkin() );\r
+ } elseif ($CONF['DefaultBlog']) {\r
+ $blog =& $manager->getBlog($CONF['DefaultBlog']);\r
+ $skin = new SKIN($blog->getDefaultSkin() );\r
+ } else {\r
+ // this statement should actually never be executed\r
+ $skin = new SKIN($CONF['BaseSkin']);\r
+ }\r
+\r
+ }\r
+\r
+ $skinid = $skin->id;\r
+ $errormessage = $msg;\r
+ $skin->parse('error');\r
+ exit;\r
+}\r
+\r
+function getConfig() {\r
+ global $CONF;\r
+\r
+ $query = 'SELECT * FROM ' . sql_table('config');\r
+ $res = sql_query($query);\r
+\r
+ while ($obj = sql_fetch_object($res) ) {\r
+ $CONF[$obj->name] = $obj->value;\r
+ }\r
+}\r
+\r
+// some checks for names of blogs, categories, templates, members, ...\r
+function isValidShortName($name) {\r
+ # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0\r
+ # original eregi: eregi('^[a-z0-9]+$', $name)\r
+ return preg_match('#^[a-z0-9]+$#i', $name);\r
+}\r
+\r
+function isValidDisplayName($name) {\r
+ # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0\r
+ # original eregi: eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name)\r
+ return preg_match('#^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$#i', $name);\r
+}\r
+\r
+function isValidCategoryName($name) {\r
+ return 1;\r
+}\r
+\r
+function isValidTemplateName($name) {\r
+ # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0\r
+ # original eregi: eregi('^[a-z0-9/]+$', $name)\r
+ return preg_match('#^[a-z0-9/]+$#i', $name);\r
+}\r
+\r
+function isValidSkinName($name) {\r
+ # replaced eregi() below with preg_match(). ereg* functions are deprecated in PHP 5.3.0\r
+ # original eregi: eregi('^[a-z0-9/]+$', $name);\r
+ return preg_match('#^[a-z0-9/]+$#i', $name);\r
+}\r
+\r
+// add and remove linebreaks\r
+function addBreaks($var) {\r
+ return nl2br($var);\r
+}\r
+\r
+function removeBreaks($var) {\r
+ return preg_replace("/<br \/>([\r\n])/", "$1", $var);\r
+}\r
+\r
+// shortens a text string to maxlength ($toadd) is what needs to be added\r
+// at the end (end length is <= $maxlength)\r
+function shorten($text, $maxlength, $toadd) {\r
+ // 1. remove entities...\r
+// $trans = get_html_translation_table(HTML_ENTITIES);\r
+ $trans = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese\r
+ $trans = array_flip($trans);\r
+ $text = strtr($text, $trans);\r
+\r
+ // 2. the actual shortening\r
+ if (strlen($text) > $maxlength) {\r
+// $text = substr($text, 0, $maxlength - strlen($toadd) ) . $toadd;\r
+ $text = mb_strimwidth($text, 0, $maxlength, $toadd, _CHARSET); // for Japanese\r
+ }\r
+\r
+ return $text;\r
+}\r
+\r
+/**\r
+ * Converts a unix timestamp to a mysql DATETIME format, and places\r
+ * quotes around it.\r
+ */\r
+function mysqldate($timestamp) {\r
+ return '"' . date('Y-m-d H:i:s', $timestamp) . '"';\r
+}\r
+\r
+/**\r
+ * functions for use in index.php\r
+ */\r
+function selectBlog($shortname) {\r
+ global $blogid, $archivelist;\r
+ $blogid = getBlogIDFromName($shortname);\r
+\r
+ // also force archivelist variable, if it is set\r
+ if ($archivelist) {\r
+ $archivelist = $blogid;\r
+ }\r
+}\r
+\r
+function selectSkin($skinname) {\r
+ global $skinid;\r
+ $skinid = SKIN::getIdFromName($skinname);\r
+}\r
+\r
+/**\r
+ * Can take either a category ID or a category name (be aware that\r
+ * multiple categories can have the same name)\r
+ */\r
+function selectCategory($cat) {\r
+ global $catid;\r
+ if (is_numeric($cat) ) {\r
+ $catid = intval($cat);\r
+ } else {\r
+ $catid = getCatIDFromName($cat);\r
+ }\r
+}\r
+\r
+function selectItem($id) {\r
+ global $itemid;\r
+ $itemid = intval($id);\r
+}\r
+\r
+// force the use of a language file (warning: can cause warnings)\r
+function selectLanguage($language) {\r
+\r
+ global $DIR_LANG;\r
+\r
+ # replaced ereg_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0\r
+ # original ereg_replace: preg_replace( '@\\|/@', '', $language) . '.php')\r
+ # important note that '\' must be matched with '\\\\' in preg* expressions\r
+\r
+ include($DIR_LANG . preg_replace('#[\\\\|/]#', '', $language) . '.php');\r
+\r
+}\r
+\r
+function parseFile($filename, $includeMode = 'normal', $includePrefix = '') {\r
+ $handler = new ACTIONS('fileparser');\r
+ $parser = new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);\r
+ $handler->parser =& $parser;\r
+\r
+ // set IncludeMode properties of parser\r
+ PARSER::setProperty('IncludeMode', $includeMode);\r
+ PARSER::setProperty('IncludePrefix', $includePrefix);\r
+\r
+ if (!file_exists($filename) ) {\r
+ doError(_GFUNCTIONS_PARSEFILE_FILEMISSING);\r
+ }\r
+\r
+ $fsize = filesize($filename);\r
+\r
+ if ($fsize <= 0) {\r
+ return;\r
+ }\r
+\r
+ // read file\r
+ $fd = fopen ($filename, 'r');\r
+ $contents = fread ($fd, $fsize);\r
+ fclose ($fd);\r
+\r
+ // parse file contents\r
+ $parser->parse($contents);\r
+}\r
+\r
+/**\r
+ * Outputs a debug message\r
+ */\r
+function debug($msg) {\r
+ echo '<p><b>' . $msg . "</b></p>\n";\r
+}\r
+\r
+// shortcut\r
+function addToLog($level, $msg) {\r
+ ACTIONLOG::add($level, $msg);\r
+}\r
+\r
+// shows a link to help file\r
+function help($id) {\r
+ echo helpHtml($id);\r
+}\r
+\r
+function helpHtml($id) {\r
+ global $CONF;\r
+ return helplink($id) . '<img src="' . $CONF['AdminURL'] . 'documentation/icon-help.gif" width="15" height="15" alt="' . _HELP_TT . '" title="' . _HELP_TT . '" /></a>';\r
+}\r
+\r
+function helplink($id) {\r
+ global $CONF;\r
+ return '<a href="' . $CONF['AdminURL'] . 'documentation/help.html#'. $id . '" onclick="if (event && event.preventDefault) event.preventDefault(); return help(this.href);">';\r
+}\r
+\r
+function getMailFooter() {\r
+ $message = "\n\n-----------------------------";\r
+ $message .= "\n Powered by Nucleus CMS";\r
+ $message .= "\n(http://www.nucleuscms.org/)";\r
+ return $message;\r
+}\r
+\r
+/**\r
+ * Returns the name of the language to use\r
+ * preference priority: member - site\r
+ * defaults to english when no good language found\r
+ *\r
+ * checks if file exists, etc...\r
+ */\r
+function getLanguageName() {\r
+ global $CONF, $member;\r
+\r
+ if ($member && $member->isLoggedIn() ) {\r
+ // try to use members language\r
+ $memlang = $member->getLanguage();\r
+\r
+ if (($memlang != '') && (checkLanguage($memlang) ) ) {\r
+ return $memlang;\r
+ }\r
+ }\r
+\r
+ // use default language\r
+ if (checkLanguage($CONF['Language']) ) {\r
+ return $CONF['Language'];\r
+ } else {\r
+ return 'english';\r
+ }\r
+}\r
+\r
+/**\r
+ * Includes a PHP file. This method can be called while parsing templates and skins\r
+ */\r
+function includephp($filename) {\r
+ // make predefined variables global, so most simple scripts can be used here\r