undo serialize deprecation and switch to installExternal api calls

This commit is contained in:
Dennis Eichhorn 2022-03-26 15:01:46 +01:00
parent 09c7ab7cfe
commit 9d6da09ef3
8 changed files with 274 additions and 108 deletions

View File

@ -25,15 +25,19 @@ use Modules\Media\Models\MediaType;
use Modules\Media\Models\MediaTypeL11n;
use Modules\Media\Models\MediaTypeL11nMapper;
use Modules\Media\Models\MediaTypeMapper;
use Modules\Media\Models\PathSettings;
use Modules\Media\Models\UploadFile;
use phpOMS\Application\ApplicationAbstract;
use phpOMS\Config\SettingsInterface;
use phpOMS\DataStorage\Database\DatabasePool;
use phpOMS\Message\Http\HttpRequest;
use phpOMS\Message\Http\HttpResponse;
use phpOMS\Module\InstallerAbstract;
use phpOMS\Module\ModuleInfo;
use phpOMS\System\File\Local\Directory;
use phpOMS\System\File\Local\File;
use phpOMS\System\File\PathException;
use phpOMS\Uri\HttpUri;
/**
* Installer class.
@ -114,9 +118,17 @@ final class Installer extends InstallerAbstract
throw new \Exception(); // @codeCoverageIgnore
}
if (\is_dir(__DIR__ . '/tmp')) {
Directory::delete(__DIR__ . '/tmp');
}
$apiApp = new class() extends ApplicationAbstract
{
protected string $appName = 'Api';
};
$apiApp->dbPool = $app->dbPool;
$apiApp->orgId = $app->orgId;
$apiApp->accountManager = $app->accountManager;
$apiApp->appSettings = $app->appSettings;
$apiApp->moduleManager = $app->moduleManager;
$apiApp->eventManager = $app->eventManager;
$result = [
'collection' => [],
@ -124,22 +136,24 @@ final class Installer extends InstallerAbstract
'type' => [],
];
\mkdir(__DIR__ . '/tmp');
if (!\is_dir(__DIR__ . '/../../../temp')) {
\mkdir(__DIR__ . '/../../../temp');
}
foreach ($mediaData as $media) {
switch ($media['type']) {
case 'collection':
$result['collection'][] = self::createCollection($app->dbPool, $media);
$result['collection'][] = self::createCollection($apiApp, $media);
break;
case 'upload':
$result['upload'][] = self::uploadMedia($app->dbPool, $media);
$result['upload'][] = self::uploadMedia($apiApp, $media);
break;
case 'type':
$result['type'][] = self::createType($app->dbPool, $media);
$result['type'][] = self::createType($apiApp, $media);
break;
default:
}
}
Directory::delete(__DIR__ . '/tmp');
return $result;
}
@ -147,61 +161,74 @@ final class Installer extends InstallerAbstract
/**
* Create collection.
*
* @param DatabasePool $dbPool Database instance
* @param ApplicationAbstract $app Application
* @param array $data Media info
*
* @return Collection
*
* @since 1.0.0
*/
private static function createCollection(DatabasePool $dbPool, array $data) : Collection
private static function createCollection(ApplicationAbstract $app, array $data) : Collection
{
/** @var \Modules\Media\Controller\ApiController $module */
$module = $app->moduleManager->getModuleInstance('Media');
if (!isset($data['path'])) {
$dirPath = __DIR__ . '/../../../Modules/Media/Files' . ($data['virtualPath'] ?? '/') . '/' . ($data['name'] ?? '');
$path = '/Modules/Media/Files' . ($data['virtualPath'] ?? '') . '/' . ($data['name'] ?? '');
$path = '/Modules/Media/Files' . ($data['virtualPath'] ?? '') . '/' . ($data['name'] ?? '');
} else {
$dirPath = $data['path'] . '/' . ($data['name'] ?? '');
$path = $data['path'] ?? '/Modules/Media/Files/' . ($data['name'] ?? '');
$path = $data['path'] ?? '/Modules/Media/Files/' . ($data['name'] ?? '');
}
$collection = new Collection();
$collection->name = $data['name'] ?? '';
$collection->setVirtualPath($data['virtualPath'] ?? '/');
$collection->setPath($path);
$collection->createdBy = new NullAccount((int) $data['user'] ?? 1);
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
CollectionMapper::create()->execute($collection);
$request->header->account = 1;
$request->setData('name', $data['name'] ?? '');
$request->setData('virtualpath', $data['virtualPath'] ?? '/');
$request->setData('path', $path);
$request->setData('create_directory', $data['create_directory'] ?? false);
if ($data['create_directory'] && !\is_dir($dirPath)) {
// @todo fix permission mode
\mkdir($dirPath, 0755, true);
}
$module->apiCollectionCreate($request, $response);
return $collection;
return $response->get('')['response'];
}
/**
* Create type.
*
* @param DatabasePool $dbPool Database instance
* @param ApplicationAbstract $app Application
* @param array $data Media info
*
* @return MediaType
*
* @since 1.0.0
*/
private static function createType(DatabasePool $dbPool, array $data) : MediaType
private static function createType(ApplicationAbstract $app, array $data) : MediaType
{
$type = new MediaType();
$type->name = $data['name'] ?? '';
/** @var \Modules\Media\Controller\ApiController $module */
$module = $app->moduleManager->get('Media');
$id = MediaTypeMapper::create()->execute($type);
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request->header->account = 1;
$request->setData('name', $data['name'] ?? '');
$module->apiMediaTypeCreate($request, $response);
$type = $response->get('')['response'];
$id = $type->getId();
foreach ($data['l11n'] as $l11n) {
$l11n = new MediaTypeL11n($l11n['title'], $l11n['lang']);
$l11n->type = $id;
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
MediaTypeL11nMapper::create()->execute($l11n);
$request->header->account = 1;
$request->setData('title', $l11n['title'] ?? '');
$request->setData('lang', $l11n['lang'] ?? null);
$request->setData('type', $id);
$module->apiMediaTypeL11nCreate($request, $response);
}
return $type;
@ -210,31 +237,50 @@ final class Installer extends InstallerAbstract
/**
* Upload media.
*
* @param DatabasePool $dbPool Database instance
* @param ApplicationAbstract $app Application
* @param array $data Media info
*
* @return array
*
* @since 1.0.0
*/
private static function uploadMedia(DatabasePool $dbPool, array $data) : array
private static function uploadMedia(ApplicationAbstract $app, array $data) : array
{
$files = [];
/** @var \Modules\Media\Controller\ApiController $module */
$module = $app->moduleManager->get('Media');
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request->header->account = 1;
$request->setData('path', empty($data['path'] ?? '') ? '' : $data['path']);
$request->setData('virtualPath',
(string) (
$data['create_collection']
? \rtrim($data['virtualPath'] ?? '/', '/') . '/' . ((string) $data['name'] ?? '')
: ($data['virtualPath'] ?? '/')
)
);
$request->setData('type', $data['media_type'] ?? null); // = identifier for modules
$request->setData('pathsettings', $data['path_setting'] ?? PathSettings::FILE_PATH);
$tempPath = __DIR__ . '/../../../temp/';
foreach ($data['files'] as $file) {
if (\is_file(__DIR__ . '/../../..' . $file)) {
File::copy(__DIR__ . '/../../..' . $file, __DIR__ . '/tmp' . $file);
File::copy(__DIR__ . '/../../..' . $file, $tempPath . $file);
$files[] = [
'size' => \filesize(__DIR__ . '/tmp' . $file),
$request->addFile([
'size' => \filesize($tempPath . $file),
'name' => \basename($file),
'tmp_name' => __DIR__ . '/tmp' . $file,
'tmp_name' => $tempPath . $file,
'error' => \UPLOAD_ERR_OK,
];
]);
} if (\is_dir(__DIR__ . '/../../..' . $file)) {
Directory::copy(__DIR__ . '/../../..' . $file, __DIR__ . '/tmp' . $file);
Directory::copy(__DIR__ . '/../../..' . $file, $tempPath . $file);
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator(__DIR__ . '/tmp' . $file . '/', \RecursiveDirectoryIterator::SKIP_DOTS),
new \RecursiveDirectoryIterator($tempPath . $file . '/', \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::SELF_FIRST
);
@ -243,63 +289,32 @@ final class Installer extends InstallerAbstract
continue;
}
$files[] = [
$request->addFile([
'size' => \filesize($item->getPathname()),
'name' => \basename($item->getPathname()),
'tmp_name' => $item->getPathname(),
'error' => \UPLOAD_ERR_OK,
];
]);
}
}
}
$upload = new UploadFile();
$upload->preserveFileName = $data['fixed_names'] ?? true;
$upload->outputDir = empty($data['path'] ?? '')
? ApiController::createMediaPath()
: __DIR__ . '/../../..' . $data['path'];
$status = $upload->upload($files, ($data['fixed_names'] ?? true) ? [] : [$data['name']], true);
$mediaFiles = [];
foreach ($status as $uFile) {
$media = new Media();
$media->setPath(ApiController::normalizeDbPath($data['path']) . '/' . $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'];
// Use defined virtual path if no collection is used.
// If a collection is created modify the virtual path so that it is the virtual path + the collection name for the uploaded files
$media->setVirtualPath((string) (
$data['create_collection']
? \rtrim($data['virtualPath'] ?? '/', '/') . '/' . ((string) $data['name'] ?? '')
: ($data['virtualPath'] ?? '/')
)
);
$media->type = $data['media_type'] ?? null; // = identifier for modules
MediaMapper::create()->execute($media);
$mediaFiles[] = $media;
}
$module->apiMediaUpload($request, $response);
if ($data['create_collection']) {
$collection = new Collection();
$collection->name = (string) $data['name'] ?? '';
$collection->setVirtualPath((string) $data['virtualPath'] ?? '/');
$collection->setPath((string) ($data['path'] ?? '/Modules/Media/Files/' . ((string) $data['name'] ?? '')));
$collection->createdBy = new NullAccount((int) $data['user'] ?? 1);
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$collection->setSources($mediaFiles);
$request->header->account = 1;
$request->setData('name', (string) $data['name'] ?? '');
$request->setData('virtualpath', (string) $data['virtualPath'] ?? '/');
$request->setData('path', (string) ($data['path'] ?? '/Modules/Media/Files/' . ((string) $data['name'] ?? '')));
CollectionMapper::create()->execute($collection);
return [$collection];
$module->apiCollectionCreate($request, $response);
return $response->get('')['resposne'];
}
return $mediaFiles;
return $response->get('')['response'];
}
}

View File

@ -21,6 +21,10 @@ use Modules\Media\Models\CollectionMapper;
use Modules\Media\Models\Media;
use Modules\Media\Models\MediaContent;
use Modules\Media\Models\MediaMapper;
use Modules\Media\Models\MediaType;
use Modules\Media\Models\MediaTypeL11n;
use Modules\Media\Models\MediaTypeL11nMapper;
use Modules\Media\Models\MediaTypeMapper;
use Modules\Media\Models\NullCollection;
use Modules\Media\Models\NullMedia;
use Modules\Media\Models\NullMediaType;
@ -76,16 +80,16 @@ final class ApiController extends Controller
public function apiMediaUpload(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{
$uploads = $this->uploadFiles(
$request->getDataList('names') ?? [],
$request->getDataList('filenames') ?? [],
$request->getFiles(),
$request->header->account,
__DIR__ . '/../../../Modules/Media/Files' . \urldecode((string) ($request->getData('path') ?? '')),
\urldecode((string) ($request->getData('virtualpath') ?? '')),
$request->getData('type', 'int'),
(string) ($request->getData('password') ?? ''),
(string) ($request->getData('encrypt') ?? ''),
(int) ($request->getData('pathsettings') ?? PathSettings::RANDOM_PATH)
names: $request->getDataList('names') ?? [],
fileNames: $request->getDataList('filenames') ?? [],
files: $request->getFiles(),
account: $request->header->account,
basePath: __DIR__ . '/../../../Modules/Media/Files' . \urldecode((string) ($request->getData('path') ?? '')),
virtualPath: \urldecode((string) ($request->getData('virtualpath') ?? '')),
type: $request->getData('type', 'int'),
password: (string) ($request->getData('password') ?? ''),
encryptionKey: (string) ($request->getData('encrypt') ?? ''),
pathSettings: (int) ($request->getData('pathsettings') ?? PathSettings::RANDOM_PATH) // IMPORTANT!!!
);
$ids = [];
@ -166,6 +170,8 @@ final class ApiController extends Controller
$outputDir = '';
$absolute = false;
// @todo sandatize $basePath, we don't know if it might be relative!
if ($pathSettings === PathSettings::RANDOM_PATH) {
$outputDir = self::createMediaPath($basePath);
} elseif ($pathSettings === PathSettings::FILE_PATH) {
@ -177,6 +183,7 @@ final class ApiController extends Controller
$upload = new UploadFile();
$upload->outputDir = $outputDir;
$upload->preserveFileName = empty($fileNames) || \count($fileNames) === \count($files);
$status = $upload->upload($files, $fileNames, $absolute, $encryptionKey);
@ -186,6 +193,8 @@ final class ApiController extends Controller
$created = [];
foreach ($status as &$stat) {
++$nCounter;
// Possible: name != filename (name = database media name, filename = name on the file system)
$stat['name'] = $sameLength ? $names[$nCounter] : $stat['filename'];
$created[] = self::createDbEntry(
@ -450,6 +459,7 @@ final class ApiController extends Controller
$collection = $this->createCollectionFromRequest($request);
$this->createModel($request->header->account, $collection, CollectionMapper::class, 'collection', $request->getOrigin());
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Collection', 'Collection successfully created.', $collection);
}
@ -504,6 +514,7 @@ final class ApiController extends Controller
Directory::create($outputDir . '/' . $request->getData('name'), 0775, true);
}
$dirPath = $outputDir . '/' . $request->getData('name');
$outputDir = \substr($outputDir, \strlen(__DIR__ . '/../../..'));
$mediaCollection->setVirtualPath($virtualPath);
@ -511,6 +522,11 @@ final class ApiController extends Controller
CollectionMapper::create()->execute($mediaCollection);
if (((bool) ($request->getData('create_directory') ?? false))
&& !\is_dir($dirPath)) {
\mkdir($dirPath, 0755, true);
}
return $mediaCollection;
}
@ -613,7 +629,7 @@ final class ApiController extends Controller
public function apiMediaCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{
$path = \urldecode((string) ($request->getData('path') ?? ''));
$virtualPath = \urldecode((string) ($request->getData('virtualpath') ?? ''));
$virtualPath = \urldecode((string) ($request->getData('virtualpath') ?? '/'));
$fileName = (string) ($request->getData('filename') ?? ($request->getData('name') ?? ''));
$fileName .= \strripos($fileName, '.') === false ? '.txt' : '';
@ -843,4 +859,143 @@ final class ApiController extends Controller
$response->header->set('Content-Type', MimeType::M_BIN, true);
}
}
/**
* Validate document create request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool>
*
* @since 1.0.0
*/
private function validateMediaTypeCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['name'] = empty($request->getData('name')))
) {
return $val;
}
return [];
}
/**
* Api method to create document
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiMediaTypeCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{
if (!empty($val = $this->validateMediaTypeCreate($request))) {
$response->set('media_type_create', new FormValidation($val));
$response->header->status = RequestStatusCode::R_400;
return;
}
$type = $this->createDocTypeFromRequest($request);
$this->createModel($request->header->account, $type, MediaTypeMapper::class, 'doc_type', $request->getOrigin());
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Media', 'Media type successfully created', $type);
}
/**
* Method to create task from request.
*
* @param RequestAbstract $request Request
*
* @return EditorDoc
*
* @since 1.0.0
*/
private function createDocTypeFromRequest(RequestAbstract $request) : MediaType
{
$type = new MediaType();
$type->name = $request->getData('name');
if (!empty($request->getData('title'))) {
$type->setL11n($request->getData('title'), $request->getData('lang') ?? $request->getLanguage());
}
return $type;
}
/**
* Validate l11n create request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool>
*
* @since 1.0.0
*/
private function validateMediaTypeL11nCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['title'] = empty($request->getData('title')))
|| ($val['type'] = empty($request->getData('type')))
) {
return $val;
}
return [];
}
/**
* Api method to create tag localization
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiMediaTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{
if (!empty($val = $this->validateMediaTypeL11nCreate($request))) {
$response->set('media_type_l11n_create', new FormValidation($val));
$response->header->status = RequestStatusCode::R_400;
return;
}
$l11nMediaType = $this->createMediaTypeL11nFromRequest($request);
$this->createModel($request->header->account, $l11nMediaType, MediaTypeL11nMapper::class, 'media_type_l11n', $request->getOrigin());
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Category localization successfully created', $l11nMediaType);
}
/**
* Method to create tag localization from request.
*
* @param RequestAbstract $request Request
*
* @return MediaTypeL11n
*
* @since 1.0.0
*/
private function createMediaTypeL11nFromRequest(RequestAbstract $request) : MediaTypeL11n
{
$l11nMediaType = new MediaTypeL11n();
$l11nMediaType->type = (int) ($request->getData('type') ?? 0);
$l11nMediaType->setLanguage((string) (
$request->getData('language') ?? $request->getLanguage()
));
$l11nMediaType->title = (string) ($request->getData('title') ?? '');
return $l11nMediaType;
}
}

View File

@ -14,7 +14,6 @@ declare(strict_types=1);
namespace Modules\Media\Models;
use phpOMS\Contract\ArrayableInterface;
use phpOMS\Localization\ISO639x1Enum;
/**
@ -25,7 +24,7 @@ use phpOMS\Localization\ISO639x1Enum;
* @link https://karaka.app
* @since 1.0.0
*/
class MediaType implements \JsonSerializable, ArrayableInterface
class MediaType implements \JsonSerializable
{
/**
* Article ID.

View File

@ -14,7 +14,6 @@ declare(strict_types=1);
namespace Modules\Media\Models;
use phpOMS\Contract\ArrayableInterface;
use phpOMS\Localization\ISO639x1Enum;
/**
@ -25,7 +24,7 @@ use phpOMS\Localization\ISO639x1Enum;
* @link https://karaka.app
* @since 1.0.0
*/
class MediaTypeL11n implements \JsonSerializable, ArrayableInterface
class MediaTypeL11n implements \JsonSerializable
{
/**
* ID.

View File

@ -29,6 +29,4 @@ abstract class PathSettings extends Enum
public const FILE_PATH = 1;
public const RANDOM_PATH = 2;
public const COLLECTION_PATH = 3;
}

View File

@ -29,6 +29,7 @@ $next = empty($this->media)
<table class="default">
<thead>
<td>
<td><?= $this->getHtml('Path', 'Media'); ?>
<td class="wf-100"><?= $this->getHtml('Name', 'Media'); ?>
<td><?= $this->getHtml('Type', 'Media'); ?>
<td><?= $this->getHtml('Size', 'Media'); ?>
@ -44,6 +45,7 @@ $next = empty($this->media)
?>
<tr data-href="<?= $url; ?>">
<td data-label="<?= $this->getHtml('Type'); ?>"><a href="<?= $url; ?>"><i class="fa fa-<?= $this->printHtml($icon); ?>"></i></a>
<td data-label="<?= $this->getHtml('Path'); ?>"><a class="content" href="<?= UriFactory::build('{/prefix}media/list?{?}&path=' . $value->getVirtualPath()); ?>"><?= $this->printHtml($value->getVirtualPath()); ?></a>
<td data-label="<?= $this->getHtml('Name'); ?>"><a href="<?= $url; ?>"><?= $this->printHtml($value->name); ?></a>
<td data-label="<?= $this->getHtml('Extension'); ?>"><a href="<?= $url; ?>"><?= $this->printHtml($value->extension); ?></a>
<td data-label="<?= $this->getHtml('Size'); ?>"><a href="<?= $url; ?>"><?= $value->size; ?></a>

View File

@ -172,10 +172,6 @@ $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()

View File

@ -36,6 +36,8 @@ $fileIconFunction = function (int $extensionType) : string
return 'file-excel-o';
} elseif ($extensionType === ExtensionType::DIRECTORY) {
return 'folder-open-o';
} elseif ($extensionType === ExtensionType::REFERENCE) {
return 'share';
}
return 'file';