if ($folders = array_filter(preg_grep('/^(\\.|users$|themes$|lib$)/', scandir('.'), PREG_GREP_INVERT), 'is_dir')) { //get the dummy list-item to repeat (removes it and takes a copy) $item = $template->repeat('.nnf_folder'); foreach ($folders as $FOLDER) { //the sorting (below) requires we be in the directory at hand to use `filemtime` chdir($FOLDER); //check if / how the forum is locked $lock = trim(@file_get_contents('locked.txt')); //get a list of files in the folder to determine which one is newest $files = preg_grep('/\\.rss$/', scandir('.')); //order by last modified date array_multisort(array_map('filemtime', $files), SORT_DESC, $files); //read the newest thread (folder could be empty though) $last = ($xml = @simplexml_load_file($files[0])) ? $xml->channel->item[0] : ''; //start applying the data to the template $item->set(array('a.nnf_folder-name' => $FOLDER, 'a.nnf_folder-name@href' => PATH_URL . safeURL($FOLDER) . '/'))->remove(array('.nnf_lock-threads' => $lock != 'threads', '.nnf_lock-posts' => $lock != 'posts')); //is there a last post in this sub-forum? if ((bool) $last) { $item->set(array('.nnf_post-author' => $last->author, 'time.nnf_post-time' => date(DATE_FORMAT, strtotime($last->pubDate)), 'time.nnf_post-time@datetime' => date('c', strtotime($last->pubDate)), 'a.nnf_post-link@href' => substr($last->link, strpos($last->link, '/', 9)))); //is the last author a mod? if (isMod($last->author)) { $item->addClass('.nnf_post-author', 'mod'); } } else { //no last post, remove the template for it $item->remove('.nnf_subforum-post'); } //attach the templated sub-forum item to the list $item->next(); chdir('..'); }
function indexRSS() { /* create an RSS feed -------------------------------------------------------------------------------------------------------------- */ $rss = new DOMTemplate(file_get_contents(FORUM_LIB . 'rss-template.xml')); $rss->set(array('/rss/channel/title' => FORUM_NAME . (PATH ? str_replace('/', ' / ', PATH) : ''), '/rss/channel/link' => FORUM_URL . url(PATH_URL)))->remove('/rss/channel/category'); //get list of threads, sort by date; most recently modified first $threads = preg_grep('/\\.rss$/', scandir('.')); array_multisort(array_map('filemtime', $threads), SORT_DESC, $threads); $items = $rss->repeat('/rss/channel/item'); //get the last post made in each thread as an RSS item foreach (array_slice($threads, 0, FORUM_THREADS) as $thread) { if ($xml = @simplexml_load_file($thread)) { //if the RSS feed is valid if ($item = @$xml->channel->item[0]) { //if the feed has any items $items->set(array('./title' => $item->title, './link' => $item->link, './author' => $item->author, './pubDate' => gmdate('r', strtotime($item->pubDate)), './description' => $item->description))->remove(array('./category[.="deleted"]' => !$item->xpath('category[.="deleted"]')))->next(); } } } file_put_contents('index.xml', $rss); /* sitemap -------------------------------------------------------------------------------------------------------------- */ //we’re going to use the RSS files as sitemaps chdir(FORUM_ROOT); //get list of sub-forums and include the root too $folders = array('') + array_filter(preg_grep('/^(\\.|users$|themes$|lib$)/', scandir(FORUM_ROOT . DIRECTORY_SEPARATOR), PREG_GREP_INVERT), 'is_dir'); //start the XML file. this template has an XMLNS, so we have to prefix all our XPath queries :( $xml = new DOMTemplate(file_get_contents(FORUM_LIB . 'sitemap-template.xml'), array('x' => 'http://www.sitemaps.org/schemas/sitemap/0.9')); //generate a sitemap index file, to point to each index RSS file in the forum: //<https://www.google.com/support/webmasters/bin/answer.py?answer=71453> $sitemap = $xml->repeat('//x:sitemap'); foreach ($folders as $folder) { //get the time of the latest item in the RSS feed //(the RSS feed may be missing as they are not generated in new folders until something is posted) if (@($rss = simplexml_load_file(FORUM_ROOT . ($folder ? DIRECTORY_SEPARATOR . $folder : '') . DIRECTORY_SEPARATOR . 'index.xml'))) { //if you delete the last thread in a folder, there won’t be anything in the RSS index file! if (@$rss->channel->item[0]) { $sitemap->set(array('./x:loc' => FORUM_URL . FORUM_PATH . ($folder ? safeURL("{$folder}/", false) : '') . 'index.xml', './x:lastmod' => gmdate('r', strtotime($rss->channel->item[0]->pubDate))))->next(); } } } file_put_contents(FORUM_ROOT . DIRECTORY_SEPARATOR . 'sitemap.xml', $xml); //you saw nothing, right? clearstatcache(); }
define('FORUM_URL', 'http' . (FORUM_HTTPS || @$_SERVER['HTTPS'] == 'on' ? 's' : '') . '://' . $_SERVER['HTTP_HOST']); //is the htaccess working properly? //('.htaccess' sets this variable for us) define('HTACCESS', (bool) @$_SERVER['HTTP_HTACCESS']); //if '.htaccess' is missing or disabled, and the 'users' folder is in an insecure location, warn the site admin to move it if (!HTACCESS && FORUM_USERS == 'users') { require FORUM_LIB . 'error_htaccess.php'; } /* common input ---------------------------------------------------------------------------------------------------------------------- */ //most pages allow for a page number; note that this is merely the user-input, it is not necessarily a valid page number! define('PAGE', preg_match('/^[1-9][0-9]*$/', @$_GET['page']) ? (int) $_GET['page'] : false); //all our pages use 'path' (often optional) to specify the sub-forum being viewed, so this is done here define('PATH', preg_match('/^(?:[^\\.\\/&]+\\/)+$/', @$_GET['path']) ? $_GET['path'] : ''); //a shorthand for when PATH is used in URL construction for HTML use define('PATH_URL', safeURL(PATH)); //for serverside use, like `chdir` / `unlink` (must replace the URL forward-slashes with backslashes on Windows) define('PATH_DIR', !PATH ? DIRECTORY_SEPARATOR : DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, PATH)); //if we are in nested sub-folders, the name of the current sub-forum, exluding the rest //(not used in URLs, so we use `PATH` instead of `PATH_URL`) define('SUBFORUM', @end(explode('/', trim(PATH, '/')))); //deny access to some folders //TODO: this should generate a 403, but we don't have a 403 page designed yet foreach (array('users/', 'lib/', 'themes/', 'cgi-bin/') as $_) { if (stripos($_, PATH) === 0) { die; } } //we have to change directory for `is_dir` to work, see <uk3.php.net/manual/en/function.is-dir.php#70005> //being in the right directory is also assumed for reading 'mods.txt' and when generating the RSS (`indexRSS`) //(oddly with `chdir` the path must end in a slash)
/* constants: some stuff we don’t expect to change ---------------------------------------------------------------------------------------------------------------------- */ define('FORUM_ROOT', dirname(__FILE__)); //full server-path for absolute references define('FORUM_PATH', str_replace(array('\\', '//'), '/', dirname($_SERVER['SCRIPT_NAME']) . '/')); define('FORUM_URL', 'http' . (FORUM_HTTPS || @$_SERVER['HTTPS'] == 'on' ? 's' : '') . '://' . $_SERVER['HTTP_HOST']); //load the user’s theme configuration, if it exists @(include FORUM_ROOT . '/themes/' . FORUM_THEME . '/theme.config.php'); //include the theme defaults @(include FORUM_ROOT . '/themes/' . FORUM_THEME . '/theme.config.default.php') or die('theme.config.default.php missing!'); /* common input ====================================================================================================================== */ //all our pages use 'path' (often optional) to specify the sub-forum being viewed, so this is done here define('PATH', preg_match('/^(?:[^\\.\\/&]+\\/)+$/', @$_GET['path']) ? $_GET['path'] : ''); //these two get used an awful lot define('PATH_URL', !PATH ? FORUM_PATH : safeURL(FORUM_PATH . PATH, false)); //when outputting as part of a URL define('PATH_DIR', !PATH ? '/' : '/' . PATH); //serverside, like `chdir` / `unlink` //if we are in nested sub-folders, the name of the current sub-forum, exluding the rest define('SUBFORUM', @end(explode('/', trim(PATH, '/')))); //we have to change directory for `is_dir` to work, see <uk3.php.net/manual/en/function.is-dir.php#70005> //being in the right directory is also assumed for reading 'mods.txt' and when generating the RSS (`indexRSS`) //(oddly with `chdir` the path must end in a slash) @chdir(FORUM_ROOT . PATH_DIR) or die('Invalid path'); /* access control ====================================================================================================================== */ /* name / password authorisation: ---------------------------------------------------------------------------------------------------------------------- */ //for HTTP authentication (sign-in): //- CGI workaround <orangejuiceliberationfront.com/http-auth-with-php-in-cgi-mode-e-g-on-dreamhost/>