上载字段上的Silverstripe自定义验证程序

上载字段上的Silverstripe自定义验证程序,silverstripe,Silverstripe,我正在使用foresight.js加载视网膜设备的高分辨率图像。Foresight尝试将低分辨率图像替换为2倍像素密度的图像。由于foresight试图在页面呈现之前替换低分辨率图像,因此我不可能在模板中使用GD图像大小调整方法来调整大小的图像。因此,我允许SS 3.1 cms用户上传一个大图像,并在上传后让系统重新调整其大小-在assets文件夹中保留一个1x和2x图像 我的问题是,如果cms用户没有上传足够大的图像,如何设置自定义验证错误消息 下面是在上传时调整图像大小的代码 class R

我正在使用foresight.js加载视网膜设备的高分辨率图像。Foresight尝试将低分辨率图像替换为2倍像素密度的图像。由于foresight试图在页面呈现之前替换低分辨率图像,因此我不可能在模板中使用GD图像大小调整方法来调整大小的图像。因此,我允许SS 3.1 cms用户上传一个大图像,并在上传后让系统重新调整其大小-在assets文件夹中保留一个1x和2x图像

我的问题是,如果cms用户没有上传足够大的图像,如何设置自定义验证错误消息

下面是在上传时调整图像大小的代码

class ResampledImage extends Image {
    static $default_lores_x = 250;
    static $default_lores_y = 250;
    static $default_hires_x = 500;
    static $default_hires_y = 500;
    static $default_assets_dir = 'Uploads';
    static $hires_flag = '2x';

    function getLoResX() {
        return ( static::$lores_x ) ? static::$lores_x : self::$default_lores_x;    
    }

    function getLoResY() {
        return ( static::$lores_y ) ? static::$lores_y : self::$default_lores_y;
    }

    function getHiResX() {
        return ( static::$hires_x ) ? static::$hires_x : self::$default_hires_x;
    }

    function getHiResY() {
        return ( static::$hires_y ) ? static::$hires_y : self::$default_hires_y;
    }

    function getAssetsDir() {
        return ( static::$assets_dir ) ? static::$assets_dir : self::$default_assets_dir;
    }

    function onAfterUpload() {
        $this->createResampledImages();
    }

    function onAfterWrite() {
        $this->createResampledImages();
    }

    function createResampledImages() {
        $extension = strtolower($this->getExtension());
        if( $this->getHeight() >= $this->getHiResX() || $this->getWidth() >= $this->getHiResY() ) {
        $original = $this->getFullPath();
        $resampled = $original. '.tmp.'. $extension;    

        $orig_title = $this->getTitle();
        $path_to_hires = Director::baseFolder() . '/' . ASSETS_DIR . '/' . $this->getAssetsDir();
        $hires =  $path_to_hires . '/' . $orig_title . self::$hires_flag . '.' . $extension;

        $gd_lg = new GD($original);
        $gd_sm = new GD($original);

        if ( $gd_lg->hasImageResource() ) {
            $gd_lg = $gd_lg->resizeRatio($this->getHiResX(), $this->getHiResY());

            if ( $gd_lg ) 
                $gd_lg->writeTo($hires);
        }

        if($gd_sm->hasImageResource()) {
            $gd_sm = $gd_sm->resizeRatio($this->getLoResX(), $this->getLoResY());

            if($gd_sm) {
                $gd_sm->writeTo($resampled);
                unlink($original);
                rename($resampled, $original);
            }
        }
    }
}  
查看UploadField::setFileEditValidator(),我似乎可以在扩展映像类上指定一个方法用作验证器,以便检查$this->getWidth()和$this->getHeight(),如果它们不够大,则返回一个错误

这可能吗

我尝试将以下方法添加到重采样图像中,但未成功:

function MyValidator() {
    $valid = true;

    if ( $this->getHeight() < $this->getHiResX() || $this->getWidth() < $this->getHiResY() ) {
        $this->validationError("Thumbnail",'Please upload a larger image');
        $valid = false;
    }

    return $valid;
}
函数MyValidator(){
$valid=true;
如果($this->getHeight()<$this->getHiResX()| |$this->getWidth()<$this->getHiResY()){
$this->validationError(“缩略图”,“请上传更大的图像”);
$valid=false;
}
返回$valid;
}

我认为
fileEditValidator
在上传图像后被实际使用,并且在显示/编辑时用于
EditForm

似乎您正在寻找的是验证
上传
。您可以使用
setValidator($Validator)
UploadField
上设置自定义
Upload\u验证程序

因此,我将尝试创建一个自定义验证器类(可能命名为CustomUploadValidator),该类扩展
Upload\u validator
(可以在框架中的Upload.php文件中找到源代码)。因此,沿着这些思路:

$myValidator = new CustomUploadValidator();
$uploadField->setValidator($myValidator);
在自定义验证器类中,可以创建一个方法
isimageragenough()
,您可以在
validate()
方法中调用该方法:

public function validate() {

    if(!$this->isImageLargeEnough()) {
        $this->errors[] = 'Image size is not large enough';
        return false;
    }

    return parent::validate();
}
在您的
isimagerageenough()
中,您可以通过
$this->tmpFile
访问上传的图像。因此,或许可以做一些类似的事情:

public function isImageLargeEnough()
{
    $imageSize = getimagesize( $this->tmpFile["tmp_name"] );
    if ($imageSize !== false)
    {
        if ( $imageSize[0] < 500 || $imageSize[1] < 500 )
        {
            return false;
        }
    }       
    return true;
}
公共函数为magerageenough()
{
$imageSize=getimagesize($this->tmpFile[“tmp_name”]);
如果($imageSize!==false)
{
如果($imageSize[0]<500 | |$imageSize[1]<500)
{
返回false;
}
}       
返回true;
}
这里的最小宽度/高度硬编码为500,但是您可能可以实现一个
setMinImageSizes
方法,将这些值存储在自定义验证器类中的变量上。可以像
$uploadField->getValidator()->setMinImageSize(543876)那样调用它


所有这些都没有经过实际测试,但希望它能为您提供一些关于查找内容的指导。

我认为
fileEditValidator
在图像上传后被正确使用,并且在显示/编辑时用于
EditForm

似乎您正在寻找的是验证
上传
。您可以使用
setValidator($Validator)
UploadField
上设置自定义
Upload\u验证程序

因此,我将尝试创建一个自定义验证器类(可能命名为CustomUploadValidator),该类扩展
Upload\u validator
(可以在框架中的Upload.php文件中找到源代码)。因此,沿着这些思路:

$myValidator = new CustomUploadValidator();
$uploadField->setValidator($myValidator);
在自定义验证器类中,可以创建一个方法
isimageragenough()
,您可以在
validate()
方法中调用该方法:

public function validate() {

    if(!$this->isImageLargeEnough()) {
        $this->errors[] = 'Image size is not large enough';
        return false;
    }

    return parent::validate();
}
在您的
isimagerageenough()
中,您可以通过
$this->tmpFile
访问上传的图像。因此,或许可以做一些类似的事情:

public function isImageLargeEnough()
{
    $imageSize = getimagesize( $this->tmpFile["tmp_name"] );
    if ($imageSize !== false)
    {
        if ( $imageSize[0] < 500 || $imageSize[1] < 500 )
        {
            return false;
        }
    }       
    return true;
}
公共函数为magerageenough()
{
$imageSize=getimagesize($this->tmpFile[“tmp_name”]);
如果($imageSize!==false)
{
如果($imageSize[0]<500 | |$imageSize[1]<500)
{
返回false;
}
}       
返回true;
}
这里的最小宽度/高度硬编码为500,但是您可能可以实现一个
setMinImageSizes
方法,将这些值存储在自定义验证器类中的变量上。可以像
$uploadField->getValidator()->setMinImageSize(543876)那样调用它


所有这些都没有经过实际测试,但希望它能为您提供一些关于查找内容的指导。

谢谢您的详细解释。我确实需要将parent::validate()分配给一个变量,并从我的validate方法返回该变量,以使它为我工作,但答案很好!很酷,很高兴它成功了。更新了答案修正
validate()
,也返回了其父项,感谢您指出。Colymba,请注意,在检查图像大小之前,我还需要在isImageLargeEnough方法中检查getimagesize是否返回false。SS似乎通过上载和写入时的验证方法运行图像,并且getimagesize在写入验证期间返回false。Colymba,你知道我如何将自定义错误消息返回到模板吗?验证失败时,EditForm仅显示一个通用的“禁止”错误。当我检查网络选项卡时,服务器正在返回正确的消息
[{“error”:“Please upload a large image”}]
-它只是没有传递到Uploadfield模板。此解决方案对v有效。4.x也是。只需将
tmpFile[“tmp_name”]
更改为
tmpFile[“name”]
,感谢您的详细解释。我确实需要将parent::validate()分配给一个变量,并从我的validate方法返回该变量,以使它为我工作,但答案很好!很酷,很高兴它成功了。更新了答案修正
validate()
,也返回了它的父项,感谢您指出。Colymba,请注意,我还需要检查getimagesize在isImag中是否返回false