Source for file mvblog.php

Documentation is available at mvblog.php

  1. <?php
  2. /**
  3.  * MvBlog -- An open source no-nosense blogtool
  4.  *
  5.  * Copyright (C) 2005-2007, Michiel van Baak
  6.  * Michiel van Baak <mvanbaak@users.sourceforge.net>
  7.  *
  8.  * See http://www.mvblog.org for more information on MvBlog.
  9.  * That page also provides Bugtrackers, Filereleases etc.
  10.  *
  11.  * This program is free software, distributed under the terms of
  12.  * the GNU General Public License Version 2. See the LICENSE file
  13.  * at the top of the source tree.
  14.  *
  15.  * @package MvBlog
  16.  * @author Michiel van Baak
  17.  * @version %%VERSION%%
  18.  * @copyright 2005-2007 Michiel van Baak
  19.  */
  20.  
  21. /*
  22.  * Start the autoloader, so we never have to include anything
  23.  */
  24. require_once("mvblog_autoloader.php");
  25. $mvblog_AutoLoader new mvblog_AutoLoader();
  26.  
  27. $pathInfo pathinfo(__FILE__);
  28. $mvblog_AutoLoader->registerPath($pathInfo["dirname"]"%s.php"mvblog_AutoLoader::OPT_LOWERCASE);
  29.  
  30. // Register the AutoLoader object as the autoloader.
  31. function __autoload($className{
  32.   global $mvblog_AutoLoader;
  33.   $mvblog_AutoLoader->autoload($className);
  34. }
  35.  
  36. /* Start heavy error reporting if we're on a dev site */
  37.  
  38. /* Read the configuration file */
  39. $configfile dirname(dirname(__FILE__)."../")."/conf/mvblog.ini";
  40. $availSettings array(
  41.     "general" => array(
  42.         "debug"    => array("type" => mvblog_IniFileReader::TYPE_BOOL,   "default" => "no"),
  43.     ),
  44.     "database" => array(
  45.         "database" => array("type" => mvblog_IniFileReader::TYPE_STRING"default" => "mvblog"),
  46.         "hostname" => array("type" => mvblog_IniFileReader::TYPE_STRING"default" => "localhost"),
  47.         "username" => array("type" => mvblog_IniFileReader::TYPE_STRING"default" => "mvblog"),
  48.         "password" => array("type" => mvblog_IniFileReader::TYPE_STRING"default" => "mvblog"),
  49.         "type"     => array("type" => mvblog_IniFileReader::TYPE_STRING"default" => "mysql"),
  50.     ),
  51. );
  52. $config new mvblog_IniFileReader($availSettings$configfile);
  53.  
  54. /**
  55.  * Class that holds methods to create public site.
  56.  * @package MvBlog
  57.  */
  58. Class MvBlog extends MvBlog_common {
  59.  
  60.     /* contstants */
  61.  
  62.     /* variables */
  63.     /**
  64.      * @var string $lang Language of blog. Can be en_US or nl_NL for now
  65.      */
  66.     public $lang       = "en_US";
  67.     /* }}} */
  68.  
  69.     /* methods */
  70.  
  71.     /* __construct {{{ */
  72.     /**
  73.      * Constructor to set some defaults
  74.      *
  75.      * @param string $basedir If set use this directory where MvBlog is located.
  76.      */
  77.     public function __construct ($basedir=""{
  78.         parent::__construct($basedir."plugins/");
  79.     }
  80.     /* }}} */
  81.     /* check_admin_logged_in() {{{ */
  82.     /**
  83.      * Check to see if the admin session is set
  84.      */
  85.     public function check_admin_logged_in({
  86.         if (!$_SESSION["author_id"]{
  87.             header("Location: login.php");
  88.         }
  89.     }
  90.     /* }}} */
  91.     /* blog_get_title() {{{ */
  92.     /**
  93.      * get the blog title.
  94.      *
  95.      * @return string title or "blog" if no title set
  96.      */
  97.     public function blog_get_title({
  98.         if ($this->settings["blogtitle"]{
  99.             $title stripslashes($this->settings["blogtitle"]);
  100.         else {
  101.             $title "blog";
  102.         }
  103.         return $title;
  104.     }
  105.     /* }}} */
  106.     /* blog_get_description() {{{ */
  107.     /**
  108.      * Get blogsetting description from database
  109.      *
  110.      * @return string The blogdescription
  111.      */
  112.     public function blog_get_description({
  113.         if ($this->settings["blogdescription"]{
  114.             $pagedescription nl2br(stripslashes($this->settings["blogdescription"]));
  115.         else {
  116.             $pagedescription "";
  117.         }
  118.         return $pagedescription;
  119.     }
  120.     /* }}} */
  121.     /* blog_content($start, $limit) {{{ */
  122.     /**
  123.      *  main function to give user correct html depending on action etc
  124.      *
  125.      * @param int $start (optional) Start entry in recordset
  126.      * @param int $limit (optional) Number of records to show
  127.      */
  128.     public function blog_content($start=0$limit=0{
  129.         /* get limit from database, when no limit given by function call */
  130.         if (!$limit{
  131.             if ($this->settings["postsperpage"]{
  132.                 $limit $this->settings["postsperpage"];
  133.             else {
  134.                 /* fall back to something sane if none found. fixes issue #25 */
  135.                 /* FB: 20070304: This shouldn't happen anymore, as there are now
  136.                                  default settings in MvBlog_common::_get_settings().
  137.                                  Keeping it anyway just to be sure/
  138.                 */
  139.                 $limit 20;
  140.             }
  141.         }
  142.         // FB: 20070304: Check if key exists and strstr->strpos()
  143.         // if (strstr($_REQUEST["action"], "view/")) {
  144.         if (array_key_exists("action"$_REQUEST&& strpos($_REQUEST["action"]"view/"!== false{
  145.             $_REQUEST["id"= (int)substr($_REQUEST["action"],5);
  146.             $_REQUEST["action""view";
  147.         }
  148.  
  149.         // Determine the action.
  150.         if (array_key_exists("action"$_REQUEST)) {
  151.             $action $_REQUEST["action"];
  152.         else {
  153.             $action ""// Will be handled by the 'default' case in the switch below.
  154.         }
  155.         switch ($action{
  156.             /* user related functions */
  157.             //this one is here for backward compatibiliy. Can be removed in release 4
  158.             case "register_confirm" $this->user_confirm();         break;
  159.             //new user actions
  160.             case "user_confirm"  $this->user_confirm();            break;
  161.             case "user_save"     $this->user_save();               break;
  162.             case "user_new"      $this->user_edit(1);              break;
  163.             case "user_login"    :
  164.                 if (array_key_exists("user"$_REQUEST&& $this->user_login($_REQUEST["user"])) {
  165.                     $this->get_articles($start$limit);
  166.                 else {
  167.                     echo gettext("wrong username/pass");
  168.                 }
  169.                 break;
  170.             case "user_settings" $this->user_edit(0);                break;
  171.             /* article related functions */
  172.             case "view"         $this->show_article($_REQUEST["id"]);      break;
  173.             case "viewdossier"  $this->get_articles($start$limit0$_REQUEST["id"]);      break;
  174.             case "post_comment" $this->post_comment($_POST);               break;
  175.             case "rss"          header("Location: common/rss.php");        break;
  176.             case "archive"      $this->get_articles($start$limit1);    break;
  177.             case "archive_old"  $this->get_articles($start$limit4);    break;
  178.             case "archive_cat"  :
  179.                 if (array_key_exists("c"$_REQUEST&& $_REQUEST["c"== "aside"{
  180.                     $this->get_articles($start$limit3);
  181.                 else {
  182.                     $this->get_articles($start$limit2);
  183.                 }
  184.                 break;
  185.             default             $this->get_articles($start$limit);       break;
  186.         }
  187.     }
  188.     /* }}} */
  189.     /* get_articles($start, $limit, $archive) {{{ */
  190.     /**
  191.      * show posts in pages or the archive
  192.      *
  193.      * @param int $start the starting point in the recordset
  194.      * @param int $limit the ammount of items to show
  195.      * @param int $archive type of archive. 0 = none, 1 = archive by date, 2 = archive by category, 3 = archive of asides, 4 = old old old
  196.      * @param int $dossier if not 0 show info about dossier
  197.      */
  198.     public function get_articles($start$limit$archive=0$dossier=0{
  199.         // FB: 20070304: Check key and set a default if not set.
  200.         if (array_key_exists("top"$_REQUEST))
  201.             $top $_REQUEST["top"];
  202.  
  203.         if (!isset($top|| empty($top))
  204.             $top 1;
  205.  
  206.         //article url base
  207.         if ($this->settings["cleanurl"])
  208.             $link "post/%d#READMORE";
  209.         else
  210.             $link "index.php?action=view&amp;id=%d#READMORE";
  211.  
  212.         //category url base
  213.         if ($this->settings["cleanurl"])
  214.             $catlink "category/%d";
  215.         else
  216.             $catlink "index.php?action=archive_cat&amp;c=%d";
  217.  
  218.         $start $top-1;
  219.  
  220.         $max_time mktime(000date("m")date("d")+1date("Y"));
  221.  
  222.         $options array(
  223.             "start"              => $start,
  224.             "limit"              => $limit,
  225.             "max_time"           => $max_time,
  226.             "top"                => $top,
  227.             "archive"            => $archive,
  228.             "dossier"            => $dossier,
  229.             "replace_references" => 1
  230.         );
  231.         foreach ($_REQUEST as $k=>$v)
  232.             $options["urlparams"][$k$v;
  233.  
  234.         $posts $this->_get_posts($options);
  235.  
  236.         echo $posts["title"];
  237.  
  238.         if (array_key_exists("desc"$posts))
  239.             echo $posts["desc"];
  240.  
  241.         if ($posts["total_count"]{
  242.             foreach ($posts["posts"as $row{
  243.                 //get number of comments
  244.                 $ccquery sprintf("SELECT COUNT(*) FROM comments WHERE articles_id = %d"$row["id"]);
  245.                 $ccq =$this->db->query($ccquery);
  246.                 $comments_count $ccq->fetchRow();
  247.                 ?>
  248.                 <div class="log_post">
  249.                     <?php if ($row["aside"!=1?>
  250.                         <div class="log_post_head">
  251.                             <h1 class="log_post_h1"><a href="<?php echo sprintf($link$row["id"])?>"><?php echo htmlspecialchars(stripslashes($row["title"]))?></a></h1>
  252.                             <h2 class="log_post_h2"><?php echo gettext("category")?>:&nbsp;
  253.                                 <?php
  254.                                 $categories explode(","$row["categories_ids"]);
  255.                                 foreach ($categories as $v{
  256.                                     if (array_key_exists($v$this->categories&& $this->categories[$v]["icon"&& $this->settings["show_cat_icons"])
  257.                                         echo "<a href=\"".sprintf($catlink$v)."\"><img src=\"images/categories/".$this->categories[$v]["icon"]."\" title=\"".htmlspecialchars($this->categories[$v]["name"])."\" alt=\"".htmlspecialchars($this->categories[$v]["name"])."\" class=\"category_icon\" /></a>&nbsp;";
  258.                                     elseif (array_key_exists($v$this->categories))
  259.                                         echo "<a href=\"".sprintf($catlink$v)."\">".htmlspecialchars($this->categories[$v]["name"])."</a>&nbsp;";
  260.                                 }
  261.                                 ?>
  262.                             </h2>
  263.                         </div>
  264.                     <?php ?>
  265.                     <div class="log_post_body">
  266.                         <?php if ($row["aside"]?>
  267.                             <div class="log_post_aside">
  268.                         <?php else ?>
  269.                             <div class="log_post_normal">
  270.                         <?php ?>
  271.                             <?php
  272.                             $text $this->strip_invalid_xml(stripslashes($row["body"]));
  273.                             $text $this->plugman->run_hooks("text_output"$text);
  274.                             if ($this->limit_text($text)) {
  275.                                 echo $text;
  276.                                 ?><br /><br /><a href="<?php echo sprintf($link$row["id"])?>" class="link_readmore"><?php echo gettext("read more")?></a><?php
  277.                             else {
  278.                                 echo $text;
  279.                             }
  280.                             ?>
  281.                         </div>
  282.                     </div>
  283.                     <div class="log_post_foot">
  284.                         <?php if ($row["aside"!=1?>
  285.                             <span class="log_post_commentslink"><a href="<?php echo sprintf($link$row["id"])?>#comments"><?php echo sprintf(ngettext("%d Comment""%d Comments"$comments_count[0])$comments_count[0])?></a><br /></span>
  286.                             <span class="log_post_author"><?php echo gettext("By").": <i>".htmlspecialchars($this->authors[$row["authors_id"]]["fullname"])?></i></span>
  287.                             <span class="log_post_date">| <?php echo gettext("On").": <i>".date("d-m-Y H:i"$row["date"])?></i></span>
  288.                             <?php if ($row["last_modified"]?>
  289.                                 <span class="log_post_author"><br /><?php echo gettext("Last modified by").": <i>".htmlspecialchars($this->authors[$row["modified_by"]]["fullname"])?></i></span>
  290.                                 <span class="log_post_date">| <?php echo gettext("Last modified on").": <i>".date("d-m-Y H:i"$row["last_modified"])?></i></span>
  291.                             <?php ?>
  292.                         <?php ?>
  293.                     </div>
  294.                 </div>
  295.                 <?php
  296.             }
  297.             if ($limit{
  298.                 echo "<div class=\"log_nextprev_container\">";
  299.                 if ($top 1)
  300.                     echo "<a href=\"".$posts["url_prev"]."\" class=\"link_prev\">".gettext("previous")."</a>&nbsp;&nbsp;";
  301.  
  302.                 if (($start+$limit$posts["total_count"])
  303.                     $end $posts["total_count"];
  304.                 else
  305.                     $end ($start+$limit);
  306.  
  307.                 echo " ".($start+1)."-".$end." (".$posts["total_count"]." ".gettext("total").") ";
  308.                 if (($start+$limit$posts["total_count"])
  309.                     echo "<a href=\"".$posts["url_next"]."\" class=\"link_next\">".gettext("next")."</a>";
  310.  
  311.                 echo "</div>";
  312.             }
  313.         else {
  314.             $adminpage "http://".$_SERVER["SERVER_NAME"].substr($_SERVER["REQUEST_URI"],0,strrpos($_SERVER["REQUEST_URI"],"/"))."/admin/";
  315.             ?>
  316.             <div class="log_post">
  317.                 <div class="log_post_head">
  318.                         <h1 class="log_post_h1">Welcome to MvBlog.</h1>
  319.                 </div>
  320.                 <div class="log_post_body">
  321.                     <div class="log_post_normal">
  322.                         <?php if (array_key_exists("action"$_REQUEST&& !empty($_REQUEST["action"])) ?>
  323.                             There are no posts to show here.
  324.                         <?php else ?>
  325.                             If you see this your install of MvBlog has been succesfull. Congratulations!<br />
  326.                             You can now add your posts etc via de Admin Interface.<br /> Login at <a href="<?php echo $adminpage?>"><?php echo $adminpage?></a>
  327.                         <?php ?>
  328.                     </div>
  329.                 </div>
  330.                 <div class="log_post_foot">
  331.                     <span class="log_post_author"><i>MvBlog system</i></span>
  332.                 </div>
  333.             </div>
  334.             <?php
  335.         }
  336.     }
  337.     /* }}} */
  338.     /* strip_invalid_xml() {{{ */
  339.     /**
  340.      * strip some stuff leftover from old editor
  341.      *
  342.      * @param string $data the text to process
  343.      * @return string the text with invalid xml stripped
  344.      */
  345.     public function strip_invalid_xml($data{
  346.         $data preg_replace("/ ref=\"[^\"].*\"/si"""$data);
  347.         return $data;
  348.     }
  349.     /* }}} */
  350.     /* limit_text($text) {{{ */
  351.     /**
  352.      * limit the length of a message
  353.      *
  354.      * @param string &$text the text to limit in length
  355.      * @return int 1 if truncated, 0 if original string is within limits
  356.      */
  357.     public function limit_text(&$text{
  358.         if (strstr($text"##BREAKPOINT##")) {
  359.             $text substr($text0strpos($text"##BREAKPOINT##"));
  360.             return 1;
  361.         else {
  362.             return 0;
  363.         }
  364.     }
  365.     /* }}} */
  366.     /* show_article($id) {{{ */
  367.     /**
  368.      * Show an article with all comments etc
  369.      *
  370.      * @param int $id The article id to show
  371.      * @param int $captcha_error if 1 it shows an error
  372.      */
  373.     public function show_article($id$captcha_error 0{
  374.         //category url base
  375.         if ($this->settings["cleanurl"])
  376.             $catlink "category/%d";
  377.         else
  378.             $catlink "index.php?action=archive_cat&amp;c=%d";
  379.  
  380.         if ($id == "httperror"{
  381.             $row array(
  382.                 "title" => $_REQUEST["error"],
  383.                 "body"  => "The requested URL (".$_SERVER["REQUEST_URI"].") was not found.
  384.                     <br /><br />If you got here from a link on another page please contact that webmaster.<br />
  385.                     If it was in your bookmarks, please update them.<br /><br />
  386.                     My best guess is you came from: ".$_SERVER['HTTP_REFERER']."<br /><br />
  387.                     In the meantime you might be interested in:<br />
  388.                     <a href=\"index.php\" title=\"homepage\">Homepage</a><br />
  389.                     <a href=\"common/rss.php\" title=\"rss feed\">RSS feed</a><br />",
  390.                 "date"  => time()
  391.             );
  392.             $errormode 1;
  393.         else {
  394.  
  395.             $res =$this->db->query(sprintf("SELECT * FROM articles WHERE id = %d"$id));
  396.  
  397.             if (PEAR::isError($res))
  398.                 die($res->getMessage());
  399.             $row $res->fetchRow(MDB2_FETCHMODE_ASSOC);
  400.             $anoncomments $row["allowanoncomments"];
  401.             /* we can have a global overwrite for the anon comments */
  402.             if ($this->settings["allowanoncomments"!= 1)
  403.                 $anoncomments 0;
  404.             $errormode 0;
  405.         }
  406.         ?>
  407.         <div class="log_post">
  408.             <div class="log_post_head">
  409.                 <?php if ($errormode?>
  410.                     <h1 class="log_post_h1_error">
  411.                 <?php else ?>
  412.                     <h1 class="log_post_h1">
  413.                 <?php ?>
  414.                     <?php echo htmlspecialchars(stripslashes($row["title"]))?>
  415.                 </h1>
  416.   &n