#symfony #symfony4 #sonata #symfony-sonata
Вопрос:
Я пытаюсь показать изображение предварительного просмотра с помощью Sonata Admin Bundle 3 версии, но я не могу этого сделать. Я получаю эту ошибку в RecipeAdmin.php: Не удалось загрузить тип «файл»: класс не существует.
RecipeAdmin.php
<?php
declare(strict_types=1);
namespace AppAdmin;
use SonataAdminBundleAdminAbstractAdmin;
use SonataAdminBundleDatagridDatagridMapper;
use SonataAdminBundleDatagridListMapper;
use SonataAdminBundleFormFormMapper;
use SonataAdminBundleShowShowMapper;
use SonataFormTypeCollectionType;
use SonataAdminBundleFormTypeModelListType;
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 amp;amp; ($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 Сущность
<?php
namespace AppEntity;
use AppRepositoryRecipeRepository;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use SymfonyComponentHttpFoundationFileUploadedFile;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity(repositoryClass=RecipeRepository::class)
*/
class Recipe
{
public function __construct() {
$this->categories = new DoctrineCommonCollectionsArrayCollection();
}
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMColumn(type="string", length=255)
*/
private $title;
/**
* @ORMColumn(type="string", length=255)
*/
private $image;
/**
* @ORMColumn(type="string", length=255)
*/
private $description;
/**
* @ORMManyToOne(targetEntity="User", inversedBy="recipes")
* @ORMJoinColumn(nullable=false)
*/
private $user;
/**
* @ORMColumn(type="integer", nullable=true)
*/
private $score;
/**
* @ORMColumn(type="boolean")
*/
private $visible;
/**
* @ORMManyToMany(targetEntity="Category", inversedBy="recipe", cascade={"persist"})
* @ORMJoinTable(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;
}
}
Вот ссылка о том, как это сделать: https://symfony.com/doc/current/bundles/SonataAdminBundle/cookbook/recipe_image_previews.html
В документации объясняется, что я должен использовать поля типа «файл», но когда я использую его в своем проекте, он не запускается.
Ответ №1:
Это ошибка в документе, вместо file
этого вы должны использовать FileType::class
и добавлять :
use SymfonyComponentFormExtensionCoreTypeFileType;
$formMapper
->add('title',null,['label' =>'Título'])
->add('image', FileType::class, $fileFormOptions)
У вас все равно будут такие ошибки, как :
The form's view data is expected to be an instance of class SymfonyComponentHttpFoundationFileFile, 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 SymfonyComponentHttpFoundationFileFile.
В кулинарной книге вам предлагается создать объект изображения, поэтому вы должны добавить его и выполнить все шаги :
https://sonata-project.org/bundles/admin/master/doc/cookbook/recipe_file_uploads.html
Я предлагаю вместо того, чтобы следовать этой кулинарной книге, вам следует установить и использовать носитель sonata, интеграция проще, и в нем есть некоторые приятные функции, такие как создание различных форматов для загрузки.