Skip to content
Permalink
Browse files

Merge pull request #2759 from Senjutsuu/max-assert-filesize-not-bigge…

…r-than-server-setting

Use and display a file or image maxSize constraint if the value is lower than the server value
  • Loading branch information...
carakas committed May 21, 2019
2 parents 8f3839d + 4e94a92 commit 0a99e89964bab910482f3842a973e36a2b760f1b
Showing with 181 additions and 14 deletions.
  1. +10 −0 app/config/form.yml
  2. +23 −0 src/Common/Core/Model.php
  3. +74 −7 src/Common/Form/FileType.php
  4. +74 −7 src/Common/Form/ImageType.php
@@ -23,3 +23,13 @@ services:
- "@translator"
tags:
- { name: form.type, alias: meta}
Common\Form\ImageType:
arguments:
- "@validator"
tags:
- { name: form.type, alias: image}
Common\Form\FileType:
arguments:
- "@validator"
tags:
- { name: form.type, alias: file}
@@ -323,4 +323,27 @@ private static function getMockSession(): Session
return self::get('fork.mock.session');
}
/**
* This method returns the filesize in a human readable format according to the value
*
* @param int $fileSize
* @return string
*/
public static function prettyPrintFileSize(int $fileSize): string
{
if ($fileSize > 999999999) {
return number_format($fileSize / 1000000000, 2, ',', ' ') . ' GB';
}
if ($fileSize > 999999) {
return number_format($fileSize / 1000000, 2, ',', ' ') . ' MB';
}
if ($fileSize > 999) {
return number_format($fileSize / 1000, 2, ',', ' ') . ' KB';
}
return $fileSize . ' bytes';
}
}
@@ -2,6 +2,7 @@
namespace Common\Form;
use Common\Core\Model;
use Common\Doctrine\ValueObject\AbstractFile;
use stdClass;
use Symfony\Component\Form\AbstractType;
@@ -15,12 +16,26 @@
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\File;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class FileType extends AbstractType
{
/**
* @var ValidatorInterface
*/
private $validator;
public function __construct(ValidatorInterface $validator)
{
$this->validator = $validator;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
if ($options['show_remove_file']) {
@@ -133,7 +148,9 @@ public function setPendingDeletion(bool $pendingDeletion)
'constraints' => array(new Valid()),
'error_bubbling' => false,
'help_text_message' => 'msg.HelpMaxFileSize',
'help_text_argument' => $this->getUploadMaxFileSize(),
'help_text_argument' => function (Options $options) {
return $this->getUploadMaxFileSize($options['file_class']);
},
]
);
}
@@ -173,33 +190,83 @@ function ($optionName) use ($options, &$view) {
);
}
private function getUploadMaxFileSize(): ?string
private function getMaxFileSizeServerValue(): ?int
{
$uploadMaxFileSize = ini_get('upload_max_filesize');
if ($uploadMaxFileSize === false) {
return null;
}
// reformat if defined as an integer
if (is_numeric($uploadMaxFileSize)) {
return $uploadMaxFileSize / 1024 . 'MB';
return $uploadMaxFileSize;
}
// reformat if specified in kB
if (mb_strtoupper(mb_substr($uploadMaxFileSize, -1)) === 'K') {
return mb_substr($uploadMaxFileSize, 0, -1) . 'kB';
return mb_substr($uploadMaxFileSize, 0, -1) * 1000;
}
// reformat if specified in MB
if (mb_strtoupper(mb_substr($uploadMaxFileSize, -1)) === 'M') {
return $uploadMaxFileSize . 'B';
return mb_substr($uploadMaxFileSize, 0, -1) * 1000 * 1000;
}
// reformat if specified in GB
if (mb_strtoupper(mb_substr($uploadMaxFileSize, -1)) === 'G') {
return $uploadMaxFileSize . 'B';
return mb_substr($uploadMaxFileSize, 0, -1) * 1000 * 1000 * 1000;
}
return null;
}
private function getMaxFileSizeConstraintValue(string $fileClass): ?int
{
// use the metaData to find the file data
/** @var ClassMetadata $metaData */
$metaData = $this->validator->getMetadataFor($fileClass);
$members = $metaData->getPropertyMetadata('file');
// the constraints can be found in the property meta data members
foreach ($members as $member) {
$constraints = $member->getConstraints();
if (count($constraints) === 1) {
/** @var File $fileConstraint */
$fileConstraint = $constraints[0];
if ($fileConstraint instanceof File) {
return $fileConstraint->maxSize;
}
}
}
return null;
}
private function getUploadMaxFileSize(string $fileClass): ?string
{
$constraintValue = $this->getMaxFileSizeConstraintValue($fileClass);
$serverValue = $this->getMaxFileSizeServerValue();
if (!is_numeric($constraintValue) && !is_numeric($serverValue)) {
return null;
}
// return the server value if the constraint value is to high
if (is_numeric($constraintValue) && is_numeric($serverValue)) {
if ($constraintValue < $serverValue) {
return Model::prettyPrintFileSize($constraintValue);
}
return Model::prettyPrintFileSize($serverValue);
}
if (is_numeric($constraintValue)) {
return Model::prettyPrintFileSize($constraintValue);
}
return $uploadMaxFileSize;
return Model::prettyPrintFileSize($serverValue);
}
}
@@ -2,6 +2,7 @@
namespace Common\Form;
use Common\Core\Model;
use Common\Doctrine\ValueObject\AbstractImage;
use stdClass;
use Symfony\Component\Form\AbstractType;
@@ -15,12 +16,26 @@
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\File;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class ImageType extends AbstractType
{
/**
* @var ValidatorInterface
*/
private $validator;
public function __construct(ValidatorInterface $validator)
{
$this->validator = $validator;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
if ($options['show_remove_image']) {
@@ -138,7 +153,9 @@ public function setPendingDeletion(bool $pendingDeletion)
'constraints' => [new Valid()],
'error_bubbling' => false,
'help_text_message' => 'msg.HelpImageFieldWithMaxFileSize',
'help_text_argument' => $this->getUploadMaxFileSize(),
'help_text_argument' => function (Options $options) {
return $this->getUploadMaxFileSize($options['image_class']);
},
]
);
}
@@ -179,33 +196,83 @@ function ($optionName) use ($options, &$view) {
);
}
private function getUploadMaxFileSize(): ?string
private function getMaxFileSizeServerValue(): ?int
{
$uploadMaxFileSize = ini_get('upload_max_filesize');
if ($uploadMaxFileSize === false) {
return null;
}
// reformat if defined as an integer
if (is_numeric($uploadMaxFileSize)) {
return $uploadMaxFileSize / 1024 . 'MB';
return $uploadMaxFileSize;
}
// reformat if specified in kB
if (mb_strtoupper(mb_substr($uploadMaxFileSize, -1)) === 'K') {
return mb_substr($uploadMaxFileSize, 0, -1) . 'kB';
return mb_substr($uploadMaxFileSize, 0, -1) * 1000;
}
// reformat if specified in MB
if (mb_strtoupper(mb_substr($uploadMaxFileSize, -1)) === 'M') {
return $uploadMaxFileSize . 'B';
return mb_substr($uploadMaxFileSize, 0, -1) * 1000 * 1000;
}
// reformat if specified in GB
if (mb_strtoupper(mb_substr($uploadMaxFileSize, -1)) === 'G') {
return $uploadMaxFileSize . 'B';
return mb_substr($uploadMaxFileSize, 0, -1) * 1000 * 1000 * 1000;
}
return null;
}
private function getMaxFileSizeConstraintValue(string $imageClass): ?int
{
// use the metaData to find the file data
/** @var ClassMetadata $metaData */
$metaData = $this->validator->getMetadataFor($imageClass);
$members = $metaData->getPropertyMetadata('file');
// the constraints can be found in the property meta data members
foreach ($members as $member) {
$constraints = $member->getConstraints();
if (count($constraints) === 1) {
/** @var File $fileConstraint */
$fileConstraint = $constraints[0];
if ($fileConstraint instanceof File) {
return $fileConstraint->maxSize;
}
}
}
return null;
}
private function getUploadMaxFileSize(string $imageClass): ?string
{
$constraintValue = $this->getMaxFileSizeConstraintValue($imageClass);
$serverValue = $this->getMaxFileSizeServerValue();
if (!is_numeric($constraintValue) && !is_numeric($serverValue)) {
return null;
}
// return the server value if the constraint value is to high
if (is_numeric($constraintValue) && is_numeric($serverValue)) {
if ($constraintValue < $serverValue) {
return Model::prettyPrintFileSize($constraintValue);
}
return Model::prettyPrintFileSize($serverValue);
}
if (is_numeric($constraintValue)) {
return Model::prettyPrintFileSize($constraintValue);
}
return $uploadMaxFileSize;
return Model::prettyPrintFileSize($serverValue);
}
}

0 comments on commit 0a99e89

Please sign in to comment.
You can’t perform that action at this time.