Last active
August 3, 2023 16:19
-
-
Save timba64/dc754130da9fefa7d1a38d2b5c5470b8 to your computer and use it in GitHub Desktop.
Some troubles with EasyAdmin 3 and KnpLabs/DoctrineBehaviors/translatable in Symfony 5.3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
a2lix_translation_form: | |
locale_provider: default | |
locales: [ru, en] | |
default_locale: ru | |
required_locales: [ru] | |
templating: "@A2lixTranslationForm/bootstrap_4_layout.html.twig" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Entity; | |
use App\Repository\BrandRepository; | |
use Doctrine\ORM\Mapping as ORM; | |
use Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface; | |
use Knp\DoctrineBehaviors\Model\Translatable\TranslatableTrait; | |
use Symfony\Component\HttpFoundation\File\File; | |
use Vich\UploaderBundle\Mapping\Annotation as Vich; | |
/** | |
* @ORM\Entity(repositoryClass=BrandRepository::class) | |
* @Vich\Uploadable | |
* @ORM\HasLifecycleCallbacks() | |
*/ | |
class Brand implements TranslatableInterface | |
{ | |
use TranslatableTrait; | |
/** | |
* @ORM\Id | |
* @ORM\GeneratedValue | |
* @ORM\Column(type="integer") | |
*/ | |
private $id; | |
/** | |
* @ORM\Column(type="datetime_immutable") | |
*/ | |
private $createdAt; | |
/** | |
* @ORM\Column(type="datetime_immutable") | |
*/ | |
private $updatedAt; | |
/** | |
* @ORM\Column(type="boolean") | |
*/ | |
private $published; | |
/** | |
* @ORM\Column(type="string", length=255, nullable=true) | |
*/ | |
private $brandPhoto; | |
/** | |
* @Vich\UploadableField(mapping="brand_images", fileNameProperty="brandPhoto") | |
* @var File|null | |
*/ | |
private $brandPhotoFile; | |
/** | |
* @ORM\Column(type="string", length=255, nullable=true) | |
*/ | |
private $brandLogo; | |
/** | |
* @Vich\UploadableField(mapping="brand_images", fileNameProperty="brandLogo") | |
* @var File|null | |
*/ | |
private $brandLogoFile; | |
/** | |
* @ORM\Column(type="smallint") | |
*/ | |
private $priority; | |
public function __construct() | |
{ | |
$this->createdAt = new \DateTimeImmutable(); | |
$this->updatedAt = new \DateTimeImmutable(); | |
} | |
public function getId(): ?int | |
{ | |
return $this->id; | |
} | |
public function getCreatedAt(): ?\DateTimeImmutable | |
{ | |
return $this->createdAt; | |
} | |
public function setCreatedAt(\DateTimeImmutable $createdAt): self | |
{ | |
$this->createdAt = $createdAt; | |
return $this; | |
} | |
/** | |
* @ORM\PrePersist | |
*/ | |
public function setCreatedAtValue() | |
{ | |
$this->createdAt = new \DateTimeImmutable(); | |
} | |
public function getUpdatedAt(): ?\DateTimeImmutable | |
{ | |
return $this->updatedAt; | |
} | |
public function setUpdatedAt(\DateTimeImmutable $updatedAt): self | |
{ | |
$this->updatedAt = $updatedAt; | |
return $this; | |
} | |
/** | |
* @ORM\PreUpdate | |
*/ | |
public function setUpdatedAtValue() | |
{ | |
$this->updatedAt = new \DateTimeImmutable(); | |
} | |
public function getPublished(): ?bool | |
{ | |
return $this->published; | |
} | |
public function setPublished(bool $published): self | |
{ | |
$this->published = $published; | |
return $this; | |
} | |
public function getBrandPhoto(): ?string | |
{ | |
return $this->brandPhoto; | |
} | |
public function setBrandPhoto(?string $brandPhoto): self | |
{ | |
$this->brandPhoto = $brandPhoto; | |
return $this; | |
} | |
public function setBrandPhotoFile(File $brandPhoto = null) | |
{ | |
$this->brandPhotoFile = $brandPhoto; | |
// VERY IMPORTANT: | |
// It is required that at least one field changes if you are using Doctrine, | |
// otherwise the event listeners won't be called and the file is lost | |
if ($brandPhoto) { | |
// if 'updatedAt' is not defined in your entity, use another property | |
$this->updatedAt = new \DateTimeImmutable('now'); | |
} | |
} | |
public function getBrandPhotoFile() | |
{ | |
return $this->brandPhotoFile; | |
} | |
public function getBrandLogo(): ?string | |
{ | |
return $this->brandLogo; | |
} | |
public function setBrandLogo(?string $brandLogo): self | |
{ | |
$this->brandLogo = $brandLogo; | |
return $this; | |
} | |
public function setBrandLogoFile(File $brandLogo = null) | |
{ | |
$this->brandLogoFile = $brandLogo; | |
// VERY IMPORTANT: | |
// It is required that at least one field changes if you are using Doctrine, | |
// otherwise the event listeners won't be called and the file is lost | |
if ($brandLogo) { | |
// if 'updatedAt' is not defined in your entity, use another property | |
$this->updatedAt = new \DateTimeImmutable('now'); | |
} | |
} | |
public function getBrandLogoFile() | |
{ | |
return $this->brandLogoFile; | |
} | |
public function getPriority(): ?int | |
{ | |
return $this->priority; | |
} | |
public function setPriority(int $priority): self | |
{ | |
$this->priority = $priority; | |
return $this; | |
} | |
public function __get($method) | |
{ | |
$arguments=[]; | |
return $this->proxyCurrentLocaleTranslation($method, $arguments); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Controller\Admin; | |
use App\Entity\Brand; | |
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; | |
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | |
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; | |
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField; | |
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | |
use App\Admin\Field\TranslationField; | |
use Symfony\Component\Form\Extension\Core\Type\TextType; | |
use FOS\CKEditorBundle\Form\Type\CKEditorType; | |
use EasyCorp\Bundle\EasyAdminBundle\Field\Field; | |
use EasyCorp\Bundle\EasyAdminBundle\Field\ImageField; | |
use Vich\UploaderBundle\Form\Type\VichImageType; | |
class BrandCrudController extends AbstractCrudController | |
{ | |
public static function getEntityFqcn(): string | |
{ | |
return Brand::class; | |
} | |
public function configureCrud(Crud $crud): Crud | |
{ | |
return $crud | |
//->renderContentMaximized() | |
//->renderSidebarMinimized() | |
// the Symfony Security permission needed to manage the entity | |
// (none by default, so you can manage all instances of the entity) | |
->setEntityPermission('ROLE_ADMIN') | |
->setFormThemes( | |
[ | |
//'@A2lixTranslationForm/bootstrap_4_layout.html.twig', | |
'admin/a2lix_bootstrap_5_layout.html.twig', | |
'@EasyAdmin/crud/form_theme.html.twig', | |
'@FOSCKEditor/Form/ckeditor_widget.html.twig', | |
] | |
); | |
} | |
public function configureFields(string $pageName): iterable | |
{ | |
$fieldsConfig = [ | |
'title' => [ | |
'field_type' => TextType::class, | |
'required' => true, | |
'label' => 'Заголовок', | |
], | |
'description' => [ | |
'field_type' => CKEditorType::class, | |
'required' => true, | |
'label' => 'Текст', | |
], | |
]; | |
return [ | |
DateTimeField::new('createdAt')->setColumns(6), | |
BooleanField::new('published')->setColumns(6), | |
Field::new('brandPhotoFile')->onlyOnForms()->setFormType(VichImageType::class)->setColumns(6), | |
ImageField::new('brandLogo')->onlyOnIndex()->setBasePath('/upload/brand-images/'), | |
Field::new('brandLogoFile')->onlyOnForms()->setFormType(VichImageType::class)->setColumns(6), | |
Field::new('priority'), | |
TranslationField::new('translations', 'Переводы', $fieldsConfig) | |
->setRequired(true) | |
->hideOnIndex(), | |
]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Entity; | |
use App\Repository\BrandTranslationRepository; | |
use Doctrine\ORM\Mapping as ORM; | |
use Knp\DoctrineBehaviors\Contract\Entity\TranslationInterface; | |
use Knp\DoctrineBehaviors\Model\Translatable\TranslationTrait; | |
use Knp\DoctrineBehaviors\Contract\Entity\SluggableInterface; | |
use Knp\DoctrineBehaviors\Model\Sluggable\SluggableTrait; | |
/** | |
* @ORM\Entity(repositoryClass=BrandTranslationRepository::class) | |
*/ | |
class BrandTranslation implements TranslationInterface, SluggableInterface | |
{ | |
use TranslationTrait; | |
use SluggableTrait; | |
/** | |
* @ORM\Id | |
* @ORM\GeneratedValue | |
* @ORM\Column(type="integer") | |
*/ | |
private $id; | |
/** | |
* @ORM\Column(type="string", length=255) | |
*/ | |
private $title; | |
/** | |
* @ORM\Column(type="text") | |
*/ | |
private $description; | |
public function getId(): ?int | |
{ | |
return $this->id; | |
} | |
public function getTitle(): ?string | |
{ | |
return $this->title; | |
} | |
public function setTitle(string $title): self | |
{ | |
$this->title = $title; | |
return $this; | |
} | |
public function getDescription(): ?string | |
{ | |
return $this->description; | |
} | |
public function setDescription(string $description): self | |
{ | |
$this->description = $description; | |
return $this; | |
} | |
/** | |
* @return string[] | |
*/ | |
public function getSluggableFields(): array | |
{ | |
return ['title']; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Controller\Admin; | |
use App\Entity\BrandTranslation; | |
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; | |
class BrandTranslationCrudController extends AbstractCrudController | |
{ | |
public static function getEntityFqcn(): string | |
{ | |
return BrandTranslation::class; | |
} | |
/* | |
public function configureFields(string $pageName): iterable | |
{ | |
return [ | |
IdField::new('id'), | |
TextField::new('title'), | |
TextEditorField::new('description'), | |
]; | |
} | |
*/ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
easy_admin: | |
design: | |
form_theme: | |
- '@EasyAdmin/form/bootstrap_4.html.twig' | |
- '@FOSCKEditor/Form/ckeditor_widget.html.twig' | |
- '@A2lixTranslationForm/bootstrap_4_layout.html.twig' | |
- '@VichUploader/Form/fields.html.twig' | |
entities: | |
# List the entity class name you want to manage | |
Brand: | |
class: App\Entity\Brand | |
form: | |
fields: | |
- {property: 'brandPhotoFile', type: 'VichImageType'} | |
- {property: 'brandLogoFile', type: 'VichImageType'} | |
Style: | |
class: App\Entity\Style |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Admin\Field; | |
use A2lix\TranslationFormBundle\Form\Type\TranslationsType; | |
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface; | |
use EasyCorp\Bundle\EasyAdminBundle\Field\FieldTrait; | |
final class TranslationField implements FieldInterface | |
{ | |
use FieldTrait; | |
public static function new(string $propertyName, ?string $label = null, $fieldsConfig = []): self | |
{ | |
return (new self()) | |
->setProperty($propertyName) | |
->setLabel($label) | |
->setFormType(TranslationsType::class) | |
->setFormTypeOptions( | |
[ | |
'default_locale' => '%locale%', | |
'fields' => $fieldsConfig, | |
] | |
); | |
} | |
} |
public function __get($name)
{
$method = 'get'. ucfirst($name);
$arguments = [];
return $this->proxyCurrentLocaleTranslation($method, $arguments);
}
Можно и так
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Finally I found a solution:
If I add magic method __get() in Brand.php
everything works great