Skip to content

Commit

Permalink
Update README, EasyAdmin integration, SQLite support and some other s…
Browse files Browse the repository at this point in the history
…mall fixes
  • Loading branch information
chiqui3d committed Dec 20, 2022
1 parent 5e46a1d commit 21b16cb
Show file tree
Hide file tree
Showing 56 changed files with 1,010 additions and 121 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ tools-update-packages-local: ## Update all tools vendor/dependencies in local
generate-ref-flex: ## Generate reference for flex
$(DOCKER_EXEC_PHP) php -r 'echo bin2hex(random_bytes(20));'


# remember add *.Makefile Configuration -> Editor -> Files Types in PHPSTORM (GNU Makefile)
-include tools/make/docker.Makefile
-include tools/make/composer.Makefile
Expand Down
81 changes: 60 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Table of Contents
* [Retrieve media files in Twig](#retrieve-media-files-in-twig)
* [Responsive images with Twig macro](#responsive-images-with-twig-macro)
* [Standalone button to open the Media File Manager in selection mode](#standalone-button-to-open-the-media-file-manager-in-selection-mode)
* [EasyAdmin integration](#easyadmin-integration)
* [Events](#events)
* [Caveats](#caveats)
* [Extra](#extra)
Expand All @@ -35,6 +36,8 @@ Table of Contents

https://user-images.githubusercontent.com/2461400/208309129-280d4fdb-d3f5-4cb7-bd32-175db6bb6f70.mp4

https://user-images.githubusercontent.com/2461400/208732093-44cf5a21-62f9-4402-bbcf-0cffa4aa56f6.mp4

## Features

* User-friendly interface:
Expand Down Expand Up @@ -67,7 +70,7 @@ https://user-images.githubusercontent.com/2461400/208309129-280d4fdb-d3f5-4cb7-b

* PHP 8.1 or higher
* Symfony 5.4 or higher
* Doctrine ORM
* Doctrine ORM (MySQL, MariaDB, SQLite)
* Imagick or GD extension: **Recommended Imagick** extension because it supports more formats than the GD extension
* Optional compression tools:
* Jpegoptim
Expand Down Expand Up @@ -126,10 +129,21 @@ sudo apt-get install webp
```sh
composer require ranky/media-bundle
```
While creating the recipes for Symfony Flex, here are the 4 steps to follow:

#### Step 1: Enable the bundle in the kernel

Although this step should be done automatically.

If you use Symfony Flex, the config/packages/ranky_media.php config file is created automatically. Otherwise:
```php
# config/bundles.php
return [
// ...
Ranky\MediaBundle\RankyMediaBundle::class => ['all' => true],
];
```

#### Step 1: Create the following file and configure it for your application.
#### Step 2: Create the following file and configure it for your application.

The minimum required configuration is provided, in the [configuration](#configuration) you will see all the options.

Expand All @@ -150,17 +164,8 @@ PHP
;
};
```
#### Step 2: Enable the bundle in the kernel:

```php
# config/bundles.php
return [
// ...
Ranky\MediaBundle\RankyMediaBundle::class => ['all' => true],
];
```

#### Step 3: Import the routes:
#### Step 3: Import the routes

YAML

Expand All @@ -173,7 +178,7 @@ ranky_media:
PHP
```php
```php
# config/routes/ranky_media.php
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

Expand All @@ -185,6 +190,13 @@ return static function (RoutingConfigurator $routes) {
};
```

#### Step 4: Schema update and assets install

```sh
php bin/console doctrine:schema:update --force
php bin/console assets:install
```

## Configuration

### Full configuration with default values
Expand Down Expand Up @@ -296,8 +308,6 @@ This is the driver that will be used for image resizing. The available drivers a
* imagick `ImageResizeDriver::IMAGICK->value`
* gd `ImageResizeDriver::GD->value`

[Caveats](#caveats)

**resize_gif_driver** (enum, default: `GifResizeDriver::NONE->value`)

This is the driver that will be used for GIF image resizing. The available drivers are:
Expand Down Expand Up @@ -354,14 +364,14 @@ It is also possible as we have seen previously that you want to import the route
- { path: ^/admin, roles: ROLE_USER }
- { path: ^/admin/users, roles: ROLE_SUPER_ADMIN }
```
Don't forget to set the [route prefix](#step-1--create-the-following-file-and-configure-it-for-your-application) in the bundle configuration.
Don't forget to set the [route prefix](#step-3--import-the-routes) in the bundle configuration.
### Media File Manager
You can do the same as me and create a page and put the following code.
Note that it is not mandatory to use blocks, you can import the assets as you prefer.
```html
```twig
{% block stylesheets %}
{{- parent() -}}
{{ encore_entry_link_tags('ranky_media', null, 'ranky_media') }}
Expand All @@ -385,8 +395,10 @@ Only one type of form, but with 4 ways to store the data in the database:

#### 1. Single selection. Store the mediaId (Ulid) without association

`media_id` type is a Doctrine ULID type

```php
#[ORM\Column(name: 'media_id', type: Types::INTEGER, nullable: true)]
#[ORM\Column(name: 'media_id', type: 'media_id', nullable: true)]
private ?MediaId $mediaId;
```

Expand Down Expand Up @@ -465,6 +477,7 @@ class MyFormType extends AbstractType
#[ORM\JoinColumn(name: 'page_id', referencedColumnName: 'id')]
#[ORM\InverseJoinColumn(name: 'media_id', referencedColumnName: 'id')]
#[ORM\ManyToMany(targetEntity: Media::class)]
#[ORM\OrderBy(["createdAt" => "DESC"])]
private ?Collection $medias;

public function __construct()
Expand Down Expand Up @@ -576,6 +589,29 @@ The `ranky-media-open-modal` class is required, In order not to conflict with th
});
});
```

### EasyAdmin integration

A [field](templates/preview/easyadmin.html.twig) for EasyAdmin has been created
that integrates the same functionalities previously explained in [Form Types](#form-types)

Here an example with the 4 variations of the form type

```php
use Ranky\MediaBundle\Presentation\Form\EasyAdmin\EARankyMediaFileManagerField;

// ...

public function configureFields(string $pageName): iterable
{
// ...
yield EARankyMediaFileManagerField::new('mediaId');
yield EARankyMediaFileManagerField::new('gallery')->multipleSelection()->modalTitle('Gallery');
yield EARankyMediaFileManagerField::new('media')->association();
yield EARankyMediaFileManagerField::new('medias')->association()->multipleSelection();
}
```

### Events

* PreCreateEvent::NAME
Expand Down Expand Up @@ -610,7 +646,7 @@ class MyEventSubscriber implements EventSubscriberInterface
* Currently, [Uppy](https://github.com/transloadit/uppy) is used to support file uploads through the Media File Manager, and it requires [SSL certificate](#install-local-certificates) or be available via localhost.
See more https://github.com/transloadit/uppy/issues/4133
* If you are using React, you will have a problem because this bundle adds React, and you can have two versions of React on one page. This will be fixed as soon as I registered a package in NPM.
* Currently, Doctrine ORM is required.
* MariaDB, MySQL and SQLite are supported. PostgreSQL is not supported yet. Only a few DQL functions need to be adapted.

## Extra

Expand All @@ -630,8 +666,11 @@ More info https://github.com/FiloSottile/mkcert
You can see how to install PHP extensions and compression tools through Docker in the [Dockerfile](tools/docker/php-fpm/Dockerfile) I used it for testing.



## To Do
* Recipes
* Fix some styles being overridden
* `ORDER BY FIELD` in `WHERE IN` clause
* PostgreSQL support
* Image Editor
* Create NPM package, so you can use/import and not have multiple versions of React
* Add sorting filters
Expand Down
3 changes: 2 additions & 1 deletion config/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@

return static function (RoutingConfigurator $routes): void {

$routes->import('../src/Presentation', 'annotation');
$routes->import('../src/Presentation/Api', 'annotation');
$routes->import('../src/Presentation/BackOffice', 'annotation');
};
6 changes: 5 additions & 1 deletion config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,15 @@
'../src/Common', // Helpers
'../src/Infrastructure/DependencyInjection',
'../src/Domain', // Entity
'../src/Presentation/Form/EasyAdmin', // EasyAdmin
'../src/Application/**/*Request.php', // DTO
]);

$services
->load('Ranky\\MediaBundle\\Presentation\\', '../src/Presentation/*')
->load('Ranky\\MediaBundle\\Presentation\\Api\\', '../src/Presentation/Api/*')
->tag('controller.service_arguments');
$services
->load('Ranky\\MediaBundle\\Presentation\\BackOffice\\', '../src/Presentation/BackOffice/*')
->tag('controller.service_arguments');

// Repositories
Expand Down
3 changes: 2 additions & 1 deletion src/Application/FindMedia/FindMediaByIds.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ public function __construct(
*/
public function __invoke(array $ids): array
{
$mediaIds = array_map(static fn(string $id) => MediaId::fromString($id), $ids);
$results = $this->mediaRepository->findByIds(
...array_map(static fn(string $id) => MediaId::fromString($id), $ids)
...$mediaIds
);

return $this->responseTransformer->mediaCollectionToArrayResponse($results);
Expand Down
11 changes: 7 additions & 4 deletions src/Infrastructure/DependencyInjection/MediaBundleExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
use Ranky\MediaBundle\Infrastructure\Filesystem\Local\LocalFileUrlResolver;
use Ranky\MediaBundle\Infrastructure\Persistence\Dbal\Types\MediaIdType;
use Ranky\MediaBundle\Infrastructure\Persistence\Dbal\Types\ThumbnailCollectionType;
use Ranky\MediaBundle\Infrastructure\Persistence\Dql\Month;
use Ranky\MediaBundle\Infrastructure\Persistence\Dql\SubstringIndex;
use Ranky\MediaBundle\Infrastructure\Persistence\Dql\Year;
use Ranky\MediaBundle\Infrastructure\Persistence\Dql\Mysql\MimeSubType;
use Ranky\MediaBundle\Infrastructure\Persistence\Dql\Mysql\MimeType;
use Ranky\MediaBundle\Infrastructure\Persistence\Dql\Mysql\Month;
use Ranky\MediaBundle\Infrastructure\Persistence\Dql\Mysql\Year;
use Ranky\MediaBundle\Infrastructure\Persistence\Orm\Repository\DoctrineOrmMediaRepository;
use Ranky\MediaBundle\Infrastructure\Persistence\Orm\Repository\DoctrineOrmUserMediaRepository;
use Ranky\MediaBundle\Infrastructure\Validation\UploadedFileValidator;
Expand Down Expand Up @@ -201,6 +202,7 @@ private function checkConfiguration(array $config): void

public function prepend(ContainerBuilder $container): void
{

$container->prependExtensionConfig('twig', [
'form_themes' => [
'@RankyMedia/form.html.twig',
Expand Down Expand Up @@ -234,7 +236,8 @@ public function prepend(ContainerBuilder $container): void
'orm' => [
'dql' => [
'string_functions' => [
'SUBSTRING_INDEX' => SubstringIndex::class,
'MIME_TYPE' => MimeType::class,
'MIME_SUBTYPE' => MimeSubType::class,
],
'datetime_functions' => [
'YEAR' => Year::class,
Expand Down
7 changes: 4 additions & 3 deletions src/Infrastructure/Filesystem/Local/LocalFileRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ public function rename(string $oldPathFileName, string $newPathFileName): void
if (!\file_exists($oldPathFileName)) {
throw new RenameFileException(
\sprintf(
'File did not find when trying to rename the file %s',
$oldPathFileName
)
'File did not find when trying to rename the file %s',
$oldPathFileName
)
);
}
$this->makeDirectory($newPathFileName);

if (!\rename($oldPathFileName, $newPathFileName)) {
throw new RenameFileException(
Expand Down
16 changes: 16 additions & 0 deletions src/Infrastructure/Persistence/Dql/DqlFunctionsFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Ranky\MediaBundle\Infrastructure\Persistence\Dql;

/**
* @phpstan-type DqlFunctions = array<"string_functions"|"datetime_functions"|"numeric_functions", array<string, class-string<\Doctrine\ORM\Query\AST\Functions\FunctionNode>>>
*/
interface DqlFunctionsFactory
{
/**
* @return DqlFunctions
*/
public static function functions(): array;
}
64 changes: 64 additions & 0 deletions src/Infrastructure/Persistence/Dql/DqlFunctionsManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);


namespace Ranky\MediaBundle\Infrastructure\Persistence\Dql;

/**
* @phpstan-import-type DqlFunctions from DqlFunctionsFactory
*/
class DqlFunctionsManager
{
public const MYSQL = 'mysql';
public const SQLITE = 'sqlite';
public const DRIVERS = [
self::MYSQL,
self::SQLITE,
];

/**
* @param string $driver
* @return DqlFunctions
*/
public static function getFunctionsByDriver(string $driver): array
{
return match ($driver) {
self::MYSQL => MysqlDqlFunctionsFactory::functions(),
self::SQLITE => SqliteDqlFunctionsFactory::functions(),
default => throw new \InvalidArgumentException(
\sprintf(
'Invalid database driver %s. Available drivers: %s',
$driver,
\implode(',', \array_keys(self::DRIVERS))
)
),
};
}

/**
* @param string $classPlatform
* @return DqlFunctions
*/
public static function getFunctionsByClassPlatform(string $classPlatform): array
{
$classPlatform = \mb_strtolower($classPlatform);

/** @see \Doctrine\DBAL\Platforms\AbstractPlatform */
return match (true) {
(\str_contains($classPlatform, 'mysql') || \str_contains(
$classPlatform,
'mariadb'
)) => MysqlDqlFunctionsFactory::functions(),
(\str_contains($classPlatform, 'sqlite')) => SqliteDqlFunctionsFactory::functions(),
default => throw new \InvalidArgumentException(
\sprintf(
'Invalid database driver %s. Available drivers: %s',
$classPlatform,
\implode(',', \array_keys(self::DRIVERS))
)
),
};
}

}
Loading

0 comments on commit 21b16cb

Please sign in to comment.