From d80cda27b115abcc97d12afe3c78342e1dc62e2a Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 13 Feb 2022 14:36:26 +0100 Subject: [PATCH] Fix media paths/references --- Admin/Install/db.json | 17 ++- Controller/ApiController.php | 47 ++++++ Controller/BackendController.php | 14 +- Models/Collection.php | 4 +- Models/CollectionMapper.php | 26 +--- Models/Media.php | 14 +- Models/MediaClass.php | 45 ++++++ Models/MediaMapper.php | 10 +- Models/NullReference.php | 39 +++++ Models/Reference.php | 144 ++++++++++++++++++ Models/ReferenceMapper.php | 30 ++++ .../Components/Media/powerpoint.tpl.php | 14 -- Theme/Backend/media-list.tpl.php | 6 + 13 files changed, 356 insertions(+), 54 deletions(-) create mode 100644 Models/MediaClass.php create mode 100644 Models/NullReference.php create mode 100644 Models/Reference.php create mode 100644 Models/ReferenceMapper.php diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 12eca72..f00eda6 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -87,12 +87,6 @@ "default": null, "null": true }, - "media_path": { - "name": "media_path", - "type": "VARCHAR(255)", - "default": null, - "null": true - }, "media_versioned": { "name": "media_versioned", "type": "TINYINT", @@ -136,8 +130,8 @@ "default": null, "null": true }, - "media_collection": { - "name": "media_collection", + "media_class": { + "name": "media_class", "type": "TINYINT", "default": null, "null": true @@ -148,6 +142,13 @@ "default": null, "null": true }, + "media_source": { + "name": "media_source", + "type": "INT", + "null": true, + "foreignTable": "media", + "foreignKey": "media_id" + }, "media_created_by": { "name": "media_created_by", "type": "INT", diff --git a/Controller/ApiController.php b/Controller/ApiController.php index adb8cd0..65a0eb0 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -520,6 +520,53 @@ final class ApiController extends Controller return $mediaCollection; } + public function createRecursiveMediaCollection(string $basePath, string $path, int $account, string $physicalPath = '') : Collection + { + $status = false; + if (!empty($physicalPath)) { + $status = !\is_dir($physicalPath) ? \mkdir($physicalPath, 0755, true) : true; + } + + $path = \trim($path, '/'); + $paths = \explode('/', $path); + $tempPaths = $paths; + $length = \count($paths); + + $temp = ''; + + /** @var Collection $parentCollection */ + $parentCollection = null; + + for ($i = $length; $i > 0; --$i) { + $temp = '/' . \implode('/', $tempPaths); + + /** @var Collection $parentCollection */ + $parentCollection = CollectionMapper::getParentCollection($temp)->execute(); + if ($parentCollection->getId() > 0) { + break; + } + + \array_pop($tempPaths); + } + + for (; $i < $length; ++$i) { + /* Create collection */ + $childCollection = new Collection(); + $childCollection->name = $paths[$i]; + $childCollection->createdBy = new NullAccount($account); + $childCollection->setVirtualPath('/'. \ltrim($temp, '/')); + $childCollection->setPath('/Modules/Media/Files' . $temp); + + CollectionMapper::create()->execute($childCollection); + CollectionMapper::writer()->createRelationTable('sources', [$childCollection->getId()], $parentCollection->getId()); + + $parentCollection = $childCollection; + $temp .= '/' . $paths[$i]; + } + + return $parentCollection; + } + /** * Api method to create media file. * diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 5ab609e..b3b95f8 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -34,6 +34,7 @@ use phpOMS\Account\PermissionType; use phpOMS\Contract\RenderableInterface; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; +use phpOMS\Utils\StringUtils; use phpOMS\Views\View; /** @@ -131,7 +132,16 @@ final class BackendController extends Controller } if ($collection instanceof Collection && !($collection instanceof NullCollection)) { - $media += $collection->getSources(); + $collectionSources = $collection->getSources(); + foreach ($collectionSources as $source) { + foreach ($media as $obj) { + if ($obj->getId() === $source->getId()) { + continue 2; + } + } + + $media[] = $source; + } /** @var string[] $glob */ $glob = $collection->isAbsolute @@ -148,6 +158,7 @@ final class BackendController extends Controller foreach ($media as $obj) { if ($obj->name === $basename || $obj->name . '.' . $obj->extension === $basename + || StringUtils::endsWith(\realpath($file), $obj->getPath()) ) { continue 2; } @@ -238,6 +249,7 @@ final class BackendController extends Controller } } + $view->addData('account', $this->app->accountManager->get($request->header->account)); $view->addData('media', $media); return $view; diff --git a/Models/Collection.php b/Models/Collection.php index 6580cc6..c0741ea 100755 --- a/Models/Collection.php +++ b/Models/Collection.php @@ -43,10 +43,10 @@ class Collection extends Media implements \Iterator /** * Is collection. * - * @var bool + * @var int * @since 1.0.0 */ - protected bool $collection = true; + public int $class = MediaClass::COLLECTION; /** * Set sources. diff --git a/Models/CollectionMapper.php b/Models/CollectionMapper.php index fd2443c..3a92269 100755 --- a/Models/CollectionMapper.php +++ b/Models/CollectionMapper.php @@ -50,30 +50,6 @@ final class CollectionMapper extends MediaMapper */ public const MODEL = Collection::class; - /** - * Primary table. - * - * @var string - * @since 1.0.0 - */ - public const TABLE = 'media'; - - /** - * Created at. - * - * @var string - * @since 1.0.0 - */ - public const CREATED_AT = 'media_created_at'; - - /** - * Primary field name. - * - * @var string - * @since 1.0.0 - */ - public const PRIMARYFIELD ='media_id'; - /** * Get media based on virtual path. * @@ -102,7 +78,7 @@ final class CollectionMapper extends MediaMapper ->with('createdBy') ->with('tags') ->where('isHidden', $hidden) - ->where('collection', true); + ->where('class', MediaClass::COLLECTION); } /** diff --git a/Models/Media.php b/Models/Media.php index 7ac1bc8..0c79f60 100755 --- a/Models/Media.php +++ b/Models/Media.php @@ -133,6 +133,14 @@ class Media implements \JsonSerializable */ public string $descriptionRaw = ''; + /** + * Resource id. + * + * @var null|Media + * @since 1.0.0 + */ + public ?Media $source = null; + /** * Media encryption nonce. * @@ -158,12 +166,12 @@ class Media implements \JsonSerializable public bool $isHidden = false; /** - * Is collection. + * Media class. * - * @var bool + * @var int * @since 1.0.0 */ - protected bool $collection = false; + public int $class = MediaClass::FILE; /** * Tags. diff --git a/Models/MediaClass.php b/Models/MediaClass.php new file mode 100644 index 0000000..6300945 --- /dev/null +++ b/Models/MediaClass.php @@ -0,0 +1,45 @@ + ['name' => 'media_password', 'type' => 'string', 'internal' => 'password'], 'media_extension' => ['name' => 'media_extension', 'type' => 'string', 'internal' => 'extension'], 'media_size' => ['name' => 'media_size', 'type' => 'int', 'internal' => 'size'], - 'media_collection' => ['name' => 'media_collection', 'type' => 'bool', 'internal' => 'collection'], + 'media_source' => ['name' => 'media_source', 'type' => 'int', 'internal' => 'source'], + 'media_class' => ['name' => 'media_class', 'type' => 'int', 'internal' => 'class'], 'media_created_by' => ['name' => 'media_created_by', 'type' => 'int', 'internal' => 'createdBy', 'readonly' => true], 'media_created_at' => ['name' => 'media_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt', 'readonly' => true], ]; @@ -79,6 +80,10 @@ class MediaMapper extends DataMapperFactory 'mapper' => MediaTypeMapper::class, 'external' => 'media_type', ], + 'source' => [ + 'mapper' => self::class, + 'external' => 'media_source', + ], ]; /** @@ -154,6 +159,7 @@ class MediaMapper extends DataMapperFactory { return self::getAll() ->with('createdBy') + ->with('source') ->with('tags') ->with('tags/title') ->where('virtualPath', $virtualPath) @@ -176,7 +182,9 @@ class MediaMapper extends DataMapperFactory return self::get() ->with('sources') + ->with('source') ->where('virtualPath', $virtualPath) + ->where('class', MediaClass::COLLECTION) ->where('name', $name); } } diff --git a/Models/NullReference.php b/Models/NullReference.php new file mode 100644 index 0000000..c7cc32c --- /dev/null +++ b/Models/NullReference.php @@ -0,0 +1,39 @@ +id = $id; + parent::__construct(); + } +} diff --git a/Models/Reference.php b/Models/Reference.php new file mode 100644 index 0000000..19605a1 --- /dev/null +++ b/Models/Reference.php @@ -0,0 +1,144 @@ +sources = $sources; + } + + /** + * Set sources. + * + * @param Media $source Source + * + * @return void + * + * @since 1.0.0 + */ + public function addSource(Media $source) : void + { + $this->sources[] = $source; + } + + /** + * Get sources. + * + * @return Media[] + * + * @since 1.0.0 + */ + public function getSources() : array + { + return $this->sources; + } + + /** + * Get media element by its name. + * + * @param string $name Name of the media element + * + * @return Media + * + * @since 1.0.0 + */ + public function getSourceByName(string $name) : Media + { + foreach ($this->sources as $source) { + if ($source->name === $name) { + return $source; + } + } + + return new NullMedia(); + } + + /** + * {@inheritdoc} + */ + public function rewind() : void + { + \reset($this->sources); + } + + /** + * {@inheritdoc} + */ + public function current() : Media + { + $current = \current($this->sources); + + return $current === false ? $this : $current; + } + + /** + * {@inheritdoc} + */ + public function key() : ?int + { + return \key($this->sources); + } + + /** + * {@inheritdoc} + */ + public function next() : void + { + \next($this->sources); + } + + /** + * {@inheritdoc} + */ + public function valid() : bool + { + return \current($this->sources) !== false; + } +} diff --git a/Models/ReferenceMapper.php b/Models/ReferenceMapper.php new file mode 100644 index 0000000..678bb8e --- /dev/null +++ b/Models/ReferenceMapper.php @@ -0,0 +1,30 @@ +load(($this->media->isAbsolute ? '' : __DIR__ . '/../../../../../../') . $this->media->getPath()); - -$writer = new Html($presentation); -?> -
-
- save('php://output'); ?> -
-
diff --git a/Theme/Backend/media-list.tpl.php b/Theme/Backend/media-list.tpl.php index 7bad37b..b240034 100755 --- a/Theme/Backend/media-list.tpl.php +++ b/Theme/Backend/media-list.tpl.php @@ -12,6 +12,8 @@ */ declare(strict_types=1); +use Modules\Media\Models\MediaClass; +use Modules\Media\Models\Reference; use phpOMS\System\File\FileUtils; use phpOMS\Uri\UriFactory; use phpOMS\Utils\Converter\FileSizeType; @@ -171,6 +173,10 @@ $next = empty($media) ? '{/prefix}media/list' : '{/prefix}media/list?{?}&id= foreach ($media as $key => $value) : ++$count; + if ($value->class === MediaClass::REFERENCE) { + $value = $value->source; + } + $url = $value->extension === 'collection' ? UriFactory::build('{/prefix}media/list?path=' . \rtrim($value->getVirtualPath(), '/') . '/' . $value->name) : UriFactory::build('{/prefix}media/single?id=' . $value->getId()