Slooze PHP Cross Reference Image Galleries

Source: /src/slooze.php - 1028 lines - 39663 bytes - Summary - Text - Print

   1  <?php  /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-indent: 2 -*- */
   2  /*

   3   * Slooze PHP Web Photo Album

   4   * Copyright (c) 2000-2005 Slooze developers (see AUTHORS file)

   5   * $Id: slooze.php,v 1.58 2006/07/16 23:03:37 mdkendall Exp $

   6   */
   7  
   8  class Slooze {
   9  
  10    /* Redefine these parameters by deriving your own class */

  11  
  12    var $admin = FALSE;         /* enable full admin mode */
  13    var $enableComments = TRUE; /* enable user addition of comments */
  14    var $enableRatings = TRUE;  /* enable user rating of pictures */
  15    var $enableViews = FALSE;   /* enable counting how many times a picture has been viewed */
  16    var $enableNav = TRUE;      /* enable First|Prev|Next|Last navigation */
  17    var $enableCache = FALSE;   /* enable caching of pages for speed */
  18    var $enableSearch = TRUE;   /* enable user search functionality */
  19    var $enableCommentsEmail = FALSE; /* enable email of new comments */
  20  
  21    var $allPathsLower = FALSE; /* make all image paths lower-case, no matter their recorded case */
  22    var $showCommentIPs = FALSE; /* put IP of commenter before comment */
  23    var $ownIPSubstring = "192.168.1."; /* don't count picture views coming from this address substring */
  24    var $sortThreshold = 5;  /* number of pics in topic before sorting offered */
  25  
  26    var $basePath = "./"; /* path to photos directory */
  27    var $cachePath = "./cache/"; /* path to cache directory */
  28    var $baseURL = "./";  /* URL of photos directory */
  29    var $actionURL = "";  /* URL for further actions */
  30    var $picture_suffix = ".jpg";  /* filename suffix for pictures */
  31    var $thumb_suffix = "-t.jpg";  /* filename suffix for thumbnails */
  32    var $thumb_height = 64;        /* height for auto-generated thumbnails */
  33    var $nl = "\r\n";              /* newline sequence */
  34    var $parentSelectPad = "&nbsp;&nbsp;"; /* what to pad the parent select with */
  35    var $emailTo = "user@example.com"; /* email address notifications are sent to */
  36    var $emailFrom = "webmaster@example.com"; /* email address notifications are sent from */
  37  
  38    var $ctClass = "SloozeCtCsv";   /* type of container for picture metadata */
  39    var $ct;                        /* container for picture metadata */
  40  
  41    var $htmlStr;   /* string to return for output to browser */
  42  
  43  
  44    /* public: constructor */

  45    function Slooze() {
  46      global $HTTP_SERVER_VARS;
  47      if (!isset($HTTP_SERVER_VARS) && isset($_SERVER)) $HTTP_SERVER_VARS = $_SERVER;
  48      if( $this->actionURL == "" ) {
  49        $this->actionURL = $HTTP_SERVER_VARS['PHP_SELF'];
  50      }
  51      $name = $this->ctClass;
  52      $this->ct = new $name;
  53    }
  54  
  55    /* public: construct valid inputs from GET or POST variables */

  56    function validateInputs() {
  57      global $HTTP_POST_VARS;
  58      global $HTTP_GET_VARS;
  59      $vars = count($_POST) > 0 ? $_POST :
  60                (count($_GET) > 0 ? $_GET :
  61                  (count($HTTP_POST_VARS) > 0 ? $HTTP_POST_VARS :
  62                    (count($HTTP_GET_VARS) > 0 ? $HTTP_GET_VARS : array() )));
  63      $cleanvars = array();
  64      reset($vars);
  65      while( list($var, $value) = each($vars) ) {
  66        $cleanvars[$var] = $this->validateInput($value);
  67      }
  68      return $cleanvars;
  69    }
  70  
  71    /* private: sanitise a single variable */

  72    function validateInput($var) {
  73      if (get_magic_quotes_gpc()) {
  74        $var = stripslashes($var);
  75      }
  76      $var = strip_tags($var);
  77      $var = htmlspecialchars($var);
  78      $var = str_replace("\n", " ", $var);
  79      $var = str_replace("\r", " ", $var);
  80      $var = trim($var);
  81      return $var;
  82    }
  83  
  84    /* ------------------------------------------------------------------- */

  85  
  86    /* public: renderPage() does the work of producing the required html page.

  87     * It produces body text only, which must be wrapped by other html to

  88     * form a complete page. The effect of renderPage() depends on the

  89     * variables passed to it. */
  90  
  91    function renderPage( $vars ) {
  92  
  93      $this->htmlStr = "";
  94  
  95      $this->ct->resetError();
  96  
  97      /* handle database update actions */

  98      if(isset($vars['action'])) {
  99        $this->handleAction($vars);
 100        /* if we have just deleted something, don't carry on and try to render it */

 101        if(strstr($vars['action'],'delete')) {
 102          $this->renderTopic();
 103          return $this->htmlStr;
 104        }
 105      }
 106  
 107      /* return an appropriate page body */

 108      /* first, try the cache */

 109      if (!$this->admin && $this->enableCache && $this->cacheRead(md5(serialize($vars)))) {
 110        return $this->htmlStr;
 111      }
 112  
 113      /* no cache hit (or cache not enabled) so render the page body */

 114      if(isset($vars['TopicID'])) {
 115        if(isset($vars['sort'])) {
 116          $this->renderTopic($vars['TopicID'], $vars['sort']);
 117        } else {
 118          $this->renderTopic($vars['TopicID']);
 119        }
 120      }
 121      else if(isset($vars['RollID']) && isset($vars['FrameID'])) {
 122        $this->renderPicture($vars['RollID'], $vars['FrameID']);
 123      }
 124      else if(isset($vars['RollID'])) {
 125        $this->renderRoll($vars['RollID']);
 126      }
 127      else if(isset($vars['search'])) {
 128        $this->renderSearch($vars['search']);
 129      }
 130      else {
 131        /* default action is render top-level topics */

 132        $this->renderTopic();
 133      }
 134      /* save the page in the cache for next time */

 135      if (!$this->admin && $this->enableCache) {
 136        $this->cacheWrite(md5(serialize($vars)));
 137      }
 138      return $this->htmlStr;
 139    }
 140  
 141    /* ------------------------------------------------------------------- */

 142  
 143    /* High-level functions to render page bodies */

 144  
 145    /* private: render a page body for a given topic */

 146    function renderTopic( $topicID = "/", $sort="" ) {
 147      $topic = $this->ct->getTopic($topicID);
 148      $this->showTopic($topic);
 149      $subTopics = $this->ct->getTopicsInParentTopic($topicID);
 150      $this->showTopics($subTopics);
 151      $pictures = $this->ct->getPicturesInTopic($topicID);
 152      if ($sort != "") {
 153        $this->showSortType($sort);
 154        $pictures = $this->sortPictures($pictures, $sort, $this->sortThreshold);
 155      }
 156      $this->showThumbs($pictures);
 157      if ( (count($pictures) > $this->sortThreshold) || $sort!="" )
 158        $this->showSort($topicID);
 159      if ($this->admin) {
 160        $this->showFormUpdateTopic($topicID);
 161        if ($topicID == "/") {
 162          $this->showFormAddTopic();
 163          $this->showRolls();
 164          $this->showFormAddRoll();
 165        }
 166        else {
 167          if (count($pictures)== 0 ) {
 168            $this->showFormDeleteTopic($topicID);
 169          }
 170        }
 171      }
 172      if ($topicID != "/") {
 173        $this->showNav($topicID);
 174      }
 175      if ($this->enableSearch) {
 176        $this->showFormSearch();
 177      }
 178    }
 179  
 180    /* private: render a page body for a given picture */

 181    function renderPicture( $rollID, $frameID ) {
 182      if ($picture = $this->ct->getPicture($rollID, $frameID)) {
 183        $topic = $this->ct->getTopic($picture['ParentTopicID']);
 184        $this->showTopic($topic, false);
 185        $this->showPicture($picture);
 186        $comments = $this->ct->getCommentsInPicture($rollID, $frameID);
 187        $this->showNav($picture['ParentTopicID']);
 188        if ($this->enableNav) {
 189          $this->showNavigation($picture);
 190        }
 191        $this->showComments($comments);
 192        if ($this->enableComments) {
 193          $this->showFormAddComment($rollID, $frameID);
 194        }
 195        if ($this->enableRatings) {
 196          $this->showFormAddRating($rollID, $frameID, $picture['Rating']);
 197        }
 198        if ($this->admin) {
 199          $this->showFormUpdatePicture($rollID, $frameID);
 200          $this->showFormDeletePicture($rollID, $frameID);
 201        }
 202        // if conditions are appropriate, increment times a picture has been viewed

 203        if (!$this->admin && $this->enableViews) {
 204          global $HTTP_SERVER_VARS;
 205          if ( !strlen($this->ownIPSubstring) || !strstr($HTTP_SERVER_VARS['REMOTE_ADDR'], $this->ownIPSubstring) )
 206            $this->ct->incrementPictureViews($rollID, $frameID, $picture);
 207        }
 208      }
 209    }
 210  
 211    /* private: render a page body for a given roll */

 212    function renderRoll( $rollID ) {
 213      $this->showRoll($rollID);
 214      $pictures = $this->ct->getPicturesInRoll($rollID);
 215      $this->showThumbs($pictures);
 216      $this->showNav();
 217      if ($this->admin) {
 218  //    $this->showFormUpdateRoll($rollID);

 219        if (count($pictures)== 0 ) {
 220          $this->showFormDeleteRoll($rollID);
 221        }
 222        $this->showFormAddPicture($rollID);
 223        $this->showFormAddAllPictures($rollID);
 224      }
 225    }
 226  
 227    /* private: render a page body for a given search */

 228    function renderSearch( $search ) {
 229      $this->showSearch($search);
 230      $pictures = $this->ct->getPicturesInSearch($search);
 231      $this->showThumbs($pictures);
 232      $this->showNav();
 233      $this->showFormSearch();
 234    }
 235  
 236    /* ------------------------------------------------------------------- */

 237  
 238    /* High-level functions to handle database updates */

 239  
 240    /* private: update the appropriate database table */

 241    function handleAction($vars) {
 242      global $HTTP_SERVER_VARS;
 243      if ($this->admin) {
 244        /* add, update and delete Topics */

 245        if($vars['action'] == 'updateTopic') {
 246          if (!isset($vars['ParentTopicID'])) $vars['ParentTopicID'] = '';
 247          $topic = array( 'TopicID' => $vars['TopicID'],
 248                          'ParentTopicID' => $vars['ParentTopicID'],
 249                          'Description' => $vars['Description'],
 250                          'Summary' => $vars['Summary']);
 251          $this->ct->updateTopic($topic);
 252        }
 253        else if($vars['action'] == 'addTopic') {
 254          $topic = array( 'TopicID' => $vars['TopicID'],
 255                          'ParentTopicID' => $vars['ParentTopicID'],
 256                          'Description' => $vars['Description'],
 257                          'Summary' => $vars['Summary']);
 258          $this->ct->addTopic($topic);
 259        }
 260        else if($vars['action'] == 'deleteTopic') {
 261          if (!$this->ct->deleteTopic($vars['TopicID']))
 262            $this->show_error($this->ct->getError());
 263        }
 264        /* add, update and delete Pictures */

 265        else if($vars['action'] == 'updatePicture') {
 266          $picture = array( 'RollID' => $vars['RollID'],
 267                          'FrameID' => $vars['FrameID'],
 268                          'ParentTopicID' => $vars['ParentTopicID'],
 269                          'Description' => $vars['Description'] );
 270          $this->ct->updatePicture($picture);
 271        }
 272        else if($vars['action'] == 'addPicture') {
 273          $picture = array( 'RollID' => $vars['RollID'],
 274                          'FrameID' => $vars['FrameID'],
 275                          'ParentTopicID' => $vars['ParentTopicID'],
 276                          'Description' => $vars['Description'],
 277                          'Views' => '0', 'Rating' => '0');
 278          $this->ct->addPicture($picture);
 279        }
 280        else if($vars['action'] == 'addAllPictures') {
 281          $this->addAllPictures($vars['RollID'], $vars['ParentTopicID']);
 282        }
 283        else if($vars['action'] == 'deletePicture') {
 284          $this->ct->deletePicture($vars['RollID'], $vars['FrameID']);
 285        }
 286        /* add, update and delete Rolls */

 287        else if($vars['action'] == 'updateRoll') {
 288          $roll = array( 'RollID' => $vars['RollID'] );
 289          $this->ct->updateRoll($roll);
 290        }
 291        else if($vars['action'] == 'addRoll') {
 292          $roll = array( 'RollID' => $vars['RollID'] );
 293          $this->ct->addRoll($roll);
 294        }
 295        else if($vars['action'] == 'deleteRoll') {
 296          if (!$this->ct->deleteRoll($vars['RollID']))
 297            $this->show_error($this->ct->getError());
 298         }
 299        /* delete Comments */

 300        else if($vars['action'] == 'deleteComment') {
 301          $this->ct->deleteComment($vars['CommentID']);
 302        }
 303      } // endif admin enabled

 304      if ($this->enableComments) {
 305        /* add Comments */

 306        if($vars['action'] == 'addComment') {
 307          if($vars['Comment'] != "") {
 308            $comment = array( 'CommentID' => uniqid(""),
 309                              'RollID' => $vars['RollID'],
 310                              'FrameID' => $vars['FrameID'],
 311                              'Comment' => $vars['Comment'],
 312                              'IP' => $HTTP_SERVER_VARS['REMOTE_ADDR']);
 313            $this->ct->addComment($comment);
 314            if ($this->enableCommentsEmail) {
 315              mail($this->emailTo, SLZ_STR_COMMENT_EMAIL_SUBJECT,
 316                   SLZ_STR_COMMENT . ": $comment[CommentID]\n" .
 317                   SLZ_STR_ROLLID . ": $comment[RollID]\n" .
 318                   SLZ_STR_FRAMEID . ": $comment[FrameID]\n" .
 319                   SLZ_STR_COMMENT . ": $comment[Comment]\n" .
 320                   "IP: $comment[IP]\n",
 321                   "From: " . $this->emailFrom);
 322            }
 323          }
 324        }
 325      } // endif comments enabled

 326      if ($this->enableRatings) {
 327        /* add Ratings */

 328        if($vars['action'] == 'addRating') {
 329          if(($vars['Rating'] >= -2) && ($vars['Rating'] <= 2)) {
 330            $rating = array( 'RollID' => $vars['RollID'],
 331                             'FrameID' => $vars['FrameID'],
 332                             'Rating' => $vars['Rating'],
 333                             'IP' => $HTTP_SERVER_VARS['REMOTE_ADDR'],
 334                             'RateTime' => time() );
 335            $this->ct->addRating($rating);
 336          }
 337        }
 338      } // endif ratings enabled

 339      /* Action has potentially changed pages - clear the cache */

 340      if ($this->enableCache) {
 341        $this->cacheClear();
 342      }
 343    }
 344  
 345    /* private: addAllPictures() searches for and adds all pictures in a roll */

 346    function addAllPictures( $rollID, $parentTopicID ) {
 347      if ($handle = opendir($this->basePath . $rollID)) {
 348        while ($file = readdir($handle)) {
 349          /* if not thumb */

 350          if (!ereg('(.+)'.str_replace('.','\.',$this->thumb_suffix).'$', $file)) {
 351            /* if is picture */

 352            if (ereg('(.+)'.str_replace('.','\.',$this->picture_suffix).'$', $file, $arr)) {
 353              set_time_limit(10);
 354              $frameID = $arr[1];
 355              $picture = array( 'RollID' => $rollID, 'FrameID' => $frameID,
 356                'ParentTopicID' => $parentTopicID, 'Description' => '',
 357                'Views' => '0', 'Rating' => '0' );
 358              /* make thumbnail if required */

 359              $this->makeThumb($picture);
 360              /* add picture if not already present */

 361              if (!$this->ct->getPicture($rollID, $frameID)) {
 362                $this->ct->addPicture($picture);
 363              }
 364            }
 365          }
 366        }
 367        closedir($handle);
 368      }
 369    }
 370  
 371    /* private: make a thumbnail image if one does not exist */

 372    function makeThumb($picture) {
 373      $fileNameStem = $this->basePath . $picture['RollID'] . "/" . $picture['FrameID'];
 374      if ($this->allPathsLower)
 375        $fileNameStem = strtolower( $fileNameStem );
 376      /* if thumbnail does not exist */

 377      if (!file_exists($fileNameStem . $this->thumb_suffix)) {
 378        if (function_exists('imagetypes') && (imagetypes() & IMG_JPG)) {
 379          /* make thumbnail using GD library */

 380          $srcImg = imagecreatefromjpeg($fileNameStem . $this->picture_suffix);
 381          $srcImgX = imagesx($srcImg);
 382          $srcImgY = imagesy($srcImg);
 383          $dstImgY = $this->thumb_height;
 384          $dstImgX = $srcImgX * $dstImgY / $srcImgY;
 385          $dstImg = imagecreate($dstImgX, $dstImgY);
 386          imagejpeg($dstImg, $fileNameStem . $this->thumb_suffix);
 387          imagedestroy($dstImg);
 388          $dstImg = imagecreatefromjpeg($fileNameStem . $this->thumb_suffix);
 389          if (function_exists('imagecopyresampled')) {
 390            imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $dstImgX, $dstImgY, $srcImgX, $srcImgY);
 391          } else {
 392            imagecopyresized($dstImg, $srcImg, 0, 0, 0, 0, $dstImgX, $dstImgY, $srcImgX, $srcImgY);
 393          }
 394          imagejpeg($dstImg, $fileNameStem . $this->thumb_suffix, 75);
 395          imagedestroy($scrImg);
 396          imagedestroy($dstImg);
 397        } else {
 398          /* GD library JPEG support apparently not available */

 399        }
 400      }
 401    }
 402  
 403    /* private: sortPictures() delivers a sorted subset of pictures */

 404    function sortPictures($pictures, $sort, $num) {
 405      if ($sort == 'views')
 406        usort($pictures, 'cmpViews' );
 407      if ($sort == 'rating')
 408        usort($pictures, 'cmpRating' );
 409      reset($pictures);
 410      $subset = array();
 411      $count = 0;
 412      while ((list($key,$value) = each($pictures)) && $count < $num) {
 413        $count += 1;
 414        $subset[$key] = $value;
 415      }
 416      return $subset;
 417    }
 418  
 419    /* ------------------------------------------------------------------- */

 420  
 421    /*

 422     * Low-level functions to render individual page elements.

 423     * These are the only functions that actually generate any HTML.

 424     */
 425  
 426    /* private: show a single topic title */

 427    function showTopic($topic, $showSummary = true) {
 428      if(is_array($topic)) {
 429        $desc = $this->defaultText($topic['Description'], SLZ_STR_NO_DESC);
 430        $this->show("<h2>" . $desc . "</h2>");
 431        // if we've got a Summary, show it

 432        if ($showSummary && strlen($topic['Summary']))
 433          $this->show("<p>".$topic['Summary'] . "</p>");
 434      }
 435    }
 436  
 437    /* private: show a list of all the topics in $topics */

 438    function showTopics( $topics ) {
 439      if(is_array($topics) && count($topics) > 0 ) {
 440        $this->show("<ul>");
 441        reset($topics);
 442        while( list($key, $topic) = each($topics)) {
 443          $desc = $this->defaultText($topic['Description'], SLZ_STR_NO_DESC);
 444          $this->show("<li>");
 445          $this->showTopicThumb($topic);
 446          $this->show("<a href=\"" . $this->actionURL ."?TopicID=" .urlencode($topic['TopicID']). "\">");
 447          $this->show($desc . "</a></li>");
 448        }
 449        $this->show("</ul>");
 450      }
 451    }
 452  
 453    /* private: show hyperlinks to display sorted versions of this topic */

 454    function showSort( $topicID ) {
 455      if ($this->enableViews || $this->enableRatings) {
 456        $this->show("<ul>");
 457        if ($this->enableViews) {
 458          $this->show("<li><a href=\"" . $this->actionURL ."?TopicID=" .urlencode($topicID).
 459                      "&amp;sort=views\">".SLZ_STR_MOST_VIEWED."</a></li>");
 460          }
 461        if ($this->enableRatings) {
 462          $this->show("<li><a href=\"" . $this->actionURL ."?TopicID=" .urlencode($topicID).
 463                      "&amp;sort=rating\">".SLZ_STR_HIGHEST_RATED."</a></li>");
 464        }
 465        $this->show("</ul>");
 466      }
 467    }
 468  
 469    /* private: show a title for a sorted subset of a topic */

 470    function showSortType( $sort ) {
 471      if ($sort == 'views')
 472        $this->show("<h3>".SLZ_STR_MOST_VIEWED."</h3>");
 473      if ($sort == 'rating')
 474        $this->show("<h3>".SLZ_STR_HIGHEST_RATED."</h3>");
 475    }
 476  
 477    /* private: show a hyperlinked topic heirarchy down to the given topic */

 478    function showNav( $topicID = "/" ) {
 479      if ($topic = $this->ct->getTopic($topicID)) {
 480        $desc = $this->defaultText($topic['Description'], SLZ_STR_NO_DESC);
 481        if ($topicID == "/") {
 482          $this->show("<p><a href=\"" . $this->actionURL . "\">" . $desc . "</a>");
 483        }
 484        else {
 485          $this->showNav($topic['ParentTopicID']);
 486          $this->show(" : <a href=\"" . $this->actionURL .
 487              "?TopicID=" . urlencode($topic['TopicID']) .
 488              "\">" . $desc . "</a>");
 489        }
 490      }
 491    }
 492  
 493    /* private: show a navigation bar with hyperlinks for First | Prev | Next | Last */

 494    function showNavigation ( $picture ) {
 495      $pictures = $this->ct->getPicturesInTopic($picture['ParentTopicID']);
 496      $currentPictureIndex = -1;
 497      /* spin through pictures in topic and get our index */

 498      while (list ($key, $val) = each ($pictures)) {
 499        // PHP4 if ($val == $picture) $currentPictureIndex = $key;

 500        if (($val['RollID'] == $picture['RollID']) && ($val['FrameID'] == $picture['FrameID'])) {
 501          $currentPictureIndex = $key;
 502        }
 503      }
 504      $firstPictureIndex = 0;
 505      $lastPictureIndex = sizeof($pictures) - 1;
 506      $prevPictureIndex = $currentPictureIndex - 1;
 507      $nextPictureIndex = $currentPictureIndex + 1;
 508      $separator = "&nbsp;" . SLZ_STR_NAV_TEXT_SEPARATOR . "&nbsp;";
 509  
 510      /* navBar is an HTML string with navigation links */

 511      $navBar = "<p>" . $this->getNavigationLink(SLZ_STR_NAV_FIRST,
 512        ($firstPictureIndex == $currentPictureIndex) ? NULL : $pictures[$firstPictureIndex]);
 513      $navBar = $navBar . $separator;
 514      $navBar = $navBar . $this->getNavigationLink(SLZ_STR_NAV_PREVIOUS,
 515        ($prevPictureIndex >= 0) ? $pictures[$prevPictureIndex] : NULL);
 516      $navBar = $navBar . $separator;
 517      $navBar = $navBar . $this->getNavigationLink(SLZ_STR_NAV_NEXT,
 518        ($nextPictureIndex <= $lastPictureIndex) ? $pictures[$nextPictureIndex] : NULL);
 519      $navBar = $navBar . $separator;
 520      $navBar = $navBar . $this->getNavigationLink(SLZ_STR_NAV_LAST,
 521        ($lastPictureIndex == $currentPictureIndex) ? NULL : $pictures[$lastPictureIndex]);
 522      $navBar = $navBar . "</p>";
 523      $this->show($navBar);
 524    }
 525  
 526    /* private: return a link to a picture, or plain text if no picture is specified */

 527    function getNavigationLink ( $displayText, $picture ) {
 528      if (is_array($picture)) {
 529        $text = "<a href=\"" . $this->actionURL . "?RollID=" . urlencode($picture['RollID']) .
 530          "&amp;FrameID=" . urlencode($picture['FrameID']) . "\">" . $displayText . "</a>";
 531      } else {
 532        $text = $displayText;
 533      }
 534      return  $text;
 535    }
 536  
 537    /* private: show a search result title */

 538    function showSearch($search) {
 539      $this->show("<h2>".SLZ_STR_HDR_SEARCH."</h2>");
 540      $this->show("<p>".SLZ_STR_SEARCH_TERM.": " . $search . "</p>");
 541    }
 542  
 543    /* private: show a single roll title */

 544    function showRoll($rollID) {
 545      $this->show("<h2>".SLZ_STR_HDR_ROLL." ".$rollID."</h2>");
 546    }
 547  
 548    /* private: show a list of all rolls */

 549    function showRolls() {
 550      $this->show("<h2>".SLZ_STR_HDR_ROLLS."</h2>");
 551      $this->show("<ul>");
 552      $rolls = $this->ct->getRolls();
 553      reset($rolls);
 554      while( list($key, $roll) = each($rolls)) {
 555        $this->show("<li>" .
 556           "<a href=\"" . $this->actionURL ."?RollID=" . urlencode($roll['RollID']) . "\">" .
 557          $roll['RollID'] . "</a>" .
 558          "</li>");
 559      }
 560      $this->show("</ul>");
 561    }
 562  
 563    /* private: show thumbnails for all pictures in $pictures */

 564    function showThumbs( $pictures ) {
 565      if(is_array($pictures) && count($pictures) > 0) {
 566        reset($pictures);
 567        $this->show("<p>");
 568        while( list($key, $picture) = each($pictures)) {
 569          $this->showThumb($picture);
 570        }
 571        $this->show("</p>");
 572      }
 573    }
 574  
 575    /* private: show thumbnail for a single picture */

 576    function showThumb( $picture ) {
 577      if (is_array($picture) && count($picture) > 0) {
 578        /* make img tag with size and caption plus a link to the fullsize picture */

 579        $fileName = $picture['RollID'] . "/" . $picture['FrameID'] . $this->thumb_suffix;
 580        if ($this->allPathsLower)
 581          $fileName = strtolower( $fileName );
 582        $size = GetImageSize( $this->basePath . $fileName );
 583        $description = $picture['Description'];
 584        if ($this->enableViews)
 585          $description .= ' [' . $picture['Views'] . ' ' . SLZ_STR_VIEWS . ']';
 586        if ($this->enableRatings)
 587          $description .= ' ['.SLZ_STR_RATING.' ' . $this->ratingText($picture['Rating']) . ']';
 588        $this->show("<a href=\"" . $this->actionURL .
 589           "?RollID=" . urlencode($picture['RollID']) .
 590           "&amp;FrameID=" . urlencode($picture['FrameID']) . "\">" .
 591           "<img src=\"" . $this->baseURL . $fileName . "\" " . $size[3] .
 592           " title=\"" . $description . "\"" .
 593           " alt=\"" . $description . "\"></a>");
 594      }
 595    }
 596  
 597    /* private: show thumbnail for a topic, if exists */

 598    function showTopicThumb( $topic ) {
 599      if (is_array($topic) && count($topic) > 0) {
 600        /* make img tag with size and caption */

 601        $fileName = "topics/" . $topic['TopicID'] . $this->thumb_suffix;
 602        if ($this->allPathsLower)
 603          $fileName = strtolower( $fileName );
 604  
 605        if (file_exists($this->basePath . $fileName)) {
 606          $size = GetImageSize( $this->basePath . $fileName );
 607          $description = $topic['Description'];
 608          $this->show("<img src=\"" . $this->baseURL . $fileName . "\" " . $size[3] .
 609             " title=\"" . $description . "\"" .
 610             " alt=\"" . $description . "\">");
 611        }
 612      }
 613    }
 614  
 615    /* private: show a single full-size picture */

 616    function showPicture( $picture ) {
 617      if (is_array($picture) && count($picture) > 0) {
 618        /* make img tag with size and caption */

 619        $this->show("<p>" .$picture['Description']. "</p>");
 620        $fileName = $picture['RollID'] . "/" . $picture['FrameID'] . $this->picture_suffix;
 621        if ($this->allPathsLower)
 622          $fileName = strtolower( $fileName );
 623        $size = GetImageSize( $this->basePath . $fileName );
 624        $description = $picture['Description'];
 625        $this->show("<p><img src=\"" . $this->baseURL . $fileName . "\" " . $size[3] .
 626           " title=\"" . $description . "\"" .
 627           " alt=\"" . $description . "\"></p>");
 628      }
 629    }
 630  
 631    /* private: show all comments in $comments */

 632    function showComments( $comments ) {
 633      if(is_array($comments) && count($comments) > 0) {
 634        reset($comments);
 635        while( list($key, $comment) = each($comments)) {
 636          $this->showComment($comment);
 637        }
 638      }
 639    }
 640  
 641    /* private: show a single comment */

 642    function showComment( $comment ) {
 643      if (is_array($comment) && count($comment) > 0) {
 644        $this->show("<p class=\"sloozecomment\">".SLZ_STR_COMMENT.": ");
 645        // show IP of commenter if it exists, and we're in admin mode

 646        if ( ($this->admin || $this->showCommentIPs) && strlen($comment['IP']) )
 647          $this->show("(". $comment['IP'] . ") ");
 648        $this->show($comment['Comment'] . "</p>");
 649        if ($this->admin) {
 650          $this->showFormDeleteComment($comment['CommentID']);
 651        }
 652      }
 653    }
 654  
 655    /* private: show a form to update a topic */

 656    function showFormUpdateTopic($topicID) {
 657      if ($topic = $this->ct->getTopic($topicID)) {
 658        $this->show("<h2>".SLZ_STR_HDR_UPDATE_TOPIC."</h2>");
 659        $this->showFormElementStart();
 660        $this->showFormElementTopicID($topicID);
 661        if ($topicID != "/") { /* root topic has no parent */
 662          $this->showFormElementParentTopicID($topic['ParentTopicID']);
 663        }
 664        $this->showFormElementDescriptionOneLine($topic['Description']);
 665        $this->showFormElementSummary($topic['Summary']);
 666        $this->showFormElementAction("updateTopic");
 667        $this->showFormElementEnd(SLZ_STR_BUTTON_UPDATE);
 668      }
 669    }
 670  
 671    /* private: show a form to delete a topic */

 672    function showFormDeleteTopic($topicID) {
 673      if ($this->ct->getTopic($topicID)) {
 674        $this->show("<h2>".SLZ_STR_HDR_DELETE_TOPIC."</h2>");
 675        $this->showFormElementStart();
 676        $this->showFormElementTopicID($topicID);
 677        $this->showFormElementAction("deleteTopic");
 678        $this->showFormElementEnd(SLZ_STR_BUTTON_DELETE);
 679      }
 680    }
 681  
 682    /* private: show a form to add a topic */

 683    function showFormAddTopic() {
 684      $this->show("<h2>".SLZ_STR_HDR_ADD_TOPIC."</h2>");
 685      $this->showFormElementStart();
 686      $this->showFormElementTopicID();
 687      $this->showFormElementParentTopicID();
 688      $this->showFormElementDescriptionOneLine();
 689      $this->showFormElementSummary();
 690      $this->showFormElementAction("addTopic");
 691      $this->showFormElementEnd(SLZ_STR_BUTTON_ADD);
 692    }
 693  
 694    /* private: show a form to update a picture */

 695    function showFormUpdatePicture($rollID, $frameID) {
 696      if ($picture = $this->ct->getPicture($rollID, $frameID)) {
 697        $this->show("<h2>".SLZ_STR_HDR_UPDATE_PICTURE."</h2>");
 698        $this->showFormElementStart();
 699        $this->showFormElementRollID($picture['RollID']);
 700        $this->showFormElementFrameID($picture['FrameID']);
 701        $this->showFormElementParentTopicID($picture['ParentTopicID']);
 702        $this->showFormElementDescriptionTextArea($picture['Description']);
 703        $this->showFormElementAction("updatePicture");
 704        $this->showFormElementEnd(SLZ_STR_BUTTON_UPDATE);
 705      }
 706    }
 707  
 708    /* private: show a form to delete a picture */

 709    function showFormDeletePicture($rollID, $frameID) {
 710      if ($this->ct->getPicture($rollID, $frameID)) {
 711        $this->show("<h2>".SLZ_STR_HDR_DELETE_PICTURE."</h2>");
 712        $this->showFormElementStart();
 713        $this->showFormElementRollID($rollID);
 714        $this->showFormElementFrameID($frameID);
 715        $this->showFormElementAction("deletePicture");
 716        $this->showFormElementEnd(SLZ_STR_BUTTON_DELETE);
 717      }
 718    }
 719  
 720    /* private: show a form to add a picture */

 721    function showFormAddPicture($rollID) {
 722      $this->show("<h2>".SLZ_STR_HDR_ADD_PICTURE."</h2>");
 723      $this->showFormElementStart();
 724      $this->showFormElementRollID($rollID);
 725      $this->showFormElementFrameID();
 726      $this->showFormElementParentTopicID();
 727      $this->showFormElementDescriptionTextArea();
 728      $this->showFormElementAction("addPicture");
 729      $this->showFormElementEnd(SLZ_STR_BUTTON_ADD);
 730    }
 731  
 732    /* private: show a form to add all pictures in a roll */

 733    function showFormAddAllPictures($rollID) {
 734      $this->show("<h2>".SLZ_STR_HDR_ADD_ALL_PICTURES."</h2>");
 735      $this->showFormElementStart();
 736      $this->showFormElementRollID($rollID);
 737      $this->showFormElementParentTopicID();
 738      $this->showFormElementAction("addAllPictures");
 739      $this->showFormElementEnd(SLZ_STR_BUTTON_ADDALL);
 740    }
 741  
 742    /* private: show a form to update a roll */

 743    function showFormUpdateRoll($rollID) {
 744      $this->show("<h2>".SLZ_STR_HDR_UPDATE_ROLL."</h2>");
 745      $this->showFormElementStart();
 746      $this->showFormElementRollID($rollID);
 747      $this->showFormElementAction("updateRoll");
 748      $this->showFormElementEnd(SLZ_STR_BUTTON_UPDATE);
 749    }
 750  
 751    /* private: show a form to delete a roll */

 752    function showFormDeleteRoll($rollID) {
 753      $this->show("<h2>".SLZ_STR_HDR_DELETE_ROLL."</h2>");
 754      $this->showFormElementStart();
 755      $this->showFormElementRollID($rollID);
 756      $this->showFormElementAction("deleteRoll");
 757      $this->showFormElementEnd(SLZ_STR_BUTTON_DELETE);
 758    }
 759  
 760    /* private: show a form to add a roll */

 761    function showFormAddRoll() {
 762      $this->show("<h2>".SLZ_STR_HDR_ADD_ROLL."</h2>");
 763      $this->showFormElementStart();
 764      $this->showFormElementRollID();
 765      $this->showFormElementAction("addRoll");
 766      $this->showFormElementEnd(SLZ_STR_BUTTON_ADD);
 767    }
 768  
 769    /* private: show a form to add a comment */

 770    function showFormAddComment($rollID, $frameID) {
 771  //  $this->show("<h2>".SLZ_STR_HDR_ADD_COMMENT."</h2>");

 772      $this->showFormElementStart();
 773      $this->showFormElementRollID($rollID);
 774      $this->showFormElementFrameID($frameID);
 775      $this->showFormElementComment();
 776      $this->showFormElementAction("addComment");
 777      $this->showFormElementEnd(SLZ_STR_BUTTON_ADD);
 778    }
 779  
 780    /* private: show a form to delete a comment */

 781    function showFormDeleteComment($commentID) {
 782  //  $this->show("<h2>".SLZ_STR_HDR_DELETE_COMMENT."</h2>");

 783      $this->showFormElementStart();
 784      $this->showFormElementCommentID($commentID);
 785      $this->showFormElementAction("deleteComment");
 786      $this->showFormElementEnd(SLZ_STR_BUTTON_DELETE);
 787    }
 788  
 789    /* private: show a form to add a rating */

 790    function showFormAddRating($rollID, $frameID, $rating=0) {
 791  //  $this->show("<h2>".SLZ_STR_HDR_ADD_RATING."</h2>");

 792      $this->showFormElementStart();
 793      $this->showFormElementRollID($rollID);
 794      $this->showFormElementFrameID($frameID);
 795      $this->showFormElementRating($rating);
 796      $this->showFormElementAction("addRating");
 797      $this->showFormElementEnd(SLZ_STR_BUTTON_RATE);
 798    }
 799  
 800    /* private: show a search form */

 801    function showFormSearch() {
 802      $this->showFormElementStart();
 803      $this->showFormElementSearch();
 804      $this->showFormElementAction("search");
 805      $this->showFormElementEnd(SLZ_STR_BUTTON_SEARCH);
 806    }
 807  
 808    /* private: show form start */

 809    function showFormElementStart() {
 810      $this->show("<form action=\"" . $this->actionURL . "\" method=\"post\"><p>");
 811    }
 812  
 813    /* private: show submit button and form end */

 814    function showFormElementEnd($button) {
 815      $this->show("<input type=\"submit\" value=\"" . $button . "\">");
 816  //  $this->show("</p></form>");

 817      $this->show("</form>");     /* Netscape rendering bug prohibits </p> */
 818    }
 819  
 820    /* private: show action form element */

 821    function showFormElementAction($action) {
 822        $this->show("<input type=\"hidden\" name=\"action\" " .
 823          "value=\"" . $action . "\">");
 824    }
 825  
 826    /* private: show Description form element as text input*/

 827    function showFormElementDescriptionOneLine($description = ""){
 828      $this->show(SLZ_STR_DESCRIPTION . ":<br>");
 829      $this->show("<input type=\"text\" size=\"32\" name=\"Description\" value=\"" . $description . "\"><br>");
 830    }
 831  
 832    /* private: show Description form element as textarea*/

 833    function showFormElementDescriptionTextArea($description = ""){
 834      $this->show(SLZ_STR_DESCRIPTION . ":<br>");
 835      $this->show("<textarea rows=\"4\" cols=\"40\" " . "name=\"Description\">" .
 836          $description . "</textarea><br>");
 837    }
 838  
 839    /* private: show Summary form element */

 840    function showFormElementSummary($Summary = ""){
 841      $this->show(SLZ_STR_SUMMARY . ":<br>");
 842      $this->show("<textarea rows=\"4\" cols=\"40\" " . "name=\"Summary\">" .
 843          $Summary . "</textarea><br>");
 844    }
 845  
 846    /* private: show Comment form element */

 847    function showFormElementComment($comment = ""){
 848      $this->show(SLZ_STR_COMMENT . ":<br>");
 849      $this->show("<textarea rows=\"3\" cols=\"40\" " . "name=\"Comment\">" .
 850          $comment . "</textarea><br>");
 851    }
 852  
 853    /* private: show Rating form element */

 854    function showFormElementRating($rating = 0){
 855      /* show current rating */

 856      $this->show(SLZ_STR_RATING . ": " . $this->ratingText($rating));
 857      /* show options for rating to add */

 858      $this->show("<br><br><select name=\"Rating\">");
 859      for( $i=2; $i>=-2; $i-- ) {
 860        $this->show("<option value=" . $i . ($i==0 ? " selected" : "") . ">" .
 861                    $this->ratingText($i) . "</option>");
 862      }
 863      $this->show("</select>");
 864    }
 865  
 866    /* private: show TopicID form element */

 867    function showFormElementTopicID($topicID = "") {
 868      if ($topicID != "") {
 869        $this->show("<input type=\"hidden\" name=\"TopicID\"");
 870        $this->show("value=\"" . $topicID . "\" >");
 871      }
 872      else {
 873        $this->show(SLZ_STR_TOPICID . ":<br>");
 874        $this->show("<input type=\"text\" name=\"TopicID\" ><br>");
 875      }
 876    }
 877  
 878    /* private: show ParentTopicID form element */

 879    function showFormElementParentTopicID($parentTopicID = "") {
 880      $this->show(SLZ_STR_PARENTTOPICID . ":<br>");
 881      $this->show("<select name=\"ParentTopicID\">");
 882  
 883      $topic = $this->ct->getTopic("/");
 884      $desc = $this->defaultText($topic['Description'], SLZ_STR_NO_DESC);
 885      $selectors = $this->getSelectFormElementParentTopicID($parentTopicID, "/", $desc);
 886      $this->show($selectors);
 887  
 888      $this->show("</select><br>");
 889    }
 890  
 891    /* private: get sorted (with indentation) ParentTopicID values for form */

 892    function getSelectFormElementParentTopicID($parentTopicID, $id, $desc, $count = 0) {
 893      $selectors = "<option value=\"" . $id . "\"" .
 894        (($id == $parentTopicID) ? " selected" : "") .
 895        ">" . $desc . "</option>" . $this->nl;
 896  
 897      $count++;
 898  
 899      $subTopics = $this->ct->getTopicsInParentTopic($id);
 900      reset($subTopics);
 901      while (list($key, $value) = each($subTopics)) {
 902        $desc = $this->defaultText($value['Description'], SLZ_STR_NO_DESC);
 903        $desc = str_pad("", $count*strlen($this->parentSelectPad),
 904                        $this->parentSelectPad) . $desc;
 905        $selectors = $selectors .
 906          $this->getSelectFormElementParentTopicID($parentTopicID, $value['TopicID'], $desc, $count);
 907      }
 908      return $selectors;
 909    }
 910  
 911    /* private: show RollID form element */

 912    function showFormElementRollID($rollID = "") {
 913      if ($rollID != "") {
 914        $this->show("<input type=\"hidden\" name=\"RollID\"");
 915        $this->show("value=\"" . $rollID . "\" >");
 916      }
 917      else {
 918        $this->show(SLZ_STR_ROLLID . ":<br>");
 919        $this->show("<input type=\"text\" name=\"RollID\" ><br>");
 920      }
 921    }
 922  
 923    /* private: show FrameID form element */

 924    function showFormElementFrameID($frameID = "") {
 925      if ($frameID != "") {
 926        $this->show("<input type=\"hidden\" name=\"FrameID\"");
 927        $this->show("value=\"" . $frameID . "\" >");
 928      }
 929      else {
 930        $this->show(SLZ_STR_FRAMEID . ":<br>");
 931        $this->show("<input type=\"text\" name=\"FrameID\" ><br>");
 932      }
 933    }
 934  
 935    /* private: show CommentID form element */

 936    function showFormElementCommentID($commentID) {
 937      $this->show("<input type=\"hidden\" name=\"CommentID\"");
 938      $this->show("value=\"" . $commentID . "\" >");
 939    }
 940  
 941    /* private: show search form element */

 942    function showFormElementSearch() {
 943      $this->show("<input type=\"text\" name=\"search\">");
 944    }
 945  
 946    /* private: generate a text representation of a rating value */

 947    function ratingText($rating) {
 948      $text[-2] = SLZ_STR_RATING_M2;
 949      $text[-1] = SLZ_STR_RATING_M1;
 950      $text[0] = SLZ_STR_RATING_0;
 951      $text[1] = SLZ_STR_RATING_P1;
 952      $text[2] = SLZ_STR_RATING_P2;
 953      $i = round(max(min(doubleval($rating), 2.0), -2.0));
 954      $r = sprintf("%1.2f", $rating);
 955      $r = str_replace( ".00", "", $r);
 956      $string = $r . " : " . $text[$i];
 957      return ($string);
 958    }
 959  
 960    /* private: generate a string, substituting a default if the text is blank */

 961    function defaultText($text, $deflt) {
 962      return( $text != '' ? $text : $deflt );
 963    }
 964  
 965    /* private: add a string to the html to be returned */

 966    function show($msg) {
 967      $this->htmlStr .= $msg . $this->nl;
 968    }
 969  
 970    /* private: add a string to the html to be returned */

 971    function show_error($msg) {
 972      if (!strlen($msg))
 973        $msg = SLZ_STR_ERR_DFLT; /* default error message */
 974      $this->show("<p class=\"sloozeerror\">Error: ".$msg."</p>");
 975    }
 976  
 977    /* private: write accumulated html to a cache file */

 978    function cacheWrite($tag) {
 979      if ($fp = @fopen($this->cachePath . $tag . '.tmp', 'w')) {
 980        $comment = '<!-- Cached -->' . $this->nl;
 981        fwrite($fp, $this->htmlStr . $comment);
 982        fclose($fp);
 983      }
 984    }
 985  
 986    /* private: read cache file to html string */

 987    function cacheRead($tag) {
 988      if ($fp = @fopen($this->cachePath . $tag . '.tmp', 'r')) {
 989        $this->htmlStr .= fread($fp, 32768);
 990        fclose($fp);
 991        return TRUE;
 992      }
 993      return FALSE;
 994    }
 995  
 996    /* private: clear the cache */

 997    function cacheClear() {
 998      if ($handle = opendir($this->cachePath)) {
 999        while ($file = readdir($handle)) {
1000          /* if is cache file */

1001          if(ereg('.+\.tmp$', $file)) {
1002            unlink($this->cachePath . $file);
1003  //        system('del "' . $this->cachePath . $file . '"');   /* Windows platforms */

1004          }
1005        }
1006        closedir($handle);
1007      }
1008    }
1009  
1010  } /* end of class Slooze */
1011  
1012    /* ------------------------------------------------------------------- */

1013  
1014    /* Private: cmpViews is a helper function for sortPictures */

1015    /* It has to be outside Slooze class due to limitations of the usort function */

1016    function cmpViews($a, $b) {
1017      if ($a['Views'] == $b['Views']) return 0;
1018      return ($a['Views'] > $b['Views']) ? -1 : 1;
1019    }
1020  
1021    /* Private: cmpRating is a helper function for sortPictures */

1022    /* It has to be outside Slooze class due to limitations of the usort function */

1023    function cmpRating($a, $b) {
1024      if ($a['Rating'] == $b['Rating']) return 0;
1025      return ($a['Rating'] > $b['Rating']) ? -1 : 1;
1026    }
1027  
1028  ?>

title

Description

title

Description

title

Description

title

title

Body