理解諾亞的分類資訊/多圖上傳
在諾亞的分類資訊中,廣告只能提交一張圖片,我們希望提交 n 張圖片。
按照下面列出的步驟修改原始碼
在我們做任何事情之前,我想將諾亞的影像操作封裝到一個類中,或者至少是一組函式中。最初編寫程式碼的人沒有這樣做。我認為這是一個很大的錯誤,因為它極大地複雜化了程式碼。
以下內容來自諾亞原始碼和我的天才常識。所有這些都將放在一個新檔案中,我們將稱之為 image.php。我們的想法是建立一個影像管理庫,我們可以將其用於其他專案,而無需進行太多重編碼。
現在讓我們先談談我們的目標。我們希望實現以下功能
- 修改從設定類別螢幕儲存的圖片最大數量(因此每個類別可以允許可變數量的圖片)
- 從類別螢幕修改最大圖片大小和縮圖大小
- 上傳系列中的第一張圖片將用作列出所有廣告時的顯示圖片
- 刪除廣告時,必須刪除圖片及其縮圖
- 每個不同的類別都必須能夠插入自定義 HTML 文字,這些文字將用作分隔符。
- 動態建立上傳欄位,以便提交不顯得雜亂
由於所有 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
更改函式 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));
}
}
替換裡面的所有內容
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() 提取影像副檔名。然後,根據這是列表檢視還是詳細檢視,我們將第一個或所有影像列印到緩衝區。
在 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
此函式驗證上傳的單個影像,然後再儲存影像。其餘的驗證由它繼承的類完成。只需刪除整個內容即可。
此函式幾乎完全修改了,只需複製新的函式即可。
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;
}
更改內部的所有內容
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);
}
}
/**********************************/
請注意,一半在類上面,另一半在類內部。