Skip to content

Commit

Permalink
Add FileField for Files.
Browse files Browse the repository at this point in the history
  • Loading branch information
bytes-commerce committed Nov 27, 2024
1 parent abe5cac commit a273e98
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 79 deletions.
93 changes: 93 additions & 0 deletions src/Field/FileField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace EasyCorp\Bundle\EasyAdminBundle\Field;

use EasyCorp\Bundle\EasyAdminBundle\Config\Asset;
use EasyCorp\Bundle\EasyAdminBundle\Config\Option\TextAlign;
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface;
use EasyCorp\Bundle\EasyAdminBundle\Form\Type\FileUploadType;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\File;
use Symfony\Contracts\Translation\TranslatableInterface;

class FileField implements FieldInterface
{
use FieldTrait;

public const OPTION_BASE_PATH = 'basePath';
public const OPTION_UPLOAD_DIR = 'uploadDir';
public const OPTION_UPLOADED_FILE_NAME_PATTERN = 'uploadedFileNamePattern';
public const OPTION_FILE_CONSTRAINTS = 'fileConstraints';

/**
* @param TranslatableInterface|string|false|null $label
*/
public static function new(string $propertyName, $label = null): FieldInterface
{
return (new self())
->setProperty($propertyName)
->setLabel($label)
->setTemplateName('crud/field/image')
->setFormType(FileUploadType::class)
->addCssClass('field-image')
->addJsFiles(Asset::fromEasyAdminAssetPackage('field-image.js'), Asset::fromEasyAdminAssetPackage('field-file-upload.js'))
->setDefaultColumns('col-md-7 col-xxl-5')
->setTextAlign(TextAlign::CENTER)
->setCustomOption(self::OPTION_BASE_PATH, null)
->setCustomOption(self::OPTION_UPLOAD_DIR, null)
->setCustomOption(self::OPTION_UPLOADED_FILE_NAME_PATTERN, '[name].[extension]')
->setCustomOption(self::OPTION_FILE_CONSTRAINTS, [new File()]);
}

public function setBasePath(string $path): self
{
$this->setCustomOption(self::OPTION_BASE_PATH, $path);

return $this;
}

/**
* Relative to project's root directory (e.g. use 'public/uploads/' for `<your-project-dir>/public/uploads/`)
* Default upload dir: `<your-project-dir>/public/uploads/images/`.
*/
public function setUploadDir(string $uploadDirPath): self
{
$this->setCustomOption(self::OPTION_UPLOAD_DIR, $uploadDirPath);

return $this;
}

/**
* @param string|\Closure $patternOrCallable
*
* If it's a string, uploaded files will be renamed according to the given pattern.
* The pattern can include the following special values:
* [day] [month] [year] [timestamp]
* [name] [slug] [extension] [contenthash]
* [randomhash] [uuid] [ulid]
* (e.g. [year]/[month]/[day]/[slug]-[contenthash].[extension])
*
* If it's a callable, you will be passed the Symfony's UploadedFile instance and you must
* return a string with the new filename.
* (e.g. fn(UploadedFile $file) => sprintf('upload_%d_%s.%s', random_int(1, 999), $file->getFilename(), $file->guessExtension()))
*/
public function setUploadedFileNamePattern($patternOrCallable): self
{
$this->setCustomOption(self::OPTION_UPLOADED_FILE_NAME_PATTERN, $patternOrCallable);

return $this;
}

/**
* @param Constraint|array<Constraint> $constraints
*
* Define constraints to be validated on the FileType.
* Image constraint is set by default.
*/
public function setFileConstraints($constraints): self
{
$this->setCustomOption(self::OPTION_FILE_CONSTRAINTS, $constraints);

return $this;
}
}
80 changes: 3 additions & 77 deletions src/Field/ImageField.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,95 +2,21 @@

namespace EasyCorp\Bundle\EasyAdminBundle\Field;

use EasyCorp\Bundle\EasyAdminBundle\Config\Asset;
use EasyCorp\Bundle\EasyAdminBundle\Config\Option\TextAlign;
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface;
use EasyCorp\Bundle\EasyAdminBundle\Form\Type\FileUploadType;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Image;
use Symfony\Contracts\Translation\TranslatableInterface;

/**
* @author Javier Eguiluz <[email protected]>
*/
final class ImageField implements FieldInterface
final class ImageField extends FileField implements FieldInterface
{
use FieldTrait;

public const OPTION_BASE_PATH = 'basePath';
public const OPTION_UPLOAD_DIR = 'uploadDir';
public const OPTION_UPLOADED_FILE_NAME_PATTERN = 'uploadedFileNamePattern';
public const OPTION_FILE_CONSTRAINTS = 'fileConstraints';

/**
* @param TranslatableInterface|string|false|null $label
*/
public static function new(string $propertyName, $label = null): self
public static function new(string $propertyName, $label = null): FieldInterface
{
return (new self())
->setProperty($propertyName)
->setLabel($label)
return parent::new($propertyName, $label)

Check failure on line 18 in src/Field/ImageField.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface::setTemplateName().
->setTemplateName('crud/field/image')
->setFormType(FileUploadType::class)
->addCssClass('field-image')
->addJsFiles(Asset::fromEasyAdminAssetPackage('field-image.js'), Asset::fromEasyAdminAssetPackage('field-file-upload.js'))
->setDefaultColumns('col-md-7 col-xxl-5')
->setTextAlign(TextAlign::CENTER)
->setCustomOption(self::OPTION_BASE_PATH, null)
->setCustomOption(self::OPTION_UPLOAD_DIR, null)
->setCustomOption(self::OPTION_UPLOADED_FILE_NAME_PATTERN, '[name].[extension]')
->setCustomOption(self::OPTION_FILE_CONSTRAINTS, [new Image()]);
}

public function setBasePath(string $path): self
{
$this->setCustomOption(self::OPTION_BASE_PATH, $path);

return $this;
}

/**
* Relative to project's root directory (e.g. use 'public/uploads/' for `<your-project-dir>/public/uploads/`)
* Default upload dir: `<your-project-dir>/public/uploads/images/`.
*/
public function setUploadDir(string $uploadDirPath): self
{
$this->setCustomOption(self::OPTION_UPLOAD_DIR, $uploadDirPath);

return $this;
}

/**
* @param string|\Closure $patternOrCallable
*
* If it's a string, uploaded files will be renamed according to the given pattern.
* The pattern can include the following special values:
* [day] [month] [year] [timestamp]
* [name] [slug] [extension] [contenthash]
* [randomhash] [uuid] [ulid]
* (e.g. [year]/[month]/[day]/[slug]-[contenthash].[extension])
*
* If it's a callable, you will be passed the Symfony's UploadedFile instance and you must
* return a string with the new filename.
* (e.g. fn(UploadedFile $file) => sprintf('upload_%d_%s.%s', random_int(1, 999), $file->getFilename(), $file->guessExtension()))
*/
public function setUploadedFileNamePattern($patternOrCallable): self
{
$this->setCustomOption(self::OPTION_UPLOADED_FILE_NAME_PATTERN, $patternOrCallable);

return $this;
}

/**
* @param Constraint|array<Constraint> $constraints
*
* Define constraints to be validated on the FileType.
* Image constraint is set by default.
*/
public function setFileConstraints($constraints): self
{
$this->setCustomOption(self::OPTION_FILE_CONSTRAINTS, $constraints);

return $this;
}
}
12 changes: 12 additions & 0 deletions templates/crud/field/file.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #}
{# @var field \EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto #}
{# @var entity \EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto #}
{% set images = field.formattedValue %}
{% if images is not iterable %}
{% set images = [images] %}
{% endif %}

{% for image in images %}
{% set html_id = 'ea-lightbox-' ~ field.uniqueId ~ '-' ~ loop.index %}
<a href="{{ asset(image) }}" title="{{ image }}" target="_blank">{{ image }}</a>
{% endfor %}
4 changes: 2 additions & 2 deletions templates/crud/field/image.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
{% for image in images %}
{% set html_id = 'ea-lightbox-' ~ field.uniqueId ~ '-' ~ loop.index %}
<a href="#" class="ea-lightbox-thumbnail" data-ea-lightbox-content-selector="#{{ html_id }}">
<img src="{{ asset(image) }}" class="img-fluid">
<img aria-label="{{ image }}" alt="{{ image }}" src="{{ asset(image) }}" class="img-fluid" />
</a>

<div id="{{ html_id }}" class="ea-lightbox">
<img src="{{ asset(image) }}">
<img aria-label="{{ image }}" alt="{{ image }}" src="{{ asset(image) }}" />
</div>
{% endfor %}

0 comments on commit a273e98

Please sign in to comment.