[geeklog-jp commit] r1425 - Geeklog 1.5.2sr1を externals/geeklog-1.5.2sr2 に取り込みます。take#4.

Zurück zum Archiv-Index

codes****@googl***** codes****@googl*****
2009年 4月 6日 (月) 10:10:17 JST


Author: tacahi
Date: Sun Apr  5 18:08:35 2009
New Revision: 1425

Added:
    externals/geeklog-1.5.2sr2/public_html/
    externals/geeklog-1.5.2sr2/public_html/404.php
    externals/geeklog-1.5.2sr2/public_html/article.php
    externals/geeklog-1.5.2sr2/public_html/comment.php
    externals/geeklog-1.5.2sr2/public_html/directory.php
    externals/geeklog-1.5.2sr2/public_html/getimage.php
    externals/geeklog-1.5.2sr2/public_html/index.php
    externals/geeklog-1.5.2sr2/public_html/lib-common.php
    externals/geeklog-1.5.2sr2/public_html/pingback.php
    externals/geeklog-1.5.2sr2/public_html/profiles.php
    externals/geeklog-1.5.2sr2/public_html/robots.txt
    externals/geeklog-1.5.2sr2/public_html/search.php
    externals/geeklog-1.5.2sr2/public_html/siteconfig.php
    externals/geeklog-1.5.2sr2/public_html/stats.php
    externals/geeklog-1.5.2sr2/public_html/submit.php
    externals/geeklog-1.5.2sr2/public_html/switchlang.php
    externals/geeklog-1.5.2sr2/public_html/trackback.php
    externals/geeklog-1.5.2sr2/public_html/users.php
    externals/geeklog-1.5.2sr2/public_html/usersettings.php

Log:
Geeklog 1.5.2sr1を externals/geeklog-1.5.2sr2 に取り込みます。take#4.


Added: externals/geeklog-1.5.2sr2/public_html/404.php
==============================================================================
--- (empty file)
+++ externals/geeklog-1.5.2sr2/public_html/404.php	Sun Apr  5 18:08:35 2009
@@ -0,0 +1,58 @@
+<?php
+
+/* Reminder: always indent with 4 spaces (no tabs). */
+//  
+---------------------------------------------------------------------------+
+// | Geeklog  
1.3                                                               |
+//  
+---------------------------------------------------------------------------+
+// |  
404.php                                                                   |
+//  
|                                                                            
|
+// | Geeklog "404 Not Found"  
page                                              |
+//  
+---------------------------------------------------------------------------+
+// | Copyright (C) 2000-2005 by the following  
authors:                         |
+//  
|                                                                            
|
+// | Authors: Tony Bibbs        - tony AT tonybibbs DOT  
com                    |
+// |          Jason Whittenburg - jwhitten AT securitygeeks DOT  
com            |
+// |          Dirk Haun         - dirk AT haun-online DOT  
de                   |
+//  
+---------------------------------------------------------------------------+
+//  
|                                                                            
|
+// | This program is free software; you can redistribute it  
and/or             |
+// | modify it under the terms of the GNU General Public  
License               |
+// | as published by the Free Software Foundation; either version  
2            |
+// | of the License, or (at your option) any later  
version.                    |
+//  
|                                                                            
|
+// | This program is distributed in the hope that it will be  
useful,           |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty  
of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See  
the             |
+// | GNU General Public License for more  
details.                              |
+//  
|                                                                            
|
+// | You should have received a copy of the GNU General Public  
License         |
+// | along with this program; if not, write to the Free Software  
Foundation,   |
+// | Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,  
USA.           |
+//  
|                                                                            
|
+//  
+---------------------------------------------------------------------------+
+//
+// $Id: 404.php,v 1.10 2005/06/23 08:06:09 dhaun Exp $
+
+require_once ('lib-common.php');
+
+$display = COM_siteHeader ('menu', $LANG_404[1]);
+$display .= COM_startBlock ($LANG_404[1]);
+if (isset ($_SERVER['SCRIPT_URI'])) {
+    $url = strip_tags ($_SERVER['SCRIPT_URI']);
+} else {
+    $pos = strpos ($_SERVER['REQUEST_URI'], '?');
+    if ($pos === false) {
+        $request = $_SERVER['REQUEST_URI'];
+    } else {
+        $request = substr ($_SERVER['REQUEST_URI'], 0, $pos);
+    }
+    $url = 'http://' . $_SERVER['HTTP_HOST'] . strip_tags ($request);
+}
+$display .= sprintf ($LANG_404[2], $url);
+$display .= $LANG_404[3];
+$display .= COM_endBlock ();
+$display .= COM_siteFooter ();
+
+echo $display
+
+?>

Added: externals/geeklog-1.5.2sr2/public_html/article.php
==============================================================================
--- (empty file)
+++ externals/geeklog-1.5.2sr2/public_html/article.php	Sun Apr  5 18:08:35  
2009
@@ -0,0 +1,385 @@
+<?php
+
+/* Reminder: always indent with 4 spaces (no tabs). */
+//  
+---------------------------------------------------------------------------+
+// | Geeklog  
1.5                                                               |
+//  
+---------------------------------------------------------------------------+
+// |  
article.php                                                               |
+//  
|                                                                            
|
+// | Shows articles in various  
formats.                                        |
+//  
+---------------------------------------------------------------------------+
+// | Copyright (C) 2000-2009 by the following  
authors:                         |
+//  
|                                                                            
|
+// | Authors: Tony Bibbs        - tony AT tonybibbs DOT  
com                    |
+// |          Jason Whittenburg - jwhitten AT securitygeeks DOT  
com            |
+// |          Dirk Haun         - dirk AT haun-online DOT  
de                   |
+// |          Vincent Furia     - vinny01 AT users DOT sourceforge DOT  
net     |
+//  
+---------------------------------------------------------------------------+
+//  
|                                                                            
|
+// | This program is free software; you can redistribute it  
and/or             |
+// | modify it under the terms of the GNU General Public  
License               |
+// | as published by the Free Software Foundation; either version  
2            |
+// | of the License, or (at your option) any later  
version.                    |
+//  
|                                                                            
|
+// | This program is distributed in the hope that it will be  
useful,           |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty  
of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See  
the             |
+// | GNU General Public License for more  
details.                              |
+//  
|                                                                            
|
+// | You should have received a copy of the GNU General Public  
License         |
+// | along with this program; if not, write to the Free Software  
Foundation,   |
+// | Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,  
USA.           |
+//  
|                                                                            
|
+//  
+---------------------------------------------------------------------------+
+
+/**
+* This page is responsible for showing a single article in different modes  
which
+* may, or may not, include the comments attached
+*
+* @author   Jason Whittenburg
+* @author   Tony Bibbbs <tony AT tonybibbs DOT com>
+* @author   Vincent Furia <vinny01 AT users DOT sourceforge DOT net>
+*/
+
+/**
+* Geeklog common function library
+*/
+require_once 'lib-common.php';
+require_once $_CONF['path_system'] . 'lib-story.php';
+if ($_CONF['trackback_enabled']) {
+    require_once $_CONF['path_system'] . 'lib-trackback.php';
+}
+
+// Uncomment the line below if you need to debug the HTTP variables being  
passed
+// to the script.  This will sometimes cause errors but it will allow you  
to see
+// the data being passed in a POST operation
+
+// echo COM_debug($_POST);
+
+// MAIN
+$display = '';
+
+$order = '';
+$query = '';
+$reply = '';
+if (isset ($_POST['mode'])) {
+    $sid = COM_applyFilter ($_POST['story']);
+    $mode = COM_applyFilter ($_POST['mode']);
+    if (isset ($_POST['order'])) {
+        $order = COM_applyFilter ($_POST['order']);
+    }
+    if (isset ($_POST['query'])) {
+        $query = COM_applyFilter ($_POST['query']);
+    }
+    if (isset ($_POST['reply'])) {
+        $reply = COM_applyFilter ($_POST['reply']);
+    }
+} else {
+    COM_setArgNames (array ('story', 'mode'));
+    $sid = COM_applyFilter (COM_getArgument ('story'));
+    $mode = COM_applyFilter (COM_getArgument ('mode'));
+    if (isset ($_GET['order'])) {
+        $order = COM_applyFilter ($_GET['order']);
+    }
+    if (isset ($_GET['query'])) {
+        $query = COM_applyFilter ($_GET['query']);
+    }
+    if (isset ($_GET['reply'])) {
+        $reply = COM_applyFilter ($_GET['reply']);
+    }
+}
+
+if (empty ($sid)) {
+    echo COM_refresh ($_CONF['site_url'] . '/index.php');
+    exit();
+}
+if ((strcasecmp ($order, 'ASC') != 0) && (strcasecmp ($order, 'DESC') !=  
0)) {
+    $order = '';
+}
+
+$result = DB_query("SELECT COUNT(*) AS count FROM {$_TABLES['stories']}  
WHERE sid = '$sid'" . COM_getPermSql ('AND'));
+$A = DB_fetchArray($result);
+if ($A['count'] > 0) {
+
+    $story = new Story();
+
+    $args = array (
+                    'sid' => $sid,
+                    'mode' => 'view'
+                  );
+
+    $output = STORY_LOADED_OK;
+    $result = PLG_invokeService('story', 'get', $args, $output, $svc_msg);
+
+    if($result == PLG_RET_OK) {
+        /* loadFromArray cannot be used, since it overwrites the timestamp  
*/
+        reset($story->_dbFields);
+
+        while (list($fieldname,$save) = each($story->_dbFields)) {
+            $varname = '_' . $fieldname;
+
+            if (array_key_exists($fieldname, $output)) {
+                $story->{$varname} = $output[$fieldname];
+            }
+        }
+    }
+
+    if ($output == STORY_PERMISSION_DENIED) {
+        $display .= COM_siteHeader ('menu', $LANG_ACCESS['accessdenied'])
+                 . COM_startBlock ($LANG_ACCESS['accessdenied'], '',
+                           COM_getBlockTemplate ('_msg_block', 'header'))
+                 . $LANG_ACCESS['storydenialmsg']
+                 . COM_endBlock (COM_getBlockTemplate  
('_msg_block', 'footer'))
+                 . COM_siteFooter ();
+    } elseif ( $output == STORY_INVALID_SID ) {
+        $display .= COM_refresh($_CONF['site_url'] . '/index.php');
+    } elseif (($mode == 'print') && ($_CONF['hideprintericon'] == 0)) {
+        $story_template = new Template($_CONF['path_layout'] . 'article');
+        $story_template->set_file('article', 'printable.thtml');
+        $story_template->set_var('xhtml', XHTML);
+        $story_template->set_var('direction', $LANG_DIRECTION);
+        $story_template->set_var('page_title',
+                $_CONF['site_name'] . ': ' .  
$story->displayElements('title'));
+        $story_template->set_var('story_title',
+                                 $story->DisplayElements('title'));
+        header('Content-Type: text/html; charset=' . COM_getCharset());
+        $story_template->set_var('story_date',  
$story->displayElements('date'));
+
+        if ($_CONF['contributedbyline'] == 1) {
+            $story_template->set_var('lang_contributedby', $LANG01[1]);
+            $authorname =  
COM_getDisplayName($story->displayElements('uid'));
+            $story_template->set_var('author', $authorname);
+            $story_template->set_var('story_author', $authorname);
+            $story_template->set_var('story_author_username',
+                                     $story->DisplayElements('username'));
+        }
+
+        $story_template->set_var('story_introtext',
+                                 $story->DisplayElements('introtext'));
+        $story_template->set_var('story_bodytext',
+                                 $story->DisplayElements('bodytext'));
+
+        $story_template->set_var('site_url', $_CONF['site_url']);
+        $story_template->set_var('site_admin_url',  
$_CONF['site_admin_url']);
+        $story_template->set_var('layout_url', $_CONF['layout_url']);
+        $story_template->set_var('site_name', $_CONF['site_name']);
+        $story_template->set_var('site_slogan', $_CONF['site_slogan']);
+        $story_template->set_var('story_id', $story->getSid());
+        $articleUrl = COM_buildUrl($_CONF['site_url']
+                                   . '/article.php?story=' .  
$story->getSid());
+        if ($story->DisplayElements('commentcode') >= 0) {
+            $commentsUrl = $articleUrl . '#comments';
+            $comments = $story->DisplayElements('comments');
+            $numComments = COM_numberFormat($comments);
+            $story_template->set_var('story_comments', $numComments);
+            $story_template->set_var('comments_url', $commentsUrl);
+            $story_template->set_var('comments_text',
+                    $numComments . ' ' . $LANG01[3]);
+            $story_template->set_var('comments_count', $numComments);
+            $story_template->set_var('lang_comments', $LANG01[3]);
+            $comments_with_count = sprintf($LANG01[121], $numComments);
+
+            if ($comments > 0) {
+                $comments_with_count = COM_createLink($comments_with_count,
+                                                      $commentsUrl);
+            }
+            $story_template->set_var('comments_with_count',
+                                     $comments_with_count);
+        }
+        $story_template->set_var ('lang_full_article', $LANG08[33]);
+        $story_template->set_var ('article_url', $articleUrl);
+
+        COM_setLangIdAndAttribute($story_template);
+
+        $story_template->parse('output', 'article');
+        $display =  
$story_template->finish($story_template->get_var('output'));
+    } else {
+        // Set page title
+        $pagetitle = $story->DisplayElements('title');
+
+        $rdf = '';
+        if ($story->DisplayElements('trackbackcode') == 0) {
+            if ($_CONF['trackback_enabled']) {
+                $permalink = COM_buildUrl ($_CONF['site_url']
+                                           . '/article.php?story=' .  
$story->getSid());
+                $trackbackurl = TRB_makeTrackbackUrl ($story->getSid());
+                $rdf = '<!--' . LB
+                     . TRB_trackbackRdf ($permalink, $pagetitle,  
$trackbackurl)
+                     . LB . '-->' . LB;
+            }
+            if ($_CONF['pingback_enabled']) {
+                header ('X-Pingback: ' .  
$_CONF['site_url'] . '/pingback.php');
+            }
+        }
+        $display .= COM_siteHeader ('menu', $pagetitle, $rdf);
+
+        if (isset($_GET['msg'])) {
+            $msg = COM_applyFilter($_GET['msg'], true);
+            if ($msg > 0) {
+                $plugin = '';
+                if (isset($_GET['plugin'])) {
+                    $plugin = COM_applyFilter($_GET['plugin']);
+                }
+                $display .= COM_showMessage($msg, $plugin);
+            }
+        }
+
+        DB_query ("UPDATE {$_TABLES['stories']} SET hits = hits + 1 WHERE  
(sid = '".$story->getSid()."') AND (date <= NOW()) AND (draft_flag = 0)");
+
+        // Display whats related
+
+        $story_template = new Template($_CONF['path_layout'] . 'article');
+        $story_template->set_file('article','article.thtml');
+
+        $story_template->set_var('xhtml', XHTML);
+        $story_template->set_var('site_url', $_CONF['site_url']);
+        $story_template->set_var('site_admin_url',  
$_CONF['site_admin_url']);
+        $story_template->set_var('layout_url', $_CONF['layout_url']);
+        $story_template->set_var('story_id', $story->getSid());
+        $story_template->set_var('story_title', $pagetitle);
+        $story_options = array ();
+        if (($_CONF['hideemailicon'] == 0) && (!empty ($_USER['username'])  
||
+                (($_CONF['loginrequired'] == 0) &&
+                 ($_CONF['emailstoryloginrequired'] == 0)))) {
+            $emailUrl = $_CONF['site_url'] . '/profiles.php?sid=' .  
$story->getSid()
+                      . '&amp;what=emailstory';
+            $story_options[] = COM_createLink($LANG11[2], $emailUrl);
+            $story_template->set_var ('email_story_url', $emailUrl);
+            $story_template->set_var ('lang_email_story', $LANG11[2]);
+            $story_template->set_var ('lang_email_story_alt', $LANG01[64]);
+        }
+        $printUrl = COM_buildUrl ($_CONF['site_url']
+                . '/article.php?story=' .  
$story->getSid() . '&amp;mode=print');
+        if ($_CONF['hideprintericon'] == 0) {
+            $story_options[] = COM_createLink($LANG11[3], $printUrl,  
array('rel' => 'nofollow'));
+            $story_template->set_var ('print_story_url', $printUrl);
+            $story_template->set_var ('lang_print_story', $LANG11[3]);
+            $story_template->set_var ('lang_print_story_alt', $LANG01[65]);
+        }
+        if ($_CONF['pdf_enabled'] == 1) {
+            $pdfUrl = $_CONF['site_url']
+                    . '/pdfgenerator.php?pageType=2&amp;pageData='
+                    . urlencode ($printUrl);
+            $story_options[] = COM_createLink($LANG11[5], $pdfUrl);
+            $story_template->set_var ('pdf_story_url', $printUrl);
+            $story_template->set_var ('lang_pdf_story', $LANG11[5]);
+        }
+        if ($_CONF['backend'] == 1) {
+            $tid = $story->displayElements('tid');
+            $result = DB_query("SELECT filename, title, format FROM  
{$_TABLES['syndication']} WHERE type = 'article' AND topic = '$tid' AND  
is_enabled = 1");
+            $feeds = DB_numRows($result);
+            for ($i = 0; $i < $feeds; $i++) {
+                list($filename, $title, $format) = DB_fetchArray($result);
+                $feedUrl = SYND_getFeedUrl($filename);
+                $feedTitle = sprintf($LANG11[6], $title);
+                $feedType = SYND_getMimeType($format);
+                $feedClass = 'feed-link';
+                if (!empty($LANG_DIRECTION) && ($LANG_DIRECTION == 'rtl'))  
{
+                    $feedClass .= '-rtl';
+                }
+                $story_options[] = COM_createLink($feedTitle, $feedUrl,
+                                                  array('type'  =>  
$feedType,
+                                                        'class' =>  
$feedClass));
+            }
+        }
+        if ($_CONF['trackback_enabled'] &&
+                ($story->displayElements('trackbackcode') >= 0) &&
+                SEC_hasRights('story.ping') &&
+                ($story->displayElements('draft_flag') == 0) &&
+                ($story->displayElements('day') < time ())) {
+            $url = $_CONF['site_admin_url']
+                 . '/trackback.php?mode=sendall&amp;id=' .  
$story->getSid();
+            $story_options[] = COM_createLink($LANG_TRB['send_trackback'],  
$url);
+        }
+        $related = STORY_whatsRelated($story->displayElements('related'),
+                                      $story->displayElements('uid'),
+                                      $story->displayElements('tid'));
+        if (!empty ($related)) {
+            $related = COM_startBlock ($LANG11[1], '',
+                COM_getBlockTemplate ('whats_related_block', 'header'))
+                . $related
+                . COM_endBlock (COM_getBlockTemplate  
('whats_related_block',
+                    'footer'));
+        }
+        if (count ($story_options) > 0) {
+            $optionsblock = COM_startBlock ($LANG11[4], '',
+                    COM_getBlockTemplate ('story_options_block', 'header'))
+                . COM_makeList ($story_options, 'list-story-options')
+                . COM_endBlock (COM_getBlockTemplate  
('story_options_block',
+                    'footer'));
+        } else {
+            $optionsblock = '';
+        }
+        $story_template->set_var ('whats_related', $related);
+        $story_template->set_var ('story_options', $optionsblock);
+        $story_template->set_var ('whats_related_story_options',
+                                  $related . $optionsblock);
+
+        $story_template->set_var ('formatted_article',
+                                  STORY_renderArticle ($story, 'n', '',  
$query));
+
+        // display comments or not?
+        if ( (is_numeric($mode)) and ($_CONF['allow_page_breaks'] == 1) )
+        {
+            $story_page = $mode;
+            $mode = '';
+            if( $story_page <= 0 ) {
+                $story_page = 1;
+            }
+            $article_arr = explode( '[page_break]',  
$story->displayElements('bodytext'));
+            $conf = $_CONF['page_break_comments'];
+            if  (
+                 ($conf == 'all') or
+                 ( ($conf =='first') and ($story_page == 1) ) or
+                 ( ($conf == 'last') and (count($article_arr) ==  
($story_page)) )
+                ) {
+                $show_comments = true;
+            } else {
+                $show_comments = false;
+            }
+        } else {
+            $show_comments = true;
+        }
+
+        // Display the comments, if there are any ..
+        if (($story->displayElements('commentcode') >= 0) and  
$show_comments) {
+            $delete_option = (SEC_hasRights('story.edit') &&  
($story->getAccess() == 3)
+                             ? true : false);
+            require_once ( $_CONF['path_system'] . 'lib-comment.php' );
+            $story_template->set_var ('commentbar',
+                    CMT_userComments ($story->getSid(),  
$story->displayElements('title'), 'article',
+                                      $order, $mode, 0, $page, false,  
$delete_option, $story->displayElements('commentcode')));
+        }
+        if ($_CONF['trackback_enabled'] &&  
($story->displayElements('trackbackcode') >= 0) &&
+                $show_comments) {
+            if (SEC_hasRights ('story.ping')) {
+                if (($story->displayElements('draft_flag') == 0) &&
+                    ($story->displayElements('day') < time ())) {
+                    $url = $_CONF['site_admin_url']
+                         . '/trackback.php?mode=sendall&amp;id=' .  
$story->getSid();
+                    $story_template->set_var ('send_trackback_link',
+                        COM_createLink($LANG_TRB['send_trackback'], $url));
+                    $story_template->set_var ('send_trackback_url', $url);
+                    $story_template->set_var ('lang_send_trackback_text',
+                                              $LANG_TRB['send_trackback']);
+                }
+            }
+
+            $permalink = COM_buildUrl ($_CONF['site_url']
+                                       . '/article.php?story=' .  
$story->getSid());
+            $story_template->set_var ('trackback',
+                    TRB_renderTrackbackComments  
($story->getSID(), 'article',
+                                                  
$story->displayElements('title'), $permalink));
+        } else {
+            $story_template->set_var ('trackback', '');
+        }
+        $display .= $story_template->finish ($story_template->parse  
('output', 'article'));
+        $display .= COM_siteFooter ();
+    }
+} else {
+    $display .= COM_refresh($_CONF['site_url'] . '/index.php');
+}
+
+echo $display;
+
+?>

Added: externals/geeklog-1.5.2sr2/public_html/comment.php
==============================================================================
--- (empty file)
+++ externals/geeklog-1.5.2sr2/public_html/comment.php	Sun Apr  5 18:08:35  
2009
@@ -0,0 +1,364 @@
+<?php
+
+/* Reminder: always indent with 4 spaces (no tabs). */
+//  
+---------------------------------------------------------------------------+
+// | Geeklog  
1.5                                                               |
+//  
+---------------------------------------------------------------------------+
+// |  
comment.php                                                               |
+//  
|                                                                            
|
+// | Let user comment on a story or  
plugin.                                    |
+//  
+---------------------------------------------------------------------------+
+// | Copyright (C) 2000-2009 by the following  
authors:                         |
+//  
|                                                                            
|
+// | Authors: Tony Bibbs        - tony AT tonybibbs DOT  
com                    |
+// |          Mark Limburg      - mlimburg AT users DOT sourceforge DOT  
net    |
+// |          Jason Whittenburg - jwhitten AT securitygeeks DOT  
com            |
+// |          Dirk Haun         - dirk AT haun-online DOT  
de                   |
+// |          Vincent Furia     - vinny01 AT users DOT sourceforge DOT  
net     |
+//  
+---------------------------------------------------------------------------+
+//  
|                                                                            
|
+// | This program is free software; you can redistribute it  
and/or             |
+// | modify it under the terms of the GNU General Public  
License               |
+// | as published by the Free Software Foundation; either version  
2            |
+// | of the License, or (at your option) any later  
version.                    |
+//  
|                                                                            
|
+// | This program is distributed in the hope that it will be  
useful,           |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty  
of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See  
the             |
+// | GNU General Public License for more  
details.                              |
+//  
|                                                                            
|
+// | You should have received a copy of the GNU General Public  
License         |
+// | along with this program; if not, write to the Free Software  
Foundation,   |
+// | Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,  
USA.           |
+//  
|                                                                            
|
+//  
+---------------------------------------------------------------------------+
+
+/**
+* This file is responsible for letting user enter a comment and saving the
+* comments to the DB.  All comment display stuff is in lib-common.php
+*
+* @author   Jason Whittenburg
+* @author   Tony Bibbs    <tonyAT tonybibbs DOT com>
+* @author   Vincent Furia <vinny01 AT users DOT sourceforge DOT net>
+*
+*/
+
+/**
+* Geeklog common function library
+*/
+require_once 'lib-common.php';
+
+/**
+ * Geeklog comment function library
+ */
+require_once $_CONF['path_system'] . 'lib-comment.php';
+
+// Uncomment the line below if you need to debug the HTTP variables being  
passed
+// to the script.  This will sometimes cause errors but it will allow you  
to see
+// the data being passed in a POST operation
+// echo COM_debug($_POST);
+
+/**
+ * Handles a comment submission
+ *
+ * @copyright Vincent Furia 2005
+ * @author Vincent Furia <vinny01 AT users DOT sourceforge DOT net>
+ * @return string HTML (possibly a refresh)
+ */
+function handleSubmit()
+{
+    global $_CONF, $_TABLES, $_USER, $LANG03;
+
+    $display = '';
+
+    $type = COM_applyFilter ($_POST['type']);
+    $sid = COM_applyFilter ($_POST['sid']);
+    switch ( $type ) {
+        case 'article':
+            $commentcode = DB_getItem ($_TABLES['stories'], 'commentcode',
+                                       "sid = '$sid'" .  
COM_getPermSQL('AND')
+                                       . " AND (draft_flag = 0) AND (date  
<= NOW()) "
+                                       . COM_getTopicSQL('AND'));
+            if (!isset($commentcode) || ($commentcode != 0)) {
+                return COM_refresh($_CONF['site_url'] . '/index.php');
+            }
+
+            $ret = CMT_saveComment ( strip_tags ($_POST['title']),
+                $_POST['comment'], $sid, COM_applyFilter ($_POST['pid'],  
true),
+                'article', COM_applyFilter ($_POST['postmode']));
+
+            if ( $ret > 0 ) { // failure //FIXME: some failures should not  
return to comment form
+                $display .= COM_siteHeader ('menu', $LANG03[1])
+                         . CMT_commentForm ($_POST['title'],  
$_POST['comment'],
+                           $sid, COM_applyFilter($_POST['pid']), $type,
+                           $LANG03[14],  
COM_applyFilter($_POST['postmode']))
+                         . COM_siteFooter();
+            } else { // success
+                $comments = DB_count ($_TABLES['comments'], 'sid', $sid);
+                DB_change ($_TABLES['stories'], 'comments',  
$comments, 'sid', $sid);
+                COM_olderStuff (); // update comment count in Older  
Stories block
+                $display = COM_refresh (COM_buildUrl ($_CONF['site_url']
+                    . "/article.php?story=$sid"));
+            }
+            break;
+        default: // assume plugin
+            if ( !($display = PLG_commentSave($type, strip_tags  
($_POST['title']),
+                                $_POST['comment'], $sid, COM_applyFilter  
($_POST['pid'], true),
+                                COM_applyFilter ($_POST['postmode']))) ) {
+                $display = COM_refresh ($_CONF['site_url'] . '/index.php');
+            }
+            break;
+    }
+
+    return $display;
+}
+
+/**
+ * Handles a comment submission
+ *
+ * @copyright Vincent Furia 2005
+ * @author Vincent Furia <vinny01 AT users DOT sourceforge DOT net>
+ * @return string HTML (possibly a refresh)
+ */
+function handleDelete()
+{
+    global $_CONF, $_TABLES;
+
+    $display = '';
+
+    $type = COM_applyFilter($_REQUEST['type']);
+    $sid = COM_applyFilter($_REQUEST['sid']);
+
+    switch ($type) {
+    case 'article':
+        $has_editPermissions = SEC_hasRights('story.edit');
+        $result = DB_query("SELECT  
owner_id,group_id,perm_owner,perm_group,perm_members,perm_anon FROM  
{$_TABLES['stories']} WHERE sid = '$sid'");
+        $A = DB_fetchArray($result);
+
+        if ($has_editPermissions && SEC_hasAccess($A['owner_id'],
+                $A['group_id'], $A['perm_owner'], $A['perm_group'],
+                $A['perm_members'], $A['perm_anon']) == 3) {
+            CMT_deleteComment(COM_applyFilter($_REQUEST['cid'], true),  
$sid,
+                              'article');
+            $comments = DB_count($_TABLES['comments'], 'sid', $sid);
+            DB_change($_TABLES['stories'], 'comments', $comments,
+                      'sid', $sid);
+            $display .= COM_refresh(COM_buildUrl ($_CONF['site_url']
+                                    . "/article.php?story=$sid") . '#comments');
+        } else {
+            COM_errorLog("User {$_USER['username']} (IP:  
{$_SERVER['REMOTE_ADDR']}) tried to illegally delete comment $cid from  
$type $sid");
+            $display .= COM_refresh($_CONF['site_url'] . '/index.php');
+        }
+        break;
+
+    default: // assume plugin
+        if (!($display = PLG_commentDelete($type,
+                            COM_applyFilter($_REQUEST['cid'], true),  
$sid))) {
+            $display = COM_refresh($_CONF['site_url'] . '/index.php');
+        }
+        break;
+    }
+
+    return $display;
+}
+
+/**
+ * Handles a comment view request
+ *
+ * @copyright Vincent Furia 2005
+ * @author Vincent Furia <vinny01 AT users DOT sourceforge DOT net>
+ * @param boolean $view View or display (true for view)
+ * @return string HTML (possibly a refresh)
+ */
+function handleView($view = true)
+{
+    global $_CONF, $_TABLES, $_USER, $LANG_ACCESS;
+
+    $display = '';
+
+    if ($view) {
+        $cid = COM_applyFilter ($_REQUEST['cid'], true);
+    } else {
+        $cid = COM_applyFilter ($_REQUEST['pid'], true);
+    }
+
+    if ($cid <= 0) {
+        return COM_refresh($_CONF['site_url'] . '/index.php');
+    }
+
+    $sql = "SELECT sid, title, type FROM {$_TABLES['comments']} WHERE cid  
= $cid";
+    $A = DB_fetchArray( DB_query($sql) );
+    $sid   = $A['sid'];
+    $title = $A['title'];
+    $type  = $A['type'];
+
+    $format = $_CONF['comment_mode'];
+    if( isset( $_REQUEST['format'] )) {
+        $format = COM_applyFilter( $_REQUEST['format'] );
+    }
+    if ( $format != 'threaded' && $format != 'nested' && $format != 'flat'  
) {
+        if ( $_USER['uid'] > 1 ) {
+            $format = DB_getItem( $_TABLES['usercomment'], 'commentmode',
+                                  "uid = {$_USER['uid']}" );
+        } else {
+            $format = $_CONF['comment_mode'];
+        }
+    }
+
+    switch ( $type ) {
+        case 'article':
+            $sql = 'SELECT COUNT(*) AS count, commentcode, owner_id,  
group_id, perm_owner, perm_group, '
+                 . "perm_members, perm_anon FROM {$_TABLES['stories']}  
WHERE (sid = '$sid') "
+                 . 'AND (draft_flag = 0) AND (commentcode >= 0) AND (date  
<= NOW())' . COM_getPermSQL('AND')
+                 . COM_getTopicSQL('AND') . ' GROUP BY sid,owner_id,  
group_id, perm_owner, perm_group,perm_members, perm_anon ';
+            $result = DB_query ($sql);
+            $B = DB_fetchArray ($result);
+            $allowed = $B['count'];
+
+            if ( $allowed == 1 ) {
+                $delete_option = ( SEC_hasRights( 'story.edit' ) &&
+                    ( SEC_hasAccess( $B['owner_id'], $B['group_id'],
+                        $B['perm_owner'], $B['perm_group'],  
$B['perm_members'],
+                        $B['perm_anon'] ) == 3 ) );
+                $order = '';
+                if (isset ( $_REQUEST['order'])) {
+                    $order = COM_applyFilter ($_REQUEST['order']);
+                }
+                $page = 0;
+                if (isset ($_REQUEST['page'])) {
+                    $page = COM_applyFilter ($_REQUEST['page'], true);
+                }
+                $display .= CMT_userComments ($sid, $title, $type, $order,
+                                $format, $cid, $page, $view,  
$delete_option,
+                                $B['commentcode']);
+            } else {
+                $display .= COM_startBlock  
($LANG_ACCESS['accessdenied'], '',
+                                    COM_getBlockTemplate  
('_msg_block', 'header'))
+                         . $LANG_ACCESS['storydenialmsg']
+                         . COM_endBlock (COM_getBlockTemplate  
('_msg_block', 'footer'));
+            }
+            break;
+
+        default: // assume plugin
+            if ( !($display = PLG_displayComment($type, $sid, $cid, $title,
+                                  COM_applyFilter ($_REQUEST['order']),  
$format,
+                                  COM_applyFilter ($_REQUEST['page'],  
true), $view)) ) {
+                return COM_refresh($_CONF['site_url'] . '/index.php');
+            }
+            break;
+    }
+
+    return COM_siteHeader('menu', $title) . $display . COM_siteFooter();
+}
+
+// MAIN
+$display = '';
+
+// If reply specified, force comment submission form
+if (isset ($_REQUEST['reply'])) {
+    $_REQUEST['mode'] = '';
+}
+
+$mode = '';
+if (!empty ($_REQUEST['mode'])) {
+    $mode = COM_applyFilter ($_REQUEST['mode']);
+}
+switch ($mode) {
+case $LANG03[14]: // Preview
+    $display .= COM_siteHeader('menu', $LANG03[14])
+             . CMT_commentForm (strip_tags ($_POST['title']),  
$_POST['comment'],
+                    COM_applyFilter ($_POST['sid']),
+                    COM_applyFilter ($_POST['pid'], true),
+                    COM_applyFilter ($_POST['type']), $mode,
+                    COM_applyFilter ($_POST['postmode']))
+             . COM_siteFooter();
+    break;
+
+case $LANG03[11]: // Submit Comment
+    $display .= handleSubmit();  // moved to function for readibility
+    break;
+
+case 'delete':
+    if (SEC_checkToken()) {
+        $display .= handleDelete();  // moved to function for readibility
+    } else {
+        $display .= COM_refresh($_CONF['site_url'] . '/index.php');
+    }
+    break;
+
+case 'view':
+    $display .= handleView(true);  // moved to function for readibility
+    break;
+
+case 'display':
+    $display .= handleView(false);  // moved to function for readibility
+    break;
+
+case 'report':
+    $display .= COM_siteHeader('menu', $LANG03[27])
+             . CMT_reportAbusiveComment(COM_applyFilter($_GET['cid'],  
true),
+                                        COM_applyFilter($_GET['type']))
+             . COM_siteFooter();
+    break;
+
+case 'sendreport':
+    if (SEC_checkToken()) {
+        $display .= CMT_sendReport(COM_applyFilter($_POST['cid'], true),
+                                   COM_applyFilter($_POST['type']));
+    } else {
+        $display .= COM_refresh($_CONF['site_url'] . '/index.php');
+    }
+    break;
+
+default:  // New Comment
+    $abort = false;
+    $sid = COM_applyFilter ($_REQUEST['sid']);
+    $type = COM_applyFilter ($_REQUEST['type']);
+    $title = '';
+    if (isset ($_REQUEST['title'])) {
+        $title = strip_tags ($_REQUEST['title']);
+    }
+    $postmode = $_CONF['postmode'];
+    if (isset ($_REQUEST['postmode'])) {
+        $postmode = COM_applyFilter ($_REQUEST['postmode']);
+    }
+
+    if ($type == 'article') {
+        $dbTitle = DB_getItem($_TABLES['stories'], 'title',
+                                "sid = '{$sid}'" . COM_getPermSQL('AND')
+                                . " AND (draft_flag = 0) AND (date <=  
NOW()) "
+                                . COM_getTopicSQL('AND'));
+        if ($dbTitle === null) {
+            // no permissions, or no story of that title
+            $display = COM_refresh($_CONF['site_url'] . '/index.php');
+            $abort = true;
+        }
+    }
+    if (!$abort) {
+        if (!empty ($sid) && !empty ($type)) {
+            if (empty ($title)) {
+                if ($type == 'article') {
+                    $title = $dbTitle;
+                }
+                $title = str_replace ('$', '&#36;', $title);
+                // CMT_commentForm expects non-htmlspecial chars for  
title...
+                $title = str_replace ( '&amp;', '&', $title );
+                $title = str_replace ( '&quot;', '"', $title );
+                $title = str_replace ( '&lt;', '<', $title );
+                $title = str_replace ( '&gt;', '>', $title );
+            }
+            $display .= COM_siteHeader('menu', $LANG03[1])
+                     . CMT_commentForm ($title, '', $sid,
+                            COM_applyFilter ($_REQUEST['pid'], true),  
$type, $mode,
+                            $postmode)
+                     . COM_siteFooter();
+        } else {
+            $display .= COM_refresh($_CONF['site_url'] . '/index.php');
+        }
+    }
+    break;
+}
+
+echo $display;
+
+?>

Added: externals/geeklog-1.5.2sr2/public_html/directory.php
==============================================================================
--- (empty file)
+++ externals/geeklog-1.5.2sr2/public_html/directory.php	Sun Apr  5  
18:08:35 2009
@@ -0,0 +1,498 @@
+<?php
+
+/* Reminder: always indent with 4 spaces (no tabs). */
+//  
+---------------------------------------------------------------------------+
+// | Geeklog  
1.5                                                               |
+//  
+---------------------------------------------------------------------------+
+// |  
directory.php                                                             |
+//  
|                                                                            
|
+// | Directory of all the stories on a Geeklog  
site.                           |
+//  
+---------------------------------------------------------------------------+
+// | Copyright (C) 2004-2008 by the following  
authors:                         |
+//  
|                                                                            
|
+// | Authors: Dirk Haun         - dirk AT haun-online DOT  
de                   |
+//  
+---------------------------------------------------------------------------+
+//  
|                                                                            
|
+// | This program is free software; you can redistribute it  
and/or             |
+// | modify it under the terms of the GNU General Public  
License               |
+// | as published by the Free Software Foundation; either version  
2            |
+// | of the License, or (at your option) any later  
version.                    |
+//  
|                                                                            
|
+// | This program is distributed in the hope that it will be  
useful,           |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty  
of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See  
the             |
+// | GNU General Public License for more  
details.                              |
+//  
|                                                                            
|
+// | You should have received a copy of the GNU General Public  
License         |
+// | along with this program; if not, write to the Free Software  
Foundation,   |
+// | Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,  
USA.           |
+//  
|                                                                            
|
+//  
+---------------------------------------------------------------------------+
+//
+// $Id: directory.php,v 1.19 2008/06/20 19:12:56 dhaun Exp $
+
+require_once ('lib-common.php');
+
+// configuration option:
+// List stories for the current month on top of the overview page
+// (if set = true)
+$conf_list_current_month = false;
+
+// name of this script
+define ('THIS_SCRIPT', 'directory.php');
+
+$display = '';
+
+if (empty ($_USER['username']) && (($_CONF['loginrequired'] == 1) ||
+                                   ($_CONF['directoryloginrequired'] ==  
1))) {
+    $display = COM_siteHeader ('menu', $LANG_DIR['title']);
+    $display .= COM_startBlock ($LANG_LOGIN[1], '',
+                                COM_getBlockTemplate  
('_msg_block', 'header'));
+    $login = new Template ($_CONF['path_layout'] . 'submit');
+    $login->set_file (array ('login' => 'submitloginrequired.thtml'));
+    $login->set_var ( 'xhtml', XHTML );
+    $login->set_var ('site_url', $_CONF['site_url']);
+    $login->set_var ('layout_url', $_CONF['layout_url']);
+    $login->set_var ('login_message', $LANG_LOGIN[2]);
+    $login->set_var ('lang_login', $LANG_LOGIN[3]);
+    $login->set_var ('lang_newuser', $LANG_LOGIN[4]);
+    $login->parse ('output', 'login');
+    $display .= $login->finish ($login->get_var ('output'));
+    $display .= COM_endBlock (COM_getBlockTemplate  
('_msg_block', 'footer'));
+    $display .= COM_siteFooter ();
+    echo $display;
+    exit;
+}
+
+/**
+* Helper function: Calculate last day of a given month
+*
+* @param    int     $month  Month
+* @param    int     $year   Year
+* @return   int             Number of days in that month
+* @bugs     Will fail from 2038 onwards ...
+*
+* "The last day of any given month can be expressed as the "0" day
+* of the next month", http://www.php.net/manual/en/function.mktime.php
+*
+*/
+function DIR_lastDayOfMonth ($month, $year)
+{
+    $month++;
+    if ($month > 12) {
+        $month = 1;
+        $year++;
+    }
+
+    $lastday = mktime (0, 0, 0, $month, 0, $year);
+
+    return intval(strftime('%d', $lastday));
+}
+
+/**
+* Display a topic selection drop-down menu
+*
+* @param    string  $topic          current topic
+* @param    int     $year           current year
+* @param    int     $month          current month
+* @param    bool    $standalone     true: don't display form inline
+*
+*/
+function DIR_topicList ($topic = 'all', $year = 0, $month = 0, $standalone  
= false)
+{
+    global $_CONF, $LANG21;
+
+    $retval = '';
+
+    $url = $_CONF['site_url'] . '/' . THIS_SCRIPT;
+    $retval .= '<form action="' . $url . '" method="post"';
+    if (!$standalone) {
+        $retval .= ' style="display:inline; float:right"' . LB;
+    }
+    $retval .= '><div>' . LB;
+    $retval .= '<select name="topic" onchange="this.form.submit()">' . LB;
+    $retval .= '<option value="all"';
+    if ($topic == 'all') {
+        $retval .= ' selected="selected"';
+    }
+    $retval .= '>' . $LANG21[7] . '</option>' . LB;
+    $retval .= COM_topicList ('tid,topic', $topic);
+    $retval .= '</select>' . LB;
+    $retval .= '<input type="hidden" name="year" value="' . $year . '"' .  
XHTML . '>';
+    $retval .= '<input type="hidden" name="month" value="' .  
$month . '"' . XHTML . '>';
+    $retval .= '</div></form>' . LB;
+
+    return $retval;
+}
+
+/**
+* Build link to a month's page
+*
+* @param    string  $topic  current topic
+* @param    int     $year   year to link to
+* @param    int     $month  month to link to
+* @param    int     $count  number of stories for that month (may be 0)
+* @return   string          month name + count, as link or plain text
+*
+*/
+function DIR_monthLink ($topic, $year, $month, $count)
+{
+    global $_CONF, $LANG_MONTH;
+
+    $retval = $LANG_MONTH[$month] . ' (' . COM_numberFormat  
($count) . ')' . LB;
+
+    if ($count > 0) {
+        $month_url = COM_buildUrl ($_CONF['site_url'] . '/'
+            . THIS_SCRIPT . '?topic=' . urlencode ($topic) . '&amp;year='
+            . $year . '&amp;month=' . $month);
+        $retval =  COM_createLink ($retval, $month_url);
+    }
+
+    $retval .= LB;
+
+    return $retval;
+}
+
+/**
+* Display navigation bar
+*
+* @param    string  $topic  current topic
+* @param    int     $year   current year
+* @param    int     $month  current month (or 0 for year view pages)
+* @return   string          navigation bar with prev, next, and "up" links
+*
+*/
+function DIR_navBar ($topic, $year, $month = 0)
+{
+    global $_CONF, $_TABLES, $LANG05, $LANG_DIR;
+
+    $retval = '';
+
+    $retval .= '<div class="pagenav">';
+
+    if ($month == 0) {
+        $prevyear = $year - 1;
+        $nextyear = $year + 1;
+    } else {
+        $prevyear = $year;
+        $prevmonth = $month - 1;
+        if ($prevmonth == 0) {
+            $prevmonth = 12;
+            $prevyear--;
+        }
+        $nextyear = $year;
+        $nextmonth = $month + 1;
+        if ($nextmonth > 12) {
+            $nextmonth = 1;
+            $nextyear++;
+        }
+    }
+
+    $result = DB_query ("SELECT MIN(YEAR(date)) AS year FROM  
{$_TABLES['stories']}");
+    $A = DB_fetchArray ($result);
+    if ($prevyear < $A['year']) {
+        $prevyear = 0;
+    }
+
+    $currentyear = date ('Y', time ());
+    if ($nextyear > $currentyear) {
+        $nextyear = 0;
+    }
+
+    if ($prevyear > 0) {
+        $url = $_CONF['site_url'] . '/' . THIS_SCRIPT . '?topic='
+             . urlencode ($topic) . '&amp;year=' . $prevyear;
+        if ($month > 0) {
+            $url .= '&amp;month=' . $prevmonth;
+        }
+        $retval .= COM_createLink($LANG05[6], COM_buildUrl ($url));
+    } else {
+        $retval .= $LANG05[6];
+    }
+
+    $retval .= ' | ';
+
+    $url = $_CONF['site_url'] . '/' . THIS_SCRIPT;
+    if ($topic != 'all') {
+        $url = COM_buildUrl ($url . '?topic=' . urlencode ($topic));
+    }
+
+    $retval .= COM_createLink($LANG_DIR['nav_top'] , $url);
+
+    $retval .= ' | ';
+
+    if ($nextyear > 0) {
+        $url = $_CONF['site_url'] . '/' . THIS_SCRIPT . '?topic='
+             . urlencode ($topic) . '&amp;year=' . $nextyear;
+        if ($month > 0) {
+            $url .= '&amp;month=' . $nextmonth;
+        }
+        $retval .= COM_createLink($LANG05[5], COM_buildUrl ($url));
+    } else {
+        $retval .= $LANG05[5];
+    }
+
+    $retval .= '</div>' . LB;
+
+    return $retval;
+}
+
+/**
+* Display month view
+*
+* @param    string  $topic  current topic
+* @param    int     $year   year to display
+* @param    int     $month  month to display
+* @param    bool    $main   true: display view on its own page
+* @return   string          list of articles for the given month
+*
+*/
+function DIR_displayMonth ($topic, $year, $month, $main = false)
+{
+    global $_CONF, $_TABLES, $LANG_MONTH, $LANG_DIR;
+
+    $retval = '';
+
+    if ($main) {
+        $retval .= '<div><h1 style="display:inline">' . $LANG_MONTH[$month]
+                . ' ' . $year . '</h1> ' . DIR_topicList ($topic, $year,  
$month)
+                . '</div>' . LB;
+    } else {
+        $retval .= '<h1>' . $LANG_MONTH[$month] . ' ' . $year . '</h1>' .  
LB;
+    }
+
+    $start = sprintf ('%04d-%02d-01 00:00:00', $year, $month);
+    $lastday = DIR_lastDayOfMonth ($month, $year);
+    $end   = sprintf ('%04d-%02d-%02d 23:59:59', $year, $month, $lastday);
+
+    $sql = "SELECT sid,title,UNIX_TIMESTAMP(date) AS  
day,DATE_FORMAT(date, '%e') AS mday FROM {$_TABLES['stories']} WHERE (date  
>= '$start') AND (date <= '$end') AND (draft_flag = 0) AND (date <= NOW())";
+    if ($topic != 'all') {
+        $sql .= " AND (tid = '$topic')";
+    }
+    $sql .= COM_getTopicSql ('AND') . COM_getPermSql ('AND')
+         . COM_getLangSQL ('sid', 'AND') . " ORDER BY date ASC";
+
+    $result = DB_query ($sql);
+    $numrows = DB_numRows ($result);
+
+    if ($numrows > 0) {
+        $entries = array ();
+        $mday = 0;
+
+        for ($i = 0; $i < $numrows; $i++) {
+            $A = DB_fetchArray ($result);
+
+            if ($mday != $A['mday']) {
+                if (sizeof ($entries) > 0) {
+                    $retval .= COM_makeList ($entries);
+                    $entries = array ();
+                }
+
+                $day = strftime ($_CONF['shortdate'], $A['day']);
+
+                $retval .= '<h2>' . $day . '</h2>' . LB;
+
+                $mday = $A['mday'];
+            }
+
+            $url = COM_buildUrl ($_CONF['site_url'] . '/article.php?story='
+                                 . $A['sid']);
+            $entries[] = COM_createLink(stripslashes ($A['title']), $url);
+        }
+
+        if (sizeof ($entries) > 0) {
+            $retval .= COM_makeList ($entries);
+        }
+
+    } else {
+        $retval .= '<p>' . $LANG_DIR['no_articles'] . '</p>';
+    }
+
+    $retval .= LB;
+
+    return $retval;
+}
+
+/**
+* Display year view
+*
+* @param    string  $topic  current topic
+* @param    int     $year   year to display
+* @param    bool    $main   true: display view on its own page
+* @return   string          list of months (+ number of stories) for given  
year
+*
+*/
+function DIR_displayYear ($topic, $year, $main = false)
+{
+    global $_CONF, $_TABLES, $LANG_MONTH, $LANG_DIR;
+
+    $retval = '';
+
+    if ($main) {
+        $retval .= '<div><h1 style="display:inline">' . $year . '</h1> '
+                . DIR_topicList ($topic, $year) . '</div>' . LB;
+    } else {
+        $retval .= '<h2>' . $year . '</h2>' . LB;
+    }
+
+    $currentyear = date ('Y', time ());
+    $currentmonth = date ('m', time ());
+
+    $start = sprintf ('%04d-01-01 00:00:00', $year);
+    $end   = sprintf ('%04d-12-31 23:59:59', $year);
+
+    $monthsql = array();
+    $monthsql['mysql'] = "SELECT DISTINCT MONTH(date) AS month,COUNT(*) AS  
count FROM {$_TABLES['stories']} WHERE (date >= '$start') AND (date  
<= '$end') AND (draft_flag = 0) AND (date <= NOW())";
+    $monthsql['mssql'] = "SELECT MONTH(date) AS month,COUNT(sid) AS count  
FROM {$_TABLES['stories']} WHERE (date >= '$start') AND (date <= '$end')  
AND (draft_flag = 0) AND (date <= NOW())";
+    if ($topic != 'all') {
+        $monthsql['mysql'] .= " AND (tid = '$topic')";
+        $monthsql['mssql'] .= " AND (tid = '$topic')";
+    }
+    $monthsql['mysql'] .= COM_getTopicSql ('AND') . COM_getPermSql ('AND')
+              . COM_getLangSQL ('sid', 'AND');
+    $monthsql['mssql'] .= COM_getTopicSql ('AND') . COM_getPermSql ('AND')
+              . COM_getLangSQL ('sid', 'AND');
+
+    $msql = array();
+    $msql['mysql'] = $monthsql['mysql'] . " GROUP BY MONTH(date) ORDER BY  
date ASC";
+    $msql['mssql'] = $monthsql['mssql'] . " GROUP BY MONTH(date) ORDER BY  
month(date) ASC";
+
+    $mresult = DB_query ($msql);
+    $nummonths = DB_numRows ($mresult);
+
+    if ($nummonths > 0) {
+        $retval .= '<ul>' . LB;
+        $lastm = 1;
+        for ($j = 0; $j < $nummonths; $j++) {
+            $M = DB_fetchArray ($mresult);
+
+            for (; $lastm < $M['month']; $lastm++) {
+                $retval .= '<li>' . DIR_monthLink ($topic, $year, $lastm,  
0)
+                        . '</li>';
+            }
+            $lastm = $M['month'] + 1;
+
+            $retval .= '<li>' . DIR_monthLink ($topic, $year, $M['month'],
+                                               $M['count']) . '</li>';
+        }
+
+        if ($year == $currentyear) {
+            $fillm = $currentmonth;
+        } else {
+            $fillm = 12;
+        }
+
+        if ($lastm <= $fillm) {
+            for (; $lastm <= $fillm; $lastm++) {
+                $retval .= '<li>' . DIR_monthLink ($topic, $year, $lastm,  
0)
+                        . '</li>';
+            }
+        }
+
+        $retval .= '</ul>' . LB;
+    } else {
+        $retval .= '<p>' . $LANG_DIR['no_articles'] . '</p>';
+    }
+
+    $retval .= LB;
+
+    return $retval;
+}
+
+/**
+* Display main view (list of years)
+*
+* Displays an overview of all the years and months, starting with the first
+* year for which a story has been posted. Can optionally display a list of
+* the stories for the current month at the top of the page.
+*
+* @param    string  $topic                  current topic
+* @param    bool    $list_current_month     true = list stories f. current  
month
+* @return   string                          list of all the years in the db
+*
+*/
+function DIR_displayAll ($topic, $list_current_month = false)
+{
+    global $_TABLES, $LANG_DIR;
+
+    $retval = '';
+
+    if ($list_current_month) {
+        $currentyear = date ('Y', time ());
+        $currentmonth = date ('n', time ());
+
+        $retval .= DIR_displayMonth ($topic, $currentyear, $currentmonth);
+
+        $retval .= '<hr' . XHTML . '>' . LB;
+    }
+
+    $retval .= '<div><h1 style="display:inline">' . $LANG_DIR['title']
+            . '</h1> ' . DIR_topicList ($topic) . '</div>' . LB;
+
+    $yearsql = array();
+    $yearsql['mysql'] = "SELECT DISTINCT YEAR(date) AS year,date FROM  
{$_TABLES['stories']} WHERE (draft_flag = 0) AND (date <= NOW())" .  
COM_getTopicSql ('AND') . COM_getPermSql ('AND')  . COM_getLangSQL  
('sid', 'AND');
+    $yearsql['mssql'] = "SELECT YEAR(date) AS year FROM  
{$_TABLES['stories']} WHERE (draft_flag = 0) AND (date <= NOW())" .  
COM_getTopicSql ('AND') . COM_getPermSql ('AND')  . COM_getLangSQL  
('sid', 'AND');
+    $ysql = array();
+    $ysql['mysql'] = $yearsql['mysql'] . " GROUP BY YEAR(date) ORDER BY  
date DESC";
+    $ysql['mssql'] = $yearsql['mssql'] . " GROUP BY YEAR(date) ORDER BY  
YEAR(date) DESC";
+
+    $yresult = DB_query ($ysql);
+    $numyears = DB_numRows ($yresult);
+
+    for ($i = 0; $i < $numyears; $i++) {
+        $Y = DB_fetchArray ($yresult);
+
+        $retval .= DIR_displayYear ($topic, $Y['year']);
+    }
+
+    return $retval;
+}
+
+// MAIN
+$display = '';
+
+if (isset ($_POST['topic']) && isset ($_POST['year']) && isset  
($_POST['month'])) {
+    $topic = $_POST['topic'];
+    $year = $_POST['year'];
+    $month = $_POST['month'];
+} else {
+    COM_setArgNames (array ('topic', 'year', 'month'));
+    $topic = COM_getArgument ('topic');
+    $year = COM_getArgument ('year');
+    $month = COM_getArgument ('month');
+}
+
+$topic = COM_applyFilter ($topic);
+if (empty ($topic)) {
+    $topic = 'all';
+}
+$year = COM_applyFilter ($year, true);
+if ($year < 0) {
+    $year = 0;
+}
+$month = COM_applyFilter ($month, true);
+if (($month < 1) || ($month > 12)) {
+    $month = 0;
+}
+
+if (($year != 0) && ($month != 0)) {
+    $title = sprintf ($LANG_DIR['title_month_year'],
+                      $LANG_MONTH[$month], $year);
+    $display .= COM_siteHeader ('menu', $title);
+    $display .= DIR_displayMonth ($topic, $year, $month, true);
+    $display .= DIR_navBar ($topic, $year, $month);
+} else if ($year != 0) {
+    $title = sprintf ($LANG_DIR['title_year'], $year);
+    $display .= COM_siteHeader ('menu', $title);
+    $display .= DIR_displayYear ($topic, $year, true);
+    $display .= DIR_navBar ($topic, $year);
+} else {
+    $display .= COM_siteHeader ('menu', $LANG_DIR['title']);
+    $display .= DIR_displayAll ($topic, $conf_list_current_month);
+}
+
+$display .= COM_siteFooter (true);
+
+echo $display;
+
+?>

Added: externals/geeklog-1.5.2sr2/public_html/getimage.php
==============================================================================
--- (empty file)
+++ externals/geeklog-1.5.2sr2/public_html/getimage.php	Sun Apr  5 18:08:35  
2009
@@ -0,0 +1,109 @@
+<?php
+
+/* Reminder: always indent with 4 spaces (no tabs). */
+//  
+---------------------------------------------------------------------------+
+// | Geeklog  
1.4                                                               |
+//  
+---------------------------------------------------------------------------+
+// |  
getimage.php                                                              |
+//  
|                                                                            
|
+// | Shows images outside of the  
webtree                                       |
+//  
+---------------------------------------------------------------------------+
+// | Copyright (C) 2004-2006 by the following  
authors:                         |
+//  
|                                                                            
|
+// | Authors: Tony Bibbs        - tony AT tonybibbs DOT  
com                    |
+//  
+---------------------------------------------------------------------------+
+//  
|                                                                            
|
+// | This program is free software; you can redistribute it  
and/or             |
+// | modify it under the terms of the GNU General Public  
License               |
+// | as published by the Free Software Foundation; either version  
2            |
+// | of the License, or (at your option) any later  
version.                    |
+//  
|                                                                            
|
+// | This program is distributed in the hope that it will be  
useful,           |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty  
of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See  
the             |
+// | GNU General Public License for more  
details.                              |
+//  
|                                                                            
|
+// | You should have received a copy of the GNU General Public  
License         |
+// | along with this program; if not, write to the Free Software  
Foundation,   |
+// | Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,  
USA.           |
+//  
|                                                                            
|
+//  
+---------------------------------------------------------------------------+
+//
+// $Id: getimage.php,v 1.8 2007/11/25 06:55:07 ospiess Exp $
+
+/**
+* For really strict webhosts, this file an be used to show images in pages  
that
+* serve the images from outside of the webtree to a place that the  
webserver
+* user can actually write too
+*
+* @author   Tony Bibbs <tony****@tonyb*****>
+*
+*/
+
+require_once 'lib-common.php';
+
+require_once $_CONF['path_system'] . 'classes/downloader.class.php';
+
+$downloader = new downloader();
+
+$downloader->setLogFile($_CONF['path_log'] . 'error.log');
+
+$downloader->setLogging(true);
+
+$downloader->setAllowedExtensions(array('gif' => 'image/gif',
+                                        'jpg' => 'image/jpeg',
+                                        'jpeg' => 'image/jpeg',
+                                        'png' => 'image/x-png',
+                                       )
+                                 );
+
+$mode = '';
+if (isset($_GET['mode'])) {
+    $mode = $_GET['mode'];
+}
+$image = '';
+if (isset($_GET['image'])) {
+    $image = COM_applyFilter ($_GET['image']);
+}
+if (strstr($image, '..')) {
+    // Can you believe this, some jackass tried to relative pathing to  
access
+    // files they shouldn't have access to?
+    COM_accessLog('Someone tried to illegally access files using  
getimage.php');
+    exit;
+}
+
+// Set the path properly
+switch ($mode) {
+    case 'show':
+    case 'articles':
+        $downloader->setPath($_CONF['path_images'] . 'articles/');
+        break;
+    case 'topics':
+        $downloader->setPath($_CONF['path_images'] . 'topics/');
+        break;
+    case 'userphotos':
+        $downloader->setPath($_CONF['path_images'] . 'userphotos/');
+        break;
+    default:
+        // Hrm, got a bad path, just die
+        exit;
+}
+
+// Let's see if we don't have a legit file.  If not bail
+if (is_file($downloader->getPath() . $image)) {
+    if ($mode == 'show') {
+        echo '<html><body><img src="' .  
$_CONF['site_url'] . '/getimage.php?mode=articles&amp;image=' . $image . '"  
alt=""' . XHTML . '></body></html>';
+    } else {
+        $downloader->downloadFile($image);
+    }
+} else {
+    $display = COM_errorLog('File, ' . $image . ', was not found in  
getimage.php');
+
+    if ($mode == 'show') {
+        echo COM_siteHeader ('menu') . $display . COM_siteFooter ();
+    } else {
+        header ('HTTP/1.0 404 Not Found');
+    }
+}
+
+?>

Added: externals/geeklog-1.5.2sr2/public_html/index.php
==============================================================================
--- (empty file)
+++ externals/geeklog-1.5.2sr2/public_html/index.php	Sun Apr  5 18:08:35  
2009
@@ -0,0 +1,361 @@
+<?php
+
+/* Reminder: always indent with 4 spaces (no tabs). */
+//  
+---------------------------------------------------------------------------+
+// | Geeklog  
1.4                                                               |
+//  
+---------------------------------------------------------------------------+
+// |  
index.php                                                                 |
+//  
|                                                                            
|
+// | Geeklog  
homepage.                                                         |
+//  
+---------------------------------------------------------------------------+
+// | Copyright (C) 2000-2007 by the following  
authors:                         |
+//  
|                                                                            
|
+// | Authors: Tony Bibbs        -  
tony****@tonyb*****                           |
+// |          Mark Limburg      -  
mlimb****@users*****               |
+// |          Jason Whittenburg -  
jwhit****@secur*****                   |
+// |          Dirk Haun         -  
dirk****@haun-*****                          |
+//  
+---------------------------------------------------------------------------+
+//  
|                                                                            
|
+// | This program is free software; you can redistribute it  
and/or             |
+// | modify it under the terms of the GNU General Public  
License               |
+// | as published by the Free Software Foundation; either version  
2            |
+// | of the License, or (at your option) any later  
version.                    |
+//  
|                                                                            
|
+// | This program is distributed in the hope that it will be  
useful,           |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty  
of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See  
the             |
+// | GNU General Public License for more  
details.                              |
+//  
|                                                                            
|
+// | You should have received a copy of the GNU General Public  
License         |
+// | along with this program; if not, write to the Free Software  
Foundation,   |
+// | Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,  
USA.           |
+//  
|                                                                            
|
+//  
+---------------------------------------------------------------------------+
+//
+// $Id: index.php,v 1.99 2008/08/14 19:05:53 mjervis Exp $
+
+require_once ('lib-common.php');
+require_once ($_CONF['path_system'] . 'lib-story.php');
+
+$newstories = false;
+$displayall = false;
+$microsummary = false;
+if (isset ($_GET['display'])) {
+    if (($_GET['display'] == 'new') && (empty ($topic))) {
+        $newstories = true;
+    } else if (($_GET['display'] == 'all') && (empty ($topic))) {
+        $displayall = true;
+    } else if ($_GET['display'] == 'microsummary') {
+        $microsummary = true;
+    }
+}
+
+// Retrieve the archive topic - currently only one supported
+$archivetid = DB_getItem ($_TABLES['topics'], 'tid', "archive_flag=1");
+
+// Microsummary support:
+// see: http://wiki.mozilla.org/Microsummaries
+if( $microsummary )
+{
+    $sql = " (date <= NOW()) AND (draft_flag = 0)";
+
+    if (empty ($topic)) {
+        $sql .= COM_getLangSQL ('tid', 'AND', 's');
+    }
+
+    // if a topic was provided only select those stories.
+    if (!empty($topic)) {
+        $sql .= " AND s.tid = '$topic' ";
+    } elseif (!$newstories) {
+        $sql .= " AND frontpage = 1 ";
+    }
+
+    if ($topic != $archivetid) {
+        $sql .= " AND s.tid != '{$archivetid}' ";
+    }
+
+    $sql .= COM_getPermSQL ('AND', 0, 2, 's');
+    $sql .= COM_getTopicSQL ('AND', 0, 's') . ' ';
+    $msql = array();
+    $msql['mysql']="SELECT STRAIGHT_JOIN s.title "
+         . "FROM {$_TABLES['stories']} AS s, {$_TABLES['users']} AS u, "
+         . "{$_TABLES['topics']} AS t WHERE (s.uid = u.uid) AND (s.tid =  
t.tid) AND"
+         . $sql . "ORDER BY featured DESC, date DESC LIMIT 0, 1";
+
+    $msql['mssql']="SELECT STRAIGHT_JOIN s.title "
+         . "FROM {$_TABLES['stories']} AS s, {$_TABLES['users']} AS u, "
+         . "{$_TABLES['topics']} AS t WHERE (s.uid = u.uid) AND (s.tid =  
t.tid) AND"
+         . $sql . "ORDER BY featured DESC, date DESC LIMIT 0, 1";
+    $result = DB_query ($msql);
+
+    if ( $A = DB_fetchArray( $result ) ) {
+        $pagetitle = $_CONF['microsummary_short'].$A['title'];
+    } else {
+        if(isset( $_CONF['pagetitle'] ))
+        {
+            $pagetitle = $_CONF['pagetitle'];
+        }
+        if( empty( $pagetitle ))
+        {
+            if( empty( $topic ))
+            {
+                $pagetitle = $_CONF['site_slogan'];
+            }
+            else
+            {
+                $pagetitle = stripslashes( DB_getItem(  
$_TABLES['topics'], 'topic',
+                                                       "tid = '$topic'" ));
+            }
+        }
+        $pagetitle = $_CONF['site_name'] . ' - ' . $pagetitle;
+    }
+    die($pagetitle);
+}
+
+
+$page = 1;
+if (isset ($_GET['page'])) {
+    $page = COM_applyFilter ($_GET['page'], true);
+    if ($page == 0) {
+        $page = 1;
+    }
+}
+
+$display = '';
+
+if (!$newstories && !$displayall) {
+    // give plugins a chance to replace this page entirely
+    $newcontent = PLG_showCenterblock (0, $page, $topic);
+    if (!empty ($newcontent)) {
+        echo $newcontent;
+        exit;
+    }
+}
+
+if($topic)
+{
+    $header = '<link rel="microsummary" href="' . $_CONF['site_url']
+            . '/index.php?display=microsummary&amp;topic=' .  
urlencode($topic)
+            . '" title="Microsummary"' . XHTML . '>';
+} else {
+    $header = '<link rel="microsummary" href="' . $_CONF['site_url']
+            . '/index.php?display=microsummary" title="Microsummary"' .  
XHTML . '>';
+}
+$display .= COM_siteHeader('menu', '', $header);
+if (isset ($_GET['msg'])) {
+    $plugin = '';
+    if (isset ($_GET['plugin'])) {
+        $plugin = COM_applyFilter ($_GET['plugin']);
+    }
+    $display .= COM_showMessage (COM_applyFilter ($_GET['msg'], true),  
$plugin);
+}
+
+
+// Show any Plugin formatted blocks
+// Requires a plugin to have a function called  
plugin_centerblock_<plugin_name>
+$displayBlock = PLG_showCenterblock (1, $page, $topic); // top blocks
+if (!empty ($displayBlock)) {
+    $display .= $displayBlock;
+    // Check if theme has added the template which allows the centerblock
+    // to span the top over the rightblocks
+    if (file_exists($_CONF['path_layout'] . 'topcenterblock-span.thtml')) {
+            $topspan = new Template($_CONF['path_layout']);
+            $topspan->set_file (array  
('topspan'=>'topcenterblock-span.thtml'));
+            $topspan->set_var( 'xhtml', XHTML );
+            $topspan->set_var( 'site_url', $_CONF['site_url'] );
+            $topspan->set_var( 'site_admin_url', $_CONF['site_admin_url']  
);
+            $topspan->set_var( 'layout_url', $_CONF['layout_url'] );
+            $topspan->parse ('output', 'topspan');
+            $display .= $topspan->finish ($topspan->get_var('output'));
+            $GLOBALS['centerspan'] = true;
+    }
+}
+
+if (isset ($_USER['uid']) && ($_USER['uid'] > 1)) {
+    $result = DB_query("SELECT maxstories,tids,aids FROM  
{$_TABLES['userindex']} WHERE uid = '{$_USER['uid']}'");
+    $U = DB_fetchArray($result);
+} else {
+    $U['maxstories'] = 0;
+}
+
+$maxstories = 0;
+if ($U['maxstories'] >= $_CONF['minnews']) {
+    $maxstories = $U['maxstories'];
+}
+if ((!empty ($topic)) && ($maxstories == 0)) {
+    $topiclimit = DB_getItem ($_TABLES['topics'], 'limitnews',
+                              "tid = '{$topic}'");
+    if ($topiclimit >= $_CONF['minnews']) {
+        $maxstories = $topiclimit;
+    }
+}
+if ($maxstories == 0) {
+    $maxstories = $_CONF['limitnews'];
+}
+
+$limit = $maxstories;
+if ($limit < 1) {
+    $limit = 1;
+}
+
+// Geeklog now allows for articles to be published in the future.  Because  
of
+// this, we need to check to see if we need to rebuild the RDF file in the  
case
+// that any such articles have now been published
+COM_rdfUpToDateCheck();
+
+// For similar reasons, we need to see if there are currently two featured
+// articles.  Can only have one but you can have one current featured  
article
+// and one for the future...this check will set the latest one as featured
+// solely
+COM_featuredCheck();
+
+// Scan for any stories that have expired and should be archived or deleted
+$asql = "SELECT sid,tid,title,expire,statuscode FROM  
{$_TABLES['stories']} ";
+$asql .= 'WHERE (expire <= NOW()) AND (statuscode = ' .  
STORY_DELETE_ON_EXPIRE;
+if (empty ($archivetid)) {
+    $asql .= ')';
+} else {
+    $asql .= ' OR statuscode = ' . STORY_ARCHIVE_ON_EXPIRE . ") AND  
tid != '$archivetid'";
+}
+$expiresql = DB_query ($asql);
+while (list ($sid, $expiretopic, $title, $expire, $statuscode) =  
DB_fetchArray ($expiresql)) {
+    if ($statuscode == STORY_ARCHIVE_ON_EXPIRE) {
+        if (!empty ($archivetid) ) {
+            COM_errorLOG("Archive Story: $sid, Topic: $archivetid, Title:  
$title, Expired: $expire");
+            DB_query ("UPDATE {$_TABLES['stories']} SET tid  
= '$archivetid', frontpage = '0', featured = '0' WHERE sid='{$sid}'");
+        }
+    } else if ($statuscode == STORY_DELETE_ON_EXPIRE) {
+        COM_errorLOG("Delete Story and comments: $sid, Topic:  
$expiretopic, Title: $title, Expired: $expire");
+        STORY_deleteImages ($sid);
+        DB_query("DELETE FROM {$_TABLES['comments']} WHERE sid='{$sid}'  
AND type = 'article'");
+        DB_query("DELETE FROM {$_TABLES['stories']} WHERE sid='{$sid}'");
+    }
+}
+
+$sql = " (date <= NOW()) AND (draft_flag = 0)";
+
+if (empty ($topic)) {
+    $sql .= COM_getLangSQL ('tid', 'AND', 's');
+}
+
+// if a topic was provided only select those stories.
+if (!empty($topic)) {
+    $sql .= " AND s.tid = '$topic' ";
+} elseif (!$newstories) {
+    $sql .= " AND frontpage = 1 ";
+}
+
+if ($topic != $archivetid) {
+    $sql .= " AND s.tid != '{$archivetid}' ";
+}
+
+$sql .= COM_getPermSQL ('AND', 0, 2, 's');
+
+if (!empty($U['aids'])) {
+    $sql .= " AND s.uid NOT IN (" . str_replace( ' ', ",", $U['aids']  
) . ") ";
+}
+
+if (!empty($U['tids'])) {
+    $sql .= " AND s.tid NOT IN ('" . str_replace( ' ', "','", $U['tids']  
) . "') ";
+}
+
+$sql .= COM_getTopicSQL ('AND', 0, 's') . ' ';
+
+if ($newstories) {
+    $sql .= "AND (date >= (date_sub(NOW(), INTERVAL  
{$_CONF['newstoriesinterval']} SECOND))) ";
+}
+
+$offset = ($page - 1) * $limit;
+$userfields = 'u.uid, u.username, u.fullname';
+if ($_CONF['allow_user_photo'] == 1) {
+    $userfields .= ', u.photo';
+    if ($_CONF['use_gravatar']) {
+        $userfields .= ', u.email';
+    }
+}
+
+$msql = array();
+$msql['mysql']="SELECT STRAIGHT_JOIN s.*, UNIX_TIMESTAMP(s.date) AS  
unixdate, "
+         . 'UNIX_TIMESTAMP(s.expire) as expireunix, '
+         . $userfields . ", t.topic, t.imageurl "
+         . "FROM {$_TABLES['stories']} AS s, {$_TABLES['users']} AS u, "
+         . "{$_TABLES['topics']} AS t WHERE (s.uid = u.uid) AND (s.tid =  
t.tid) AND"
+         . $sql . "ORDER BY featured DESC, date DESC LIMIT $offset,  
$limit";
+
+$msql['mssql']="SELECT STRAIGHT_JOIN s.sid, s.uid, s.draft_flag, s.tid,  
s.date, s.title, cast(s.introtext as text) as introtext, cast(s.bodytext as  
text) as bodytext, s.hits, s.numemails, s.comments, s.trackbacks,  
s.related, s.featured, s.show_topic_icon, s.commentcode, s.trackbackcode,  
s.statuscode, s.expire, s.postmode, s.frontpage, s.in_transit, s.owner_id,  
s.group_id, s.perm_owner, s.perm_group, s.perm_members, s.perm_anon,  
s.advanced_editor_mode, "
+         . " UNIX_TIMESTAMP(s.date) AS unixdate, "
+         . 'UNIX_TIMESTAMP(s.expire) as expireunix, '
+         . $userfields . ", t.topic, t.imageurl "
+         . "FROM {$_TABLES['stories']} AS s, {$_TABLES['users']} AS u, "
+         . "{$_TABLES['topics']} AS t WHERE (s.uid = u.uid) AND (s.tid =  
t.tid) AND"
+         . $sql . "ORDER BY featured DESC, date DESC LIMIT $offset,  
$limit";
+
+$result = DB_query ($msql);
+
+$nrows = DB_numRows ($result);
+
+$data = DB_query ("SELECT COUNT(*) AS count FROM {$_TABLES['stories']} AS  
s WHERE" . $sql);
+$D = DB_fetchArray ($data);
+$num_pages = ceil ($D['count'] / $limit);
+
+if ( $A = DB_fetchArray( $result ) ) {
+
+    $story = new Story();
+    $story->loadFromArray($A);
+    if ( $_CONF['showfirstasfeatured'] == 1 ) {
+        $story->_featured = 1;
+    }
+
+    // display first article
+    $display .= STORY_renderArticle ($story, 'y');
+
+    // get plugin center blocks after featured article
+    if ($story->DisplayElements('featured') == 1) {
+        $display .= PLG_showCenterblock (2, $page, $topic);
+    }
+
+    // get remaining stories
+    while ($A = DB_fetchArray ($result)) {
+        $story = new Story();
+        $story->loadFromArray($A);
+        $display .= STORY_renderArticle ($story, 'y');
+    }
+
+    // get plugin center blocks that follow articles
+    $display .= PLG_showCenterblock (3, $page, $topic); // bottom blocks
+
+    // Print Google-like paging navigation
+    if (!isset ($_CONF['hide_main_page_navigation']) ||
+            ($_CONF['hide_main_page_navigation'] == 0)) {
+        if (empty ($topic)) {
+            $base_url = $_CONF['site_url'] . '/index.php';
+            if ($newstories) {
+                $base_url .= '?display=new';
+            }
+        } else {
+            $base_url = $_CONF['site_url'] . '/index.php?topic=' . $topic;
+        }
+        $display .= COM_printPageNavigation ($base_url, $page, $num_pages);
+    }
+} else { // no stories to display
+    if (!isset ($_CONF['hide_no_news_msg']) ||
+            ($_CONF['hide_no_news_msg'] == 0)) {
+        $display .= COM_startBlock ($LANG05[1], '',
+                    COM_getBlockTemplate ('_msg_block', 'header')) .  
$LANG05[2];
+        if (!empty ($topic)) {
+            $topicname = DB_getItem ($_TABLES['topics'], 'topic',
+                                     "tid = '$topic'");
+            $display .= sprintf ($LANG05[3], $topicname);
+        }
+        $display .= COM_endBlock (COM_getBlockTemplate  
('_msg_block', 'footer'));
+    }
+
+    $display .= PLG_showCenterblock (3, $page, $topic); // bottom blocks
+}
+
+$display .= COM_siteFooter (true); // The true value enables right hand  
blocks.
+
+// Output page
+echo $display;
+
+?>

Added: externals/geeklog-1.5.2sr2/public_html/lib-common.php
==============================================================================
--- (empty file)
+++ externals/geeklog-1.5.2sr2/public_html/lib-common.php	Sun Apr  5  
18:08:35 2009
@@ -0,0 +1,6823 @@
+<?php
+
+/* Reminder: always indent with 4 spaces (no tabs). */
+//  
+---------------------------------------------------------------------------+
+// | Geeklog  
1.5                                                               |
+//  
+---------------------------------------------------------------------------+
+// |  
lib-common.php                                                            |
+//  
|                                                                            
|
+// | Geeklog common  
library.                                                   |
+//  
+---------------------------------------------------------------------------+
+// | Copyright (C) 2000-2008 by the following  
authors:                         |
+//  
|                                                                            
|
+// | Authors: Tony Bibbs        - tony AT tonybibbs DOT  
com                    |
+// |          Mark Limburg      - mlimburg AT users DOT sourceforge DOT  
net    |
+// |          Jason Whittenburg - jwhitten AT securitygeeks DOT  
com            |
+// |          Dirk Haun         - dirk AT haun-online DOT  
de                   |
+// |          Vincent Furia     - vinny01 AT users DOT sourceforge DOT  
net     |
+//  
+---------------------------------------------------------------------------+
+//  
|                                                                            
|
+// | This program is free software; you can redistribute it  
and/or             |
+// | modify it under the terms of the GNU General Public  
License               |
+// | as published by the Free Software Foundation; either version  
2            |
+// | of the License, or (at your option) any later  
version.                    |
+//  
|                                                                            
|
+// | This program is distributed in the hope that it will be  
useful,           |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty  
of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See  
the             |
+// | GNU General Public License for more  
details.                              |
+//  
|                                                                            
|
+// | You should have received a copy of the GNU General Public  
License         |
+// | along with this program; if not, write to the Free Software  
Foundation,   |
+// | Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,  
USA.           |
+//  
|                                                                            
|
+//  
+---------------------------------------------------------------------------+
+//
+// $Id: lib-common.php,v 1.728 2008/09/21 08:37:09 dhaun Exp $
+
+// Prevent PHP from reporting uninitialized variables
+error_reporting( E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR );
+
+/**
+* This is the common library for Geeklog.  Through our code, you will see
+* functions with the COM_ prefix (e.g. COM_siteHeader()).  Any such  
functions
+* can be found in this file.
+*
+* --- You don't need to modify anything in this file! ---
+*
+* WARNING: put any custom hacks in lib-custom.php and not in here.  This  
file is
+* modified frequently by the Geeklog development team.  If you put your  
hacks in
+* lib-custom.php you will find upgrading much easier.
+*
+*/
+
+/**
+* Turn this on to get various debug messages from the code in this library
+* @global Boolean $_COM_VERBOSE
+*/
+
+$_COM_VERBOSE = false;
+
+/**
+  * Here, we shall establish an error handler. This will mean that  
whenever a
+  * php level error is encountered, our own code handles it. This will  
hopefuly
+  * go someway towards preventing nasties like path exposures from ever  
being
+  * possible. That is, unless someone has overridden our error handler  
with one
+  * with a path exposure issue...
+  *
+  * Must make sure that the function hasn't been disabled before calling  
it.
+  *
+  */
+if( function_exists('set_error_handler') )
+{
+    if( PHP_VERSION >= 5 )
+    {
+        /* Tell the error handler to use the default error reporting  
options.
+         * you may like to change this to use it in more/less cases, if so,
+         * just use the syntax used in the call to error_reporting() above.
+         */
+        $defaultErrorHandler = set_error_handler('COM_handleError',  
error_reporting());
+    } else {
+        $defaultErrorHandler = set_error_handler('COM_handleError');
+    }
+}
+
+/*
+* Configuration Include:
+* You do NOT need to modify anything here any more!
+*/
+require_once 'siteconfig.php' ;
+require_once $_CONF['path_system'] . 'classes/config.class.php';
+
+$config =& config::get_instance();
+$config->set_configfile($_CONF['path'] . 'db-config.php');
+$config->load_baseconfig();
+$config->initConfig();
+
+$_CONF = $config->get_config('Core');
+
+// Before we do anything else, check to ensure site is enabled
+
+if (isset($_CONF['site_enabled']) && !$_CONF['site_enabled']) {
+
+    if (empty($_CONF['site_disabled_msg'])) {
+        header("HTTP/1.1 503 Service Unavailable");
+        header("Status: 503 Service Unavailable");
+        echo $_CONF['site_name'] . ' is temporarily down.  Please check  
back soon.';
+    } else {
+        // if the msg starts with http: assume it's a URL we should  
redirect to
+        if (preg_match("/^(https?):/", $_CONF['site_disabled_msg']) === 1)  
{
+            echo COM_refresh($_CONF['site_disabled_msg']);
+        } else {
+            header("HTTP/1.1 503 Service Unavailable");
+            header("Status: 503 Service Unavailable");
+            echo $_CONF['site_disabled_msg'];
+        }
+    }
+
+    exit;
+}
+
+// this file can't be used on its own - redirect to index.php
+if (strpos(strtolower($_SERVER['PHP_SELF']), 'lib-common.php') !== false) {
+    echo COM_refresh($_CONF['site_url'] . '/index.php');
+    exit;
+}
+
+// timezone hack - set the webserver's timezone
+if( !empty( $_CONF['timezone'] ) && !ini_get( 'safe_mode' ) &&
+        function_exists( 'putenv' )) {
+    putenv( 'TZ=' . $_CONF['timezone'] );
+}
+
+
+//  
+---------------------------------------------------------------------------+
+// | Library Includes: You shouldn't have to touch anything below  
here         |
+//  
+---------------------------------------------------------------------------+
+
+/**
+* If needed, add our PEAR path to the list of include paths
+*
+*/
+if( !$_CONF['have_pear'] )
+{
+    $curPHPIncludePath = ini_get( 'include_path' );
+    if( defined( 'PATH_SEPARATOR' ))
+    {
+        $separator = PATH_SEPARATOR;
+    }
+    else
+    {
+        // prior to PHP 4.3.0, we have to guess the correct separator ...
+        $separator = ';';
+        if( strpos( $curPHPIncludePath, $separator ) === false )
+        {
+            $separator = ':';
+        }
+    }
+    if( ini_set( 'include_path', $_CONF['path_pear'] . $separator
+                                 . $curPHPIncludePath ) === false )
+    {
+        COM_errorLog( 'ini_set failed - there may be problems using the  
PEAR classes.', 1);
+    }
+}
+
+
+/**
+* This is necessary to ensure compatibility with PHP 4.1.x
+*
+*/
+if( !function_exists( 'is_a' ))
+{
+    require_once( 'PHP/Compat.php' );
+
+    PHP_Compat::loadFunction( 'is_a' );
+}
+
+
+/**
+* Include page time -- used to time how fast each page was created
+*
+*/
+
+require_once( $_CONF['path_system'] . 'classes/timer.class.php' );
+$_PAGE_TIMER = new timerobject();
+$_PAGE_TIMER->startTimer();
+
+/**
+* Include URL class
+*
+* This provides optional URL rewriting functionality.
+* Please note this code is still experimental and is only currently used  
by the
+* staticpages plugin.
+*/
+
+require_once( $_CONF['path_system'] . 'classes/url.class.php' );
+$_URL = new url( $_CONF['url_rewrite'] );
+
+/**
+* This is our HTML template class.  It is the same one found in PHPLib and  
is
+* licensed under the LGPL.  See that file for details
+*
+*/
+
+require_once( $_CONF['path_system'] . 'classes/template.class.php' );
+
+/**
+* This is the database library.
+*
+* Including this gives you a working connection to the database
+*
+*/
+
+require_once( $_CONF['path_system'] . 'lib-database.php' );
+
+/**
+* This is the security library used for application security
+*
+*/
+
+require_once( $_CONF['path_system'] . 'lib-security.php' );
+
+/**
+* This is the syndication library used to offer (RSS) feeds.
+*
+*/
+
+require_once( $_CONF['path_system'] . 'lib-syndication.php' );
+
+/**
+ *These variables were taken out of the configuration and placed here  
since they
+ *are necessary to change with the themes, not whole sites. They should  
now be
+ *overridden by setting them to a different value than here in the theme's
+ *function.php or in lib-custom.php. Therefore they are NOT TO BE CHANGED  
HERE.
+ */
+$_CONF['left_blocks_in_footer'] = 0;  // use left blocks in header
+$_CONF['right_blocks_in_footer'] = 1;  // use right blocks in footer
+
+/**
+* This is the custom library.
+*
+* It is the sandbox for every Geeklog Admin to play in.
+* We will never modify this file.  This should hold all custom
+* hacks to make upgrading easier.
+*
+*/
+
+require_once( $_CONF['path_system'] . 'lib-custom.php' );
+
+/**
+* Include plugin class.
+* This is a poorly implemented class that was not very well thought out.
+* Still very necessary
+*
+*/
+
+require_once( $_CONF['path_system'] . 'lib-plugins.php' );
+
+/**
+* Session management library
+*
+*/
+
+require_once( $_CONF['path_system'] . 'lib-sessions.php' );
+
+/**
+* Ulf Harnhammar's kses class
+*
+*/
+
+require_once( $_CONF['path_system'] . 'classes/kses.class.php' );
+
+/**
+* Multibyte functions
+*
+*/
+require_once( $_CONF['path_system'] . 'lib-mbyte.php' );
+
+// Set theme
+// Need to modify this code to check if theme was cached in user cookie.   
That
+// way if user logged in and set theme and then logged out we would still  
know
+// which theme to show them.
+
+$usetheme = '';
+if( isset( $_POST['usetheme'] ))
+{
+    $usetheme = COM_sanitizeFilename($_POST['usetheme'], true);
+}
+if( !empty( $usetheme ) && is_dir( $_CONF['path_themes'] . $usetheme ))
+{
+    $_CONF['theme'] = $usetheme;
+    $_CONF['path_layout'] = $_CONF['path_themes'] . $_CONF['theme'] . '/';
+    $_CONF['layout_url'] = $_CONF['site_url'] . '/layout/' .  
$_CONF['theme'];
+}
+else if( $_CONF['allow_user_themes'] == 1 )
+{
+    if( isset( $_COOKIE[$_CONF['cookie_theme']] ) && empty(  
$_USER['theme'] ))
+    {
+        $theme = COM_sanitizeFilename($_COOKIE[$_CONF['cookie_theme']],  
true);
+        if( is_dir( $_CONF['path_themes'] . $theme ))
+        {
+            $_USER['theme'] = $theme;
+        }
+    }
+
+    if( !empty( $_USER['theme'] ))
+    {
+        if( is_dir( $_CONF['path_themes'] . $_USER['theme'] ))
+        {
+            $_CONF['theme'] = $_USER['theme'];
+            $_CONF['path_layout'] = $_CONF['path_themes'] .  
$_CONF['theme'] . '/';
+            $_CONF['layout_url'] = $_CONF['site_url'] . '/layout/' .  
$_CONF['theme'];
+        }
+        else
+        {
+            $_USER['theme'] = $_CONF['theme'];
+        }
+    }
+}
+
+/**
+* Include theme functions file
+*/
+
+// Include theme functions file which may/may not do anything
+
+if (file_exists($_CONF['path_layout'] . 'functions.php')) {
+    require_once $_CONF['path_layout'] . 'functions.php';
+}
+
+// ensure XHTML constant is defined to avoid problems elsewhere
+
+if (!defined('XHTML')) {
+    define('XHTML', '');
+}
+
+// themes can now specify the default image type
+// fall back to 'gif' if they don't
+
+if (empty($_IMAGE_TYPE)) {
+    $_IMAGE_TYPE = 'gif';
+}
+
+// Similarly set language
+
+if( isset( $_COOKIE[$_CONF['cookie_language']] ) && empty(  
$_USER['language'] ))
+{
+    $language = COM_sanitizeFilename($_COOKIE[$_CONF['cookie_language']]);
+    if( is_file( $_CONF['path_language'] . $language . '.php' ) &&
+            ( $_CONF['allow_user_language'] == 1 ))
+    {
+        $_USER['language'] = $language;
+        $_CONF['language'] = $language;
+    }
+}
+else if( !empty( $_USER['language'] ))
+{
+    if( is_file( $_CONF['path_language'] . $_USER['language'] . '.php' ) &&
+            ( $_CONF['allow_user_language'] == 1 ))
+    {
+        $_CONF['language'] = $_USER['language'];
+    }
+}
+else if( !empty( $_CONF['languages'] ) && !empty( $_CONF['language_files']  
))
+{
+    $_CONF['language'] = COM_getLanguage();
+}
+
+// Handle Who's Online block
+if (COM_isAnonUser() && isset($_SERVER['REMOTE_ADDR'])) {
+    // The following code handles anonymous users so they show up properly
+    DB_query( "DELETE FROM {$_TABLES['sessions']} WHERE remote_ip  
= '{$_SERVER['REMOTE_ADDR']}' AND uid = 1" );
+
+    $tries = 0;
+    do
+    {
+        // Build a useless sess_id (needed for insert to work properly)
+        mt_srand(( double )microtime() * 1000000 );
+        $sess_id = mt_rand();
+        $curtime = time();
+
+        // Insert anonymous user session
+        $result = DB_query( "INSERT INTO {$_TABLES['sessions']} (sess_id,  
start_time, remote_ip, uid) VALUES ($sess_id,  
$curtime, '{$_SERVER['REMOTE_ADDR']}', 1)", 1 );
+        $tries++;
+    }
+    while(( $result === false) && ( $tries < 5 ));
+}
+
+// Clear out any expired sessions
+DB_query( "DELETE FROM {$_TABLES['sessions']} WHERE start_time < " . (  
time() - $_CONF['whosonline_threshold'] ));
+
+/**
+*
+* Language include
+*
+*/
+
+require_once $_CONF['path_language'] . $_CONF['language'] . '.php';
+
+if (empty($LANG_DIRECTION)) {
+    // default to left-to-right
+    $LANG_DIRECTION = 'ltr';
+}
+
+COM_switchLocaleSettings();
+
+if( setlocale( LC_ALL, $_CONF['locale'] ) === false )
+{
+    setlocale( LC_TIME, $_CONF['locale'] );
+}
+
+/**
+* Global array of groups current user belongs to
+*
+* @global array $_GROUPS
+*
+*/
+
+if( !COM_isAnonUser() )
+{
+    $_GROUPS = SEC_getUserGroups( $_USER['uid'] );
+}
+else
+{
+    $_GROUPS = SEC_getUserGroups( 1 );
+}
+
+/**
+* Global array of current user permissions [read,edit]
+*
+* @global array $_RIGHTS
+*
+*/
+
+$_RIGHTS = explode( ',', SEC_getUserPermissions() );
+
+if( isset( $_GET['topic'] ))
+{
+    $topic = COM_applyFilter( $_GET['topic'] );
+}
+else if( isset( $_POST['topic'] ))
+{
+    $topic = COM_applyFilter( $_POST['topic'] );
+}
+else
+{
+    $topic = '';
+}
+
+
+//  
+---------------------------------------------------------------------------+
+// | HTML  
WIDGETS                                                              |
+//  
+---------------------------------------------------------------------------+
+
+/**
+* Return the file to use for a block template.
+*
+* This returns the template needed to build the HTML for a block.  This  
function
+* allows designers to give a block it's own custom look and feel.  If no
+* templates for the block are specified, the default blockheader.html and
+* blockfooter.html will be used.
+*
+* @param        string      $blockname      corresponds to name field in  
block table
+* @param        string      $which          can be either 'header'  
or 'footer' for corresponding template
+* @param        string      $position       can be 'left', 'right' or  
blank. If set, will be used to find a side specific override template.
+* @see function COM_startBlock
+* @see function COM_endBlock
+* @see function COM_showBlocks
+* @see function COM_showBlock
+* @return   string  template name
+*/
+function COM_getBlockTemplate( $blockname, $which, $position='' )
+{
+    global $_BLOCK_TEMPLATE, $_COM_VERBOSE, $_CONF;
+
+    if( $_COM_VERBOSE )
+    {
+        COM_errorLog( "_BLOCK_TEMPLATE[$blockname] = " .  
$_BLOCK_TEMPLATE[$blockname], 1 );
+    }
+
+    if( !empty( $_BLOCK_TEMPLATE[$blockname] ))
+    {
+        $templates = explode( ',', $_BLOCK_TEMPLATE[$blockname] );
+        if( $which == 'header' )
+        {
+            if( !empty( $templates[0] ))
+            {
+                $template = $templates[0];
+            }
+            else
+            {
+                $template = 'blockheader.thtml';
+            }
+        }
+        else
+        {
+            if( !empty( $templates[1] ))
+            {
+                $template = $templates[1];
+            }
+            else
+            {
+                $template = 'blockfooter.thtml';
+            }
+        }
+    }
+    else
+    {
+        if( $which == 'header' )
+        {
+            $template = 'blockheader.thtml';
+        }
+        else
+        {
+            $template = 'blockfooter.thtml';
+        }
+    }
+
+    // If we have a position specific request, and the template is not  
already
+    // position specific then look to see if there is a position specific
+    // override.
+    $templateLC = strtolower($template);
+    if( !empty($position) && ( strpos($templateLC, $position) === false ) )
+    {
+        // Trim .thtml from the end.
+        $positionSpecific = substr($template, 0, strlen($template) - 6);
+        $positionSpecific .= '-' . $position . '.thtml';
+        if( file_exists( $_CONF['path_layout'] . $positionSpecific ) )
+        {
+            $template = $positionSpecific;
+        }
+    }
+
+    if( $_COM_VERBOSE )
+    {
+        COM_errorLog( "Block template for the $which of $blockname is:  
$template", 1 );
+    }
+
+    return $template;
+}
+
+/**
+* Gets all installed themes
+*
+* Returns a list of all the directory names in $_CONF['path_themes'], i.e.
+* a list of all the theme names.
+*
+* @param    bool    $all    if true, return all themes even if users  
aren't allowed to change their default themes
+* @return   array           All installed themes
+*
+*/
+function COM_getThemes( $all = false )
+{
+    global $_CONF;
+
+    $index = 1;
+
+    $themes = array();
+
+    $fd = opendir( $_CONF['path_themes'] );
+
+    // If users aren't allowed to change their theme then only return the  
default theme
+
+    if(( $_CONF['allow_user_themes'] == 0 ) && !$all )
+    {
+        $themes[$index] = $_CONF['theme'];
+    }
+    else
+    {
+        while(( $dir = @readdir( $fd )) == TRUE )
+        {
+            if( is_dir( $_CONF['path_themes'] . $dir) && $dir <> '.' &&  
$dir <> '..' && $dir <> 'CVS' && substr( $dir, 0 , 1 ) <> '.' )
+            {
+                clearstatcache();
+                $themes[$index] = $dir;
+                $index++;
+            }
+        }
+    }
+
+    return $themes;
+}
+
+/**
+* Create the menu, i.e. replace {menu_elements} in the site header with the
+* actual menu entries.
+*
+* @param    Template    $header     reference to the header template
+* @param    array       $plugin_menu    array of plugin menu entries, if  
any
+*
+*/
+function COM_renderMenu( &$header, $plugin_menu )
+{
+    global $_CONF, $_USER, $LANG01, $topic;
+
+    if( empty( $_CONF['menu_elements'] ))
+    {
+        $_CONF['menu_elements'] = array( // default set of links
+                'contribute', 'search', 'stats', 'directory', 'plugins' );
+    }
+
+    $anon = COM_isAnonUser();
+    $menuCounter = 0;
+    $allowedCounter = 0;
+    $counter = 0;
+
+    $num_plugins = sizeof( $plugin_menu );
+    if( ( $num_plugins == 0 ) && in_array( 'plugins',  
$_CONF['menu_elements'] ))
+    {
+        $key = array_search( 'plugins', $_CONF['menu_elements'] );
+        unset( $_CONF['menu_elements'][$key] );
+    }
+
+    if( in_array( 'custom', $_CONF['menu_elements'] ))
+    {
+        $custom_entries = array();
+        if( function_exists( 'CUSTOM_menuEntries' ))
+        {
+            $custom_entries = CUSTOM_menuEntries();
+        }
+        if( sizeof( $custom_entries ) == 0 )
+        {
+            $key = array_search( 'custom', $_CONF['menu_elements'] );
+            unset( $_CONF['menu_elements'][$key] );
+        }
+    }
+
+    $num_elements = sizeof( $_CONF['menu_elements'] );
+
+    foreach( $_CONF['menu_elements'] as $item )
+    {
+        $counter++;
+        $allowed = true;
+        $last_entry = ( $counter == $num_elements ) ? true : false;
+
+        switch( $item )
+        {
+            case 'contribute':
+                if( empty( $topic ))
+                {
+                    $url = $_CONF['site_url'] . '/submit.php?type=story';
+                    $header->set_var( 'current_topic', '' );
+                }
+                else
+                {
+                    $url = $_CONF['site_url']
+                         . '/submit.php?type=story&amp;topic=' . $topic;
+                    $header->set_var( 'current_topic', '&amp;topic=' .  
$topic );
+                }
+                $label = $LANG01[71];
+                if( $anon && ( $_CONF['loginrequired'] ||
+                        $_CONF['submitloginrequired'] ))
+                {
+                    $allowed = false;
+                }
+                break;
+
+            case 'custom':
+                $custom_count = 0;
+                $custom_size = sizeof( $custom_entries );
+                foreach( $custom_entries as $entry )
+                {
+                    $custom_count++;
+
+                    if( empty( $entry['url'] ) || empty( $entry['label'] ))
+                    {
+                        continue;
+                    }
+
+                    $header->set_var( 'menuitem_url',  $entry['url'] );
+                    $header->set_var( 'menuitem_text', $entry['label'] );
+
+                    if( $last_entry && ( $custom_count == $custom_size ))
+                    {
+                        $header->parse( 'menu_elements', 'menuitem_last',
+                                        true );
+                    }
+                    else
+                    {
+                        $header->parse( 'menu_elements', 'menuitem', true  
);
+                    }
+                    $menuCounter++;
+                }
+                $url = '';
+                $label = '';
+                break;
+
+            case 'directory':
+                $url = $_CONF['site_url'] . '/directory.php';
+                if( !empty( $topic ))
+                {
+                    $url = COM_buildUrl( $url . '?topic='
+                                         . urlencode( $topic ));
+                }
+                $label = $LANG01[117];
+                if( $anon && ( $_CONF['loginrequired'] ||
+                        $_CONF['directoryloginrequired'] ))
+                {
+                    $allowed = false;
+                }
+                break;
+
+            case 'home':
+                $url = $_CONF['site_url'] . '/';
+                $label = $LANG01[90];
+                break;
+
+            case 'plugins':
+                for( $i = 1; $i <= $num_plugins; $i++ )
+                {
+                    $header->set_var( 'menuitem_url', current(  
$plugin_menu ));
+                    $header->set_var( 'menuitem_text', key( $plugin_menu  
));
+
+                    if( $last_entry && ( $i == $num_plugins ))
+                    {
+                        $header->parse( 'menu_elements', 'menuitem_last',
+                                        true );
+                    }
+                    else
+                    {
+                        $header->parse( 'menu_elements', 'menuitem', true  
);
+                    }
+                    $menuCounter++;
+
+                    next( $plugin_menu );
+                }
+                $url = '';
+                $label = '';
+                break;
+
+            case 'prefs':
+                $url = $_CONF['site_url'] . '/usersettings.php';
+                $label = $LANG01[48];
+                break;
+
+            case 'search':
+                $url = $_CONF['site_url'] . '/search.php';
+                $label = $LANG01[75];
+                if( $anon && ( $_CONF['loginrequired'] ||
+                        $_CONF['searchloginrequired'] ))
+                {
+                    $allowed = false;
+                }
+                break;
+
+            case 'stats':
+                $url = $_CONF['site_url'] . '/stats.php';
+                $label = $LANG01[76];
+                if( $anon &&
+                    ( $_CONF['loginrequired'] ||  
$_CONF['statsloginrequired'] ))
+                {
+                    $allowed = false;
+                }
+                break;
+
+            default: // unknown entry
+                $url = '';
+                $label = '';
+                break;
+        }
+
+        if( !empty( $url ) && !empty( $label ))
+        {
+            $header->set_var( 'menuitem_url',  $url );
+            $header->set_var( 'menuitem_text', $label );
+            if( $last_entry )
+            {
+                $header->parse( 'menu_elements', 'menuitem_last', true );
+            }
+            else
+            {
+                $header->parse( 'menu_elements', 'menuitem', true );
+            }
+            $menuCounter++;
+
+            if( $allowed )
+            {
+                if( $last_entry )
+                {
+                     
$header->parse( 'allowed_menu_elements', 'menuitem_last',
+                                    true );
+                }
+                else
+                {
+                    $header->parse( 'allowed_menu_elements', 'menuitem',  
true );
+                }
+                $allowedCounter++;
+            }
+        }
+    }
+
+    if( $menuCounter == 0 )
+    {
+        $header->parse( 'menu_elements', 'menuitem_none', true );
+    }
+    if( $allowedCounter == 0 )
+    {
+        $header->parse( 'allowed_menu_elements', 'menuitem_none', true );
+    }
+}
+
+/**
+* Returns the site header
+*
+* This loads the proper templates, does variable substitution and returns  
the
+* HTML for the site header with or without blocks depending on the value  
of $what
+*
+* Programming Note:
+*
+* The two functions COM_siteHeader and COM_siteFooter provide the  
framework for
+* page display in Geeklog.  COM_siteHeader controls the display of the  
Header
+* and left blocks and COM_siteFooter controls the dsiplay of the right  
blocks
+* and the footer.  You use them like a sandwich.  Thus the following code  
will
+* display a Geeklog page with both right and left blocks displayed.
+*
+*  
-------------------------------------------------------------------------------------
+* <?php
+* require_once('lib-common.php');
+* $display .= COM_siteHeader(); //Change to COM_siteHeader('none') to not  
display left blocks
+* $display .= "Here is your html for display";
+* $display .= COM_siteFooter(true);  // Change to COM_siteFooter() to not  
display right blocks
+* echo $display;
+* ? >
+*  
---------------------------------------------------------------------------------------
+*
+* Note that the default for the header is to display the left blocks and  
the
+* default of the footer is to not display the right blocks.
+*
+* This sandwich produces code like this (greatly simplified)
+*
+* // COM_siteHeader
+* <table><tr><td colspan="3">Header</td></tr>
+* <tr><td>Left Blocks</td><td>
+*
+* // Your HTML goes here
+* Here is your html for display
+*
+* // COM_siteFooter
+* </td><td>Right Blocks</td></tr>
+* <tr><td colspan="3">Footer</td></table>
+*
+* @param    string  $what       If 'none' then no left blocks are  
returned, if 'menu' (default) then right blocks are returned
+* @param    string  $pagetitle  optional content for the page's <title>
+* @param    string  $headercode optional code to go into the page's <head>
+* @return   string              Formatted HTML containing the site header
+* @see function COM_siteFooter
+*
+*/
+
+function COM_siteHeader( $what = 'menu', $pagetitle = '', $headercode = ''  
)
+{
+    global $_CONF, $_TABLES, $_USER, $LANG01, $LANG_BUTTONS,  
$LANG_DIRECTION,
+           $_IMAGE_TYPE, $topic, $_COM_VERBOSE;
+
+    // If the theme implemented this for us then call their version  
instead.
+
+    $function = $_CONF['theme'] . '_siteHeader';
+
+    if( function_exists( $function ))
+    {
+        return $function( $what, $pagetitle, $headercode );
+    }
+
+    // send out the charset header
+    header( 'Content-Type: text/html; charset=' . COM_getCharset());
+
+    // If we reach here then either we have the default theme OR
+    // the current theme only needs the default variable substitutions
+
+    $header = new Template( $_CONF['path_layout'] );
+    $header->set_file( array(
+        'header'        => 'header.thtml',
+        'menuitem'      => 'menuitem.thtml',
+        'menuitem_last' => 'menuitem_last.thtml',
+        'menuitem_none' => 'menuitem_none.thtml',
+        'leftblocks'    => 'leftblocks.thtml',
+        'rightblocks'   => 'rightblocks.thtml'
+        ));
+    $header->set_var( 'xhtml', XHTML );
+
+    // get topic if not on home page
+    if( !isset( $_GET['topic'] ))
+    {
+        if( isset( $_GET['story'] ))
+        {
+            $sid = COM_applyFilter( $_GET['story'] );
+        }
+        elseif( isset( $_GET['sid'] ))
+        {
+            $sid = COM_applyFilter( $_GET['sid'] );
+        }
+        elseif( isset( $_POST['story'] ))
+        {
+            $sid = COM_applyFilter( $_POST['story'] );
+        }
+        if( empty( $sid ) && $_CONF['url_rewrite'] &&
+                ( strpos( $_SERVER['PHP_SELF'], 'article.php' ) !== false  
))
+        {
+            COM_setArgNames( array( 'story', 'mode' ));
+            $sid = COM_applyFilter( COM_getArgument( 'story' ));
+        }
+        if( !empty( $sid ))
+        {
+            $topic = DB_getItem( $_TABLES['stories'], 'tid', "sid='$sid'"  
);
+        }
+    }
+    else
+    {
+        $topic = COM_applyFilter( $_GET['topic'] );
+    }
+
+    $feed_url = array();
+    if( $_CONF['backend'] == 1 ) // add feed-link to header if applicable
+    {
+        $baseurl = SYND_getFeedUrl();
+
+        $sql = 'SELECT format, filename, title, language FROM '
+             . $_TABLES['syndication'] . " WHERE (header_tid = 'all')";
+        if( !empty( $topic ))
+        {
+            $sql .= " OR (header_tid = '" . addslashes( $topic ) . "')";
+        }
+        $result = DB_query( $sql );
+        $numRows = DB_numRows( $result );
+        for( $i = 0; $i < $numRows; $i++ )
+        {
+            $A = DB_fetchArray( $result );
+            if ( !empty( $A['filename'] ))
+            {
+                $format = explode( '-', $A['format'] );
+                $format_type = strtolower( $format[0] );
+                $format_name = ucwords( $format[0] );
+
+                $feed_url[] = '<link rel="alternate" type="application/'
+                          . $format_type . '+xml" hreflang="' .  
$A['language']
+                          . '" href="' . $baseurl . $A['filename'] . '"  
title="'
+                          . $format_name . ' Feed: ' . $A['title'] . '"' .  
XHTML . '>';
+            }
+        }
+    }
+    $header->set_var( 'feed_url', implode( LB, $feed_url ));
+
+    $relLinks = array();
+    if( !COM_onFrontpage() )
+    {
+        $relLinks['home'] = '<link rel="home" href="' . $_CONF['site_url']
+                          . '/" title="' . $LANG01[90] . '"' . XHTML . '>';
+    }
+    $loggedInUser = !COM_isAnonUser();
+    if( $loggedInUser || (( $_CONF['loginrequired'] == 0 ) &&
+                ( $_CONF['searchloginrequired'] == 0 )))
+    {
+        if(( substr( $_SERVER['PHP_SELF'], -strlen( '/search.php' ))
+                != '/search.php' ) || isset( $_GET['mode'] ))
+        {
+            $relLinks['search'] = '<link rel="search" href="'
+                                . $_CONF['site_url'] . '/search.php"  
title="'
+                                . $LANG01[75] . '"' . XHTML . '>';
+        }
+    }
+    if( $loggedInUser || (( $_CONF['loginrequired'] == 0 ) &&
+                ( $_CONF['directoryloginrequired'] == 0 )))
+    {
+        if( strpos( $_SERVER['PHP_SELF'], '/article.php' ) !== false ) {
+            $relLinks['contents'] = '<link rel="contents" href="'
+                        . $_CONF['site_url'] . '/directory.php" title="'
+                        . $LANG01[117] . '"' . XHTML . '>';
+        }
+    }
+    if (!$_CONF['disable_webservices']) {
+        $relLinks['service'] = '<link rel="service" '
+                    . 'type="application/atomsvc+xml" ' . 'href="'
+                    .  
$_CONF['site_url'] . '/webservices/atom/?introspection" '
+                    . 'title="' . $LANG01[130] . '"' . XHTML . '>';
+    }
+    // TBD: add a plugin API and a lib-custom.php function
+    $header->set_var( 'rel_links', implode( LB, $relLinks ));
+
+    if( empty( $pagetitle ) && isset( $_CONF['pagetitle'] ))
+    {
+        $pagetitle = $_CONF['pagetitle'];
+    }
+    if( empty( $pagetitle ))
+    {
+        if( empty( $topic ))
+        {
+            $pagetitle = $_CONF['site_slogan'];
+        }
+        else
+        {
+            $pagetitle = stripslashes( DB_getItem(  
$_TABLES['topics'], 'topic',
+                                                   "tid = '$topic'" ));
+        }
+    }
+    if( !empty( $pagetitle ))
+    {
+        $header->set_var( 'page_site_splitter', ' - ');
+    }
+    else
+    {
+        $header->set_var( 'page_site_splitter', '');
+    }
+    $header->set_var( 'page_title', $pagetitle );
+    $header->set_var( 'site_name', $_CONF['site_name']);
+
+    if (COM_onFrontpage()) {
+        $title_and_name = $_CONF['site_name'];
+        if (!empty($pagetitle)) {
+            $title_and_name .= ' - ' . $pagetitle;
+        }
+    } else {
+        $title_and_name = '';
+        if (!empty($pagetitle)) {
+            $title_and_name = $pagetitle . ' - ';
+        }
+        $title_and_name .= $_CONF['site_name'];
+    }
+    $header->set_var('page_title_and_site_name', $title_and_name);
+
+    COM_setLangIdAndAttribute($header);
+
+    $header->set_var( 'background_image', $_CONF['layout_url']
+                                          . '/images/bg.' . $_IMAGE_TYPE );
+    $header->set_var( 'site_url', $_CONF['site_url'] );
+    $header->set_var( 'site_admin_url', $_CONF['site_admin_url'] );
+    $header->set_var( 'layout_url', $_CONF['layout_url'] );
+    $header->set_var( 'site_mail', "mailto:{$_CONF['site_mail']}" );
+    $header->set_var( 'site_name', $_CONF['site_name'] );
+    $header->set_var( 'site_slogan', $_CONF['site_slogan'] );
+    $rdf = substr_replace( $_CONF['rdf_file'], $_CONF['site_url'], 0,
+                           strlen( $_CONF['path_html'] ) - 1 );
+    $header->set_var( 'rdf_file', $rdf );
+    $header->set_var( 'rss_url', $rdf );
+
+    $msg = rtrim($LANG01[67]) . ' ' . $_CONF['site_name'];
+
+    if( !empty( $_USER['username'] ))
+    {
+        $msg .= ', ' . COM_getDisplayName( $_USER['uid'],  
$_USER['username'],
+                                           $_USER['fullname'] );
+    }
+
+    $curtime =  COM_getUserDateTimeFormat();
+
+    $header->set_var( 'welcome_msg', $msg );
+    $header->set_var( 'datetime', $curtime[0] );
+    $header->set_var( 'site_logo', $_CONF['layout_url']
+                                   . '/images/logo.' . $_IMAGE_TYPE );
+    $header->set_var( 'css_url', $_CONF['layout_url'] . '/style.css' );
+    $header->set_var( 'theme', $_CONF['theme'] );
+
+    $header->set_var('charset', COM_getCharset());
+    $header->set_var('direction', $LANG_DIRECTION);
+
+    // Now add variables for buttons like e.g. those used by the Yahoo  
theme
+    $header->set_var( 'button_home', $LANG_BUTTONS[1] );
+    $header->set_var( 'button_contact', $LANG_BUTTONS[2] );
+    $header->set_var( 'button_contribute', $LANG_BUTTONS[3] );
+    $header->set_var( 'button_sitestats', $LANG_BUTTONS[7] );
+    $header->set_var( 'button_personalize', $LANG_BUTTONS[8] );
+    $header->set_var( 'button_search', $LANG_BUTTONS[9] );
+    $header->set_var( 'button_advsearch', $LANG_BUTTONS[10] );
+    $header->set_var( 'button_directory', $LANG_BUTTONS[11] );
+
+    // Get plugin menu options
+    $plugin_menu = PLG_getMenuItems();
+
+    if( $_COM_VERBOSE )
+    {
+        COM_errorLog( 'num plugin menu items in header = ' . count(  
$plugin_menu ), 1 );
+    }
+
+    // Now add nested template for menu items
+    COM_renderMenu( $header, $plugin_menu );
+
+    if( count( $plugin_menu ) == 0 )
+    {
+        $header->parse( 'plg_menu_elements', 'menuitem_none', true );
+    }
+    else
+    {
+        $count_plugin_menu = count( $plugin_menu );
+        for( $i = 1; $i <= $count_plugin_menu; $i++ )
+        {
+            $header->set_var( 'menuitem_url', current( $plugin_menu ));
+            $header->set_var( 'menuitem_text', key( $plugin_menu ));
+
+            if( $i == $count_plugin_menu )
+            {
+                $header->parse( 'plg_menu_elements', 'menuitem_last', true  
);
+            }
+            else
+            {
+                $header->parse( 'plg_menu_elements', 'menuitem', true );
+            }
+
+            next( $plugin_menu );
+        }
+    }
+
+    // Call to plugins to set template variables in the header
+    PLG_templateSetVars( 'header', $header );
+
+    if( $_CONF['left_blocks_in_footer'] == 1 )
+    {
+        $header->set_var( 'left_blocks', '' );
+        $header->set_var( 'geeklog_blocks', '' );
+    }
+    else
+    {
+        $lblocks = '';
+
+        /* Check if an array has been passed that includes the name of a  
plugin
+         * function or custom function
+         * This can be used to take control over what blocks are then  
displayed
+         */
+        if( is_array( $what ))
+        {
+            $function = $what[0];
+            if( function_exists( $function ))
+            {
+                $lblocks = $function( $what[1], 'left' );
+            }
+            else
+            {
+                $lblocks = COM_showBlocks( 'left', $topic );
+            }
+        }
+        else if( $what <> 'none' )
+        {
+            // Now show any blocks -- need to get the topic if not on home  
page
+            $lblocks = COM_showBlocks( 'left', $topic );
+        }
+
+        if( empty( $lblocks ))
+        {
+            $header->set_var( 'left_blocks', '' );
+            $header->set_var( 'geeklog_blocks', '' );
+        }
+        else
+        {
+            $header->set_var( 'geeklog_blocks', $lblocks );
+            $header->parse( 'left_blocks', 'leftblocks', true );
+            $header->set_var( 'geeklog_blocks', '');
+        }
+    }
+
+    if( $_CONF['right_blocks_in_footer'] == 1 )
+    {
+        $header->set_var( 'right_blocks', '' );
+        $header->set_var( 'geeklog_blocks', '' );
+    }
+    else
+    {
+        $rblocks = '';
+
+        /* Check if an array has been passed that includes the name of a  
plugin
+         * function or custom function
+         * This can be used to take control over what blocks are then  
displayed
+         */
+        if( is_array( $what ))
+        {
+            $function = $what[0];
+            if( function_exists( $function ))
+            {
+                $rblocks = $function( $what[1], 'right' );
+            }
+            else
+            {
+                $rblocks = COM_showBlocks( 'right', $topic );
+            }
+        }
+        else if( $what <> 'none' )
+        {
+            // Now show any blocks -- need to get the topic if not on home  
page
+            $rblocks = COM_showBlocks( 'right', $topic );
+        }
+
+        if( empty( $rblocks ))
+        {
+            $header->set_var( 'right_blocks', '' );
+            $header->set_var( 'geeklog_blocks', '' );
+        }
+        else
+        {
+            $header->set_var( 'geeklog_blocks', $rblocks, true );
+            $header->parse( 'right_blocks', 'rightblocks', true );
+        }
+    }
+
+    if( isset( $_CONF['advanced_editor'] ) && ( $_CONF['advanced_editor']  
== 1 )
+            && file_exists( $_CONF['path_layout']
+                            . 'advanced_editor_header.thtml' ))
+    {
+        $header->set_file( 'editor'  , 'advanced_editor_header.thtml');
+        $header->parse( 'advanced_editor', 'editor' );
+
+    }
+    else
+    {
+         $header->set_var( 'advanced_editor', '' );
+    }
+
+    // Call any plugin that may want to include extra Meta tags
+    // or Javascript functions
+    $header->set_var( 'plg_headercode', $headercode . PLG_getHeaderCode()  
);
+
+    // The following lines allow users to embed PHP in their templates.   
This
+    // is almost a contradition to the reasons for using templates but  
this may
+    // prove useful at times ...
+    // Don't use PHP in templates if you can live without it!
+
+    $tmp = $header->parse( 'index_header', 'header' );
+
+    $xml_declaration = '';
+    if ( get_cfg_var('short_open_tag') == '1' )
+    {
+        if ( preg_match( '/(<\?xml[^>]*>)(.*)/s', $tmp, $match ) )
+        {
+            $xml_declaration = $match[1] . LB;
+            $tmp = $match[2];
+        }
+    }
+
+    ob_start();
+    eval( '?>' . $tmp );
+    $retval = $xml_declaration . ob_get_contents();
+    ob_end_clean();
+
+    return $retval;
+}
+
+
+/**
+* Returns the site footer
+*
+* This loads the proper templates, does variable substitution and returns  
the
+* HTML for the site footer.
+*
+* @param   boolean     $rightblock     Whether or not to show blocks on  
right hand side default is no
+* @param   array       $custom         An array defining custom function  
to be used to format Rightblocks
+* @see function COM_siteHeader
+* @return   string  Formated HTML containing site footer and optionally  
right blocks
+*
+*/
+function COM_siteFooter( $rightblock = -1, $custom = '' )
+{
+    global $_CONF, $_TABLES, $LANG01, $_PAGE_TIMER, $topic, $LANG_BUTTONS;
+
+    // If the theme implemented this for us then call their version  
instead.
+
+    $function = $_CONF['theme'] . '_siteFooter';
+
+    if( function_exists( $function ))
+    {
+        return $function( $rightblock, $custom );
+    }
+
+    COM_hit();
+
+    // Set template directory
+    $footer = new Template( $_CONF['path_layout'] );
+
+    // Set template file
+    $footer->set_file( array(
+            'footer'      => 'footer.thtml',
+            'rightblocks' => 'rightblocks.thtml',
+            'leftblocks'  => 'leftblocks.thtml'
+            ));
+
+    // Do variable assignments
+    $footer->set_var( 'xhtml', XHTML );
+    $footer->set_var( 'site_url', $_CONF['site_url']);
+    $footer->set_var( 'site_admin_url', $_CONF['site_admin_url']);
+    $footer->set_var( 'layout_url',$_CONF['layout_url']);
+    $footer->set_var( 'site_mail', "mailto:{$_CONF['site_mail']}" );
+    $footer->set_var( 'site_name', $_CONF['site_name'] );
+    $footer->set_var( 'site_slogan', $_CONF['site_slogan'] );
+    $rdf = substr_replace( $_CONF['rdf_file'], $_CONF['site_url'], 0,
+                           strlen( $_CONF['path_html'] ) - 1 );
+    $footer->set_var( 'rdf_file', $rdf );
+    $footer->set_var( 'rss_url', $rdf );
+
+    $year = date( 'Y' );
+    $copyrightyear = $year;
+    if( !empty( $_CONF['copyrightyear'] ))
+    {
+        $copyrightyear = $_CONF['copyrightyear'];
+    }
+    $footer->set_var( 'copyright_notice', '&nbsp;' . $LANG01[93] . '  
&copy; '
+            . $copyrightyear . ' ' . $_CONF['site_name'] . '<br' .  
XHTML . '>&nbsp;'
+            . $LANG01[94] );
+    $footer->set_var( 'copyright_msg', $LANG01[93] . ' &copy; '
+            . $copyrightyear . ' ' . $_CONF['site_name'] );
+    $footer->set_var( 'current_year', $year );
+    $footer->set_var( 'lang_copyright', $LANG01[93] );
+    $footer->set_var( 'trademark_msg', $LANG01[94] );
+    $footer->set_var( 'powered_by', $LANG01[95] );
+    $footer->set_var( 'geeklog_url', 'http://www.geeklog.net/' );
+    $footer->set_var( 'geeklog_version', VERSION );
+    // Now add variables for buttons like e.g. those used by the Yahoo  
theme
+    $footer->set_var( 'button_home', $LANG_BUTTONS[1] );
+    $footer->set_var( 'button_contact', $LANG_BUTTONS[2] );
+    $footer->set_var( 'button_contribute', $LANG_BUTTONS[3] );
+    $footer->set_var( 'button_sitestats', $LANG_BUTTONS[7] );
+    $footer->set_var( 'button_personalize', $LANG_BUTTONS[8] );
+    $footer->set_var( 'button_search', $LANG_BUTTONS[9] );
+    $footer->set_var( 'button_advsearch', $LANG_BUTTONS[10] );
+    $footer->set_var( 'button_directory', $LANG_BUTTONS[11] );
+
+    /* Right blocks. Argh. Don't talk to me about right blocks...
+     * Right blocks will be displayed if Right_blocks_in_footer is set [1],
+     * AND (this function has been asked to show them (first param) OR the
+     * show_right_blocks conf variable has been set to override what the  
code
+     * wants to do.
+     *
+     * If $custom sets an array (containing functionname and first  
argument)
+     * then this is used instead of the default (COM_showBlocks) to render
+     * the right blocks (and left).
+     *
+     * [1] - if it isn't, they'll be in the header already.
+     *
+     */
+    $displayRightBlocks = true;
+    if ($_CONF['right_blocks_in_footer'] == 1)
+    {
+        if( ($rightblock < 0) || !$rightblock )
+        {
+            if( isset( $_CONF['show_right_blocks'] ) )
+            {
+                $displayRightBlocks = $_CONF['show_right_blocks'];
+            }
+            else
+            {
+                $displayRightBlocks = false;
+            }
+        } else {
+            $displayRightBlocks = true;
+        }
+    } else {
+        $displayRightBlocks = false;
+    }
+
+    if ($displayRightBlocks)
+    {
+        /* Check if an array has been passed that includes the name of a  
plugin
+         * function or custom function.
+         * This can be used to take control over what blocks are then  
displayed
+         */
+        if( is_array( $custom ))
+        {
+            $function = $custom['0'];
+            if( function_exists( $function ))
+            {
+                $rblocks = $function( $custom['1'], 'right' );
+            } else {
+                $rblocks = COM_showBlocks( 'right', $topic );
+            }
+        } else {
+            $rblocks = COM_showBlocks( 'right', $topic );
+        }
+
+        if( empty( $rblocks ))
+        {
+            $footer->set_var( 'geeklog_blocks', '');
+            $footer->set_var( 'right_blocks', '' );
+        } else {
+            $footer->set_var( 'geeklog_blocks', $rblocks);
+            $footer->parse( 'right_blocks', 'rightblocks', true );
+            $footer->set_var( 'geeklog_blocks', '');
+        }
+    } else {
+        $footer->set_var( 'geeklog_blocks', '');
+        $footer->set_var( 'right_blocks', '' );
+    }
+
+    if( $_CONF['left_blocks_in_footer'] == 1 )
+    {
+        $lblocks = '';
+
+        /* Check if an array has been passed that includes the name of a  
plugin
+         * function or custom function
+         * This can be used to take control over what blocks are then  
displayed
+         */
+        if( is_array( $custom ))
+        {
+            $function = $custom[0];
+            if( function_exists( $function ))
+            {
+                $lblocks = $function( $custom[1], 'left' );
+            }
+        }
+        else
+        {
+            $lblocks = COM_showBlocks( 'left', $topic );
+        }
+
+        if( empty( $lblocks ))
+        {
+            $footer->set_var( 'left_blocks', '' );
+            $footer->set_var( 'geeklog_blocks', '');
+        }
+        else
+        {
+            $footer->set_var( 'geeklog_blocks', $lblocks);
+            $footer->parse( 'left_blocks', 'leftblocks', true );
+            $footer->set_var( 'geeklog_blocks', '');
+        }
+    }
+
+    // Global centerspan variable set in index.php
+    if( isset( $GLOBALS['centerspan'] ))
+    {
+        $footer->set_var( 'centerblockfooter-span', '</td></tr></table>' );
+    }
+
+    $exectime = $_PAGE_TIMER->stopTimer();
+    $exectext = $LANG01[91] . ' ' . $exectime . ' ' . $LANG01[92];
+
+    $footer->set_var( 'execution_time', $exectime );
+    $footer->set_var( 'execution_textandtime', $exectext );
+
+    // Call to plugins to set template variables in the footer
+    PLG_templateSetVars( 'footer', $footer );
+
+    // Actually parse the template and make variable substitutions
+    $footer->parse( 'index_footer', 'footer' );
+
+    // Return resulting HTML
+    return $footer->finish( $footer->get_var( 'index_footer' ));
+}
+
+/**
+* Prints out standard block header
+*
+* Prints out standard block header but pulling header HTML formatting from
+* the database.
+*
+* Programming Note:  The two functions COM_startBlock and COM_endBlock are  
used
+* to sandwich your block content.  These functions are not used only for  
blocks
+* but anything that uses that format, e.g. Stats page.  They are used like
+* COM_siteHeader and COM_siteFooter but for internal page elements.
+*
+*
+* @param        string      $title      Value to set block title to
+* @param        string      $helpfile   Help file, if one exists
+* @param        string      $template   HTML template file to use to  
format the block
+* @see COM_endBlock
+* @see COM_siteHeader  For similiar construct
+* @return   string  Formatted HTML containing block header
+*
+*/
+
+function COM_startBlock( $title='', $helpfile='',  
$template='blockheader.thtml' )
+{
+    global $_CONF, $LANG01, $_IMAGE_TYPE;
+
+    $block = new Template( $_CONF['path_layout'] );
+    $block->set_file( 'block', $template );
+
+    $block->set_var( 'xhtml', XHTML );
+    $block->set_var( 'site_url', $_CONF['site_url'] );
+    $block->set_var( 'site_admin_url', $_CONF['site_admin_url'] );
+    $block->set_var( 'layout_url', $_CONF['layout_url'] );
+    $block->set_var( 'block_title', stripslashes( $title ));
+
+    if( !empty( $helpfile ))
+    {
+        $helpimg = $_CONF['layout_url'] . '/images/button_help.' .  
$_IMAGE_TYPE;
+        $help_content = '<img src="' . $helpimg. '" alt="?"' . XHTML . '>';
+        $help_attr = array('class'=>'blocktitle');
+        if( !stristr( $helpfile, 'http://' ))
+        {
+            $help_url = $_CONF['site_url'] . "/help/$helpfile";
+        }
+        else
+        {
+            $help_url = $helpfile;
+        }
+        $help = COM_createLink($help_content, $help_url, $help_attr);
+        $block->set_var( 'block_help', $help );
+    }
+
+    $block->parse( 'startHTML', 'block' );
+
+    return $block->finish( $block->get_var( 'startHTML' ));
+}
+
+/**
+* Closes out COM_startBlock
+*
+* @param        string      $template       HTML template file used to  
format block footer
+* @return   string  Formatted HTML to close block
+* @see function COM_startBlock
+*
+*/
+function COM_endBlock( $template='blockfooter.thtml' )
+{
+    global $_CONF;
+
+    $block = new Template( $_CONF['path_layout'] );
+    $block->set_file( 'block', $template );
+
+    $block->set_var( 'xhtml', XHTML );
+    $block->set_var( 'site_url', $_CONF['site_url'] );
+    $block->set_var( 'site_admin_url', $_CONF['site_admin_url'] );
+    $block->set_var( 'layout_url', $_CONF['layout_url'] );
+    $block->parse( 'endHTML', 'block' );
+
+    return $block->finish( $block->get_var( 'endHTML' ));
+}
+
+
+/**
+* Creates a <option> list from a database list for use in forms
+*
+* Creates option list form field using given arguments
+*
+* @param        string      $table      Database Table to get data from
+* @param        string      $selection  Comma delimited string of fields  
to pull The first field is the value of the option and the second is the  
label to be displayed.  This is used in a SQL statement and can include  
DISTINCT to start.
+* @param        string/array      $selected   Value (from $selection) to  
set to SELECTED or default
+* @param        int         $sortcol    Which field to sort option list by  
0 (value) or 1 (label)
+* @param        string      $where      Optional WHERE clause to use in  
the SQL Selection
+* @see function COM_checkList
+* @return   string  Formated HTML of option values
+*
+*/
+function COM_optionList( $table, $selection, $selected='', $sortcol=1,  
$where='' )
+{
+    global $_DB_table_prefix;
+
+    $retval = '';
+
+    $LangTableName = '';
+    if( substr( $table, 0, strlen( $_DB_table_prefix )) ==  
$_DB_table_prefix )
+    {
+        $LangTableName = 'LANG_' . substr( $table, strlen(  
$_DB_table_prefix ));
+    }
+    else
+    {
+        $LangTableName = 'LANG_' . $table;
+    }
+
+    global $$LangTableName;
+
+    if( isset( $$LangTableName ))
+    {
+        $LangTable = $$LangTableName;
+    }
+    else
+    {
+        $LangTable = array();
+    }
+
+    $tmp = str_replace( 'DISTINCT ', '', $selection );
+    $select_set = explode( ',', $tmp );
+
+    $sql = "SELECT $selection FROM $table";
+    if( $where != '' )
+    {
+        $sql .= " WHERE $where";
+    }
+    $sql .= " ORDER BY {$select_set[$sortcol]}";
+    $result = DB_query( $sql );
+    $nrows = DB_numRows( $result );
+
+    for( $i = 0; $i < $nrows; $i++ )
+    {
+        $A = DB_fetchArray( $result, true );
+        $retval .= '<option value="' . $A[0] . '"';
+
+        if( is_array( $selected ) AND count( $selected ) > 0 )
+        {
+            foreach( $selected as $selected_item )
+            {
+                if( $A[0] == $selected_item )
+                {
+                    $retval .= ' selected="selected"';
+                }
+            }
+        }
+        elseif( !is_array( $selected ) AND $A[0] == $selected )
+        {
+            $retval .= ' selected="selected"';
+        }
+
+        $retval .= '>';
+        if( empty( $LangTable[$A[0]] ))
+        {
+            $retval .= $A[1];
+        }
+        else
+        {
+            $retval .= $LangTable[$A[0]];
+        }
+        $retval .= '</option>' . LB;
+    }
+
+    return $retval;
+}
+
+/**
+* Create and return a dropdown-list of available topics
+*
+* This is a variation of COM_optionList() from lib-common.php. It will add
+* only those topics to the option list which are accessible by the current
+* user.
+*
+* @param        string      $selection  Comma delimited string of fields  
to pull The first field is the value of the option and the second is the  
label to be displayed.  This is used in a SQL statement and can include  
DISTINCT to start.
+* @param        string      $selected   Value (from $selection) to set to  
SELECTED or default
+* @param        int         $sortcol    Which field to sort option list by  
0 (value) or 1 (label)
+* @param        boolean     $ignorelang Whether to return all topics  
(true) or only the ones for the current language (false)
+* @see function COM_optionList
+* @return   string  Formated HTML of option values
+*
+*/
+function COM_topicList( $selection, $selected = '', $sortcol = 1,  
$ignorelang = false )
+{
+    global $_TABLES;
+
+    $retval = '';
+
+    $topics = COM_topicArray($selection, $sortcol, $ignorelang);
+    foreach ($topics as $tid => $topic) {
+        $retval .= '<option value="' . $tid . '"';
+        if ($tid == $selected) {
+            $retval .= ' selected="selected"';
+        }
+        $retval .= '>' . $topic . '</option>' . LB;
+    }
+
+    return $retval;
+}
+
+/**
+* Return a list of topics in an array
+* (derived from COM_topicList - API may change)
+*
+* @param    string  $selection  Comma delimited string of fields to pull  
The first field is the value of the option and the second is the label to  
be displayed.  This is used in a SQL statement and can include DISTINCT to  
start.
+* @param    int     $sortcol    Which field to sort option list by 0  
(value) or 1 (label)
+* @param    boolean $ignorelang Whether to return all topics (true) or  
only the ones for the current language (false)
+* @return   array               Array of topics
+* @see function COM_topicList
+*
+*/
+function COM_topicArray($selection, $sortcol = 0, $ignorelang = false)
+{
+    global $_TABLES;
+
+    $retval = array();
+
+    $tmp = str_replace('DISTINCT ', '', $selection);
+    $select_set = explode(',', $tmp);
+
+    $sql = "SELECT $selection FROM {$_TABLES['topics']}";
+    if ($ignorelang) {
+        $sql .= COM_getPermSQL();
+    } else {
+        $permsql = COM_getPermSQL();
+        if (empty($permsql)) {
+            $sql .= COM_getLangSQL('tid');
+        } else {
+            $sql .= $permsql . COM_getLangSQL('tid', 'AND');
+        }
+    }
+    $sql .=  " ORDER BY $select_set[$sortcol]";
+
+    $result = DB_query($sql);
+    $nrows = DB_numRows($result);
+
+    if (count($select_set) > 1) {
+        for ($i = 0; $i < $nrows; $i++) {
+            $A = DB_fetchArray($result, true);
+            $retval[$A[0]] = stripslashes($A[1]);
+        }
+    } else {
+        for ($i = 0; $i < $nrows; $i++) {
+            $A = DB_fetchArray($result, true);
+            $retval[] = $A[0];
+        }
+    }
+
+    return $retval;
+}
+
+/**
+* Creates a <input> checklist from a database list for use in forms
+*
+* Creates a group of checkbox form fields with given arguments
+*
+* @param        string      $table      DB Table to pull data from
+* @param        string      $selection  Comma delimited list of fields to  
pull from table
+* @param        string      $where      Where clause of SQL statement
+* @param        string      $selected   Value to set to CHECKED
+* @see function COM_optionList
+* @return   string  HTML with Checkbox code
+*
+*/
+
+function COM_checkList( $table, $selection, $where='', $selected='' )
+{
+    global $_TABLES, $_COM_VERBOSE;
+
+    $sql = "SELECT $selection FROM $table";
+
+    if( !empty( $where ))
+    {
+        $sql .= " WHERE $where";
+    }
+
+    $result = DB_query( $sql );
+    $nrows = DB_numRows( $result );
+
+    if( !empty( $selected ))
+    {
+        if( $_COM_VERBOSE )
+        {
+            COM_errorLog( "exploding selected array: $selected in  
COM_checkList", 1 );
+        }
+
+        $S = explode( ' ', $selected );
+    }
+    else
+    {
+        if( $_COM_VERBOSE)
+        {
+            COM_errorLog( 'selected string was empty COM_checkList', 1 );
+        }
+
+        $S = array();
+    }
+    $retval = '<ul class="checkboxes-list">' . LB;
+    for( $i = 0; $i < $nrows; $i++ )
+    {
+        $access = true;
+        $A = DB_fetchArray( $result, true );
+
+        if( $table == $_TABLES['topics'] AND SEC_hasTopicAccess( $A['tid']  
) == 0 )
+        {
+            $access = false;
+        }
+
+        if( $access )
+        {
+            $retval .= '<li><input type="checkbox" name="' . $table . '[]"  
value="' . $A[0] . '"';
+
+            $sizeS = sizeof( $S );
+            for( $x = 0; $x < $sizeS; $x++ )
+            {
+                if( $A[0] == $S[$x] )
+                {
+                    $retval .= ' checked="checked"';
+                    break;
+                }
+            }
+
+            if(( $table == $_TABLES['blocks'] ) && isset( $A[2] ) && (  
$A[2] == 'gldefault' ))
+            {
+                $retval .= XHTML . '><span class="gldefault">' .  
stripslashes( $A[1] ) . '</span></li>' . LB;
+            }
+            else
+            {
+                $retval .= XHTML . '><span>' . stripslashes( $A[1]  
) . '</span></li>' . LB;
+            }
+        }
+    }
+    $retval .= '</ul>' . LB;
+
+    return $retval;
+}
+
+/**
+* Prints out an associative array for debugging
+*
+* The core of this code has been lifted from phpweblog which is licenced
+* under the GPL.  This is not used very much in the code but you can use it
+* if you see fit
+*
+* @param        array       $A      Array to loop through and print values  
for
+* @return   string  Formated HTML List
+*
+*/
+
+function COM_debug( $A )
+{
+    if( !empty( $A ))
+    {
+        $retval .= LB . '<pre><p>---- DEBUG ----</p>';
+
+        for( reset( $A ); $k = key( $A ); next( $A ))
+        {
+            $retval .= sprintf( "<li>%13s [%s]</li>\n", $k, $A[$k] );
+        }
+
+        $retval .= '<p>---------------</p></pre>' . LB;
+    }
+
+    return $retval;
+}
+
+/**
+*
+* Checks to see if RDF file needs updating and updates it if so.
+* Checks to see if we need to update the RDF as a result
+* of an article with a future publish date reaching it's
+* publish time and if so updates the RDF file.
+*
+* @param    string  $updated_type   (optional) feed type to update
+* @param    string  $updated_topic  (optional) feed topic to update
+* @param    string  $updated_id     (optional) feed id to update
+*
+* @note When called without parameters, this will only check for new  
entries to
+*       include in the feeds. Pass the $updated_XXX parameters when the  
content
+*       of an existing entry has changed.
+*
+* @see file lib-syndication.php
+*
+*/
+function COM_rdfUpToDateCheck( $updated_type = '', $updated_topic = '',  
$updated_id = '' )
+{
+    global $_CONF, $_TABLES;
+
+    if( $_CONF['backend'] > 0 )
+    {
+        if( !empty( $updated_type ) && ( $updated_type != 'article' ))
+        {
+            // when a plugin's feed is to be updated, skip Geeklog's own  
feeds
+            $sql = "SELECT fid,type,topic,limits,update_info FROM  
{$_TABLES['syndication']} WHERE (is_enabled = 1) AND (type <> 'article')";
+        }
+        else
+        {
+            $sql = "SELECT fid,type,topic,limits,update_info FROM  
{$_TABLES['syndication']} WHERE is_enabled = 1";
+        }
+        $result = DB_query( $sql );
+        $num = DB_numRows( $result );
+        for( $i = 0; $i < $num; $i++)
+        {
+            $A = DB_fetchArray( $result );
+
+            $is_current = true;
+            if( $A['type'] == 'article' )
+            {
+                $is_current = SYND_feedUpdateCheck( $A['topic'],
+                                $A['update_info'], $A['limits'],
+                                $updated_topic, $updated_id );
+            }
+            else
+            {
+                $is_current = PLG_feedUpdateCheck( $A['type'], $A['fid'],
+                                $A['topic'], $A['update_info'],  
$A['limits'],
+                                $updated_type, $updated_topic, $updated_id  
);
+            }
+            if( !$is_current )
+            {
+                SYND_updateFeed( $A['fid'] );
+            }
+        }
+    }
+}
+
+/**
+* Checks and Updates the featured status of all articles.
+*
+* Checks to see if any articles that were published for the future have  
been
+* published and, if so, will see if they are featured.  If they are  
featured,
+* this will set old featured article (if there is one) to normal
+*
+*/
+
+function COM_featuredCheck()
+{
+    global $_TABLES;
+
+    $curdate = date( "Y-m-d H:i:s", time() );
+
+    if( DB_getItem( $_TABLES['stories'], 'count(*)', "featured = 1 AND  
draft_flag = 0 AND date <= '$curdate'" ) > 1 )
+    {
+        // OK, we have two featured stories, fix that
+
+        $sid = DB_getItem( $_TABLES['stories'], 'sid', "featured = 1 AND  
draft_flag = 0 ORDER BY date LIMIT 1" );
+        DB_query( "UPDATE {$_TABLES['stories']} SET featured = 0 WHERE sid  
= '$sid'" );
+    }
+}
+
+/**
+*
+* Logs messages to error.log or the web page or both
+*
+* Prints a well formatted message to either the web page, error log
+* or both.
+*
+* @param        string      $logentry       Text to log to error log
+* @param        int         $actionid       1 = write to log file, 2 =  
write to screen (default) both
+* @see function COM_accessLog
+* @return   string  If $actionid = 2 or '' then HTML formatted string  
(wrapped in block) else nothing
+*
+*/
+
+function COM_errorLog( $logentry, $actionid = '' )
+{
+    global $_CONF, $LANG01;
+
+    $retval = '';
+
+    if( !empty( $logentry ))
+    {
+        $logentry = str_replace( array( '<?', '?>' ), array( '(@', '@)' ),
+                                 $logentry );
+
+        $timestamp = strftime( '%c' );
+
+        if (!isset($_CONF['path_layout']) &&
+                (($actionid == 2) || empty($actionid))) {
+            $actionid = 1;
+        }
+        if (!isset($_CONF['path_log']) && ($actionid != 2)) {
+            $actionid = 3;
+        }
+
+        switch( $actionid )
+        {
+            case 1:
+                $logfile = $_CONF['path_log'] . 'error.log';
+
+                if( !$file = fopen( $logfile, 'a' ))
+                {
+                    $retval .= $LANG01[33] . ' ' . $logfile . ' (' .  
$timestamp . ')<br' . XHTML . '>' . LB;
+                }
+                else
+                {
+                    fputs( $file, "$timestamp - $logentry \n" );
+                }
+                break;
+
+            case 2:
+                $retval .= COM_startBlock( $LANG01[55] . ' ' .  
$timestamp, '',
+                                
COM_getBlockTemplate( '_msg_block', 'header' ))
+                        . nl2br( $logentry )
+                        . COM_endBlock( COM_getBlockTemplate( '_msg_block',
+                                                              'footer' ));
+                break;
+
+            case 3:
+                $retval = nl2br($logentry);
+                break;
+
+            default:
+                $logfile = $_CONF['path_log'] . 'error.log';
+
+                if( !$file = fopen( $logfile, 'a' ))
+                {
+                    $retval .= $LANG01[33] . ' ' . $logfile . ' (' .  
$timestamp . ')<br' . XHTML . '>' . LB;
+                }
+                else
+                {
+                    fputs( $file, "$timestamp - $logentry \n" );
+                    $retval .= COM_startBlock( $LANG01[34] . ' - ' .  
$timestamp,
+                                   '', COM_getBlockTemplate( '_msg_block',
+                                   'header' ))
+                            . nl2br( $logentry )
+                            . COM_endBlock(  
COM_getBlockTemplate( '_msg_block',
+                                                                  'footer'  
));
+                }
+                break;
+        }
+    }
+
+    return $retval;
+}
+
+/**
+* Logs message to access.log
+*
+* This will print a message to the Geeklog access log
+*
+* @param        string      $string         Message to write to access log
+* @see COM_errorLog
+*
+*/
+
+function COM_accessLog( $logentry )
+{
+    global $_CONF, $_USER, $LANG01;
+
+    $retval = '';
+
+    if( !empty( $logentry ))
+    {
+        $logentry = str_replace( array( '<?', '?>' ), array( '(@', '@)' ),
+                                 $logentry );
+
+        $timestamp = strftime( '%c' );
+        $logfile = $_CONF['path_log'] . 'access.log';
+
+        if( !$file = fopen( $logfile, 'a' ))
+        {
+            return $LANG01[33] . $logfile . ' (' . $timestamp . ')<br' .  
XHTML . '>' . LB;
+        }
+
+        if( isset( $_USER['uid'] ))
+        {
+            $byuser = $_USER['uid'] . '@' . $_SERVER['REMOTE_ADDR'];
+        }
+        else
+        {
+            $byuser = 'anon@' . $_SERVER['REMOTE_ADDR'];
+        }
+
+        fputs( $file, "$timestamp ($byuser) - $logentry\n" );
+    }
+
+    return $retval;
+}
+
+/**
+* Shows all available topics
+*
+* Show the topics in the system the user has access to and prints them in  
HTML.
+* This function is used to show the topics in the topics block.
+*
+* @param    string    $topic      ID of currently selected topic
+* @return   string                HTML formatted topic list
+*
+*/
+
+function COM_showTopics( $topic='' )
+{
+    global $_CONF, $_TABLES, $_USER, $LANG01, $_BLOCK_TEMPLATE, $page;
+
+    $langsql = COM_getLangSQL( 'tid' );
+    if( empty( $langsql ))
+    {
+        $op = 'WHERE';
+    }
+    else
+    {
+        $op = 'AND';
+    }
+
+    $sql = "SELECT tid,topic,imageurl FROM {$_TABLES['topics']}" .  
$langsql;
+    if( !COM_isAnonUser() )
+    {
+        $tids = DB_getItem( $_TABLES['userindex'], 'tids',
+                            "uid = '{$_USER['uid']}'" );
+        if( !empty( $tids ))
+        {
+            $sql .= " $op (tid NOT IN ('" . str_replace( ' ', "','", $tids  
)
+                 . "'))" . COM_getPermSQL( 'AND' );
+        }
+        else
+        {
+            $sql .= COM_getPermSQL( $op );
+        }
+    }
+    else
+    {
+        $sql .= COM_getPermSQL( $op );
+    }
+    if( $_CONF['sortmethod'] == 'alpha' )
+    {
+        $sql .= ' ORDER BY topic ASC';
+    }
+    else
+    {
+        $sql .= ' ORDER BY sortnum';
+    }
+    $result = DB_query( $sql );
+
+    $retval = '';
+    $sections = new Template( $_CONF['path_layout'] );
+    if( isset( $_BLOCK_TEMPLATE['topicoption'] ))
+    {
+        $templates = explode( ',', $_BLOCK_TEMPLATE['topicoption'] );
+        $sections->set_file( array( 'option'  => $templates[0],
+                                    'current' => $templates[1] ));
+    }
+    else
+    {
+        $sections->set_file( array( 'option'   => 'topicoption.thtml',
+                                    'inactive' => 'topicoption_off.thtml'  
));
+    }
+
+    $sections->set_var( 'xhtml', XHTML );
+    $sections->set_var( 'site_url', $_CONF['site_url'] );
+    $sections->set_var( 'site_admin_url', $_CONF['site_admin_url'] );
+    $sections->set_var( 'layout_url', $_CONF['layout_url'] );
+    $sections->set_var( 'block_name',  
str_replace( '_', '-', 'section_block' ));
+
+    if( $_CONF['hide_home_link'] == 0 )
+    {
+        // Give a link to the homepage here since a lot of people use this  
for
+        // navigating the site
+
+        if( COM_onFrontpage() )
+        {
+            $sections->set_var( 'option_url', '' );
+            $sections->set_var( 'option_label', $LANG01[90] );
+            $sections->set_var( 'option_count', '' );
+            $sections->set_var( 'topic_image', '' );
+            $retval .= $sections->parse( 'item', 'inactive' );
+        }
+        else
+        {
+            $sections->set_var( 'option_url',
+                                $_CONF['site_url'] . '/index.php' );
+            $sections->set_var( 'option_label', $LANG01[90] );
+            $sections->set_var( 'option_count', '' );
+            $sections->set_var( 'topic_image', '' );
+            $retval .= $sections->parse( 'item', 'option' );
+        }
+    }
+
+    if( $_CONF['showstorycount'] )
+    {
+        $sql = "SELECT tid, COUNT(*) AS count FROM {$_TABLES['stories']} "
+             . 'WHERE (draft_flag = 0) AND (date <= NOW()) '
+             . COM_getPermSQL( 'AND' )
+             . ' GROUP BY tid';
+        $rcount = DB_query( $sql );
+        while( $C = DB_fetchArray( $rcount ))
+        {
+            $storycount[$C['tid']] = $C['count'];
+        }
+    }
+
+    if( $_CONF['showsubmissioncount'] )
+    {
+        $sql = "SELECT tid, COUNT(*) AS count FROM  
{$_TABLES['storysubmission']} "
+             . ' GROUP BY tid';
+        $rcount = DB_query( $sql );
+        while( $C = DB_fetchArray( $rcount ))
+        {
+            $submissioncount[$C['tid']] = $C['count'];
+        }
+    }
+
+    while( $A = DB_fetchArray( $result ) )
+    {
+        $topicname = stripslashes( $A['topic'] );
+        $sections->set_var( 'option_url', $_CONF['site_url']
+                            . '/index.php?topic=' . $A['tid'] );
+        $sections->set_var( 'option_label', $topicname );
+
+        $countstring = '';
+        if( $_CONF['showstorycount'] || $_CONF['showsubmissioncount'] )
+        {
+            $countstring .= '(';
+
+            if( $_CONF['showstorycount'] )
+            {
+                if( empty( $storycount[$A['tid']] ))
+                {
+                    $countstring .= 0;
+                }
+                else
+                {
+                    $countstring .= COM_numberFormat(  
$storycount[$A['tid']] );
+                }
+            }
+
+            if( $_CONF['showsubmissioncount'] )
+            {
+                if( $_CONF['showstorycount'] )
+                {
+                    $countstring .= '/';
+                }
+                if( empty( $submissioncount[$A['tid']] ))
+                {
+                    $countstring .= 0;
+                }
+                else
+                {
+                    $countstring .= COM_numberFormat(  
$submissioncount[$A['tid']] );
+                }
+            }
+
+            $countstring .= ')';
+        }
+        $sections->set_var( 'option_count', $countstring );
+
+        $topicimage = '';
+        if( !empty( $A['imageurl'] ))
+        {
+            $imageurl = COM_getTopicImageUrl( $A['imageurl'] );
+            $topicimage = '<img src="' . $imageurl . '" alt="' . $topicname
+                        . '" title="' . $topicname . '" border="0"' .  
XHTML . '>';
+        }
+        $sections->set_var( 'topic_image', $topicimage );
+
+        if(( $A['tid'] == $topic ) && ( $page == 1 ))
+        {
+            $retval .= $sections->parse( 'item', 'inactive' );
+        }
+        else
+        {
+            $retval .= $sections->parse( 'item', 'option' );
+        }
+    }
+
+    return $retval;
+}
+
+/**
+* Shows the user their menu options
+*
+* This shows the average joe use their menu options. This is the user  
block on right side
+*
+* @param        string      $help       Help file to show
+* @param        string      $title      Title of Menu
+* @param        string      $position   Side being shown  
on 'left', 'right'. Though blank works not likely.
+* @see function COM_adminMenu
+*
+*/
+
+function COM_userMenu( $help='', $title='', $position='' )
+{
+    global $_TABLES, $_USER, $_CONF, $LANG01, $LANG04, $_BLOCK_TEMPLATE;
+
+    $retval = '';
+
+    if( !COM_isAnonUser() )
+    {
+        $usermenu = new Template( $_CONF['path_layout'] );
+        if( isset( $_BLOCK_TEMPLATE['useroption'] ))
+        {
+            $templates = explode( ',', $_BLOCK_TEMPLATE['useroption'] );
+            $usermenu->set_file( array( 'option' => $templates[0],
+                                        'current' => $templates[1] ));
+        }
+        else
+        {
+           $usermenu->set_file( array( 'option' => 'useroption.thtml',
+                                       'current' => 'useroption_off.thtml'  
));
+        }
+        $usermenu->set_var( 'xhtml', XHTML );
+        $usermenu->set_var( 'site_url', $_CONF['site_url'] );
+        $usermenu->set_var( 'site_admin_url', $_CONF['site_admin_url'] );
+        $usermenu->set_var( 'layout_url', $_CONF['layout_url'] );
+        $usermenu->set_var( 'block_name',  
str_replace( '_', '-', 'user_block' ));
+
+        if( empty( $title ))
+        {
+            $title = DB_getItem( $_TABLES['blocks'], 'title',
+                                 "name='user_block'" );
+        }
+
+        // what's our current URL?
+        $thisUrl = COM_getCurrentURL();
+
+        $retval .= COM_startBlock( $title, $help,
+                           COM_getBlockTemplate( 'user_block', 'header',  
$position ));
+
+        // This function will show the user options for all installed  
plugins
+        // (if any)
+
+        $plugin_options = PLG_getUserOptions();
+        $nrows = count( $plugin_options );
+
+        for( $i = 0; $i < $nrows; $i++ )
+        {
+            $plg = current( $plugin_options );
+            $usermenu->set_var( 'option_label', $plg->adminlabel );
+
+            if( !empty( $plg->numsubmissions ))
+            {
+                $usermenu->set_var( 'option_count', '(' .  
$plg->numsubmissions . ')' );
+            }
+            else
+            {
+                $usermenu->set_var( 'option_count', '' );
+            }
+
+            $usermenu->set_var( 'option_url', $plg->adminurl );
+            if( $thisUrl == $plg->adminurl )
+            {
+                $retval .= $usermenu->parse( 'item', 'current' );
+            }
+            else
+            {
+                $retval .= $usermenu->parse( 'item', 'option' );
+            }
+            next( $plugin_options );
+        }
+
+        $url = $_CONF['site_url'] . '/usersettings.php';
+        $usermenu->set_var( 'option_label', $LANG01[48] );
+        $usermenu->set_var( 'option_count', '' );
+        $usermenu->set_var( 'option_url', $url );
+        if( $thisUrl == $url )
+        {
+            $retval .= $usermenu->parse( 'item', 'current' );
+        }
+        else
+        {
+            $retval .= $usermenu->parse( 'item', 'option' );
+        }
+
+        $url = $_CONF['site_url'] . '/users.php?mode=logout';
+        $usermenu->set_var( 'option_label', $LANG01[19] );
+        $usermenu->set_var( 'option_count', '' );
+        $usermenu->set_var( 'option_url', $url );
+        $retval .= $usermenu->parse( 'item', 'option' );
+        $retval .=  COM_endBlock(  
COM_getBlockTemplate( 'user_block', 'footer', $position ));
+    }
+    else
+    {
+        $retval .= COM_startBlock( $LANG01[47], $help,
+                           COM_getBlockTemplate( 'user_block', 'header',  
$position ));
+        $login = new Template( $_CONF['path_layout'] );
+        $login->set_file( 'form', 'loginform.thtml' );
+        $login->set_var( 'xhtml', XHTML );
+        $login->set_var( 'site_url', $_CONF['site_url'] );
+        $login->set_var( 'site_admin_url', $_CONF['site_admin_url'] );
+        $login->set_var( 'layout_url', $_CONF['layout_url'] );
+        $login->set_var( 'lang_username', $LANG01[21] );
+        $login->set_var( 'lang_password', $LANG01[57] );
+        $login->set_var( 'lang_forgetpassword', $LANG01[119] );
+        $login->set_var( 'lang_login', $LANG01[58] );
+        if( $_CONF['disable_new_user_registration'] == 1 )
+        {
+            $login->set_var( 'lang_signup', '' );
+        }
+        else
+        {
+            $login->set_var( 'lang_signup', $LANG01[59] );
+        }
+
+        // 3rd party remote authentification.
+        if ($_CONF['user_login_method']['3rdparty']  
&& !$_CONF['usersubmission']) {
+            $modules = SEC_collectRemoteAuthenticationModules();
+            if (count($modules) == 0) {
+                $user_templates->set_var('services', '');
+            } else {
+                if (!$_CONF['user_login_method']['standard'] &&
+                        (count($modules) == 1)) {
+                    $select = '<input type="hidden" name="service" value="'
+                            . $modules[0] . '"' . XHTML . '>' .  
$modules[0];
+                } else {
+                    // Build select
+                    $select = '<select name="service" id="service">';
+                    if ($_CONF['user_login_method']['standard']) {
+                        $select .= '<option value="">' .  
$_CONF['site_name']
+                                . '</option>';
+                    }
+                    foreach ($modules as $service) {
+                        $select .= '<option value="' . $service . '">'
+                                . $service . '</option>';
+                    }
+                    $select .= '</select>';
+                }
+
+                $login->set_file('services', 'blockservices.thtml');
+                $login->set_var('lang_service', $LANG04[121]);
+                $login->set_var('select_service', $select);
+                $login->parse('output', 'services');
+                $login->set_var('services',
+                                $login->finish($login->get_var('output')));
+            }
+        } else {
+           $login->set_var('services', '');
+        }
+
+        // OpenID remote authentification.
+        if ($_CONF['user_login_method']['openid'] &&  
($_CONF['usersubmission'] == 0)  
&& !$_CONF['disable_new_user_registration']) {
+            $login->set_file('openid_login', 'loginform_openid.thtml');
+            $login->set_var('lang_openid_login', $LANG01[128]);
+            $login->set_var('input_field_size', 18);
+            $login->set_var('app_url', $_CONF['site_url'] . '/users.php');
+            $login->parse('output', 'openid_login');
+            $login->set_var('openid_login',
+                $login->finish($login->get_var('output')));
+        } else {
+            $login->set_var('openid_login', '');
+        }
+
+        $retval .= $login->parse( 'output', 'form' );
+        $retval .= COM_endBlock(  
COM_getBlockTemplate( 'user_block', 'footer', $position ));
+    }
+
+    return $retval;
+}
+
+/**
+* Prints administration menu
+*
+* This will return the administration menu items that the user has
+* sufficient rights to -- Admin Block on right side.
+*
+* @param        string      $help       Help file to show
+* @param        string      $title      Menu Title
+* @param        string      $position   Side being shown  
on 'left', 'right' or blank.
+* @see function COM_userMenu
+*
+*/
+
+function COM_adminMenu( $help = '', $title = '', $position = '' )
+{
+    global $_TABLES, $_USER, $_CONF, $LANG01, $_BLOCK_TEMPLATE, $LANG_PDF,
+           $_DB_dbms, $config;
+
+    $retval = '';
+
+    if( empty( $_USER['username'] ))
+    {
+        return $retval;
+    }
+
+    $plugin_options = PLG_getAdminOptions();
+    $num_plugins = count( $plugin_options );
+
+    if( SEC_isModerator() OR  
SEC_hasRights( 'story.edit,block.edit,topic.edit,user.edit,plugin.edit,user.mail,syndication.edit', 'OR'  
) OR ( $num_plugins > 0 ))
+    {
+        // what's our current URL?
+        $thisUrl = COM_getCurrentURL();
+
+        $adminmenu = new Template( $_CONF['path_layout'] );
+        if( isset( $_BLOCK_TEMPLATE['adminoption'] ))
+        {
+            $templates = explode( ',', $_BLOCK_TEMPLATE['adminoption'] );
+            $adminmenu->set_file( array( 'option' => $templates[0],
+                                         'current' => $templates[1] ));
+        }
+        else
+        {
+            $adminmenu->set_file( array( 'option' => 'adminoption.thtml',
+                                         'current'  
=> 'adminoption_off.thtml' ));
+        }
+        $adminmenu->set_var( 'xhtml', XHTML );
+        $adminmenu->set_var( 'site_url', $_CONF['site_url'] );
+        $adminmenu->set_var( 'site_admin_url', $_CONF['site_admin_url'] );
+        $adminmenu->set_var( 'layout_url', $_CONF['layout_url'] );
+        $adminmenu->set_var( 'block_name',  
str_replace( '_', '-', 'admin_block' ));
+
+        if( empty( $title ))
+        {
+            $title = DB_getItem( $_TABLES['blocks'], 'title',
+                                 "name = 'admin_block'" );
+        }
+
+        $retval .= COM_startBlock( $title, $help,
+                           COM_getBlockTemplate( 'admin_block', 'header',  
$position ));
+
+        $topicsql = '';
+        if( SEC_isModerator() || SEC_hasRights( 'story.edit' ))
+        {
+            $tresult = DB_query( "SELECT tid FROM {$_TABLES['topics']}"
+                                 . COM_getPermSQL() );
+            $trows = DB_numRows( $tresult );
+            if( $trows > 0 )
+            {
+                $tids = array();
+                for( $i = 0; $i < $trows; $i++ )
+                {
+                    $T = DB_fetchArray( $tresult );
+                    $tids[] = $T['tid'];
+                }
+                if( sizeof( $tids ) > 0 )
+                {
+                    $topicsql = " (tid IN ('" . implode( "','", $tids  
) . "'))";
+                }
+            }
+        }
+
+        $modnum = 0;
+        if( SEC_hasRights( 'story.edit,story.moderate', 'OR' ) || ((  
$_CONF['usersubmission'] == 1 ) && SEC_hasRights( 'user.edit,user.delete'  
)))
+        {
+
+            if( SEC_hasRights( 'story.moderate' ))
+            {
+                if( empty( $topicsql ))
+                {
+                    $modnum += DB_count( $_TABLES['storysubmission'] );
+                }
+                else
+                {
+                    $sresult = DB_query( "SELECT COUNT(*) AS count FROM  
{$_TABLES['storysubmission']} WHERE" . $topicsql );
+                    $S = DB_fetchArray( $sresult );
+                    $modnum += $S['count'];
+                }
+            }
+
+            if(( $_CONF['listdraftstories'] == 1 ) &&  
SEC_hasRights( 'story.edit' ))
+            {
+                $sql = "SELECT COUNT(*) AS count FROM  
{$_TABLES['stories']} WHERE (draft_flag = 1)";
+                if( !empty( $topicsql ))
+                {
+                    $sql .= ' AND' . $topicsql;
+                }
+                $result = DB_query( $sql . COM_getPermSQL( 'AND', 0, 3 ));
+                $A = DB_fetchArray( $result );
+                $modnum += $A['count'];
+            }
+
+            if( $_CONF['usersubmission'] == 1 )
+            {
+                if( SEC_hasRights( 'user.edit' ) &&  
SEC_hasRights( 'user.delete' ))
+                {
+                    $modnum += DB_count( $_TABLES['users'], 'status', '2'  
);
+                }
+            }
+        }
+
+        if (SEC_inGroup('Root')) {
+            $url = $_CONF['site_admin_url'] . '/configuration.php';
+            $adminmenu->set_var('option_url', $url);
+            $adminmenu->set_var('option_label', $LANG01[129]);
+            $adminmenu->set_var('option_count',  
count($config->_get_groups()));
+            $menu_item = $adminmenu->parse('item',
+                                           ($thisUrl == $url) ? 'current' :
+                                                                'option');
+            $link_array[$LANG01[129]] = $menu_item;
+        }
+
+
+        // now handle submissions for plugins
+        $modnum += PLG_getSubmissionCount();
+
+        if( SEC_hasRights( 'story.edit' ))
+        {
+            $url = $_CONF['site_admin_url'] . '/story.php';
+            $adminmenu->set_var( 'option_url', $url );
+            $adminmenu->set_var( 'option_label', $LANG01[11] );
+            if( empty( $topicsql ))
+            {
+                $numstories = DB_count( $_TABLES['stories'] );
+            }
+            else
+            {
+                $nresult = DB_query( "SELECT COUNT(*) AS count from  
{$_TABLES['stories']} WHERE" . $topicsql . COM_getPermSql( 'AND' ));
+                $N = DB_fetchArray( $nresult );
+                $numstories = $N['count'];
+            }
+            $adminmenu->set_var( 'option_count',
+                                 COM_numberFormat( $numstories ));
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+            $link_array[$LANG01[11]] = $menu_item;
+        }
+
+        if( SEC_hasRights( 'block.edit' ))
+        {
+            $result = DB_query( "SELECT COUNT(*) AS count FROM  
{$_TABLES['blocks']}" . COM_getPermSql());
+            list( $count ) = DB_fetchArray( $result );
+
+            $url = $_CONF['site_admin_url'] . '/block.php';
+            $adminmenu->set_var( 'option_url', $url );
+            $adminmenu->set_var( 'option_label', $LANG01[12] );
+            $adminmenu->set_var( 'option_count', COM_numberFormat( $count  
));
+
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+            $link_array[$LANG01[12]] = $menu_item;
+        }
+
+        if( SEC_hasRights( 'topic.edit' ))
+        {
+            $result = DB_query( "SELECT COUNT(*) AS count FROM  
{$_TABLES['topics']}" . COM_getPermSql());
+            list( $count ) = DB_fetchArray( $result );
+
+            $url = $_CONF['site_admin_url'] . '/topic.php';
+            $adminmenu->set_var( 'option_url', $url );
+            $adminmenu->set_var( 'option_label', $LANG01[13] );
+            $adminmenu->set_var( 'option_count', COM_numberFormat( $count  
));
+
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+            $link_array[$LANG01[13]] = $menu_item;
+        }
+
+        if( SEC_hasRights( 'user.edit' ))
+        {
+            $url = $_CONF['site_admin_url'] . '/user.php';
+            $adminmenu->set_var( 'option_url', $url );
+            $adminmenu->set_var( 'option_label', $LANG01[17] );
+            $adminmenu->set_var( 'option_count',
+                    COM_numberFormat( DB_count( $_TABLES['users'] ) -1 ));
+
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+            $link_array[$LANG01[17]] = $menu_item;
+        }
+
+        if( SEC_hasRights( 'group.edit' ))
+        {
+            if (SEC_inGroup('Root')) {
+                $grpFilter = '';
+            } else {
+                $thisUsersGroups = SEC_getUserGroups ();
+                $grpFilter = 'WHERE (grp_id IN (' . implode (',',  
$thisUsersGroups) . '))';
+            }
+            $result = DB_query( "SELECT COUNT(*) AS count FROM  
{$_TABLES['groups']} $grpFilter;" );
+            $A = DB_fetchArray( $result );
+
+            $url = $_CONF['site_admin_url'] . '/group.php';
+            $adminmenu->set_var( 'option_url', $url );
+            $adminmenu->set_var( 'option_label', $LANG01[96] );
+            $adminmenu->set_var( 'option_count',
+                                 COM_numberFormat( $A['count'] ));
+
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+            $link_array[$LANG01[96]] = $menu_item;
+        }
+
+        if( SEC_hasRights( 'user.mail' ))
+        {
+            $url = $_CONF['site_admin_url'] . '/mail.php';
+            $adminmenu->set_var( 'option_url', $url );
+            $adminmenu->set_var( 'option_label', $LANG01[105] );
+            $adminmenu->set_var( 'option_count', 'N/A' );
+
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+            $link_array[$LANG01[105]] = $menu_item;
+        }
+
+        if(( $_CONF['backend'] == 1 ) && SEC_hasRights( 'syndication.edit'  
))
+        {
+            $url = $_CONF['site_admin_url'] . '/syndication.php';
+            $adminmenu->set_var( 'option_url', $url );
+            $adminmenu->set_var( 'option_label', $LANG01[38] );
+            $count = COM_numberFormat( DB_count( $_TABLES['syndication']  
));
+            $adminmenu->set_var( 'option_count', $count );
+
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+            $link_array[$LANG01[38]] = $menu_item;
+        }
+
+        if(( $_CONF['trackback_enabled'] || $_CONF['pingback_enabled'] ||
+                $_CONF['ping_enabled'] ) && SEC_hasRights( 'story.ping' ))
+        {
+            $url = $_CONF['site_admin_url'] . '/trackback.php';
+            $adminmenu->set_var( 'option_url', $url );
+            $adminmenu->set_var( 'option_label', $LANG01[116] );
+            if( $_CONF['ping_enabled'] )
+            {
+                $count = COM_numberFormat( DB_count(  
$_TABLES['pingservice'] ));
+                $adminmenu->set_var( 'option_count', $count );
+            }
+            else
+            {
+                $adminmenu->set_var( 'option_count', 'N/A' );
+            }
+
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+            $link_array[$LANG01[116]] = $menu_item;
+        }
+
+        if( SEC_hasRights( 'plugin.edit' ))
+        {
+            $url = $_CONF['site_admin_url'] . '/plugins.php';
+            $adminmenu->set_var( 'option_url', $url );
+            $adminmenu->set_var( 'option_label', $LANG01[77] );
+            $adminmenu->set_var( 'option_count',
+                    COM_numberFormat( DB_count( $_TABLES['plugins'] )));
+
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+            $link_array[$LANG01[77]] = $menu_item;
+        }
+
+        // This will show the admin options for all installed plugins (if  
any)
+
+        for( $i = 0; $i < $num_plugins; $i++ )
+        {
+            $plg = current( $plugin_options );
+
+            $adminmenu->set_var( 'option_url', $plg->adminurl );
+            $adminmenu->set_var( 'option_label', $plg->adminlabel );
+
+            if( empty( $plg->numsubmissions ))
+            {
+                $adminmenu->set_var( 'option_count', 'N/A' );
+            }
+            else
+            {
+                $adminmenu->set_var( 'option_count',
+                                     COM_numberFormat(  
$plg->numsubmissions ));
+            }
+
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $plg->adminurl ) ? 'current' : 'option',  
true );
+            $link_array[$plg->adminlabel] = $menu_item;
+
+            next( $plugin_options );
+        }
+
+        if(( $_CONF['allow_mysqldump'] == 1 ) AND ( $_DB_dbms == 'mysql' )  
AND
+                SEC_inGroup( 'Root' ))
+        {
+            $url = $_CONF['site_admin_url'] . '/database.php';
+            $adminmenu->set_var( 'option_url', $url );
+            $adminmenu->set_var( 'option_label', $LANG01[103] );
+            $adminmenu->set_var( 'option_count', 'N/A' );
+
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+            $link_array[$LANG01[103]] = $menu_item;
+        }
+
+        // Add PDF Generator Link if the feature is enabled
+        if(( $_CONF['pdf_enabled'] == 1 ) AND SEC_inGroup( 'Root' ))
+        {
+            $url = $_CONF['site_url'] . '/pdfgenerator.php';
+            $adminmenu->set_var( 'option_url', $url );
+            $adminmenu->set_var( 'option_label', $LANG_PDF[9] );
+            $adminmenu->set_var( 'option_count', 'N/A' );
+
+            $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+            $link_array[$LANG_PDF[9]] = $menu_item;
+        }
+
+        if( $_CONF['link_documentation'] == 1 )
+        {
+            $adminmenu->set_var( 'option_url',
+                                 $_CONF['site_url'] . '/docs/index.html' );
+            $adminmenu->set_var( 'option_label', $LANG01[113] );
+            $adminmenu->set_var( 'option_count', 'N/A' );
+            $menu_item = $adminmenu->parse( 'item', 'option' );
+            $link_array[$LANG01[113]] = $menu_item;
+        }
+
+        if( $_CONF['link_versionchecker'] == 1 AND SEC_inGroup( 'Root' ))
+        {
+            $adminmenu->set_var( 'option_url',
+               'http://www.geeklog.net/versionchecker.php?version=' .  
VERSION );
+            $adminmenu->set_var( 'option_label', $LANG01[107] );
+            $adminmenu->set_var( 'option_count', VERSION );
+
+            $menu_item = $adminmenu->parse( 'item', 'option' );
+            $link_array[$LANG01[107]] = $menu_item;
+        }
+
+        if( $_CONF['sort_admin'] )
+        {
+            uksort( $link_array, 'strcasecmp' );
+        }
+
+        $url = $_CONF['site_admin_url'] . '/moderation.php';
+        $adminmenu->set_var( 'option_url', $url );
+        $adminmenu->set_var( 'option_label', $LANG01[10] );
+        $adminmenu->set_var( 'option_count', COM_numberFormat( $modnum ));
+        $menu_item = $adminmenu->parse( 'item',
+                    ( $thisUrl == $url ) ? 'current' : 'option' );
+        $link_array = array( $menu_item ) + $link_array;
+
+        foreach( $link_array as $link )
+        {
+            $retval .= $link;
+        }
+
+        $retval .= COM_endBlock(  
COM_getBlockTemplate( 'admin_block', 'footer', $position ));
+    }
+
+    return $retval;
+}
+
+/**
+* Redirects user to a given URL
+*
+* This function does a redirect using a meta refresh. This is (or at least
+* used to be) more compatible than using a HTTP Location: header.
+*
+* @param    string  $url    URL to send user to
+* @return   string          HTML meta redirect
+* @note     This does not need to be XHTML compliant. It may also be used
+*           in situations where the XHTML constant is not defined yet ...
+*
+*/
+function COM_refresh($url)
+{
+    return "<html><head><meta http-equiv=\"refresh\" content=\"0;  
URL=$url\"></head></html>\n";
+}
+
+/**
+ * DEPRECIATED -- see CMT_userComments in lib-comment.php
+ */
+function COM_userComments( $sid, $title, $type='article', $order='',  
$mode='', $pid = 0, $page = 1, $cid = false, $delete_option = false ) {
+    global $_CONF;
+
+    require_once $_CONF['path_system'] . 'lib-comment.php';
+    return CMT_userComments( $sid, $title, $type, $order, $mode, $pid,  
$page, $cid, $delete_option );
+}
+
+/**
+* This censors inappropriate content
+*
+* This will replace 'bad words' with something more appropriate
+*
+* @param        string      $Message        String to check
+* @see function COM_checkHTML
+* @return   string  Edited $Message
+*
+*/
+
+function COM_checkWords( $Message )
+{
+    global $_CONF;
+
+    $EditedMessage = $Message;
+
+    if( $_CONF['censormode'] != 0 )
+    {
+        if( is_array( $_CONF['censorlist'] ))
+        {
+            $Replacement = $_CONF['censorreplace'];
+
+            switch( $_CONF['censormode'])
+            {
+                case 1: # Exact match
+                    $RegExPrefix = '(\s*)';
+                    $RegExSuffix = '(\W*)';
+                    break;
+
+                case 2: # Word beginning
+                    $RegExPrefix = '(\s*)';
+                    $RegExSuffix = '(\w*)';
+                    break;
+
+                case 3: # Word fragment
+                    $RegExPrefix   = '(\w*)';
+                    $RegExSuffix   = '(\w*)';
+                    break;
+            }
+
+            foreach ($_CONF['censorlist'] as $c) {
+                if (!empty($c)) {
+                    $EditedMessage = MBYTE_eregi_replace($RegExPrefix . $c
+                        . $RegExSuffix, "\\1$Replacement\\2",  
$EditedMessage);
+                }
+            }
+        }
+    }
+
+    return $EditedMessage;
+}
+
+/**
+*  Takes some amount of text and replaces all javascript events on*= with  
in
+*
+*  This script takes some amount of text and matches all javascript  
events, on*= (onBlur= onMouseClick=)
+*  and replaces them with in*=
+*  Essentially this will cause onBlur to become inBlur, onFocus to be  
inFocus
+*  These are not valid javascript events and the browser will ignore them.
+* @param    string  $Message    Text to filter
+* @return   string  $Message with javascript filtered
+* @see  COM_checkWords
+* @see  COM_checkHTML
+*
+*/
+
+function COM_killJS( $Message )
+{
+    return( preg_replace( '/(\s)+[oO][nN](\w*) ?=/', '\1in\2=', $Message  
));
+}
+
+/**
+* Handles the part within a [code] ... [/code] section, i.e. escapes all
+* special characters.
+*
+* @param   string  $str  the code section to encode
+* @return  string  $str with the special characters encoded
+* @see     COM_checkHTML
+*
+*/
+function COM_handleCode( $str )
+{
+    $search  = array( '&',     '\\',    '<',    '>',    '[',     ']'     );
+    $replace = array( '&amp;', '&#92;', '&lt;', '&gt;', '&#91;', '&#93;' );
+
+    $str = str_replace( $search, $replace, $str );
+
+    return( $str );
+}
+
+/**
+* This function checks html tags.
+*
+* Checks to see that the HTML tags are on the approved list and
+* removes them if not.
+*
+* @param    string  $str            HTML to check
+* @param    string  $permissions    comma-separated list of rights which  
identify the current user as an "Admin"
+* @return   string                  Filtered HTML
+*
+*/
+function COM_checkHTML( $str, $permissions = 'story.edit' )
+{
+    global $_CONF;
+
+    // replace any \ with &#092; (HTML equiv)
+    $str = str_replace('\\', '&#092;', COM_stripslashes($str) );
+
+    // Get rid of any newline characters
+    $str = preg_replace( "/\n/", '', $str );
+
+    // Replace any $ with &#36; (HTML equiv)
+    $str = str_replace( '$', '&#36;', $str );
+    // handle [code] ... [/code]
+    do
+    {
+        $start_pos = MBYTE_strpos( MBYTE_strtolower( $str ), '[code]' );
+        if( $start_pos !== false )
+        {
+            $end_pos = MBYTE_strpos( MBYTE_strtolower( $str ), '[/code]' );
+            if( $end_pos !== false )
+            {
+                $encoded = COM_handleCode( MBYTE_substr( $str, $start_pos  
+ 6,
+                        $end_pos - ( $start_pos + 6 )));
+                $encoded = '<pre><code>' . $encoded . '</code></pre>';
+                $str = MBYTE_substr( $str, 0, $start_pos ) . $encoded
+                     . MBYTE_substr( $str, $end_pos + 7 );
+            }
+            else // missing [/code]
+            {
+                // Treat the rest of the text as code (so as not to lose  
any
+                // special characters). However, the calling entity should
+                // better be checking for missing [/code] before calling  
this
+                // function ...
+                $encoded = COM_handleCode( MBYTE_substr( $str, $start_pos  
+ 6 ));
+                $encoded = '<pre><code>' . $encoded . '</code></pre>';
+                $str = MBYTE_substr( $str, 0, $start_pos ) . $encoded;
+            }
+        }
+    }
+    while( $start_pos !== false );
+
+    // handle [raw] ... [/raw]
+    do
+    {
+        $start_pos = MBYTE_strpos( MBYTE_strtolower( $str ), '[raw]' );
+        if( $start_pos !== false )
+        {
+            $end_pos = MBYTE_strpos( MBYTE_strtolower( $str ), '[/raw]' );
+            if( $end_pos !== false )
+            {
+                $encoded = COM_handleCode( MBYTE_substr( $str, $start_pos  
+ 5,
+                        $end_pos - ( $start_pos + 5 )));
+                // [raw2] to avoid infinite loop. Not HTML comment as we  
strip
+                // them later.
+                $encoded = '[raw2]' . $encoded . '[/raw2]';
+                $str = MBYTE_substr( $str, 0, $start_pos ) . $encoded
+                     . MBYTE_substr( $str, $end_pos + 6 );
+            }
+            else // missing [/raw]
+            {
+                // Treat the rest of the text as raw (so as not to lose any
+                // special characters). However, the calling entity should
+                // better be checking for missing [/raw] before calling  
this
+                // function ...
+                $encoded = COM_handleCode( MBYTE_substr( $str, $start_pos  
+ 5 ));
+                // [raw2] to avoid infinite loop. Not HTML comment as we  
strip
+                // them later.
+                $encoded = '[raw2]' . $encoded . '[/raw2]';
+                $str = MBYTE_substr( $str, 0, $start_pos ) . $encoded;
+            }
+        }
+    }
+    while( $start_pos !== false );
+
+    if( isset( $_CONF['skip_html_filter_for_root'] ) &&
+             ( $_CONF['skip_html_filter_for_root'] == 1 ) &&
+            SEC_inGroup( 'Root' ))
+    {
+        return $str;
+    }
+
+    // strip_tags() gets confused by HTML comments ...
+    $str = preg_replace( '/<!--.+?-->/', '', $str );
+
+    $filter = new kses4;
+    if( isset( $_CONF['allowed_protocols'] ) && is_array(  
$_CONF['allowed_protocols'] ) && ( sizeof( $_CONF['allowed_protocols'] ) >  
0 ))
+    {
+        $filter->SetProtocols( $_CONF['allowed_protocols'] );
+    }
+    else
+    {
+        $filter->SetProtocols( array( 'http:', 'https:', 'ftp:' ));
+    }
+
+    if( empty( $permissions) || !SEC_hasRights( $permissions ) ||
+            empty( $_CONF['admin_html'] ))
+    {
+        $html = $_CONF['user_html'];
+    }
+    else
+    {
+        $html = array_merge_recursive( $_CONF['user_html'],
+                                       $_CONF['admin_html'] );
+    }
+
+    foreach( $html as $tag => $attr )
+    {
+        $filter->AddHTML( $tag, $attr );
+    }
+    /* Replace [raw][/raw] with <!--raw--><!--/raw-->, note done "late"  
because
+     * of the above noted // strip_tags() gets confused by HTML  
comments ...
+     */
+    $str = $filter->Parse( $str );
+    $str = str_replace('[raw2]','<!--raw--><span class="raw">', $str);
+    $str = str_replace('[/raw2]','</span><!--/raw-->', $str);
+    return $str;
+}
+
+/**
+* undo function for htmlspecialchars()
+*
+* This function translates HTML entities created by htmlspecialchars() back
+* into their ASCII equivalents. Also handles the entities for $, {, and }.
+*
+* @param    string   $string   The string to convert.
+* @return   string   The converted string.
+*
+*/
+function COM_undoSpecialChars( $string )
+{
+    $string = str_replace( '&#36;',  '$', $string );
+    $string = str_replace( '&#123;', '{', $string );
+    $string = str_replace( '&#125;', '}', $string );
+    $string = str_replace( '&gt;',   '>', $string );
+    $string = str_replace( '&lt;',   '<', $string );
+    $string = str_replace( '&quot;', '"', $string );
+    $string = str_replace( '&nbsp;', ' ', $string );
+    $string = str_replace( '&amp;',  '&', $string );
+
+    return( $string );
+}
+
+/**
+* Makes an ID based on current date/time
+*
+* This function creates a 17 digit sid for stories based on the 14 digit  
date
+* and a 3 digit random number that was seeded with the number of  
microseconds
+* (.000001th of a second) since the last full second.
+* NOTE: this is now used for more than just stories!
+*
+* @return   string  $sid  Story ID
+*
+*/
+
+function COM_makesid()
+{
+    $sid = date( 'YmdHis' );
+    srand(( double ) microtime() * 1000000 );
+    $sid .= rand( 0, 999 );
+
+    return $sid;
+}
+
+/**
+* Checks to see if email address is valid.
+*
+* This function checks to see if an email address is in the correct from.
+*
+* @param    string    $email   Email address to verify
+* @return   boolean            True if valid otherwise false
+*
+*/
+function COM_isEmail( $email )
+{
+    require_once( 'Mail/RFC822.php' );
+
+    $rfc822 = new Mail_RFC822;
+
+    return( $rfc822->isValidInetAddress( $email ) ? true : false );
+}
+
+
+/**
+* Encode a string such that it can be used in an email header
+*
+* @param    string  $string     the text to be encoded
+* @return   string              encoded text
+*
+*/
+function COM_emailEscape( $string )
+{
+    global $_CONF;
+
+    if (function_exists('CUSTOM_emailEscape')) {
+        return CUSTOM_emailEscape($string);
+    }
+
+    $charset = COM_getCharset();
+    if(( $charset == 'utf-8' ) && ( $string != utf8_decode( $string )))
+    {
+        if( function_exists( 'iconv_mime_encode' ))
+        {
+            $mime_parameters = array( 'input-charset'  => 'utf-8',
+                                      'output-charset' => 'utf-8',
+                                      // 'Q' encoding is more readable  
than 'B'
+                                      'scheme'         => 'Q'
+                                    );
+            $string = substr( iconv_mime_encode( '', $string,
+                                                 $mime_parameters ), 2 );
+        }
+        else
+        {
+            $string = '=?' . $charset . '?B?' . base64_encode( $string  
) . '?=';
+        }
+    }
+    else if( preg_match( '/[^0-9a-z\-\.,:;\?! ]/i', $string ))
+    {
+        $string = '=?' . $charset . '?B?' . base64_encode( $string  
) . '?=';
+    }
+
+    return $string;
+}
+
+/**
+* Takes a name and an email address and returns a string that vaguely
+* resembles an email address specification conforming to RFC(2)822 ...
+*
+* @param    string  $name       name, e.g. John Doe
+* @param    string  $address    email address only, e.g.  
john.****@examp*****
+* @return   string              formatted email address
+*
+*/
+function COM_formatEmailAddress( $name, $address )
+{
+    if (function_exists('CUSTOM_formatEmailAddress')) {
+        return CUSTOM_formatEmailAddress($name, $address);
+    }
+
+    $formatted_name = COM_emailEscape( $name );
+
+    // if the name comes back unchanged, it's not UTF-8, so preg_match is  
fine
+    if(( $formatted_name == $name ) && preg_match( '/[^0-9a-z ]/i', $name  
))
+    {
+        $formatted_name = str_replace( '"', '\\"', $formatted_name );
+        $formatted_name = '"' . $formatted_name . '"';
+    }
+
+    return $formatted_name . ' <' . $address . '>';
+}
+
+/**
+* Send an email.
+*
+* All emails sent by Geeklog are sent through this function now.
+*
+* @param    string      $to         recipients name and email address
+* @param    string      $subject    subject of the email
+* @param    string      $message    the text of the email
+* @param    string      $from       (optional) sender of the the email
+* @param    boolean     $html       (optional) true if to be sent as HTML  
email
+* @param    int         $priority   (optional) add X-Priority header, if >  
0
+* @param    string      $cc         (optional) other recipients (name +  
email)
+* @return   boolean                 true if successful,  otherwise false
+*
+* @note Please note that using the $cc parameter will expose the email  
addresses
+*       of all recipients. Use with care.
+*
+*/
+function COM_mail( $to, $subject, $message, $from = '', $html = false,  
$priority = 0, $cc = '' )
+{
+    global $_CONF;
+
+    static $mailobj;
+
+    if( empty( $from ))
+    {
+        $from = COM_formatEmailAddress( $_CONF['site_name'],  
$_CONF['site_mail']);
+    }
+
+    $to = substr( $to, 0, strcspn( $to, "\r\n" ));
+    $cc = substr( $cc, 0, strcspn( $cc, "\r\n" ));
+    $from = substr( $from, 0, strcspn( $from, "\r\n" ));
+    $subject = substr( $subject, 0, strcspn( $subject, "\r\n" ));
+    $subject = COM_emailEscape( $subject );
+
+    if( function_exists( 'CUSTOM_mail' ))
+    {
+        return CUSTOM_mail( $to, $subject, $message, $from, $html,  
$priority, $cc );
+    }
+
+    include_once( 'Mail.php' );
+    include_once( 'Mail/RFC822.php' );
+
+    $method = $_CONF['mail_settings']['backend'];
+
+    if( !isset( $mailobj ))
+    {
+        if(( $method == 'sendmail' ) || ( $method == 'smtp' ))
+        {
+            $mailobj =& Mail::factory( $method, $_CONF['mail_settings'] );
+        }
+        else
+        {
+            $method = 'mail';
+            $mailobj =& Mail::factory( $method );
+        }
+    }
+
+    $charset = COM_getCharset();
+    $headers = array();
+
+    $headers['From'] = $from;
+    if( $method != 'mail' )
+    {
+        $headers['To'] = $to;
+    }
+    if( !empty( $cc ))
+    {
+        $headers['Cc'] = $cc;
+    }
+    $headers['Date'] = date( 'r' ); // RFC822 formatted date
+    if( $method == 'smtp' )
+    {
+        list( $usec, $sec ) = explode( ' ', microtime());
+        $m = substr( $usec, 2, 5 );
+        $headers['Message-Id'] = '<' .  date( 'YmdHis' ) . '.' . $m
+                               . '@' .  
$_CONF['mail_settings']['host'] . '>';
+    }
+    if( $html )
+    {
+        $headers['Content-Type'] = 'text/html; charset=' . $charset;
+        $headers['Content-Transfer-Encoding'] = '8bit';
+    }
+    else
+    {
+        $headers['Content-Type'] = 'text/plain; charset=' . $charset;
+    }
+    $headers['Subject'] = $subject;
+    if( $priority > 0 )
+    {
+        $headers['X-Priority'] = $priority;
+    }
+    $headers['X-Mailer'] = 'Geeklog ' . VERSION;
+
+    if (!empty($_SERVER['REMOTE_ADDR']) && !empty($_SERVER['SERVER_ADDR'])  
&&
+            ($_SERVER['REMOTE_ADDR'] != $_SERVER['SERVER_ADDR'])) {
+        $url = COM_getCurrentURL();
+        if (substr($url, 0, strlen($_CONF['site_admin_url']))
+                != $_CONF['site_admin_url']) {
+            $headers['X-Originating-IP'] = $_SERVER['REMOTE_ADDR'];
+        }
+    }
+
+    $retval = $mailobj->send( $to, $headers, $message );
+    if( $retval !== true )
+    {
+        COM_errorLog( $retval->toString(), 1 );
+    }
+
+    return( $retval === true ? true : false );
+}
+
+
+/**
+* Creates older stuff block
+*
+* Creates the olderstuff block for display.
+* Actually updates the olderstuff record in the gl_blocks database.
+* @return   void
+*/
+
+function COM_olderStuff()
+{
+    global $_TABLES, $_CONF;
+
+    $sql = "SELECT sid,tid,title,comments,UNIX_TIMESTAMP(date) AS day FROM  
{$_TABLES['stories']} WHERE (perm_anon = 2) AND (frontpage = 1) AND (date  
<= NOW()) AND (draft_flag = 0)" . COM_getTopicSQL( 'AND', 1 ) . " ORDER BY  
featured DESC, date DESC LIMIT {$_CONF['limitnews']},  
{$_CONF['limitnews']}";
+    $result = DB_query( $sql );
+    $nrows = DB_numRows( $result );
+
+    if( $nrows > 0 )
+    {
+        $dateonly = $_CONF['dateonly'];
+        if( empty( $dateonly ))
+        {
+            $dateonly = '%d-%b'; // fallback: day - abbrev. month name
+        }
+
+        $day = 'noday';
+        $string = '';
+
+        for( $i = 0; $i < $nrows; $i++ )
+        {
+            $A = DB_fetchArray( $result );
+
+            $daycheck = strftime( '%A', $A['day'] );
+            if( $day != $daycheck )
+            {
+                if( $day != 'noday' )
+                {
+                    $daylist = COM_makeList(  
$oldnews, 'list-older-stories' );
+                    $daylist = preg_replace( "/(\015\012)|(\015)|(\012)/",
+                                             '', $daylist );
+                    $string .= $daylist . '<br' . XHTML . '>';
+                }
+
+                $day2 = strftime( $dateonly, $A['day'] );
+                $string .= '<h3>' . $daycheck . ' <small>' . $day2
+                        . '</small></h3>' . LB;
+                $oldnews = array();
+                $day = $daycheck;
+            }
+
+            $oldnews_url = COM_buildUrl(  
$_CONF['site_url'] . '/article.php?story='
+                . $A['sid'] );
+            $oldnews[] = COM_createLink($A['title'], $oldnews_url)
+                .' (' . COM_numberFormat( $A['comments'] ) . ')';
+        }
+
+        if( !empty( $oldnews ))
+        {
+            $daylist = COM_makeList( $oldnews, 'list-older-stories' );
+            $daylist = preg_replace( "/(\015\012)|(\015)|(\012)/", '',  
$daylist );
+            $string .= $daylist;
+            $string = addslashes( $string );
+
+            DB_query( "UPDATE {$_TABLES['blocks']} SET content = '$string'  
WHERE name = 'older_stories'" );
+        }
+    }
+}
+
+/**
+* Shows a single Geeklog block
+*
+* This shows a single block and is typically called from
+* COM_showBlocks OR from plugin code
+*
+* @param        string      $name       Logical name of block (not same as  
title) -- 'user_block', 'admin_block', 'section_block', 'whats_new_block'.
+* @param        string      $help       Help file location
+* @param        string      $title      Title shown in block header
+* @param        string      $position   Side, 'left', 'right' or empty.
+* @see function COM_showBlocks
+* @return   string  HTML Formated block
+*
+*/
+
+function COM_showBlock( $name, $help='', $title='', $position='' )
+{
+    global $_CONF, $topic, $_TABLES, $_USER;
+
+    $retval = '';
+
+    if( !isset( $_USER['noboxes'] ))
+    {
+        if( !COM_isAnonUser() )
+        {
+            $_USER['noboxes'] = DB_getItem(  
$_TABLES['userindex'], 'noboxes',
+                                            "uid = {$_USER['uid']}" );
+        }
+        else
+        {
+            $_USER['noboxes'] = 0;
+        }
+    }
+
+    switch( $name )
+    {
+        case 'user_block':
+            $retval .= COM_userMenu( $help,$title, $position );
+            break;
+
+        case 'admin_block':
+            $retval .= COM_adminMenu( $help,$title, $position );
+            break;
+
+        case 'section_block':
+            $retval .= COM_startBlock( $title, $help,
+                               COM_getBlockTemplate( $name, 'header',  
$position ))
+                . COM_showTopics( $topic )
+                . COM_endBlock( COM_getBlockTemplate( $name, 'footer',  
$position ));
+            break;
+
+        case 'whats_new_block':
+            if( !$_USER['noboxes'] )
+            {
+                $retval .= COM_whatsNewBlock( $help, $title, $position );
+            }
+            break;
+    }
+
+    return $retval;
+}
+
+
+/**
+* Shows Geeklog blocks
+*
+* Returns HTML for blocks on a given side and, potentially, for
+* a given topic. Currentlly only used by static pages.
+*
+* @param        string      $side       Side to get blocks for (right or  
left for now)
+* @param        string      $topic      Only get blocks for this topic
+* @param        string      $name       Block name (not used)
+* @see function COM_showBlock
+* @return   string  HTML Formated blocks
+*
+*/
+
+function COM_showBlocks( $side, $topic='', $name='all' )
+{
+    global $_CONF, $_TABLES, $_USER, $LANG21, $topic, $page;
+
+    $retval = '';
+
+    // Get user preferences on blocks
+    if( !isset( $_USER['noboxes'] ) || !isset( $_USER['boxes'] ))
+    {
+        if( !COM_isAnonUser() )
+        {
+            $result = DB_query( "SELECT boxes,noboxes FROM  
{$_TABLES['userindex']} "
+                               ."WHERE uid = '{$_USER['uid']}'" );
+            list($_USER['boxes'], $_USER['noboxes']) = DB_fetchArray(  
$result );
+        }
+        else
+        {
+            $_USER['boxes'] = '';
+            $_USER['noboxes'] = 0;
+        }
+    }
+
+    $blocksql['mssql']  = "SELECT bid, is_enabled, name, type, title, tid,  
blockorder, cast(content as text) as content, ";
+    $blocksql['mssql'] .= "rdfurl, rdfupdated, rdflimit, onleft,  
phpblockfn, help, owner_id, ";
+    $blocksql['mssql'] .= "group_id, perm_owner, perm_group, perm_members,  
perm_anon, allow_autotags,UNIX_TIMESTAMP(rdfupdated) AS date ";
+
+    $blocksql['mysql'] = "SELECT *,UNIX_TIMESTAMP(rdfupdated) AS date ";
+
+    $commonsql = "FROM {$_TABLES['blocks']} WHERE is_enabled = 1";
+
+    if( $side == 'left' )
+    {
+        $commonsql .= " AND onleft = 1";
+    }
+    else
+    {
+        $commonsql .= " AND onleft = 0";
+    }
+
+    if( !empty( $topic ))
+    {
+        $commonsql .= " AND (tid = '$topic' OR tid = 'all')";
+    }
+    else
+    {
+        if( COM_onFrontpage() )
+        {
+            $commonsql .= " AND (tid = 'homeonly' OR tid = 'all')";
+        }
+        else
+        {
+            $commonsql .= " AND (tid = 'all')";
+        }
+    }
+
+    if( !empty( $_USER['boxes'] ))
+    {
+        $BOXES = str_replace( ' ', ',', $_USER['boxes'] );
+
+        $commonsql .= " AND (bid NOT IN ($BOXES) OR bid = '-1')";
+    }
+
+    $commonsql .= ' ORDER BY blockorder,title ASC';
+
+    $blocksql['mysql'] .= $commonsql;
+    $blocksql['mssql'] .= $commonsql;
+    $result = DB_query( $blocksql );
+    $nrows = DB_numRows( $result );
+
+    // convert result set to an array of associated arrays
+    $blocks = array();
+    for( $i = 0; $i < $nrows; $i++ )
+    {
+        $blocks[] = DB_fetchArray( $result );
+    }
+
+    // Check and see if any plugins have blocks to show
+    $pluginBlocks = PLG_getBlocks( $side, $topic, $name );
+    $blocks = array_merge( $blocks, $pluginBlocks );
+
+    // sort the resulting array by block order
+    $column = 'blockorder';
+    $sortedBlocks = $blocks;
+    $num_sortedBlocks = sizeof( $sortedBlocks );
+    for( $i = 0; $i < $num_sortedBlocks - 1; $i++ )
+    {
+        for( $j = 0; $j < $num_sortedBlocks - 1 - $i; $j++ )
+        {
+            if( $sortedBlocks[$j][$column] > $sortedBlocks[$j+1][$column] )
+            {
+                $tmp = $sortedBlocks[$j];
+                $sortedBlocks[$j] = $sortedBlocks[$j + 1];
+                $sortedBlocks[$j + 1] = $tmp;
+            }
+        }
+    }
+    $blocks = $sortedBlocks;
+
+    // Loop though resulting sorted array and pass associative arrays
+    // to COM_formatBlock
+    foreach( $blocks as $A )
+    {
+        if( $A['type'] == 'dynamic' or SEC_hasAccess( $A['owner_id'],  
$A['group_id'], $A['perm_owner'], $A['perm_group'], $A['perm_members'],  
$A['perm_anon'] ) > 0 )
+        {
+           $retval .= COM_formatBlock( $A, $_USER['noboxes'] );
+        }
+    }
+
+    return $retval;
+}
+
+/**
+* Formats a Geeklog block
+*
+* This shows a single block and is typically called from
+* COM_showBlocks OR from plugin code
+*
+* @param        array     $A          Block Record
+* @param        bool      $noboxes    Set to true if userpref is no blocks
+* @return       string    HTML Formated block
+*
+*/
+function COM_formatBlock( $A, $noboxes = false )
+{
+    global $_CONF, $_TABLES, $_USER, $LANG21;
+
+    $retval = '';
+
+    $lang = COM_getLanguageId();
+    if (!empty($lang)) {
+
+        $blocksql['mssql']  = "SELECT bid, is_enabled, name, type, title,  
tid, blockorder, cast(content as text) as content, ";
+        $blocksql['mssql'] .= "rdfurl, rdfupdated, rdflimit, onleft,  
phpblockfn, help, owner_id, ";
+        $blocksql['mssql'] .= "group_id, perm_owner, perm_group,  
perm_members, perm_anon, allow_autotags,UNIX_TIMESTAMP(rdfupdated) AS  
date ";
+
+        $blocksql['mysql'] = "SELECT *,UNIX_TIMESTAMP(rdfupdated) AS  
date ";
+
+        $commonsql = "FROM {$_TABLES['blocks']} WHERE name = '"
+                   . $A['name'] . '_' . $lang . "'";
+
+        $blocksql['mysql'] .= $commonsql;
+        $blocksql['mssql'] .= $commonsql;
+        $result = DB_query( $blocksql );
+
+        if (DB_numRows($result) == 1) {
+            // overwrite with data for language-specific block
+            $A = DB_fetchArray($result);
+        }
+    }
+
+    if( array_key_exists( 'onleft', $A ) )
+    {
+        if( $A['onleft'] == 1 )
+        {
+            $position = 'left';
+        } else {
+            $position = 'right';
+        }
+    } else {
+        $position = '';
+    }
+
+    if( $A['type'] == 'portal' )
+    {
+        if( COM_rdfCheck( $A['bid'], $A['rdfurl'], $A['date'],  
$A['rdflimit'] ))
+        {
+            $A['content'] = DB_getItem( $_TABLES['blocks'], 'content',
+                                        "bid = '{$A['bid']}'");
+        }
+    }
+
+    if( $A['type'] == 'gldefault' )
+    {
+        $retval .= COM_showBlock( $A['name'], $A['help'], $A['title'],  
$position );
+    }
+
+    if( $A['type'] == 'phpblock' && !$noboxes )
+    {
+        if( !( $A['name'] == 'whosonline_block' AND DB_getItem(  
$_TABLES['blocks'], 'is_enabled', "name='whosonline_block'" ) == 0 ))
+        {
+            $function = $A['phpblockfn'];
+            $matches = array();
+            if (preg_match('/^(phpblock_\w*)\\((.*)\\)$/', $function,  
$matches) == 1)
+            {
+                $function = $matches[1];
+                $args = $matches[2];
+            }
+            $blkheader = COM_startBlock( $A['title'], $A['help'],
+                    COM_getBlockTemplate( $A['name'], 'header', $position  
));
+            $blkfooter = COM_endBlock( COM_getBlockTemplate( $A['name'],
+                    'footer', $position ));
+
+            if( function_exists( $function ))
+            {
+               if (isset($args))
+               {
+                    $fretval = $function($A, $args);
+               } else {
+                    $fretval = $function();
+               }
+               if( !empty( $fretval ))
+               {
+                    $retval .= $blkheader;
+                    $retval .= $fretval;
+                    $retval .= $blkfooter;
+               }
+            }
+            else
+            {
+                // show error message
+                $retval .= $blkheader;
+                $retval .= sprintf( $LANG21[31], $function );
+                $retval .= $blkfooter;
+            }
+        }
+    }
+
+    if( !empty( $A['content'] ) && ( trim( $A['content'] ) != '' )  
&& !$noboxes )
+    {
+        $blockcontent = stripslashes( $A['content'] );
+
+        // Hack: If the block content starts with a '<' assume it
+        // contains HTML and do not call nl2br() which would only add
+        // unwanted <br> tags.
+
+        if( substr( $blockcontent, 0, 1 ) != '<' )
+        {
+            $blockcontent = nl2br( $blockcontent );
+        }
+
+        // autotags are only(!) allowed in normal blocks
+        if(( $A['allow_autotags'] == 1 ) && ( $A['type'] == 'normal' ))
+        {
+            $blockcontent = PLG_replaceTags( $blockcontent );
+        }
+        $blockcontent = str_replace( array( '<?', '?>' ), '',  
$blockcontent );
+
+        $retval .= COM_startBlock( $A['title'], $A['help'],
+                       COM_getBlockTemplate( $A['name'], 'header',  
$position ))
+                . $blockcontent . LB
+                . COM_endBlock( COM_getBlockTemplate(  
$A['name'], 'footer', $position ));
+    }
+
+    return $retval;
+}
+
+
+/**
+* Checks to see if it's time to import and RDF/RSS block again
+*
+* Updates RDF/RSS block if needed
+*
+* @param    string  $bid            Block ID
+* @param    string  $rdfurl         URL to get headlines from
+* @param    string  $date           Last time the headlines were imported
+* @param    string  $maxheadlines   max. number of headlines to import
+* @return   void
+* @see function COM_rdfImport
+*
+*/
+function COM_rdfCheck( $bid, $rdfurl, $date, $maxheadlines = 0 )
+{
+    $retval = false;
+    $nextupdate = $date + 3600;
+
+    if( $nextupdate < time() )
+    {
+        COM_rdfImport( $bid, $rdfurl, $maxheadlines );
+        $retval = true;
+    }
+
+    return $retval;
+}
+
+/**
+* Syndication import function. Imports headline data to a portal block.
+*
+* Rewritten December 19th 2004 by Michael Jervis  
(mike@*censored*ingbrit.com). Now
+* utilises a Factory Pattern to open a URL and automaticaly retreive a feed
+* object populated with feed data. Then import it into the portal block.
+*
+* @param    string  $bid            Block ID
+* @param    string  $rdfurl         URL to get content from
+* @param    int     $maxheadlines   Maximum number of headlines to display
+* @return   void
+* @see function COM_rdfCheck
+*
+*/
+function COM_rdfImport($bid, $rdfurl, $maxheadlines = 0)
+{
+    global $_CONF, $_TABLES, $LANG21;
+
+    // Import the feed handling classes:
+    require_once $_CONF['path_system']
+                 . '/classes/syndication/parserfactory.class.php';
+    require_once $_CONF['path_system']
+                 . '/classes/syndication/feedparserbase.class.php';
+
+    $result = DB_query("SELECT rdf_last_modified, rdf_etag FROM  
{$_TABLES['blocks']} WHERE bid = $bid");
+    list($last_modified, $etag) = DB_fetchArray($result);
+
+    // Load the actual feed handlers:
+    $factory = new FeedParserFactory($_CONF['path_system']
+                                     . '/classes/syndication/');
+    $factory->userAgent = 'Geeklog/' . VERSION;
+    if (!empty($last_modified) && !empty($etag)) {
+        $factory->lastModified = $last_modified;
+        $factory->eTag = $etag;
+    }
+
+    // Aquire a reader:
+    $feed = $factory->reader($rdfurl, $_CONF['default_charset']);
+
+    if ($feed) {
+        /* We have located a reader, and populated it with the information  
from
+         * the syndication file. Now we will sort out our display, and  
update
+         * the block.
+         */
+        if ($maxheadlines == 0) {
+            if (!empty($_CONF['syndication_max_headlines'])) {
+                $maxheadlines = $_CONF['syndication_max_headlines'];
+            } else {
+                $maxheadlines = count($feed->articles);
+            }
+        }
+
+        $update = date('Y-m-d H:i:s');
+        $last_modified = '';
+        if (!empty($factory->lastModified)) {
+            $last_modified = addslashes($factory->lastModified);
+        }
+        $etag = '';
+        if (!empty($factory->eTag)) {
+            $etag = addslashes($factory->eTag);
+        }
+
+        if (empty($last_modified) || empty($etag)) {
+            DB_query("UPDATE {$_TABLES['blocks']} SET rdfupdated  
= '$update', rdf_last_modified = NULL, rdf_etag = NULL WHERE bid = '$bid'");
+        } else {
+            DB_query("UPDATE {$_TABLES['blocks']} SET rdfupdated  
= '$update', rdf_last_modified = '$last_modified', rdf_etag = '$etag' WHERE  
bid = '$bid'");
+        }
+
+        $charset = COM_getCharset();
+
+        // format articles for display
+        $readmax = min($maxheadlines, count($feed->articles));
+        for ($i = 0; $i < $readmax; $i++) {
+            if (empty($feed->articles[$i]['title'])) {
+                $feed->articles[$i]['title'] = $LANG21[61];
+            }
+
+            if ($charset == 'utf-8') {
+                $title = $feed->articles[$i]['title'];
+            } else {
+                $title = utf8_decode($feed->articles[$i]['title']);
+            }
+            if ($feed->articles[$i]['link'] != '') {
+                $content = COM_createLink($title,  
$feed->articles[$i]['link']);
+            } elseif ($feed->articles[$i]['enclosureurl'] != '') {
+                $content = COM_createLink($title,  
$feed->articles[$i]['enclosureurl']);
+            } else {
+                $content = $title;
+            }
+            $articles[] = $content;
+        }
+
+        // build a list
+        $content = COM_makeList($articles, 'list-feed');
+        $content = preg_replace("/(\015\012)|(\015)|(\012)/", '',  
$content);
+
+        if (strlen($content) > 65000) {
+            $content = $LANG21[68];
+        }
+
+        // Standard theme based function to put it in the block
+        $result = DB_change($_TABLES['b

==============================================================================
Diff truncated at 200k characters




Geeklogjp-changes メーリングリストの案内
Zurück zum Archiv-Index