mirror of
https://github.com/Karaka-Management/oms-Media.git
synced 2026-02-17 17:58:40 +00:00
rename virtual path and allow loading by virtual path
This commit is contained in:
parent
f2b87ea482
commit
1e0cf2fabc
|
|
@ -107,12 +107,11 @@ final class BackendController extends Controller
|
||||||
$view = new View($this->app->l11nManager, $request, $response);
|
$view = new View($this->app->l11nManager, $request, $response);
|
||||||
$view->setTemplate('/Modules/Media/Theme/Backend/media-list');
|
$view->setTemplate('/Modules/Media/Theme/Backend/media-list');
|
||||||
|
|
||||||
$path = (string) ($request->getData('path') ?? '/');
|
$path = \str_replace('+', ' ', (string) ($request->getData('path') ?? '/'));
|
||||||
|
|
||||||
/** @var Media[] $media */
|
/** @var Media[] $media */
|
||||||
$media = MediaMapper::getByVirtualPath(\str_replace('+', ' ', $path));
|
$media = MediaMapper::getByVirtualPath($path);
|
||||||
|
$collection = CollectionMapper::getParentCollection($path);
|
||||||
$collection = CollectionMapper::getParentCollection(\str_replace('+', ' ', $path));
|
|
||||||
|
|
||||||
if (\is_array($collection) && \is_dir(__DIR__ . '/../Files' . $path)) {
|
if (\is_array($collection) && \is_dir(__DIR__ . '/../Files' . $path)) {
|
||||||
$collection = new Collection();
|
$collection = new Collection();
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,14 @@ class Collection extends Media implements \Iterator
|
||||||
*/
|
*/
|
||||||
protected string $extension = 'collection';
|
protected string $extension = 'collection';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is collection.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
protected int $collection = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Modules\Media\Models;
|
namespace Modules\Media\Models;
|
||||||
|
|
||||||
|
use phpOMS\DataStorage\Database\RelationType;
|
||||||
|
use Modules\Admin\Models\Account;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapper class.
|
* Mapper class.
|
||||||
*
|
*
|
||||||
|
|
@ -70,4 +73,106 @@ final class CollectionMapper extends MediaMapper
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
protected static string $primaryField = 'media_id';
|
protected static string $primaryField = 'media_id';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get media based on virtual path.
|
||||||
|
*
|
||||||
|
* The virtual path is equivalent to the directory path on a file system.
|
||||||
|
*
|
||||||
|
* A media model also has a file path, this however doesn't have to be the same as the virtual path
|
||||||
|
* and in fact most of the time it is different. This is because the location on a hard drive or web
|
||||||
|
* drive should not have any impact on the media file/media structure in the application.
|
||||||
|
*
|
||||||
|
* As a result media files are structured by virutal path in the app, by file path on the file system
|
||||||
|
* and by Collections which can have sub-collections as well. Collections allow to reference files
|
||||||
|
* in a different virtual path and are therfore similar to "symlinks", except that they don't reference
|
||||||
|
* a file but create a new virtual media model which groups other media models together in a new virtual
|
||||||
|
* path if so desired without deleting or moving the orginal media files.
|
||||||
|
*
|
||||||
|
* @param string $virtualPath Virtual path
|
||||||
|
* @param bool $hidden Get hidden files
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function getByVirtualPath(string $virtualPath = '/', bool $hidden = false) : array
|
||||||
|
{
|
||||||
|
$depth = 3;
|
||||||
|
$query = self::getQuery();
|
||||||
|
$query->where(self::$table . '_' . $depth . '.media_virtual', '=', $virtualPath);
|
||||||
|
$query->where(self::$table . '_' . $depth . '.media_collection', '=', 1);
|
||||||
|
|
||||||
|
if ($hidden === false) {
|
||||||
|
$query->andWhere(self::$table . '_' . $depth . '.media_hidden', '=', (int) $hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::getAllByQuery($query, RelationType::ALL, $depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get collections and optionally hard drive directories.
|
||||||
|
*
|
||||||
|
* @param string $virtualPath Virtual path
|
||||||
|
* @param bool $showDirectories Show local hard drive directories
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function getCollectionsByPath(string $path, bool $showDirectories = false) : array
|
||||||
|
{
|
||||||
|
$collection = CollectionMapper::getByVirtualPath($path);
|
||||||
|
$parent = [];
|
||||||
|
|
||||||
|
if ($showDirectories) {
|
||||||
|
$parent = CollectionMapper::getParentCollection($path);
|
||||||
|
if (\is_array($parent) && \is_dir(__DIR__ . '/../../Media/Files' . $path)) {
|
||||||
|
$parent = new Collection();
|
||||||
|
$parent->setName(\basename($path));
|
||||||
|
$parent->setVirtualPath(\dirname($path));
|
||||||
|
$parent->setPath(\dirname($path));
|
||||||
|
$parent->setAbsolute(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($parent instanceof Collection) {
|
||||||
|
$collection += $parent->getSources();
|
||||||
|
|
||||||
|
/** @var string[] $glob */
|
||||||
|
$glob = $parent->isAbsolute()
|
||||||
|
? $parent->getPath() . '/' . $parent->getName() . '/*'
|
||||||
|
: \glob(__DIR__ . '/../Files/' . \rtrim($parent->getPath(), '/') . '/' . $parent->getName() . '/*');
|
||||||
|
$glob = $glob === false ? [] : $glob;
|
||||||
|
|
||||||
|
foreach ($glob as $file) {
|
||||||
|
if (!\is_dir($file)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($collection as $obj) {
|
||||||
|
if (($obj->getExtension() !== 'collection'
|
||||||
|
&& !empty($obj->getExtension())
|
||||||
|
&& $obj->getName() . '.' . $obj->getExtension() === \basename($file))
|
||||||
|
|| ($obj->getExtension() === 'collection'
|
||||||
|
&& $obj->getName() === \basename($file))
|
||||||
|
) {
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pathinfo = \pathinfo($file);
|
||||||
|
|
||||||
|
$localMedia = new Collection();
|
||||||
|
$localMedia->setName($pathinfo['filename']);
|
||||||
|
$localMedia->setExtension(\is_dir($file) ? 'collection' : $pathinfo['extension'] ?? '');
|
||||||
|
$localMedia->setVirtualPath($path);
|
||||||
|
$localMedia->setCreatedBy(new Account());
|
||||||
|
|
||||||
|
$collection[] = $localMedia;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$collection, $parent];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,14 @@ class Media implements \JsonSerializable
|
||||||
*/
|
*/
|
||||||
protected bool $hidden = false;
|
protected bool $hidden = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is collection.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
protected int $collection = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ class MediaMapper extends DataMapperAbstract
|
||||||
'media_password' => ['name' => 'media_password', 'type' => 'string', 'internal' => 'password'],
|
'media_password' => ['name' => 'media_password', 'type' => 'string', 'internal' => 'password'],
|
||||||
'media_extension' => ['name' => 'media_extension', 'type' => 'string', 'internal' => 'extension'],
|
'media_extension' => ['name' => 'media_extension', 'type' => 'string', 'internal' => 'extension'],
|
||||||
'media_size' => ['name' => 'media_size', 'type' => 'int', 'internal' => 'size'],
|
'media_size' => ['name' => 'media_size', 'type' => 'int', 'internal' => 'size'],
|
||||||
|
'media_collection' => ['name' => 'media_collection', 'type' => 'int', 'internal' => 'collection'],
|
||||||
'media_created_by' => ['name' => 'media_created_by', 'type' => 'int', 'internal' => 'createdBy', 'readonly' => true],
|
'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],
|
'media_created_at' => ['name' => 'media_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt', 'readonly' => true],
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,9 @@ echo $this->getData('nav')->render();
|
||||||
<tr><td><?= $this->getHtml('Name'); ?><td class="wf-100"><?= $this->printHtml($media->getName()); ?>
|
<tr><td><?= $this->getHtml('Name'); ?><td class="wf-100"><?= $this->printHtml($media->getName()); ?>
|
||||||
<tr><td><?= $this->getHtml('Size'); ?><td class="wf-100"><?= $this->printHtml($media->getSize()); ?>
|
<tr><td><?= $this->getHtml('Size'); ?><td class="wf-100"><?= $this->printHtml($media->getSize()); ?>
|
||||||
<tr><td><?= $this->getHtml('Created'); ?><td><?= $this->printHtml($media->getCreatedAt()->format('Y-m-d')); ?>
|
<tr><td><?= $this->getHtml('Created'); ?><td><?= $this->printHtml($media->getCreatedAt()->format('Y-m-d')); ?>
|
||||||
<tr><td><?= $this->getHtml('Creator'); ?><td><a href="<?= UriFactory::build('{/prefix}profile/single?for=' . $media->getCreatedBy()->getId()); ?>"><?= $this->printHtml($media->getCreatedBy()->getName2() . ', ' . $media->getCreatedBy()->getName1()); ?></a>
|
<tr><td><?= $this->getHtml('Creator'); ?><td><a href="<?= UriFactory::build('{/prefix}profile/single?for=' . $media->getCreatedBy()->getId()); ?>"><?= $this->printHtml(
|
||||||
|
\ltrim($media->getCreatedBy()->getName2() . ', ' . $media->getCreatedBy()->getName1(), ', ')
|
||||||
|
); ?></a>
|
||||||
<tr><td colspan="2"><?= $this->getHtml('Description'); ?>
|
<tr><td colspan="2"><?= $this->getHtml('Description'); ?>
|
||||||
<tr><td colspan="2"><?= $media->getDescription(); ?>
|
<tr><td colspan="2"><?= $media->getDescription(); ?>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user