annotate vendor/symfony/validator/Constraints/ImageValidator.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\Validator\Constraints;
Chris@0 13
Chris@0 14 use Symfony\Component\Validator\Constraint;
Chris@0 15 use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
Chris@0 16 use Symfony\Component\Validator\Exception\RuntimeException;
Chris@0 17 use Symfony\Component\Validator\Exception\UnexpectedTypeException;
Chris@0 18
Chris@0 19 /**
Chris@0 20 * Validates whether a value is a valid image file and is valid
Chris@0 21 * against minWidth, maxWidth, minHeight and maxHeight constraints.
Chris@0 22 *
Chris@0 23 * @author Benjamin Dulau <benjamin.dulau@gmail.com>
Chris@0 24 * @author Bernhard Schussek <bschussek@gmail.com>
Chris@0 25 */
Chris@0 26 class ImageValidator extends FileValidator
Chris@0 27 {
Chris@0 28 /**
Chris@0 29 * {@inheritdoc}
Chris@0 30 */
Chris@0 31 public function validate($value, Constraint $constraint)
Chris@0 32 {
Chris@0 33 if (!$constraint instanceof Image) {
Chris@0 34 throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Image');
Chris@0 35 }
Chris@0 36
Chris@17 37 $violations = \count($this->context->getViolations());
Chris@0 38
Chris@0 39 parent::validate($value, $constraint);
Chris@0 40
Chris@17 41 $failed = \count($this->context->getViolations()) !== $violations;
Chris@0 42
Chris@0 43 if ($failed || null === $value || '' === $value) {
Chris@0 44 return;
Chris@0 45 }
Chris@0 46
Chris@0 47 if (null === $constraint->minWidth && null === $constraint->maxWidth
Chris@0 48 && null === $constraint->minHeight && null === $constraint->maxHeight
Chris@14 49 && null === $constraint->minPixels && null === $constraint->maxPixels
Chris@0 50 && null === $constraint->minRatio && null === $constraint->maxRatio
Chris@0 51 && $constraint->allowSquare && $constraint->allowLandscape && $constraint->allowPortrait
Chris@0 52 && !$constraint->detectCorrupted) {
Chris@0 53 return;
Chris@0 54 }
Chris@0 55
Chris@0 56 $size = @getimagesize($value);
Chris@0 57
Chris@14 58 if (empty($size) || (0 === $size[0]) || (0 === $size[1])) {
Chris@0 59 $this->context->buildViolation($constraint->sizeNotDetectedMessage)
Chris@0 60 ->setCode(Image::SIZE_NOT_DETECTED_ERROR)
Chris@0 61 ->addViolation();
Chris@0 62
Chris@0 63 return;
Chris@0 64 }
Chris@0 65
Chris@0 66 $width = $size[0];
Chris@0 67 $height = $size[1];
Chris@0 68
Chris@0 69 if ($constraint->minWidth) {
Chris@0 70 if (!ctype_digit((string) $constraint->minWidth)) {
Chris@14 71 throw new ConstraintDefinitionException(sprintf('"%s" is not a valid minimum width.', $constraint->minWidth));
Chris@0 72 }
Chris@0 73
Chris@0 74 if ($width < $constraint->minWidth) {
Chris@0 75 $this->context->buildViolation($constraint->minWidthMessage)
Chris@0 76 ->setParameter('{{ width }}', $width)
Chris@0 77 ->setParameter('{{ min_width }}', $constraint->minWidth)
Chris@0 78 ->setCode(Image::TOO_NARROW_ERROR)
Chris@0 79 ->addViolation();
Chris@0 80
Chris@0 81 return;
Chris@0 82 }
Chris@0 83 }
Chris@0 84
Chris@0 85 if ($constraint->maxWidth) {
Chris@0 86 if (!ctype_digit((string) $constraint->maxWidth)) {
Chris@14 87 throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum width.', $constraint->maxWidth));
Chris@0 88 }
Chris@0 89
Chris@0 90 if ($width > $constraint->maxWidth) {
Chris@0 91 $this->context->buildViolation($constraint->maxWidthMessage)
Chris@0 92 ->setParameter('{{ width }}', $width)
Chris@0 93 ->setParameter('{{ max_width }}', $constraint->maxWidth)
Chris@0 94 ->setCode(Image::TOO_WIDE_ERROR)
Chris@0 95 ->addViolation();
Chris@0 96
Chris@0 97 return;
Chris@0 98 }
Chris@0 99 }
Chris@0 100
Chris@0 101 if ($constraint->minHeight) {
Chris@0 102 if (!ctype_digit((string) $constraint->minHeight)) {
Chris@0 103 throw new ConstraintDefinitionException(sprintf('"%s" is not a valid minimum height', $constraint->minHeight));
Chris@0 104 }
Chris@0 105
Chris@0 106 if ($height < $constraint->minHeight) {
Chris@0 107 $this->context->buildViolation($constraint->minHeightMessage)
Chris@0 108 ->setParameter('{{ height }}', $height)
Chris@0 109 ->setParameter('{{ min_height }}', $constraint->minHeight)
Chris@0 110 ->setCode(Image::TOO_LOW_ERROR)
Chris@0 111 ->addViolation();
Chris@0 112
Chris@0 113 return;
Chris@0 114 }
Chris@0 115 }
Chris@0 116
Chris@0 117 if ($constraint->maxHeight) {
Chris@0 118 if (!ctype_digit((string) $constraint->maxHeight)) {
Chris@0 119 throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum height', $constraint->maxHeight));
Chris@0 120 }
Chris@0 121
Chris@0 122 if ($height > $constraint->maxHeight) {
Chris@0 123 $this->context->buildViolation($constraint->maxHeightMessage)
Chris@0 124 ->setParameter('{{ height }}', $height)
Chris@0 125 ->setParameter('{{ max_height }}', $constraint->maxHeight)
Chris@0 126 ->setCode(Image::TOO_HIGH_ERROR)
Chris@0 127 ->addViolation();
Chris@0 128 }
Chris@0 129 }
Chris@0 130
Chris@14 131 $pixels = $width * $height;
Chris@14 132
Chris@14 133 if (null !== $constraint->minPixels) {
Chris@14 134 if (!ctype_digit((string) $constraint->minPixels)) {
Chris@14 135 throw new ConstraintDefinitionException(sprintf('"%s" is not a valid minimum amount of pixels', $constraint->minPixels));
Chris@14 136 }
Chris@14 137
Chris@14 138 if ($pixels < $constraint->minPixels) {
Chris@14 139 $this->context->buildViolation($constraint->minPixelsMessage)
Chris@14 140 ->setParameter('{{ pixels }}', $pixels)
Chris@14 141 ->setParameter('{{ min_pixels }}', $constraint->minPixels)
Chris@14 142 ->setParameter('{{ height }}', $height)
Chris@14 143 ->setParameter('{{ width }}', $width)
Chris@14 144 ->setCode(Image::TOO_FEW_PIXEL_ERROR)
Chris@14 145 ->addViolation();
Chris@14 146 }
Chris@14 147 }
Chris@14 148
Chris@14 149 if (null !== $constraint->maxPixels) {
Chris@14 150 if (!ctype_digit((string) $constraint->maxPixels)) {
Chris@14 151 throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum amount of pixels', $constraint->maxPixels));
Chris@14 152 }
Chris@14 153
Chris@14 154 if ($pixels > $constraint->maxPixels) {
Chris@14 155 $this->context->buildViolation($constraint->maxPixelsMessage)
Chris@14 156 ->setParameter('{{ pixels }}', $pixels)
Chris@14 157 ->setParameter('{{ max_pixels }}', $constraint->maxPixels)
Chris@14 158 ->setParameter('{{ height }}', $height)
Chris@14 159 ->setParameter('{{ width }}', $width)
Chris@14 160 ->setCode(Image::TOO_MANY_PIXEL_ERROR)
Chris@14 161 ->addViolation();
Chris@14 162 }
Chris@14 163 }
Chris@14 164
Chris@0 165 $ratio = round($width / $height, 2);
Chris@0 166
Chris@0 167 if (null !== $constraint->minRatio) {
Chris@0 168 if (!is_numeric((string) $constraint->minRatio)) {
Chris@0 169 throw new ConstraintDefinitionException(sprintf('"%s" is not a valid minimum ratio', $constraint->minRatio));
Chris@0 170 }
Chris@0 171
Chris@0 172 if ($ratio < $constraint->minRatio) {
Chris@0 173 $this->context->buildViolation($constraint->minRatioMessage)
Chris@0 174 ->setParameter('{{ ratio }}', $ratio)
Chris@0 175 ->setParameter('{{ min_ratio }}', $constraint->minRatio)
Chris@0 176 ->setCode(Image::RATIO_TOO_SMALL_ERROR)
Chris@0 177 ->addViolation();
Chris@0 178 }
Chris@0 179 }
Chris@0 180
Chris@0 181 if (null !== $constraint->maxRatio) {
Chris@0 182 if (!is_numeric((string) $constraint->maxRatio)) {
Chris@0 183 throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum ratio', $constraint->maxRatio));
Chris@0 184 }
Chris@0 185
Chris@0 186 if ($ratio > $constraint->maxRatio) {
Chris@0 187 $this->context->buildViolation($constraint->maxRatioMessage)
Chris@0 188 ->setParameter('{{ ratio }}', $ratio)
Chris@0 189 ->setParameter('{{ max_ratio }}', $constraint->maxRatio)
Chris@0 190 ->setCode(Image::RATIO_TOO_BIG_ERROR)
Chris@0 191 ->addViolation();
Chris@0 192 }
Chris@0 193 }
Chris@0 194
Chris@0 195 if (!$constraint->allowSquare && $width == $height) {
Chris@0 196 $this->context->buildViolation($constraint->allowSquareMessage)
Chris@0 197 ->setParameter('{{ width }}', $width)
Chris@0 198 ->setParameter('{{ height }}', $height)
Chris@0 199 ->setCode(Image::SQUARE_NOT_ALLOWED_ERROR)
Chris@0 200 ->addViolation();
Chris@0 201 }
Chris@0 202
Chris@0 203 if (!$constraint->allowLandscape && $width > $height) {
Chris@0 204 $this->context->buildViolation($constraint->allowLandscapeMessage)
Chris@0 205 ->setParameter('{{ width }}', $width)
Chris@0 206 ->setParameter('{{ height }}', $height)
Chris@0 207 ->setCode(Image::LANDSCAPE_NOT_ALLOWED_ERROR)
Chris@0 208 ->addViolation();
Chris@0 209 }
Chris@0 210
Chris@0 211 if (!$constraint->allowPortrait && $width < $height) {
Chris@0 212 $this->context->buildViolation($constraint->allowPortraitMessage)
Chris@0 213 ->setParameter('{{ width }}', $width)
Chris@0 214 ->setParameter('{{ height }}', $height)
Chris@0 215 ->setCode(Image::PORTRAIT_NOT_ALLOWED_ERROR)
Chris@0 216 ->addViolation();
Chris@0 217 }
Chris@0 218
Chris@0 219 if ($constraint->detectCorrupted) {
Chris@17 220 if (!\function_exists('imagecreatefromstring')) {
Chris@0 221 throw new RuntimeException('Corrupted images detection requires installed and enabled GD extension');
Chris@0 222 }
Chris@0 223
Chris@0 224 $resource = @imagecreatefromstring(file_get_contents($value));
Chris@0 225
Chris@0 226 if (false === $resource) {
Chris@0 227 $this->context->buildViolation($constraint->corruptedMessage)
Chris@0 228 ->setCode(Image::CORRUPTED_IMAGE_ERROR)
Chris@0 229 ->addViolation();
Chris@0 230
Chris@0 231 return;
Chris@0 232 }
Chris@0 233
Chris@0 234 imagedestroy($resource);
Chris@0 235 }
Chris@0 236 }
Chris@0 237 }