Apply fixes from StyleCI (#100)

This commit is contained in:
Sergio Brighenti 2019-11-20 18:49:31 +01:00 committed by GitHub
parent 1ce14a24f4
commit a424f87523
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 1722 additions and 1572 deletions

View file

@ -2,22 +2,22 @@
namespace App\Controllers;
use League\Flysystem\FileNotFoundException;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class AdminController extends Controller
{
/**
* @param Request $request
* @param Response $response
* @return Response
* @param Request $request
* @param Response $response
*
* @throws FileNotFoundException
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return Response
*/
public function system(Request $request, Response $response): Response
{
@ -35,20 +35,21 @@ class AdminController extends Controller
}
return view()->render($response, 'dashboard/system.twig', [
'usersCount' => $usersCount,
'mediasCount' => $mediasCount,
'orphanFilesCount' => $orphanFilesCount,
'totalSize' => humanFileSize($totalSize),
'post_max_size' => ini_get('post_max_size'),
'usersCount' => $usersCount,
'mediasCount' => $mediasCount,
'orphanFilesCount' => $orphanFilesCount,
'totalSize' => humanFileSize($totalSize),
'post_max_size' => ini_get('post_max_size'),
'upload_max_filesize' => ini_get('upload_max_filesize'),
'installed_lang' => $this->lang->getList(),
'forced_lang' => $request->getAttribute('forced_lang')
'installed_lang' => $this->lang->getList(),
'forced_lang' => $request->getAttribute('forced_lang'),
]);
}
/**
* @param Request $request
* @param Response $response
* @param Request $request
* @param Response $response
*
* @return Response
*/
public function deleteOrphanFiles(Response $response): Response
@ -74,8 +75,9 @@ class AdminController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param Request $request
* @param Response $response
*
* @return Response
*/
public function applyLang(Request $request, Response $response): Response
@ -96,8 +98,9 @@ class AdminController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param Request $request
* @param Response $response
*
* @return Response
*/
public function applyCustomHead(Request $request, Response $response): Response

View file

@ -1,9 +1,7 @@
<?php
namespace App\Controllers;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Exception\HttpNotFoundException;
@ -12,12 +10,14 @@ use Slim\Exception\HttpUnauthorizedException;
class ClientController extends Controller
{
/**
* @param Request $request
* @param Response $response
* @param int $id
* @return Response
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
*
* @return Response
*/
public function getShareXConfig(Request $request, Response $response, int $id): Response
{
@ -25,21 +25,22 @@ class ClientController extends Controller
if ($user->token === null || $user->token === '') {
$this->session->alert(lang('no_upload_token'), 'danger');
return redirect($response, $request->getHeaderLine('Referer'));
}
$json = [
'DestinationType' => 'ImageUploader, TextUploader, FileUploader',
'RequestURL' => route('upload'),
'FileFormName' => 'upload',
'Arguments' => [
'file' => '$filename$',
'text' => '$input$',
'RequestURL' => route('upload'),
'FileFormName' => 'upload',
'Arguments' => [
'file' => '$filename$',
'text' => '$input$',
'token' => $user->token,
],
'URL' => '$json:url$',
'URL' => '$json:url$',
'ThumbnailURL' => '$json:url$/raw',
'DeletionURL' => '$json:url$/delete/'.$user->token,
'DeletionURL' => '$json:url$/delete/'.$user->token,
];
return json($response, $json, 200, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)
@ -47,15 +48,17 @@ class ClientController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param int $id
* @return Response
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return Response
*/
public function getBashScript(Request $request, Response $response, int $id): Response
{
@ -63,15 +66,16 @@ class ClientController extends Controller
if ($user->token === null || $user->token === '') {
$this->session->alert(lang('no_upload_token'), 'danger');
return redirect($response, $request->getHeaderLine('Referer'));
}
return view()->render($response->withHeader('Content-Disposition', 'attachment;filename="xbackbone_uploader_'.$user->username.'.sh"'),
'scripts/xbackbone_uploader.sh.twig',
[
'username' => $user->username,
'username' => $user->username,
'upload_url' => route('upload'),
'token' => $user->token,
'token' => $user->token,
]
);
}

View file

@ -27,7 +27,6 @@ use Slim\Exception\HttpUnauthorizedException;
*/
abstract class Controller
{
/** @var Container */
protected $container;
@ -38,20 +37,22 @@ abstract class Controller
/**
* @param $name
* @return mixed|null
*
* @throws DependencyException
* @throws NotFoundException
*
* @return mixed|null
*/
public function __get($name)
{
if ($this->container->has($name)) {
return $this->container->get($name);
}
return null;
}
/**
* @param $id
*
* @return int
*/
protected function getUsedSpaceByUser($id): int
@ -73,12 +74,14 @@ abstract class Controller
}
/**
* @param Request $request
* @param Request $request
* @param $id
* @param bool $authorize
* @return mixed
* @param bool $authorize
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
*
* @return mixed
*/
protected function getUser(Request $request, $id, $authorize = false)
{

View file

@ -8,11 +8,12 @@ use Psr\Http\Message\ServerRequestInterface as Request;
class DashboardController extends Controller
{
/**
* @Inject
* @param Request $request
* @param Response $response
*
* @param Request $request
* @param Response $response
*
* @return Response
*/
public function redirects(Request $request, Response $response): Response
@ -25,13 +26,15 @@ class DashboardController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param int|null $page
* @return Response
* @param Request $request
* @param Response $response
* @param int|null $page
*
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return Response
*/
public function home(Request $request, Response $response, int $page = 0): Response
{
@ -61,21 +64,23 @@ class DashboardController extends Controller
$response,
($this->session->get('admin', false) && $this->session->get('gallery_view', true)) ? 'dashboard/list.twig' : 'dashboard/grid.twig',
[
'medias' => $query->getMedia(),
'next' => $page < floor($query->getPages()),
'previous' => $page >= 1,
'medias' => $query->getMedia(),
'next' => $page < floor($query->getPages()),
'previous' => $page >= 1,
'current_page' => ++$page,
]
);
}
/**
* @param Response $response
* @param Response $response
*
* @return Response
*/
public function switchView(Response $response): Response
{
$this->session->set('gallery_view', !$this->session->get('gallery_view', true));
return redirect($response, route('home'));
}
}

View file

@ -2,33 +2,36 @@
namespace App\Controllers;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class LoginController extends Controller
{
/**
* @param Response $response
* @return Response
* @param Response $response
*
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return Response
*/
public function show(Response $response): Response
{
if ($this->session->get('logged', false)) {
return redirect($response, route('home'));
}
return view()->render($response, 'auth/login.twig');
}
/**
* @param Request $request
* @param Response $response
* @return Response
* @param Request $request
* @param Response $response
*
* @throws \Exception
*
* @return Response
*/
public function login(Request $request, Response $response): Response
{
@ -37,16 +40,19 @@ class LoginController extends Controller
if (!$result || !password_verify(param($request, 'password'), $result->password)) {
$this->session->alert(lang('bad_login'), 'danger');
return redirect($response, route('login'));
}
if (isset($this->config['maintenance']) && $this->config['maintenance'] && !$result->is_admin) {
$this->session->alert(lang('maintenance_in_progress'), 'info');
return redirect($response, route('login'));
}
if (!$result->active) {
$this->session->alert(lang('account_disabled'), 'danger');
return redirect($response, route('login'));
}
@ -76,7 +82,7 @@ class LoginController extends Controller
setcookie('remember', "{$selector}:{$token}", $expire, '; SameSite=Lax', '', false, true);
} else {
setcookie('remember', "{$selector}:{$token}", [
'expires' => $expire,
'expires' => $expire,
'httponly' => true,
'samesite' => 'Lax',
]);
@ -91,11 +97,12 @@ class LoginController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param Request $request
* @param Response $response
*
* @return Response
*/
public function logout(Request $request,Response $response): Response
public function logout(Request $request, Response $response): Response
{
$this->session->clear();
$this->session->set('logged', false);
@ -107,5 +114,4 @@ class LoginController extends Controller
return redirect($response, route('login.show'));
}
}

View file

@ -1,9 +1,7 @@
<?php
namespace App\Controllers;
use GuzzleHttp\Psr7\Stream;
use Intervention\Image\Constraint;
use Intervention\Image\ImageManagerStatic as Image;
@ -18,17 +16,19 @@ use Slim\Exception\HttpUnauthorizedException;
class MediaController extends Controller
{
/**
* @param Request $request
* @param Response $response
* @param string $userCode
* @param string $mediaCode
* @param string|null $token
* @return Response
* @param Request $request
* @param Response $response
* @param string $userCode
* @param string $mediaCode
* @param string|null $token
*
* @throws HttpNotFoundException
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
* @throws FileNotFoundException
*
* @return Response
*/
public function show(Request $request, Response $response, string $userCode, string $mediaCode, string $token = null): Response
{
@ -61,27 +61,28 @@ class MediaController extends Controller
}
}
$media->size = humanFileSize($size);
} catch (FileNotFoundException $e) {
throw new HttpNotFoundException($request);
}
return view()->render($response, 'upload/public.twig', [
'delete_token' => $token,
'media' => $media,
'type' => $type,
'extension' => pathinfo($media->filename, PATHINFO_EXTENSION),
'media' => $media,
'type' => $type,
'extension' => pathinfo($media->filename, PATHINFO_EXTENSION),
]);
}
}
/**
* @param Request $request
* @param Response $response
* @param int $id
* @return Response
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws FileNotFoundException
* @throws HttpNotFoundException
*
* @return Response
*/
public function getRawById(Request $request, Response $response, int $id): Response
{
@ -95,15 +96,17 @@ class MediaController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param string $userCode
* @param string $mediaCode
* @param string|null $ext
* @return Response
* @param Request $request
* @param Response $response
* @param string $userCode
* @param string $mediaCode
* @param string|null $ext
*
* @throws FileNotFoundException
* @throws HttpBadRequestException
* @throws HttpNotFoundException
*
* @return Response
*/
public function getRaw(Request $request, Response $response, string $userCode, string $mediaCode, ?string $ext = null): Response
{
@ -120,15 +123,16 @@ class MediaController extends Controller
return $this->streamMedia($request, $response, $this->storage, $media);
}
/**
* @param Request $request
* @param Response $response
* @param string $userCode
* @param string $mediaCode
* @return Response
* @param Request $request
* @param Response $response
* @param string $userCode
* @param string $mediaCode
*
* @throws FileNotFoundException
* @throws HttpNotFoundException
*
* @return Response
*/
public function download(Request $request, Response $response, string $userCode, string $mediaCode): Response
{
@ -137,15 +141,18 @@ class MediaController extends Controller
if (!$media || !$media->published && $this->session->get('user_id') !== $media->user_id && !$this->session->get('admin', false)) {
throw new HttpNotFoundException($request);
}
return $this->streamMedia($request, $response, $this->storage, $media, 'attachment');
}
/**
* @param Request $request
* @param Response $response
* @param int $id
* @return Response
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws HttpNotFoundException
*
* @return Response
*/
public function togglePublish(Request $request, Response $response, int $id): Response
{
@ -165,12 +172,14 @@ class MediaController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param int $id
* @return Response
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
*
* @return Response
*/
public function delete(Request $request, Response $response, int $id): Response
{
@ -192,14 +201,16 @@ class MediaController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param string $userCode
* @param string $mediaCode
* @param string $token
* @return Response
* @param Request $request
* @param Response $response
* @param string $userCode
* @param string $mediaCode
* @param string $token
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
*
* @return Response
*/
public function deleteByToken(Request $request, Response $response, string $userCode, string $mediaCode, string $token): Response
{
@ -213,11 +224,13 @@ class MediaController extends Controller
if (!$user) {
$this->session->alert(lang('token_not_found'), 'danger');
return redirect($response, $request->getHeaderLine('Referer'));
}
if (!$user->active) {
$this->session->alert(lang('account_disabled'), 'danger');
return redirect($response, $request->getHeaderLine('Referer'));
}
@ -232,9 +245,10 @@ class MediaController extends Controller
}
/**
* @param Request $request
* @param string $storagePath
* @param int $id
* @param Request $request
* @param string $storagePath
* @param int $id
*
* @throws HttpNotFoundException
*/
protected function deleteMedia(Request $request, string $storagePath, int $id)
@ -251,6 +265,7 @@ class MediaController extends Controller
/**
* @param $userCode
* @param $mediaCode
*
* @return mixed
*/
protected function getMedia($userCode, $mediaCode)
@ -266,13 +281,15 @@ class MediaController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param Filesystem $storage
* @param Request $request
* @param Response $response
* @param Filesystem $storage
* @param $media
* @param string $disposition
* @return Response
* @param string $disposition
*
* @throws FileNotFoundException
*
* @return Response
*/
protected function streamMedia(Request $request, Response $response, Filesystem $storage, $media, string $disposition = 'inline'): Response
{
@ -303,13 +320,15 @@ class MediaController extends Controller
}
/**
* @param Filesystem $storage
* @param Filesystem $storage
* @param $media
* @param null $width
* @param null $height
* @param string $disposition
* @return Response
* @param null $width
* @param null $height
* @param string $disposition
*
* @throws FileNotFoundException
*
* @return Response
*/
protected function makeThumbnail(Filesystem $storage, $media, $width = null, $height = null, string $disposition = 'inline')
{
@ -323,12 +342,13 @@ class MediaController extends Controller
}
/**
* @param Response $response
* @param Stream $stream
* @param string $range
* @param string $disposition
* @param Response $response
* @param Stream $stream
* @param string $range
* @param string $disposition
* @param $media
* @param $mime
*
* @return Response
*/
protected function handlePartialRequest(Response $response, Stream $stream, string $range, string $disposition, $media, $mime)
@ -347,11 +367,11 @@ class MediaController extends Controller
}
if ($range === '-') {
$start = $stream->getSize() - (int)substr($range, 1);
$start = $stream->getSize() - (int) substr($range, 1);
} else {
$range = explode('-', $range);
$start = (int)$range[0];
$end = (isset($range[1]) && is_numeric($range[1])) ? (int)$range[1] : $stream->getSize();
$start = (int) $range[0];
$end = (isset($range[1]) && is_numeric($range[1])) ? (int) $range[1] : $stream->getSize();
}
$end = ($end > $stream->getSize() - 1) ? $stream->getSize() - 1 : $end;

View file

@ -8,7 +8,8 @@ use Psr\Http\Message\ServerRequestInterface as Request;
class ThemeController extends Controller
{
/**
* @param Response $response
* @param Response $response
*
* @return Response
*/
public function getThemes(Response $response): Response
@ -26,18 +27,21 @@ class ThemeController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param Request $request
* @param Response $response
*
* @return Response
*/
public function applyTheme(Request $request, Response $response): Response
{
if (!is_writable(BASE_DIR.'static/bootstrap/css/bootstrap.min.css')) {
$this->session->alert(lang('cannot_write_file'), 'danger');
return redirect($response, route('system'));
}
file_put_contents(BASE_DIR.'static/bootstrap/css/bootstrap.min.css', file_get_contents(param($request, 'css')));
return redirect($response, route('system'));
}
}

View file

@ -2,7 +2,6 @@
namespace App\Controllers;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use RuntimeException;
@ -13,13 +12,15 @@ class UpgradeController extends Controller
const GITHUB_SOURCE_API = 'https://api.github.com/repos/SergiX44/XBackBone/releases';
/**
* @param Response $response
* @param Response $response
*
* @return Response
*/
public function upgrade(Response $response): Response
{
if (!is_writable(BASE_DIR)) {
$this->session->alert(lang('path_not_writable', BASE_DIR), 'warning');
return redirect($response, route('system'));
}
@ -27,11 +28,13 @@ class UpgradeController extends Controller
$json = $this->getApiJson();
} catch (RuntimeException $e) {
$this->session->alert($e->getMessage(), 'danger');
return redirect($response, route('system'));
}
if (version_compare($json[0]->tag_name, PLATFORM_VERSION, '<=')) {
$this->session->alert(lang('already_latest_version'), 'warning');
return redirect($response, route('system'));
}
@ -39,11 +42,13 @@ class UpgradeController extends Controller
if (file_put_contents($tmpFile, file_get_contents($json[0]->assets[0]->browser_download_url)) === false) {
$this->session->alert(lang('cannot_retrieve_file'), 'danger');
return redirect($response, route('system'));
};
}
if (filesize($tmpFile) !== $json[0]->assets[0]->size) {
$this->session->alert(lang('file_size_no_match'), 'danger');
return redirect($response, route('system'));
}
@ -64,7 +69,6 @@ class UpgradeController extends Controller
removeDirectory(BASE_DIR.'vendor/');
$updateZip = new ZipArchive();
$updateZip->open($tmpFile);
@ -89,14 +93,15 @@ class UpgradeController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param Request $request
* @param Response $response
*
* @return Response
*/
public function checkForUpdates(Request $request, Response $response): Response
{
$jsonResponse = [
'status' => null,
'status' => null,
'message' => null,
'upgrade' => false,
];
@ -148,5 +153,4 @@ class UpgradeController extends Controller
return json_decode($data);
}
}

View file

@ -8,14 +8,15 @@ use Psr\Http\Message\ServerRequestInterface as Request;
class UploadController extends Controller
{
/**
* @param Request $request
* @param Response $response
* @return Response
* @param Request $request
* @param Response $response
*
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return Response
*/
public function webUpload(Request $request, Response $response): Response
{
@ -23,6 +24,7 @@ class UploadController extends Controller
if ($user->token === null || $user->token === '') {
$this->session->alert(lang('no_upload_token'), 'danger');
return redirect($response, $request->getHeaderLine('Referer'));
}
@ -32,10 +34,12 @@ class UploadController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @return Response
* @param Request $request
* @param Response $response
*
* @throws FileExistsException
*
* @return Response
*/
public function upload(Request $request, Response $response): Response
{
@ -46,11 +50,13 @@ class UploadController extends Controller
if ($this->config['maintenance']) {
$json['message'] = 'Endpoint under maintenance.';
return json($response, $json, 503);
}
if ($request->getServerParams()['CONTENT_LENGTH'] > stringToBytes(ini_get('post_max_size'))) {
$json['message'] = 'File too large (post_max_size too low?).';
return json($response, $json, 400);
}
@ -60,16 +66,19 @@ class UploadController extends Controller
if ($file === null) {
$json['message'] = 'Request without file attached.';
return json($response, $json, 400);
}
if ($file->getError() === UPLOAD_ERR_INI_SIZE) {
$json['message'] = 'File too large (upload_max_filesize too low?).';
return json($response, $json, 400);
}
if (param($request, 'token') === null) {
$json['message'] = 'Token not specified.';
return json($response, $json, 400);
}
@ -77,11 +86,13 @@ class UploadController extends Controller
if (!$user) {
$json['message'] = 'Token specified not found.';
return json($response, $json, 404);
}
if (!$user->active) {
$json['message'] = 'Account disabled.';
return json($response, $json, 401);
}

View file

@ -2,7 +2,6 @@
namespace App\Controllers;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Exception\HttpNotFoundException;
@ -13,12 +12,14 @@ class UserController extends Controller
const PER_PAGE = 15;
/**
* @param Response $response
* @param int|null $page
* @return Response
* @param Response $response
* @param int|null $page
*
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return Response
*/
public function index(Response $response, int $page = 0): Response
{
@ -31,20 +32,22 @@ class UserController extends Controller
return view()->render($response,
'user/index.twig',
[
'users' => $users,
'next' => $page < floor($pages),
'previous' => $page >= 1,
'users' => $users,
'next' => $page < floor($pages),
'previous' => $page >= 1,
'current_page' => ++$page,
]
);
}
/**
* @param Response $response
* @return Response
* @param Response $response
*
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return Response
*/
public function create(Response $response): Response
{
@ -52,34 +55,40 @@ class UserController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param Request $request
* @param Response $response
*
* @return Response
*/
public function store(Request $request, Response $response): Response
{
if (param($request, 'email') === null) {
$this->session->alert(lang('email_required'), 'danger');
return redirect($response, route('user.create'));
}
if ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `email` = ?', param($request, 'email'))->fetch()->count > 0) {
$this->session->alert(lang('email_taken'), 'danger');
return redirect($response, route('user.create'));
}
if (param($request, 'username') === null) {
$this->session->alert(lang('username_required'), 'danger');
return redirect($response, route('user.create'));
}
if (param($request, 'password') === null) {
$this->session->alert(lang('password_required'), 'danger');
return redirect($response, route('user.create'));
}
if ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `username` = ?', param($request, 'username'))->fetch()->count > 0) {
$this->session->alert(lang('username_taken'), 'danger');
return redirect($response, route('user.create'));
}
@ -106,15 +115,17 @@ class UserController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param Request $request
* @param Response $response
* @param $id
* @return Response
*
* @throws HttpNotFoundException
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
* @throws HttpUnauthorizedException
*
* @return Response
*/
public function edit(Request $request, Response $response, int $id): Response
{
@ -122,17 +133,19 @@ class UserController extends Controller
return view()->render($response, 'user/edit.twig', [
'profile' => false,
'user' => $user,
'user' => $user,
]);
}
/**
* @param Request $request
* @param Response $response
* @param int $id
* @return Response
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
*
* @return Response
*/
public function update(Request $request, Response $response, int $id): Response
{
@ -140,26 +153,31 @@ class UserController extends Controller
if (param($request, 'email') === null) {
$this->session->alert(lang('email_required'), 'danger');
return redirect($response, route('user.edit', ['id' => $id]));
}
if ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `email` = ? AND `email` <> ?', [param($request, 'email'), $user->email])->fetch()->count > 0) {
$this->session->alert(lang('email_taken'), 'danger');
return redirect($response, route('user.edit', ['id' => $id]));
}
if (param($request, 'username') === null) {
$this->session->alert(lang('username_required'), 'danger');
return redirect($response, route('user.edit', ['id' => $id]));
}
if ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `username` = ? AND `username` <> ?', [param($request, 'username'), $user->username])->fetch()->count > 0) {
$this->session->alert(lang('username_taken'), 'danger');
return redirect($response, route('user.edit', ['id' => $id]));
}
if ($user->id === $this->session->get('user_id') && param($request, 'is_admin') === null) {
$this->session->alert(lang('cannot_demote'), 'danger');
return redirect($response, route('user.edit', ['id' => $id]));
}
@ -184,21 +202,22 @@ class UserController extends Controller
$this->session->alert(lang('user_updated', [param($request, 'username')]), 'success');
$this->logger->info('User '.$this->session->get('username')." updated $user->id.", [
array_diff_key((array)$user, array_flip(['password'])),
array_diff_key((array) $user, array_flip(['password'])),
array_diff_key($request->getParsedBody(), array_flip(['password'])),
]);
return redirect($response, route('user.index'));
}
/**
* @param Request $request
* @param Response $response
* @param int $id
* @return Response
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
*
* @return Response
*/
public function delete(Request $request, Response $response, int $id): Response
{
@ -206,6 +225,7 @@ class UserController extends Controller
if ($user->id === $this->session->get('user_id')) {
$this->session->alert(lang('cannot_delete'), 'danger');
return redirect($response, route('user.index'));
}
@ -218,14 +238,16 @@ class UserController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @return Response
* @param Request $request
* @param Response $response
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return Response
*/
public function profile(Request $request, Response $response): Response
{
@ -233,22 +255,25 @@ class UserController extends Controller
return view()->render($response, 'user/edit.twig', [
'profile' => true,
'user' => $user,
'user' => $user,
]);
}
/**
* @param Request $request
* @param Response $response
* @param int $id
* @return Response
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
*
* @return Response
*/
public function profileEdit(Request $request, Response $response, int $id): Response
{
if (param($request, 'email') === null) {
$this->session->alert(lang('email_required'), 'danger');
return redirect($response, route('profile'));
}
@ -256,6 +281,7 @@ class UserController extends Controller
if ($this->database->query('SELECT COUNT(*) AS `count` FROM `users` WHERE `email` = ? AND `email` <> ?', [param($request, 'email'), $user->email])->fetch()->count > 0) {
$this->session->alert(lang('email_taken'), 'danger');
return redirect($response, route('profile'));
}
@ -279,12 +305,14 @@ class UserController extends Controller
}
/**
* @param Request $request
* @param Response $response
* @param int $id
* @return Response
* @param Request $request
* @param Response $response
* @param int $id
*
* @throws HttpNotFoundException
* @throws HttpUnauthorizedException
*
* @return Response
*/
public function refreshToken(Request $request, Response $response, int $id): Response
{

View file

@ -2,63 +2,64 @@
namespace App\Database;
use PDO;
class DB
{
/** @var DB */
protected static $instance;
/** @var DB */
protected static $instance;
/** @var PDO */
protected $pdo;
/** @var PDO */
protected $pdo;
/** @var string */
protected $currentDriver;
/** @var string */
protected $currentDriver;
public function __construct(string $dsn, string $username = null, string $password = null)
{
$this->pdo = new PDO($dsn, $username, $password);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
public function __construct(string $dsn, string $username = null, string $password = null)
{
$this->pdo = new PDO($dsn, $username, $password);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$this->currentDriver = $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
if ($this->currentDriver === 'sqlite') {
$this->pdo->exec('PRAGMA foreign_keys = ON');
}
}
$this->currentDriver = $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
if ($this->currentDriver === 'sqlite') {
$this->pdo->exec('PRAGMA foreign_keys = ON');
}
}
public function query(string $query, $parameters = [])
{
if (!is_array($parameters)) {
$parameters = [$parameters];
}
$query = $this->pdo->prepare($query);
public function query(string $query, $parameters = [])
{
if (!is_array($parameters)) {
$parameters = [$parameters];
}
$query = $this->pdo->prepare($query);
foreach ($parameters as $index => $parameter) {
$query->bindValue($index + 1, $parameter, is_int($parameter) ? PDO::PARAM_INT : PDO::PARAM_STR);
}
foreach ($parameters as $index => $parameter) {
$query->bindValue($index + 1, $parameter, is_int($parameter) ? PDO::PARAM_INT : PDO::PARAM_STR);
}
$query->execute();
$query->execute();
return $query;
}
return $query;
}
/**
* Get the PDO instance
* @return PDO
*/
public function getPdo(): PDO
{
return $this->pdo;
}
/**
* Get the PDO instance.
*
* @return PDO
*/
public function getPdo(): PDO
{
return $this->pdo;
}
/**
* Get the current PDO driver
* @return string
*/
public function getCurrentDriver(): string
{
return $this->currentDriver;
}
/**
* Get the current PDO driver.
*
* @return string
*/
public function getCurrentDriver(): string
{
return $this->currentDriver;
}
}

View file

@ -1,9 +1,7 @@
<?php
namespace App\Database;
use PDOException;
class Migrator
@ -21,12 +19,12 @@ class Migrator
*/
private $firstMigrate;
/**
* Migrator constructor.
* @param DB $db
* @param string $schemaPath
* @param bool $firstMigrate
*
* @param DB $db
* @param string $schemaPath
* @param bool $firstMigrate
*/
public function __construct(DB $db, string $schemaPath, bool $firstMigrate = false)
{
@ -57,9 +55,7 @@ class Migrator
$inMigrationsTable = $this->db->query("SELECT * FROM `migrations` WHERE `name` IN ($in)", $names)->fetchAll();
foreach ($files as $file) {
$continue = false;
$exists = false;
@ -79,6 +75,7 @@ class Migrator
}
$sql = file_get_contents($file);
try {
$this->db->getPdo()->exec($sql);
if (!$exists) {
@ -90,9 +87,9 @@ class Migrator
if (!$exists) {
$this->db->query('INSERT INTO `migrations` VALUES (?,?)', [basename($file), 0]);
}
throw $exception;
}
}
}
}

View file

@ -2,7 +2,6 @@
namespace App\Database\Queries;
use App\Database\DB;
use League\Flysystem\FileNotFoundException;
use League\Flysystem\Filesystem;
@ -10,222 +9,228 @@ use League\Flysystem\Plugin\ListFiles;
class MediaQuery
{
const PER_PAGE = 21;
const PER_PAGE_ADMIN = 27;
const PER_PAGE = 21;
const PER_PAGE_ADMIN = 27;
const ORDER_TIME = 0;
const ORDER_NAME = 1;
const ORDER_SIZE = 2;
const ORDER_TIME = 0;
const ORDER_NAME = 1;
const ORDER_SIZE = 2;
/** @var DB */
protected $db;
/** @var DB */
protected $db;
/** @var bool */
protected $isAdmin;
/** @var bool */
protected $isAdmin;
protected $userId;
protected $userId;
/** @var int */
protected $orderBy;
/** @var int */
protected $orderBy;
/** @var string */
protected $orderMode;
/** @var string */
protected $orderMode;
/** @var string */
protected $text;
/** @var string */
protected $text;
/** @var Filesystem */
protected $storage;
/** @var Filesystem */
protected $storage;
private $pages;
private $media;
private $pages;
private $media;
/**
* MediaQuery constructor.
*
* @param DB $db
* @param bool $isAdmin
* @param Filesystem $storage
*/
public function __construct(DB $db, bool $isAdmin, Filesystem $storage)
{
$this->db = $db;
$this->isAdmin = $isAdmin;
$this->storage = $storage;
}
/**
* MediaQuery constructor.
* @param DB $db
* @param bool $isAdmin
* @param Filesystem $storage
*/
public function __construct(DB $db, bool $isAdmin, Filesystem $storage)
{
$this->db = $db;
$this->isAdmin = $isAdmin;
$this->storage = $storage;
}
/**
* @param $id
*
* @return $this
*/
public function withUserId($id)
{
$this->userId = $id;
/**
* @param $id
* @return $this
*/
public function withUserId($id)
{
$this->userId = $id;
return $this;
}
return $this;
}
/**
* @param string|null $type
* @param string $mode
* @return $this
*/
public function orderBy(string $type = null, $mode = 'ASC')
{
$this->orderBy = ($type === null) ? self::ORDER_TIME : $type;
$this->orderMode = (strtoupper($mode) === 'ASC') ? 'ASC' : 'DESC';
return $this;
}
/**
* @param string|null $type
* @param string $mode
*
* @return $this
*/
public function orderBy(string $type = null, $mode = 'ASC')
{
$this->orderBy = ($type === null) ? self::ORDER_TIME : $type;
$this->orderMode = (strtoupper($mode) === 'ASC') ? 'ASC' : 'DESC';
/**
* @param string $text
* @return $this
*/
public function search(?string $text)
{
$this->text = $text;
return $this;
}
return $this;
}
/**
* @param int $page
*/
public function run(int $page)
{
if ($this->orderBy == self::ORDER_SIZE) {
$this->runWithOrderBySize($page);
return;
}
/**
* @param string $text
*
* @return $this
*/
public function search(?string $text)
{
$this->text = $text;
$queryPages = 'SELECT COUNT(*) AS `count` FROM `uploads`';
return $this;
}
if ($this->isAdmin) {
$queryMedia = 'SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id` %s LIMIT ? OFFSET ?';
} else {
$queryMedia = 'SELECT `uploads`.*,`users`.`user_code`, `users`.`username` FROM `uploads` INNER JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `user_id` = ? %s LIMIT ? OFFSET ?';
$queryPages .= ' WHERE `user_id` = ?';
}
/**
* @param int $page
*/
public function run(int $page)
{
if ($this->orderBy == self::ORDER_SIZE) {
$this->runWithOrderBySize($page);
$orderAndSearch = '';
$params = [];
return;
}
if ($this->text !== null) {
$orderAndSearch = $this->isAdmin ? 'WHERE `uploads`.`filename` LIKE ? ' : 'AND `uploads`.`filename` LIKE ? ';
$queryPages .= $this->isAdmin ? ' WHERE `filename` LIKE ?' : ' AND `filename` LIKE ?';
$params[] = '%' . htmlentities($this->text) . '%';
}
$queryPages = 'SELECT COUNT(*) AS `count` FROM `uploads`';
switch ($this->orderBy) {
case self::ORDER_NAME:
$orderAndSearch .= 'ORDER BY `filename` ' . $this->orderMode;
break;
default:
case self::ORDER_TIME:
$orderAndSearch .= 'ORDER BY `timestamp` ' . $this->orderMode;
break;
}
if ($this->isAdmin) {
$queryMedia = 'SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id` %s LIMIT ? OFFSET ?';
} else {
$queryMedia = 'SELECT `uploads`.*,`users`.`user_code`, `users`.`username` FROM `uploads` INNER JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `user_id` = ? %s LIMIT ? OFFSET ?';
$queryPages .= ' WHERE `user_id` = ?';
}
$queryMedia = sprintf($queryMedia, $orderAndSearch);
$orderAndSearch = '';
$params = [];
if ($this->isAdmin) {
$this->media = $this->db->query($queryMedia, array_merge($params, [self::PER_PAGE_ADMIN, $page * self::PER_PAGE_ADMIN]))->fetchAll();
$this->pages = $this->db->query($queryPages, $params)->fetch()->count / self::PER_PAGE_ADMIN;
} else {
$this->media = $this->db->query($queryMedia, array_merge([$this->userId], $params, [self::PER_PAGE, $page * self::PER_PAGE]))->fetchAll();
$this->pages = $this->db->query($queryPages, array_merge([$this->userId], $params))->fetch()->count / self::PER_PAGE;
}
if ($this->text !== null) {
$orderAndSearch = $this->isAdmin ? 'WHERE `uploads`.`filename` LIKE ? ' : 'AND `uploads`.`filename` LIKE ? ';
$queryPages .= $this->isAdmin ? ' WHERE `filename` LIKE ?' : ' AND `filename` LIKE ?';
$params[] = '%'.htmlentities($this->text).'%';
}
foreach ($this->media as $media) {
try {
$media->size = humanFileSize($this->storage->getSize($media->storage_path));
$media->mimetype = $this->storage->getMimetype($media->storage_path);
} catch (FileNotFoundException $e) {
$media->size = null;
$media->mimetype = null;
}
$media->extension = pathinfo($media->filename, PATHINFO_EXTENSION);
}
switch ($this->orderBy) {
case self::ORDER_NAME:
$orderAndSearch .= 'ORDER BY `filename` '.$this->orderMode;
break;
default:
case self::ORDER_TIME:
$orderAndSearch .= 'ORDER BY `timestamp` '.$this->orderMode;
break;
}
}
$queryMedia = sprintf($queryMedia, $orderAndSearch);
/**
* @param int $page
*/
private function runWithOrderBySize(int $page)
{
$this->storage->addPlugin(new ListFiles());
if ($this->isAdmin) {
$this->media = $this->db->query($queryMedia, array_merge($params, [self::PER_PAGE_ADMIN, $page * self::PER_PAGE_ADMIN]))->fetchAll();
$this->pages = $this->db->query($queryPages, $params)->fetch()->count / self::PER_PAGE_ADMIN;
} else {
$this->media = $this->db->query($queryMedia, array_merge([$this->userId], $params, [self::PER_PAGE, $page * self::PER_PAGE]))->fetchAll();
$this->pages = $this->db->query($queryPages, array_merge([$this->userId], $params))->fetch()->count / self::PER_PAGE;
}
if ($this->isAdmin) {
$files = $this->storage->listFiles('/', true);
$this->pages = count($files) / self::PER_PAGE_ADMIN;
foreach ($this->media as $media) {
try {
$media->size = humanFileSize($this->storage->getSize($media->storage_path));
$media->mimetype = $this->storage->getMimetype($media->storage_path);
} catch (FileNotFoundException $e) {
$media->size = null;
$media->mimetype = null;
}
$media->extension = pathinfo($media->filename, PATHINFO_EXTENSION);
}
}
$offset = $page * self::PER_PAGE_ADMIN;
$limit = self::PER_PAGE_ADMIN;
} else {
$userCode = $this->db->query('SELECT `user_code` FROM `users` WHERE `id` = ?', [$this->userId])->fetch()->user_code;
$files = $this->storage->listFiles($userCode);
$this->pages = count($files) / self::PER_PAGE;
/**
* @param int $page
*/
private function runWithOrderBySize(int $page)
{
$this->storage->addPlugin(new ListFiles());
$offset = $page * self::PER_PAGE;
$limit = self::PER_PAGE;
}
if ($this->isAdmin) {
$files = $this->storage->listFiles('/', true);
$this->pages = count($files) / self::PER_PAGE_ADMIN;
array_multisort(array_column($files, 'size'), ($this->orderMode === 'ASC') ? SORT_ASC : SORT_DESC, SORT_NUMERIC, $files);
$offset = $page * self::PER_PAGE_ADMIN;
$limit = self::PER_PAGE_ADMIN;
} else {
$userCode = $this->db->query('SELECT `user_code` FROM `users` WHERE `id` = ?', [$this->userId])->fetch()->user_code;
$files = $this->storage->listFiles($userCode);
$this->pages = count($files) / self::PER_PAGE;
if ($this->text !== null) {
if ($this->isAdmin) {
$medias = $this->db->query('SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `uploads`.`filename` LIKE ? ', ['%' . htmlentities($this->text) . '%'])->fetchAll();
} else {
$medias = $this->db->query('SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `user_id` = ? AND `uploads`.`filename` LIKE ? ', [$this->userId, '%' . htmlentities($this->text) . '%'])->fetchAll();
}
$offset = $page * self::PER_PAGE;
$limit = self::PER_PAGE;
}
$paths = array_column($files, 'path');
} else {
$files = array_slice($files, $offset, $limit);
$paths = array_column($files, 'path');
array_multisort(array_column($files, 'size'), ($this->orderMode === 'ASC') ? SORT_ASC : SORT_DESC, SORT_NUMERIC, $files);
$medias = $this->db->query('SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `uploads`.`storage_path` IN ("' . implode('","', $paths) . '")')->fetchAll();
}
if ($this->text !== null) {
if ($this->isAdmin) {
$medias = $this->db->query('SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `uploads`.`filename` LIKE ? ', ['%'.htmlentities($this->text).'%'])->fetchAll();
} else {
$medias = $this->db->query('SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `user_id` = ? AND `uploads`.`filename` LIKE ? ', [$this->userId, '%'.htmlentities($this->text).'%'])->fetchAll();
}
$paths = array_flip($paths);
foreach ($medias as $media) {
$paths[$media->storage_path] = $media;
}
$paths = array_column($files, 'path');
} else {
$files = array_slice($files, $offset, $limit);
$paths = array_column($files, 'path');
$this->media = [];
foreach ($files as $file) {
$media = $paths[$file['path']];
if (!is_object($media)) {
continue;
}
$media->size = humanFileSize($file['size']);
try {
$media->mimetype = $this->storage->getMimetype($file['path']);
} catch (FileNotFoundException $e) {
$media->mimetype = null;
}
$media->extension = $file['extension'];
$this->media[] = $media;
}
$medias = $this->db->query('SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `uploads`.`storage_path` IN ("'.implode('","', $paths).'")')->fetchAll();
}
if ($this->text !== null) {
$this->media = array_slice($this->media, $offset, $limit);
}
}
$paths = array_flip($paths);
foreach ($medias as $media) {
$paths[$media->storage_path] = $media;
}
/**
* @return mixed
*/
public function getMedia()
{
return $this->media;
$this->media = [];
foreach ($files as $file) {
$media = $paths[$file['path']];
if (!is_object($media)) {
continue;
}
$media->size = humanFileSize($file['size']);
}
try {
$media->mimetype = $this->storage->getMimetype($file['path']);
} catch (FileNotFoundException $e) {
$media->mimetype = null;
}
$media->extension = $file['extension'];
$this->media[] = $media;
}
/**
* @return mixed
*/
public function getPages()
{
return $this->pages;
}
if ($this->text !== null) {
$this->media = array_slice($this->media, $offset, $limit);
}
}
/**
* @return mixed
*/
public function getMedia()
{
return $this->media;
}
/**
* @return mixed
*/
public function getPages()
{
return $this->pages;
}
}

View file

@ -1,6 +1,5 @@
<?php
namespace App\Exception\Handlers;
use Slim\Handlers\ErrorHandler;

View file

@ -1,9 +1,7 @@
<?php
namespace App\Exception\Handlers\Renderers;
use App\Exceptions\UnderMaintenanceException;
use Slim\Exception\HttpBadRequestException;
use Slim\Exception\HttpForbiddenException;
@ -16,33 +14,35 @@ use Throwable;
class HtmlErrorRenderer implements ErrorRendererInterface
{
/**
* @param Throwable $exception
* @param bool $displayErrorDetails
* @return string
* @param Throwable $exception
* @param bool $displayErrorDetails
*
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @return string
*/
public function __invoke(Throwable $exception, bool $displayErrorDetails): string
{
if ($exception instanceof UnderMaintenanceException) {
return view()->string( 'errors/maintenance.twig');
return view()->string('errors/maintenance.twig');
}
if ($exception instanceof HttpUnauthorizedException || $exception instanceof HttpForbiddenException) {
return view()->string( 'errors/403.twig');
return view()->string('errors/403.twig');
}
if ($exception instanceof HttpMethodNotAllowedException) {
return view()->string( 'errors/405.twig');
return view()->string('errors/405.twig');
}
if ($exception instanceof HttpNotFoundException) {
return view()->string( 'errors/404.twig');
return view()->string('errors/404.twig');
}
if ($exception instanceof HttpBadRequestException) {
return view()->string( 'errors/400.twig');
return view()->string('errors/400.twig');
}
return view()->string('errors/500.twig', ['exception' => $displayErrorDetails ? $exception : null]);

View file

@ -2,7 +2,6 @@
namespace App\Exceptions;
use Slim\Exception\HttpSpecializedException;
class UnderMaintenanceException extends HttpSpecializedException
@ -11,5 +10,4 @@ class UnderMaintenanceException extends HttpSpecializedException
protected $message = 'Platform Under Maintenance.';
protected $title = '503 Service Unavailable';
protected $description = 'We\'ll be back very soon! :)';
}

View file

@ -1,9 +1,7 @@
<?php
namespace App\Factories;
use App\Web\View;
use Psr\Container\ContainerInterface as Container;
use Slim\Factory\ServerRequestCreatorFactory;
@ -13,16 +11,15 @@ use Twig\TwigFunction;
class ViewFactory
{
public static function createAppInstance(Container $container)
{
$config = $container->get('config');
$loader = new FilesystemLoader(BASE_DIR.'resources/templates');
$twig = new Environment($loader, [
'cache' => BASE_DIR.'resources/cache/twig',
'autoescape' => 'html',
'debug' => $config['debug'],
'cache' => BASE_DIR.'resources/cache/twig',
'autoescape' => 'html',
'debug' => $config['debug'],
'auto_reload' => $config['debug'],
]);
@ -47,14 +44,15 @@ class ViewFactory
return new View($twig);
}
public static function createInstallerInstance(Container $container) {
public static function createInstallerInstance(Container $container)
{
$config = $container->get('config');
$loader = new FilesystemLoader([BASE_DIR . 'install/templates', BASE_DIR.'resources/templates']);
$loader = new FilesystemLoader([BASE_DIR.'install/templates', BASE_DIR.'resources/templates']);
$twig = new Environment($loader, [
'cache' => false,
'autoescape' => 'html',
'debug' => $config['debug'],
'cache' => false,
'autoescape' => 'html',
'debug' => $config['debug'],
'auto_reload' => $config['debug'],
]);
@ -67,5 +65,4 @@ class ViewFactory
return new View($twig);
}
}

View file

@ -11,19 +11,21 @@ use Slim\Exception\HttpUnauthorizedException;
class AdminMiddleware extends Middleware
{
/**
* @param Request $request
* @param RequestHandler $handler
* @return Response
* @param Request $request
* @param RequestHandler $handler
*
* @throws HttpUnauthorizedException
*
* @return Response
*/
public function __invoke(Request $request, RequestHandler $handler): ResponseInterface
{
if (!$this->database->query('SELECT `id`, `is_admin` FROM `users` WHERE `id` = ? LIMIT 1', [$this->session->get('user_id')])->fetch()->is_admin) {
$this->session->set('admin', false);
throw new HttpUnauthorizedException($request);
}
{
if (!$this->database->query('SELECT `id`, `is_admin` FROM `users` WHERE `id` = ? LIMIT 1', [$this->session->get('user_id')])->fetch()->is_admin) {
$this->session->set('admin', false);
throw new HttpUnauthorizedException($request);
}
return $handler->handle($request);
}
}
}

View file

@ -2,7 +2,6 @@
namespace App\Middleware;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
@ -10,26 +9,27 @@ use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
class AuthMiddleware extends Middleware
{
/**
* @param Request $request
* @param RequestHandler $handler
* @param Request $request
* @param RequestHandler $handler
*
* @return ResponseInterface
*/
public function __invoke(Request $request, RequestHandler $handler): ResponseInterface
{
if (!$this->session->get('logged', false)) {
$this->session->set('redirectTo', (string)$request->getUri());
$this->session->set('redirectTo', (string) $request->getUri());
return redirect(new Response(), route('login.show'));
}
if (!$this->database->query('SELECT `id`, `active` FROM `users` WHERE `id` = ? LIMIT 1', [$this->session->get('user_id')])->fetch()->active) {
$this->session->alert(lang('account_disabled'), 'danger');
$this->session->set('logged', false);
return redirect(new Response(), route('login.show'));
}
return $handler->handle($request);
}
}

View file

@ -10,10 +10,12 @@ use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
class CheckForMaintenanceMiddleware extends Middleware
{
/**
* @param Request $request
* @param RequestHandler $handler
* @return Response
* @param Request $request
* @param RequestHandler $handler
*
* @throws UnderMaintenanceException
*
* @return Response
*/
public function __invoke(Request $request, RequestHandler $handler): Response
{

View file

@ -1,19 +1,17 @@
<?php
namespace App\Middleware;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
class InjectMiddleware extends Middleware
{
/**
* @param Request $request
* @param RequestHandler $handler
* @param Request $request
* @param RequestHandler $handler
*
* @return Response
*/
public function __invoke(Request $request, RequestHandler $handler)

View file

@ -1,19 +1,17 @@
<?php
namespace App\Middleware;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
class LangMiddleware extends Middleware
{
/**
* @param Request $request
* @param RequestHandler $handler
* @param Request $request
* @param RequestHandler $handler
*
* @return Response
*/
public function __invoke(Request $request, RequestHandler $handler)

View file

@ -9,11 +9,11 @@ use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
abstract class Middleware extends Controller
{
/**
* @param Request $request
* @param RequestHandler $handler
* @param Request $request
* @param RequestHandler $handler
*
* @return Response
*/
public abstract function __invoke(Request $request, RequestHandler $handler);
abstract public function __invoke(Request $request, RequestHandler $handler);
}

View file

@ -1,19 +1,17 @@
<?php
namespace App\Middleware;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
class RememberMiddleware extends Middleware
{
/**
* @param Request $request
* @param RequestHandler $handler
* @param Request $request
* @param RequestHandler $handler
*
* @return Response
*/
public function __invoke(Request $request, RequestHandler $handler)
@ -34,7 +32,6 @@ class RememberMiddleware extends Middleware
}
}
return $handler->handle($request);
}
}

View file

@ -2,30 +2,27 @@
namespace App\Web;
class Lang
{
const DEFAULT_LANG = 'en';
const LANG_PATH = __DIR__.'../../resources/lang/';
/** @var string */
/** @var string */
protected static $langPath = self::LANG_PATH;
/** @var string */
/** @var string */
protected static $lang;
/** @var Lang */
/** @var Lang */
protected static $instance;
/** @var array */
/** @var array */
protected $cache = [];
/**
* @return Lang
*/
public static function getInstance(): Lang
public static function getInstance(): self
{
if (self::$instance === null) {
self::$instance = new self();
@ -35,11 +32,12 @@ class Lang
}
/**
* @param string $lang
* @param string $langPath
* @param string $lang
* @param string $langPath
*
* @return Lang
*/
public static function build($lang = self::DEFAULT_LANG, $langPath = null): Lang
public static function build($lang = self::DEFAULT_LANG, $langPath = null): self
{
self::$lang = $lang;
@ -54,6 +52,7 @@ class Lang
/**
* Recognize the current language from the request.
*
* @return bool|string
*/
public static function recognize()
@ -61,6 +60,7 @@ class Lang
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
return locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']);
}
return self::DEFAULT_LANG;
}
@ -72,7 +72,6 @@ class Lang
return self::$lang;
}
/**
* @param $lang
*/
@ -106,10 +105,10 @@ class Lang
return $languages;
}
/**
* @param $key
* @param array $args
* @param array $args
*
* @return string
*/
public function get($key, $args = []): string
@ -121,6 +120,7 @@ class Lang
* @param $key
* @param $lang
* @param $args
*
* @return string
*/
private function getString($key, $lang, $args): string

View file

@ -2,16 +2,16 @@
namespace App\Web;
use Exception;
class Session
{
/**
* Session constructor.
* @param string $name
* @param string $path
*
* @param string $name
* @param string $path
*
* @throws Exception
*/
public function __construct(string $name, $path = '')
@ -34,11 +34,11 @@ class Session
}
$started = @session_start([
'name' => $name,
'save_path' => $path,
'name' => $name,
'save_path' => $path,
'cookie_httponly' => true,
'gc_probability' => 25,
'cookie_samesite' => 'Lax' // works only for php >= 7.3
'gc_probability' => 25,
'cookie_samesite' => 'Lax', // works only for php >= 7.3
]);
if (!$started) {
@ -56,7 +56,8 @@ class Session
}
/**
* Destroy the current session
* Destroy the current session.
*
* @return bool
*/
public function destroy(): bool
@ -65,7 +66,7 @@ class Session
}
/**
* Clear all session stored values
* Clear all session stored values.
*/
public function clear(): void
{
@ -73,8 +74,10 @@ class Session
}
/**
* Check if session has a stored key
* Check if session has a stored key.
*
* @param $key
*
* @return bool
*/
public function has($key): bool
@ -83,7 +86,8 @@ class Session
}
/**
* Get the content of the current session
* Get the content of the current session.
*
* @return array
*/
public function all(): array
@ -92,9 +96,11 @@ class Session
}
/**
* Returned a value given a key
* Returned a value given a key.
*
* @param $key
* @param null $default
* @param null $default
*
* @return mixed
*/
public function get($key, $default = null)
@ -103,7 +109,8 @@ class Session
}
/**
* Add a key-value pair to the session
* Add a key-value pair to the session.
*
* @param $key
* @param $value
*/
@ -113,25 +120,26 @@ class Session
}
/**
* Set a flash alert
* Set a flash alert.
*
* @param $message
* @param string $type
* @param string $type
*/
public function alert($message, string $type = 'info'): void
{
$_SESSION['_flash'][] = [$type => $message];
}
/**
* Retrieve flash alerts
* Retrieve flash alerts.
*
* @return array
*/
public function getAlert(): ?array
{
$flash = self::get('_flash');
self::set('_flash', []);
return $flash;
}
}

View file

@ -1,18 +1,12 @@
<?php
namespace App\Web;
use DI\Container;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Factory\ServerRequestCreatorFactory;
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
use Twig\Loader\FilesystemLoader;
use Twig\TwigFunction;
class View
{
@ -21,10 +15,10 @@ class View
*/
private $twig;
/**
* View constructor.
* @param Environment $twig
*
* @param Environment $twig
*/
public function __construct(Environment $twig)
{
@ -32,28 +26,33 @@ class View
}
/**
* @param Response $response
* @param string $view
* @param array|null $parameters
* @return Response
* @param Response $response
* @param string $view
* @param array|null $parameters
*
* @throws LoaderError
* @throws RuntimeError
* @throws SyntaxError
*
* @return Response
*/
public function render(Response $response, string $view, ?array $parameters = [])
{
$body = $this->twig->render($view, $parameters);
$response->getBody()->write($body);
return $response;
}
/**
* @param string $view
* @param array|null $parameters
* @return string
* @param string $view
* @param array|null $parameters
*
* @throws LoaderError
* @throws RuntimeError
* @throws SyntaxError
*
* @return string
*/
public function string(string $view, ?array $parameters = [])
{
@ -67,5 +66,4 @@ class View
{
return $this->twig;
}
}

View file

@ -10,22 +10,26 @@ if (!defined('HUMAN_RANDOM_CHARS')) {
if (!function_exists('humanFileSize')) {
/**
* Generate a human readable file size
* Generate a human readable file size.
*
* @param $size
* @param int $precision
* @param int $precision
*
* @return string
*/
function humanFileSize($size, $precision = 2): string
{
for ($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) {
}
return round($size, $precision).' '.['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'][$i];
}
}
if (!function_exists('humanRandomString')) {
/**
* @param int $length
* @param int $length
*
* @return string
*/
function humanRandomString(int $length = 10): string
@ -38,13 +42,15 @@ if (!function_exists('humanRandomString')) {
for ($x = 0; $x < $numberOffset; $x++) {
$result .= rand(0, 9);
}
return $result;
}
}
if (!function_exists('isDisplayableImage')) {
/**
* @param string $mime
* @param string $mime
*
* @return bool
*/
function isDisplayableImage(string $mime): bool
@ -67,19 +73,20 @@ if (!function_exists('isDisplayableImage')) {
if (!function_exists('stringToBytes')) {
/**
* @param $str
*
* @return float
*/
function stringToBytes(string $str): float
{
$val = trim($str);
if (is_numeric($val)) {
return (float)$val;
return (float) $val;
}
$last = strtolower($val[strlen($val) - 1]);
$val = substr($val, 0, -1);
$val = (float)$val;
$val = (float) $val;
switch ($last) {
case 'g':
$val *= 1024;
@ -88,13 +95,15 @@ if (!function_exists('stringToBytes')) {
case 'k':
$val *= 1024;
}
return $val;
}
}
if (!function_exists('removeDirectory')) {
/**
* Remove a directory and it's content
* Remove a directory and it's content.
*
* @param $path
*/
function removeDirectory($path)
@ -104,13 +113,13 @@ if (!function_exists('removeDirectory')) {
is_dir($file) ? removeDirectory($file) : unlink($file);
}
rmdir($path);
return;
}
}
if (!function_exists('cleanDirectory')) {
/**
* Removes all directory contents
* Removes all directory contents.
*
* @param $path
*/
function cleanDirectory($path)
@ -127,20 +136,24 @@ if (!function_exists('cleanDirectory')) {
if (!function_exists('resolve')) {
/**
* Resolve a service from de DI container
* @param string $service
* Resolve a service from de DI container.
*
* @param string $service
*
* @return mixed
*/
function resolve(string $service)
{
global $app;
return $app->getContainer()->get($service);
}
}
if (!function_exists('view')) {
/**
* Render a view to the response body
* Render a view to the response body.
*
* @return \App\Web\View
*/
function view()
@ -149,13 +162,14 @@ if (!function_exists('view')) {
}
}
if (!function_exists('redirect')) {
/**
* Set the redirect response
* @param Response $response
* @param string $url
* @param int $status
* Set the redirect response.
*
* @param Response $response
* @param string $url
* @param int $status
*
* @return Response
*/
function redirect(Response $response, string $url, $status = 302)
@ -168,8 +182,10 @@ if (!function_exists('redirect')) {
if (!function_exists('asset')) {
/**
* Get the asset link with timestamp
* @param string $path
* Get the asset link with timestamp.
*
* @param string $path
*
* @return string
*/
function asset(string $path): string
@ -180,40 +196,48 @@ if (!function_exists('asset')) {
if (!function_exists('urlFor')) {
/**
* Generate the app url given a path
* @param string $path
* @param string $append
* Generate the app url given a path.
*
* @param string $path
* @param string $append
*
* @return string
*/
function urlFor(string $path = '', string $append = ''): string
{
$baseUrl = resolve('config')['base_url'];
return $baseUrl.$path.$append;
}
}
if (!function_exists('route')) {
/**
* Generate the app url given a path
* @param string $path
* @param array $args
* @param string $append
* Generate the app url given a path.
*
* @param string $path
* @param array $args
* @param string $append
*
* @return string
*/
function route(string $path, array $args = [], string $append = ''): string
{
global $app;
$uri = $app->getRouteCollector()->getRouteParser()->relativeUrlFor($path, $args);
return urlFor($uri, $append);
}
}
if (!function_exists('param')) {
/**
* Get a parameter from the request
* @param Request $request
* @param string $name
* @param null $default
* Get a parameter from the request.
*
* @param Request $request
* @param string $name
* @param null $default
*
* @return string
*/
function param(Request $request, string $name, $default = null)
@ -227,22 +251,26 @@ if (!function_exists('param')) {
if (isset($params[$name])) {
return $params[$name];
}
return $default;
}
}
if (!function_exists('json')) {
/**
* Return a json response
* @param Response $response
* Return a json response.
*
* @param Response $response
* @param $data
* @param int $status
* @param int $options
* @param int $status
* @param int $options
*
* @return Response
*/
function json(Response $response, $data, int $status = 200, $options = 0): Response
{
$response->getBody()->write(json_encode($data, $options));
return $response
->withStatus($status)
->withHeader('Content-Type', 'application/json');
@ -251,8 +279,9 @@ if (!function_exists('json')) {
if (!function_exists('lang')) {
/**
* @param string $key
* @param array $args
* @param string $key
* @param array $args
*
* @return string
*/
function lang(string $key, $args = []): string
@ -263,8 +292,9 @@ if (!function_exists('lang')) {
if (!function_exists('isBot')) {
/**
* @param string $userAgent
* @return boolean
* @param string $userAgent
*
* @return bool
*/
function isBot(string $userAgent)
{
@ -290,34 +320,36 @@ if (!function_exists('isBot')) {
if (!function_exists('mime2font')) {
/**
* Convert get the icon from the file mimetype
* Convert get the icon from the file mimetype.
*
* @param $mime
*
* @return mixed|string
*/
function mime2font($mime)
{
$classes = [
'image' => 'fa-file-image',
'audio' => 'fa-file-audio',
'video' => 'fa-file-video',
'application/pdf' => 'fa-file-pdf',
'application/msword' => 'fa-file-word',
'application/vnd.ms-word' => 'fa-file-word',
'application/vnd.oasis.opendocument.text' => 'fa-file-word',
'image' => 'fa-file-image',
'audio' => 'fa-file-audio',
'video' => 'fa-file-video',
'application/pdf' => 'fa-file-pdf',
'application/msword' => 'fa-file-word',
'application/vnd.ms-word' => 'fa-file-word',
'application/vnd.oasis.opendocument.text' => 'fa-file-word',
'application/vnd.openxmlformats-officedocument.wordprocessingml' => 'fa-file-word',
'application/vnd.ms-excel' => 'fa-file-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml' => 'fa-file-excel',
'application/vnd.oasis.opendocument.spreadsheet' => 'fa-file-excel',
'application/vnd.ms-powerpoint' => 'fa-file-powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml' => 'fa-file-powerpoint',
'application/vnd.oasis.opendocument.presentation' => 'fa-file-powerpoint',
'text/plain' => 'fa-file-alt',
'text/html' => 'fa-file-code',
'text/x-php' => 'fa-file-code',
'application/json' => 'fa-file-code',
'application/gzip' => 'fa-file-archive',
'application/zip' => 'fa-file-archive',
'application/octet-stream' => 'fa-file-alt',
'application/vnd.ms-excel' => 'fa-file-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml' => 'fa-file-excel',
'application/vnd.oasis.opendocument.spreadsheet' => 'fa-file-excel',
'application/vnd.ms-powerpoint' => 'fa-file-powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml' => 'fa-file-powerpoint',
'application/vnd.oasis.opendocument.presentation' => 'fa-file-powerpoint',
'text/plain' => 'fa-file-alt',
'text/html' => 'fa-file-code',
'text/x-php' => 'fa-file-code',
'application/json' => 'fa-file-code',
'application/gzip' => 'fa-file-archive',
'application/zip' => 'fa-file-archive',
'application/octet-stream' => 'fa-file-alt',
];
foreach ($classes as $fullMime => $class) {
@ -325,6 +357,7 @@ if (!function_exists('mime2font')) {
return $class;
}
}
return 'fa-file';
}
}
@ -347,7 +380,9 @@ if (!function_exists('dd')) {
if (!function_exists('queryParams')) {
/**
* Get the query parameters of the current request.
* @param array $replace
*
* @param array $replace
*
* @return string
*/
function queryParams(array $replace = [])
@ -362,23 +397,28 @@ if (!function_exists('queryParams')) {
if (!function_exists('inPath')) {
/**
* Check if uri start with a path
* @param string $uri
* @param string $path
* Check if uri start with a path.
*
* @param string $uri
* @param string $path
*
* @return bool
*/
function inPath(string $uri, string $path): bool
{
$path = parse_url(urlFor($path), PHP_URL_PATH);
return substr($uri, 0, strlen($uri)) === $path;
}
}
if (!function_exists('glob_recursive')) {
/**
* Does not support flag GLOB_BRACE
* Does not support flag GLOB_BRACE.
*
* @param $pattern
* @param int $flags
* @param int $flags
*
* @return array|false
*/
function glob_recursive($pattern, $flags = 0)
@ -387,6 +427,7 @@ if (!function_exists('glob_recursive')) {
foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
$files = array_merge($files, glob_recursive($dir.'/'.basename($pattern), $flags));
}
return $files;
}
}
@ -394,12 +435,15 @@ if (!function_exists('glob_recursive')) {
if (!function_exists('dsnFromConfig')) {
/**
* Return the database DSN from config.
* @param array $config
*
* @param array $config
*
* @return string
*/
function dsnFromConfig(array $config): string
{
$dsn = $config['db']['connection'] === 'sqlite' ? BASE_DIR.$config['db']['dsn'] : $config['db']['dsn'];
return $config['db']['connection'].':'.$dsn;
}
}

View file

@ -1,4 +1,5 @@
<?php
// Auth routes
use App\Controllers\AdminController;
use App\Controllers\ClientController;
@ -40,7 +41,6 @@ $app->group('', function (RouteCollectorProxy $group) {
})->add(AdminMiddleware::class);
$group->group('/user', function (RouteCollectorProxy $group) {
$group->get('/create', [UserController::class, 'create'])->setName('user.create');
$group->post('/create', [UserController::class, 'store'])->setName('user.store');
$group->get('/{id}/edit', [UserController::class, 'edit'])->setName('user.edit');
@ -58,7 +58,6 @@ $app->group('', function (RouteCollectorProxy $group) {
$group->post('/upload/{id}/unpublish', [MediaController::class, 'togglePublish'])->setName('upload.unpublish');
$group->get('/upload/{id}/raw', [MediaController::class, 'getRawById'])->add(AdminMiddleware::class)->setName('upload.raw');
$group->post('/upload/{id}/delete', [MediaController::class, 'delete'])->setName('upload.delete');
})->add(App\Middleware\CheckForMaintenanceMiddleware::class)->add(AuthMiddleware::class);
$app->get('/', [DashboardController::class, 'redirects'])->setName('root');

View file

@ -9,12 +9,12 @@ use App\Middleware\RememberMiddleware;
use App\Web\View;
use DI\Bridge\Slim\Bridge;
use DI\ContainerBuilder;
use Psr\Container\ContainerInterface as Container;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use function DI\factory;
use function DI\get;
use function DI\value;
use Psr\Container\ContainerInterface as Container;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
if (!file_exists('config.php') && is_dir('install/')) {
header('Location: ./install/');
@ -27,19 +27,19 @@ if (!file_exists('config.php') && is_dir('install/')) {
// Load the config
$config = array_replace_recursive([
'app_name' => 'XBackBone',
'base_url' => isset($_SERVER['HTTPS']) ? 'https://'.$_SERVER['HTTP_HOST'] : 'http://'.$_SERVER['HTTP_HOST'],
'debug' => false,
'app_name' => 'XBackBone',
'base_url' => isset($_SERVER['HTTPS']) ? 'https://'.$_SERVER['HTTP_HOST'] : 'http://'.$_SERVER['HTTP_HOST'],
'debug' => false,
'maintenance' => false,
'db' => [
'db' => [
'connection' => 'sqlite',
'dsn' => BASE_DIR.'resources/database/xbackbone.db',
'username' => null,
'password' => null,
'dsn' => BASE_DIR.'resources/database/xbackbone.db',
'username' => null,
'password' => null,
],
'storage' => [
'driver' => 'local',
'path' => realpath(__DIR__.'/').DIRECTORY_SEPARATOR.'storage',
'path' => realpath(__DIR__.'/').DIRECTORY_SEPARATOR.'storage',
],
], require BASE_DIR.'config.php');
@ -51,7 +51,7 @@ if (!$config['debug']) {
}
$builder->addDefinitions([
'config' => value($config),
'config' => value($config),
View::class => factory(function (Container $container) {
return ViewFactory::createAppInstance($container);
}),
@ -84,7 +84,7 @@ $app->add(function (Request $request, RequestHandler $handler) use (&$app, &$con
if ($request->getMethod() === 'GET') {
return $app->getResponseFactory()
->createResponse(301)
->withHeader('Location', (string)$uri);
->withHeader('Location', (string) $uri);
} else {
$request = $request->withUri($uri);
}

View file

@ -1,11 +1,11 @@
<?php
use App\Database\DB;
use App\Factories\ViewFactory;
use App\Web\Lang;
use App\Web\Session;
use App\Web\View;
use Aws\S3\S3Client;
use function DI\factory;
use function DI\get;
use Google\Cloud\Storage\StorageClient;
use League\Flysystem\Adapter\Ftp as FtpAdapter;
use League\Flysystem\Adapter\Local;
@ -18,8 +18,6 @@ use Psr\Container\ContainerInterface as Container;
use Spatie\Dropbox\Client as DropboxClient;
use Spatie\FlysystemDropbox\DropboxAdapter;
use Superbalist\Flysystem\GoogleStorage\GoogleStorageAdapter;
use function DI\factory;
use function DI\get;
return [
Logger::class => factory(function () {
@ -27,7 +25,7 @@ return [
$streamHandler = new RotatingFileHandler(BASE_DIR.'logs/log.txt', 10, Logger::DEBUG);
$lineFormatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", "Y-m-d H:i:s");
$lineFormatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", 'Y-m-d H:i:s');
$lineFormatter->includeStacktraces(true);
$streamHandler->setFormatter($lineFormatter);
@ -45,6 +43,7 @@ return [
DB::class => factory(function (Container $container) {
$config = $container->get('config');
return new DB(dsnFromConfig($config), $config['db']['username'], $config['db']['password']);
}),
'database' => get(DB::class),
@ -57,33 +56,35 @@ return [
case 's3':
$client = new S3Client([
'credentials' => [
'key' => $config['storage']['key'],
'key' => $config['storage']['key'],
'secret' => $config['storage']['secret'],
],
'region' => $config['storage']['region'],
'region' => $config['storage']['region'],
'version' => 'latest',
]);
return new Filesystem(new AwsS3Adapter($client, $config['storage']['bucket'], $config['storage']['path']));
case 'dropbox':
$client = new DropboxClient($config['storage']['token']);
return new Filesystem(new DropboxAdapter($client), ['case_sensitive' => false]);
case 'ftp':
return new Filesystem(new FtpAdapter([
'host' => $config['storage']['host'],
'host' => $config['storage']['host'],
'username' => $config['storage']['username'],
'password' => $config['storage']['password'],
'port' => $config['storage']['port'],
'root' => $config['storage']['path'],
'passive' => $config['storage']['passive'],
'ssl' => $config['storage']['ssl'],
'timeout' => 30,
'port' => $config['storage']['port'],
'root' => $config['storage']['path'],
'passive' => $config['storage']['passive'],
'ssl' => $config['storage']['ssl'],
'timeout' => 30,
]));
case 'google-cloud':
$client = new StorageClient([
'projectId' => $config['storage']['project_id'],
'projectId' => $config['storage']['project_id'],
'keyFilePath' => $config['storage']['key_path'],
]);
return new Filesystem(new GoogleStorageAdapter($client, $client->bucket($config['storage']['bucket'])));
default:
throw new InvalidArgumentException('The driver specified is not supported.');

View file

@ -1,14 +1,15 @@
<?php
return [
'base_url' => 'https://localhost', // no trailing slash
'db' => [
'connection' => 'sqlite',
'dsn' => 'resources/database/xbackbone.db',
'username' => null,
'password' => null,
],
'storage' => [
'driver' => 'local',
'path' => './storage',
],
'db' => [
'connection' => 'sqlite',
'dsn' => 'resources/database/xbackbone.db',
'username' => null,
'password' => null,
],
'storage' => [
'driver' => 'local',
'path' => './storage',
],
];

View file

@ -1,9 +1,10 @@
<?php
(PHP_MAJOR_VERSION >= 7 && PHP_MINOR_VERSION >= 1) ?: die('Sorry, PHP 7.1 or above is required to run XBackBone.');
require __DIR__ . '/vendor/autoload.php';
define('BASE_DIR', realpath(__DIR__) . DIRECTORY_SEPARATOR);
(PHP_MAJOR_VERSION >= 7 && PHP_MINOR_VERSION >= 1) ?: die('Sorry, PHP 7.1 or above is required to run XBackBone.');
require __DIR__.'/vendor/autoload.php';
define('BASE_DIR', realpath(__DIR__).DIRECTORY_SEPARATOR);
define('PLATFORM_VERSION', json_decode(file_get_contents('composer.json'))->version);
$app = require_once __DIR__ . '/bootstrap/app.php';
$app = require_once __DIR__.'/bootstrap/app.php';
$app->run();

View file

@ -1,4 +1,5 @@
<?php
(PHP_MAJOR_VERSION >= 7 && PHP_MINOR_VERSION >= 1) ?: die('Sorry, PHP 7.1 or above is required to run XBackBone.');
require __DIR__.'/../vendor/autoload.php';
@ -9,14 +10,14 @@ use App\Web\Session;
use App\Web\View;
use DI\Bridge\Slim\Bridge;
use DI\ContainerBuilder;
use function DI\factory;
use function DI\get;
use function DI\value;
use League\Flysystem\FileExistsException;
use League\Flysystem\Filesystem;
use Psr\Container\ContainerInterface as Container;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use function DI\factory;
use function DI\get;
use function DI\value;
define('PLATFORM_VERSION', json_decode(file_get_contents(__DIR__.'/../composer.json'))->version);
define('BASE_DIR', realpath(__DIR__.'/../').DIRECTORY_SEPARATOR);
@ -24,16 +25,16 @@ define('BASE_DIR', realpath(__DIR__.'/../').DIRECTORY_SEPARATOR);
// default config
$config = [
'base_url' => str_replace('/install/', '', (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http')."://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"),
'debug' => true,
'db' => [
'debug' => true,
'db' => [
'connection' => 'sqlite',
'dsn' => realpath(__DIR__.'/../').implode(DIRECTORY_SEPARATOR, ['resources', 'database', 'xbackbone.db']),
'username' => null,
'password' => null,
'dsn' => realpath(__DIR__.'/../').implode(DIRECTORY_SEPARATOR, ['resources', 'database', 'xbackbone.db']),
'username' => null,
'password' => null,
],
'storage' => [
'driver' => 'local',
'path' => realpath(__DIR__.'/../').DIRECTORY_SEPARATOR.'storage',
'path' => realpath(__DIR__.'/../').DIRECTORY_SEPARATOR.'storage',
],
];
@ -44,7 +45,7 @@ if (file_exists(__DIR__.'/../config.php')) {
$builder = new ContainerBuilder();
$builder->addDefinitions([
'config' => value($config),
'config' => value($config),
View::class => factory(function (Container $container) {
return ViewFactory::createInstallerInstance($container);
}),
@ -57,7 +58,6 @@ $app->setBasePath(parse_url($config['base_url'].'/install', PHP_URL_PATH));
$app->addRoutingMiddleware();
$app->get('/', function (Response $response, View $view, Session $session) use (&$config) {
if (!extension_loaded('gd')) {
$session->alert('The required "gd" extension is not loaded.', 'danger');
}
@ -109,7 +109,6 @@ $app->post('/', function (Request $request, Response $response, Filesystem $stor
$config['db']['username'] = param($request, 'db_user');
$config['db']['password'] = param($request, 'db_password');
// setup storage configuration
switch ($config['storage']['driver']) {
case 's3':
@ -125,6 +124,7 @@ $app->post('/', function (Request $request, Response $response, Filesystem $stor
case 'ftp':
if (!extension_loaded('ftp')) {
$session->alert('The "ftp" extension is not loaded.', 'danger');
return redirect($response, urlFor('/'));
}
$config['storage']['host'] = param($request, 'storage_host');
@ -149,6 +149,7 @@ $app->post('/', function (Request $request, Response $response, Filesystem $stor
// check if the storage is valid
$storageTestFile = 'storage_test.xbackbone.txt';
try {
try {
$success = $storage->write($storageTestFile, 'XBACKBONE_TEST_FILE');
@ -162,6 +163,7 @@ $app->post('/', function (Request $request, Response $response, Filesystem $stor
$storage->readAndDelete($storageTestFile);
} catch (Exception $e) {
$session->alert("Storage setup error: {$e->getMessage()} [{$e->getCode()}]", 'danger');
return redirect($response, urlFor('/install'));
}
@ -187,6 +189,7 @@ $app->post('/', function (Request $request, Response $response, Filesystem $stor
$migrator->migrate();
} catch (PDOException $e) {
$session->alert("Cannot connect to the database: {$e->getMessage()} [{$e->getCode()}]", 'danger');
return redirect($response, urlFor('/install'));
}
@ -211,11 +214,13 @@ $app->post('/', function (Request $request, Response $response, Filesystem $stor
$ret = file_put_contents(__DIR__.'/../config.php', '<?php'.PHP_EOL.'return '.var_export($config, true).';');
if ($ret === false) {
$session->alert('The config folder is not writable ('.__DIR__.'/../config.php'.')', 'danger');
return redirect($response, '/install');
}
// Installed successfully, destroy the installer session
$session->destroy();
return redirect($response, urlFor('/?afterInstall=true'));
});

View file

@ -1,72 +1,73 @@
<?php
return [
'lang' => 'Bulgarian',
'enforce_language' => 'Изберете език',
'yes' => 'Да',
'no' => 'Не',
'send' => 'Изпрати',
'no_media' => 'Не бяха намерени файлове.',
'login.username' => 'Потребителско име или E-Mail',
'password' => 'Парола',
'login' => 'Влезте',
'username' => 'Потребителско име',
'home' => 'Начална страница',
'users' => 'Потребители',
'system' => 'Система',
'profile' => 'Профил',
'logout' => 'Излезте',
'pager.next' => 'Следващо',
'pager.previous' => 'Предишно',
'copy_link' => 'Копирай линк',
'public.telegram' => 'Сподели по Telegram',
'lang' => 'Bulgarian',
'enforce_language' => 'Изберете език',
'yes' => 'Да',
'no' => 'Не',
'send' => 'Изпрати',
'no_media' => 'Не бяха намерени файлове.',
'login.username' => 'Потребителско име или E-Mail',
'password' => 'Парола',
'login' => 'Влезте',
'username' => 'Потребителско име',
'home' => 'Начална страница',
'users' => 'Потребители',
'system' => 'Система',
'profile' => 'Профил',
'logout' => 'Излезте',
'pager.next' => 'Следващо',
'pager.previous' => 'Предишно',
'copy_link' => 'Копирай линк',
'public.telegram' => 'Сподели по Telegram',
'public.delete_text' => 'Сигурни ли сте, че искате да изтриете това? Ще изчезне завинаги!',
'preview' => 'Предварителен преглед',
'filename' => 'Файлово име',
'size' => 'Размер',
'public' => 'Публично',
'owner' => 'Собственик',
'date' => 'Дата',
'raw' => 'Покажи оригинал',
'download' => 'Изтегли',
'delete' => 'Изтрий',
'publish' => 'Публикувай',
'hide' => 'Скрий',
'files' => 'Файлове',
'orphaned_files' => 'Загубени файлове',
'theme' => 'Тема',
'click_to_load' => 'Натиснете за да заредите...',
'apply' => 'Приложи',
'save' => 'Запомни',
'used' => 'Използвано',
'system_info' => 'Системна информация',
'user.create' => 'Създай потребител',
'user.edit' => 'Редактирай потребител',
'is_active' => 'Е активен',
'is_admin' => 'Е администратор',
'your_profile' => 'Вашия профил',
'token' => 'Ключ',
'copy' => 'Копирай',
'update' => 'Обнови',
'edit' => 'Редактирай',
'client_config' => 'Конфигурация на клиента',
'user_code' => 'Потребителски код',
'active' => 'Активен',
'admin' => 'Админ',
'reg_date' => 'Дата на регистрация',
'confirm' => 'Потвърждение',
'confirm_string' => 'Сигурни ли сте?',
'installed' => 'Инсталацията завърши успешно!',
'welcome' => 'Добре дошли, %s!',
'goodbye' => 'Довиждане!',
'email_required' => 'Имейлът е необходим.',
'email_taken' => 'Имейлът вече се използва.',
'username_required' => 'Потребителското име е необходимо.',
'username_taken' => 'Потребителското име вече е заето.',
'password_required' => 'Паролата е необходима.',
'user_created' => 'Потребител "%s" бе създаден!',
'user_updated' => 'Потребител "%s" бе обновен!',
'profile_updated' => 'Профилът бе обновен успешно!',
'user_deleted' => 'Потребителят бе изтрит.',
'cannot_delete' => 'Не можете да изтриете себе си.',
'gallery' => 'Галерия',
'preview' => 'Предварителен преглед',
'filename' => 'Файлово име',
'size' => 'Размер',
'public' => 'Публично',
'owner' => 'Собственик',
'date' => 'Дата',
'raw' => 'Покажи оригинал',
'download' => 'Изтегли',
'delete' => 'Изтрий',
'publish' => 'Публикувай',
'hide' => 'Скрий',
'files' => 'Файлове',
'orphaned_files' => 'Загубени файлове',
'theme' => 'Тема',
'click_to_load' => 'Натиснете за да заредите...',
'apply' => 'Приложи',
'save' => 'Запомни',
'used' => 'Използвано',
'system_info' => 'Системна информация',
'user.create' => 'Създай потребител',
'user.edit' => 'Редактирай потребител',
'is_active' => 'Е активен',
'is_admin' => 'Е администратор',
'your_profile' => 'Вашия профил',
'token' => 'Ключ',
'copy' => 'Копирай',
'update' => 'Обнови',
'edit' => 'Редактирай',
'client_config' => 'Конфигурация на клиента',
'user_code' => 'Потребителски код',
'active' => 'Активен',
'admin' => 'Админ',
'reg_date' => 'Дата на регистрация',
'confirm' => 'Потвърждение',
'confirm_string' => 'Сигурни ли сте?',
'installed' => 'Инсталацията завърши успешно!',
'welcome' => 'Добре дошли, %s!',
'goodbye' => 'Довиждане!',
'email_required' => 'Имейлът е необходим.',
'email_taken' => 'Имейлът вече се използва.',
'username_required' => 'Потребителското име е необходимо.',
'username_taken' => 'Потребителското име вече е заето.',
'password_required' => 'Паролата е необходима.',
'user_created' => 'Потребител "%s" бе създаден!',
'user_updated' => 'Потребител "%s" бе обновен!',
'profile_updated' => 'Профилът бе обновен успешно!',
'user_deleted' => 'Потребителят бе изтрит.',
'cannot_delete' => 'Не можете да изтриете себе си.',
'gallery' => 'Галерия',
];

View file

@ -1,46 +1,47 @@
<?php
return [
'lang' => 'Danish',
'yes' => 'Ja',
'no' => 'Nej',
'send' => 'Send',
'no_media' => 'Intet media fundet.',
'login.username' => 'Brugernavn eller E-Mail',
'password' => 'Adgangskode',
'login' => 'Log på',
'username' => 'Brugernavn',
'home' => 'Hjem',
'users' => 'Brugere',
'system' => 'System',
'profile' => 'Profil',
'logout' => 'Log ud',
'pager.next' => 'Næste',
'pager.previous' => 'Forrige',
'copy_link' => 'Kopier link',
'public.telegram' => 'Del på Telegram',
'lang' => 'Danish',
'yes' => 'Ja',
'no' => 'Nej',
'send' => 'Send',
'no_media' => 'Intet media fundet.',
'login.username' => 'Brugernavn eller E-Mail',
'password' => 'Adgangskode',
'login' => 'Log på',
'username' => 'Brugernavn',
'home' => 'Hjem',
'users' => 'Brugere',
'system' => 'System',
'profile' => 'Profil',
'logout' => 'Log ud',
'pager.next' => 'Næste',
'pager.previous' => 'Forrige',
'copy_link' => 'Kopier link',
'public.telegram' => 'Del på Telegram',
'public.delete_text' => 'Er du sikker på du vil slette denne genstand? Det vil blive slettet permanent!',
'preview' => 'Forhåndsvisning',
'filename' => 'Filnavn',
'size' => 'Størrelse',
'public' => 'Offentligt',
'owner' => 'Ejer',
'date' => 'Dato',
'raw' => 'Vis rå',
'download' => 'Hent',
'delete' => 'Slet',
'publish' => 'Offentliggøre',
'hide' => 'Skjul',
'files' => 'Filer',
'orphaned_files' => 'Forældreløse filer',
'theme' => 'Tema',
'click_to_load' => 'Klik for at indlæse...',
'apply' => 'Anvend',
'save' => 'Gem',
'used' => 'Brugt',
'system_info' => 'System information',
'user.create' => 'Ny bruger',
'user.edit' => 'Rediger bruger',
'is_active' => 'Er aktiv',
'is_admin' => 'Er administrator',
'your_profile' => 'Din Profil',
'preview' => 'Forhåndsvisning',
'filename' => 'Filnavn',
'size' => 'Størrelse',
'public' => 'Offentligt',
'owner' => 'Ejer',
'date' => 'Dato',
'raw' => 'Vis rå',
'download' => 'Hent',
'delete' => 'Slet',
'publish' => 'Offentliggøre',
'hide' => 'Skjul',
'files' => 'Filer',
'orphaned_files' => 'Forældreløse filer',
'theme' => 'Tema',
'click_to_load' => 'Klik for at indlæse...',
'apply' => 'Anvend',
'save' => 'Gem',
'used' => 'Brugt',
'system_info' => 'System information',
'user.create' => 'Ny bruger',
'user.edit' => 'Rediger bruger',
'is_active' => 'Er aktiv',
'is_admin' => 'Er administrator',
'your_profile' => 'Din Profil',
];

View file

@ -1,116 +1,117 @@
<?php
return [
'lang' => 'German',
'yes' => 'Ja',
'no' => 'Nein',
'send' => 'Senden',
'no_media' => 'Datei nicht gefunden.',
'login.username' => 'Benutzername oder E-Mail',
'password' => 'Passwort',
'login' => 'Login',
'username' => 'Benutzername',
'home' => 'Startseite',
'users' => 'Benutzer',
'system' => 'System',
'profile' => 'Profil',
'logout' => 'Ausloggen',
'pager.next' => 'Nächste',
'pager.previous' => 'Zurück',
'copy_link' => 'Kopiere Link',
'public.telegram' => 'Teile auf Telegram',
'public.delete_text' => 'Möchtest du das wirklich löschen? Es wird dann für immer weg sein!',
'preview' => 'Vorschau',
'filename' => 'Dateiname',
'size' => 'Größe aller Datein',
'public' => 'Öffentlich',
'owner' => 'Besitzer',
'date' => 'Datum',
'raw' => 'zeige RAW',
'download' => 'Herunterladen',
'delete' => 'Löschen',
'publish' => 'Veröffentlichen',
'hide' => 'Verstecken',
'files' => 'Datei(n)',
'orphaned_files' => 'verwaiste Dateien',
'theme' => 'Design',
'click_to_load' => 'Klick um zu laden...',
'apply' => 'Sichern',
'save' => 'Speichern',
'used' => 'Benutzen',
'system_info' => 'System Informationen',
'user.create' => 'Benutzer erstellen',
'user.edit' => 'Benutzer bearbeiten',
'is_active' => 'ist aktiviert',
'is_admin' => 'ist Administrator',
'your_profile' => 'Dein Profil',
'token' => 'Schlüssel',
'copy' => 'Kopieren',
'update' => 'Aktualisieren',
'edit' => 'Bearbeiten',
'client_config' => 'Benutzereinstellungen',
'user_code' => 'Benutzer-ID',
'active' => 'Aktiv',
'admin' => 'Administrator',
'reg_date' => 'Registrierungsdatum',
'none' => 'keine',
'open' => 'Offen',
'confirm' => 'Bestätigung',
'confirm_string' => 'Bist du sicher?',
'installed' => 'Installation erfolgreich abgeschlossen!',
'bad_login' => 'Falsche Anmeldeinformationen.',
'account_disabled' => 'Dein Account ist deaktiviert.',
'welcome' => 'Willkommen, %s!',
'goodbye' => 'Auf Wiedersehen!',
'token_not_found' => 'Das angegebene Schlüssel wurde nicht gefunden.',
'email_required' => 'Die E-Mail ist erforderlich.',
'email_taken' => 'Die E-Mail ist bereits vergeben.',
'username_required' => 'Der Benutzername ist erforderlich.',
'username_taken' => 'Der Benutzername ist bereits vergeben.',
'password_required' => 'Das Passwort ist erforderlich.',
'user_created' => 'Benutzer "%s" wurde erstellt!',
'user_updated' => 'Benutzer "%s" wurde aktualisiert!',
'profile_updated' => 'Profil erfolgreich aktualisiert!',
'user_deleted' => 'Benutzer gelöscht.',
'cannot_delete' => 'Du kannst dich nicht selbst löschen.',
'cannot_demote' => 'Du kannst dich nicht selber degradieren.',
'cannot_write_file' => 'Der Ordner hat keine Schreibrechte.',
'switch_to' => 'Wechseln zu',
'gallery' => 'Galerie',
'table' => 'Tabelle',
'dotted_search' => 'Suche...',
'order_by' => 'Sortieren nach...',
'time' => 'Zeit',
'name' => 'Name',
'maintenance' => 'Wartungsarbeiten',
'clean_orphaned_uploads' => 'Leere verwaiste Uploads',
'path_not_writable' => 'Der Speicherort ist nicht beschreibbar.',
'already_latest_version' => 'Sie haben bereits die neueste Version.',
'new_version_available' => 'Neue Version %s ist verfügbar!',
'cannot_retrieve_file' => 'Die Datei kann nicht abgerufen werden.',
'file_size_no_match' => 'Die heruntergeladene Datei stimmt nicht mit der richtigen Dateigröße überein.',
'check_for_updates' => 'Auf Updates prüfen',
'upgrade' => 'Aktualisierung',
'updates' => 'Updates',
'lang' => 'German',
'yes' => 'Ja',
'no' => 'Nein',
'send' => 'Senden',
'no_media' => 'Datei nicht gefunden.',
'login.username' => 'Benutzername oder E-Mail',
'password' => 'Passwort',
'login' => 'Login',
'username' => 'Benutzername',
'home' => 'Startseite',
'users' => 'Benutzer',
'system' => 'System',
'profile' => 'Profil',
'logout' => 'Ausloggen',
'pager.next' => 'Nächste',
'pager.previous' => 'Zurück',
'copy_link' => 'Kopiere Link',
'public.telegram' => 'Teile auf Telegram',
'public.delete_text' => 'Möchtest du das wirklich löschen? Es wird dann für immer weg sein!',
'preview' => 'Vorschau',
'filename' => 'Dateiname',
'size' => 'Größe aller Datein',
'public' => 'Öffentlich',
'owner' => 'Besitzer',
'date' => 'Datum',
'raw' => 'zeige RAW',
'download' => 'Herunterladen',
'delete' => 'Löschen',
'publish' => 'Veröffentlichen',
'hide' => 'Verstecken',
'files' => 'Datei(n)',
'orphaned_files' => 'verwaiste Dateien',
'theme' => 'Design',
'click_to_load' => 'Klick um zu laden...',
'apply' => 'Sichern',
'save' => 'Speichern',
'used' => 'Benutzen',
'system_info' => 'System Informationen',
'user.create' => 'Benutzer erstellen',
'user.edit' => 'Benutzer bearbeiten',
'is_active' => 'ist aktiviert',
'is_admin' => 'ist Administrator',
'your_profile' => 'Dein Profil',
'token' => 'Schlüssel',
'copy' => 'Kopieren',
'update' => 'Aktualisieren',
'edit' => 'Bearbeiten',
'client_config' => 'Benutzereinstellungen',
'user_code' => 'Benutzer-ID',
'active' => 'Aktiv',
'admin' => 'Administrator',
'reg_date' => 'Registrierungsdatum',
'none' => 'keine',
'open' => 'Offen',
'confirm' => 'Bestätigung',
'confirm_string' => 'Bist du sicher?',
'installed' => 'Installation erfolgreich abgeschlossen!',
'bad_login' => 'Falsche Anmeldeinformationen.',
'account_disabled' => 'Dein Account ist deaktiviert.',
'welcome' => 'Willkommen, %s!',
'goodbye' => 'Auf Wiedersehen!',
'token_not_found' => 'Das angegebene Schlüssel wurde nicht gefunden.',
'email_required' => 'Die E-Mail ist erforderlich.',
'email_taken' => 'Die E-Mail ist bereits vergeben.',
'username_required' => 'Der Benutzername ist erforderlich.',
'username_taken' => 'Der Benutzername ist bereits vergeben.',
'password_required' => 'Das Passwort ist erforderlich.',
'user_created' => 'Benutzer "%s" wurde erstellt!',
'user_updated' => 'Benutzer "%s" wurde aktualisiert!',
'profile_updated' => 'Profil erfolgreich aktualisiert!',
'user_deleted' => 'Benutzer gelöscht.',
'cannot_delete' => 'Du kannst dich nicht selbst löschen.',
'cannot_demote' => 'Du kannst dich nicht selber degradieren.',
'cannot_write_file' => 'Der Ordner hat keine Schreibrechte.',
'switch_to' => 'Wechseln zu',
'gallery' => 'Galerie',
'table' => 'Tabelle',
'dotted_search' => 'Suche...',
'order_by' => 'Sortieren nach...',
'time' => 'Zeit',
'name' => 'Name',
'maintenance' => 'Wartungsarbeiten',
'clean_orphaned_uploads' => 'Leere verwaiste Uploads',
'path_not_writable' => 'Der Speicherort ist nicht beschreibbar.',
'already_latest_version' => 'Sie haben bereits die neueste Version.',
'new_version_available' => 'Neue Version %s ist verfügbar!',
'cannot_retrieve_file' => 'Die Datei kann nicht abgerufen werden.',
'file_size_no_match' => 'Die heruntergeladene Datei stimmt nicht mit der richtigen Dateigröße überein.',
'check_for_updates' => 'Auf Updates prüfen',
'upgrade' => 'Aktualisierung',
'updates' => 'Updates',
'maintenance_in_progress' => 'Die Seite macht Wartungsarbeiten, bitte versuche es später noch einmal.',
'cancel' => 'Abbruch',
'deleted_orphans' => '%d verwaiste Dateie(n) wurden erfolgreich gelöscht.',
'enforce_language' => 'Name der Sprache',
'auto_set' => 'Automatisch einstellen',
'translated_strings' => 'übersetzte Zeichen',
'total_strings' => 'Übersetzt',
'lang_name' => 'Name von der Sprache',
'default_lang_behavior' => 'XBackBone versucht von dein Browser die Sprache herauszufinden (Standard: English).',
'lang_set' => 'Sprache ist jetzt "%s"',
'prerelease_channel' => 'Beta Channel',
'upload' => 'Hochladen',
'no_upload_token' => 'Sie haben kein persönlichen Token. (Erstellen Sie eine und versuchen Sie es erneut.)',
'drop_to_upload' => 'Klicken sie hier oder ziehen sie die Datei hier rein.',
'donation' => 'Spenden',
'donate_text' => 'Wenn sie XBackBone mögen und sie die Entwicklung unterstützen möchten, spenden sie einen kleinen Beitrag!',
'custom_head_html' => 'Eigenes HTML Head Content',
'custom_head_html_hint' => 'Dieser Inhalt wird auf jeder Seite am Tag <head> hinzugefügt.',
'custom_head_set' => 'Benutzerdefinierter HTML Head wurde angewendet.',
'remember_me' => 'Erinnere mich daran',
'please_wait' => 'Bitte warten…',
'dont_close' => 'Schließen Sie diesen Tab erst, wenn Sie fertig sind.',
'cancel' => 'Abbruch',
'deleted_orphans' => '%d verwaiste Dateie(n) wurden erfolgreich gelöscht.',
'enforce_language' => 'Name der Sprache',
'auto_set' => 'Automatisch einstellen',
'translated_strings' => 'übersetzte Zeichen',
'total_strings' => 'Übersetzt',
'lang_name' => 'Name von der Sprache',
'default_lang_behavior' => 'XBackBone versucht von dein Browser die Sprache herauszufinden (Standard: English).',
'lang_set' => 'Sprache ist jetzt "%s"',
'prerelease_channel' => 'Beta Channel',
'upload' => 'Hochladen',
'no_upload_token' => 'Sie haben kein persönlichen Token. (Erstellen Sie eine und versuchen Sie es erneut.)',
'drop_to_upload' => 'Klicken sie hier oder ziehen sie die Datei hier rein.',
'donation' => 'Spenden',
'donate_text' => 'Wenn sie XBackBone mögen und sie die Entwicklung unterstützen möchten, spenden sie einen kleinen Beitrag!',
'custom_head_html' => 'Eigenes HTML Head Content',
'custom_head_html_hint' => 'Dieser Inhalt wird auf jeder Seite am Tag <head> hinzugefügt.',
'custom_head_set' => 'Benutzerdefinierter HTML Head wurde angewendet.',
'remember_me' => 'Erinnere mich daran',
'please_wait' => 'Bitte warten…',
'dont_close' => 'Schließen Sie diesen Tab erst, wenn Sie fertig sind.',
];

View file

@ -1,113 +1,114 @@
<?php
return [
'lang' => 'English',
'enforce_language' => 'Enforce language',
'yes' => 'Yes',
'no' => 'No',
'send' => 'Send',
'no_media' => 'No media found.',
'login.username' => 'Username or E-Mail',
'password' => 'Password',
'login' => 'Login',
'username' => 'Username',
'home' => 'Home',
'users' => 'Users',
'system' => 'System',
'profile' => 'Profile',
'logout' => 'Logout',
'pager.next' => 'Next',
'pager.previous' => 'Previous',
'copy_link' => 'Copy link',
'public.telegram' => 'Share on Telegram',
'public.delete_text' => 'Are you sure you want to delete this item? It will be gone forever!',
'preview' => 'Preview',
'filename' => 'Filename',
'size' => 'Size',
'public' => 'Public',
'owner' => 'Owner',
'date' => 'Date',
'raw' => 'Show raw',
'download' => 'Download',
'upload' => 'Upload',
'delete' => 'Delete',
'publish' => 'Publish',
'hide' => 'Hide',
'files' => 'Files',
'orphaned_files' => 'Orphaned Files',
'theme' => 'Theme',
'click_to_load' => 'Click to load...',
'apply' => 'Apply',
'save' => 'Save',
'used' => 'Used',
'system_info' => 'System Information',
'user.create' => 'Create User',
'user.edit' => 'Edit User',
'is_active' => 'Is active',
'is_admin' => 'Is administrator',
'your_profile' => 'Your Profile',
'token' => 'Token',
'copy' => 'Copy',
'update' => 'Update',
'edit' => 'Edit',
'client_config' => 'Client Configuration',
'user_code' => 'User Code',
'active' => 'Active',
'admin' => 'Admin',
'reg_date' => 'Registration Date',
'none' => 'None',
'open' => 'Open',
'confirm' => 'Confirmation',
'confirm_string' => 'Are you sure?',
'installed' => 'Installation completed successfully!',
'bad_login' => 'Wrong credentials.',
'account_disabled' => 'Your account is disabled.',
'welcome' => 'Welcome, %s!',
'goodbye' => 'Goodbye!',
'token_not_found' => 'Token specified not found.',
'email_required' => 'The email is required.',
'email_taken' => 'The email is already taken.',
'username_required' => 'The username is required.',
'username_taken' => 'The username is already taken.',
'password_required' => 'The password is required.',
'user_created' => 'User "%s" created!',
'user_updated' => 'User "%s" updated!',
'profile_updated' => 'Profile updated successfully!',
'user_deleted' => 'User deleted.',
'cannot_delete' => 'You cannot delete yourself.',
'cannot_demote' => 'You cannot demote yourself.',
'cannot_write_file' => 'The destination path is not writable.',
'deleted_orphans' => 'Successfully deleted %d orphaned files.',
'switch_to' => 'Switch to',
'gallery' => 'Gallery',
'table' => 'Table',
'dotted_search' => 'Search...',
'order_by' => 'Order by...',
'time' => 'Time',
'name' => 'Name',
'maintenance' => 'Maintenance',
'clean_orphaned_uploads' => 'Clean Orphaned Uploads',
'path_not_writable' => 'The output path is not writable.',
'already_latest_version' => 'You already have the latest version.',
'new_version_available' => 'New version %s available!',
'cannot_retrieve_file' => 'Cannot retrieve the file.',
'file_size_no_match' => 'The downloaded file doesn\'t match the correct file size.',
'check_for_updates' => 'Check for updates',
'upgrade' => 'Upgrade',
'updates' => 'Updates',
'lang' => 'English',
'enforce_language' => 'Enforce language',
'yes' => 'Yes',
'no' => 'No',
'send' => 'Send',
'no_media' => 'No media found.',
'login.username' => 'Username or E-Mail',
'password' => 'Password',
'login' => 'Login',
'username' => 'Username',
'home' => 'Home',
'users' => 'Users',
'system' => 'System',
'profile' => 'Profile',
'logout' => 'Logout',
'pager.next' => 'Next',
'pager.previous' => 'Previous',
'copy_link' => 'Copy link',
'public.telegram' => 'Share on Telegram',
'public.delete_text' => 'Are you sure you want to delete this item? It will be gone forever!',
'preview' => 'Preview',
'filename' => 'Filename',
'size' => 'Size',
'public' => 'Public',
'owner' => 'Owner',
'date' => 'Date',
'raw' => 'Show raw',
'download' => 'Download',
'upload' => 'Upload',
'delete' => 'Delete',
'publish' => 'Publish',
'hide' => 'Hide',
'files' => 'Files',
'orphaned_files' => 'Orphaned Files',
'theme' => 'Theme',
'click_to_load' => 'Click to load...',
'apply' => 'Apply',
'save' => 'Save',
'used' => 'Used',
'system_info' => 'System Information',
'user.create' => 'Create User',
'user.edit' => 'Edit User',
'is_active' => 'Is active',
'is_admin' => 'Is administrator',
'your_profile' => 'Your Profile',
'token' => 'Token',
'copy' => 'Copy',
'update' => 'Update',
'edit' => 'Edit',
'client_config' => 'Client Configuration',
'user_code' => 'User Code',
'active' => 'Active',
'admin' => 'Admin',
'reg_date' => 'Registration Date',
'none' => 'None',
'open' => 'Open',
'confirm' => 'Confirmation',
'confirm_string' => 'Are you sure?',
'installed' => 'Installation completed successfully!',
'bad_login' => 'Wrong credentials.',
'account_disabled' => 'Your account is disabled.',
'welcome' => 'Welcome, %s!',
'goodbye' => 'Goodbye!',
'token_not_found' => 'Token specified not found.',
'email_required' => 'The email is required.',
'email_taken' => 'The email is already taken.',
'username_required' => 'The username is required.',
'username_taken' => 'The username is already taken.',
'password_required' => 'The password is required.',
'user_created' => 'User "%s" created!',
'user_updated' => 'User "%s" updated!',
'profile_updated' => 'Profile updated successfully!',
'user_deleted' => 'User deleted.',
'cannot_delete' => 'You cannot delete yourself.',
'cannot_demote' => 'You cannot demote yourself.',
'cannot_write_file' => 'The destination path is not writable.',
'deleted_orphans' => 'Successfully deleted %d orphaned files.',
'switch_to' => 'Switch to',
'gallery' => 'Gallery',
'table' => 'Table',
'dotted_search' => 'Search...',
'order_by' => 'Order by...',
'time' => 'Time',
'name' => 'Name',
'maintenance' => 'Maintenance',
'clean_orphaned_uploads' => 'Clean Orphaned Uploads',
'path_not_writable' => 'The output path is not writable.',
'already_latest_version' => 'You already have the latest version.',
'new_version_available' => 'New version %s available!',
'cannot_retrieve_file' => 'Cannot retrieve the file.',
'file_size_no_match' => 'The downloaded file doesn\'t match the correct file size.',
'check_for_updates' => 'Check for updates',
'upgrade' => 'Upgrade',
'updates' => 'Updates',
'maintenance_in_progress' => 'Platform under maintenance, try again later...',
'cancel' => 'Cancel',
'auto_set' => 'Set automatically',
'default_lang_behavior' => 'XBackBone will try to match the browser language by default (the fallback is English).',
'lang_set' => 'System language enforced to "%s"',
'prerelease_channel' => 'Prerelease Channel',
'no_upload_token' => 'You don\'t have a personal upload token. (Generate one and try again.)',
'drop_to_upload' => 'Click or drop your files here to upload.',
'donation' => 'Donation',
'donate_text' => 'If you like XBackBone, consider a donation to support development!',
'custom_head_html' => 'Custom HTML Head content',
'custom_head_html_hint' => 'This content will be added at the <head> tag on every page.',
'custom_head_set' => 'Custom HTML head applied.',
'remember_me' => 'Remember me',
'please_wait' => 'Please wait…',
'dont_close' => 'Do not close this tab until completion.',
'cancel' => 'Cancel',
'auto_set' => 'Set automatically',
'default_lang_behavior' => 'XBackBone will try to match the browser language by default (the fallback is English).',
'lang_set' => 'System language enforced to "%s"',
'prerelease_channel' => 'Prerelease Channel',
'no_upload_token' => 'You don\'t have a personal upload token. (Generate one and try again.)',
'drop_to_upload' => 'Click or drop your files here to upload.',
'donation' => 'Donation',
'donate_text' => 'If you like XBackBone, consider a donation to support development!',
'custom_head_html' => 'Custom HTML Head content',
'custom_head_html_hint' => 'This content will be added at the <head> tag on every page.',
'custom_head_set' => 'Custom HTML head applied.',
'remember_me' => 'Remember me',
'please_wait' => 'Please wait…',
'dont_close' => 'Do not close this tab until completion.',
];

View file

@ -1,102 +1,103 @@
<?php
return [
'lang' => 'Spanish',
'yes' => 'Si',
'no' => 'No',
'send' => 'Enviar',
'no_media' => 'Contenido no encontrado.',
'login.username' => 'Nombre de usuario o Correo Electrónico',
'password' => 'Contraseña',
'login' => 'Iniciar sesión',
'username' => 'Nombre de usuario',
'home' => 'Inicio',
'users' => 'Usuarios',
'system' => 'Sistema',
'profile' => 'Perfil',
'logout' => 'Cerrar sesión',
'pager.next' => 'Siguiente',
'pager.previous' => 'Previo',
'copy_link' => 'Copiar enlace',
'public.telegram' => 'Compartir en Telegram',
'public.delete_text' => '¿Está seguro que desea borrar este elemento? ¡Será borrado para siempre!',
'preview' => 'Vista previa',
'filename' => 'Nombre del archivo',
'size' => 'Tamaño',
'public' => 'Público',
'owner' => 'Dueño',
'date' => 'Fecha',
'raw' => 'Mostrar archivo sin formato',
'download' => 'Descargar',
'delete' => 'Borrar',
'publish' => 'Publicar',
'hide' => 'Esconder',
'files' => 'Archivos',
'orphaned_files' => 'Archivos huérfanos',
'theme' => 'Tema',
'click_to_load' => 'Clic para cargar...',
'apply' => 'Aplicar',
'save' => 'Guardar',
'used' => 'Usado',
'system_info' => 'Información del Sistema',
'user.create' => 'Crear Usuario',
'user.edit' => 'Editar Usuario',
'is_active' => 'Está activo',
'is_admin' => 'Es administrador',
'your_profile' => 'Tu Perfil',
'token' => 'Ficha',
'copy' => 'Copiar',
'update' => 'Actualizar',
'edit' => 'Editar',
'client_config' => 'Configuración del Cliente',
'user_code' => 'Código de Usuario',
'active' => 'Activo',
'admin' => 'Administrador',
'reg_date' => 'Fecha de Registración',
'none' => 'Ninguno',
'open' => 'Abrir',
'confirm' => 'Confirmación',
'confirm_string' => '¿Está seguro?',
'installed' => '¡Instalación completa!',
'bad_login' => 'Credenciales incorrectas.',
'account_disabled' => 'Su cuenta está desactivada.',
'welcome' => '¡Bienvenido, %s!',
'goodbye' => '¡Adiós!',
'token_not_found' => 'Ficha indicada No encontrada.',
'email_required' => 'El Correo Electrónico es requisito.',
'email_taken' => 'El Correo Electrónico ya está en uso.',
'username_required' => 'El Nombre de Usuario es requisito.',
'username_taken' => 'El Nombre de Usuario ya está en uso.',
'password_required' => 'La Contraseña es requisito.',
'user_created' => '¡Usuario "%s" creado!',
'user_updated' => '¡Usuario "%s" actualizado!',
'profile_updated' => '¡Perfil actualizado con éxito!',
'user_deleted' => 'Usuario borrado.',
'cannot_delete' => 'No puede borrarse a usted mismo.',
'cannot_write_file' => 'La ruta de destino no se puede escribir.',
'deleted_orphans' => 'Borró los archivos huérfanos %d con éxito.',
'switch_to' => 'Cambiar a',
'gallery' => 'Galería',
'table' => 'Tabla',
'dotted_search' => 'Búsqueda...',
'order_by' => 'Ordenar por...',
'time' => 'Tiempo',
'name' => 'Nombre',
'maintenance' => 'Mantenimiento',
'path_not_writable' => 'La ruta de salida no se puede escribir.',
'already_latest_version' => 'Ya tiene la última versión.',
'new_version_available' => '¡Nueva versión %s disponible!',
'cannot_retrieve_file' => 'No se puede recuperar el archivo.',
'file_size_no_match' => 'El archivo descargado no coincide con el tamaño de archivo correcto.',
'check_for_updates' => 'Buscar actualizaciones',
'upgrade' => 'Mejorar',
'updates' => 'Actualizaciones',
'lang' => 'Spanish',
'yes' => 'Si',
'no' => 'No',
'send' => 'Enviar',
'no_media' => 'Contenido no encontrado.',
'login.username' => 'Nombre de usuario o Correo Electrónico',
'password' => 'Contraseña',
'login' => 'Iniciar sesión',
'username' => 'Nombre de usuario',
'home' => 'Inicio',
'users' => 'Usuarios',
'system' => 'Sistema',
'profile' => 'Perfil',
'logout' => 'Cerrar sesión',
'pager.next' => 'Siguiente',
'pager.previous' => 'Previo',
'copy_link' => 'Copiar enlace',
'public.telegram' => 'Compartir en Telegram',
'public.delete_text' => '¿Está seguro que desea borrar este elemento? ¡Será borrado para siempre!',
'preview' => 'Vista previa',
'filename' => 'Nombre del archivo',
'size' => 'Tamaño',
'public' => 'Público',
'owner' => 'Dueño',
'date' => 'Fecha',
'raw' => 'Mostrar archivo sin formato',
'download' => 'Descargar',
'delete' => 'Borrar',
'publish' => 'Publicar',
'hide' => 'Esconder',
'files' => 'Archivos',
'orphaned_files' => 'Archivos huérfanos',
'theme' => 'Tema',
'click_to_load' => 'Clic para cargar...',
'apply' => 'Aplicar',
'save' => 'Guardar',
'used' => 'Usado',
'system_info' => 'Información del Sistema',
'user.create' => 'Crear Usuario',
'user.edit' => 'Editar Usuario',
'is_active' => 'Está activo',
'is_admin' => 'Es administrador',
'your_profile' => 'Tu Perfil',
'token' => 'Ficha',
'copy' => 'Copiar',
'update' => 'Actualizar',
'edit' => 'Editar',
'client_config' => 'Configuración del Cliente',
'user_code' => 'Código de Usuario',
'active' => 'Activo',
'admin' => 'Administrador',
'reg_date' => 'Fecha de Registración',
'none' => 'Ninguno',
'open' => 'Abrir',
'confirm' => 'Confirmación',
'confirm_string' => '¿Está seguro?',
'installed' => '¡Instalación completa!',
'bad_login' => 'Credenciales incorrectas.',
'account_disabled' => 'Su cuenta está desactivada.',
'welcome' => '¡Bienvenido, %s!',
'goodbye' => '¡Adiós!',
'token_not_found' => 'Ficha indicada No encontrada.',
'email_required' => 'El Correo Electrónico es requisito.',
'email_taken' => 'El Correo Electrónico ya está en uso.',
'username_required' => 'El Nombre de Usuario es requisito.',
'username_taken' => 'El Nombre de Usuario ya está en uso.',
'password_required' => 'La Contraseña es requisito.',
'user_created' => '¡Usuario "%s" creado!',
'user_updated' => '¡Usuario "%s" actualizado!',
'profile_updated' => '¡Perfil actualizado con éxito!',
'user_deleted' => 'Usuario borrado.',
'cannot_delete' => 'No puede borrarse a usted mismo.',
'cannot_write_file' => 'La ruta de destino no se puede escribir.',
'deleted_orphans' => 'Borró los archivos huérfanos %d con éxito.',
'switch_to' => 'Cambiar a',
'gallery' => 'Galería',
'table' => 'Tabla',
'dotted_search' => 'Búsqueda...',
'order_by' => 'Ordenar por...',
'time' => 'Tiempo',
'name' => 'Nombre',
'maintenance' => 'Mantenimiento',
'path_not_writable' => 'La ruta de salida no se puede escribir.',
'already_latest_version' => 'Ya tiene la última versión.',
'new_version_available' => '¡Nueva versión %s disponible!',
'cannot_retrieve_file' => 'No se puede recuperar el archivo.',
'file_size_no_match' => 'El archivo descargado no coincide con el tamaño de archivo correcto.',
'check_for_updates' => 'Buscar actualizaciones',
'upgrade' => 'Mejorar',
'updates' => 'Actualizaciones',
'maintenance_in_progress' => 'Plataforma en mantenimiento, inténtelo más tarde...',
'cancel' => 'Cancelar',
'enforce_language' => 'Afirmar lenguaje',
'auto_set' => 'Establecer automáticamente',
'translated_strings' => 'cadenas de texto traducidas',
'total_strings' => 'total de cadenas de texto',
'lang_name' => 'nombre del lenguaje',
'default_lang_behavior' => 'XBackBone tratará de coincidir con el lenguaje predeterminado del navegador (recurrimos al Inglés automáticamente).',
'lang_set' => 'Lenguaje del sistema impuesto a "%s"',
'cancel' => 'Cancelar',
'enforce_language' => 'Afirmar lenguaje',
'auto_set' => 'Establecer automáticamente',
'translated_strings' => 'cadenas de texto traducidas',
'total_strings' => 'total de cadenas de texto',
'lang_name' => 'nombre del lenguaje',
'default_lang_behavior' => 'XBackBone tratará de coincidir con el lenguaje predeterminado del navegador (recurrimos al Inglés automáticamente).',
'lang_set' => 'Lenguaje del sistema impuesto a "%s"',
];

View file

@ -1,4 +1,5 @@
<?php
return [
'lang' => 'French',
];

View file

@ -1,113 +1,114 @@
<?php
return [
'lang' => 'Italian',
'yes' => 'Sì',
'no' => 'No',
'send' => 'Invia',
'no_media' => 'Nessun media trovato.',
'login.username' => 'Username o E-Mail',
'password' => 'Password',
'login' => 'Accedi',
'username' => 'Username',
'home' => 'Home',
'users' => 'Utenti',
'system' => 'Sistema',
'profile' => 'Profilo',
'logout' => 'Esci',
'pager.next' => 'Avanti',
'pager.previous' => 'Indietro',
'copy_link' => 'Copia link',
'public.telegram' => 'Condividi su Telegram',
'public.delete_text' => 'Sei sicuro di voler eliminare questo elemento? Andrà perso per sempre!',
'preview' => 'Anteprima',
'filename' => 'Nome file',
'size' => 'Dimensione',
'public' => 'Pubblico',
'owner' => 'Proprietario',
'date' => 'Data',
'raw' => 'Vedi raw',
'download' => 'Scarica',
'upload' => 'Carica',
'delete' => 'Elimina',
'publish' => 'Pubblica',
'hide' => 'Nascondi',
'files' => 'File',
'orphaned_files' => 'File orfani',
'theme' => 'Tema',
'click_to_load' => 'Clicca per caricare...',
'apply' => 'Applica',
'save' => 'Salva',
'used' => 'Usato',
'system_info' => 'Informazioni di Sistema',
'user.create' => 'Crea Utente',
'user.edit' => 'Modifica Utente',
'is_active' => 'Attivo',
'is_admin' => 'Amministratore',
'your_profile' => 'Il tuo profilo',
'token' => 'Token',
'copy' => 'Copia',
'update' => 'Aggiorna',
'edit' => 'Modifica',
'client_config' => 'Config. client',
'user_code' => 'Codice Utente',
'active' => 'Attivo',
'admin' => 'Amministratore',
'reg_date' => 'Data Registrazione',
'none' => 'Nessuno',
'open' => 'Apri',
'confirm' => 'Conferma',
'confirm_string' => 'Sei sicuro?',
'installed' => 'Installazione completata!',
'bad_login' => 'Credenziali errate.',
'account_disabled' => 'Il tuo account è disattivato.',
'welcome' => 'Benvenuto, %s!',
'goodbye' => 'Arrivederci!',
'token_not_found' => 'Il token specificato non è stato trovato.',
'email_required' => 'Email obbligatoria.',
'email_taken' => 'Email già in uso.',
'username_required' => 'Username obbligatorio.',
'username_taken' => 'Username già in uso.',
'password_required' => 'Password obbligatoria.',
'user_created' => 'L\'utente "%s" è stato creato!',
'user_updated' => 'L\'utente "%s" è stato aggiornato!',
'profile_updated' => 'Profilo aggiornato con successo!',
'user_deleted' => 'Utente rimosso.',
'cannot_delete' => 'Non puoi eliminare te stesso.',
'cannot_demote' => 'Non puoi degradare te stesso.',
'cannot_write_file' => 'Il percorso di destinazione non è scrivibile.',
'deleted_orphans' => 'Eliminati %d file orfani.',
'switch_to' => 'Vedi come',
'gallery' => 'Galleria',
'table' => 'Tabella',
'dotted_search' => 'Cerca...',
'order_by' => 'Ordina per...',
'time' => 'Data',
'name' => 'Nome',
'maintenance' => 'Manutenzione',
'clean_orphaned_uploads' => 'Pulisci upload orfani',
'path_not_writable' => 'Il percorso di output non è scrivibile.',
'already_latest_version' => 'Hai già l\'ultima versione disponibile.',
'new_version_available' => 'Nuova versione disponibile: %s',
'cannot_retrieve_file' => 'Impossibile scaricare il file.',
'file_size_no_match' => 'La dimensione del file scaricato non è corretta.',
'check_for_updates' => 'Controllo aggiornamenti',
'upgrade' => 'Upgrade',
'updates' => 'Aggiornamenti',
'lang' => 'Italian',
'yes' => 'Sì',
'no' => 'No',
'send' => 'Invia',
'no_media' => 'Nessun media trovato.',
'login.username' => 'Username o E-Mail',
'password' => 'Password',
'login' => 'Accedi',
'username' => 'Username',
'home' => 'Home',
'users' => 'Utenti',
'system' => 'Sistema',
'profile' => 'Profilo',
'logout' => 'Esci',
'pager.next' => 'Avanti',
'pager.previous' => 'Indietro',
'copy_link' => 'Copia link',
'public.telegram' => 'Condividi su Telegram',
'public.delete_text' => 'Sei sicuro di voler eliminare questo elemento? Andrà perso per sempre!',
'preview' => 'Anteprima',
'filename' => 'Nome file',
'size' => 'Dimensione',
'public' => 'Pubblico',
'owner' => 'Proprietario',
'date' => 'Data',
'raw' => 'Vedi raw',
'download' => 'Scarica',
'upload' => 'Carica',
'delete' => 'Elimina',
'publish' => 'Pubblica',
'hide' => 'Nascondi',
'files' => 'File',
'orphaned_files' => 'File orfani',
'theme' => 'Tema',
'click_to_load' => 'Clicca per caricare...',
'apply' => 'Applica',
'save' => 'Salva',
'used' => 'Usato',
'system_info' => 'Informazioni di Sistema',
'user.create' => 'Crea Utente',
'user.edit' => 'Modifica Utente',
'is_active' => 'Attivo',
'is_admin' => 'Amministratore',
'your_profile' => 'Il tuo profilo',
'token' => 'Token',
'copy' => 'Copia',
'update' => 'Aggiorna',
'edit' => 'Modifica',
'client_config' => 'Config. client',
'user_code' => 'Codice Utente',
'active' => 'Attivo',
'admin' => 'Amministratore',
'reg_date' => 'Data Registrazione',
'none' => 'Nessuno',
'open' => 'Apri',
'confirm' => 'Conferma',
'confirm_string' => 'Sei sicuro?',
'installed' => 'Installazione completata!',
'bad_login' => 'Credenziali errate.',
'account_disabled' => 'Il tuo account è disattivato.',
'welcome' => 'Benvenuto, %s!',
'goodbye' => 'Arrivederci!',
'token_not_found' => 'Il token specificato non è stato trovato.',
'email_required' => 'Email obbligatoria.',
'email_taken' => 'Email già in uso.',
'username_required' => 'Username obbligatorio.',
'username_taken' => 'Username già in uso.',
'password_required' => 'Password obbligatoria.',
'user_created' => 'L\'utente "%s" è stato creato!',
'user_updated' => 'L\'utente "%s" è stato aggiornato!',
'profile_updated' => 'Profilo aggiornato con successo!',
'user_deleted' => 'Utente rimosso.',
'cannot_delete' => 'Non puoi eliminare te stesso.',
'cannot_demote' => 'Non puoi degradare te stesso.',
'cannot_write_file' => 'Il percorso di destinazione non è scrivibile.',
'deleted_orphans' => 'Eliminati %d file orfani.',
'switch_to' => 'Vedi come',
'gallery' => 'Galleria',
'table' => 'Tabella',
'dotted_search' => 'Cerca...',
'order_by' => 'Ordina per...',
'time' => 'Data',
'name' => 'Nome',
'maintenance' => 'Manutenzione',
'clean_orphaned_uploads' => 'Pulisci upload orfani',
'path_not_writable' => 'Il percorso di output non è scrivibile.',
'already_latest_version' => 'Hai già l\'ultima versione disponibile.',
'new_version_available' => 'Nuova versione disponibile: %s',
'cannot_retrieve_file' => 'Impossibile scaricare il file.',
'file_size_no_match' => 'La dimensione del file scaricato non è corretta.',
'check_for_updates' => 'Controllo aggiornamenti',
'upgrade' => 'Upgrade',
'updates' => 'Aggiornamenti',
'maintenance_in_progress' => 'Manutenzione in corso, riprova più tardi.',
'cancel' => 'Annulla',
'enforce_language' => 'Imponi lingua',
'auto_set' => 'Imposta automaticamente',
'default_lang_behavior' => 'Per impostazione predefinita, XBackbone cercherà di abbinare la lingua del browser (il fallback è l\'Inglese).',
'lang_set' => 'Lingua di sistema applicata a "%s"',
'prerelease_channel' => 'Canale prerelease',
'no_upload_token' => 'Non hai un token personale per l\'upload associato. (Generane uno e riprova)',
'drop_to_upload' => 'Clicca o lascia i tuoi file qui per caricarli.',
'donation' => 'Donazione',
'donate_text' => 'Se ti piace XBackBone, prendi in considerazione una donazione per sostenere lo sviluppo!',
'custom_head_html' => 'Contenuto Head HTML personalizzato',
'custom_head_html_hint' => 'Questo contenuto sarà aggiunto al tag <head> in ogni pagina.',
'custom_head_set' => 'Custom Head HTML applicato con successo.',
'remember_me' => 'Ricordami',
'please_wait' => 'Attendere prego...',
'dont_close' => 'Non chiudere questa scheda fino al completamento.',
'cancel' => 'Annulla',
'enforce_language' => 'Imponi lingua',
'auto_set' => 'Imposta automaticamente',
'default_lang_behavior' => 'Per impostazione predefinita, XBackbone cercherà di abbinare la lingua del browser (il fallback è l\'Inglese).',
'lang_set' => 'Lingua di sistema applicata a "%s"',
'prerelease_channel' => 'Canale prerelease',
'no_upload_token' => 'Non hai un token personale per l\'upload associato. (Generane uno e riprova)',
'drop_to_upload' => 'Clicca o lascia i tuoi file qui per caricarli.',
'donation' => 'Donazione',
'donate_text' => 'Se ti piace XBackBone, prendi in considerazione una donazione per sostenere lo sviluppo!',
'custom_head_html' => 'Contenuto Head HTML personalizzato',
'custom_head_html_hint' => 'Questo contenuto sarà aggiunto al tag <head> in ogni pagina.',
'custom_head_set' => 'Custom Head HTML applicato con successo.',
'remember_me' => 'Ricordami',
'please_wait' => 'Attendere prego...',
'dont_close' => 'Non chiudere questa scheda fino al completamento.',
];

View file

@ -1,112 +1,113 @@
<?php
return [
'theme' => 'Drakt',
'username_taken' => 'Brukernavnet er i bruk.',
'file_size_no_match' => 'Nedlastet fil samsvarer ikke med riktig filstørrelse.',
'delete' => 'Slett',
'is_admin' => 'Er administrator',
'filename' => 'Filnavn',
'clean_orphaned_uploads' => 'Tøm avsondrede opplastinger',
'admin' => 'Admin',
'size' => 'Størrelse',
'path_not_writable' => 'Utdatastien kan ikke skrives til.',
'edit' => 'Rediger',
'no_media' => 'Fant inne noe media.',
'account_disabled' => 'Kontoen din er avskrudd.',
'user_created' => 'Bruker "%s" opprettet.',
'installed' => 'Installert.',
'check_for_updates' => 'Se etter oppdateringer',
'home' => 'Hjem',
'date' => 'Dato',
'pager.next' => 'Neste',
'password' => 'Passord',
'cannot_write_file' => 'Målstien kan ikke skrives til.',
'confirm' => 'Bekreftelse',
'new_version_available' => 'Ny versjon %s tilgjengelig.',
'user_code' => 'Brukerkode',
'order_by' => 'Sorter etter…',
'send' => 'Send',
'owner' => 'Eier',
'users' => 'Brukere',
'client_config' => 'Klientoppsett',
'active' => 'Aktiv',
'user.edit' => 'Rediger bruker',
'email_taken' => 'E-postadressen er i bruk.',
'email_required' => 'E-postadresse er påkrevd.',
'already_latest_version' => 'Du har allerede siste versjon.',
'pager.previous' => 'Forrige',
'public.telegram' => 'Del på Telegram',
'gallery' => 'Galleri',
'is_active' => 'Er aktiv',
'maintenance' => 'Vedlikehold',
'your_profile' => 'Din profil',
'name' => 'Navn',
'deleted_orphans' => 'Slettet %d avsondrede filer.',
'username' => 'Brukernavn',
'save' => 'Lagre',
'lang' => 'Norwegian Bokmål',
'upgrade' => 'Oppgrader',
'updates' => 'Oppdateringer',
'user_updated' => 'Bruker "%s" oppdatert.',
'system' => 'System',
'copy' => 'Kopier',
'theme' => 'Drakt',
'username_taken' => 'Brukernavnet er i bruk.',
'file_size_no_match' => 'Nedlastet fil samsvarer ikke med riktig filstørrelse.',
'delete' => 'Slett',
'is_admin' => 'Er administrator',
'filename' => 'Filnavn',
'clean_orphaned_uploads' => 'Tøm avsondrede opplastinger',
'admin' => 'Admin',
'size' => 'Størrelse',
'path_not_writable' => 'Utdatastien kan ikke skrives til.',
'edit' => 'Rediger',
'no_media' => 'Fant inne noe media.',
'account_disabled' => 'Kontoen din er avskrudd.',
'user_created' => 'Bruker "%s" opprettet.',
'installed' => 'Installert.',
'check_for_updates' => 'Se etter oppdateringer',
'home' => 'Hjem',
'date' => 'Dato',
'pager.next' => 'Neste',
'password' => 'Passord',
'cannot_write_file' => 'Målstien kan ikke skrives til.',
'confirm' => 'Bekreftelse',
'new_version_available' => 'Ny versjon %s tilgjengelig.',
'user_code' => 'Brukerkode',
'order_by' => 'Sorter etter…',
'send' => 'Send',
'owner' => 'Eier',
'users' => 'Brukere',
'client_config' => 'Klientoppsett',
'active' => 'Aktiv',
'user.edit' => 'Rediger bruker',
'email_taken' => 'E-postadressen er i bruk.',
'email_required' => 'E-postadresse er påkrevd.',
'already_latest_version' => 'Du har allerede siste versjon.',
'pager.previous' => 'Forrige',
'public.telegram' => 'Del på Telegram',
'gallery' => 'Galleri',
'is_active' => 'Er aktiv',
'maintenance' => 'Vedlikehold',
'your_profile' => 'Din profil',
'name' => 'Navn',
'deleted_orphans' => 'Slettet %d avsondrede filer.',
'username' => 'Brukernavn',
'save' => 'Lagre',
'lang' => 'Norwegian Bokmål',
'upgrade' => 'Oppgrader',
'updates' => 'Oppdateringer',
'user_updated' => 'Bruker "%s" oppdatert.',
'system' => 'System',
'copy' => 'Kopier',
'maintenance_in_progress' => 'Det utføres vedlikehold på plattformen, prøv igjen senere…',
'copy_link' => 'Kopier lenke',
'bad_login' => 'Feil identitetsdetaljer.',
'logout' => 'Logg ut',
'public' => 'Offentlig',
'none' => 'Ingen',
'profile' => 'Profil',
'files' => 'Filer',
'token' => 'Symbol',
'publish' => 'Publiser',
'no' => 'Nei',
'open' => 'Åpne',
'welcome' => 'Velkommen %s.',
'login.username' => 'Brukernavn eller e-post',
'reg_date' => 'Registreringsdato',
'confirm_string' => 'Er du sikker?',
'time' => 'Tid',
'switch_to' => 'Bytt til',
'cancel' => 'Avbryt',
'used' => 'Brukt',
'cannot_demote' => 'Du kan ikke fjerne egen rang.',
'preview' => 'Forhåndsvis',
'cannot_delete' => 'Du kan ikke slette deg selv.',
'system_info' => 'Systeminfo',
'yes' => 'Ja',
'table' => 'Tabell',
'cannot_retrieve_file' => 'Kan ikke hente filen.',
'update' => 'Oppdater',
'public.delete_text' => 'Er du sikker på at du ønsker å slette dette elementet? Det vil gå tapt for alltid.',
'token_not_found' => 'Angitt symbol ble ikke funnet.',
'profile_updated' => 'Profil oppdatert.',
'username_required' => 'Brukernavn kreves.',
'user.create' => 'Opprett bruker',
'login' => 'Logg inn',
'goodbye' => 'Adjø.',
'raw' => 'Vis rådata',
'download' => 'Last ned',
'click_to_load' => 'Klikk for å laste inn…',
'password_required' => 'Passord kreves.',
'user_deleted' => 'Bruker slettet.',
'hide' => 'Skjul',
'orphaned_files' => 'Avsondrede filer',
'apply' => 'Bruk',
'dotted_search' => 'Søk…',
'enforce_language' => 'Påtving språk',
'auto_set' => 'Sett automatisk',
'translated_strings' => 'oversatte strenger',
'total_strings' => 'totalt antall strenger',
'lang_name' => 'språknavn',
'default_lang_behavior' => 'Som forvalg, vil XBackBone prøve å samsvare nettleserspråk (tilbakefallsspråk er engelsk).',
'lang_set' => 'Systemspråk er satt til "%s"',
'prerelease_channel' => 'Forhåndsslipp-kanal',
'upload' => 'Last opp',
'donation' => 'Donasjon',
'custom_head_html' => 'Egendefinert HTML-hodeinnhold',
'custom_head_html_hint' => 'Dette inneholdet vil bli lagt til i <head>-taggen på hver side.',
'custom_head_set' => 'Egendefinert HTML-hode lagt til.',
'remember_me' => 'Husk meg',
'please_wait' => 'Vent…',
'copy_link' => 'Kopier lenke',
'bad_login' => 'Feil identitetsdetaljer.',
'logout' => 'Logg ut',
'public' => 'Offentlig',
'none' => 'Ingen',
'profile' => 'Profil',
'files' => 'Filer',
'token' => 'Symbol',
'publish' => 'Publiser',
'no' => 'Nei',
'open' => 'Åpne',
'welcome' => 'Velkommen %s.',
'login.username' => 'Brukernavn eller e-post',
'reg_date' => 'Registreringsdato',
'confirm_string' => 'Er du sikker?',
'time' => 'Tid',
'switch_to' => 'Bytt til',
'cancel' => 'Avbryt',
'used' => 'Brukt',
'cannot_demote' => 'Du kan ikke fjerne egen rang.',
'preview' => 'Forhåndsvis',
'cannot_delete' => 'Du kan ikke slette deg selv.',
'system_info' => 'Systeminfo',
'yes' => 'Ja',
'table' => 'Tabell',
'cannot_retrieve_file' => 'Kan ikke hente filen.',
'update' => 'Oppdater',
'public.delete_text' => 'Er du sikker på at du ønsker å slette dette elementet? Det vil gå tapt for alltid.',
'token_not_found' => 'Angitt symbol ble ikke funnet.',
'profile_updated' => 'Profil oppdatert.',
'username_required' => 'Brukernavn kreves.',
'user.create' => 'Opprett bruker',
'login' => 'Logg inn',
'goodbye' => 'Adjø.',
'raw' => 'Vis rådata',
'download' => 'Last ned',
'click_to_load' => 'Klikk for å laste inn…',
'password_required' => 'Passord kreves.',
'user_deleted' => 'Bruker slettet.',
'hide' => 'Skjul',
'orphaned_files' => 'Avsondrede filer',
'apply' => 'Bruk',
'dotted_search' => 'Søk…',
'enforce_language' => 'Påtving språk',
'auto_set' => 'Sett automatisk',
'translated_strings' => 'oversatte strenger',
'total_strings' => 'totalt antall strenger',
'lang_name' => 'språknavn',
'default_lang_behavior' => 'Som forvalg, vil XBackBone prøve å samsvare nettleserspråk (tilbakefallsspråk er engelsk).',
'lang_set' => 'Systemspråk er satt til "%s"',
'prerelease_channel' => 'Forhåndsslipp-kanal',
'upload' => 'Last opp',
'donation' => 'Donasjon',
'custom_head_html' => 'Egendefinert HTML-hodeinnhold',
'custom_head_html_hint' => 'Dette inneholdet vil bli lagt til i <head>-taggen på hver side.',
'custom_head_set' => 'Egendefinert HTML-hode lagt til.',
'remember_me' => 'Husk meg',
'please_wait' => 'Vent…',
];

View file

@ -1,104 +1,105 @@
<?php
return [
'lang' => 'Dutch',
'yes' => 'Ja',
'no' => 'Nee',
'send' => 'Versturen',
'no_media' => 'Geen media gevonden.',
'login.username' => 'Gebruikersnaam of E-Mail',
'password' => 'Wachtwoord',
'login' => 'Inloggen',
'username' => 'Gebruikersnaam',
'home' => 'Home',
'users' => 'Gebruikers',
'system' => 'Systeem',
'profile' => 'Profiel',
'logout' => 'Uitloggen',
'pager.next' => 'Volgende',
'pager.previous' => 'Vorige',
'copy_link' => 'Link kopiëren',
'public.telegram' => 'Delen op Telegram',
'public.delete_text' => 'Weet je zeker dat je dit item wilt verwijderen? Dit is permanent!',
'preview' => 'Voorbeeld',
'filename' => 'Bestandsnaam',
'size' => 'Grootte',
'public' => 'Publiek',
'owner' => 'Eigenaar',
'date' => 'Datum',
'raw' => 'Bekijk raw',
'download' => 'Download',
'delete' => 'Verwijderen',
'publish' => 'Publiceren',
'hide' => 'Verbergen',
'files' => 'Bestanden',
'orphaned_files' => 'Weesbestanden',
'theme' => 'Thema',
'click_to_load' => 'Klik om te laden...',
'apply' => 'Toepassen',
'save' => 'Opslaan',
'used' => 'Gebruikt',
'system_info' => 'Systeem informatie',
'user.create' => 'Gebruiker aanmaken',
'user.edit' => 'Gebruiker aanpassen',
'is_active' => 'Is actief',
'is_admin' => 'Is administrator',
'your_profile' => 'Jouw profiel',
'token' => 'Token',
'copy' => 'Kopiëren',
'update' => 'Updaten',
'edit' => 'Aanpassen',
'client_config' => 'Client configuratie',
'user_code' => 'Gebruikerscode',
'active' => 'Actief',
'admin' => 'Administrator',
'reg_date' => 'Registratiedatum',
'none' => 'Geen',
'open' => 'Open',
'confirm' => 'Bevestiging',
'confirm_string' => 'Weet je het zeker?',
'installed' => 'Installatie succesvol voltooid!',
'bad_login' => 'Verkeerde verificatiegegevens.',
'account_disabled' => 'Je account is gedeactiveerd.',
'welcome' => 'Welkom, %s!',
'goodbye' => 'Tot ziens!',
'token_not_found' => 'Gespecificeerde token niet gevonden.',
'email_required' => 'Het email adres is noodzakelijk.',
'email_taken' => 'Het email adres is al in gebruik.',
'username_required' => 'De gebruikersnaam is noodzakelijk.',
'username_taken' => 'De gebruikersnaam is al in gebruik.',
'password_required' => 'Het wachtwoord is verplicht.',
'user_created' => 'Gebruiker "%s" aangemaakt!',
'user_updated' => 'Gebruiker "%s" gewijzigd!',
'profile_updated' => 'Profiel succesvol geüpdatet!',
'user_deleted' => 'Gebruiker verwijderd.',
'cannot_delete' => 'Je kan jezelf niet verwijderen.',
'cannot_demote' => 'Je kan je eigen niveau niet verlagen.',
'cannot_write_file' => 'Het opgegeven bestandspad is niet beschrijfbaar.',
'deleted_orphans' => '%d weesbestanden succesvol verwijderd.',
'switch_to' => 'Wijzig naar',
'gallery' => 'Galerij',
'table' => 'Tabel',
'dotted_search' => 'Zoeken...',
'order_by' => 'Sorteren op…',
'time' => 'Tijd',
'name' => 'Naam',
'maintenance' => 'Onderhoud',
'clean_orphaned_uploads' => 'Weesbestanden opschonen',
'path_not_writable' => 'Het pad is niet beschrijfbaar.',
'already_latest_version' => 'Je gebruikt al de nieuwste versie.',
'new_version_available' => 'Nieuwe versie %s beschikbaar!',
'cannot_retrieve_file' => 'Kan het bestand niet ophalen.',
'file_size_no_match' => 'Het gedownloade bestand is niet de correcte grootte.',
'check_for_updates' => 'Controleer op updates',
'upgrade' => 'Upgraden',
'updates' => 'Updates',
'lang' => 'Dutch',
'yes' => 'Ja',
'no' => 'Nee',
'send' => 'Versturen',
'no_media' => 'Geen media gevonden.',
'login.username' => 'Gebruikersnaam of E-Mail',
'password' => 'Wachtwoord',
'login' => 'Inloggen',
'username' => 'Gebruikersnaam',
'home' => 'Home',
'users' => 'Gebruikers',
'system' => 'Systeem',
'profile' => 'Profiel',
'logout' => 'Uitloggen',
'pager.next' => 'Volgende',
'pager.previous' => 'Vorige',
'copy_link' => 'Link kopiëren',
'public.telegram' => 'Delen op Telegram',
'public.delete_text' => 'Weet je zeker dat je dit item wilt verwijderen? Dit is permanent!',
'preview' => 'Voorbeeld',
'filename' => 'Bestandsnaam',
'size' => 'Grootte',
'public' => 'Publiek',
'owner' => 'Eigenaar',
'date' => 'Datum',
'raw' => 'Bekijk raw',
'download' => 'Download',
'delete' => 'Verwijderen',
'publish' => 'Publiceren',
'hide' => 'Verbergen',
'files' => 'Bestanden',
'orphaned_files' => 'Weesbestanden',
'theme' => 'Thema',
'click_to_load' => 'Klik om te laden...',
'apply' => 'Toepassen',
'save' => 'Opslaan',
'used' => 'Gebruikt',
'system_info' => 'Systeem informatie',
'user.create' => 'Gebruiker aanmaken',
'user.edit' => 'Gebruiker aanpassen',
'is_active' => 'Is actief',
'is_admin' => 'Is administrator',
'your_profile' => 'Jouw profiel',
'token' => 'Token',
'copy' => 'Kopiëren',
'update' => 'Updaten',
'edit' => 'Aanpassen',
'client_config' => 'Client configuratie',
'user_code' => 'Gebruikerscode',
'active' => 'Actief',
'admin' => 'Administrator',
'reg_date' => 'Registratiedatum',
'none' => 'Geen',
'open' => 'Open',
'confirm' => 'Bevestiging',
'confirm_string' => 'Weet je het zeker?',
'installed' => 'Installatie succesvol voltooid!',
'bad_login' => 'Verkeerde verificatiegegevens.',
'account_disabled' => 'Je account is gedeactiveerd.',
'welcome' => 'Welkom, %s!',
'goodbye' => 'Tot ziens!',
'token_not_found' => 'Gespecificeerde token niet gevonden.',
'email_required' => 'Het email adres is noodzakelijk.',
'email_taken' => 'Het email adres is al in gebruik.',
'username_required' => 'De gebruikersnaam is noodzakelijk.',
'username_taken' => 'De gebruikersnaam is al in gebruik.',
'password_required' => 'Het wachtwoord is verplicht.',
'user_created' => 'Gebruiker "%s" aangemaakt!',
'user_updated' => 'Gebruiker "%s" gewijzigd!',
'profile_updated' => 'Profiel succesvol geüpdatet!',
'user_deleted' => 'Gebruiker verwijderd.',
'cannot_delete' => 'Je kan jezelf niet verwijderen.',
'cannot_demote' => 'Je kan je eigen niveau niet verlagen.',
'cannot_write_file' => 'Het opgegeven bestandspad is niet beschrijfbaar.',
'deleted_orphans' => '%d weesbestanden succesvol verwijderd.',
'switch_to' => 'Wijzig naar',
'gallery' => 'Galerij',
'table' => 'Tabel',
'dotted_search' => 'Zoeken...',
'order_by' => 'Sorteren op…',
'time' => 'Tijd',
'name' => 'Naam',
'maintenance' => 'Onderhoud',
'clean_orphaned_uploads' => 'Weesbestanden opschonen',
'path_not_writable' => 'Het pad is niet beschrijfbaar.',
'already_latest_version' => 'Je gebruikt al de nieuwste versie.',
'new_version_available' => 'Nieuwe versie %s beschikbaar!',
'cannot_retrieve_file' => 'Kan het bestand niet ophalen.',
'file_size_no_match' => 'Het gedownloade bestand is niet de correcte grootte.',
'check_for_updates' => 'Controleer op updates',
'upgrade' => 'Upgraden',
'updates' => 'Updates',
'maintenance_in_progress' => 'Platform in onderhoud, probeer het later nog eens...',
'cancel' => 'Annuleren',
'enforce_language' => 'Taal afdwingen',
'auto_set' => 'Automatisch instellen',
'translated_strings' => 'vertaalde strings',
'total_strings' => 'Totaal aantal strings',
'lang_name' => 'Taal',
'default_lang_behavior' => 'XBackBone probeert standaard de taal van de browser te matchen (fallback is Engels).',
'lang_set' => 'Systeemtaal "%s" afgedwongen',
'cancel' => 'Annuleren',
'enforce_language' => 'Taal afdwingen',
'auto_set' => 'Automatisch instellen',
'translated_strings' => 'vertaalde strings',
'total_strings' => 'Totaal aantal strings',
'lang_name' => 'Taal',
'default_lang_behavior' => 'XBackBone probeert standaard de taal van de browser te matchen (fallback is Engels).',
'lang_set' => 'Systeemtaal "%s" afgedwongen',
];

View file

@ -1,46 +1,47 @@
<?php
return [
'lang' => 'Portuguese',
'yes' => 'Sim',
'no' => 'Não',
'send' => 'Enviar',
'no_media' => 'Nenhuma mídia encontrada.',
'login.username' => 'Username ou E-Mail',
'password' => 'Password',
'login' => 'Login',
'username' => 'Nome de Utilizador',
'home' => 'Home',
'users' => 'Utilizadores',
'system' => 'Sistema',
'profile' => 'Perfil',
'logout' => 'Sair',
'pager.next' => 'Seguinte',
'pager.previous' => 'Anterior',
'copy_link' => 'Copiar link',
'public.telegram' => 'Partilhar no Telegram',
'lang' => 'Portuguese',
'yes' => 'Sim',
'no' => 'Não',
'send' => 'Enviar',
'no_media' => 'Nenhuma mídia encontrada.',
'login.username' => 'Username ou E-Mail',
'password' => 'Password',
'login' => 'Login',
'username' => 'Nome de Utilizador',
'home' => 'Home',
'users' => 'Utilizadores',
'system' => 'Sistema',
'profile' => 'Perfil',
'logout' => 'Sair',
'pager.next' => 'Seguinte',
'pager.previous' => 'Anterior',
'copy_link' => 'Copiar link',
'public.telegram' => 'Partilhar no Telegram',
'public.delete_text' => 'Tem a certeza que pretende apagar este item ? Vai desaparecer para sempre!',
'preview' => 'Pré-visualização',
'filename' => 'Nome do ficheiro',
'size' => 'Tamanho',
'public' => 'Público',
'owner' => 'Dono',
'date' => 'Data',
'raw' => 'Mostrar raw',
'download' => 'Transferir',
'delete' => 'Apagar',
'publish' => 'Publicar',
'hide' => 'Esconder',
'files' => 'Ficheiros',
'theme' => 'Tema',
'apply' => 'Aplicar',
'save' => 'Guardar',
'used' => 'Usado',
'system_info' => 'Informações do Sistema',
'user.create' => 'Criar Utilizador',
'user.edit' => 'Editar Utilizador',
'is_active' => 'É ativo',
'is_admin' => 'É administrador',
'your_profile' => 'O teu perfil',
'token' => 'Token',
'copy' => 'Copiar',
'preview' => 'Pré-visualização',
'filename' => 'Nome do ficheiro',
'size' => 'Tamanho',
'public' => 'Público',
'owner' => 'Dono',
'date' => 'Data',
'raw' => 'Mostrar raw',
'download' => 'Transferir',
'delete' => 'Apagar',
'publish' => 'Publicar',
'hide' => 'Esconder',
'files' => 'Ficheiros',
'theme' => 'Tema',
'apply' => 'Aplicar',
'save' => 'Guardar',
'used' => 'Usado',
'system_info' => 'Informações do Sistema',
'user.create' => 'Criar Utilizador',
'user.edit' => 'Editar Utilizador',
'is_active' => 'É ativo',
'is_admin' => 'É administrador',
'your_profile' => 'O teu perfil',
'token' => 'Token',
'copy' => 'Copiar',
];

View file

@ -1,104 +1,105 @@
<?php
return [
'lang' => 'Russian',
'yes' => 'Да',
'no' => 'Нет',
'send' => 'Отправить',
'no_media' => 'Файлы не найдены.',
'login.username' => 'Имя пользователя или E-Mail',
'password' => 'Пароль',
'login' => 'Войти',
'username' => 'Имя пользователя',
'home' => 'Главная',
'users' => 'Пользователи',
'system' => 'Система',
'profile' => 'Профиль',
'logout' => 'Выйти',
'pager.next' => 'Следующая',
'pager.previous' => 'Предыдущая',
'copy_link' => 'Скопировать ссылку',
'public.telegram' => 'Отправить в Telegram',
'public.delete_text' => 'Вы уверены, что хотите удалить это? Восстановление будет невозможно!',
'preview' => 'Превью',
'filename' => 'Имя файла',
'size' => 'Размер',
'public' => 'Публичный',
'owner' => 'Владелец',
'date' => 'Дата',
'raw' => 'Показать оригинал',
'download' => 'Скачать',
'delete' => 'Удалить',
'publish' => 'Опубликовать',
'hide' => 'Скрыть',
'files' => 'Файлы',
'orphaned_files' => 'Потерянные файлы',
'theme' => 'Тема',
'click_to_load' => 'Нажмите для загрузки...',
'apply' => 'Применить',
'save' => 'Сохранить',
'used' => 'Использовано',
'system_info' => 'Системная информация',
'user.create' => 'Добавить пользователя',
'user.edit' => 'Редактировать пользователя',
'is_active' => 'Активен',
'is_admin' => 'Администратор',
'your_profile' => 'Ваш профиль',
'token' => 'Ключ',
'copy' => 'Скопировать',
'update' => 'Обновить',
'edit' => 'Редактировать',
'client_config' => 'Конфигурация клиента',
'user_code' => 'Код пользователя',
'active' => 'Активен',
'admin' => 'Админ',
'reg_date' => 'Дата регистрации',
'none' => 'Нет',
'open' => 'Открыть',
'confirm' => 'Подтверждение',
'confirm_string' => 'Вы уверены?',
'installed' => 'Установка успешно завершена!',
'bad_login' => 'Неверные учетные данные.',
'account_disabled' => 'Ваша учетная запись отключена.',
'welcome' => 'Добро пожаловать, %s!',
'goodbye' => 'До встречи!',
'token_not_found' => 'Указанный ключ не найден.',
'email_required' => 'Требуется указать e-mail.',
'email_taken' => 'E-mail уже занят.',
'username_required' => 'Требуется указать имя пользователя.',
'username_taken' => 'Имя пользователя уже занято.',
'password_required' => 'Требуется указать пароль.',
'user_created' => 'Пользователь "%s" создан!',
'user_updated' => 'Пользователь "%s" изменен!',
'profile_updated' => 'Профиль успешно обновлен!',
'user_deleted' => 'Пользователь удален.',
'cannot_delete' => 'Вы не можете удалить самого себя.',
'cannot_demote' => 'Вы не можете понизить самого себя.',
'cannot_write_file' => 'Указанный путь недоступен для записи.',
'deleted_orphans' => '%d потерянных файлов успешно удалено.',
'switch_to' => 'Переключиться на',
'gallery' => 'Галерея',
'table' => 'Таблица',
'dotted_search' => 'Поиск...',
'order_by' => 'Сортировка...',
'time' => 'Время',
'name' => 'Название',
'maintenance' => 'Обслуживание',
'clean_orphaned_uploads' => 'Удалить потерянные файлы',
'path_not_writable' => 'Путь недоступен для записи.',
'already_latest_version' => 'У вас уже последняя версия.',
'new_version_available' => 'Доступна новая версия %s!',
'cannot_retrieve_file' => 'Не удается получить файл.',
'file_size_no_match' => 'Загруженный файл имеет некорректный размер.',
'check_for_updates' => 'Проверить обновления',
'upgrade' => 'Обновить',
'updates' => 'Обновления',
'lang' => 'Russian',
'yes' => 'Да',
'no' => 'Нет',
'send' => 'Отправить',
'no_media' => 'Файлы не найдены.',
'login.username' => 'Имя пользователя или E-Mail',
'password' => 'Пароль',
'login' => 'Войти',
'username' => 'Имя пользователя',
'home' => 'Главная',
'users' => 'Пользователи',
'system' => 'Система',
'profile' => 'Профиль',
'logout' => 'Выйти',
'pager.next' => 'Следующая',
'pager.previous' => 'Предыдущая',
'copy_link' => 'Скопировать ссылку',
'public.telegram' => 'Отправить в Telegram',
'public.delete_text' => 'Вы уверены, что хотите удалить это? Восстановление будет невозможно!',
'preview' => 'Превью',
'filename' => 'Имя файла',
'size' => 'Размер',
'public' => 'Публичный',
'owner' => 'Владелец',
'date' => 'Дата',
'raw' => 'Показать оригинал',
'download' => 'Скачать',
'delete' => 'Удалить',
'publish' => 'Опубликовать',
'hide' => 'Скрыть',
'files' => 'Файлы',
'orphaned_files' => 'Потерянные файлы',
'theme' => 'Тема',
'click_to_load' => 'Нажмите для загрузки...',
'apply' => 'Применить',
'save' => 'Сохранить',
'used' => 'Использовано',
'system_info' => 'Системная информация',
'user.create' => 'Добавить пользователя',
'user.edit' => 'Редактировать пользователя',
'is_active' => 'Активен',
'is_admin' => 'Администратор',
'your_profile' => 'Ваш профиль',
'token' => 'Ключ',
'copy' => 'Скопировать',
'update' => 'Обновить',
'edit' => 'Редактировать',
'client_config' => 'Конфигурация клиента',
'user_code' => 'Код пользователя',
'active' => 'Активен',
'admin' => 'Админ',
'reg_date' => 'Дата регистрации',
'none' => 'Нет',
'open' => 'Открыть',
'confirm' => 'Подтверждение',
'confirm_string' => 'Вы уверены?',
'installed' => 'Установка успешно завершена!',
'bad_login' => 'Неверные учетные данные.',
'account_disabled' => 'Ваша учетная запись отключена.',
'welcome' => 'Добро пожаловать, %s!',
'goodbye' => 'До встречи!',
'token_not_found' => 'Указанный ключ не найден.',
'email_required' => 'Требуется указать e-mail.',
'email_taken' => 'E-mail уже занят.',
'username_required' => 'Требуется указать имя пользователя.',
'username_taken' => 'Имя пользователя уже занято.',
'password_required' => 'Требуется указать пароль.',
'user_created' => 'Пользователь "%s" создан!',
'user_updated' => 'Пользователь "%s" изменен!',
'profile_updated' => 'Профиль успешно обновлен!',
'user_deleted' => 'Пользователь удален.',
'cannot_delete' => 'Вы не можете удалить самого себя.',
'cannot_demote' => 'Вы не можете понизить самого себя.',
'cannot_write_file' => 'Указанный путь недоступен для записи.',
'deleted_orphans' => '%d потерянных файлов успешно удалено.',
'switch_to' => 'Переключиться на',
'gallery' => 'Галерея',
'table' => 'Таблица',
'dotted_search' => 'Поиск...',
'order_by' => 'Сортировка...',
'time' => 'Время',
'name' => 'Название',
'maintenance' => 'Обслуживание',
'clean_orphaned_uploads' => 'Удалить потерянные файлы',
'path_not_writable' => 'Путь недоступен для записи.',
'already_latest_version' => 'У вас уже последняя версия.',
'new_version_available' => 'Доступна новая версия %s!',
'cannot_retrieve_file' => 'Не удается получить файл.',
'file_size_no_match' => 'Загруженный файл имеет некорректный размер.',
'check_for_updates' => 'Проверить обновления',
'upgrade' => 'Обновить',
'updates' => 'Обновления',
'maintenance_in_progress' => 'Система на обслуживании, попробуйте позже...',
'cancel' => 'Отмена',
'enforce_language' => 'Выбрать язык',
'auto_set' => 'Выбрать автоматически',
'translated_strings' => 'переведенные строки',
'total_strings' => 'всего строк',
'lang_name' => 'язык',
'default_lang_behavior' => 'XBackBone попробует выбрать язык вашего браузера по умолчанию, иначе будет выбран Английский.',
'lang_set' => 'Выбран следующий язык: "%s"',
'cancel' => 'Отмена',
'enforce_language' => 'Выбрать язык',
'auto_set' => 'Выбрать автоматически',
'translated_strings' => 'переведенные строки',
'total_strings' => 'всего строк',
'lang_name' => 'язык',
'default_lang_behavior' => 'XBackBone попробует выбрать язык вашего браузера по умолчанию, иначе будет выбран Английский.',
'lang_set' => 'Выбран следующий язык: "%s"',
];