diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 80fb4cc..8a89b19 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -1,4 +1,53 @@ { + "media_type": { + "name": "media_type", + "fields": { + "media_type_id": { + "name": "media_type_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "media_type_name": { + "name": "media_type_name", + "type": "VARCHAR(255)", + "null": false + } + } + }, + "media_type_l11n": { + "name": "media_type_l11n", + "fields": { + "media_type_l11n_id": { + "name": "media_type_l11n_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "media_type_l11n_title": { + "name": "media_type_l11n_title", + "type": "VARCHAR(255)", + "null": false + }, + "media_type_l11n_type": { + "name": "media_type_l11n_type", + "type": "INT", + "null": false, + "foreignTable": "media_type", + "foreignKey": "media_type_id" + }, + "media_type_l11n_language": { + "name": "media_type_l11n_language", + "type": "VARCHAR(2)", + "default": null, + "null": true, + "foreignTable": "language", + "foreignKey": "language_639_1" + } + } + }, "media": { "name": "media", "fields": { @@ -16,8 +65,10 @@ }, "media_type": { "name": "media_type", - "type": "VARCHAR(255)", - "null": false + "type": "INT", + "null": true, + "foreignTable": "media_type", + "foreignKey": "media_type_id" }, "media_description": { "name": "media_description", diff --git a/Admin/Installer.php b/Admin/Installer.php index 14e35c8..d6c1b09 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -17,6 +17,10 @@ namespace Modules\Media\Admin; use Modules\Admin\Models\AccountMapper; use Modules\Admin\Models\NullAccount; use Modules\Media\Controller\ApiController; +use Modules\Media\Models\MediaType; +use Modules\Media\Models\MediaTypeMapper; +use Modules\Media\Models\MediaTypeL11n; +use Modules\Media\Models\MediaTypeL11nMapper; use Modules\Media\Models\Collection; use Modules\Media\Models\CollectionMapper; use Modules\Media\Models\Media; @@ -111,6 +115,7 @@ final class Installer extends InstallerAbstract $result = [ 'collection' => [], 'upload' => [], + 'type' => [], ]; \mkdir(__DIR__ . '/tmp'); @@ -122,6 +127,9 @@ final class Installer extends InstallerAbstract case 'upload': $result['upload'][] = self::uploadMedia($app->dbPool, $media); break; + case 'type': + $result['type'][] = self::createType($app->dbPool, $media); + break; default: } } @@ -166,6 +174,33 @@ final class Installer extends InstallerAbstract return $collection; } + /** + * Create type. + * + * @param DatabasePool $dbPool Database instance + * @param array $data Media info + * + * @return MediaType + * + * @since 1.0.0 + */ + private static function createType(DatabasePool $dbPool, array $data) : MediaType + { + $type = new MediaType(); + $type->name = $data['name'] ?? ''; + + $id = MediaTypeMapper::create($type); + + foreach ($data['l11n'] as $l11n) { + $l11n = new MediaTypeL11n($l11n['title'], $l11n['lang']); + $l11n->type = $id; + + MediaTypeL11nMapper::create($l11n); + } + + return $type; + } + /** * Upload media. * @@ -224,12 +259,12 @@ final class Installer extends InstallerAbstract $media = new Media(); $media->setPath(ApiController::normalizeDbPath($data['path']) . '/' . $uFile['filename']); - $media->name = $uFile['filename']; + $media->name = !empty($uFile['name']) ? $uFile['name'] : $uFile['filename']; $media->size = $uFile['size']; $media->createdBy = new NullAccount((int) $data['user'] ?? 1); $media->extension = $uFile['extension']; - $media->setVirtualPath((string) ($data['virtualPath'] ?? '/') . '/' . $data['name']); - $media->type = $data['media_type'] ?? ''; // = identifier for modules + $media->setVirtualPath((string) ($data['virtualPath'] ?? '/')); + $media->type = $data['media_type'] ?? null; // = identifier for modules MediaMapper::create($media); diff --git a/Admin/Routes/Web/Api.php b/Admin/Routes/Web/Api.php index 2dbc334..80554ce 100755 --- a/Admin/Routes/Web/Api.php +++ b/Admin/Routes/Web/Api.php @@ -1,4 +1,16 @@ -getData('id')); + if (((int) $request->getData('id')) !== 0) { + /** @var Media $media */ + $media = MediaMapper::get((int) $request->getData('id')); + } else { + $path = \urldecode($request->getData('path')); + $media = new NullMedia(); + if (\is_file(__DIR__ . '/../../../' . \ltrim($path, '\\/'))) { + $name = \explode('.', \basename($path)); + + $media->name = $name[0]; + $media->extension = $name[1] ?? ''; + $media->setVirtualPath(\dirname($path)); + $media->setPath('/' . \ltrim($path, '\\/')); + $media->isAbsolute = false; + } + } $view = $this->createView($media, $request, $response); $this->setMediaResponseHeader($view, $media, $request, $response); diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 217c024..589c248 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -145,7 +145,7 @@ final class BackendController extends Controller $pathinfo = \pathinfo($file); $localMedia = new Media(); - $localMedia->name = $pathinfo['filename']; + $localMedia->name = $pathinfo['basename']; $localMedia->extension = \is_dir($file) ? 'collection' : $pathinfo['extension'] ?? ''; $localMedia->setVirtualPath($path); $localMedia->createdBy = new Account(); diff --git a/Models/Media.php b/Models/Media.php index 6fcf41a..b0f0ab7 100755 --- a/Models/Media.php +++ b/Models/Media.php @@ -48,10 +48,10 @@ class Media implements \JsonSerializable /** * Type. * - * @var string + * @var null|int|MediaType * @since 1.0.0 */ - public string $type = ''; + public null|int|MediaType $type = null; /** * Extension. diff --git a/Models/MediaMapper.php b/Models/MediaMapper.php index 0eda17e..2b4086c 100755 --- a/Models/MediaMapper.php +++ b/Models/MediaMapper.php @@ -38,7 +38,7 @@ class MediaMapper extends DataMapperAbstract protected static array $columns = [ 'media_id' => ['name' => 'media_id', 'type' => 'int', 'internal' => 'id'], 'media_name' => ['name' => 'media_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], - 'media_type' => ['name' => 'media_type', 'type' => 'string', 'internal' => 'type'], + 'media_type' => ['name' => 'media_type', 'type' => 'int', 'internal' => 'type'], 'media_description' => ['name' => 'media_description', 'type' => 'string', 'internal' => 'description', 'autocomplete' => true], 'media_description_raw' => ['name' => 'media_description_raw', 'type' => 'string', 'internal' => 'descriptionRaw'], 'media_versioned' => ['name' => 'media_versioned', 'type' => 'bool', 'internal' => 'isVersioned'], @@ -68,6 +68,19 @@ class MediaMapper extends DataMapperAbstract ], ]; + /** + * Belongs to. + * + * @var array + * @since 1.0.0 + */ + protected static array $ownsOne = [ + 'type' => [ + 'mapper' => MediaTypeMapper::class, + 'external' => 'media_type', + ], + ]; + /** * Has many relation. * diff --git a/Models/MediaType.php b/Models/MediaType.php new file mode 100644 index 0000000..833859f --- /dev/null +++ b/Models/MediaType.php @@ -0,0 +1,118 @@ +id; + } + + /** + * @return string + * + * @since 1.0.0 + */ + public function getL11n() : string + { + return $this->title instanceof MediaTypeL11n ? $this->title->title : $this->title; + } + + /** + * Set title + * + * @param string|MediaTypeL11n $title Media article title + * @param string $lang Language + * + * @return void + * + * @since 1.0.0 + */ + public function setL11n(string | MediaTypeL11n $title, string $lang = ISO639x1Enum::_EN) : void + { + if ($title instanceof MediaTypeL11n) { + $this->title = $title; + } elseif (isset($this->title) && $this->title instanceof MediaTypeL11n) { + $this->title->title = $title; + } else { + $this->title = new MediaTypeL11n(); + $this->title->title = $title; + $this->title->setLanguage($lang); + } + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + 'title' => $this->title, + 'name' => $this->name, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() + { + return $this->toArray(); + } +} diff --git a/Models/MediaTypeL11n.php b/Models/MediaTypeL11n.php new file mode 100644 index 0000000..2e63913 --- /dev/null +++ b/Models/MediaTypeL11n.php @@ -0,0 +1,133 @@ +title = $title; + $this->language = $language; + } + + /** + * Get id + * + * @return int + * + * @since 1.0.0 + */ + public function getId() : int + { + return $this->id; + } + + /** + * Get language + * + * @return string + * + * @since 1.0.0 + */ + public function getLanguage() : string + { + return $this->language; + } + + /** + * Set language + * + * @param string $language Language + * + * @return void + * + * @since 1.0.0 + */ + public function setLanguage(string $language) : void + { + $this->language = $language; + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + 'title' => $this->title, + 'type' => $this->type, + 'language' => $this->language, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() + { + return $this->toArray(); + } +} diff --git a/Models/MediaTypeL11nMapper.php b/Models/MediaTypeL11nMapper.php new file mode 100644 index 0000000..e70e8c7 --- /dev/null +++ b/Models/MediaTypeL11nMapper.php @@ -0,0 +1,57 @@ + + * @since 1.0.0 + */ + protected static array $columns = [ + 'media_type_l11n_id' => ['name' => 'media_type_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'media_type_l11n_title' => ['name' => 'media_type_l11n_title', 'type' => 'string', 'internal' => 'title', 'autocomplete' => true], + 'media_type_l11n_type' => ['name' => 'media_type_l11n_type', 'type' => 'int', 'internal' => 'type'], + 'media_type_l11n_language' => ['name' => 'media_type_l11n_language', 'type' => 'string', 'internal' => 'language'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + protected static string $table = 'media_type_l11n'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + protected static string $primaryField = 'media_type_l11n_id'; +} diff --git a/Models/MediaTypeMapper.php b/Models/MediaTypeMapper.php new file mode 100644 index 0000000..1ae9b69 --- /dev/null +++ b/Models/MediaTypeMapper.php @@ -0,0 +1,80 @@ + + * @since 1.0.0 + */ + protected static array $columns = [ + 'media_type_id' => ['name' => 'media_type_id', 'type' => 'int', 'internal' => 'id'], + 'media_type_name' => ['name' => 'media_type_name', 'type' => 'string', 'internal' => 'name'], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + protected static array $hasMany = [ + 'title' => [ + 'mapper' => MediaTypeL11nMapper::class, + 'table' => 'media_type_l11n', + 'self' => 'media_type_l11n_type', + 'column' => 'title', + 'conditional' => true, + 'external' => null, + ], + ]; + + /** + * Model to use by the mapper. + * + * @var string + * @since 1.0.0 + */ + protected static string $model = MediaType::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + protected static string $table = 'media_type'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + protected static string $primaryField = 'media_type_id'; +} diff --git a/Models/NullMediaType.php b/Models/NullMediaType.php new file mode 100644 index 0000000..c07a7fe --- /dev/null +++ b/Models/NullMediaType.php @@ -0,0 +1,38 @@ +id = $id; + } +} diff --git a/Models/NullMediaTypeL11n.php b/Models/NullMediaTypeL11n.php new file mode 100644 index 0000000..3183fc5 --- /dev/null +++ b/Models/NullMediaTypeL11n.php @@ -0,0 +1,39 @@ +id = $id; + parent::__construct(); + } +} diff --git a/Theme/Api/render.tpl.php b/Theme/Api/render.tpl.php index 2a35379..5227072 100755 --- a/Theme/Api/render.tpl.php +++ b/Theme/Api/render.tpl.php @@ -17,6 +17,8 @@ declare(strict_types=1); $media = $this->getData('media'); +$t = ($media->isAbsolute ? '' : __DIR__ . '/../../../../') . $media->getPath(); + $fp = \fopen(($media->isAbsolute ? '' : __DIR__ . '/../../../../') . $media->getPath(), 'r'); \fpassthru($fp); \fclose($fp); diff --git a/Theme/Backend/Components/Media/image.tpl.php b/Theme/Backend/Components/Media/image.tpl.php index 9d11252..80b030a 100755 --- a/Theme/Backend/Components/Media/image.tpl.php +++ b/Theme/Backend/Components/Media/image.tpl.php @@ -6,7 +6,10 @@ use phpOMS\Uri\UriFactory;
- <?= $this->printHtml($this->media->name); ?> + <?= $this->printHtml($this->media->name); ?>
\ No newline at end of file