简体   繁体   中英

Showing image previews Sonata Admin Bundle Could not load type "file"

I'm trying to show preview image with Sonata Admin Bundle 3 version but I can't do it. I get this error in RecipeAdmin.php: Could not load type "file": class does not exist.

RecipeAdmin.php

<?php

declare(strict_types=1);

namespace App\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\Form\Type\CollectionType;
use Sonata\AdminBundle\Form\Type\ModelListType;



final class RecipeAdmin extends AbstractAdmin
{

    protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
    {
        $datagridMapper
        ->add('title',null,['label' =>'Título'])
        ->add('image',null,['label' =>'Imagen'])
        ->add('description',null,['label' =>'Descripción'])
        ->add('score',null,['label' =>'Puntuación'])
        ->add('visible')
            ;
    }

    protected function configureListFields(ListMapper $listMapper): void
    {
        $listMapper
            ->add('id')
            ->add('user', CollectionType::class,['label' =>'Usuario'])
            ->add('title',null,['label' =>'Título'])
            ->add('image',null,['label' =>'Imagen'])
            ->add('description',null,['label' =>'Descripción'])
            ->add('score',null,['label' =>'Puntuación'])
            ->add('visible',null,['label' =>'Visible'])
            ->add('_action', null, [
                'label' => 'Acciones',
                'actions' => [
                    'show' => [],
                    'edit' => [],
                    'delete' => [],
                ],
            ]);
    }

    protected function configureFormFields(FormMapper $formMapper): void
    {
        

            $image = $this->getSubject();

            // use $fileFormOptions so we can add other options to the field
            $fileFormOptions = ['required' => false];
            if ($image && ($webPath = $image->getImage())) {
                // get the request so the full path to the image can be set
                $request = $this->getRequest();
                $fullPath = $request->getBasePath().'/'.$webPath;
    
                // add a 'help' option containing the preview's img tag
                $fileFormOptions['help'] = '<img src="'.$fullPath.'" class="admin-preview"/>';
                $fileFormOptions['help_html'] = true;
            }

            $formMapper
            ->add('title',null,['label' =>'Título'])
            ->add('image', 'file', $fileFormOptions)
            ->add('description',null,['label' =>'Descripción'])
            ->add('score',null,['label' =>'Puntuación'])
            ->add('visible')
            ;
    }

    protected function configureShowFields(ShowMapper $showMapper): void
    {
        $showMapper
            ->add('title',null,['label' =>'Título'])
            ->add('image',null,['label' =>'Imagen'])
            ->add('description',null,['label' =>'Descripción'])
            ->add('user', CollectionType::class)
            ->add('score',null,['label' =>'Puntuaciones'])
            ->add('visible')
            ;
    }
}

Recipe.php Entity

<?php

namespace App\Entity;

use App\Repository\RecipeRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=RecipeRepository::class)
 */
class Recipe
{
    public function __construct() {
        $this->categories = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $title;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $image;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $description;

    /** 
     * @ORM\ManyToOne(targetEntity="User", inversedBy="recipes")
     * @ORM\JoinColumn(nullable=false)
    */
    private $user;

    /**
     * @ORM\Column(type="integer", nullable=true)
     */
    private $score;

    /**
     * @ORM\Column(type="boolean")
     */
    private $visible;

    /**
     * @ORM\ManyToMany(targetEntity="Category", inversedBy="recipe", cascade={"persist"})
     * @ORM\JoinTable(name="recipes_categories")
     */
    private $categories;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function setId(int $id)
    {
        $this->id = $id;

        return $this;
    }

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }

    public function getImage(): ?string
    {
        return $this->image;
    }

    public function setImage(string $image): self
    {
        $this->image = $image;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(string $description): self
    {
        $this->description = $description;

        return $this;
    }

    public function getUser()
    {
        return $this->user;
    }

    public function setUser($user)
    {
        $this->user = $user;

        return $this;
    }

    public function getScore(): ?int
    {
        return $this->score;
    }

    public function setScore(?int $score): self
    {
        $this->score = $score;

        return $this;
    }

    public function getVisible(): ?bool
    {
        return $this->visible;
    }

    public function setVisible(bool $visible): self
    {
        $this->visible = $visible;

        return $this;
    }

    public function getCategories()
    {
        return $this->categories;
    }

    public function setCategories($categories)
    {
        $this->categories = $categories;

        return $this;
    }

    

    public function __toString()
    {
        return $this->getTitle();
    }

    public function addCategory(Category $category): self
    {
        if (!$this->categories->contains($category)) {
            $this->categories[] = $category;
        }

        return $this;
    }

    public function removeCategory(Category $category): self
    {
        $this->categories->removeElement($category);

        return $this;
    }
}

This is the link about how do it: https://symfony.com/doc/current/bundles/SonataAdminBundle/cookbook/recipe_image_previews.html

https://sonata-project.org/bundles/admin/master/doc/cookbook/recipe_image_previews.html#showing-image-previews

In the documentation explains that I have to use 'file' type fields but when I use it in my proyect doesn't runs.

This is an error in the doc, instead of file you should use FileType::class and adding:

use Symfony\Component\Form\Extension\Core\Type\FileType;
    

$formMapper
    ->add('title',null,['label' =>'Título'])
    ->add('image', FileType::class, $fileFormOptions)

You will still have error such as:

The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) string. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) string to an instance of Symfony\Component\HttpFoundation\File\File.

In the cookbook they tell you to create an Image Entity so you should add it and follow all the steps: https://sonata-project.org/bundles/admin/master/doc/cookbook/recipe_file_uploads.html

I suggest instead of following this cookbook, you should install and use the sonata media , the integration is easier and it have some nice features such as making different formats for your upload.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM