mirror of
https://github.com/Karaka-Management/oms-Media.git
synced 2026-02-04 19:48:42 +00:00
added parsed content field, fixed directory listing bug
This commit is contained in:
parent
2e067f63f0
commit
7227aabc9b
|
|
@ -53,6 +53,23 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"media_parsed": {
|
||||
"name": "media_parsed",
|
||||
"fields": {
|
||||
"media_parsed_id": {
|
||||
"name": "media_parsed_id",
|
||||
"type": "INT",
|
||||
"null": false,
|
||||
"primary": true,
|
||||
"autoincrement": true
|
||||
},
|
||||
"media_parsed_content": {
|
||||
"name": "media_parsed_content",
|
||||
"type": "LONGTEXT",
|
||||
"null": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"media": {
|
||||
"name": "media",
|
||||
"fields": {
|
||||
|
|
@ -142,6 +159,14 @@
|
|||
"default": null,
|
||||
"null": true
|
||||
},
|
||||
"media_content": {
|
||||
"name": "media_content",
|
||||
"type": "INT",
|
||||
"null": true,
|
||||
"default": null,
|
||||
"foreignTable": "media_parsed",
|
||||
"foreignKey": "media_parsed_id"
|
||||
},
|
||||
"media_source": {
|
||||
"name": "media_source",
|
||||
"type": "INT",
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use Modules\Admin\Models\NullAccount;
|
|||
use Modules\Media\Models\Collection;
|
||||
use Modules\Media\Models\CollectionMapper;
|
||||
use Modules\Media\Models\Media;
|
||||
use Modules\Media\Models\MediaContent;
|
||||
use Modules\Media\Models\MediaMapper;
|
||||
use Modules\Media\Models\NullCollection;
|
||||
use Modules\Media\Models\NullMedia;
|
||||
|
|
@ -43,6 +44,11 @@ use phpOMS\System\File\Local\Directory;
|
|||
use phpOMS\System\MimeType;
|
||||
use phpOMS\Utils\Parser\Markdown\Markdown;
|
||||
use phpOMS\Views\View;
|
||||
use PhpOffice\PhpWord\IOFactory;
|
||||
use PhpOffice\PhpWord\Writer\HTML;
|
||||
use phpOMS\Application\ApplicationAbstract;
|
||||
use phpOMS\Autoloader;
|
||||
use phpOMS\Utils\Parser\Pdf\PdfParser;
|
||||
|
||||
/**
|
||||
* Media class.
|
||||
|
|
@ -133,6 +139,7 @@ final class ApiController extends Controller
|
|||
* @param int $pathSettings Settings which describe where the file should be uploaded to (physically)
|
||||
* RANDOM_PATH = random location in the base path
|
||||
* FILE_PATH = combination of base path and virtual path
|
||||
* @param bool $hasAccountRelation The uploaded files should be related to an account
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
|
|
@ -148,7 +155,8 @@ final class ApiController extends Controller
|
|||
int $type = null,
|
||||
string $password = '',
|
||||
string $encryptionKey = '',
|
||||
int $pathSettings = PathSettings::RANDOM_PATH
|
||||
int $pathSettings = PathSettings::RANDOM_PATH,
|
||||
bool $hasAccountRelation = true
|
||||
) : array
|
||||
{
|
||||
if (empty($files)) {
|
||||
|
|
@ -174,12 +182,22 @@ final class ApiController extends Controller
|
|||
|
||||
$sameLength = \count($names) === \count($status);
|
||||
$nCounter = -1;
|
||||
|
||||
$created = [];
|
||||
foreach ($status as &$stat) {
|
||||
++$nCounter;
|
||||
$stat['name'] = $sameLength ? $names[$nCounter] : $stat['filename'];
|
||||
|
||||
$created[] = self::createDbEntry(
|
||||
$stat,
|
||||
$account,
|
||||
$virtualPath,
|
||||
$type,
|
||||
app: $hasAccountRelation ? $this->app : null
|
||||
);
|
||||
}
|
||||
|
||||
return $this->createDbEntries($status, $account, $virtualPath, $type);
|
||||
return $created;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -220,54 +238,6 @@ final class ApiController extends Controller
|
|||
return $basePath . '/_' . $rndPath[0] . $rndPath[1] . $rndPath[2] . $rndPath[3] . '/_' . $rndPath[4] . $rndPath[5] . $rndPath[6] . $rndPath[7];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create database entries for uploaded files
|
||||
*
|
||||
* @param array $status Files
|
||||
* @param int $account Uploader
|
||||
* @param string $virtualPath Virtual path
|
||||
* @param null|int $type Media type (internal categorization = identifier for modules)
|
||||
* @param string $ip Ip
|
||||
*
|
||||
* @return Media[]
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function createDbEntries(
|
||||
array $status,
|
||||
int $account,
|
||||
string $virtualPath = '',
|
||||
int $type = null,
|
||||
string $ip = '127.0.0.1'
|
||||
) : array
|
||||
{
|
||||
$mediaCreated = [];
|
||||
|
||||
foreach ($status as $uFile) {
|
||||
if (($created = self::createDbEntry($uFile, $account, $virtualPath, $type)) !== null) {
|
||||
$mediaCreated[] = $created;
|
||||
|
||||
$this->app->moduleManager->get('Admin')->createAccountModelPermission(
|
||||
new AccountPermission(
|
||||
$account,
|
||||
$this->app->orgId,
|
||||
$this->app->appName,
|
||||
self::NAME,
|
||||
self::NAME,
|
||||
PermissionState::MEDIA,
|
||||
$created->getId(),
|
||||
null,
|
||||
PermissionType::READ | PermissionType::MODIFY | PermissionType::DELETE | PermissionType::PERMISSION
|
||||
),
|
||||
$account,
|
||||
$ip
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $mediaCreated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create db entry for uploaded file
|
||||
*
|
||||
|
|
@ -275,12 +245,20 @@ final class ApiController extends Controller
|
|||
* @param int $account Uploader
|
||||
* @param string $virtualPath Virtual path (not on the hard-drive)
|
||||
* @param null|int $type Media type (internal categorization)
|
||||
* @param ApplicationAbstract $app Should create relation to uploader
|
||||
*
|
||||
* @return null|Media
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function createDbEntry(array $status, int $account, string $virtualPath = '', int $type = null) : ?Media
|
||||
public static function createDbEntry(
|
||||
array $status,
|
||||
int $account,
|
||||
string $virtualPath = '',
|
||||
int $type = null,
|
||||
string $ip = '127.0.0.1',
|
||||
ApplicationAbstract $app = null
|
||||
) : ?Media
|
||||
{
|
||||
if ($status['status'] !== UploadStatus::OK) {
|
||||
return null;
|
||||
|
|
@ -296,11 +274,63 @@ final class ApiController extends Controller
|
|||
$media->setVirtualPath($virtualPath);
|
||||
$media->type = $type === null ? null : new NullMediaType($type);
|
||||
|
||||
if (\is_file($media->getAbsolutePath())) {
|
||||
$content = self::loadFileContent($media->getAbsolutePath(), $media->extension);
|
||||
|
||||
if (!empty($content)) {
|
||||
$media->content = new MediaContent();
|
||||
$media->content->content = $content;
|
||||
}
|
||||
}
|
||||
|
||||
MediaMapper::create()->execute($media);
|
||||
|
||||
if ($app !== null) {
|
||||
$app->moduleManager->get('Admin')->createAccountModelPermission(
|
||||
new AccountPermission(
|
||||
$account,
|
||||
$app->orgId,
|
||||
$app->appName,
|
||||
self::NAME,
|
||||
self::NAME,
|
||||
PermissionState::MEDIA,
|
||||
$media->getId(),
|
||||
null,
|
||||
PermissionType::READ | PermissionType::MODIFY | PermissionType::DELETE | PermissionType::PERMISSION
|
||||
),
|
||||
$account,
|
||||
$ip
|
||||
);
|
||||
}
|
||||
|
||||
return $media;
|
||||
}
|
||||
|
||||
private static function loadFileContent(string $path, string $extension) : string
|
||||
{
|
||||
switch ($extension) {
|
||||
case 'pdf':
|
||||
return PdfParser::pdf2text($path);
|
||||
break;
|
||||
case 'doc':
|
||||
case 'docx':
|
||||
Autoloader::addPath(__DIR__ . '/../../../Resources/');
|
||||
|
||||
$reader = IOFactory::createReader('Word2007');
|
||||
$doc = $reader->load($path);
|
||||
|
||||
$writer = new HTML($doc);
|
||||
return $writer->getContent();
|
||||
break;
|
||||
case 'txt':
|
||||
case 'md':
|
||||
return \file_get_contents($path);
|
||||
break;
|
||||
default:
|
||||
return '';
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the file path
|
||||
*
|
||||
|
|
@ -624,11 +654,18 @@ final class ApiController extends Controller
|
|||
],
|
||||
];
|
||||
|
||||
$created = $this->createDbEntries($status, $request->header->account, $virtualPath, $request->getData('type', 'int'));
|
||||
|
||||
$ids = [];
|
||||
foreach ($created as $file) {
|
||||
$ids[] = $file->getId();
|
||||
foreach ($status as $stat) {
|
||||
$created = self::createDbEntry(
|
||||
$status,
|
||||
$request->header->account,
|
||||
$virtualPath,
|
||||
$request->getData('type', 'int'),
|
||||
$request->getOrigin(),
|
||||
$this->app
|
||||
);
|
||||
|
||||
$ids[] = $created->getId();
|
||||
}
|
||||
|
||||
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Media', 'Media successfully created.', $ids);
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ final class BackendController extends Controller
|
|||
|
||||
$collection = $collectionMapper->execute();
|
||||
|
||||
if (\is_array($collection) && \is_dir(__DIR__ . '/../Files' . $path)) {
|
||||
if ((\is_array($collection) || $collection instanceof NullCollection) && \is_dir(__DIR__ . '/../Files' . $path)) {
|
||||
$collection = new Collection();
|
||||
$collection->name = \basename($path);
|
||||
$collection->setVirtualPath(\dirname($path));
|
||||
|
|
@ -149,6 +149,8 @@ final class BackendController extends Controller
|
|||
: \glob(__DIR__ . '/../Files/' . \trim($collection->getVirtualPath(), '/') . '/' . $collection->name . '/*');
|
||||
$glob = $glob === false ? [] : $glob;
|
||||
|
||||
$unIndexedFiles = [];
|
||||
|
||||
foreach ($glob as $file) {
|
||||
$basename = \basename($file);
|
||||
if ($basename[0] === '_' && \strlen($basename) === 5) {
|
||||
|
|
@ -158,7 +160,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())
|
||||
|| ($obj->getPath() !== '' && StringUtils::endsWith(\realpath($file), $obj->getPath()))
|
||||
) {
|
||||
continue 2;
|
||||
}
|
||||
|
|
@ -172,8 +174,10 @@ final class BackendController extends Controller
|
|||
$localMedia->setVirtualPath($path);
|
||||
$localMedia->createdBy = new Account();
|
||||
|
||||
$media[] = $localMedia;
|
||||
$unIndexedFiles[] = $localMedia;
|
||||
}
|
||||
|
||||
$media = \array_merge($media, $unIndexedFiles);
|
||||
}
|
||||
|
||||
$view->addData('media', $media);
|
||||
|
|
@ -221,6 +225,7 @@ final class BackendController extends Controller
|
|||
->with('createdBy')
|
||||
->with('tags')
|
||||
->with('tags/title')
|
||||
->with('content')
|
||||
->where('id', $id)
|
||||
->where('tags/title/language', $request->getLanguage())
|
||||
->execute();
|
||||
|
|
|
|||
|
|
@ -45,6 +45,14 @@ class Media implements \JsonSerializable
|
|||
*/
|
||||
public string $name = '';
|
||||
|
||||
/**
|
||||
* Content.
|
||||
*
|
||||
* @var null|MediaContent
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public ?MediaContent $content = null;
|
||||
|
||||
/**
|
||||
* Type.
|
||||
*
|
||||
|
|
|
|||
70
Models/MediaContent.php
Normal file
70
Models/MediaContent.php
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
/**
|
||||
* Karaka
|
||||
*
|
||||
* PHP Version 8.0
|
||||
*
|
||||
* @package Modules\Media\Models
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://karaka.app
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Media\Models;
|
||||
|
||||
use Modules\Admin\Models\Account;
|
||||
use Modules\Admin\Models\NullAccount;
|
||||
use Modules\Tag\Models\NullTag;
|
||||
use Modules\Tag\Models\Tag;
|
||||
|
||||
/**
|
||||
* Media class.
|
||||
*
|
||||
* @package Modules\Media\Models
|
||||
* @license OMS License 1.0
|
||||
* @link https://karaka.app
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class MediaContent implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* ID.
|
||||
*
|
||||
* @var int
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected int $id = 0;
|
||||
|
||||
public string $content = '';
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getId() : int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toArray() : array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'content' => $this->content,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
}
|
||||
63
Models/MediaContentMapper.php
Normal file
63
Models/MediaContentMapper.php
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
/**
|
||||
* Karaka
|
||||
*
|
||||
* PHP Version 8.0
|
||||
*
|
||||
* @package Modules\Media\Models
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://karaka.app
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Media\Models;
|
||||
|
||||
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
|
||||
|
||||
/**
|
||||
* Media mapper class.
|
||||
*
|
||||
* @package Modules\Media\Models
|
||||
* @license OMS License 1.0
|
||||
* @link https://karaka.app
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class MediaContentMapper extends DataMapperFactory
|
||||
{
|
||||
/**
|
||||
* Columns.
|
||||
*
|
||||
* @var array<string, array{name:string, type:string, internal:string, autocomplete?:bool, readonly?:bool, writeonly?:bool, annotations?:array}>
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public const COLUMNS = [
|
||||
'media_parsed_id' => ['name' => 'media_parsed_id', 'type' => 'int', 'internal' => 'id'],
|
||||
'media_parsed_content' => ['name' => 'media_parsed_content', 'type' => 'string', 'internal' => 'content'],
|
||||
];
|
||||
|
||||
/**
|
||||
* Model to use by the mapper.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public const MODEL = MediaContent::class;
|
||||
|
||||
/**
|
||||
* Primary table.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public const TABLE = 'media_parsed';
|
||||
|
||||
/**
|
||||
* Primary field name.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public const PRIMARYFIELD ='media_parsed_id';
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ class MediaMapper extends DataMapperFactory
|
|||
'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_content' => ['name' => 'media_content', 'type' => 'int', 'internal' => 'content'],
|
||||
'media_versioned' => ['name' => 'media_versioned', 'type' => 'bool', 'internal' => 'isVersioned'],
|
||||
'media_hidden' => ['name' => 'media_hidden', 'type' => 'bool', 'internal' => 'isHidden'],
|
||||
'media_file' => ['name' => 'media_file', 'type' => 'string', 'internal' => 'path', 'autocomplete' => true],
|
||||
|
|
@ -84,6 +85,10 @@ class MediaMapper extends DataMapperFactory
|
|||
'mapper' => self::class,
|
||||
'external' => 'media_source',
|
||||
],
|
||||
'content' => [
|
||||
'mapper' => MediaContentMapper::class,
|
||||
'external' => 'media_content',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -180,7 +185,7 @@ class MediaMapper extends DataMapperFactory
|
|||
$virtualPath = '/' . \trim(\substr($path, 0, \strripos($path, '/') + 1), '/');
|
||||
$name = \substr($path, \strripos($path, '/') + 1);
|
||||
|
||||
return self::get()
|
||||
return CollectionMapper::get()
|
||||
->with('sources')
|
||||
->with('source')
|
||||
->where('virtualPath', $virtualPath)
|
||||
|
|
|
|||
38
Models/NullMediaContent.php
Normal file
38
Models/NullMediaContent.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* Karaka
|
||||
*
|
||||
* PHP Version 8.0
|
||||
*
|
||||
* @package Modules\Media\Models
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://karaka.app
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Media\Models;
|
||||
|
||||
/**
|
||||
* Media class.
|
||||
*
|
||||
* @package Modules\Media\Models
|
||||
* @license OMS License 1.0
|
||||
* @link https://karaka.app
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class NullMediaContent extends MediaContent
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int $id Model id
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function __construct(int $id = 0)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,20 @@ use \phpOMS\Uri\UriFactory;
|
|||
|
||||
<section id="mediaFile" class="portlet">
|
||||
<div class="portlet-body">
|
||||
<iframe style="min-height: 600px;" data-form="iUiSettings" data-name="iframeHelper" id="iHelperFrame" src="<?= UriFactory::build('{/backend}Resources/mozilla/Pdf/web/viewer.html?{?}&file=' . \urlencode(($this->media->isAbsolute ? '' : '/../../../../') . $this->media->getPath())); ?>" allowfullscreen></iframe>
|
||||
<div id="media" class="tabview tab-2 m-editor">
|
||||
<ul class="tab-links">
|
||||
<li><label tabindex="0" for="media-c-tab-1"><?= $this->getHtml('Preview', 'Media'); ?></label>
|
||||
<li><label tabindex="0" for="media-c-tab-2"><?= $this->getHtml('Content', 'Media'); ?></label>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<input type="radio" id="media-c-tab-1" name="tabular-1" checked>
|
||||
<div class="tab">
|
||||
<iframe style="min-height: 600px;" data-form="iUiSettings" data-name="iframeHelper" id="iHelperFrame" src="<?= UriFactory::build('{/backend}Resources/mozilla/Pdf/web/viewer.html?{?}&file=' . \urlencode(($this->media->isAbsolute ? '' : '/../../../../') . $this->media->getPath())); ?>" allowfullscreen></iframe>
|
||||
</div>
|
||||
<input type="radio" id="media-c-tab-2" name="tabular-1">
|
||||
<div class="tab">
|
||||
<pre class="textContent" data-tpl-text="/media/content" data-tpl-value="/media/content"><?= $this->printHtml($this->media->content->content); ?></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -207,7 +207,7 @@ $next = empty($media) ? '{/prefix}media/list' : '{/prefix}media/list?{?}&id=
|
|||
<td data-label="<?= $this->getHtml('Size'); ?>"><a href="<?= $url; ?>"><?php
|
||||
$size = FileSizeType::autoFormat($value->size);
|
||||
echo $this->printHtml($value->extension !== 'collection' ? \number_format($size[0], 1, '.', ',') . $size[1] : ''); ?></a>
|
||||
<td data-label="<?= $this->getHtml('Creator'); ?>"><a class="content" href="<?= UriFactory::build('{/prefix}profile/single?{?}&for=' . $value->createdBy->getId()); ?>"><?= $this->printHtml($value->createdBy->name1); ?></a>
|
||||
<td data-label="<?= $this->getHtml('Creator'); ?>"><a class="content" href="<?= UriFactory::build('{/prefix}profile/single?{?}&for=' . $value->createdBy->getId()); ?>"><?= $this->printHtml($this->renderUserName('%3$s %2$s %1$s', [$value->createdBy->name1, $value->createdBy->name2, $value->createdBy->name3, $value->createdBy->login ?? ''])); ?></a>
|
||||
<td data-label="<?= $this->getHtml('Created'); ?>"><a href="<?= $url; ?>"><?= $this->printHtml($value->createdAt->format('Y-m-d')); ?></a>
|
||||
<?php endforeach; ?>
|
||||
<?php if ($count === 0) : ?>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user