added tags on the preview page
added a way to disable autotagging Fixed issue with email content type the uploads page previews are now with a link Disabled logging of 404 errors
This commit is contained in:
parent
afefbfa99d
commit
041bb9fd55
13 changed files with 107 additions and 41 deletions
|
@ -21,6 +21,13 @@ class AdminController extends Controller
|
|||
*/
|
||||
public function system(Request $request, Response $response): Response
|
||||
{
|
||||
$settings = [];
|
||||
foreach ($this->database->query('SELECT `key`, `value` FROM `settings`') as $setting) {
|
||||
$settings[$setting->key] = $setting->value;
|
||||
}
|
||||
|
||||
$settings['default_user_quota'] = humanFileSize($this->getSetting('default_user_quota', stringToBytes('1G')), 0, true);
|
||||
|
||||
return view()->render($response, 'dashboard/system.twig', [
|
||||
'usersCount' => $usersCount = $this->database->query('SELECT COUNT(*) AS `count` FROM `users`')->fetch()->count,
|
||||
'mediasCount' => $mediasCount = $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads`')->fetch()->count,
|
||||
|
@ -32,14 +39,7 @@ class AdminController extends Controller
|
|||
'forced_lang' => $request->getAttribute('forced_lang'),
|
||||
'php_version' => phpversion(),
|
||||
'max_memory' => ini_get('memory_limit'),
|
||||
'register_enabled' => $this->getSetting('register_enabled', 'off'),
|
||||
'hide_by_default' => $this->getSetting('hide_by_default', 'off'),
|
||||
'copy_url_behavior' => $this->getSetting('copy_url_behavior', 'off'),
|
||||
'quota_enabled' => $this->getSetting('quota_enabled', 'off'),
|
||||
'default_user_quota' => humanFileSize($this->getSetting('default_user_quota', stringToBytes('1G')), 0, true),
|
||||
'recaptcha_enabled' => $this->getSetting('recaptcha_enabled', 'off'),
|
||||
'recaptcha_site_key' => $this->getSetting('recaptcha_site_key'),
|
||||
'recaptcha_secret_key' => $this->getSetting('recaptcha_secret_key'),
|
||||
'settings' => $settings,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class MediaController extends Controller
|
|||
*/
|
||||
public function show(Request $request, Response $response, string $userCode, string $mediaCode, string $token = null): Response
|
||||
{
|
||||
$media = $this->getMedia($userCode, $mediaCode);
|
||||
$media = $this->getMedia($userCode, $mediaCode, true);
|
||||
|
||||
if (!$media || (!$media->published && $this->session->get('user_id') !== $media->user_id && !$this->session->get('admin', false))) {
|
||||
throw new HttpNotFoundException($request);
|
||||
|
@ -112,7 +112,7 @@ class MediaController extends Controller
|
|||
*/
|
||||
public function getRaw(Request $request, Response $response, string $userCode, string $mediaCode, ?string $ext = null): Response
|
||||
{
|
||||
$media = $this->getMedia($userCode, $mediaCode);
|
||||
$media = $this->getMedia($userCode, $mediaCode, false);
|
||||
|
||||
if (!$media || !$media->published && $this->session->get('user_id') !== $media->user_id && !$this->session->get('admin', false)) {
|
||||
throw new HttpNotFoundException($request);
|
||||
|
@ -144,7 +144,7 @@ class MediaController extends Controller
|
|||
*/
|
||||
public function download(Request $request, Response $response, string $userCode, string $mediaCode): Response
|
||||
{
|
||||
$media = $this->getMedia($userCode, $mediaCode);
|
||||
$media = $this->getMedia($userCode, $mediaCode, false);
|
||||
|
||||
if (!$media || !$media->published && $this->session->get('user_id') !== $media->user_id && !$this->session->get('admin', false)) {
|
||||
throw new HttpNotFoundException($request);
|
||||
|
@ -230,7 +230,7 @@ class MediaController extends Controller
|
|||
*/
|
||||
public function deleteByToken(Request $request, Response $response, string $userCode, string $mediaCode, string $token): Response
|
||||
{
|
||||
$media = $this->getMedia($userCode, $mediaCode);
|
||||
$media = $this->getMedia($userCode, $mediaCode, false);
|
||||
|
||||
if (!$media) {
|
||||
throw new HttpNotFoundException($request);
|
||||
|
@ -286,16 +286,28 @@ class MediaController extends Controller
|
|||
* @param $userCode
|
||||
* @param $mediaCode
|
||||
*
|
||||
* @param bool $withTags
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getMedia($userCode, $mediaCode)
|
||||
protected function getMedia($userCode, $mediaCode, $withTags = false)
|
||||
{
|
||||
$mediaCode = pathinfo($mediaCode)['filename'];
|
||||
|
||||
return $this->database->query('SELECT `uploads`.*, `users`.*, `users`.`id` AS `userId`, `uploads`.`id` AS `mediaId` FROM `uploads` INNER JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `user_code` = ? AND `uploads`.`code` = ? LIMIT 1', [
|
||||
$media = $this->database->query('SELECT `uploads`.*, `users`.*, `users`.`id` AS `userId`, `uploads`.`id` AS `mediaId` FROM `uploads` INNER JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `user_code` = ? AND `uploads`.`code` = ? LIMIT 1', [
|
||||
$userCode,
|
||||
$mediaCode,
|
||||
])->fetch();
|
||||
|
||||
if (!$withTags || !$media) {
|
||||
return $media;
|
||||
}
|
||||
|
||||
$media->tags = [];
|
||||
foreach ($this->database->query('SELECT `tags`.`id`, `tags`.`name` FROM `uploads_tags` INNER JOIN `tags` ON `uploads_tags`.`tag_id` = `tags`.`id` WHERE `uploads_tags`.`upload_id` = ?', $media->mediaId) as $tag) {
|
||||
$media->tags[$tag->id] = $tag->name;
|
||||
}
|
||||
|
||||
return $media;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,6 +29,7 @@ class SettingController extends Controller
|
|||
|
||||
// registrations
|
||||
$this->updateSetting('register_enabled', param($request, 'register_enabled', 'off'));
|
||||
$this->updateSetting('auto_tagging', param($request, 'auto_tagging', 'off'));
|
||||
|
||||
// quota
|
||||
$this->updateSetting('quota_enabled', param($request, 'quota_enabled', 'off'));
|
||||
|
|
|
@ -200,7 +200,9 @@ class UploadController extends Controller
|
|||
]);
|
||||
$mediaId = $this->database->getPdo()->lastInsertId();
|
||||
|
||||
$this->autoTag($mediaId, $storagePath);
|
||||
if ($this->getSetting('auto_tagging') === 'on') {
|
||||
$this->autoTag($mediaId, $storagePath);
|
||||
}
|
||||
|
||||
$this->json['message'] = 'OK';
|
||||
$this->json['url'] = urlFor("/{$user->user_code}/{$code}.{$fileInfo['extension']}");
|
||||
|
@ -225,7 +227,7 @@ class UploadController extends Controller
|
|||
$query = make(TagQuery::class);
|
||||
$query->addTag($type, $mediaId);
|
||||
|
||||
if ($type === 'application') {
|
||||
if ($type === 'application' || $subtype === 'gif') {
|
||||
$query->addTag($subtype, $mediaId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ class UserController extends Controller
|
|||
|
||||
if (param($request, 'send_notification') !== null) {
|
||||
$resetToken = null;
|
||||
if (!empty(param($request, 'password'))) {
|
||||
if (empty(param($request, 'password'))) {
|
||||
$resetToken = bin2hex(random_bytes(16));
|
||||
|
||||
$this->database->query('UPDATE `users` SET `reset_token`=? WHERE `id` = ?', [
|
||||
|
@ -284,7 +284,7 @@ class UserController extends Controller
|
|||
*/
|
||||
private function sendCreateNotification($request, $resetToken = null)
|
||||
{
|
||||
if (empty(param($request, 'password'))) {
|
||||
if ($resetToken === null && !empty(param($request, 'password'))) {
|
||||
$message = lang('mail.new_account_text_with_pw', [
|
||||
param($request, 'username'),
|
||||
$this->config['app_name'],
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
namespace App\Exception\Handlers;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Slim\Handlers\ErrorHandler;
|
||||
use Throwable;
|
||||
|
||||
class AppErrorHandler extends ErrorHandler
|
||||
{
|
||||
|
@ -10,4 +13,15 @@ class AppErrorHandler extends ErrorHandler
|
|||
{
|
||||
resolve('logger')->error($error);
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequestInterface $request, Throwable $exception, bool $displayErrorDetails, bool $logErrors, bool $logErrorDetails): ResponseInterface
|
||||
{
|
||||
$response = parent::__invoke($request, $exception, $displayErrorDetails, $logErrors, $logErrorDetails);
|
||||
|
||||
if ($response->getStatusCode() !== 404) {
|
||||
$this->writeToErrorLog();
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ class Mail
|
|||
|
||||
$this->addRequiredHeader('X-Mailer: PHP/'.phpversion());
|
||||
$this->addRequiredHeader('MIME-Version: 1.0');
|
||||
$this->addRequiredHeader('Content-Type: text/html; charset=iso-8859-1');
|
||||
$this->addRequiredHeader('Content-Type: text/plain; charset=iso-8859-1');
|
||||
|
||||
$this->headers .= $this->additionalHeaders;
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ $errorHandler = new AppErrorHandler($app->getCallableResolver(), $app->getRespon
|
|||
$errorHandler->registerErrorRenderer('text/html', HtmlErrorRenderer::class);
|
||||
|
||||
// Add Error Middleware
|
||||
$errorMiddleware = $app->addErrorMiddleware($config['debug'], true, true);
|
||||
$errorMiddleware = $app->addErrorMiddleware($config['debug'], false, true);
|
||||
$errorMiddleware->setDefaultErrorHandler($errorHandler);
|
||||
|
||||
// Load the application routes
|
||||
|
|
|
@ -172,4 +172,5 @@ Click on the following link to go to the login page:
|
|||
'ldap_cant_connect' => 'Can\'t connect to the LDAP auth server.',
|
||||
'upload_max_file_size' => 'The max file size is currently %s.',
|
||||
'no_tags' => 'No tags added',
|
||||
'auto_tagging' => 'Auto upload tagging',
|
||||
];
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
</div>
|
||||
</div>
|
||||
{% if isDisplayableImage(media.mimetype) %}
|
||||
<div class="content-image rounded-top" style="background-image: url({{ urlFor('/' ~ media.user_code ~ '/' ~ media.code ~ '.' ~ media.extension ~ '/raw?height=267') }});"></div>
|
||||
<div class="content-image" style="background-image: url({{ urlFor('/' ~ media.user_code ~ '/' ~ media.code ~ '.' ~ media.extension ~ '/raw?height=267') }});"></div>
|
||||
{% else %}
|
||||
<div class="text-center" style="font-size: 178px;"><i class="far {{ mime2font(media.mimetype) }} mb-4 mt-4"></i></div>
|
||||
{% endif %}
|
||||
|
|
|
@ -62,7 +62,13 @@
|
|||
<div class="form-group row">
|
||||
<label for="register_enabled" class="col-sm-4 col-form-label">{{ lang('register_enabled') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="checkbox" name="register_enabled" data-toggle="toggle" {{ register_enabled == 'on' ? 'checked' }}>
|
||||
<input type="checkbox" name="register_enabled" data-toggle="toggle" {{ settings.register_enabled == 'on' ? 'checked' }}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="auto_tagging" class="col-sm-4 col-form-label">{{ lang('auto_tagging') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="checkbox" name="auto_tagging" data-toggle="toggle" {{ settings.auto_tagging == 'on' ? 'checked' }}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
|
@ -88,7 +94,7 @@
|
|||
<div class="form-group row">
|
||||
<label for="custom_head" class="col-sm-4 col-form-label">{{ lang('custom_head_html') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<textarea name="custom_head" class="form-control text-monospace">{{ customHead|raw }}</textarea>
|
||||
<textarea name="custom_head" class="form-control text-monospace">{{ settings.customHead|raw }}</textarea>
|
||||
<small>{{ lang('custom_head_html_hint') }}</small>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -96,13 +102,13 @@
|
|||
<div class="form-group row">
|
||||
<label for="quota_enabled" class="col-sm-4 col-form-label">{{ lang('quota_enabled') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="checkbox" name="quota_enabled" data-toggle="toggle" {{ quota_enabled == 'on' ? 'checked' }} onchange="document.getElementById('default_user_quota').toggleAttribute('readonly')">
|
||||
<input type="checkbox" name="quota_enabled" data-toggle="toggle" {{ settings.quota_enabled == 'on' ? 'checked' }} onchange="document.getElementById('default_user_quota').toggleAttribute('readonly')">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="default_user_quota" class="col-sm-4 col-form-label">{{ lang('default_user_quota') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" id="default_user_quota" name="default_user_quota" pattern="[0-9]+[K|M|G|T]" title="512M, 2G, 1T, ..." placeholder="1G" value="{{ default_user_quota }}" {{ quota_enabled == 'off' ? 'readonly' }}>
|
||||
<input type="text" class="form-control" id="default_user_quota" name="default_user_quota" pattern="[0-9]+[K|M|G|T]" title="512M, 2G, 1T, ..." placeholder="1G" value="{{ settings.default_user_quota }}" {{ settings.quota_enabled == 'off' ? 'readonly' }}>
|
||||
<small>512M, 2G, 1T, ...</small>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -110,20 +116,20 @@
|
|||
<div class="form-group row">
|
||||
<label for="recaptcha_enabled" class="col-sm-4 col-form-label">{{ lang('recaptcha_enabled') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="checkbox" name="recaptcha_enabled" data-toggle="toggle" {{ recaptcha_enabled == 'on' ? 'checked' }} onchange="document.getElementById('recaptcha_site_key').toggleAttribute('readonly');document.getElementById('recaptcha_secret_key').toggleAttribute('readonly')">
|
||||
<input type="checkbox" name="recaptcha_enabled" data-toggle="toggle" {{ settings.recaptcha_enabled == 'on' ? 'checked' }} onchange="document.getElementById('recaptcha_site_key').toggleAttribute('readonly');document.getElementById('recaptcha_secret_key').toggleAttribute('readonly')">
|
||||
<br><small>{{ lang('only_recaptcha_v3') }}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="recaptcha_site_key" class="col-sm-4 col-form-label">{{ lang('recaptcha_site_key') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" id="recaptcha_site_key" name="recaptcha_site_key" value="{{ recaptcha_site_key }}" {{ recaptcha_enabled == 'off' ? 'readonly' }}>
|
||||
<input type="text" class="form-control" id="recaptcha_site_key" name="recaptcha_site_key" value="{{ settings.recaptcha_site_key }}" {{ settings.recaptcha_enabled == 'off' ? 'readonly' }}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="recaptcha_secret_key" class="col-sm-4 col-form-label">{{ lang('recaptcha_secret_key') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" id="recaptcha_secret_key" name="recaptcha_secret_key" value="{{ recaptcha_secret_key }}" {{ recaptcha_enabled == 'off' ? 'readonly' }}>
|
||||
<input type="text" class="form-control" id="recaptcha_secret_key" name="recaptcha_secret_key" value="{{ settings.recaptcha_secret_key }}" {{ settings.recaptcha_enabled == 'off' ? 'readonly' }}>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-outline-success float-right mt-3">
|
||||
|
|
|
@ -43,29 +43,23 @@
|
|||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% set typeMatched = false %}
|
||||
{% if type is same as ('image') %}
|
||||
{% set typeMatched = true %}
|
||||
<div class="row mb-2">
|
||||
<div class="col-md-12">
|
||||
<img src="{{ url }}/raw" class="img-thumbnail rounded mx-auto d-block" alt="{{ media.filename }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-center">
|
||||
{{ media.filename }}
|
||||
</div>
|
||||
</div>
|
||||
{% elseif type is same as ('text') %}
|
||||
{% set typeMatched = true %}
|
||||
<div class="row mb-2">
|
||||
<div class="col-md-12">
|
||||
<pre><code>{{ media.text }}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-center">
|
||||
{{ media.filename }}
|
||||
</div>
|
||||
</div>
|
||||
{% elseif type is same as ('audio') %}
|
||||
{% set typeMatched = true %}
|
||||
<div class="media-player media-audio">
|
||||
<audio id="player" autoplay controls loop preload="auto">
|
||||
<source src="{{ url }}/raw" type="{{ media.mimetype }}">
|
||||
|
@ -74,6 +68,7 @@
|
|||
</audio>
|
||||
</div>
|
||||
{% elseif type is same as ('video') %}
|
||||
{% set typeMatched = true %}
|
||||
<div class="media-player">
|
||||
<video id="player" autoplay controls loop preload="auto">
|
||||
<source src="{{ url }}/raw" type="{{ media.mimetype }}">
|
||||
|
@ -82,11 +77,13 @@
|
|||
</video>
|
||||
</div>
|
||||
{% elseif media.mimetype is same as ('application/pdf') %}
|
||||
{% set typeMatched = true %}
|
||||
<object type="{{ media.mimetype }}" data="{{ url }}/raw" class="pdf-viewer">
|
||||
Your browser does not support PDF previews.
|
||||
<a href="{{ url }}/download" class="btn btn-dark btn-lg"><i class="fas fa-cloud-download-alt fa-fw"></i> Download</a>
|
||||
</object>
|
||||
{% else %}
|
||||
{% endif %}
|
||||
{% if not typeMatched %}
|
||||
<div class="text-center">
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-12">
|
||||
|
@ -98,17 +95,41 @@
|
|||
<b>{{ media.filename }}</b>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-4">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{{ media.size }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{% if media.tags is not empty %}
|
||||
<div class="row mt-1 mb-2">
|
||||
<div class="col-md-12 text-center">
|
||||
{% for tag_id, tag_name in media.tags %}
|
||||
<span class="badge badge-pill badge-primary shadow-sm mr-1" title="{{ tag_name }}">{{ tag_name }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-12">
|
||||
<a href="{{ url }}/download" class="btn btn-dark btn-lg"><i class="fas fa-cloud-download-alt fa-fw"></i> Download</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="row mt-1">
|
||||
<div class="col-md-12 text-center">
|
||||
{{ media.filename }}
|
||||
</div>
|
||||
</div>
|
||||
{% if media.tags is not empty %}
|
||||
<div class="row mt-2">
|
||||
<div class="col-md-12 text-center">
|
||||
{% for tag_id, tag_name in media.tags %}
|
||||
<span class="badge badge-pill badge-primary shadow-sm mr-1" title="{{ tag_name }}">{{ tag_name }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -11,6 +11,15 @@ var app = {
|
|||
var text = Math.round(uploadProgress) + '%';
|
||||
$('#uploadProgess').css({'width': text}).text(text);
|
||||
},
|
||||
queuecomplete: function () {
|
||||
$('#uploadProgess').css({'width': '0%'}).text('');
|
||||
},
|
||||
success: function (file, response) {
|
||||
$(file.previewElement)
|
||||
.find('.dz-filename')
|
||||
.children()
|
||||
.html('<a href="' + response.url + '">' + file.name + '</a>');
|
||||
},
|
||||
timeout: 0
|
||||
};
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue