EasyAdminBundle icon indicating copy to clipboard operation
EasyAdminBundle copied to clipboard

ImageField doesn't create folder automatically

Open noorwachid opened this issue 3 years ago • 5 comments

In the documentation it said I can set setUploadedFileNamePattern with [year]/[month]/[day]/[slug]-[contenthash].[extension] the file name is saved to the database but the actual file not uploaded and there's no folder with that specifed pattern.

noorwachid avatar Nov 21 '21 11:11 noorwachid

The file is uploaded, but to the folder specified in setUploadDir. To fix it you need to modity one file:

In Controller/AbstractCrudController.php in processUploadedFiles(FormInterface $form): void you need to modify it slightly,

foreach ($state->getUploadedFiles() as $index => $file) {
    $fileName = u($filePaths[$index])->replace($uploadDir, '')->toString();

    // if after token evaluation, filename contains dirs, we need to append it to $uploadDir
    if (($extraDirs = dirname($fileName)) !== '.')
    {
        $uploadDir .= $extraDirs;
        if (!file_exists($uploadDir))
        {
            mkdir($uploadDir, 0755, true);
        }
    }
    $uploadNew($file, $uploadDir, $fileName);
}

I'm sure there's a more 'symfony' way of doing it though

sxsws avatar Nov 29 '21 22:11 sxsws

@sxsws The better workaround would be probably

ImageField::new('filePath')
     ...
    ->setFormTypeOption('upload_new', function (UploadedFile $file, string $uploadDir, string $fileName) {
        if (($extraDirs = dirname($fileName)) !== '.') {
            $uploadDir .= $extraDirs;
            if (!file_exists($uploadDir)) {
                mkdir($uploadDir, 0750, true);
            }
        }
        $file->move($uploadDir, $fileName);
    }),

scasei avatar Sep 14 '22 19:09 scasei

same problem

tourze avatar Dec 02 '22 04:12 tourze

I tried this :

class ProductCrudController extends AbstractCrudController
{
    private $currentDate;

    public function __construct()
    {
        $this->currentDate = (new DateTime())->format('Ym');
        $dirName = "uploads/" . $this->currentDate;

        if (!is_dir($dirName)) {
            mkdir($dirName);
        }
    }

    public static function getEntityFqcn(): string
    {
        return Product::class;
    }

    public function configureFields(string $pageName): iterable
    {
        return [
            TextField::new('name')
                ->setRequired(true),
            SlugField::new('slug')->setTargetFieldName('name')
                ->setRequired(true),
            AssociationField::new('category', "Catégorie"),
            ImageField::new('illustration')
                ->setBasePath('uploads')
                ->setUploadDir('public/uploads/' . $this->currentDate . '/')
                ->setFormType(FileUploadType::class)
                ->setUploadedFileNamePattern('[year][month]/[slug]-[randomhash].[extension]')
                ->setRequired($pageName !== Crud::PAGE_EDIT),
            TextField::new('subtitle')
                ->setRequired(true),
            TextEditorField::new('description')
                ->setRequired(true),
            MoneyField::new('price')->setCurrency('EUR')
                ->setRequired(true),
        ];
    }
}

But it's not perfect, i still have some problems. When i want to update file, the old file is not deleted.

saxgard13 avatar Dec 21 '22 18:12 saxgard13

@sxsws The better workaround would be probably

ImageField::new('filePath')
     ...
    ->setFormTypeOption('upload_new', function (UploadedFile $file, string $uploadDir, string $fileName) {
        if (($extraDirs = dirname($fileName)) !== '.') {
            $uploadDir .= $extraDirs;
            if (!file_exists($uploadDir)) {
                mkdir($uploadDir, 0750, true);
            }
        }
        $file->move($uploadDir, $fileName);
    }),

this works flawlessly

agaktr avatar Nov 21 '23 16:11 agaktr