Location: PHPKode > projects > Atom PhotoBlog > apbClasses/AtomPhotoBlog.class.php
<?php
   /*
   AtomPhotoBlog.class.php - Main Class of Atom PhotoBlogger
   Version 1.0.9
   Copyright (C) 2007 by Sascha Tayefeh

   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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   */

   /*!
   The main class: AtomPhotoBlog::

   CLASS-HIERARCHY:

   MySQL.class <- MySQLPhoto.class <- AtomPhotoBlog.class

   PARAMETERS (alphabetically sorted):
   -------------------------------------------------------------
   Public properties of interest for the end-user 
   -------------------------------------------------------------
 
      public $access=FALSE	// access granted flag. if this flag is set, admin-stuff will be printed/proceeded
      public $atomFile 		// The url to where the atom-file is going to be created.
      public $atomFileUrl	// The path to where the atom-file is going to be created.
      public $blogDescription	// Description of this blog.
      public $blogOwnerEmail	// Your Email
      public $blogOwner		// Your Name
      public $blogSubTitle	// SubTitle of this blog.
      public $blogTitle		// Title of this blog
      public $doSession 	// Send cookies?
      public $embedCopyright	// If this bool is true, a copyright tag will be embedded into the image when uploaded.
      public $feedEncoding	// Feed-encoding. MUST ALWAYS BE UTF-8 (->Atom convetion)
      public $htmlEncoding	// Html charset encoding
      public $isSessionStarted 	// Was a session requested?
      public $jpegQuality	// Quality of Jpegs when resizing.
      public $largeImageHeight	// max width and
      public $largeImageWidth	// max height of the large image
      public $maxRows		// max number of rows to show in index-table
      public $picPath		// path to blog-picture directory. Here is, where uploaded pictures are stored.
      public $picUrl		// url to blog-picture directory. Here is, where uploaded pictures are located.
      public $rootPath		// path to the root of this script. 
      public $rootUrl		// url to the root of this script. 
      public $rssFile		// path to where the rss-file is going to be created. 
      public $rssFileUrl	// url to where the rss-file is going to be created. 
      public $showTitleInIndex 	// Show the title in the index-table?
      public $styleSheet 	// The Style-Sheet
      public $thumbnailHeight	// max width and
      public $thumbnailWidth	// max height of your thumbnails.

      private $admin 		// Admin object derived from Admin.class.php
      private $db 		// Our XML-Database interface for communiaction within this class
      private $dbRss 		// Our XML-Database interface for communiaction within this class
      private $fileName		// The name of the uploaded image-file.
      private $generator	// This script's name
      private $generatorUrl	// Where to find this script on the web
      private $generatorVersion	// The version of this script
      private $getDo		// set by ::getVarsFromBrowser. It is the $_GET['do']-Var. $getDo is the page-navigator-switch used by ::show()
      private $getMode		// set by ::getVarsFromBrowser. It is the $_GET['mode']-Var
      private $getPhotoId 	// Default foto Id=-1 is interpreted as "latest picture"
      private $getTag		// set by ::getVarsFromBrowser. Picture-tag
      private $isLoadAtom	// bool-property that is set as soon as the atom-file is loaded.
      private $isLoadRss	// bool-property that is set as soon as the rss-file is loaded.
      private $navi		// Features all ids'n stuff necessary for the navigator-method (the next/prev-button stuff) $navi['thisId']= picId of currently selected picture $navi['oldestId']= oldest picture $navi['prevId']= previouse picture $navi['nextId']= next picture $navi['latestId']= latest picture $navi['tagLink']= was a tag selected? if yes, say so 
      private $target		// readily assembled, new target-image filename
      private $targetTn		// readily assembled, new target-thumbnail filename
      private $targetTnUrl	// readily assembled, new target-thumbnail url
      private $targetUrl	// readily assembled, new target-image url 


   METHODS (alphabetically sorted):
   -------------------------------------------------------------
   Public methods of interest for the end-user
   -------------------------------------------------------------

      public function AtomPhotoBlog($p) 	// The Constructor.
      public function getVarsFromBrowser() 	// Set this object's parameters proceeding GET/POST/SESSION-vars. This is part of the constructur, so it does not need to be called manually. 
      public function index($selTag) 		// Show Index/Archive/Browse-Image table. If $selTag is set, show only approbiatly tagged images.
      public function printAdminMenuItems()	// <li>-list (WITHOUT <ol>/<ul>, so you can put it wherever you want
      public function printBodyDiv() 		// Print the photoblog-body, e.g, the index/forms/picture...
      public function printBodyElements() 	// Container that calls printBodyDiv, printFeedsBody, and printValidator
      public function printCommentForm($thisId)	// Print Comment Form, $thisId= MysqlPictureID
      public function printCss() 		// Print the Css-Tag for the header
      public function printEncoding() 		// Header-Tag for charset-encoding
      public function printFeedsBody($full=TRUE,$textOnly=FALSE) // print the feeds-links in the body
      public function printFeedsHeader() 	// Print the feeds-tag for the header
      public function printHeaderElements() 	// Prints ALL header-elements: javascript/title/encoding/css/feeds
      public function printJavaScriptLink($link) // Given a link to a java-script, this method creates an appropiate header-tag.
      public function printMenu($moreMenuItems=NULL)
      public function printNavi() 		// Print the navigation-menu <div> for the large-image view (prev/next-buttons)
      public function printSettingsForm() 	// Print the options form.
      public function printTags($connectMyselfToMysql) // Print Tags-List. If the bool-arg is TRUE, it will connect to MYSL-Server. Do so, if calling this method from outside this object.
      public function printTitle() 		// Header-Tag for the title. Title is obtained from object's parameter 'blogTitle'.
      public function printUploadForm() 	// Print upload a picture form
      public function printValidator() 		// Print CSS/HTML/XML-Validators
      public function resizeImage( $uploadedClientFileName, $serverTempFileName, $imageMaxWidth = 850, $imageMaxHeight = 600, $quality=90, $embedThisCopyright=TRUE) // I've made this one public, so you can use it for a completely different purpose than blogging.
      public function show($thisId,$selTag) 	// show the large image. $thisId=mysqlId

   -------------------------------------------------------------
   Private Methods, not of interest for the user,
   but for the developer. For further information, read the
   comments atom the implementations of the method.
   -------------------------------------------------------------


      private function accessError()
      private function approveComments()
      private function checkLogin()
      private function createAtomEntry($mime,$entryId,$oldId=FALSE)
      private function createId()
      private function createMysqlEntry($timeStamp)
      private function createRssEntry($entryId)
      private function deleteAtomEntry($timeStamp)
      private function deleteFiles($timeStamp)
      private function deleteMySQLEntry($pId)
      private function deletePicture($getpId)
      private function deleteRssEntry($timeStamp)
      private function doApprove()
      private function editAtomEntry($pId,$oldTimeStamp,$newTimeStamp=FALSE)
      private function editMySQLEntry($pId,$timeStamp)
      private function editPicture()
      private function editRssEntry($pId,$timeStamp)
      private function encryptCap($string, $key)
      private function getSelectedTagString($selTag)
      private function htmlRecodeLight($string)
      private function htmlRecode($string)
      private function initAtom()
      private function initRss()
      private function logout()
      private function mysqlStoreTag($cleanTag,$entryId)
      private function parseUploadForm($customTime=FALSE)
      private function printEditForm($getpId)
      private function printLoginForm()
      private function readAtom()
      private function readRss()
      private function saveComment()
      private function saveNewFile($files)
      private function saveSettings()
      private function saveVars()
      private function setPicLocation($timeStamp)
      private function validEntry($envVar,$regExp,$myError)
      private function xmlRecodeLight($string)
      private function xmlRecodeNum($string)
      private function xmlRecode($string)
   */

   require_once './apbClasses/MySQLPhoto.class.php';
   require_once './apbClasses/Admin.class.php';
   require_once './apbData/salt.php';
   require_once './apbClasses/CheckContent.php';

   class AtomPhotoBlog extends MySQLPhoto
   {
      // ---------- Properties
      public $feedEncoding="utf-8";
      public $rootPath=".";
      public $rootUrl="http://localhost/";
      public $picPath="http://localhost/blog";
      public $picUrl="http://localhost/blog";
      public $blogDescription="BlaBla";
      public $blogTitle="Atom Photo Blog";
      public $blogSubTitle="An object-oriented Photo-Blog based on Atom Web-Feeds";
      public $blogOwner="Nobody";
      public $blogOwnerEmail="hide@address.com";
      public $atomFile="./blog/atom.xml";
      public $atomFileUrl="http://localhost/blog/atom.xml";
      public $rssFile="./blog/rss.xml";
      public $rssFileUrl="http://localhost/blog/rss.xml";
      public $htmlEncoding="iso-8859-1";
      public $maxRows=4;
      public $largeImageWidth=800;
      public $largeImageHeight=600;
      public $thumbnailWidth=141;
      public $thumbnailHeight=94;
      public $jpegQuality=85;
      public $embedCopyright=TRUE;
      public $doSession=TRUE; // Send cookies?
      public $isSessionStarted=FALSE; // Was a session requested?
      public $showTitleInIndex=FALSE; // Show the title in the index-table?
      public $styleSheet='./apbCss/atomPB.css'; // The Style-Sheet


      // Please, be fair and do not change these three lines:
      private $generator="AtomPhotoBlog.class by Sascha Tayefeh ";
      private $generatorVersion="1.0.9";
      private $generatorUrl="http://www.tayefeh.de";

      private $fileName;
      private $target;
      private $targetTn;
      private $targetUrl;
      private $targetTnUrl;
      private $db; // Our XML-Database interface for communiaction within this class
      private $dbRss; // Our XML-Database interface for communiaction within this class
      private $isLoadAtom=FALSE;
      private $isLoadRss=FALSE;

      /*
      Features all ids'n stuff necessary for
      the navigator-method (the next/prev-button stuff)
      $navi['thisId']= picId of currently selected picture
      $navi['oldestId']= oldest picture
      $navi['prevId']= previouse picture
      $navi['nextId']= next picture
      $navi['latestId']= latest picture
      $navi['tagLink']= was a tag selected? if yes, say so
      */
      private $navi=array();


      /*
      All navigation variables are tarsfered using the GET-Method, thus,
      all parameters start witg "get".  
      */
      private $getMode="default";
      private $getDo="default";
      private $getPhotoId=-1; // Default foto Id=-1 is interpreted as "latest picture"
      private $getTag=FALSE;

      private $admin; // Admin object derived from Admin.class.php
      public $access=FALSE; // access granted flag

      /*!
      This method stores all GETS/POSTS in private members of this object.
      */
      public function getVarsFromBrowser()
      {

	 // XSS ATTACK?!?
	 foreach ($_GET as $item => $value) { if (preg_match("/[^a-zA-Z0-9 ,]/i",$value)) die("*** ERROR: Invalid usage of var $item, possible XSS attack!"); }

	 // Use a whitelist to set vars
	 if(isset($_GET['mode'])) $this->getMode=$_GET['mode'];
	 if(isset($_POST['mode'])) $this->getMode=$_POST['mode'];
	 if(isset($_GET['do'])) $this->getDo=$_GET['do'];
	 if(isset($_POST['do'])) $this->getDo=$_POST['do'];
	 if(isset($_GET['photoId'])) $this->getPhotoId=$_GET['photoId'];
	 if(isset($_GET['tag'])) $this->getTag=$_GET['tag'];

	 return;
      }

      /*!
      Generave a <div> and an <ul> that provides the menu.
      If you want to add more menu-items, just set this members
      only argument using an assoc. array thats keys provide
      the menu-item name, and thats values provide the link, e.g.
      ::printMenu(array("About"=>"./about.php","SomewhereElse","http://www.somewhereelse.som"))
      */
      public function printMenu($moreMenuItems=NULL)
      {
	 echo '<div class="apb menu" id="apbMenu">';
	 echo '<ul class="apb menu">';
	 echo '<li class="apb menu"><a class="apb menu" href="'.$_SERVER['PHP_SELF'].'?do=index">Archive</a></li>';

	 if(isset($moreMenuItems))
	 foreach ($moreMenuItems as $item => $link)
	 echo '<li class="apb menu"><a class="apb menu" href="'.$link.'">'.$item.'</a></li>';

	 if(!$this->access)
	 {
	    echo '<li class="apb menu"><a class="apb menu" href="'.$_SERVER['PHP_SELF'].'?do=login">Login</a></li>';
	 }
	 if($this->access) $this->printAdminMenuItems();
	 echo '</ul>';
	 echo '</div>'; // end div menu

	 return;
      }

      /*!
      Security (Captcha) and Errorcheck the comment sent by comment form. 
      If o.k, store it for approvement by the admin.
      */
       private function saveComment()
      {
	 $error=FALSE;

	 if(!isset($_SESSION['apbMyCap']))
	 die ('<p class="apb error">You cannot access this method like this</p>');

	 echo "<div id=\"apbComment\" class=\"apb form\">";

	 // Error Check
	 if(trim($_POST['posterComment']==""))
	 {
	    $error=TRUE;
	    $errorList['NO COMMENT']="Your comment contains no text.";
	 }
	 if(trim($_POST['posterName']==""))
	 {
	    $error=TRUE;
	    $errorList['NO NAME']="Your name field contains no text.";
	 }

	 // Wordlist check
	 $val = new CheckContent("./apbData/pbblacklist.txt");
	 if(
	    (!($val->validate($_POST['posterComment'])))
	    ||
	    (!($val->validate($_POST['posterName'])))
	 )
	 {
	    $error=TRUE;
	    $errorList['INVALID CONTENT']="Your entry contains abusive words.";
	 }

	 // Captcha Check
	 $sec= $this->encryptCap($_POST["secCode"], "jf9wqf82frh");
	 $sec=str_replace("=", "", $sec);
	 if($sec != $_SESSION['apbMyCap'])
	 {
	    $error=TRUE;
	    $errorList['CAPTCHA']="You did not enter the security code correctly.";
	 }

	 if ($error)
	 {
	    echo "<p class=\"apb form error\">You didn't fill out the form correctly:</p>";

	    echo "<ol class=\"apb form errorList\">";
	    foreach($errorList as $value)
	    echo "<li class=\"apb form error errorList\">$value</li>";
	    echo "</ol>";

	    echo "<p class=\"apb form\">Please go ";
	    echo "back";
	    echo " and retry.</p>";
	 } else
	 {
	    unset($_SESSION['apbMyCap']);

	    if(isset($_POST['posterHomepage']) 
	    && trim($_POST['posterHomepage']) != ""
	    && trim($_POST['posterHomepage']) != "http://")
	    $homepage=trim($_POST['posterHomepage']);

	    $this->mysqlConnect();
	    // Create Array
	    $rowData=array(
	       "homepage" => strip_tags($homepage),
	       "comment" => strip_tags($_POST['posterComment']),
	       "email" => "",
	       "name" => strip_tags($_POST['posterName']),
	       "entryId" => $_POST['posterId'],
	       "IP" => $_SERVER["REMOTE_ADDR"]
	    );
	    $this->mysqlStoreRow($rowData,$this->apbPrefix.'comments');
	    $this->mysqlDisconnect();
	    echo '<h1 class="apb form success">Comment submitted FOR REVIEW!</h1>';

	    echo '<p class="apb form"> Your comment has been submitted for review by this site\'s owner.';
	    echo ' This means that it will NOT APPEAR before being approved by admin!';
	    echo ' As soon as your comment has been approved, it will appear beneath the picture you chose.';
	    echo '</p>';
	    echo '<p class="apb form"> <a class=\"apb\" href="';
	    echo urldecode($_POST['posterThisShow']);
	    echo '">Return to picture</a></p>';
	    echo "</div>";
	 }
	 return;
      }


      /*!
      Print the last/previous/index/next/latest navigation menu.
      Before calling this method, this object's parameters navi['thisId']
      and navi['tagLink'] MUST be set!
      */
      public function printNavi()
      {
	 if (
	    !isset($this->navi)
	    || !isset($this->navi['thisId'])
	    || !isset($this->navi['tagLink'])
	 )
	 die ('<p class="apb error form">ERROR: printNavi() method called without parameter $navi[] being initialized (sufficiantly). At least $navi["thisId"] and $navi["tagLink"] MUST be available.</p>');

	 echo '<div class="apb navi" id="apbNavi" >';
	 echo '<ul class="apb navi">';

	 // Oldest Button
	 echo '<li class="apb navi">';
	 if ($this->navi['thisId'] != $this->navi['oldestId'])
	 {
	    echo '<a class="apb navi" href="';
	    echo $_SERVER['PHP_SELF'];
	    echo "?do=show&amp;photoId=".$this->navi['oldestId'].$this->navi['tagLink'];
	    echo "\">";
	    echo "Oldest";
	    echo "</a>";
	 } else
	 {
	    echo "Oldest";
	 }
	 echo "</li>";

	 // Previous Button
	 echo '<li class="apb navi">';
	 if ($this->navi['thisId'] != $this->navi['oldestId'])
	 {
	    echo '<a href="';
	    echo $_SERVER['PHP_SELF'];
	    echo "?do=show&amp;photoId=".$this->navi['prevId'].$this->navi['tagLink'];
	    echo "\">";
	    echo "Previous";
	    echo "</a>";
	 } else {
	    echo "Previous";
	 }
	 echo "</li>";

	 // INDEX Button
	 echo '<li class="apb navi">';
	 echo '<a href="';
	 echo $_SERVER['PHP_SELF'];
	 echo "?do=index";
	 echo "\">";
	 echo "Index";
	 echo "</a></li>";

	 // Next Button
	 echo '<li class="apb navi">';
	 if ($this->navi['thisId'] != $this->navi['latestId'])
	 {
	    echo '<a href="';
	    echo $_SERVER['PHP_SELF'];
	    echo "?do=show&amp;photoId=".$this->navi['nextId'].$this->navi['tagLink'];
	    echo "\">";
	    echo "Next";
	    echo "</a>";
	 } else {
	    echo "Next";
	 }
	 echo "</li>";

	 // First Button
	 echo '<li class="apb navi">';
	 if ($this->navi['thisId'] != $this->navi['latestId'])
	 {
	    echo '<a href="';
	    echo $_SERVER['PHP_SELF'];
	    echo "?do=show&amp;photoId=",$this->navi['latestId'].$this->navi['tagLink'];
	    echo "\">";
	    echo "Latest";
	    echo "</a>";
	 } else {
	    echo "Latest";
	 }
	 echo "</li>";
	 echo "</ul>";
	 echo "</div>"; // End Navi
	 return;
      }


      /*!
      Just save the vars obtained from Options-Form. No errorcheck, just save.
      This private method is used by ::saveSettins().
      */
      private function saveVars()
      {
	 foreach( $_POST  as $key => $value) $apbPara[$key]= $value;

	 $apbPara['blogOwner']=$this->xmlRecodeLight($apbPara['blogOwner']);
	 $apbPara['blogTitle']=$this->xmlRecodeLight($apbPara['blogTitle']);
	 $apbPara['blogSubTitle']=$this->xmlRecodeLight($apbPara['blogSubTitle']);

	 $fp=fopen('./apbData/vars.php',"w+") or die("Could not write Logfile");

	 $buf ='<?php'."\n";
	    $buf .='$apbPara=array('."\n";
	    foreach( $apbPara as $key => $value)
	    {
	       $value=str_replace('"','\"',$value);
	       if (
		  $key!="do" &&
		  $key!="adLg" &&
		  $key!="adPw" &&
		  $key!="adPwRep" &&
		  $key!="mysqlPasswdRep" &&
		  $key!="embedCopyright"
	       ) $buf .= "\t\"$key\"\t=>\"$value\",\n";
	    }
	    if ($apbPara['showTitleInIndex']=="Yes") $buf .= "\t\"showTitleInIndex\"\t=> TRUE, \n";
	    else $buf .= "\t\"showTitleInIndex\"\t=> FALSE, \n";
	    if ($apbPara['embedCopyright']=="Yes") $buf .= "\t\"embedCopyright\"\t=> TRUE\n";
	    else $buf .= "\t\"embedCopyright\"\t=> FALSE\n";
	    $buf.= ");\n";
	 $buf.= "\n?>\n";

	 fwrite($fp,$buf);
	 fclose($fp);
      }

      /*!
      Errorcheck and save variables obtained from settings-form.
      */
      private function saveSettings()
      {
	 $nErrors=0;
	 $error=NULL;

	 // Errorcheck
	 $error['largeImageWidth']=$this->validEntry('largeImageWidth','/[^0-9]/',"MUST BE A DIGIT");
	 $error['largeImageHeight']=$this->validEntry('largeImageHeight','/[^0-9]/',"MUST BE A DIGIT");
	 $error['thumbnailWidth']=$this->validEntry('thumbnailWidth','/[^0-9]/',"MUST BE A DIGIT");
	 $error['thumbnailHeight']=$this->validEntry('thumbnailHeight','/[^0-9]/',"MUST BE A DIGIT");
	 $error['jpegQuality']=$this->validEntry('jpegQuality','/[^0-9]/',"MUST BE A DIGIT");
	 $error['maxRows']=$this->validEntry('maxRows','/[^0-9]/',"MUST BE A DIGIT");
	 $error['blogOwner']=$this->validEntry('blogOwner','/[^a-zA-Z ]/',"MUST BE A LETTER");

	 if (isset($_POST['blogOwnerEmail']) && !preg_match('/^[^@\s]+@([-a-z0-9]+\.)+[a-z]{2,}$/i',trim($_POST['blogOwnerEmail'])))
	 $error['blogOwnerEmail']=$_POST['blogOwnerEmail']." MUST BE A VALID E-MAIL";

	 if (isset($_POST['adLg']) && preg_match('/[^a-z0-9 ]/i',trim($_POST['adLg'])))
	 $error['adLg']="Invalid name: Only letters and numbers allowed";

	 if ( (isset($_POST['adPw']) && isset($_POST['adPwRep'])) && $_POST['adPw'] != $_POST['adPwRep'] )
	 $error['adPwRep']="Invalid admin password: Passwords do not equal!";

	 if ( $_POST['mysqlPasswd'] != $_POST['mysqlPasswdRep'] )
	 $error['mysqlPasswdRep']="Invalid MySQL password: Passwords do not equal!";

	 if ( (isset($_POST['blogTitle']) && trim($_POST['blogTitle'])=="") )
	 $error['blogTitle']="Invalid title: Title is empty?!";

	 if ( (isset($_POST['mysqlSrv']) && trim($_POST['mysqlSrv'])=="") )
	 $error['mysqlSrv']="Invalid Mysql-Server: Mysql-Server MUST NOT BE EMPTY!";

	 if ( (isset($_POST['mysqlDb']) && trim($_POST['mysqlDb'])=="") )
	 $error['mysqlDb']="Invalid Mysql-Database: Mysql-Database MUST NOT BE EMPTY!";

	 if ( (isset($_POST['mysqlLogin']) && trim($_POST['mysqlLogin'])=="") )
	 $error['mysqlLogin']="Invalid Mysql-Login: Mysql-Loginname MUST NOT BE EMPTY!";



	 if(isset($error))
	 {
	    echo "<ul class=\"apb form error\">";
	    foreach ($error as $key => $value)
	    if ($error[$key]){
	       echo "<li class=\"apb form error\">*** ERROR in field $key: $value</li>";
	       $nErrors++;
	    }
	    echo "</ul>";
	    if ($nErrors>0) die;
	 }
	 // ********** Save
	 echo "<div id=\"apbOptionsSave\" class=\"apb form\"><h1>Save Settings</h1>";

	 // Save Admin login
	 if (trim($_POST['adLg']!="" && trim($_POST['adPw']!="")))  $this->admin->savePw($_POST['adLg'],$_POST['adPw'])  ;

	 // Save Vars
	 $this->saveVars();

	 echo "<p class=\"apb form success\" >";
	 echo "SUCCESS!!!";
	 echo "</p>";

	 echo "</div>";
	 return;
      }

      private function validEntry($envVar,$regExp,$myError)
      {
	 $error=FALSE;
	 if ( (isset($_POST[$envVar]) && trim($_POST[$envVar])=="") )
	 $error="MUST NOT BE EMPTY";
	 elseif (preg_match($regExp,trim($_POST[$envVar])))
	 $error=$myError;
	 return $error;
      }

      /*!
      Print the Settings-Form.
      */
      public function printSettingsForm()
      {
	 if ($this->accessError()) return FALSE;
	 echo "<div id=\"apbOptions\" class=\"apb form options\"><h1 class=\"apb form\">Edit Settings</h1>";

	 // ********** Index
	 echo "<div id=\"apbOptionsIndex\" class=\"apb form optionsIndex \">";
	 echo "<h2 class=\"apb form\">Index</h2>";
	 echo "<ul class=\"apb form \">";
	 echo "<li class=\"apb form  \"><a href=\"#apbOptionsPersonal\">Personal Settings</a></li>";
	 echo "<li class=\"apb form  \"><a href=\"#apbOptionsAdmin\">Admin Settings</a></li>";
	 echo "<li class=\"apb form  \"><a href=\"#apbOptionsMySQL\">MySQL Settings</a></li>";
	 echo "<li class=\"apb form  \"><a href=\"#apbOptionsBlog\">Blog Settings</a></li>";
	 echo "<li class=\"apb form  \"><a href=\"#apbOptionsServer\">Server Settings</a></li>";
	 echo "</ul>";
	 echo "</div>"; // End OptionsIndex


	 echo "<form method=\"post\" action=\"";
	 echo $_SERVER['PHP_SELF']."\">";

	 // ********** Personal Options
	 echo "<hr class=\"apb form\" />";
	 echo "<div id=\"apbOptionsPersonal\" class=\"apb form\">";
	 echo "<p class=\"apb block\"><a href=\"#apbOptions\">Return To Index</a></p>";
	 echo "<h2 class=\"apb form\">Personal Settings</h2>";

	 echo "<dl class=\"apb form\">";

	 echo "<dt class=\"apb form \">Your Name: </dt>";
	 echo "<dd class=\"apb form \"><input class=\"inputbox \" size=\"40\" type=\"text\" name=\"blogOwner\" value=\"$this->blogOwner\" /></dd>";

	 echo "<dt class=\"apb form \">Your Email: </dt>";
	 echo "<dd class=\"apb form \"><input class=\"inputbox \" size=\"40\" type=\"text\" name=\"blogOwnerEmail\" value=\"$this->blogOwnerEmail\" /></dd>";

	 echo "</dl>";


	 echo "<input class=\"inputbox myButton\"  type=\"submit\" value=\"Submit\" />";
	 echo "</div>"; // End OptionsPersonal

	 // ********** Admin Options
	 echo "<hr class=\"apb form\" />";
	 echo "<div id=\"apbOptionsAdmin\" class=\"apb form \">";
	 echo "<p class=\"apb block form\"><a href=\"#apbOptions\">Return To Index</a></p>";
	 echo "<h2 class=\"apb form\">Admin Settings</h2>";
	 echo "<dl class=\"apb form\">";

	 echo "<dt class=\"apb form\">Login Name (if you change this, you <span  class=\"important\">MUST</span> change the password, too!): </dt>";

	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"27\" type=\"text\" name=\"adLg\" value=\"";
	 //	 echo trim($this->admin->getLoginName());
	 echo "\" /></dd>";

	 echo "<dt class=\"apb form\">Login Password: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"10\" type=\"password\" name=\"adPw\"  /></dd>";
	 echo "<dd class=\"apb form\"> Repeat: <input class=\"inputbox \" size=\"10\" type=\"password\" name=\"adPwRep\"  /></dd>";

	 echo "</dl>";

	 echo "<input class=\"inputbox myButton\"  type=\"submit\" value=\"Submit\" />";
	 echo "</div>"; // End OptionsAdmin

	 // ********** MySQL Options
	 echo "<hr class=\"apb form\" />";
	 echo "<div id=\"apbOptionsMySQL\" class=\"apb form \">";
	 echo "<p class=\"apb block form\"><a href=\"#apbOptions\">Return To Index</a></p>";
	 echo "<h2 class=\"apb form\">MySQL Settings</h2>";

	 echo "<dl class=\"apb form\">";

	 echo "<dt class=\"apb form\">MySQL Server: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"40\" type=\"text\" name=\"mysqlServer\" value=\"$this->mysqlServer\" /></dd>";

	 echo "<dt class=\"apb form\">MySQL Login Name: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"40\" type=\"text\" name=\"mysqlLogin\" value=\"$this->mysqlLogin\" /></dd>";

	 echo "<dt class=\"apb form\">MySQL Password: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"10\" type=\"password\" name=\"mysqlPasswd\" value=\"$this->mysqlPasswd\" /></dd>";
	 echo "<dd class=\"apb form\"> Repeat: <input class=\"inputbox \" size=\"10\" type=\"password\" name=\"mysqlPasswdRep\" value=\"$this->mysqlPasswd\" /></dd>";

	 echo "<dt class=\"apb form\">MySQL Database: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"40\" type=\"text\" name=\"mysqlDb\" value=\"$this->mysqlDb\" /></dd>";

	 echo "</dl>";

	 echo "<input class=\"inputbox myButton\"  type=\"submit\" value=\"Submit\" />";
	 echo "</div>"; // End OptionsMySQL


	 // ********** Blog Options
	 echo "<hr class=\"apb form\" />";
	 echo "<div id=\"apbOptionsBlog\" class=\"apb form \">";
	 echo "<p class=\"apb block\"><a href=\"#apbOptions\">Return To Index</a></p>";
	 echo "<h2 class=\"apb form\">Blog Settings</h2>";
	 echo "<dl class=\"apb form\">";

	 echo "<dt class=\"apb form\">Blog Title: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"40\" type=\"text\" name=\"blogTitle\" value=\"$this->blogTitle\" /></dd>";

	 echo "<dt class=\"apb form\">Blog SubTitle: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"80\" type=\"text\" name=\"blogSubTitle\" value=\"$this->blogSubTitle\" /></dd>";

	 echo "<dt class=\"apb form\">Max Size of Image: </dt>";
	 echo "<dd class=\"apb form\">Width:<input class=\"inputbox right \" size=\"5\" type=\"text\" name=\"largeImageWidth\" value=\"$this->largeImageWidth\" /></dd>";
	 echo "<dd class=\"apb form\">Height:<input class=\"inputbox right\" size=\"5\" type=\"text\" name=\"largeImageHeight\" value=\"$this->largeImageHeight\" /></dd>";

	 echo "<dt class=\"apb form\">Max Size of Thumbnails (will affect future uploads, only!): </dt>";
	 echo "<dd class=\"apb form\">Width:<input class=\"inputbox right\" size=\"5\" type=\"text\" name=\"thumbnailWidth\" value=\"$this->thumbnailWidth\" /></dd>";
	 echo "<dd class=\"apb form\">Height:<input class=\"inputbox right\" size=\"5\" type=\"text\" name=\"thumbnailHeight\" value=\"$this->thumbnailHeight\" /></dd>";


	 echo "<dt class=\"apb form\">JPeg Image Quality: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox right \" size=\"2\" type=\"text\" name=\"jpegQuality\" value=\"$this->jpegQuality\" /></dd>";

	 echo "<dt class=\"apb form\">Pictures per line in index: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox right \" size=\"2\" type=\"text\" name=\"maxRows\" value=\"$this->maxRows\" /></dd>";
	 echo "<dt class=\"apb form\">StyleSheet-File: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"60\"type=\"text\" name=\"styleSheet\" value=\"$this->styleSheet\" /></dd>";

	 if($this->embedCopyright) { $checkMe[1]='checked=\"checked\"'; $checkMe[2]=''; }
	 else {   $checkMe[2]='checked=\"checked\"'; $checkMe[1]=''; }
	 echo "<dt class=\"apb form\">Embed CopyrightTag to Image: </dt>";
	 echo "<dd class=\"apb form\">Yes: <input class=\"inputbox \"  type=\"radio\" ".$checkMe[1]." name=\"embedCopyright\" value=\"Yes\" /></dd>";
	 echo "<dd class=\"apb form\"> No: <input class=\"inputbox \"  type=\"radio\"  ".$checkMe[2]." name=\"embedCopyright\" value=\"No\" /></dd>";

	 if($this->showTitleInIndex) { $checkMe[1]='checked=\"checked\"'; $checkMe[2]=''; }
	 else {   $checkMe[2]='checked=\"checked\"'; $checkMe[1]=''; }
	 echo "<dt class=\"apb form\">Show Title of Index Pictures: </dt>";
	 echo "<dd class=\"apb form\">Yes: <input class=\"inputbox \"  type=\"radio\" ".$checkMe[1]." name=\"showTitleInIndex\" value=\"Yes\" /></dd>";
	 echo "<dd class=\"apb form\"> No: <input class=\"inputbox \"  type=\"radio\"  ".$checkMe[2]." name=\"showTitleInIndex\" value=\"No\" /></dd>";


	 echo "</dl>";
	 echo "<input class=\"inputbox myButton\"  type=\"submit\" value=\"Submit\" />";
	 echo "</div>"; // End OptionsBlog

	 // ********** Server Options
	 echo "<hr class=\"apb form\" />";
	 echo "<div id=\"apbOptionsServer\" class=\"apb form\">";
	 echo "<p class=\"apb block\"><a href=\"#apbOptions\">Return To Index</a></p>";
	 echo "<h2 class=\"apb form\">Server Settings</h2>";

	 echo "<dl class=\"apb form\" >";

	 echo "<dt class=\"apb form\">CharSet: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" type=\"text\" name=\"htmlEncoding\" value=\"$this->htmlEncoding\" /></dd>";

	 echo "<dt class=\"apb form\" >Root Path: </dt>";
	 echo "<dd class=\"apb form\" ><input class=\"inputbox \" size=\"60\"type=\"text\" name=\"rootPath\" value=\"$this->rootPath\" /></dd>";

	 echo "<dt class=\"apb form\">Root Url: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"60\"type=\"text\" name=\"rootUrl\" value=\"$this->rootUrl\" /></dd>";

	 echo "<dt class=\"apb form\">PicturePath: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"60\"type=\"text\" name=\"picPath\" value=\"$this->picPath\" /></dd>";

	 echo "<dt class=\"apb form\">Picture Url: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"60\"type=\"text\" name=\"picUrl\" value=\"$this->picUrl\" /></dd>";

	 echo "<dt class=\"apb form\">Atom Feed File Path: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"60\"type=\"text\" name=\"atomFile\" value=\"$this->atomFile\" /></dd>";

	 echo "<dt class=\"apb form\">Atom Feed File Url: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"60\"type=\"text\" name=\"atomFileUrl\" value=\"$this->atomFileUrl\" /></dd>";

	 echo "<dt class=\"apb form\">Rss Feed File Path: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"60\"type=\"text\" name=\"rssFile\" value=\"$this->rssFile\" /></dd>";

	 echo "<dt class=\"apb form\">Rss Feed File Url: </dt>";
	 echo "<dd class=\"apb form\"><input class=\"inputbox \" size=\"60\"type=\"text\" name=\"rssFileUrl\" value=\"$this->rssFileUrl\" /></dd>";

	 echo "</dl>";
	 echo "<input class=\"inputbox myButton\"  type=\"submit\" value=\"Submit\" />";
	 echo "<input style=\"display: none\" name=\"do\" value=\"saveSettings\" />";
	 echo "</div>"; // End OptionsBlog

	 echo "</form>";

	 echo "</div>"; // End apbOptions
	 return TRUE;
      }

      public function printBodyDiv()
      {
	 $ok=TRUE;

	 switch ($this->getDo)
	 {
	    case "options": // Open admin's options menu
	       $ok=$this->accessError() ? FALSE : $this->printSettingsForm();
	       break;
	    case "edit": // Open admin's edit menu
	       $ok=$this->accessError() ? FALSE : $this->printEditForm($this->getPhotoId);
	       break;
	    case "doEdit": // Open admin's edit menu
	       $ok=$this->accessError() ? FALSE : $this->editPicture();
	       break;
	    case "delete": // Open admin's deletion menu
	       $ok=$this->accessError() ? FALSE : $this->deletePicture($this->getPhotoId);
	       break;
	    case "upload": // Open admin's upload menu
	       $ok=$this->accessError() ? FALSE : $this->printUploadForm();
	       break;
	    case "appComs": // Open admin's comment-approve menu
	       $ok=$this->accessError() ? FALSE : $this->approveComments();
	       break;
	    case "pwDone": // Password was sent by form, check it
	       $ok=$this->checkLogin();
	       break;
	    case "logout": // Print the admin-login form
	       $ok=$this->accessError() ? FALSE : $this->logout();
	       break;
	    case "login": // Print the admin-login form
	       $ok=$this->printLoginForm();
	       break;
	    case "doApprove": // Admin has approved comments. Now proceed.
	       $ok=$this->accessError() ? FALSE : $this->doApprove();
	       break;
	    case "comment": // User has send comment, put into approval-queue
	       $ok=$this->saveComment();
	       break;
	    case "saveSettings": // Admin has uploaded picture, proceed now.
	       $ok=$this->accessError() ? FALSE : $this->saveSettings();
	       break;
	    case "save": // Admin has uploaded picture, proceed now.
	       $ok=$this->accessError() ? FALSE : $this->saveNewFile($_FILES);
	       break;
	    case "show": // Show single picture
	       $this->getTag ? $this->show($this->getPhotoId,$this->getTag) : $this->show($this->getPhotoId);
	       break;
	    case "index": // Show single picture
	       $this->getTag ? $this->index($this->getTag) : $this->index();
	       break;
	    default: // Show the index
	       $this->getTag ? $this->show($this->getPhotoId,$this->getTag) : $this->show($this->getPhotoId);
	       break;
	 }
	 return ($ok ? TRUE : FALSE);
      }

      public function printAdminMenuItems()
      {
	 echo "<li class=\"apb menu admin\"><a class=\"apb menu admin\" href=\"".$_SERVER['PHP_SELF']."?do=upload\">";
	 echo "Upload Photo";
	 echo "</a></li>";

	 echo "<li class=\"apb menu admin\"><a class=\"apb menu admin\" href=\"".$_SERVER['PHP_SELF']."?do=appComs\">";
	 echo "Approve Comments";
	 echo "</a></li>";

	 echo "<li class=\"apb menu admin\"><a class=\"apb menu admin\" href=\"".$_SERVER['PHP_SELF']."?do=options\">";
	 echo "Options";
	 echo "</a></li>";

	 echo "<li class=\"apb menu admin\"><a class=\"apb menu admin\" href=\"".$_SERVER['PHP_SELF']."?do=logout\">";
	 echo "Logout";
	 echo "</a></li>";
	 return;
      }

      private $replaceHtml=array(
	 '\"'=>'"',
	 "\'"=>"'",
	 "&"=>"&amp;"
      );

      private $replaceXmlLight=array(
	 '\"'=>'"',
	 "\'"=>"'"
      );

      private $replaceXmlNum=array(
	 "<"=>"&#60;",
	 ">"=>"&#62;",
	 "&"=>"&#38;",
	 "'"=>"&#39;",
	 '"'=>"&#34;"
      );

      private $replaceXml=array(
	 "<"=>"&lt;",
	 ">"=>"&gt;",
	 "&"=>"&amp;",
	 "'"=>"&apos;",
	 '"'=>"&quot;"
      );

      // The Constructor
      public function AtomPhotoBlog($p)
      {
	 global $salt;
	 foreach($p as $key => $value) $this->$key=$value;

	 if($this->doSession)
	 {
	    $this->admin = new Admin(
	       array(
		  "SALT"=>$salt,
		  "SESSIONNAME"=>"apb",
		  "FILE"=>$this->rootPath."/apbData/apbpw.php",
		  "FAILLOG"=>$this->rootPath."/apbData/apb.log",
		  "LOGINURL"=>$_SERVER['PHP_SELF'],
		  "LOGOUTURL"=>$_SERVER['PHP_SELF']
	       )
	    );
	    $this->access=$this->admin->checkAccess();
	    $this->isSessionStarted=TRUE;
	 }
	 $this->getVarsFromBrowser();
	 $this->db= new DOMDocument('1.0', $this->feedEncoding);
	 $this->db->formatOutput=true;
	 $this->db->preserveWhiteSpace=false;
	 $this->db->substituteEntities=false;

	 $this->dbRss= new DOMDocument('1.0', $this->feedEncoding);
	 $this->dbRss->formatOutput=true;
	 $this->dbRss->preserveWhiteSpace=false;



	 $this->atomFile=$this->picPath."/atom.xml";
	 $this->atomFileUrl =$this->picUrl."/atom.xml";
	 $this->rssFile=$this->picPath."/rss.xml";
	 $this->rssFileUrl =$this->picUrl."/rss.xml";

	 return ;
      }

      private function htmlRecode($string)
      {
	 $string= str_replace(array_keys($this->replaceHtml),array_values($this->replaceHtml),$string);
	 $string=htmlentities($string);
	 return $string;
      }

      private function htmlRecodeLight($string)
      {
	 return str_replace(array_keys($this->replaceHtml),array_values($this->replaceHtml),$string);
      }


      private function xmlRecodeNum($string)
      {
	 $string=str_replace(array_keys($this->replaceXmlLight),array_values($this->replaceXmlLight),$string);
	 $string=str_replace(array_keys($this->replaceXmlNum),array_values($this->replaceXmlNum),$string);
	 return $string;
      }

      private function xmlRecodeLight($string)
      {
	 $string=str_replace(array_keys($this->replaceXmlLight),array_values($this->replaceXmlLight),$string);
	 return $string;
      }


      private function xmlRecode($string)
      {
	 $string=str_replace(array_keys($this->replaceXmlLight),array_values($this->replaceXmlLight),$string);
	 $string=str_replace(array_keys($this->replaceXml),array_values($this->replaceXml),$string);
	 return $string;
      }

      public function printBodyElements()
      {
	 $this->printBodyDiv();
	 $this->printFeedsBody(TRUE,FALSE);
	 $this->printValidator();
	 return;
      }

      /*!
      All header elements can be accessed by this method.
      If you plan to implement this blog into your own project,
      you may want to call this classes header members 
      one by one.
      */
      public function printHeaderElements()
      {
	 $this->printJavaScriptLink("./js/apb.js");
	 $this->printTitle();
	 $this->printEncoding();
	 $this->printCss();
	 $this->printFeedsHeader();
	 return;
      }

      /*!
      Print the header element: JavaScripts. The argument
      is no more than an URL to where the js is located.
      */
      public function printJavaScriptLink($link)
      {
	 echo "\n".'<script type="text/javascript" src="';
	 echo $link;
	 echo '"></script>'."\n";
	 return;
      }

      /*!
      Print the header element: Title, which is derived
      from this classes parameter $blogTitle; 
      */
      public function printTitle()
      {
	 echo '<title>';
	 echo htmlentities($this->blogTitle);
	 echo '</title>';
	 return;
      }

      public function printEncoding()
      {
	 echo '<meta http-equiv="Content-Type" content="text/html;charset=';
	 echo $this->htmlEncoding;
	 echo '" />';
	 return;
      }


      /*! 
      Call this method from within the header, so browsers will automatically
      find this feed.
      */
      public function printFeedsHeader()
      {
	 // The Atom Feeder
	 echo '<link rel="alternate" type="application/atom+xml" title="'.$this->blogTitle;
	 echo ' (Atom 1.0)" href="'.$this->atomFileUrl.'" />';

	 // The Rss Feeder
	 echo '<link rel="alternate" type="application/rss+xml" title="'.$this->blogTitle;
	 echo ' (Rss 2.0)" href="'.$this->rssFileUrl.'" />';

	 return;
      }

      public function printCss()
      {	 // The Style-Sheet
      echo '<link rel="stylesheet" href="'.$this->styleSheet.'" type="text/css" media="all" />';
      return;
      }

      /*!
      Additionally to the feed-links within the header (::printFeedsHeader()), you may want
      to show the links to the feeds within your document. Use this method.
      The first bool argument concerns *which* feed-links are shown: 
      If TRUE, all links (e.g. AddTo Yahoo, Google etc) are shown, if FALSE only links
      to RSS2.0 and ATOM1.0 Feed are shown. 
      The second bool argument makes the Links appear as images (FALSE) or text only
      (TRUE).
      */
      public function printFeedsBody($full=TRUE,$textOnly=FALSE)
      {
	 echo "<div class=\"apb abo\" id=\"apbAbo\">";

	 echo "<ul class=\"apb quick abo\">";

	 // local Rss Feeder
	 echo "<li class=\"apb quick abo\">";
	 echo '<a href="';
	 echo $this->rssFileUrl;
	 echo '">';
	 if($textOnly) echo 'Rss&nbsp;2.0';
	 else echo '<img src="'.$this->rootUrl.'/apbIcons/ilenvo-rss.png" width="26" height="15" alt="RSS 2.0 Feed" />';
	 echo '</a>';
	 echo "</li>";

	 // local Atom Feeder
	 echo "<li class=\"apb quick abo\">";
	 echo '<a href="';
	 echo $this->atomFileUrl;
	 echo '">';
	 if($textOnly) echo 'Atom&nbsp;1.0';
	 else echo '<img src="'.$this->rootUrl.'/apbIcons/ilenvo-atom.png" width="30" height="15" alt="Atom 1.0 Feed" /> ';
	 echo '</a>';
	 echo "</li>";

	 if($full)
	 {
	    // Yahoo feeder
	    echo "<li class=\"apb abo\">";
	    echo '<a href="http://us.rd.yahoo.com/my/atm/Test/Test/*http://add.my.yahoo.com/rss?url=';
	    echo $this->atomFileUrl;
	    echo '"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif" width="91" height="17" border="0" align="middle" alt="Add to My Yahoo!" /></a>';
	    echo "</li>";

	    // Newsgator feeder
	    echo "<li class=\"apb abo\">";
	    echo '<a href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=';
	    echo $this->atomFileUrl;
	    echo '"><img runat="server" src="http://www.newsgator.com/images/ngsub1.gif" alt="Subscribe in NewsGator Online" border="0" /></a>';
	    echo "</li>";

	    // Google feeder
	    echo "<li class=\"apb abo\">";
	    echo '<a href="http://www.google.com/ig/add?feedurl=';
	    echo $this->atomFileUrl;
	    echo '">';
	    echo 'Add to Google';
	    echo '</a>';
	    echo "</li>";
	 }
	 echo "</ul>";
	 echo "</div>";

	 return;
      }

      /*!
      If you want to check whether these pages and feeds are well-formed,
      use this method to print a <div> with links to some validators.
      */
      public function printValidator()
      {
	 echo "<div class=\"apb validators\" id=\"apbValidators\">";
	 echo "<ul class=\"apb validators\">";

	 // Atom Validator @ W3C
	 echo "<li class=\"apb validators\">";
	 echo '<a href="http://validator.w3.org/feed/check.cgi?url=';
	 echo $this->atomFileUrl;
	 echo '">W3C-Atom</a>';
	 echo "</li>";

	 // Atom Validator @ Validome
	 echo "<li class=\"apb validators\">";
	 echo '<a href="http://www.validome.org/rss-atom/validate?version=atom_1_0&amp;url=';
	 echo $this->atomFileUrl;
	 echo '">';
	 echo 'Validome-Atom</a>';
	 echo "</li>";

	 // Rss Validator @ Validome
	 echo "<li class=\"apb validators\">";
	 echo '<a href="http://www.validome.org/rss-atom/validate?version=rss_2_0&amp;url=';
	 echo $this->rssFileUrl;
	 echo '">';
	 echo 'Validome-Rss</a>';
	 echo "</li>";

	 // Rss Validator @ feedvalidator
	 echo "<li class=\"apb validators\">";
	 echo '<a href="http://feedvalidator.org/check.cgi?url=';
	 echo $this->rssFileUrl;
	 echo '">W3C-Rss</a>';
	 echo "</li>";

	 // W3C-XHTML Validator
	 echo "<li class=\"apb validators\">";
	 echo ' <a href="http://validator.w3.org/check?uri=referer">W3C-XHTML</a>';
	 echo "</li>";
	 echo "</ul>";

	 echo "</div>";
	 return;
      }

      //! This method creates an unique Id for atom-feeds.
      private function createId()
      {
	 $url=$this->picUrl;
	 $domain=str_replace("http://","",$url);
	 $domain=substr_replace($domain,"",stripos($domain,'/'));
	 $urlPath='/'.eregi_replace("http://[0-9a-zA-Z\-_+:\.#]*/",'',$url);

	 $blogId ="tag:".$domain.",".date("Y-m-d",time()).":";
	 $blogId.=$urlPath."/".date("YmdHis");

	 return $blogId;
      }

      /*!
      Initialize the Rss-Feed by writing the header stuff of an Rss-XML-file
      */
      private function initRss()
      {
	 // temporarily creade a minimal doc structure and
	 //	 echo "<li>Initializing Rss</li>";
	 $dbRss= new DOMDocument('1.0', $this->feedEncoding);
	 $dbRss->formatOutput=true;
	 $dbRss->preserveWhiteSpace=true;
	 $rss=$dbRss->appendChild($dbRss->createElement('rss'));
	 $rss->setAttribute('xmlns:content','http://purl.org/rss/1.0/modules/content/');
	 $rss->setAttribute('version','2.0');

	 $channel=$rss->appendChild($dbRss->createElement('channel'));

	 $title=$channel->appendChild($dbRss->createElement('title',$this->xmlRecode(utf8_encode($this->blogTitle))));
	 $link=$channel->appendChild($dbRss->createElement('link',$this->xmlRecode(utf8_encode($this->rootUrl))));
	 $description=$channel->appendChild($dbRss->createElement('description',$this->xmlRecode(utf8_encode($this->blogSubTitle))));

	 //	 $language=$channel->appendChild($dbRss->createElement('language',$this->xmlRecode(utf8_encode("en-us"))));
	 $lastBuildDate=$channel->appendChild($dbRss->createElement('lastBuildDate',date("r",time())));
	 $pubDate=$channel->appendChild($dbRss->createElement('pubDate',date("r",time())));
	 $copyright=$channel->appendChild($dbRss->createElement('copyright','Copyright (c) '.date("Y",time()).', '.$this->xmlRecode(utf8_encode($this->blogOwner))));
	 $docs=$channel->appendChild($dbRss->createElement('docs',utf8_encode($this->rssFileUrl)));
	 $generator=$channel->appendChild($dbRss->createElement('generator',$this->xmlRecode(utf8_encode($this->generator." V".$this->generatorVersion))));
	 $category=$channel->appendChild($dbRss->createElement('category',$this->xmlRecode(utf8_encode('photoblog'))));
	 $category=$channel->appendChild($dbRss->createElement('category',$this->xmlRecode(utf8_encode('blog'))));
	 $category=$channel->appendChild($dbRss->createElement('category',$this->xmlRecode(utf8_encode('picture'))));
	 $managingEditor=$channel->appendChild($dbRss->createElement('managingEditor',$this->xmlRecode(utf8_encode($this->blogOwnerEmail))));
	 $webMaster=$channel->appendChild($dbRss->createElement('webMaster',$this->xmlRecode(utf8_encode($this->blogOwnerEmail))));
	 $dbRss->save($this->rssFile);
      }

      /*!
      Initialize the Atom-Feed by writing the header stuff of an Atom-XML-file
      */
      private function initAtom()
      {
	 // temporarily creade a minimal doc structure and
	 // save it
	 $db= new DOMDocument('1.0', $this->feedEncoding);
	 $db->formatOutput=true;
	 $db->preserveWhiteSpace=true;
	 //	 $db->substituteEntities=true;

	 //  --------------------
	 //    Create Atom Feed
	 //  --------------------

	 // Header Begin
	 $feed=$db->appendChild($db->createElement('feed'));
	 $feed->setAttribute('xmlns','http://www.w3.org/2005/Atom');

	 $title=$feed->appendChild($db->createElement('title',$this->xmlRecode(utf8_encode($this->blogTitle))));
	 $title->setAttribute('type','text');

	 $linkAlt=$feed->appendChild($db->createElement('link'));
	 $linkAlt->setAttribute('rel','alternate');
	 $linkAlt->setAttribute('type','text/html');
	 //	 $linkAlt->setAttribute('hreflang','de');
	 $linkAlt->setAttribute('href',$this->rootUrl);

	 $linkSelf=$feed->appendChild($db->createElement('link'));
	 $linkSelf->setAttribute('rel','self');
	 $linkSelf->setAttribute('type','application/atom+xml');
	 $linkSelf->setAttribute('href',$this->atomFileUrl);

	 $subTitle=$feed->appendChild($db->createElement('subtitle',$this->blogSubTitle));
	 $subTitle->setAttribute('type','text');

	 $update=$feed->appendChild($db->createElement('updated',date("c",time())));

	 $author=$feed->appendChild($db->createElement('author'));
	 $author->appendChild($db->createElement('name',$this->xmlRecode(utf8_encode($this->blogOwner))));

	 $blogId=$this->createId();
	 $id=$feed->appendChild($db->createElement('id',$blogId.rand(1,1000)));

	 $rights=$feed->appendChild($db->createElement('rights','Copyright (c) '.date("Y",time()).', '.$this->xmlRecode(utf8_encode($this->blogOwner))));

	 $generator=$feed->appendChild($db->createElement('generator',$this->xmlRecode(utf8_encode($this->generator))));
	 $generator->setAttribute('uri',$this->xmlRecode(utf8_encode($this->generatorUrl)));
	 $generator->setAttribute('version',$this->generatorVersion);

	 // Header End
	 $db->save($this->atomFile);
      }

      /*!
      Read the atom1.0 file. If it doesn't exist, create it!
      */
      private function readAtom()
      {
	 if(!file_exists($this->atomFile))  $this->initAtom();
	 $this->db->load($this->atomFile) or die("Could not load atom-file");
	 $this->isLoadAtom=TRUE;
      }

      /*!
      Read the Rss2.0 file. If it doesn't exist, create it!
      */
      private function readRss()
      {
	 if(!file_exists($this->rssFile))  $this->initRss();
	 $this->dbRss->load($this->rssFile) or die("Could not load rss-file");
	 $this->isLoadRss=TRUE;
      }


      /*!
      The main show-the-big image method. It has two arguments. The first
      one is an integer that provides the MySQL-Id of the image to show.
      The second one provides the TAG selected. Both are being initialized
      by default to impossible values (-1, and "9x98ex9MAGIC") in order to
      perform default stuff (=show the latest image).
      */
      public function show($thisId=-1,$selTag="9x98ex9MAGIC")
      {
	 $this->mysqlConnect();

	 if($selTag=="9x98ex9MAGIC") // Select all
	 {
	    $query[1]="select max(phpTimeStamp) from ".$this->apbPrefix."entries ";
	    $query[2]="select * from ".$this->apbPrefix."entries where phpTimeStamp= ";
	    $query[3]="select * from ".$this->apbPrefix."entries where id=";
	    $query[4]="select min(phpTimeStamp) from ".$this->apbPrefix."entries ";
	    $query[5]="select * from ".$this->apbPrefix."entries where phpTimeStamp=";
	    $query[6]="select max(phpTimeStamp) from ".$this->apbPrefix."entries";
	    $query[7]="select * from ".$this->apbPrefix."entries where phpTimeStamp=";
	    $query[8]="select * from ".$this->apbPrefix."entries order by phpTimeStamp asc;";
	    $tagLink="";
	 } else  // Only select tagged
	 {
	    $tagQuery =$this->getSelectedTagString($selTag);

	    if(!$tagQuery) { return -1; }
	    $query[1]="select max(phpTimeStamp) from ".$this->apbPrefix."entries where ($tagQuery) ";
	    $query[2]="select * from ".$this->apbPrefix."entries where phpTimeStamp= ";
	    $query[3]="select * from ".$this->apbPrefix."entries where id=";
	    $query[4]="select min(phpTimeStamp) from ".$this->apbPrefix."entries where ($tagQuery) ";
	    $query[5]="select * from ".$this->apbPrefix."entries where phpTimeStamp=";
	    $query[6]="select max(phpTimeStamp) from ".$this->apbPrefix."entries where ($tagQuery) ";
	    $query[7]="select * from ".$this->apbPrefix."entries where phpTimeStamp=";
	    $query[8]="select * from ".$this->apbPrefix."entries where ($tagQuery) order by phpTimeStamp asc;";
	    $tagLink="&amp;tag=".$selTag;
	 }

	 if($thisId==-1)
	 {
	    $buffer=$this->mysqlQuery($query[1]);
	    $buffer=mysql_fetch_array($buffer); $thisT=$buffer[0]; // Last Entry's id?
	    if(!$thisT) return -1;
	    $buffer=mysql_fetch_assoc($this->mysqlQuery($query[2].$thisT)); $thisId=$buffer['id'];
	 }

	 $thisE =mysql_fetch_assoc($this->mysqlQuery($query[3].$thisId));

	 if(!$thisE) return -1;
	 // Oldest Entry's id?
	 $buffer=mysql_fetch_array($this->mysqlQuery($query[4])); $oldestT=$buffer[0];
	 $buffer=mysql_fetch_assoc($this->mysqlQuery($query[5].$oldestT)); $oldestId=$buffer['id'];

	 // Latest Entry's id?
	 $buffer=mysql_fetch_array($this->mysqlQuery($query[6])); $latestT=$buffer[0];
	 $buffer=mysql_fetch_assoc($this->mysqlQuery($query[7].$latestT)); $latestId=$buffer['id'];

	 // Next Entry's id?
	 $buffer=$this->mysqlQuery($query[8]);
	 $finished=FALSE;
	 while (!$finished && $row= mysql_fetch_assoc($buffer))
	 {
	    if ($row['id'] == $thisId )
	    {
	       if ($oldestId!=$thisId)
	       {
		  $prevId=$rem['id'];
		  $prevTn=$rem['tnLink'];
		  $prevTit=$rem['title'];
	       }
	       if ($latestId!=$thisId)
	       {
		  $row=mysql_fetch_assoc($buffer);
		  $nextId=$row['id'];
		  $nextTn=$row['tnLink'];
		  $nextTit=$row['title'];
	       }
	       $finished=TRUE;
	    }
	    $rem['id']=$row['id'];
	    $rem['phpTimeStamp']=$row['phpTimeStamp'];
	    $rem['tnLink']=$row['tnLink'];
	    $rem['title']=$row['tnLink'];
	 }

	 $url=$thisE['picLink'];
	 $alt=$title=$thisE['title'];
	 $comment=$thisE['comment'];
	 $timeStamp=$thisE['phpTimeStamp'];
	 $hits=$thisE['hits'];
	 $hits++;

	 // IncreaseCounter
	 $this->mysqlQuery("update ".$this->apbPrefix."entries set hits=".$hits." where id=".$thisId);

	 // Prepare the navi-array
	 $this->navi=array(
	    "thisId" =>$thisId,
	    "oldestId" =>$oldestId,
	    "latestId" =>$latestId,
	    "tagLink" =>$tagLink
	 );
	 if (isset($prevId)) $this->navi['prevId']=$prevId;
	 if (isset($nextId)) $this->navi['nextId']=$nextId;

	 // Print the navigator
	 $this->printNavi();

	 // View Image
	 echo "<div class=\"apb largeImage\" id=\"apbLargeImage\">";
	 if($this->access)
	 {
	    echo "<div class=\"apb edit largeImage \" id=\"apbLargeImageEdit\">";
	    echo '<ul class="apb edit admin ">';
	    echo '<li class="apb edit admin ">';
	    echo '<a href="';
	    echo $_SERVER['PHP_SELF']."?do=edit&amp;photoId=$thisId \">";
	    echo "Edit";
	    echo "</a>";
	    echo "</li>";
	    echo '<li class="apb edit admin ">';
	    echo '<a href="';
	    echo $_SERVER['PHP_SELF']."?do=delete&amp;photoId=$thisId \">";
	    echo "Delete";
	    echo "</a>";
	    echo "</li>";
	    echo "</ul>";
	    echo "</div>";
	 } // ENDIF admin


	 if ($this->navi['thisId'] != $this->navi['oldestId'])
	 {
	    echo '<a href="';
	    echo $_SERVER['PHP_SELF'];
	    echo "?do=show&amp;photoId=".$this->navi['prevId'].$this->navi['tagLink'];
	    echo "\">";
	    echo "<img class=\"apb largeImage\" alt=\"$alt\" src=\"$url\" />";
	    echo "</a>";
	 } else {
	    echo "<img class=\"apb largeImage\" alt=\"$alt\" src=\"$url\" />";
	 }

	 echo "</div>"; // End Large Image

	 // View Title
	 echo "<div class=\"apb largeImageText\" id=\"apbLargeImageText\">";
	 echo "<h1>$title</h1>";
	 echo "</div>"; // End Title

	 echo "<div class=\"apb largeImageDescription\" id=\"apbLargeImageDescription\">";
	 echo "<p>&dagger;  ";
	 echo date("d-m-Y ",$timeStamp);
	 echo "&dagger;  $hits views</p>";
	 echo "<p>";
	 echo $comment;
	 echo "</p>";
	 echo "</div>"; // End Description

	 // Any comments available, at all?
	 $query="select * from ".$this->apbPrefix."comments where entryId= ".$thisId." order by timeStamp desc";
	 $buffer=$this->mysqlQuery($query);
	 $nPics=mysql_num_rows($buffer);
	 if ($nPics>0)
	 {
	    // Any *approved* comments available?
	    $query="select * from ".$this->apbPrefix."comments where entryId= ".$thisId." and approved=1";
	    if(mysql_num_rows($this->mysqlQuery($query)))
	    {
	       echo "<div class=\"apb largeImageComments\" id=\"apbLargeImageComments\">";
	       echo "<h2 class=\"apb\">Visitor's Comments</h2>";
	       echo '<ol class="apb comments">';
	       while ($cE = mysql_fetch_assoc($buffer))
	       {
		  if($cE['approved']==1)
		  {
		     echo '<li class="apb comments">';
		     echo $cE['name'];

		     if ($cE['homepage']!="")
		     {
			echo " <a href=\"".$cE['homepage']."\">";
			echo "(Homepage)";
			echo "</a>";
		     }

		     echo ' wrote: ';
		     echo $cE['comment'];
		     echo '</li>';
		  }
	       }
	       echo "</ol>";
	       echo "</div>"; // End Description
	    }
	 }

	 // Print Comment Form
	 $this->printCommentForm($thisId);
	 $this->mysqlDisconnect();
	 return;
      }


      /*!
      Just a method called by the Captcha member. Ignore this, please.
      */
      private function encryptCap($string, $key)
      {
	 $result = '';
	 for($i=0; $i<strlen($string); $i++) {
	    $char = substr($string, $i, 1);
	    $keychar = substr($key, ($i % strlen($key))-1, 1);
	    $char = chr(ord($char)+ord($keychar));
	    $result.=$char;
	 }
	 return base64_encode($result);
      }


      /*!
      This is the comment form that's being printed with every view of the large image.
      Its only argument is the MySQL-id of the current image.
      */
      public function printCommentForm($thisId)
      {
	 echo "<div class=\"apb commentForm\" id=\"apbCommentForm\">";
	 echo "<h2 class=\"apb commentForm\">";
	 echo "<a  id=\"apbCommentLink\" style=\"text-decoration: underline\" href=\"JavaScript:showCommentForm()\">";
	 echo "Add Your Comment";
	 echo "</a>";
	 echo "</h2>";
	 echo "<div style=\"display: none\" id=\"apbCommentHide\">";
	 echo "<form method=\"post\" action=\"";
	 echo $_SERVER['PHP_SELF']."\">";
	 echo "<dl>";
	 echo "<dt class=\"apb\">Your Name (mandatory):</dt><dd class=\"apb\"><input  class=\"abp inputbox\" name=\"posterName\" size=\"40\" /></dd>";
	 //	 echo "<dt class=\"apb\">Your E-Mail (optional):</dt><dd class=\"apb\"><input  class=\"abp inputbox\" name=\"posterEmail\" size=\"40\" /></dd>";
	 echo "<dt class=\"apb\">Your Homepage (optional):</dt><dd class=\"apb\"><input  class=\"abp inputbox\" name=\"posterHomepage\" size=\"40\" value=\"http://\" /></dd>";
	 echo "<dt class=\"apb\">Your Comment (mandatory):</dt><dd class=\"apb\"><textarea class=\"abp inputbox\" name=\"posterComment\" cols=\"40\" rows=\"6\" ></textarea></dd>";
	 echo "<dt>&nbsp;</dt><dd class=\"apb\"><img alt=\"OHowWeLaughed\" src=\"./apbMakeCaptcha.php\"  title=\"SecCode\" /></dd>";
	 echo "<dt>Enter the Code displayed above:</dt><dd class=\"apb\"><input type=\"text\" size=\"4\" name=\"secCode\" /></dd>";
	 echo "<dt>&nbsp;</dt><dd class=\"apb\"><input class=\"inputbox myButton\"  type=\"submit\" value=\"Submit\" />";
	 echo "<input style=\"display: none;\" name=\"do\" value=\"comment\" />";
	 echo "<input style=\"display: none;\" name=\"posterId\" value=\"$thisId\" />";
	 echo "<input style=\"display: none;\" name=\"posterThisShow\" value=\"".urlencode($_SERVER['REQUEST_URI'])."\" />";
	 echo "</dd>";
	 echo "</dl>";
	 echo "</form>";
	 echo "</div>"; // End hide
	 echo "</div>"; // End Form
	 return;
      }

      /*!
      Print the <div> that provides a list of all available tags.
      */
      public function printTags($connectMyselfToMysql=FALSE)
      {
	 if($connectMyselfToMysql) $this->mysqlConnect();
	 $buffer=$this->mysqlQuery("select * from ".$this->apbPrefix."tags");
	 $nTags=mysql_num_rows($buffer);
	 if($nTags >= 1)
	 {
	    echo "<div class=\"apb tagList\" id=\"apbTagList\">";
	    // parse the mysql-query into a php array, so we can use php-array functions
	    echo "<ul class=\"apb tagList\">";
	    echo "<li class=\"apb tagList\">";
	    echo "Tags:";
	    echo "</li>";
	    while ($tagEntry = mysql_fetch_assoc($buffer))
	    {
	       // we need tagNames to create the unique and sorted tag-list
	       $tagNames[$tagEntry['id']]=$tagEntry['tag'];
	    }

	    $tagNames=(array_unique($tagNames));
	    asort($tagNames);
	    echo "<li class=\"apb tagList\">";
	    echo "<a class=\"apb taglist\" href=\"".$_SERVER['PHP_SELF']."?do=index\">";
	    if($this->getTag) echo "[SELECT ALL]";
	    else echo "<span class=\"tagHighlight\">[ALL]</span>";

	    echo "</a>";
	    echo "</li>";

	    foreach ($tagNames as $tag)
	    {
	       echo "<li class=\"apb tagList\">";
	       echo "<a rel=\"tag\" class=\"apb\" href=\"".$_SERVER['PHP_SELF']."?do=index&amp;tag=";
	       echo urlencode($tag)."\">";
	       if($this->getTag && $this->getTag == $tag) echo "<span class=\"tagHighlight\">$tag</span>";
	       else echo $tag;
	       echo "</a>";
	       echo "</li>";
	    }
	    echo "</ul>";
	    echo "</div>"; // End of apbTags
	 }

	 if($connectMyselfToMysql) $this->mysqlDisconnect();
      }

      /*!
      This is the ultimate resizer-method. Its arguments are self-explaining.
      It returns a pointer to the new image.
      */
      public function resizeImage
      (
	 $uploadedClientFileName,
	 $serverTempFileName,
	 $imageMaxWidth = 850,
	 $imageMaxHeight = 600,
	 $quality=90,
	 $embedThisCopyright=TRUE
      )
      {
	 preg_match("/(\.\w+)$/",$uploadedClientFileName,$match); $uploadedFileType = strtolower($match[1]);

	 if(!in_array($uploadedFileType, array(".jpg",".jpeg",".png")))
	 die ("<p class=\"apb form error\">*** Error: File Format $uploadedFileType NOT SUPPORTED</p><p class=\"apb form\">Currently, only JPEG and PNG files are supporten.</p>");

	 //$serverTempFileName='/home/sascha/public_html/sascha/gallery/blog/blabla';
	 switch ($uploadedFileType)
	 {
	    case ".jpg":
	    case ".jpeg":
	       //	       $image = @imagecreatefromjpeg($serverTempFileName);
	       $image = imagecreatefromjpeg($serverTempFileName);
	       break;
	    case ".png":
	       //	       $image = @imagecreatefrompng($serverTempFileName);
	       $image = imagecreatefrompng($serverTempFileName);
	       break;
	    default:
	       break;
	 }

	 list($oldWidth, $oldHeight) = getimagesize($serverTempFileName);
	 echo "<li class=\"apb form\">Original Image size: $oldWidth x $oldHeight<class=\"apb form\"/>";
	 if (($oldWidth > $imageMaxWidth) || ($oldHeight > $imageMaxHeight))
	 {
	    echo "<li class=\"apb form\">I will resize this image.</li>";
	    $widthRatio = $oldWidth / $imageMaxWidth;
	    $heightRatio = $oldHeight / $imageMaxHeight;
	    if ($widthRatio >= $heightRatio)
	    {
	       $newWidth = $imageMaxWidth;
	       $newHeight = (int) ($oldHeight / $widthRatio);
	    }
	    else
	    {
	       $newHeight = $imageMaxHeight;
	       $newWidth = (int) ($oldWidth / $heightRatio);
	    }
	    echo "<li class=\"apb form\">Image size: $newWidth x $newHeight</li>";
	    $newImage = @imagecreatetruecolor($newWidth, $newHeight);
	    imagecopyresampled($newImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $oldWidth, $oldHeight);
	    echo "<li class=\"apb form\">Resampled </li>";
	 }
	 else
	 {
	    echo "<li class=\"apb form\">I did NOT resize this image.</li>";
	    $newImage = $image;
	 }

	 // Embbed copyright for highRes pictures
	 if($this->embedCopyright && $embedThisCopyright)
	 {
	    $string= "Copyright ".date("Y",time())." by ".$this->blogOwner;
	    $gray = imagecolorallocate($newImage,200,200,200);
	    $darkgray = imagecolorallocate($newImage,40, 40, 40);
	    $px = 5;
	    $py = (imagesy($newImage) - 14);
	    imagefilledrectangle ( $newImage, 0, $py, 250, ($py+20), $darkgray);
	    imagestring($newImage, 2, $px, $py, $string, $gray);
	    echo "<p>Copyright tag embedded</p>";
	 }

	 // And return the pointer to the image (I hope, it's just the pointer ...)
	 return $newImage;
      }

      /*!
         For a selected tag (argument of this member),
	 return the tag Id.
	 Connection to mysql-Server MUST have been established BEFORE
	 calling this method.
       */
      private function getSelectedTagString($selTag)
      {


	 $query="select * from ".$this->apbPrefix."tags where tag=\"$selTag\";";
	 $buffer=$this->mysqlQuery($query);

	 $nPics=mysql_num_rows($buffer);
	 if ($nPics == 0)
	 {
	    echo "<p class=\"apb\">No pictures tagged &quot;$selTag&quot; available...</p>";
	    return;
	 } else
	 {
	    $k=1;
	    $selTagId="";
	    while ($entry = mysql_fetch_assoc($buffer))
	    {
	       $selTagId.="id=".$entry['entryId'];
	       if(($k++ != $nPics) ) $selTagId.=" or ";
	    }
	 }
	 return $selTagId;
      }

      /*!
      Show the index, archive, or browser of all your images ($selTag=MAGIC)
      or of a certain tag, that is given by the only argument of this method.
      */
      public function index($selTag="9x98ex9MAGIC")
      {
	 $pCount=0; // Column counter

	 $this->mysqlConnect();

	 if($selTag=="9x98ex9MAGIC") // Select all
	 {
	    $query="select * from ".$this->apbPrefix."entries order by phpTimeStamp desc;";
	 } else // Only select tagged
	 {
	    $tagQuery=$this->getSelectedTagString($selTag);
	    if(!$tagQuery) { return -1; };
	    $query="select * from ".$this->apbPrefix."entries where ";
	    $query.=$tagQuery;
	    $query.=" order by phpTimeStamp desc;";
	 }

	 $buffer=$this->mysqlQuery($query);
	 $nPics=mysql_num_rows($buffer);
	 echo "<div class=\"apb index\" id=\"apbIndex\">";

	 if ($nPics == 0)
	 {
	    echo "\n<p class=\"apb\">No pictures available, yet</p>";
	 } else
	 {
	    //	    echo "<p class=\"apb\">$nPics picture(s) available</p>";


	    echo "<table class=\"apb index\" id=\"apbIndexTable\" >";
	    while ($entry = mysql_fetch_assoc($buffer))
	    {
	       $urlTn=$entry['tnLink'];
	       $url=$entry['picLink'];
	       $pId=$entry['id'];
	       $alt=$entry['title'];
	       $title=$alt;
	       if ($pCount==0) echo "<tr class=\"apb index\">";
	       echo "  <td class=\"apb index\">";
	       echo "<table class=\"apb index thumbnail\" id=\"abpPic$pId\"><tr class=\"apb index thumbnail\">";
	       echo "<td class=\"apb index thumbnail\"";
	       //	       echo " style=\"";
	       //	       echo "height:".$this->thumbnailHeight."px; width:".$this->thumbnailWidth."px";
	       //	       echo "\"";
	       echo ">\n";
	       echo '<a class="apb index thumbnail" href="';
	       echo $_SERVER['PHP_SELF'];
	       echo "?do=show&amp;photoId=".$pId;
	       if($selTag!="9x98ex9MAGIC") echo "&amp;tag=".$selTag;
	       echo "\">";
	       echo "         <img class=\"apb index thumbnail\" alt=\"".$alt."\" src=\"$urlTn\"";
	       echo " />"."\n";;
	       echo "     </a>\n";
	       echo "</td></tr>";
	       if($this->showTitleInIndex)
	       {
		  echo "<tr class=\"apb index indexTitle\"><td class=\"apb index indexTitle\"";
		  echo ">";
		  echo $title;
		  echo "</td></tr>";
	       }
	       // IF ADMIN
	       if($this->access)
	       {
		  echo "<tr class=\"apb index admin\">";
		  echo "<td  class=\"apb index admin\"> ";
		  echo "<ul class=\"apb index edit admin\">";
		  echo "<li class=\"apb index edit admin\">";
		  echo '<a href="';
		  echo $_SERVER['PHP_SELF']."?do=edit&amp;photoId=$pId \">";
		  echo "Edit";
		  echo "</a>";
		  echo "</li>";
		  echo "<li class=\"apb index edit admin\">";
		  echo '<a href="';
		  echo $_SERVER['PHP_SELF']."?do=delete&amp;photoId=$pId \">";
		  echo "Delete";
		  echo "</a>";
		  echo "</li></ul>";
		  echo "</td></tr>";
	       } // ENDIF admin
	       echo "</table>\n";
	       echo "  </td>";

	       if ($pCount==$this->maxRows-1) { echo "</tr>"; $pCount=-1; }
	       $pCount++;
	    }
	    if ($pCount != 0) echo '</tr>';
	    echo "</table>\n"; // End Table
	 }
	 echo "</div>\n"; // End of PhotoIndex
      }

      private function checkLogin()
      {
	 echo "<div class=\"apb form\" id=\"apbLoginForm\" >";
	 echo "<h1>Admin Login Evaluation</h1>";
	 $this->admin->checkPw($_POST['username'],$_POST['password']);
	 echo "</div>";
      }

      /*!
      Redefinition of the Admin::logout()-Method.
      */
      private function logout()
      {
	 echo "<div class=\"apb form\" id=\"apbLogoutForm\" >";
	 echo "<h1>Admin Logout</h1>";
	 $this->admin->logout();
	 echo "</div>";
	 return;
      }

      /*!
      Just use Admin::login within native <div> and <h1>
      */
      private function printLoginForm()
      {
	 echo "<div class=\"apb loginForm\" id=\"apbLoginForm\" >";
	 echo "<h1 class=\"apb form\">Admin Login</h1>";
	 $this->admin->login();
	 echo "</div>";
	 return;
      }

      /*!
      React on access-request.
      */
      private function accessError()
      {
	 if(!$this->access)
	 {
	    echo '<p class="apb error">ACCESS DENIED!!!</p>';
	    return TRUE;
	 } else return FALSE;
      }

      /*!
      This method prints the form for uploading an image.
      */
      public function printUploadForm()
      {
	 echo "<div class=\"apb form\" id=\"apbUploadForm\">";
	 echo "<h1>Upload a new photo</h1>";
	 echo "<form enctype=\"multipart/form-data\" method=\"post\" action=\"";
	 echo $_SERVER['PHP_SELF']."\">";
	 echo "<dl>";
	 echo "<dt class=\"apb form\">File:</dt><dd class=\"apb form\"><input  class=\"abp inputbox\" type=\"file\" name=\"textfile\" size=\"40\" /></dd>";
	 echo "<dt class=\"apb form\">Title:</dt><dd class=\"apb form\"><input  class=\"abp inputbox\" name=\"title\" size=\"40\" value=\"\" /></dd>";
	 echo "<dt class=\"apb form\">Tags (Comma seperated, english letters ONLY):</dt><dd class=\"apb form\"><input  class=\"abp inputbox\" name=\"tag\" size=\"40\" value=\"\" /></dd>";
	 echo "<dt class=\"apb form\">Date:</dt><dd class=\"apb form\"><input  class=\"abp inputbox\" name=\"date\" size=\"10\" value=\"".date("Y-m-d",time())."\" /></dd>";
	 echo "<dt class=\"apb form\">Comment:</dt><dd class=\"apb form\"><textarea class=\"abp inputbox\" name=\"comment\" cols=\"40\" rows=\"6\" ></textarea></dd>";
	 echo "<dt>&nbsp;</dt><dd class=\"apb form\"><input class=\"inputbox myButton\"  type=\"submit\" value=\"Start Upload\" />";
	 echo "<input style=\"display: none\" name=\"do\" value=\"save\" />";
	 echo "</dd>";
	 echo "</dl>";
	 echo "</form>";
	 echo "</div>";

	 return TRUE;
      }

      /*!
      Parse and errorcheck the data provided by the form for uploading a new picture.
      */
      private function parseUploadForm($customTime=FALSE)
      {
	 // --------------- Error Check Tag
	 if (preg_match("/[^a-zA-Z0-9 ,]/i",$_POST['tag'])) die("*** ERROR: Your tag must not contain any other than alphanumeric letters: a-z A-Z and 0-9");

	 // --------------- Error Check T
	 if (preg_match("/[^a-zA-Z0-9 ,]/i",$_POST['tag'])) die("*** ERROR: Your tag must not contain any other than alphanumeric letters: a-z A-Z and 0-9");

	 // --------------- Date parsing and date error check
	 if($customTime) $currentTime=date("His",$customTime);
	 else $currentTime=date("His",time());

	 $sentDate=explode("-",$_POST['date']);
	 if (strlen($sentDate[0])>4) die("*** ERROR: Year too long: $sentDate[0]");
	 if (strlen($sentDate[0])<4) die("*** ERROR: Year too short: $sentDate[0]");
	 if (strlen($sentDate[1])<2) $sentDate[1]="0".$sentDate[1];
	 if (strlen($sentDate[1])>2) die("*** ERROR: Month too long: $sentDate[1]");
	 if (strlen($sentDate[2])<2) $sentDate[2]="0".$sentDate[2];
	 if (strlen($sentDate[2])>2) die("*** ERROR: Day too long: $sentDate[2]");
	 $back['timeStamp']=mktime(
	    substr($currentTime,0,2),
	    substr($currentTime,2,2),
	    substr($currentTime,4,2),
	    $sentDate[1],
	    $sentDate[2],
	    $sentDate[0]
	 );
	 return $back;
      }

      /*!
      Set this classes parameters that deal with the location of the picture.
      The picture-name is assembled using the filename and a certain timestamp.
      Latter is the string argument of this method.
      */
      private function setPicLocation($timeStamp)
      {

	 $fileName=$this->fileName;
	 $this->target=$this->picPath."/".$timeStamp."-".$fileName;
	 $this->targetTn=$this->picPath."/".$timeStamp."-tn_".$fileName;

	 $this->targetUrl=$this->picUrl."/".$timeStamp."-".$fileName;
	 $this->targetTnUrl=$this->picUrl."/".$timeStamp."-tn_".$fileName;

	 return;
      }


      /*!
      Try and save the new file, if all errorchecks were passed.
      This method performs all necessary steps like parsing and
      errorchecking, resizing of the image, naming the files,
      updating the feeds and finally, saving and chmodding the
      image and its thumbnail.
      */
      private function saveNewFile($files)
      {
	 $source=$files['textfile']['tmp_name'];
	 $fileName=$this->fileName=$files['textfile']['name'];
	 $picPath=$this->picPath;
	 echo "<div class=\"apb form\" id=\"apbUploadStatus\">";

	 echo "<ul class=\"apb form\">";

	 $back=$this->parseUploadForm();
	 $timeStamp=$back['timeStamp'];
	 // Parse Filename

	 preg_match("/(\.\w+)$/",$_FILES["textfile"]["name"],$match);
	 $uploadedFileType = strtolower($match[1]);

	 echo "<li class=\"apb form\">File type is: ".$uploadedFileType."</li>";

	 $this->setPicLocation($timeStamp);


	 // --------------- RESIZE IMAGE
	 if(is_uploaded_file($_FILES["textfile"]["tmp_name"]))
	 {
	    echo "<li class=\"apb form\">Resizing Image (may take a while, hold on)</li>";
	    $newImageL=$this->resizeImage($_FILES["textfile"]["name"],$_FILES["textfile"]['tmp_name'], $this->largeImageWidth, $this->largeImageHeight, 95,TRUE);
	    $newImageS=$this->resizeImage($_FILES["textfile"]["name"],$_FILES["textfile"]['tmp_name'], $this->thumbnailWidth, $this->thumbnailHeight , 95,FALSE);
	    switch ($uploadedFileType)
	    {
	       case ".jpg":
	       case ".jpeg":
		  echo "<li class=\"apb form\">Jpg ...";
		  imagejpeg($newImageL,$this->target,($this->jpegQuality)-5);
		  imagejpeg($newImageS,$this->targetTn,$this->jpegQuality);
		  echo " resized</li>";
		  $mime='image/jpeg';
		  break;
	       case ".png":
		  echo "<li class=\"apb form\">PNG ...";
		  imagepng($newImageL,$this->target);
		  imagepng($newImageS,$this->targetTn);
		  echo " resized</li>";
		  $mime='image/png';
		  break;
	       case ".gif":
		  imagegif($newImageL,$this->target);
		  imagegif($newImageS,$this->targetTn);
		  $mime='image/gif';
		  break;
	       default:
		  break;
	    }
	    // Change Access rights
	    if(chmod($this->target, 0644) && chmod($this->targetTn, 0644))
	    echo "<li class=\"apb form\" >Also, access rights have been changed correctly</li>";
	    else
	    echo "<li class=\"apb form\" style=\"font-size: x-large\">*** ERROR: Could not change access rights!</li>";
	    echo "</ul>";
	 } else die ("<p class=\"apb error\" style=\"font-size: x-large\">*** ERROR: Could not upload image</p>");

	 $entryId=$this->createMysqlEntry($timeStamp);

	 $this->createAtomEntry($mime,$entryId);

	 $this->createRssEntry($entryId);
	 echo "<p class=\"apb form success\" style=\"font-size: x-large\">";
	 echo "SUCCESS!!!";
	 echo "</p>";
	 echo "</div>";
      }

      /*!
      Print the form to edit a pictures properties.
      This method is privat, so it MUST be called from a navigator from
      within this object.
      */
      private function printEditForm($getpId)
      {
	 $tagString="";
	 $pId=(int) $getpId;

	 $this->mysqlConnect();
	 $query="select * from ".$this->apbPrefix."entries where id=".$pId;
	 $buffer=$this->mysqlQuery($query);
	 $nPics=mysql_num_rows($buffer);
	 if($nPics)
	 {
	    $entries=mysql_fetch_assoc($buffer);
	    $query="select * from ".$this->apbPrefix."tags where entryId=".$pId;
	    $buffer=$this->mysqlQuery($query);

	    while($tags=mysql_fetch_assoc($buffer)) $tagString.=$tags['tag'].", ";

	    // Replace terminal ,
	    $tagString=substr_replace($tagString,"",strrpos($tagString,","));

	    echo "<div id=\"apbEditPicture\" class=\"apb form\" >";
	    echo "<h1>Edit Picture Data</h1>";
	    echo "<form method=\"post\" action=\"";
	    echo $_SERVER['PHP_SELF']."\">";
	    echo "<dl>";
	    echo "<dt class=\"apb form\">Title:</dt><dd class=\"apb form\"><input  class=\"abp inputbox\" name=\"title\" size=\"40\" value=\"".$entries['title']."\" /></dd>";
	    echo "<dt class=\"apb form\">Tag:</dt><dd class=\"apb form\"><input  class=\"abp inputbox\" name=\"tag\" size=\"40\" value=\"$tagString\" /></dd>";
	    echo "<dt class=\"apb form\">Date:</dt><dd class=\"apb form\"><input  class=\"abp inputbox\" name=\"date\" size=\"10\" value=\"".date("Y-m-d",$entries['phpTimeStamp'])."\" /></dd>";
	    echo "<dt class=\"apb form\">Comment:</dt><dd class=\"apb form\"><textarea class=\"abp inputbox\" name=\"comment\" cols=\"40\" rows=\"6\" >".$entries['comment']."</textarea></dd>";
	    echo "<dt>&nbsp;</dt><dd class=\"apb form\"><input class=\"inputbox myButton\"  type=\"submit\" value=\"Submit Changes\" />";
	    echo "<input style=\"display: none\" name=\"do\" value=\"doEdit\" />";
	    echo "<input style=\"display: none\" name=\"oldDate\" value=\"".$entries['phpTimeStamp']."\" />";
	    echo "<input style=\"display: none\" name=\"pId\" value=\"".$pId."\" />";
	    echo "<input style=\"display: none\" name=\"fileName\" value=\"".$entries['fileName']."\" />";
	    echo "</dd>";
	    echo "</dl>";
	    echo "</form>";

	 } else
	 {
	    echo "<p class=\"apb error \">ERROR: No picture with Id $pId available!</p>";
	 }

	 $this->mysqlDisconnect();

	 echo "</div>";
	 return TRUE;
      }

      /*!
      Proceed the data sent by the printEdirForm(). This method
      updates the feeds and mysql-database.
      */
      private function editPicture()
      {
	 $oldTimeStamp=$_POST['oldDate'];
	 $pId=$_POST['pId'];
	 $this->fileName=$_POST['fileName'];

	 echo "<div class=\"apb form\" id=\"apbEditPicture\">";
	 echo "<h1>Edit Picture</h1>";

	 $back=$this->parseUploadForm();

	 // Has Date Changed? If yes, we have to create a new Timestamp
	 // and re-save the file
	 $newTimeStamp=$back['timeStamp'];

	 $oldTime=date("H:i:s",$oldTimeStamp); $oldDate=date("Y-m-d",$oldTimeStamp);
	 $newTime=date("H:i:s",$newTimeStamp); $newDate=date("Y-m-d",$newTimeStamp);

	 $changeDate = $oldDate != $newDate ? TRUE : FALSE;

	 if(!$changeDate) // Easy Case: Date has not changed, just update feeds and MySQLDB
	 {
	    // Create Picture Location Parameters of this object
	    $this->setPicLocation($oldTimeStamp);

	    // Update MySQL Entry
	    $this->editMySQLEntry($pId,$oldTimeStamp);
	    $status['atom']=$this->editAtomEntry($pId,$oldTimeStamp);
	    $status['rss']=$this->editRssEntry($pId,$oldTimeStamp);
	 }
	 else
	 {
	    // Remember Old Location
	    $this->setPicLocation($oldTimeStamp);
	    $oldTargetPath=$this->target;
	    $oldTargetTnPath=$this->targetTn;

	    $this->setPicLocation($newTimeStamp);

	    copy($oldTargetPath,$this->target)
	    or die('<p class="apb error form">ERROR: Could Not Copy Picture File! Check your permissions of the filesystem</p>');
	    copy($oldTargetTnPath,$this->targetTn)
	    or die('<p class="apb error form">ERROR: Could Not Copy Picture File! Check your permissions of the filesystem</p>');
	    unlink($oldTargetPath)
	    or die('<p class="apb error form">ERROR: Could Not Copy Picture File! Check your permissions of the filesystem</p>');
	    unlink($oldTargetTnPath)
	    or die('<p class="apb error form">ERROR: Could Not Copy Picture File! Check your permissions of the filesystem</p>');

	    $this->editMySQLEntry($pId,$newTimeStamp);
	    $status['atom']=$this->editAtomEntry($pId,$oldTimeStamp,$newTimeStamp);
	    $status['rss']=$this->editRssEntry($pId,$oldTimeStamp);

	 }

	 $status['atom']=TRUE;

	 if(!$status['atom'])
	 {
	    echo '<p class="apb error form">ERROR: Could not update Atom-Feed File</p>';
	    exit;
	 }
	 else echo '<p class="apb success form">SUCCESS</p>';

	 echo "</div>";
	 return;
      }


      /*!
      This method deletes a picture. For security reasons, this one is private, too.
      Calling this method comprises updating the feeds and the mysql-db, as well as
      removing the image-files from disk. The only argument is an integer that equals
      the id of the picture in the mysql-db.
      */
      private function deletePicture($getpId)
      {
	 echo "<div class=\"apb form\" id=\"apbDeletePicture\">";
	 echo "<h1>Deleting Picture</h1>";
	 $pId=(int) $getpId;
	 $timeStamp=$this->deleteMySQLEntry($pId);

	 if(!$timeStamp) echo "<p class=\"apb form error\">Could not clean MySQL-Entry. Aborting.</p>";
	 else
	 {
	    echo "<p class=\"apb form success\">MySQL-Entry cleaned...</p>";

	    if(!$this->deleteAtomEntry($timeStamp)) die('<p class="apb form error">WARNING: Could not updated atom.xml!</p>');
	    else echo "<p class=\"apb form success\">Atom-Feed update successful...</p>";

	    if(!$this->deleteRssEntry($timeStamp)) die('<p class="apb form error">WARNING: Could not updated rss.xml!</p>');
	    else echo "<p class=\"apb form success\">Rss-Feed update successful...</p>";

	    if(!$this->deleteFiles($timeStamp)) die('<p class="apb form error">ERROR: Could not delete files!</p>');
	    else echo "<p class=\"apb form success\">File deletion successful...</p>";

	    echo "<p class=\"apb form success\" >";
	    echo "SUCCESS!!!";
	    echo "</p>";
	 }
	 echo "</div>";
	 return;
      }

      /*!
      Delete image files, called from within AtomPhotoBlog::deletePicture().
      */
      private function deleteFiles($timeStamp)
      {
	 $status=FALSE;

	 $fileName=$this->picPath."/".$timeStamp.'*';


	 $dh=opendir($this->picPath);
	 while (($entry = readdir($dh) ))
	 {
	    if ( ereg($timeStamp,$entry))
	    {
	       $status=TRUE;
	       $fileName=$this->picPath."/".$entry;
	       unlink($fileName);
	    }
	 }

	 return $status;
      }

      /*!
      This private method updates an entry of the atom-feed. DO NOT TOUCH THESE
      LINES UNLESS YOU EXACTLY KNOW WHAT YOU ARE DOING!
      */
      private function editAtomEntry($pId,$oldTimeStamp,$newTimeStamp=FALSE)
      {
	 $status=TRUE;
	 if(!$newTimeStamp) $newTimeStamp=$oldTimeStamp;

	 if(!$this->isLoadAtom) $this->readAtom();
	 $feed=$this->db->documentElement;

	 $xpath = new DOMXPath($this->db);
	 $xpath->registerNamespace('pf', 'http://www.w3.org/2005/Atom');

	 // Identify entry by timestamp in link-attribute (this one is unique ... hopefully)
	 $query = "//pf:feed/pf:entry/pf:link[contains(@href,$oldTimeStamp)]";
	 $entries = $xpath->query($query);

	 $nEntries=$entries->length;
	 if($nEntries==1)
	 {
	    $parentNode=$entries->item(0)->parentNode;
	    // Remember old id
	    $oldId=$parentNode->getElementsByTagName('id')->item(0)->nodeValue;

	    // Remember mime-type
	    $mime=$entries->item(0)->getAttribute('type');

	    // Remove old entry
	    $feed->removeChild($parentNode);

	    // Create Atom Entry
	    $this->createAtomEntry($mime,$pId,$oldId);
	 }
	 else $status=FALSE;

	 return $status;
      }

      /*!
      This private method deletes an entry of the atom-feed. DO NOT TOUCH THESE
      LINES UNLESS YOU EXACTLY KNOW WHAT YOU ARE DOING!
      */
      private function deleteAtomEntry($timeStamp)
      {
	 $status=TRUE;

	 if(!$this->isLoadAtom) $this->readAtom();
	 $feed=$this->db->documentElement;

	 $xpath = new DOMXPath($this->db);
	 $xpath->registerNamespace('pf', 'http://www.w3.org/2005/Atom');

	 // Identify entry by timestamp in link-attribute (this one is unique ... hopefully)
	 $query = "//pf:feed/pf:entry/pf:link[contains(@href,$timeStamp)]";
	 $entries = $xpath->query($query);

	 $nEntries=$entries->length;
	 if($nEntries==1) $feed->removeChild($entries->item(0)->parentNode);
	 else $status=FALSE;

	 $this->db->save($this->atomFile);
	 return $status;
      }

      /*!
      This private method deletes an entry of the rss-feed. DO NOT TOUCH THESE
      LINES UNLESS YOU EXACTLY KNOW WHAT YOU ARE DOING!
      */
      private function deleteRssEntry($timeStamp)
      {
	 $status=TRUE;

	 if(!$this->isLoadRss) $this->readRss();
	 $rss=$this->dbRss->documentElement;

	 $xpath = new DOMXPath($this->dbRss);

	 // Identify entry by timestamp in link-attribute (this one is unique ... hopefully)
	 $query = "//rss/channel/item/content:encoded[contains(.,$timeStamp)]";
	 $entries = $xpath->query($query);

	 if($entries->length)
	 {
	    $nEntries=$entries->length;
	    $parentNode=$entries->item(0)->parentNode->parentNode;
	    if($nEntries==1) $parentNode->removeChild($entries->item(0)->parentNode);
	    else $status=FALSE;

	    $this->dbRss->save($this->rssFile);
	 } else
	 {
	    $status=FALSE;

	 }
	 return $status;
      }


      /*!
      This private method edits an entry of the rss-feed. DO NOT TOUCH THESE
      LINES UNLESS YOU EXACTLY KNOW WHAT YOU ARE DOING!
      */
      private function editRssEntry($pId,$timeStamp)
      {
	 $status=TRUE;

	 if(!$this->isLoadRss) $this->readRss();
	 $rss=$this->dbRss->documentElement;

	 $xpath = new DOMXPath($this->dbRss);

	 // Identify entry by timestamp in link-attribute (this one is unique ... hopefully)
	 $query = "//rss/channel/item/content:encoded[contains(.,$timeStamp)]";
	 $entries = $xpath->query($query);

	 if($entries->length)
	 {
	    $nEntries=$entries->length;
	    $parentNode=$entries->item(0)->parentNode->parentNode;
	    echo $nEntries;

	    if($nEntries==1) {
	       if(!$parentNode->removeChild($entries->item(0)->parentNode))
	       die('<p class="apb error form">COULD NOT REMOVE ITEM FROM RSS-FILE</p>');
	    }
	    else $status=FALSE;

	    if(!$status) die('<p class="apb error form">COULD NOT REMOVE ITEM FROM RSS-FILE because there isn\'t exactly ONE item</p>');

	    $this->createRssEntry($pId);
	 } else
	 {
	    $status=FALSE;

	 }
	 return $status;
      }


      /*!
      This private method edits an mysqlentry. DO NOT TOUCH THESE
      LINES UNLESS YOU EXACTLY KNOW WHAT YOU ARE DOING!
      */
      private function editMySQLEntry($pId,$timeStamp)
      {
	 $this->mysqlConnect();

	 // Update Entries Table
	 $rowData=array(
	    "title"=>htmlentities($_POST['title']),
	    "comment"=>htmlentities($_POST['comment']),
	    "picLink"=>$this->targetUrl,
	    "tnLink"=>$this->targetTnUrl,
	    "time"=>date("H:i:s", $timeStamp),
	    "date"=>date("Y-m-d", $timeStamp),
	    "year"=>date("Y", $timeStamp),
	    "phpTimeStamp"=>$timeStamp,
	    "IP"=>$_SERVER['REMOTE_ADDR']
	 );

	 $where="id=$pId";
	 $this->mysqlUpdateRow($rowData,$this->apbPrefix."entries",$where);


	 // Update Tag Table
	 $query="delete from ".$this->apbPrefix."tags where entryId=$pId";
	 $this->mysqlQuery($query);
	 $this->mysqlStoreTag($this->htmlRecode($_POST['tag']),$pId);

	 $this->mysqlDisconnect();
	 return;
      }

      /*!
      This private method deletes an mysqlentry. DO NOT TOUCH THESE
      LINES UNLESS YOU EXACTLY KNOW WHAT YOU ARE DOING!
      */
      private function deleteMySQLEntry($pId)
      {
	 $tnTimeStamp=FALSE;
	 $this->mysqlConnect();


	 echo "<p>Request for deletion of picture Id $pId </p>";

	 $query="select * from ".$this->apbPrefix."entries where id=".$pId;

	 $buffer=$this->mysqlQuery($query);

	 $nPics=mysql_num_rows($buffer);
	 if($nPics)
	 {
	    $thisPic=mysql_fetch_assoc($buffer);
	    $tnTimeStamp=$thisPic['phpTimeStamp'];

	    $query="delete from ".$this->apbPrefix."entries where id=".$pId;
	    $buffer=$this->mysqlQuery($query);

	    $query="delete from ".$this->apbPrefix."tags where entryId=".$pId;
	    $buffer=$this->mysqlQuery($query);

	    $query="delete from ".$this->apbPrefix."comments where entryId=".$pId;
	    $buffer=$this->mysqlQuery($query);


	 } else
	 {
	    echo "<p class=\"apb error \">ERROR: No picture with Id $pId available!</p>";
	 }


	 $this->mysqlDisconnect();

	 return $tnTimeStamp;
      }

      /*!
      This private method creates an mysqlentry for a picture. 
      DO NOT TOUCH THESE LINES UNLESS YOU EXACTLY KNOW WHAT YOU ARE DOING!
      */
      private function createMysqlEntry($timeStamp)
      {
	 // Cosmetic String Stuff

	 $cleanTitle=$this->htmlRecode($_POST['title']);
	 $cleanComment=$this->htmlRecode($_POST['comment']);
	 $cleanTag=$this->htmlRecode($_POST['tag']);

	 // --------------- Create MySQL Entry
	 $queryEntry=array(
	    "title"=>htmlentities($_POST['title']),
	    "comment"=>htmlentities($_POST['comment']),
	    "fileName"=>$this->fileName,
	    "picLink"=>$this->targetUrl,
	    "tnLink"=>$this->targetTnUrl,
	    "time"=>date("H:i:s", $timeStamp),
	    "date"=>date("Y-m-d", $timeStamp),
	    "year"=>date("Y", $timeStamp),
	    "phpTimeStamp"=>$timeStamp,
	    "IP"=>$_SERVER['REMOTE_ADDR']
	 );

	 $this->mysqlConnect();
	 $this->mysqlStoreRow($queryEntry,$this->apbPrefix.'entries');

	 // Find out the id of the entry that was store
	 $buffer=mysql_fetch_assoc($this->mysqlQuery('select id from `'.$this->apbPrefix.'entries` where phpTimeStamp="'.$timeStamp.'";'));
	 $entryId=$buffer['id'];

	 // Store the tags
	 $this->mysqlStoreTag($cleanTag,$entryId);
	 $this->mysqlDisconnect();
	 return $entryId;
      }

      /*!
      This private method creates an mysqlentry for a tag. 
      DO NOT TOUCH THESE LINES UNLESS YOU EXACTLY KNOW WHAT YOU ARE DOING!
      */
      private function mysqlStoreTag($cleanTag,$entryId)
      {
	 $tagArray=explode(",",$cleanTag); // Disassemble Tags
	 foreach($tagArray as $tag)
	 {
	    $tag=trim($tag);
	    if(preg_match("/[a-zA-Z0-9 ]/i", $tag))
	    {
	       $queryTag=array(
		  "tag"=>$tag,
		  "entryId"=>$entryId
	       );
	       $this->mysqlStoreRow($queryTag,$this->apbPrefix.'tags');
	    } else if($tag != '') echo "<p class=\"warning\">*** WARNING: Tag '".$tag."' was NOT saved</p>";
	 }

	 return;
      }

      /*!
      This private method appends (NOT INITIALIZES) an RSS-Entry. 
      DO NOT TOUCH THESE LINES UNLESS YOU EXACTLY KNOW WHAT YOU ARE DOING!
      */
      private function createRssEntry($entryId)
      {
	 $myFirstChild=NULL;
	 //	 echo "<li>Appending Rss-entry</li>";
	 if(!$this->isLoadRss) $this->readRss();

	 $rss=$this->dbRss->documentElement;
	 $channel=$this->dbRss->getElementsByTagName("channel")->item(0);

	 
	 // Distinguish between first entry and further entries. We need to insert
	 // new element atop rather than to append.
	 $myFirstChild=$channel->getElementsByTagName("item");
	 if($myFirstChild->length)
	    $item=$channel->insertBefore($this->dbRss->createElement('item'),$myFirstChild->item(0));
	 else
	    $item=$channel->appendChild($this->dbRss->createElement('item'));
	 
	 $title=$item->appendChild($this->dbRss->createElement('title',utf8_encode($this->htmlRecodeLight($_POST['title']))));

	 $targetLoader="http://".$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'].'?do=show&amp;photoId='.$entryId;
	 $link=$item->appendChild($this->dbRss->createElement('link',utf8_encode($targetLoader)));

	 $pubDate=$item->appendChild($this->dbRss->createElement('pubDate',date("r",time())));

	 $guid=$item->appendChild($this->dbRss->createElement('guid',$this->xmlRecode(utf8_encode($targetLoader))));
	 $guid->setAttribute('isPermaLink','true');

	 $description=$item->appendChild($this->dbRss->createElement('description'));
	 $description->nodeValue=(utf8_encode($this->htmlRecodeLight($_POST['comment'])));

	 $content=$item->appendChild($this->dbRss->createElement('content:encoded'));
	 $cDataString ='<p><a href="http://'.$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'].'?do=show&photoId='.$entryId.'"> ';
	 $cDataString.='<img';
	 $cDataString.=' src="'.$this->xmlRecode(utf8_encode($this->targetTnUrl)).'" ';
	 $cDataString.=' alt="'.$this->xmlRecode(utf8_encode($_POST['title'])).'"';
	 $cDataString.=' />';
	 $cDataString.='</a></p>';
	 $cDataString.='<p>'.utf8_encode($this->htmlRecodeLight($_POST['comment'])).'</p>';
	 $CDATA=$content->appendChild($this->dbRss->createCDATASection( $cDataString));

	 $this->dbRss->getElementsByTagName('lastBuildDate')->item(0)->nodeValue=date("r",time());
	 $this->dbRss->getElementsByTagName('pubDate')->item(0)->nodeValue=date("r",time());

	 $this->dbRss->save($this->rssFile);
      }

      /*!
      This private method appends (NOT INITIALIZES) an Atom-Entry. 
      DO NOT TOUCH THESE LINES UNLESS YOU EXACTLY KNOW WHAT YOU ARE DOING!
      */
      private function createAtomEntry($mime,$entryId,$oldId=FALSE)
      {
	 $myIds=NULL;
	 //  -------------- Create atom.xml entry
	 if(!$this->isLoadAtom) $this->readAtom();
	 $feed=$this->db->documentElement;

	 // Entry Begin
	 
	 // Distinguish between first entry and further entries. We need to insert
	 // new element atop rather than to append.
	$myIds=$feed->getElementsByTagName('id');
	 if($myIds->length>1)
	 {
	    $refNode=$myIds->item(1)->parentNode;
	    $entry=$refNode->parentNode->insertBefore($this->db->createElement('entry'),$refNode);
	 }
	 else
	    $entry=$feed->appendChild($this->db->createElement('entry'));

	 //	 $linkSelf=$entry->appendChild($this->db->createElement('link'));
	 //	 $linkSelf->setAttribute('rel','self');
	 //	 $linkSelf->setAttribute('type','application/atom+xml');
	 //	 $linkSelf->setAttribute('href',$this->atomFileUrl);

	 $eTitle=$entry->appendChild($this->db->createElement('title',utf8_encode($this->htmlRecodeLight($_POST['title']))));
	 $eTitle->setAttribute('type','text');
	 //	 $eTitle->setAttribute('type','xhtml');
	 //$eTitle->setAttribute('xml:lang','de');
	 //	 $eTitleDiv=$eTitle->appendChild($this->db->createElement('div',$this->xmlRecode(utf8_encode($_POST['title']))));
	 //	 $eTitleDiv->setAttribute('xmlns','http://www.w3.org/1999/xhtml');
	 //	 $eTitleDiv->setAttribute('lang','de');
	 //	 $eTitleDiv->setAttribute('dir','ltr');

	 $eAuthor=$entry->appendChild($this->db->createElement('author'));
	 $eAuthor->appendChild($this->db->createElement('name',$this->xmlRecode(utf8_encode($this->blogOwner))));

	 $targetLoader="http://".$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'].'?do=show&photoId='.$entryId;

	 $eLinkAlt=$entry->appendChild($this->db->createElement('link'));
	 $eLinkAlt->setAttribute('href',$targetLoader);
	 $eLinkAlt->setAttribute('rel','alternate');
	 $eLinkAlt->setAttribute('type','text/html');

	 /*
	 $eLinkAlt=$entry->appendChild($this->db->createElement('link'));
	 $eLinkAlt->setAttribute('href',$this->targetTnUrl);
	 $eLinkAlt->setAttribute('rel','alternate');
	 $eLinkAlt->setAttribute('type',$mime);
	 */

	 $eLinkEncl=$entry->appendChild($this->db->createElement('link'));
	 $eLinkEncl->setAttribute('href',$this->targetUrl);
	 $eLinkEncl->setAttribute('length',filesize($this->target));
	 $eLinkEncl->setAttribute('rel','enclosure');
	 $eLinkEncl->setAttribute('type',$mime);

	 if($oldId) $eId=$entry->appendChild($this->db->createElement('id',$oldId));
	 else $eId=$entry->appendChild($this->db->createElement('id',$this->createId()));

	 $eUpdated=$entry->appendChild($this->db->createElement('updated',date("c",time())));

	 $eRights=$entry->appendChild($this->db->createElement('rights','Copyright (c) 2006, '.$this->xmlRecode(utf8_encode($this->blogOwner))));

	 $eSummary=$entry->appendChild($this->db->createElement('summary',utf8_encode($this->htmlRecodeLight($_POST['comment']))));
	 $eSummary->setAttribute('type','text');

	 $eContent=$entry->appendChild($this->db->createElement('content'));
	 $eContent->setAttribute('type','xhtml');
	 $eContentDiv=$eContent->appendChild($this->db->createElement('div'));
	 $eContentDiv->setAttribute('xmlns','http://www.w3.org/1999/xhtml');
	 $eContentDivA=$eContentDiv->appendChild($this->db->createElement('a'));
	 $eContentDivA->setAttribute('href',"http://".$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'].'?do=show&photoId='.$entryId);
	 $eContentDivAImg=$eContentDivA->appendChild($this->db->createElement('img'));
	 $eContentDivAImg->setAttribute('src',$this->targetTnUrl);
	 $eContentDivAImg->setAttribute('alt',$this->xmlRecode(utf8_encode($this->htmlRecodeLight($_POST['title']))));
	 //	 $prepareString=$this->xmlRecode(utf8_encode($this->htmlRecodeLight($_POST['comment'])));
	 //	 $prepareString=$this->xmlRecodeNum($prepareString);
	 $prepareString=utf8_encode($this->xmlRecode($_POST['comment']));

	 $eContentDivP=$eContentDiv->appendChild($this->db->createElement('p',$prepareString));

	 // Update feed's modification date
	 $this->db->getElementsByTagName('updated')->item(0)->nodeValue=date("c",time());

	 // Entry END
	 $this->db->save($this->atomFile);
	 return;
      }

      /*!
      Approve comment form. For the admin's eyes, only.
      */
      private function approveComments()
      {
	 echo "<div id=\"apbApproveComments\" class=\"apb form left\">";
	 $this->mysqlConnect();
	 $selection='where approved=0';
	 $buffer=$this->mysqlQuery("SELECT * FROM  `".$this->apbPrefix."comments` ".$selection." order by timeStamp asc")
	 or die("<p class=\"apb form error\">*** ERROR: Reading Comments-Table failed</p>");

	 $n_entries = mysql_num_rows($buffer);
	 echo "<p class=\"apb form\">Number of comments to approve: ".$n_entries."</p>";
	 echo "<form method=\"post\" action=\"";
	 echo $_SERVER['PHP_SELF']."\">";
	 echo "<input class=\"inputbox myButton\"  type=\"submit\" value=\"Sumbit\" />";
	 echo "<table id=\"apbApprove\" class=\"apb approved form\">";
	 echo "<tr class=\"apb form approve\">";
	 echo "<th class=\"apb form approve tn\">Picture</th>";
	 echo "<th class=\"apb form approve\">Comment</th>";
	 echo "<th class=\"apb form approve\">Author</th>";
	 echo "<th class=\"apb form approve\">Homepage</th>";
	 echo "<th class=\"apb form approve\">TimeStamp</th>";
	 echo "<th class=\"apb form approve\">I.P.</th>";
	 echo "<th class=\"apb form approve radio\">Approve</th>";
	 echo "<th class=\"apb form approve radio\">Reject</th>";
	 echo "<th class=\"apb form approve radio\">LeaveIt</th>";
	 echo "</tr>";
	 while ($row = mysql_fetch_assoc($buffer))
	 {
	    $entry=mysql_fetch_assoc($this->mysqlQuery("SELECT  tnLink, title FROM  `".$this->apbPrefix."entries` where id=".$row['entryId']));

	    // Print the contents in any case
	    echo "<tr class=\"apb form approve\">";
	    echo "<td class=\"apb form approve tn\"><img height=\"50px\" src=\"".$entry['tnLink']."\"/><br/>";
	    echo $entry['title'];
	    echo "</td>";
	    echo "<td class=\"apb form approve\">".$row['comment']."</td>";
	    echo "<td class=\"apb form approve\">".$row['name']."</td>";

	    if(isset($row['homepage'])) 
	    {
	       echo "<td class=\"apb form approve\"><a href=\"".$row['homepage']."\">".$row['homepage']."</a></td>";
	    }
	    else echo "<td class=\"apb form approve\">No Homepage</td>";

	    echo "<td class=\"apb form approve\">".$row['timeStamp']."</td>";
	    echo "<td class=\"apb form approve\">".$row['IP']."</td>";
	    echo "<td class=\"apb form approve radio\">";
	    echo '<input type="radio" name="'.$row['id'].'" checked="checked" value="approve">';
	    echo "</td>";
	    echo "<td class=\"apb form approve radio\">";
	    echo '<input type="radio" name="'.$row['id'].'" value="reject">';
	    echo "</td>";
	    echo "<td class=\"apb form approve radio\">";
	    echo '<input type="radio" name="'.$row['id'].'" value="leave">';
	    echo "</td>";
	    echo "</tr>";
	 }
	 echo "</table>";
	 echo "<input class=\"inputbox myButton\"  type=\"submit\" value=\"Sumbit\" />";
	 echo "<input style=\"display: none\" name=\"do\" value=\"doApprove\" />";
	 //	 echo "<input type=\"hidden\" name=\"n\" value=\"$n_entries\" />";
	 echo "</form>";
	 mysql_free_result($buffer);
	 $this->mysqlDisconnect();
	 return TRUE;
      }

      /*!
      If admin has sent the form, this method is called in order to save approvements.
      */
      private function doApprove()
      {

	 $approve=array();
	 $reject=array();
	 // Parse form
	 foreach ($_POST as $key => $value)
	 {
	    switch($value)
	    {
	       case 'approve':
		  array_push($approve,$key);
		  break;
	       case 'reject':
		  array_push($reject,$key);
		  break;
	    }
	 }

	 $this->mysqlConnect();

	 if(count($approve))
	 {
	    $query = "update `".$this->apbPrefix."comments` set approved=1 where ";
	    $i=1;
	    foreach ($approve as $value)
	    {
	       $query .= "id=$value";
	       if($i++<count($approve)) $query .=" or ";
	    }
	    $this->mysqlQuery($query) or die('*** ERROR: Approvement Query failed');


	 }

	 if(count($reject))
	 {
	    $query = "delete from `".$this->apbPrefix."comments` where ";
	    $i=1;
	    foreach ($reject as $value)
	    {
	       $query .= "id=$value ";
	       if($i++<count($reject)) $query .=" or ";
	    }
	    $this->mysqlQuery($query) or die('*** ERROR: Rejection Query failed');
	 }

	 echo "<h1>Summary of comment-approvement</h1>";
	 echo "<h2 class=\"apb  success approved\">";
	 echo "Approved: ".count($approve).", Rejected: ".count($reject);
	 echo "</h2>";

	 $this->mysqlDisconnect();
	 return TRUE;
      }
   }


Return current item: Atom PhotoBlog