diff --git a/composer.json b/composer.json
index 22cb30b..b186a58 100644
--- a/composer.json
+++ b/composer.json
@@ -8,7 +8,8 @@
"psr/http-message": "*",
"ramsey/uuid": "^4.1",
"ramsey/uuid-doctrine": "^1.6",
- "symfony/validator": "4.4.*"
+ "symfony/validator": "4.4.*",
+ "vich/uploader-bundle": "^1.16"
},
"require-dev": {
"codeception/codeception": "^2.5",
diff --git a/src/Application/Cms/MediaFile/Service/MediaFilePathResolver.php b/src/Application/Cms/MediaFile/Service/MediaFilePathResolver.php
new file mode 100644
index 0000000..6524966
--- /dev/null
+++ b/src/Application/Cms/MediaFile/Service/MediaFilePathResolver.php
@@ -0,0 +1,49 @@
+';
+ private const VIDEO_HTML_MASK = '';
+ private const PDF_HTML_MASK = '';
+
+ /**
+ * @var UploaderHelper
+ */
+ private $uploaderHelper;
+
+ public function __construct(UploaderHelper $uploaderHelper)
+ {
+ $this->uploaderHelper = $uploaderHelper;
+ }
+
+ public function getFileUrl(MediaFile $file): ?string
+ {
+ return $this->uploaderHelper->asset($file, 'file');
+ }
+
+ public function getFileHtml(MediaFile $file): ?string
+ {
+ $url = $this->getFileUrl($file);
+
+ if ($file->getType()->isImage()) {
+ return sprintf(self::IMAGE_HTML_MASK, $url, $file->getTitle());
+ }
+
+ if ($file->getType()->isVideo()) {
+ return sprintf(self::VIDEO_HTML_MASK, $url);
+ }
+
+ if ($file->getType()->isPdf()) {
+ return sprintf(self::PDF_HTML_MASK, $url);
+ }
+
+ return null;
+ }
+}
diff --git a/src/Application/Cms/MediaFile/Service/MediaFileTypeResolver.php b/src/Application/Cms/MediaFile/Service/MediaFileTypeResolver.php
new file mode 100644
index 0000000..86b879e
--- /dev/null
+++ b/src/Application/Cms/MediaFile/Service/MediaFileTypeResolver.php
@@ -0,0 +1,43 @@
+getMimeType();
+
+ if ($mimeType === self::PDF_MIME_TYPE) {
+ return new MediaFileType(MediaFileType::PDF_TYPE);
+ }
+
+ if (in_array($mimeType, self::IMAGE_MIME_TYPES, true)) {
+ return new MediaFileType(MediaFileType::IMAGE_TYPE);
+ }
+
+ if (in_array($mimeType, self::VIDEO_MIME_TYPES, true)) {
+ return new MediaFileType(MediaFileType::VIDEO_TYPE);
+ }
+
+ throw new ApplicationException('Mime type ' . $mimeType . ' is not supported');
+ }
+}
diff --git a/src/Application/EventListener/MediaFileUpdatedListener.php b/src/Application/EventListener/MediaFileUpdatedListener.php
new file mode 100644
index 0000000..5eec497
--- /dev/null
+++ b/src/Application/EventListener/MediaFileUpdatedListener.php
@@ -0,0 +1,60 @@
+mediaFileTypeResolver = $mediaFileTypeResolver;
+ $this->fileMappingFactory = $fileMappingFactory;
+ }
+
+ public function preUpdate(LifecycleEventArgs $args): void
+ {
+ $this->handleEventArgs($args);
+ }
+
+ public function prePersist(LifecycleEventArgs $args): void
+ {
+ $this->handleEventArgs($args);
+ }
+
+ private function handleEventArgs(LifecycleEventArgs $args): void
+ {
+ $object = $args->getObject();
+
+ if (!$object instanceof MediaFile) {
+ return;
+ }
+
+ if (!$object->getFile()) {
+ return;
+ }
+
+ $object->setType($this->mediaFileTypeResolver->getMediaFileTypeByFile($object->getFile()));
+ $mapping = $this->fileMappingFactory->fromField($object, 'file');
+
+ if ($mapping) {
+ $object->setStorage(new MediaFileStorage($mapping->getUploadDestination()));
+ }
+ }
+}
diff --git a/src/Domain/Entity/MediaCatalog.php b/src/Domain/Entity/MediaCatalog.php
new file mode 100644
index 0000000..0a82234
--- /dev/null
+++ b/src/Domain/Entity/MediaCatalog.php
@@ -0,0 +1,46 @@
+id = $id;
+ $this->name = $name;
+ }
+
+ public function __toString()
+ {
+ return $this->name;
+ }
+
+ public function getId(): Id
+ {
+ return $this->id;
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function setName(string $name): void
+ {
+ $this->name = $name;
+ }
+}
diff --git a/src/Domain/Entity/MediaFile.php b/src/Domain/Entity/MediaFile.php
new file mode 100644
index 0000000..58c8c2f
--- /dev/null
+++ b/src/Domain/Entity/MediaFile.php
@@ -0,0 +1,146 @@
+id = $id;
+ $this->catalog = $catalog;
+ $this->title = $title;
+ $this->type = $type;
+ $this->name = $name;
+ $this->storage = $storage;
+ $this->originalName = $originalName;
+ }
+
+ public function getId(): Id
+ {
+ return $this->id;
+ }
+
+ public function getCatalog(): MediaCatalog
+ {
+ return $this->catalog;
+ }
+
+ public function setCatalog(MediaCatalog $catalog): void
+ {
+ $this->catalog = $catalog;
+ }
+
+ public function getTitle(): string
+ {
+ return $this->title;
+ }
+
+ public function setTitle(string $title): void
+ {
+ $this->title = $title;
+ }
+
+ public function getType(): MediaFileType
+ {
+ return $this->type;
+ }
+
+ public function setType(MediaFileType $type): void
+ {
+ $this->type = $type;
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function setName(?string $name): void
+ {
+ $this->name = $name;
+ }
+
+ public function getStorage(): MediaFileStorage
+ {
+ return $this->storage;
+ }
+
+ public function setStorage(MediaFileStorage $storage): void
+ {
+ $this->storage = $storage;
+ }
+
+ public function getFile(): ?File
+ {
+ return $this->file;
+ }
+
+ public function setFile(?File $file): void
+ {
+ $this->file = $file;
+ }
+
+ public function getOriginalName(): ?string
+ {
+ return $this->originalName;
+ }
+
+ public function setOriginalName(?string $originalName): void
+ {
+ $this->originalName = $originalName;
+ }
+}
diff --git a/src/Domain/Entity/ValueObject/MediaFileStorage.php b/src/Domain/Entity/ValueObject/MediaFileStorage.php
new file mode 100644
index 0000000..b8030cd
--- /dev/null
+++ b/src/Domain/Entity/ValueObject/MediaFileStorage.php
@@ -0,0 +1,31 @@
+ self::S3_STORAGE,
+ self::NFS_STORAGE => self::NFS_STORAGE,
+ ];
+
+ use ValueObjectTrait;
+
+ public function isS3(): bool
+ {
+ return $this->value === self::S3_STORAGE;
+ }
+
+ public function isNfs(): bool
+ {
+ return $this->value === self::NFS_STORAGE;
+ }
+}
diff --git a/src/Domain/Entity/ValueObject/MediaFileType.php b/src/Domain/Entity/ValueObject/MediaFileType.php
new file mode 100644
index 0000000..795579a
--- /dev/null
+++ b/src/Domain/Entity/ValueObject/MediaFileType.php
@@ -0,0 +1,45 @@
+ self::IMAGE_TYPE,
+ self::PDF_TYPE => self::PDF_TYPE,
+ self::VIDEO_TYPE => self::VIDEO_TYPE,
+ ];
+
+ use ValueObjectTrait;
+
+ protected function checkValue(string $value): void
+ {
+ if (!in_array($value, self::AVAILABLE_TYPES)) {
+ throw new IncorrectValueObjectException('This media file type is not supported');
+ }
+ }
+
+ public function isPdf(): bool
+ {
+ return $this->value === self::PDF_TYPE;
+ }
+
+ public function isImage(): bool
+ {
+ return $this->value === self::IMAGE_TYPE;
+ }
+
+ public function isVideo(): bool
+ {
+ return $this->value === self::VIDEO_TYPE;
+ }
+}
diff --git a/src/Domain/Repository/MediaCatalogRepository/Exception/MediaCatalogNotFoundException.php b/src/Domain/Repository/MediaCatalogRepository/Exception/MediaCatalogNotFoundException.php
new file mode 100644
index 0000000..8db7064
--- /dev/null
+++ b/src/Domain/Repository/MediaCatalogRepository/Exception/MediaCatalogNotFoundException.php
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/src/Infrastructure/Doctrine/Entity/mapping/MediaFile.orm.xml b/src/Infrastructure/Doctrine/Entity/mapping/MediaFile.orm.xml
new file mode 100644
index 0000000..2375790
--- /dev/null
+++ b/src/Infrastructure/Doctrine/Entity/mapping/MediaFile.orm.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Infrastructure/Doctrine/Repository/MediaCatalogRepository.php b/src/Infrastructure/Doctrine/Repository/MediaCatalogRepository.php
new file mode 100644
index 0000000..a22e4cb
--- /dev/null
+++ b/src/Infrastructure/Doctrine/Repository/MediaCatalogRepository.php
@@ -0,0 +1,55 @@
+toString());
+ }
+
+ public function getAll(): array
+ {
+ try {
+ return $this->findAll();
+ } catch (Exception $e) {
+ throw new MediaCatalogRepositoryException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ public function getFirst(): MediaCatalog
+ {
+ try {
+ $catalog = $this->findOneBy([], ['id' => 'desc']);
+
+ if ($catalog === null) {
+ throw new MediaCatalogNotFoundException();
+ }
+
+ return $catalog;
+ } catch (MediaCatalogNotFoundException $e) {
+ throw $e;
+ } catch (Exception $e) {
+ throw new MediaCatalogRepositoryException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+}
diff --git a/src/Infrastructure/Doctrine/Repository/MediaFileRepository.php b/src/Infrastructure/Doctrine/Repository/MediaFileRepository.php
new file mode 100644
index 0000000..5dc3226
--- /dev/null
+++ b/src/Infrastructure/Doctrine/Repository/MediaFileRepository.php
@@ -0,0 +1,38 @@
+toString());
+ }
+
+ public function getByCatalog(MediaCatalog $catalog): array
+ {
+ try {
+ return $this->findBy(['catalog' => $catalog]);
+ } catch (Exception $e) {
+ throw new MediaFileRepositoryException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+}
diff --git a/src/Infrastructure/Doctrine/Type/MediaFileStorageType.php b/src/Infrastructure/Doctrine/Type/MediaFileStorageType.php
new file mode 100644
index 0000000..6101f44
--- /dev/null
+++ b/src/Infrastructure/Doctrine/Type/MediaFileStorageType.php
@@ -0,0 +1,28 @@
+getVarcharTypeDeclarationSQL($fieldDeclaration);
+ }
+
+ public function getName(): string
+ {
+ return 'cms_media_file_storage';
+ }
+}
diff --git a/src/Infrastructure/Doctrine/Type/MediaFileType.php b/src/Infrastructure/Doctrine/Type/MediaFileType.php
new file mode 100644
index 0000000..9b56055
--- /dev/null
+++ b/src/Infrastructure/Doctrine/Type/MediaFileType.php
@@ -0,0 +1,28 @@
+getVarcharTypeDeclarationSQL($fieldDeclaration);
+ }
+
+ public function getName(): string
+ {
+ return 'cms_media_file_type';
+ }
+}
diff --git a/src/Infrastructure/Symfony/Form/ComponentTypes/HTMLComponentType.php b/src/Infrastructure/Symfony/Form/ComponentTypes/HTMLComponentType.php
index 05669a3..c61effd 100644
--- a/src/Infrastructure/Symfony/Form/ComponentTypes/HTMLComponentType.php
+++ b/src/Infrastructure/Symfony/Form/ComponentTypes/HTMLComponentType.php
@@ -13,7 +13,12 @@ class HTMLComponentType extends AbstractType implements DataTransformerInterface
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
- $builder->add('html', TextareaType::class);
+ $builder->add('html', TextareaType::class, [
+ 'attr' => [
+ 'styles' => 'height: auto;',
+ 'rows' => 10,
+ ]
+ ]);
$builder->resetViewTransformers();
$builder->addViewTransformer($this);
diff --git a/src/Infrastructure/Symfony/Form/Fields/VichFileField.php b/src/Infrastructure/Symfony/Form/Fields/VichFileField.php
new file mode 100644
index 0000000..57fb690
--- /dev/null
+++ b/src/Infrastructure/Symfony/Form/Fields/VichFileField.php
@@ -0,0 +1,23 @@
+setProperty($propertyName)
+ ->setTemplatePath('')
+ ->setLabel($label)
+ ->setFormType(VichFileType::class);
+ }
+}
diff --git a/src/Infrastructure/Symfony/Form/PageComponentType.php b/src/Infrastructure/Symfony/Form/PageComponentType.php
index 144059b..7ce06a9 100644
--- a/src/Infrastructure/Symfony/Form/PageComponentType.php
+++ b/src/Infrastructure/Symfony/Form/PageComponentType.php
@@ -13,6 +13,8 @@
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\Form\FormEvent;
+use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -44,15 +46,38 @@ public function buildForm(FormBuilderInterface $builder, array $options)
'required' => true,
'label' => 'Позиция',
'attr' => [
- 'positionable' => 'positionable'
+ 'positionable' => 'positionable',
+ 'value' => 1,
],
])
->add('isPublished', CheckboxType::class, [
- 'label' => 'Компонент активен'
+ 'label' => 'Компонент активен',
+ 'attr' => [
+ 'checked' => 'checked',
+ ],
])
->add('data', HTMLComponentType::class, [
'label' => 'Данные'
]);
+
+ $builder->addEventListener(FormEvents::PRE_SET_DATA, static function (FormEvent $event) {
+ $component = $event->getData();
+ $form = $event->getForm();
+
+ if ($component instanceof PageComponent) {
+ $form
+ ->add('isPublished', CheckboxType::class, [
+ 'label' => 'Компонент активен'
+ ])
+ ->add('order', IntegerType::class, [
+ 'required' => true,
+ 'label' => 'Позиция',
+ 'attr' => [
+ 'positionable' => 'positionable',
+ ],
+ ]);
+ }
+ });
}
public function configureOptions(OptionsResolver $resolver): void
diff --git a/src/Resources/config/packages/doctrine.yaml b/src/Resources/config/packages/doctrine.yaml
index 6a5bb6e..a39a587 100644
--- a/src/Resources/config/packages/doctrine.yaml
+++ b/src/Resources/config/packages/doctrine.yaml
@@ -7,6 +7,8 @@ doctrine:
cms_content_type: 'Skyeng\MarketingCmsBundle\Infrastructure\Doctrine\Type\ContentType'
cms_cache_time: 'Skyeng\MarketingCmsBundle\Infrastructure\Doctrine\Type\CacheTimeType'
page_component_name: 'Skyeng\MarketingCmsBundle\Infrastructure\Doctrine\Type\PageComponentNameType'
+ cms_media_file_storage: 'Skyeng\MarketingCmsBundle\Infrastructure\Doctrine\Type\MediaFileStorageType'
+ cms_media_file_type: 'Skyeng\MarketingCmsBundle\Infrastructure\Doctrine\Type\MediaFileType'
orm:
entity_managers:
diff --git a/src/Resources/config/packages/prod/vich_uploader.yaml b/src/Resources/config/packages/prod/vich_uploader.yaml
new file mode 100644
index 0000000..9acf8ff
--- /dev/null
+++ b/src/Resources/config/packages/prod/vich_uploader.yaml
@@ -0,0 +1,4 @@
+vich_uploader:
+ mappings:
+ cms_media_files:
+ upload_destination: 'uploads.s3'
diff --git a/src/Resources/config/packages/vich_uploader.yaml b/src/Resources/config/packages/vich_uploader.yaml
new file mode 100644
index 0000000..7169b8a
--- /dev/null
+++ b/src/Resources/config/packages/vich_uploader.yaml
@@ -0,0 +1,9 @@
+parameters:
+ env(UPLOADS_BASE_URL): '/uploads'
+
+vich_uploader:
+ mappings:
+ cms_media_files:
+ uri_prefix: '%env(UPLOADS_BASE_URL)%'
+ upload_destination: 'uploads.nfs'
+ namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
diff --git a/src/Resources/config/services.yaml b/src/Resources/config/services.yaml
index cbe353b..1e1eead 100644
--- a/src/Resources/config/services.yaml
+++ b/src/Resources/config/services.yaml
@@ -11,3 +11,9 @@ services:
- '../../Domain/{Exception,Traits,Entity,Event}'
- '../../Domain/{Exception,Traits,Entity,Event}/*.php'
- '../../Domain/{Exception,Traits,Entity,Event}/**/*.php'
+
+ marketing_cms_bundle.listener.media_file_updated_listener:
+ class: Skyeng\MarketingCmsBundle\Application\EventListener\MediaFileUpdatedListener
+ tags:
+ - { name: doctrine.event_listener, event: preUpdate, method: preUpdate }
+ - { name: doctrine.event_listener, event: prePersist, method: prePersist }
diff --git a/src/Resources/config/validator/validation.yaml b/src/Resources/config/validator/validation.yaml
index fdfb938..10208f6 100644
--- a/src/Resources/config/validator/validation.yaml
+++ b/src/Resources/config/validator/validation.yaml
@@ -41,3 +41,16 @@ Skyeng\MarketingCmsBundle\Domain\Entity\Page:
- Valid: ~
customMetaTags:
- Valid: ~
+
+# Media
+
+Skyeng\MarketingCmsBundle\Domain\Entity\MediaCatalog:
+ constraints:
+ - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity: name
+
+Skyeng\MarketingCmsBundle\Domain\Entity\MediaFile:
+ properties:
+ file:
+ - File: { maxSize: 20M, mimeTypes: [ image/jpeg, image/png, image/gif, application/pdf, video/mp4 ] }
+ catalog:
+ - NotBlank: ~
diff --git a/src/Resources/config/vich_uploader/Domain.Entity.MediaFile.yml b/src/Resources/config/vich_uploader/Domain.Entity.MediaFile.yml
new file mode 100644
index 0000000..b9e44e9
--- /dev/null
+++ b/src/Resources/config/vich_uploader/Domain.Entity.MediaFile.yml
@@ -0,0 +1,5 @@
+Skyeng\MarketingCmsBundle\Domain\Entity\MediaFile:
+ file:
+ mapping: cms_media_files
+ filename_property: name
+ original_name: originalName
diff --git a/src/Resources/public/ea-copy-actions.js b/src/Resources/public/ea-copy-actions.js
new file mode 100644
index 0000000..a0f578f
--- /dev/null
+++ b/src/Resources/public/ea-copy-actions.js
@@ -0,0 +1,17 @@
+$('body').on('click', 'a.copy-action-ea', function (event) {
+ event.preventDefault();
+
+ var $temp = $('');
+ $('body').append($temp);
+ $temp.val($(this).attr('href')).select();
+ document.execCommand('copy');
+ $temp.remove();
+
+ var $childrenIcon = $(this).children('.action-icon');
+
+ $childrenIcon.removeClass('fa-copy').addClass('fa-check');
+
+ setTimeout(function () {
+ $childrenIcon.removeClass('fa-check').addClass('fa-copy');
+ }, 1000);
+});
diff --git a/src/UI/Controller/Admin/MediaCatalogCrudController.php b/src/UI/Controller/Admin/MediaCatalogCrudController.php
new file mode 100644
index 0000000..54485fa
--- /dev/null
+++ b/src/UI/Controller/Admin/MediaCatalogCrudController.php
@@ -0,0 +1,65 @@
+mediaCatalogRepository = $mediaCatalogRepository;
+ }
+
+ public static function getEntityFqcn(): string
+ {
+ return MediaCatalog::class;
+ }
+
+ public function configureCrud(Crud $crud): Crud
+ {
+ return $crud
+ ->setPageTitle(Crud::PAGE_INDEX, 'Каталог')
+ ->setPageTitle(Crud::PAGE_DETAIL, 'Каталог')
+ ->setPageTitle(Crud::PAGE_NEW, 'Создать каталог')
+ ->setPageTitle(Crud::PAGE_EDIT, 'Каталог');
+ }
+
+ public function configureActions(Actions $actions): Actions
+ {
+ $actions->remove(Crud::PAGE_INDEX, Action::DELETE);
+ return $actions;
+ }
+
+ public function configureFields(string $pageName): iterable
+ {
+ $name = TextField::new('name', 'Название');
+
+ if (in_array($pageName, [Crud::PAGE_INDEX, Crud::PAGE_DETAIL], true)) {
+ return [$name];
+ }
+
+ return [$name];
+ }
+
+ public function createEntity(string $entityFqcn): MediaCatalog
+ {
+ return new MediaCatalog(
+ $this->mediaCatalogRepository->getNextIdentity(),
+ '',
+ );
+ }
+}
diff --git a/src/UI/Controller/Admin/MediaFileCrudController.php b/src/UI/Controller/Admin/MediaFileCrudController.php
new file mode 100644
index 0000000..7273617
--- /dev/null
+++ b/src/UI/Controller/Admin/MediaFileCrudController.php
@@ -0,0 +1,154 @@
+mediaFileRepository = $mediaFileRepository;
+ $this->mediaCatalogRepository = $mediaCatalogRepository;
+ $this->mediaFilePathResolver = $mediaFilePathResolver;
+ }
+
+ public static function getEntityFqcn(): string
+ {
+ return MediaFile::class;
+ }
+
+ public function configureFilters(Filters $filters): Filters
+ {
+ return $filters
+ ->add(
+ ChoiceFilter::new('type', 'Тип файла')->setChoices([MediaFileType::AVAILABLE_TYPES])
+ );
+ }
+
+ public function configureCrud(Crud $crud): Crud
+ {
+ return $crud
+ ->setPageTitle(Crud::PAGE_INDEX, 'Медиа файлы')
+ ->setPageTitle(Crud::PAGE_DETAIL, 'Медиа файл')
+ ->setPageTitle(Crud::PAGE_NEW, 'Создать медиа файл')
+ ->setPageTitle(Crud::PAGE_EDIT, 'Медиа файл');
+ }
+
+ public function configureAssets(Assets $assets): Assets
+ {
+ $hideMediaCatalogSelectorClearButton = '#MediaFile_catalog + .select2 .select2-selection__clear {display:none;}';
+
+ return $assets
+ ->addHtmlContentToHead("")
+ ->addJsFile('bundles/marketingcms/ea-copy-actions.js');
+ }
+
+ public function configureActions(Actions $actions): Actions
+ {
+ $actions->update(Crud::PAGE_INDEX, Action::NEW, function (Action $action) {
+ return $action->setLabel('Создать медиа файл');
+ });
+
+ $getFileLink = Action::new('getFileLink', 'Ссылка', 'fa fa-copy')
+ ->linkToUrl(function (MediaFile $file) {
+ return $this->mediaFilePathResolver->getFileUrl($file);
+ })
+ ->addCssClass('copy-action-ea');
+
+ $getFileHtml = Action::new('getFileHtml', 'Html', 'fa fa-copy')
+ ->linkToUrl(function (MediaFile $file) {
+ return $this->mediaFilePathResolver->getFileHtml($file);
+ })
+ ->addCssClass('copy-action-ea');
+
+ $actions->add(Crud::PAGE_INDEX, $getFileLink);
+ $actions->add(Crud::PAGE_INDEX, $getFileHtml);
+
+ try {
+ $this->mediaCatalogRepository->getFirst();
+ } catch (MediaCatalogNotFoundException $e) {
+ $actions->remove(Crud::PAGE_INDEX, Action::NEW);
+ }
+
+ return $actions;
+ }
+
+ public function getFileHtml(AdminContext $context)
+ {
+ $mediaFile = $context->getEntity()->getInstance();
+
+ return $mediaFile->getName();
+ }
+
+ public function configureFields(string $pageName): iterable
+ {
+ $title = TextField::new('title', 'Заголовок файла');
+ $file = VichFileField::new('file', 'Файл')->setFormTypeOptions([
+ 'allow_delete' => false,
+ ]);
+ $catalog = AssociationField::new('catalog', 'Каталог')->setRequired(true);
+ $originalName = TextField::new('originalName', 'Название файла');
+
+ if (in_array($pageName, [Crud::PAGE_INDEX, Crud::PAGE_DETAIL], true)) {
+ return [$originalName, $title, $catalog];
+ }
+
+ if ($pageName === Crud::PAGE_NEW) {
+ $file->setRequired(true);
+ }
+
+ return [$catalog, $title, $file];
+ }
+
+ public function createEntity(string $entityFqcn): MediaFile
+ {
+ return new MediaFile(
+ $this->mediaFileRepository->getNextIdentity(),
+ $this->mediaCatalogRepository->getFirst(),
+ '',
+ new MediaFileType(MediaFileType::IMAGE_TYPE),
+ '',
+ new MediaFileStorage(MediaFileStorage::NFS_STORAGE),
+ '',
+ );
+ }
+}
diff --git a/src/UI/Controller/Admin/PageCrudController.php b/src/UI/Controller/Admin/PageCrudController.php
index 7af9b41..38fec4f 100644
--- a/src/UI/Controller/Admin/PageCrudController.php
+++ b/src/UI/Controller/Admin/PageCrudController.php
@@ -4,6 +4,11 @@
namespace Skyeng\MarketingCmsBundle\UI\Controller\Admin;
+use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
+use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
+use EasyCorp\Bundle\EasyAdminBundle\Config\Option\EA;
+use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
+use Skyeng\MarketingCmsBundle\Domain\Entity\MediaFile;
use Skyeng\MarketingCmsBundle\Domain\Entity\Page;
use Skyeng\MarketingCmsBundle\Domain\Entity\PageOpenGraphData;
use Skyeng\MarketingCmsBundle\Domain\Entity\PageSeoData;
@@ -38,10 +43,19 @@ class PageCrudController extends AbstractCrudController
*/
private $pageRepository;
- public function __construct(ResourceRepositoryInterface $resourceRepository, PageRepositoryInterface $pageRepository)
- {
+ /**
+ * @var AdminUrlGenerator
+ */
+ private $adminUrlGenerator;
+
+ public function __construct(
+ ResourceRepositoryInterface $resourceRepository,
+ PageRepositoryInterface $pageRepository,
+ AdminUrlGenerator $adminUrlGenerator
+ ) {
$this->resourceRepository = $resourceRepository;
$this->pageRepository = $pageRepository;
+ $this->adminUrlGenerator = $adminUrlGenerator;
}
public static function getEntityFqcn(): string
@@ -59,6 +73,25 @@ public function configureCrud(Crud $crud): Crud
->setPaginatorUseOutputWalkers(true);
}
+ public function configureActions(Actions $actions): Actions
+ {
+ $mediaFilesAction = Action::new('mediaFiles', 'Медиа библиотека', 'fa fa-image')
+ ->linkToUrl(
+ $this->adminUrlGenerator
+ ->setController(MediaFileCrudController::class)
+ ->setAction('index')
+ ->generateUrl()
+ )
+ ->setHtmlAttributes(['target' => '_blank'])
+ ->addCssClass('btn')
+ ->addCssClass('btn-secondary');
+
+ $actions->add(Crud::PAGE_EDIT, $mediaFilesAction);
+ $actions->add(Crud::PAGE_NEW, $mediaFilesAction);
+
+ return $actions;
+ }
+
public function configureFields(string $pageName): iterable
{
$resource = ResourceField::new('resource.uri', 'Ссылка');