跳轉到內容

理解諾亞的分類資訊/多圖上傳

來自 Wikibooks,開放世界中的開放書籍

在諾亞的分類資訊中,廣告只能提交一張圖片,我們希望提交 n 張圖片。

解決方案

[編輯 | 編輯原始碼]

按照下面列出的步驟修改原始碼

初步編碼

[編輯 | 編輯原始碼]

在我們做任何事情之前,我想將諾亞的影像操作封裝到一個類中,或者至少是一組函式中。最初編寫程式碼的人沒有這樣做。我認為這是一個很大的錯誤,因為它極大地複雜化了程式碼。

以下內容來自諾亞原始碼和我的天才常識。所有這些都將放在一個新檔案中,我們將稱之為 image.php。我們的想法是建立一個影像管理庫,我們可以將其用於其他專案,而無需進行太多重編碼。

Image.php 原始碼

目標功能

[編輯 | 編輯原始碼]

現在讓我們先談談我們的目標。我們希望實現以下功能

  • 修改從設定類別螢幕儲存的圖片最大數量(因此每個類別可以允許可變數量的圖片)
  • 從類別螢幕修改最大圖片大小和縮圖大小
  • 上傳系列中的第一張圖片將用作列出所有廣告時的顯示圖片
  • 刪除廣告時,必須刪除圖片及其縮圖
  • 每個不同的類別都必須能夠插入自定義 HTML 文字,這些文字將用作分隔符。
  • 動態建立上傳欄位,以便提交不顯得雜亂

修改 gorum/dbproperty.php

[編輯 | 編輯原始碼]

由於所有 object_vars 都自動儲存到資料庫中,因此使用 $this->data 將資料從一個函式傳遞到下一個函式存在問題。為了解決這個問題,需要對 dbproperty.php 進行以下修改。

 function getCreateSetStr($base, $typ, $create=TRUE)
 {
     $object_vars = get_object_vars($base);
     $firstField = TRUE;
     $query = "";
     $typ = $base->getTypeInfo();
     foreach( $object_vars as $attribute=>$value )
     {
  // NEW DAWID
  if (!isset($typ["attributes"][$attribute]))
  continue;
  // NEW DAWID

修改 gorum/object.php

[編輯 | 編輯原始碼]

更改函式 getVisibility,如所示

 function getVisibility( $typ, $attr )
 {
     global $gorumroll;
  
  if (!isset($typ["attributes"][$attr]))
  return Form_hidden;

修改分類

[編輯 | 編輯原始碼]

首先,我們需要在我們的類別資料庫(表:classifieds_classifiedscategory)中新增 6 行新資料。

imagesAllowed, Type int(4), default = 10, Unsigned
ThumbSizeX, Type int(10), default = 64, Unsigned
ThumbSizeY, Type int(10), default = 100, Unsigned
imageMaxSizeX, Type int(12), default = 800, Unsigned
imageMaxSizeY, Type int(12), default = 600, Unsigned
imageSpacer, Type varchar(250), default = 'HTML TEXT'

這些是我新增的新行。從資訊中您可以看到,imagesAllowed 的範圍是 0-16,thumbSize 的範圍是 0-1024,imageSize 的範圍是 0-2048。如果這些太少或太多,請相應地調整,以免佔用資料庫空間。

以下是用於新增這些內容的 SQL 指令碼

 ALTER TABLE `classifieds_classifiedscategory` ADD `imagesAllowed` INT( 4 ) UNSIGNED NOT NULL DEFAULT '10',
 ADD `thumbSizeX` INT( 10 ) UNSIGNED NOT NULL DEFAULT '64',
 ADD `thumbSizeY` INT( 10 ) UNSIGNED NOT NULL DEFAULT '100',
 ADD `imageMaxSizeX` INT( 12 ) UNSIGNED NOT NULL DEFAULT '800',
 ADD `imageMaxSizeY` INT( 12 ) UNSIGNED NOT NULL DEFAULT '600';
 ADD `imageSpacer` VARCHAR( 250 ) NOT NULL DEFAULT '<br/><img src="i/spacer.gif" alt="." width="$thumbWidth" height="20" />';

修改 category.php 的原始碼

由於諾亞使用的框架很出色,我們可以輕鬆地將更多欄位新增到類別中。只需在檔案頂部新增這些行。

 $category_typ["attributes"]["picture"] =  
             array(
                 "type"=>"VARCHAR",
                 "file",
                 "max" =>"250"
              );
 
 /* DAWID JOUBERT IMAGE MODIFICATIONS ADDITIONS */
 $category_typ["attributes"]["imagesAllowed"] =  
             array(
                 "type"=>"INT",
                 "text",
                 "max" =>"16"
              );  
 $category_typ["attributes"]["thumbSizeX"] =  
             array(
                 "type"=>"INT",
                 "text",
                 "max" =>"1024"
              );    
 $category_typ["attributes"]["thumbSizeY"] =  
             array(
                 "type"=>"INT",
                 "text",
                 "max" =>"1024"
              ); 
 $category_typ["attributes"]["imageMaxSizeX"] =  
             array(
                 "type"=>"INT",
                 "text",
                 "max" =>"2048"
              );
 $category_typ["attributes"]["imageMaxSizeY"] =  
             array(
                 "type"=>"INT",
                 "text",
                 "max" =>"2048"
              ); 
 $category_typ["attributes"]["imageSpacer"] =  
             array(
                 "type"=>"VARCHAR",
                 "text",
                 "max" =>"250"
              );        
 
 class ClassifiedsCategory extends Category

將新文字新增到語言檔案

現在,我們還需要將以下內容新增到 lang_en.php(以及您計劃使用的所有其他語言)中。為了保持一致性,請將其新增到名為“類別”的註釋之後

 // Dawid Joubert Image Editing
 $lll["imagesAllowed"]="Number of Images Allowed";
 $lll["thumbSizeX"]="Generated Thumbnails' size X";
 $lll["thumbSizeY"]="Generated Thumbnails' size Y";
 $lll["imageMaxSizeX"]="Max Image Size X";
 $lll["imageMaxSizeY"]="Max Image Size Y";
 $lll["imageSpacer"]="HTML Text to place after each image (use as spacer)";
 $lll["pictureTemp"]='Pictures';
 $lll["imageFileNotLoaded"]='Image file not saved/created!';

修改廣告

[編輯 | 編輯原始碼]

在表 classifieds_advertisement 中,我們不會新增任何行。相反,我們將修改一個名為 picture 的現有行。

Picture 是大小為 250 的字串(VARCHAR)。目前,諾亞將上傳的 1 張圖片的副檔名儲存在 picture 中。我們將執行類似的操作,我們將儲存檔案的副檔名,但將它們用逗號分隔。因此,第一個副檔名是第一張圖片,第二個副檔名是第二張圖片,依此類推。

現在我們必須修改 advertisements.php 的原始碼 這將是大量的修改,因此讓我們首先就當前的功能達成一致。

圖片儲存在“$adAttDir/$this->id".".".$ext”下,它們的縮圖儲存在“$adAttDir/th_$this->id".".".$ext”下。這種格式對於儲存單個圖片沒有問題,但對於儲存多個圖片來說就存在問題。因此,我們將對其進行修改。

首先,為了保持向後相容性,我們將保留序列中第一個圖片的當前格式,但第二個、第三個和第 n 個圖片將採用以下模式。

完整圖片:“$adAttDir/$this->id"."-$i.".$this->picture”

縮圖:“$adAttDir/th_$this->id"."-$i.".$this->picture”

其中 $i 是圖片編號,從 0 開始,因此如果使用者有 6 張 jpeg 圖片,它們將被命名為以下方式

pictures/listings/5.jpg // First image. Shown in advert listing
pictures/listings/5-0.jpg // Second Image. Shown in details view (when viewing the advert)
pictures/listings/5-1.jpg // ""
pictures/listings/5-2.jpg // ""
pictures/listings/5-3.jpg // ""
pictures/listings/5-4.jpg // ""

我們需要一個函式,可以將像“jpg,gif,jpg”這樣的字串拆分為陣列(“jpg”,“gif”,“jpg”)。在 image.php 中已經建立了這樣一個函式,名為 getImageExtensionsFromString($string)


因此,我認為我們需要修改 4 個函式

  • delete()
    當您刪除廣告時,將呼叫此函式
  • showListVal()
    此函式用於顯示廣告列表和廣告詳情本身中的每條資訊。我們需要此函式,以便它現在在檢視廣告詳情時列出所有圖片
  • activateVariableFields()
    此函式需要進行修改,以便它顯示上傳 n 張圖片的選項
  • storeAttatchment()
    修改,以便它實際儲存所有傳入的圖片
  • showDetials()
    顯示廣告的詳細檢視

替換裡面的所有內容

 if ($this->picture) 
 {
 .. Old Code ..
 };

用這個,使整個塊看起來像(現在任何人都敢告訴我這看起來不乾淨!!!)

  if( $this->picture )
  {
  $this->getImageExtensions();
  $limit = count($this->imageExtensions); 
  for ($i=0;$i < $limit;$i++)
  {
  cleanDelete($this->getImageName($i));
  cleanDelete($this->getThumbName($i)); 
  }
  }

showListVal()

[編輯 | 編輯原始碼]

替換裡面的所有內容

 elseif ($attr=="showpic") 
 {
  ..old source code...
 }
</syntaxhighlight">

With. After which I briefly describe what we are doing.
<syntaxhighlight lang="php">
 elseif ($attr=="showpic") 
  {
  $s="<img src='$adAttDir/no.png'>"; // Will be overwritten later
  $this->getImageLimits();
  
  if($this->picture && $this->imagesAllowed) // Do we have any extensions to work with?
  {
  // Create the image extensions for use
  $this->getImageExtensions(); 
  $this->Debug(); 
  // Are we in the details view?
  if ($gorumroll->method == "showdetails")
  {
  $limit = count($this->imageExtensions); 
  $s = ''; 
  for ($i=0;$i < $limit;$i++)
  {
  if (strlen($this->imageExtensions[$i]) > 2)
  { 
  $s .= $this->getImageHTML($i)."<br />"; 
  }
  } 
  }
  else
  { 
  // Just make the output equal to a single image
  $s= $this->getImageHTML(0);
  }
  }
  }

$s 是函式的輸出緩衝區。所有 HTML 必須寫入其中。我們首先將 $s 設定為預設影像圖示。這樣,如果未找到任何影像,至少會顯示預設圖示。接下來,我們檢視 picture 中是否有任何文字(請記住,在 php 中 "" 或 0 或 "0" 都被視為“false”)。因此,如果其中有圖片,我們會繼續。使用 getImageExtensions() 提取影像副檔名。然後,根據這是列表檢視還是詳細檢視,我們將第一個或所有影像列印到緩衝區。


activateVariableFields()

[編輯 | 編輯原始碼]

在 advertisement.php 的頂部,有 $item_typ["attributes"]["picture"] = {..}; 將此新增到陣列 "form invisible" 中,這將確保在修改/建立新增時不會將其新增到表單中。上面提到的宣告現在將如下所示。

 $item_typ["attributes"]["picture"] =  
             array(
                 "type"='>'"VARCHAR",
                 "file",
                 "max" ='>'"250",
  "form invisible"
              );

現在,下一部分將確保在呼叫 CREATE_FORM 和 MODIFY_FORM 方法時,影像欄位將新增到表單中。將此新增到全域性定義之後。

 global $gorumroll, $expiration;
 // NEW CODE DAWID
 $this-'>'getImageLimits(); 
 // Create new input boxes for each picture, but only if we are creating a new advert or modifying an existing one
 if (($gorumroll-'>'method == "modify_form") || ($gorumroll-'>'method == "create_form"))
 {
  for ($i = 0;$i '<' $this-'>'imagesAllowed;$i++)
  {
  $lll["picture$i"]=str_replace('$i',$i$,lll["pictureTemp"]); // Creates language thingies
  $item_typ["attributes"]["picture$i"] =  
  array(
  "type"='>'"VARCHAR",
  "file",
  "max" ='>'"250"
   ); 
  };
 };
 // NEW CODE DAWID
 
 hasAdminRights($isAdm);

abba

此函式驗證上傳的單個影像,然後再儲存影像。其餘的驗證由它繼承的類完成。只需刪除整個內容即可。

storeAttachment()

[編輯 | 編輯原始碼]

此函式幾乎完全修改了,只需複製新的函式即可。

 function storeAttachment()
 {
     global $HTTP_POST_FILES;
     global $whatHappened, $lll, $infoText;
     global $adAttDir, $applName, $itemClassName;
     global $maxPicSize;
  
  // New code
     // Load this class
  $this->getImageLimits(); // Get the dimensions and stuff allowed
  $this->getImageExtensions();
  $parsedAtleastOne = false;
  $count = 0;
  // Loop for every image allowed
  for ($i = 0;$i < $this->imagesAllowed;$i++)
  { 
  if ((isset($this->imageExtensions[$count]) == false))
  $this->imageExtensions[$count] = ".";
  
  if (strlen($this->imageExtensions[$count]) > 2) 
  {
  $count++;
  $hasImage = true;
  } else $hasImage = false;
  
  $ind = "picture$i";
      if (!isset($HTTP_POST_FILES[$ind]["name"]) || $HTTP_POST_FILES[$ind]["name"]=="")
  continue;
 
  if (!file_exists($HTTP_POST_FILES[$ind]["tmp_name"]))
  {
  // This should never happen
  handleError("Temp Image doesn't exists?? WTF"); 
  continue;
  }
 
  if (strstr($HTTP_POST_FILES[$ind]["name"]," "))
  {
          $infoText .= $lll["spacenoatt"].'<br />';
  continue;
      }
  
      if ($HTTP_POST_FILES[$ind]["tmp_name"]=="none")
  continue;
  
      if ($HTTP_POST_FILES[$ind]["size"] > $maxPicSize) 
  {
          $infoText .= sprintf($lll["picFileSizeToLarge2"], $maxPicSize).'<br />';
  continue; 
      }
  
  $fname=$HTTP_POST_FILES[$ind]["tmp_name"];
  $size = getimagesize($fname);
  if (!$size) 
  {
  $infoText.=$lll["notValidImageFile"].'<br />';
  continue; 
  }
  
  $type = $size[2];
  global $g_Extensions; // Found in image.php
  if (!isset($g_Extensions[$type])) 
  {
  $infoText .=$lll["notValidImageFile"].'<br />';
  continue; 
  } 
  
  // We are checking dimensions anymore as we might as well resize the image
 /* if( $size[0]>$this->imageMaxSizeX || $size[1]>$this->imageMaxSizeY )
  {
  $infoText .=sprintf($lll["picFileDimensionToLarge"], $this->imageMaxSizeX, $this->imageMaxSizeY).'<br />';
  $whatHappened = "invalid_form";
  continue;
  } */ 
  if ($hasImage) $count--;
  
  // Instanciate a new image
  $image = new myImage;
  // Read the image
  $image->ReadImage($HTTP_POST_FILES[$ind]["tmp_name"]);
 
  // Remove old pictures and thumbnails
  cleanDelete($this->getImageName($count));
  cleanDelete($this->getThumbName($count));
  
  // Save the image extension
  $this->imageExtensions[$count] = $g_Extensions[$type]; 
 
  // Now create our image
  if ($image->CreateLocal($this->getImageName($count),$this->imageMaxSizeX$,this->imageMaxSizeY))
  {
  // Create the thumb
  $image->CreateLocal($this->getThumbName($count),$this->thumbSizeX$,this->thumbSizeY,true);   
  
  $parsedAtleastOne = true; 
  $count++;
  }
  else 
  {
  // Why wasn't it created, could it be because the file format doesn't support resizing
  if ($image->supported == false)
  $infoText .=sprintf($lll["picFileDimensionToLarge"], $this->imageMaxSizeX, $this->imageMaxSizeY).'<br />';
  else $infoText.=$lll["imageFileNotLoaded"].'<br />';
  $this->imageExtensions[$count] = "."; 
  }
  }
     $HTTP_POST_FILES["picture"]["name"]="";
  if ($parsedAtleastOne)
  {
  $this->picture = addslashes(createImageExtensionsStringFromArray($this->imageExtensions));
  $this->Debug();
  // Create the extensions string
  $query = "UPDATE $applName"."_$itemClassName SET picture='$this->picture'".
   " WHERE id=$this->id";
  executeQuery( $query );
  }
     return ok;
 }

showDetails()

[編輯 | 編輯原始碼]

更改內部的所有內容

 if($this-'>'picture)
 {
  ...
 }

改為

  if($this->picture)
  { 
  $s.="<tr><td valign='top' align='left' rowspan='30' class='cell'>\n";
  $s.=$this->showListVal("showpic");
  $s.="</td>";
  $s.="</tr>\n";
  }

最後更多函式

[編輯 | 編輯原始碼]

將這些新函式新增到檔案頂部

 /**********************************/
 // Advertisement specific image functions
 function cleanDelete($name)
 {
  if (file_exists($name))
  {
  // Attempt to delete
      $ret=@unlink($name); 
  if(!$ret) $infoText=sprintf($lll["cantdelfile"],$name);
  return $ret;
  }
  return true;
 };
 
 function getImageExtensionsFromString($string)
 {
  return split('[,]', $string);
 };
 
 function createImageExtensionsStringFromArray($arr)
 {
  $out = "";
  foreach ($arr as $value)
  {
  $out .= $value.',';
  }
  return $out;
 }
 
 /**********************************/
 
 class Advertisement extends Item
 {
 
 /**********************************/
 // Advertisement specific image functions
 
  function getImageExtensions()
  {
  if (isset($this->picture))
  $this->imageExtensions = getImageExtensionsFromString($this->picture);
  }
  
  function getImageName($i)
  {
  if (!isset($this->imageExtensions[$i])) return ""; 
  global $adAttDir;
  if ($i != 0) 
  {
  return $fileName = "$adAttDir/$this->id"."-$i.".$this->imageExtensions[$i];
  }
  else return $fileName = "$adAttDir/$this->id".".".$this->imageExtensions[$i];
  }
  
  function getThumbName($i)
  {
  if (!isset($this->imageExtensions[$i])) return ""; 
  global $adAttDir;
  if ($i != 0) 
  {
  return $thumbName = "$adAttDir/th_$this->id"."-$i.".$this->imageExtensions[$i];
  }
  else return $thumbName = "$adAttDir/th_$this->id".".".$this->imageExtensions[$i];
  }
  
  function getImageHTML($i)
  {
  if (!isset($this->imageExtensions[$i])) return "";
  if (strlen($this->imageExtensions[$i]) < 2) return "";
  $picName = $this->getImageName($i); // Get the first image
  $thName = $this->getThumbName($i); // Get the first thumb
  
  // If the thumbnail doesn't exists use the original picture's name instead.
  if (!file_exists($thName)) $thName = $picName;
  if (!file_exists($picName)) return "";
  
  // Okay now we need to find the dimensions of the thumbnail and scale them for viewing.
  // If it really is a thumbnail we won't have to scale using html. If it isn't then we have no
  // other choice as the reason no thumb exists is because this format is not supported by php
  $size = getimagesize( $thName );
  $size = RatioImageSize($size,$this->thumbSizeX,$this->thumbSizeY,true);
  return "<a href='$picName' target='_blank'><img src='$thName' width='$size[0]' height='$size[1]' border='0'></a>$this->imageSpacer"; 
  }
 
  // Get the image settings from this advert's category 
  function getImageLimits()
  {
  //if (!isset($this->imageLimitsLoaded)) return;
  
      global $categoryClassName;
         $c = new $categoryClassName;
         $c->id = $this->cid;
         load($c);
         $this->imagesAllowed = $c->imagesAllowed;
         $this->thumbSizeX = $c->thumbSizeX;
         $this->thumbSizeY = $c->thumbSizeY;
         $this->imageMaxSizeX= $c->imageMaxSizeX; 
         $this->imageMaxSizeY= $c->imageMaxSizeY; 
  $this->imageLimitsLoaded = true;
  // Construct the image spacer
  $this->imageSpacer = 
  str_replace(array('$thumbWidth','$thumbHeight'),
  array($c->thumbSizeX$,c->thumbSizeY),$c->imageSpacer);
  
  // Quick validation test
  if ($c->imagesAllowed)
  {
  if ($c->thumbSizeX * $c->thumbSizeY * $c->imageMaxSizeX * $c->imageMaxSizeY <= 0)
  die('Image dimensions impossible');
  }
  }
  
  function Debug()
  {
  if (false)
  {
  if (isset($this->imageExtensions))
  echo array_to_str($this->imageExtensions); 
  if (isset($this->picture)) 
  echo array_to_str($this->picture); 
  }
  }
 /**********************************/

請注意,一半在類上面,另一半在類內部。

Image.php 原始碼

華夏公益教科書