Search:

# CWIS Developers Documentation

- Main Page
- Classes
- Files

- File List
- File Members

# SPTImage.php

Go to the documentation of this file.

    00001 <?PHP
    00002 #
    00003 #   FILE:  SPTImage.php
    00004 #
    00005 #   METHODS PROVIDED:
    00006 #       SPTImage($ImageIdOrFileNameOrImageObj,
    00007 #                   $MaxPreviewWidth = NULL, $MaxPreviewHeight = NULL,
    00008 #                   $MaxThumbnailWidth = NULL, $MaxThumbnailHeight = NULL)
    00009 #           - object constructor
    00010 #       Delete()
    00011 #           - delete image and associated files and data
    00012 #       AltText($NewValue = NULL)
    00013 #           - get/set alt text attribute
    00014 #       Id()
    00015 #       Url()
    00016 #       PreviewUrl()
    00017 #       ThumbnailUrl()
    00018 #       Format()
    00019 #       Height()
    00020 #       Width()
    00021 #       PreviewHeight()
    00022 #       PreviewWidth()
    00023 #       ThumbnailHeight()
    00024 #       ThumbnailWidth()
    00025 #           - get attributes
    00026 #
    00027 #   AUTHOR:  Edward Almasy
    00028 #
    00029 #   Part of CWIS
    00030 #   Copyright 2002-2011 Internet Scout Project
    00031 #   http://scout.wisc.edu
    00032 #
    00033
    00034 class SPTImage {
    00035
    00036     # ---- PUBLIC INTERFACE --------------------------------------------------
    00037
    00043     const IMAGE_PATH = "ImageStorage/";
    00044     const PREVIEW_PATH = "ImageStorage/Previews/";
    00045     const THUMBNAIL_PATH = "ImageStorage/Thumbnails/";
    00046
    00047     # object constructor
    00048     function SPTImage($ImageIdOrFileNameOrImageObj,
    00049                       $MaxWidth = NULL, $MaxHeight = NULL,
    00050                       $MaxPreviewWidth = NULL, $MaxPreviewHeight = NULL,
    00051                       $MaxThumbnailWidth = NULL, $MaxThumbnailHeight = NULL)
    00052     {
    00053         # clear error status (0 = AI_OKAY)
    00054         $this->ErrorStatus = 0;
    00055
    00056         # trigger the Image class file to be autoloaded since some parts of this
    00057         # class (SPTImage) use constants defined in it but don't construct Image
    00058         # objects
    00059         new Image(NULL);
    00060
    00061         # create and save a database handle for our use
    00062         $this->DB = new SPTDatabase();
    00063
    00064         # if image object was passed in
    00065         if (is_object($ImageIdOrFileNameOrImageObj)
    00066                 && method_exists($ImageIdOrFileNameOrImageObj, "SPTImage"))
    00067         {
    00068             # create copy of image passed in
    00069             $this->CreateCopyOfImage($ImageIdOrFileNameOrImageObj);
    00070         }
    00071         # else if image ID was passed in
    00072         elseif (($ImageIdOrFileNameOrImageObj > 0)
    00073                 && preg_match("/[0-9]+/", $ImageIdOrFileNameOrImageObj))
    00074         {
    00075             # load info on existing image
    00076             $this->LoadImageInfo($ImageIdOrFileNameOrImageObj);
    00077         }
    00078         # else assume that value passed in is file name
    00079         else
    00080         {
    00081             # create new image from named file
    00082             $this->CreateNewImage($ImageIdOrFileNameOrImageObj,
    00083                                   $MaxWidth, $MaxHeight,
    00084                                   $MaxPreviewWidth, $MaxPreviewHeight,
    00085                                   $MaxThumbnailWidth, $MaxThumbnailHeight);
    00086         }
    00087     }
    00088
    00089     # get attributes
    00090     function Id() {  return $this->Id;  }
    00091     function Url() {  return $this->FileName;  }
    00092     function PreviewUrl() {  return $this->PreviewFileName;  }
    00093     function ThumbnailUrl() {  return $this->ThumbnailFileName;  }
    00094     function Format() {  return $this->Format;  }
    00095     function Height() {  return $this->Height;  }
    00096     function Width() {  return $this->Width;  }
    00097     function PreviewHeight() {  return $this->PreviewHeight;  }
    00098     function PreviewWidth() {  return $this->PreviewWidth;  }
    00099     function ThumbnailHeight() {  return $this->ThumbnailHeight;  }
    00100     function ThumbnailWidth() {  return $this->ThumbnailWidth;  }
    00101     function ImageStorageDirectory() {  return self::IMAGE_PATH;  }
    00102     function PreviewStorageDirectory() {  return self::PREVIEW_PATH;  }
    00103     function ThumbnailStorageDirectory() {  return self::THUMBNAIL_PATH;  }
    00104     function GetLink() {  return $this->FileName;  }
    00105
    00106     # get/set attributes
    00107     function AltText($NewValue = NULL)
    00108     {
    00109         # if new value supplied and new value differs from existing value
    00110         if (($NewValue !== NULL) && ($NewValue != $this->AltText))
    00111         {
    00112             # save new value to database
    00113             $this->DB->Query("UPDATE Images SET"
    00114                              ." AltText = '".addslashes($NewValue)."'"
    00115                              ." WHERE ImageId = ".$this->Id);
    00116
    00117             # save new value locally
    00118             $this->AltText = $NewValue;
    00119         }
    00120
    00121         # return attribute value to caller
    00122         return $this->AltText;
    00123     }
    00124
    00125     # delete image and associated files and data
    00126     function Delete()
    00127     {
    00128         # delete base image file
    00129         if (file_exists($this->FileName)) {  unlink($this->FileName);  }
    00130
    00131         # delete preview image file
    00132         if (file_exists($this->PreviewFileName)) {  unlink($this->PreviewFileName);  }
    00133
    00134         # delete thumbnail image file
    00135         if (file_exists($this->ThumbnailFileName)) {  unlink($this->ThumbnailFileName);  }
    00136
    00137         # delete image info record in database
    00138         $this->DB->Query("DELETE FROM Images WHERE ImageId = ".$this->Id);
    00139     }
    00140
    00141     # return error status set by the constructor
    00142     function Status()
    00143     {
    00144         return $this->ErrorStatus;
    00145     }
    00146
    00147     # check to make sure image storage directories are available
    00148     # (returns array of error codes or NULL if no errors found)
    00149     static function CheckDirectories()
    00150     {
    00151         # determine paths
    00152         $ImagePath = self::IMAGE_PATH;
    00153         $PreviewPath = self::PREVIEW_PATH;
    00154         $ThumbnailPath = self::THUMBNAIL_PATH;
    00155
    00156         # assume everything will be okay
    00157         $ErrorsFound = NULL;
    00158
    00159         # check base image directory
    00160         if (!is_dir($ImagePath) || !is_writable($ImagePath))
    00161         {
    00162             if (!is_dir($ImagePath))
    00163             {
    00164                 @mkdir($ImagePath, 0755);
    00165             }
    00166             else
    00167             {
    00168                 @chmod($ImagePath, 0755);
    00169             }
    00170             if (!is_dir($ImagePath))
    00171             {
    00172                 $ErrorsFound[] = "Image Storage Directory Not Found";
    00173             }
    00174             elseif (!is_writable($ImagePath))
    00175             {
    00176                 $ErrorsFound[] = "Image Storage Directory Not Writable";
    00177             }
    00178         }
    00179
    00180         # check preview directory
    00181         if (!is_dir($PreviewPath) || !is_writable($PreviewPath))
    00182         {
    00183             if (!is_dir($PreviewPath))
    00184             {
    00185                 @mkdir($PreviewPath, 0755);
    00186             }
    00187             else
    00188             {
    00189                 @chmod($PreviewPath, 0755);
    00190             }
    00191             if (!is_dir($PreviewPath))
    00192             {
    00193                 $ErrorsFound[] = "Preview Storage Directory Not Found";
    00194             }
    00195             elseif (!is_writable($PreviewPath))
    00196             {
    00197                 $ErrorsFound[] = "Preview Storage Directory Not Writable";
    00198             }
    00199         }
    00200
    00201         # check thumbnail directory
    00202         if (!is_dir($ThumbnailPath) || !is_writable($ThumbnailPath))
    00203         {
    00204             if (!is_dir($ThumbnailPath))
    00205             {
    00206                 @mkdir($ThumbnailPath, 0755);
    00207             }
    00208             else
    00209             {
    00210                 @chmod($ThumbnailPath, 0755);
    00211             }
    00212             if (!is_dir($ThumbnailPath))
    00213             {
    00214                 $ErrorsFound[] = "Thumbnail Storage Directory Not Found";
    00215             }
    00216             elseif (!is_writable($ThumbnailPath))
    00217             {
    00218                 $ErrorsFound[] = "Thumbnail Storage Directory Not Writable";
    00219             }
    00220         }
    00221
    00222         # return any errors found to caller
    00223         return $ErrorsFound;
    00224     }
    00225
    00226     public function Resize($MaxWidth, $MaxHeight,
    00227                            $MaxPreviewWidth, $MaxPreviewHeight,
    00228                            $MaxThumbnailWidth, $MaxThumbnailHeight)
    00229     {
    00230         $SrcImage = new Image($this->FileName);
    00231
    00232         # scale the original image if necessary
    00233         $MaxWidth = min($MaxWidth, $SrcImage->XSize());
    00234         $MaxHeight = min($MaxHeight, $SrcImage->YSize());
    00235         $SrcImage->ScaleTo($MaxWidth, $MaxHeight, TRUE);
    00236
    00237         # save and reload image info
    00238         $SrcImage->SaveAs($this->FileName);
    00239         $SrcImage = new Image($this->FileName);
    00240
    00241         # retrieve image width and height
    00242         $this->Height = $SrcImage->YSize();
    00243         $this->Width = $SrcImage->XSize();
    00244
    00245         # generate preview image and calculate width and height
    00246         $MaxPreviewWidth = min($MaxPreviewWidth, $this->Width);
    00247         $MaxPreviewHeight = min($MaxPreviewHeight, $this->Height);
    00248         $SrcImage->ScaleTo($MaxPreviewWidth, $MaxPreviewHeight, TRUE);
    00249         $SrcImage->SaveAs($this->PreviewFileName, IMGTYPE_JPEG);
    00250         if (($this->Width * $MaxPreviewHeight)
    00251                 > ($this->Height * $MaxPreviewWidth))
    00252         {
    00253             $this->PreviewWidth = $MaxPreviewWidth;
    00254             $this->PreviewHeight =
    00255                     ($MaxPreviewWidth * $SrcImage->YSize()) / $SrcImage->XSize();
    00256         }
    00257         else
    00258         {
    00259             $this->PreviewWidth =
    00260                     ($MaxPreviewHeight * $SrcImage->XSize()) / $SrcImage->YSize();
    00261             $this->PreviewHeight = $MaxPreviewHeight;
    00262         }
    00263
    00264         # generate thumbnail image and calculate width and height
    00265         $MaxThumbnailWidth = min($MaxThumbnailWidth, $this->Width);
    00266         $MaxThumbnailHeight = min($MaxThumbnailHeight, $this->Height);
    00267         $SrcImage->ScaleTo($MaxThumbnailWidth, $MaxThumbnailHeight, TRUE);
    00268         $SrcImage->SaveAs($this->ThumbnailFileName, IMGTYPE_JPEG);
    00269         if (($this->Width * $MaxThumbnailHeight)
    00270                 > ($this->Height * $MaxThumbnailWidth))
    00271         {
    00272             $this->ThumbnailWidth = $MaxThumbnailWidth;
    00273             $this->ThumbnailHeight =
    00274                     ($MaxThumbnailWidth * $SrcImage->YSize()) / $SrcImage->XSize();
    00275         }
    00276         else
    00277         {
    00278             $this->ThumbnailWidth = ($MaxThumbnailHeight * $SrcImage->XSize()) / $SrcImage->YSize();
    00279             $this->ThumbnailHeight = $MaxThumbnailHeight;
    00280         }
    00281
    00282         # save image attributes to database
    00283         $this->SaveImageInfo();
    00284     }
    00285
    00286     # ---- PRIVATE INTERFACE -------------------------------------------------
    00287
    00288     var $Id;
    00289     var $FileName;
    00290     var $PreviewFileName;
    00291     var $ThumbnailFileName;
    00292     var $Format;
    00293     var $AltText;
    00294     var $Url;
    00295     var $PreviewUrl;
    00296     var $ThumbnailUrl;
    00297     var $Height;
    00298     var $Width;
    00299     var $PreviewHeight;
    00300     var $PreviewWidth;
    00301     var $ThumbnailHeight;
    00302     var $ThumbnailWidth;
    00303     var $DB;
    00304     var $ErrorStatus;
    00305
    00306     function CreateNewImage($FileName, $MaxWidth, $MaxHeight,
    00307                             $MaxPreviewWidth, $MaxPreviewHeight,
    00308                             $MaxThumbnailWidth, $MaxThumbnailHeight)
    00309     {
    00310         # if file does not exist or is not readable
    00311         if (!is_readable($FileName))
    00312         {
    00313             # set error status
    00314             $this->ErrorStatus = AI_FILEUNREADABLE;
    00315         }
    00316         else
    00317         {
    00318             # if image is invalid or unsupported type
    00319             $SrcImage = new Image($FileName);
    00320             if ($SrcImage->Status() != AI_OKAY)
    00321             {
    00322                 # set error status
    00323                 $this->ErrorStatus = $SrcImage->Status();
    00324             }
    00325             else
    00326             {
    00327                 # retrieve image type
    00328                 $this->Format = $SrcImage->Type();
    00329
    00330                 # generate new image ID
    00331                 $this->Id = $this->GenerateNewImageId();
    00332
    00333                 # generate and set file names
    00334                 $this->SetFileNames();
    00335
    00336                 # if our image file name differs from file name passed in
    00337                 if (realpath($this->FileName) != realpath($FileName))
    00338                 {
    00339                     # create image file
    00340                     $SrcImage->SaveAs($this->FileName);
    00341
    00342                     # if create failed set error status and bail out
    00343                     if ($SrcImage->Status() != AI_OKAY)
    00344                     {
    00345                         echo "create failed<br>";
    00346                         echo "Status: ".$SrcImage->Status()."<br>";
    00347                         echo "Failed Command: ".$SrcImage->FailedExternalCommand()."<br>";
    00348                         echo "Missing External Executables: ";
    00349                         print_r(Image::MissingExternalExecutables());
    00350                         echo "<br>";
    00351                         $this->ErrorStatus = $SrcImage->Status();
    00352                         return;
    00353                     }
    00354                 }
    00355
    00356                 # scale the original image if necessary
    00357                 $MaxWidth = min($MaxWidth, $SrcImage->XSize());
    00358                 $MaxHeight = min($MaxHeight, $SrcImage->YSize());
    00359                 $SrcImage->ScaleTo($MaxWidth, $MaxHeight, TRUE);
    00360
    00361                 # save and reload image info
    00362                 $SrcImage->SaveAs($this->FileName);
    00363                 $SrcImage = new Image($this->FileName);
    00364
    00365                 # retrieve image width and height
    00366                 $this->Height = $SrcImage->YSize();
    00367                 $this->Width = $SrcImage->XSize();
    00368
    00369                 # generate preview image and calculate width and height
    00370                 $MaxPreviewWidth = min($MaxPreviewWidth, $this->Width);
    00371                 $MaxPreviewHeight = min($MaxPreviewHeight, $this->Height);
    00372                 $SrcImage->ScaleTo($MaxPreviewWidth, $MaxPreviewHeight, TRUE);
    00373                 $SrcImage->SaveAs($this->PreviewFileName, IMGTYPE_JPEG);
    00374                 if ($SrcImage->Status() != AI_OKAY)
    00375                 {
    00376                     echo "preview save as failed<br>";
    00377                     $this->ErrorStatus = $SrcImage->Status();
    00378                     return;
    00379                 }
    00380                 if (($this->Width * $MaxPreviewHeight)
    00381                         > ($this->Height * $MaxPreviewWidth))
    00382                 {
    00383                     $this->PreviewWidth = $MaxPreviewWidth;
    00384                     $this->PreviewHeight =
    00385                             ($MaxPreviewWidth * $SrcImage->YSize()) / $SrcImage->XSize();
    00386                 }
    00387                 else
    00388                 {
    00389                     $this->PreviewWidth =
    00390                             ($MaxPreviewHeight * $SrcImage->XSize()) / $SrcImage->YSize();
    00391                     $this->PreviewHeight = $MaxPreviewHeight;
    00392                 }
    00393
    00394                 # generate thumbnail image and calculate width and height
    00395                 $MaxThumbnailWidth = min($MaxThumbnailWidth, $this->Width);
    00396                 $MaxThumbnailHeight = min($MaxThumbnailHeight, $this->Height);
    00397                 $SrcImage->ScaleTo($MaxThumbnailWidth, $MaxThumbnailHeight, TRUE);
    00398                 $SrcImage->SaveAs($this->ThumbnailFileName, IMGTYPE_JPEG);
    00399                 if ($SrcImage->Status() != AI_OKAY)
    00400                 {
    00401                     echo "thumbnail SaveAs failed.<br>";
    00402                     $this->ErrorStatus = $SrcImage->Status();
    00403                     return;
    00404                 }
    00405                 if (($this->Width * $MaxThumbnailHeight)
    00406                         > ($this->Height * $MaxThumbnailWidth))
    00407                 {
    00408                     $this->ThumbnailWidth = $MaxThumbnailWidth;
    00409                     $this->ThumbnailHeight =
    00410                             ($MaxThumbnailWidth * $SrcImage->YSize()) / $SrcImage->XSize();
    00411                 }
    00412                 else
    00413                 {
    00414                     $this->ThumbnailWidth = ($MaxThumbnailHeight * $SrcImage->XSize()) / $SrcImage->YSize();
    00415                     $this->ThumbnailHeight = $MaxThumbnailHeight;
    00416                 }
    00417
    00418                 # save image attributes to database
    00419                 $this->SaveImageInfo();
    00420             }
    00421         }
    00422     }
    00423
    00424     function LoadImageInfo($ImageId)
    00425     {
    00426         # save image ID
    00427         $this->Id = $ImageId;
    00428
    00429         # load image record from database
    00430         $this->DB->Query("SELECT * FROM Images WHERE ImageId = ".$ImageId);
    00431
    00432         # if the ID is invalid
    00433         if (!$this->DB->NumRowsSelected())
    00434         {
    00435             $this->ErrorStatus = AI_INTERNALERROR;
    00436             return;
    00437         }
    00438
    00439         $Record = $this->DB->FetchRow();
    00440
    00441         # load in values from record
    00442         $this->Format          = $Record["Format"];
    00443         $this->AltText         = $Record["AltText"];
    00444         $this->Height          = $Record["Height"];
    00445         $this->Width           = $Record["Width"];
    00446         $this->PreviewHeight   = $Record["PreviewHeight"];
    00447         $this->PreviewWidth    = $Record["PreviewWidth"];
    00448         $this->ThumbnailHeight = $Record["ThumbnailHeight"];
    00449         $this->ThumbnailWidth  = $Record["ThumbnailWidth"];
    00450
    00451         # generate file names
    00452         $this->SetFileNames();
    00453     }
    00454
    00455     function CreateCopyOfImage($SrcImage)
    00456     {
    00457         $Image = new Image($SrcImage->Url());
    00458         if ($Image->Status() != AI_OKAY)
    00459         {
    00460             # set error status
    00461             $this->ErrorStatus = $Image->Status();
    00462             return;
    00463         }
    00464
    00465         # generate new image ID
    00466         $this->Id = $this->GenerateNewImageId();
    00467
    00468         # generate file names
    00469         $this->SetFileNames();
    00470
    00471         # copy attributes from source image
    00472         $this->Format = $SrcImage->Format();
    00473         $this->AltText = $SrcImage->AltText();
    00474         $this->Width = $SrcImage->Width();
    00475         $this->Height = $SrcImage->Height();
    00476         $this->PreviewWidth = $SrcImage->PreviewWidth();
    00477         $this->PreviewHeight = $SrcImage->PreviewHeight();
    00478         $this->ThumbnailWidth = $SrcImage->ThumbnailWidth();
    00479         $this->ThumbnailHeight = $SrcImage->ThumbnailHeight();
    00480
    00481         # copy source image files
    00482         copy($SrcImage->Url(), $this->FileName);
    00483         copy($SrcImage->PreviewUrl(), $this->PreviewFileName);
    00484         copy($SrcImage->ThumbnailUrl(), $this->ThumbnailFileName);
    00485
    00486         # save image attributes to database
    00487         $this->SaveImageInfo();
    00488     }
    00489
    00490     # generate and save image, preview, and thumnail file names
    00491     # (requires image ID and format to be set beforehand)
    00492     function SetFileNames()
    00493     {
    00494         if (Image::Extension($this->Format))
    00495         {
    00496             $FileExtension = Image::Extension($this->Format);
    00497         }
    00498         else
    00499         {
    00500             $FileExtension = "";
    00501         }
    00502
    00503         $this->FileName = self::IMAGE_PATH . "Img--"
    00504                 .sprintf("%08d.", $this->Id).$FileExtension;
    00505         $this->PreviewFileName = self::PREVIEW_PATH . "Preview--"
    00506                 .sprintf("%08d.", $this->Id).$FileExtension;
    00507         $this->ThumbnailFileName = self::THUMBNAIL_PATH . "Thumb--"
    00508                 .sprintf("%08d.", $this->Id).$FileExtension;
    00509     }
    00510
    00511     # retrieve next image ID
    00512     function GenerateNewImageId()
    00513     {
    00514         # look up highest image ID in database
    00515         $CurrentHighestId = $this->DB->Query("SELECT ImageId FROM Images"
    00516                                              ." ORDER BY ImageId DESC LIMIT 1",
    00517                                              "ImageId");
    00518
    00519         # return next highest ID or 1 if no ID yet used
    00520         return ($CurrentHighestId > 0) ? ($CurrentHighestId + 1) : 1;
    00521     }
    00522
    00523     # store image attributes to database
    00524     function SaveImageInfo()
    00525     {
    00526         # look for existing image record with matching ID
    00527         $RecordCount = $this->DB->Query("SELECT COUNT(*) AS RecordCount FROM Images"
    00528                                         ." WHERE ImageId = ".$this->Id,
    00529                                         "RecordCount");
    00530
    00531         # if matching ID found
    00532         if ($RecordCount > 0)
    00533         {
    00534             # update existing image record
    00535             $this->DB->Query("UPDATE Images SET"
    00536                              ." Format = '"         .$this->Format."',"
    00537                              ." AltText = '"        .addslashes($this->AltText)."',"
    00538                              ." Height = '"         .$this->Height."',"
    00539                              ." Width = '"          .$this->Width."',"
    00540                              ." PreviewHeight = '"  .$this->PreviewHeight."',"
    00541                              ." PreviewWidth = '"   .$this->PreviewWidth."',"
    00542                              ." ThumbnailHeight = '".$this->ThumbnailHeight."',"
    00543                              ." ThumbnailWidth = '" .$this->ThumbnailWidth."'"
    00544                              ." WHERE ImageId = ".$this->Id);
    00545         }
    00546         else
    00547         {
    00548             # add new image record
    00549             $this->DB->Query("INSERT INTO Images SET"
    00550                              ." ImageId = '"        .$this->Id."',"
    00551                              ." Format = '"         .$this->Format."',"
    00552                              ." AltText = '"        .addslashes($this->AltText)."',"
    00553                              ." Height = '"         .$this->Height."',"
    00554                              ." Width = '"          .$this->Width."',"
    00555                              ." PreviewHeight = '"  .$this->PreviewHeight."',"
    00556                              ." PreviewWidth = '"   .$this->PreviewWidth."',"
    00557                              ." ThumbnailHeight = '".$this->ThumbnailHeight."',"
    00558                              ." ThumbnailWidth = '" .$this->ThumbnailWidth."'");
    00559         }
    00560     }
    00561 }