commit
7f07ecdfad
8 changed files with 91 additions and 1 deletions
|
@ -188,6 +188,43 @@ class MediaController extends Controller
|
|||
return $this->streamMedia($request, $response, $this->storage, $media, 'attachment');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
* @param string $vanity
|
||||
* @param string $id
|
||||
*
|
||||
* @return Response
|
||||
* @throws HttpNotFoundException
|
||||
* @throws HttpBadRequestException
|
||||
*/
|
||||
public function createVanity(Request $request, Response $response, int $id): Response
|
||||
{
|
||||
$media = $this->database->query('SELECT * FROM `uploads` WHERE `id` = ? LIMIT 1', $id)->fetch();
|
||||
|
||||
$vanity = param($request, 'vanity');
|
||||
$vanity = preg_replace('/[^a-z0-9]+/', '-', strtolower($vanity));
|
||||
|
||||
//handle collisions
|
||||
$collision = $this->database->query('SELECT * FROM `uploads` WHERE `code` = ? AND `id` != ? LIMIT 1', [$vanity, $id])->fetch();
|
||||
|
||||
if (!$media) {
|
||||
throw new HttpNotFoundException($request);
|
||||
}
|
||||
|
||||
if ($vanity === '' || $collision) {
|
||||
throw new HttpBadRequestException($request);
|
||||
}
|
||||
|
||||
$this->database->query('UPDATE `uploads` SET `code` = ? WHERE `id` = ?', [$vanity, $media->id]);
|
||||
$media->code = $vanity;
|
||||
$response->getBody()->write(json_encode($media));
|
||||
|
||||
$this->logger->info('User '.$this->session->get('username').' created a vanity link for media '.$media->id);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
|
|
1
app/routes.php
Normal file → Executable file
1
app/routes.php
Normal file → Executable file
|
@ -62,6 +62,7 @@ $app->group('', function (RouteCollectorProxy $group) {
|
|||
|
||||
$group->post('/upload/{id}/publish', [MediaController::class, 'togglePublish'])->setName('upload.publish');
|
||||
$group->post('/upload/{id}/unpublish', [MediaController::class, 'togglePublish'])->setName('upload.unpublish');
|
||||
$group->post('/upload/{id}/vanity', [MediaController::class, 'createVanity'])->setName('upload.vanity');
|
||||
$group->get('/upload/{id}/raw', [MediaController::class, 'getRawById'])->add(AdminMiddleware::class)->setName('upload.raw');
|
||||
$group->map(['GET', 'POST'], '/upload/{id}/delete', [MediaController::class, 'delete'])->setName('upload.delete');
|
||||
|
||||
|
|
3
resources/lang/en.lang.php
Normal file → Executable file
3
resources/lang/en.lang.php
Normal file → Executable file
|
@ -30,6 +30,8 @@ return [
|
|||
'download' => 'Download',
|
||||
'upload' => 'Upload',
|
||||
'delete' => 'Delete',
|
||||
'confirm' => 'Confirm',
|
||||
'vanity_url' => 'Custom URL',
|
||||
'publish' => 'Publish',
|
||||
'hide' => 'Hide',
|
||||
'files' => 'Files',
|
||||
|
@ -58,7 +60,6 @@ return [
|
|||
'reg_date' => 'Registration Date',
|
||||
'none' => 'None',
|
||||
'open' => 'Open',
|
||||
'confirm' => 'Confirmation',
|
||||
'confirm_string' => 'Are you sure?',
|
||||
'installed' => 'Installation completed successfully!',
|
||||
'bad_login' => 'Wrong credentials.',
|
||||
|
|
19
resources/templates/comp/modal_vanity.twig
Executable file
19
resources/templates/comp/modal_vanity.twig
Executable file
|
@ -0,0 +1,19 @@
|
|||
<div class="modal fade" id="modalVanity" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">{{ lang('vanity_url') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input type="text" class="form-control" id="modalVanity-input" maxlength="64">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary media-vanity" id="modalVanity-link"><i class="fas fa-check fa-fw"></i> {{ lang('confirm') }}</button>
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ lang('no') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
2
resources/templates/dashboard/grid.twig
Normal file → Executable file
2
resources/templates/dashboard/grid.twig
Normal file → Executable file
|
@ -28,6 +28,7 @@
|
|||
{% else %}
|
||||
<a class="btn btn-sm btn-info publish-toggle" data-toggle="tooltip" title="{{ lang('publish') }}" data-id="{{ media.id }}" data-published="{{ media.published }}"><i class="fas fa-check-circle"></i></a>
|
||||
{% endif %}
|
||||
<button class="btn btn-info btn-sm public-vanity" data-id="{{ media.id }}" data-toggle="tooltip" title="{{ lang('vanity_url') }}"><i class="fas fa-star"></i></button>
|
||||
<button type="button" class="btn btn-sm btn-danger media-delete" data-link="{{ route('upload.delete', {'id': media.id}) }}" data-id="{{ media.id }}" data-toggle="tooltip" title="{{ lang('delete') }}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
|
@ -68,4 +69,5 @@
|
|||
<div class="text-center text-muted"><i>{{ lang('no_media') }}</i></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'comp/modal_vanity.twig' %}
|
||||
{% endblock %}
|
||||
|
|
2
resources/templates/dashboard/list.twig
Normal file → Executable file
2
resources/templates/dashboard/list.twig
Normal file → Executable file
|
@ -6,6 +6,7 @@
|
|||
{% include 'comp/navbar.twig' %}
|
||||
<div class="container">
|
||||
{% include 'comp/alert.twig' %}
|
||||
{% include 'comp/modal_vanity.twig' %}
|
||||
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
|
@ -77,6 +78,7 @@
|
|||
{% else %}
|
||||
<a href="javascript:void(0)" class="btn btn-sm btn-outline-info publish-toggle" data-toggle="tooltip" title="{{ lang('publish') }}" data-id="{{ media.id }}" data-published="{{ media.published }}"><i class="fas fa-check-circle"></i></a>
|
||||
{% endif %}
|
||||
<a href="javascript:void(0)" class="btn btn-sm btn-outline-info public-vanity" data-id="{{ media.id }}" data-toggle="tooltip" title="{{ lang('vanity_url') }}"><i class="fas fa-star"></i></a>
|
||||
<a href="javascript:void(0)" class="btn btn-sm btn-outline-danger media-delete" data-link="{{ route('upload.delete', {'id': media.id}) }}" data-id="{{ media.id }}" data-toggle="tooltip" title="{{ lang('delete') }}"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</td>
|
||||
|
|
2
resources/templates/upload/public.twig
Normal file → Executable file
2
resources/templates/upload/public.twig
Normal file → Executable file
|
@ -49,6 +49,7 @@
|
|||
<a href="{{ url }}/raw" class="btn btn-secondary my-2 my-sm-0" data-toggle="tooltip" title="{{ lang('raw') }}"><i class="fas fa-file-alt fa-lg fa-fw"></i></a>
|
||||
<a href="{{ url }}/download" class="btn btn-warning my-2 my-sm-0" data-toggle="tooltip" title="{{ lang('download') }}"><i class="fas fa-cloud-download-alt fa-lg fa-fw"></i></a>
|
||||
{% if session.get('logged') %}
|
||||
<a href="javascript:void(0)" class="btn btn-info my-2 my-sm-0 public-vanity" data-link="{{ route('upload.vanity', {'id': media.mediaId}) }}" data-id="{{ media.mediaId }}" data-toggle="tooltip" title="{{ lang('vanity') }}"><i class="fas fa-star fa-lg fa-fw"></i></a>
|
||||
<a href="javascript:void(0)" class="btn btn-danger my-2 my-sm-0 public-delete" data-link="{{ route('upload.delete', {'id': media.mediaId}) }}" data-toggle="tooltip" title="{{ lang('delete') }}"><i class="fas fa-trash fa-lg fa-fw"></i></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -162,4 +163,5 @@
|
|||
</div>
|
||||
</div>
|
||||
{% include 'comp/modal_delete.twig' %}
|
||||
{% include 'comp/modal_vanity.twig' %}
|
||||
{% endblock %}
|
||||
|
|
26
src/js/app.js
Normal file → Executable file
26
src/js/app.js
Normal file → Executable file
|
@ -29,8 +29,10 @@ var app = {
|
|||
|
||||
$('.user-delete').click(app.modalDelete);
|
||||
$('.public-delete').click(app.modalDelete);
|
||||
$('.public-vanity').click(app.modalVanity);
|
||||
$('.media-delete').click(app.mediaDelete);
|
||||
$('.publish-toggle').click(app.publishToggle);
|
||||
|
||||
$('.refresh-token').click(app.refreshToken);
|
||||
$('#themes').mousedown(app.loadThemes);
|
||||
$('.checkForUpdatesButton').click(app.checkForUpdates);
|
||||
|
@ -57,6 +59,30 @@ var app = {
|
|||
$('#modalDelete-link').attr('href', $(this).data('link'));
|
||||
$('#modalDelete').modal('show');
|
||||
},
|
||||
modalVanity: function () {
|
||||
var id = $(this).data('id');
|
||||
$('#modalVanity').modal('show');
|
||||
$('#modalVanity-link').click(function () {
|
||||
var $callerButton = $(this);
|
||||
$.post(window.AppConfig.base_url + '/upload/' + id + '/vanity', {vanity: $('#modalVanity-input').val()}, function (responseData, status) {
|
||||
$callerButton.tooltip('dispose');
|
||||
$('#modalVanity').modal('hide');
|
||||
$('#modalVanity-input').val('');
|
||||
var parsedData = JSON.parse(responseData);
|
||||
if ($('#media_' + id).find('.btn-group').length > 0) {
|
||||
$('#media_' + id).find('.btn-group').find('a').each(function (item) {
|
||||
var oldUrl = $(this).attr('href');
|
||||
var newUrl = oldUrl.replace(oldUrl.substr(oldUrl.lastIndexOf('/') + 1), parsedData.code.code);
|
||||
$(this).attr('href', newUrl);
|
||||
});
|
||||
} else {
|
||||
var oldUrl = window.location.href;
|
||||
var newUrl = oldUrl.replace(oldUrl.substr(oldUrl.lastIndexOf('/') + 1), parsedData.code.code);
|
||||
window.location.href = newUrl;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
publishToggle: function () {
|
||||
var id = $(this).data('id');
|
||||
var $callerButton = $(this);
|
||||
|
|
Loading…
Reference in a new issue