理解诺亚的分类信息/多图上传
在诺亚的分类信息中,广告只能提交一张图片,我们希望提交 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);
}
}
/**********************************/
请注意,一半在类上面,另一半在类内部。