2013-08-14 3 views
2

Я использую foresight.js для загрузки изображений hi-res для устройств сетчатки. Foresight пытается заменить lo-res изображения изображениями с плотностью двух пикселей. Поскольку предварительная попытка попытаться заменить lo-res-изображения до отображения страницы, мне не удастся использовать методы изменения размера изображения GD в шаблоне для моих измененных изображений. Таким образом, я разрешаю пользователю SS 3.1 cms загружать одно крупное изображение и изменять его размер после загрузки - оставляя 1x и 2x изображение в папке с ресурсами.Silverstripe Custom Validator on Uploadfield

Мой вопрос в том, как установить пользовательское сообщение об ошибке проверки, если пользователь 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() и вернуть ошибку, если они недостаточно велики.

Возможно ли это?

Я попытался добавить следующий метод ResampledImage, но это было неудачным:

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; 
} 
+0

/threadnecro - некоторые из ваших static :: declarations выглядят пропавшими без вести? – nbsp

+0

Я отказался от использования Foresight и должен изменить размер при загрузке. Форсайт, похоже, не играет хорошо, захватывая изображения, измененные с использованием методов изображения SS - отсюда и беспорядочность. Вместо этого я использую расширенное расширение отклика silverstripe, используя пользовательский метод Validator Validator, описанный ниже. –

ответ

3

Я думаю, что fileEditValidator является acutally используется после того, как изображение было загружено и для EditForm при отображении/под ред.

Кажется, что то, что вы ищете, является подтверждением Upload. Вы можете установить таможню Upload_Validator с setValidator($validator) на UploadField.

Так что я бы попытался создать собственный класс валидатора (возможно, названный CustomUploadValidator), который расширяет Upload_Validator (исходный файл можно найти в файле Upload.php в рамках). Так, что-то вдоль этих линий:

$myValidator = new CustomUploadValidator(); 
$uploadField->setValidator($myValidator); 

В пользовательском классе валидатора возможно создать метод isImageLargeEnough() который вы назвали бы в validate() методе:

public function validate() { 

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

    return parent::validate(); 
} 

в вашем isImageLargeEnough() вы можете получить доступ к загруженному изображению через $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; 
} 

Здесь мин ширина/высота упорно кодированной до 500, но вы, вероятно, можно реализовать setMinImageSizes метод, который хранит тех, кто на переменной в классе валидатора. который можно назвать так: $uploadField->getValidator()->setMinImageSize(543, 876);

Ничего из этого на самом деле не проверено, но, надеюсь, оно может дать вам несколько указаний на то, что нужно искать.

+0

Спасибо за очень подробное объяснение.Мне нужно было назначить parent :: validate() переменной и вернуть переменную из моего метода проверки, чтобы заставить ее работать для меня, но отличный ответ! –

+0

круто, рад, что сработал. обновил ответ, исправляющий 'validate()', чтобы также вернуть родительский элемент, спасибо, указав его. – colymba

+1

Colymba, обратите внимание, что мне также необходимо проверить, возвратил ли getimagesize false в методе isImageLargeEnough, прежде чем проверять размер изображения. Кажется, что SS запускает изображение через метод проверки при загрузке и записи, а getimagesize возвращает false во время проверки записи. –