Implemented custom queries
This commit is contained in:
parent
ca361c8eef
commit
2b8671f0c6
|
@ -1,5 +1,7 @@
|
|||
## v2.4
|
||||
+ Added function to remove orphaned files.
|
||||
+ Switch between tab and gallery mode using an admin account.
|
||||
+ Multiple uploads sorting methods.
|
||||
+ Internal refactoring and improvements
|
||||
|
||||
## v2.3.1
|
||||
|
|
|
@ -22,7 +22,7 @@ class AdminController extends Controller
|
|||
$mediasCount = $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads`')->fetch()->count;
|
||||
$orphanFilesCount = $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `user_id` IS NULL')->fetch()->count;
|
||||
|
||||
$medias = $this->database->query('SELECT `users`.`user_code`, `uploads`.`code`, `uploads`.`storage_path` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id`')->fetchAll();
|
||||
$medias = $this->database->query('SELECT `uploads`.`storage_path` FROM `uploads`')->fetchAll();
|
||||
|
||||
$totalSize = 0;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Controllers;
|
||||
|
||||
use League\Flysystem\FileNotFoundException;
|
||||
use App\Database\Queries\MediaQuery;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
|
@ -39,36 +39,33 @@ class DashboardController extends Controller
|
|||
$page = isset($args['page']) ? (int)$args['page'] : 0;
|
||||
$page = max(0, --$page);
|
||||
|
||||
if ($this->session->get('admin', false)) {
|
||||
$medias = $this->database->query('SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id` ORDER BY `timestamp` DESC LIMIT ? OFFSET ?', [self::PER_PAGE_ADMIN, $page * self::PER_PAGE_ADMIN])->fetchAll();
|
||||
$pages = $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads`')->fetch()->count / self::PER_PAGE_ADMIN;
|
||||
} else {
|
||||
$medias = $this->database->query('SELECT `uploads`.*,`users`.`user_code`, `users`.`username` FROM `uploads` INNER JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `user_id` = ? ORDER BY `timestamp` DESC LIMIT ? OFFSET ?', [$this->session->get('user_id'), self::PER_PAGE, $page * self::PER_PAGE])->fetchAll();
|
||||
$pages = $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `user_id` = ?', $this->session->get('user_id'))->fetch()->count / self::PER_PAGE;
|
||||
}
|
||||
$query = new MediaQuery($this->database, $this->session->get('admin', false));
|
||||
|
||||
$filesystem = storage();
|
||||
|
||||
foreach ($medias as $media) {
|
||||
try {
|
||||
$media->size = humanFileSize($filesystem->getSize($media->storage_path));
|
||||
$media->mimetype = $filesystem->getMimetype($media->storage_path);
|
||||
} catch (FileNotFoundException $e) {
|
||||
$media->size = null;
|
||||
$media->mimetype = null;
|
||||
}
|
||||
$media->extension = pathinfo($media->filename, PATHINFO_EXTENSION);
|
||||
}
|
||||
$query->orderBy(MediaQuery::ORDER_NAME)
|
||||
->withUserId($this->session->get('user_id'))
|
||||
->run($page);
|
||||
|
||||
return $this->view->render(
|
||||
$response,
|
||||
$this->session->get('admin', false) ? 'dashboard/admin.twig' : 'dashboard/home.twig',
|
||||
($this->session->get('admin', false) && $this->session->get('gallery_view', true)) ? 'dashboard/admin.twig' : 'dashboard/home.twig',
|
||||
[
|
||||
'medias' => $medias,
|
||||
'next' => $page < floor($pages),
|
||||
'medias' => $query->getMedia(),
|
||||
'next' => $page < floor($query->getPages()),
|
||||
'previous' => $page >= 1,
|
||||
'current_page' => ++$page,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
* @param $args
|
||||
* @return Response
|
||||
*/
|
||||
public function switchView(Request $request, Response $response, $args): Response
|
||||
{
|
||||
$this->session->set('gallery_view', !$this->session->get('gallery_view', true));
|
||||
return redirect($response, 'home');
|
||||
}
|
||||
}
|
201
app/Database/Queries/MediaQuery.php
Normal file
201
app/Database/Queries/MediaQuery.php
Normal file
|
@ -0,0 +1,201 @@
|
|||
<?php
|
||||
|
||||
namespace App\Database\Queries;
|
||||
|
||||
|
||||
use App\Database\DB;
|
||||
use League\Flysystem\FileNotFoundException;
|
||||
use League\Flysystem\Plugin\ListFiles;
|
||||
|
||||
class MediaQuery
|
||||
{
|
||||
const PER_PAGE = 21;
|
||||
const PER_PAGE_ADMIN = 25;
|
||||
|
||||
const ORDER_TIME = 0;
|
||||
const ORDER_NAME = 1;
|
||||
const ORDER_SIZE = 2;
|
||||
|
||||
|
||||
/** @var DB */
|
||||
protected $db;
|
||||
|
||||
/** @var bool */
|
||||
protected $isAdmin;
|
||||
|
||||
protected $userId;
|
||||
|
||||
/** @var int */
|
||||
protected $orderBy;
|
||||
|
||||
/** @var string */
|
||||
protected $orderMode;
|
||||
|
||||
/** @var string */
|
||||
protected $text;
|
||||
|
||||
private $pages;
|
||||
private $media;
|
||||
|
||||
/**
|
||||
* MediaQuery constructor.
|
||||
* @param DB $db
|
||||
* @param bool $isAdmin
|
||||
*/
|
||||
public function __construct(DB $db, bool $isAdmin)
|
||||
{
|
||||
$this->db = $db;
|
||||
$this->isAdmin = $isAdmin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return $this
|
||||
*/
|
||||
public function withUserId($id)
|
||||
{
|
||||
$this->userId = $id;
|
||||
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 $text
|
||||
* @return $this
|
||||
*/
|
||||
public function search(string $text)
|
||||
{
|
||||
$this->text = $text;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $page
|
||||
*/
|
||||
public function run(int $page)
|
||||
{
|
||||
if ($this->orderBy == self::ORDER_SIZE) {
|
||||
$this->runWithOrderBySize($page);
|
||||
return;
|
||||
}
|
||||
|
||||
$queryPages = 'SELECT COUNT(*) AS `count` FROM `uploads`';
|
||||
|
||||
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` = ?';
|
||||
}
|
||||
|
||||
switch ($this->orderBy) {
|
||||
case self::ORDER_NAME:
|
||||
$queryMedia = sprintf($queryMedia, 'ORDER BY `filename` ' . $this->orderMode);
|
||||
break;
|
||||
default:
|
||||
case self::ORDER_TIME:
|
||||
$queryMedia = sprintf($queryMedia, 'ORDER BY `timestamp` ' . $this->orderMode);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this->isAdmin) {
|
||||
$this->media = $this->db->query($queryMedia, [self::PER_PAGE_ADMIN, $page * self::PER_PAGE_ADMIN])->fetchAll();
|
||||
$this->pages = $this->db->query($queryPages)->fetch()->count / self::PER_PAGE_ADMIN;
|
||||
} else {
|
||||
$this->media = $this->db->query($queryMedia, [$this->userId, self::PER_PAGE, $page * self::PER_PAGE])->fetchAll();
|
||||
$this->pages = $this->db->query($queryPages, $this->userId)->fetch()->count / self::PER_PAGE;
|
||||
}
|
||||
|
||||
$filesystem = storage();
|
||||
|
||||
foreach ($this->media as $media) {
|
||||
try {
|
||||
$media->size = humanFileSize($filesystem->getSize($media->storage_path));
|
||||
$media->mimetype = $filesystem->getMimetype($media->storage_path);
|
||||
} catch (FileNotFoundException $e) {
|
||||
$media->size = null;
|
||||
$media->mimetype = null;
|
||||
}
|
||||
$media->extension = pathinfo($media->filename, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $page
|
||||
*/
|
||||
private function runWithOrderBySize(int $page)
|
||||
{
|
||||
$filesystem = storage();
|
||||
$filesystem->addPlugin(new ListFiles());
|
||||
|
||||
if ($this->isAdmin) {
|
||||
$files = $filesystem->listFiles('/', true);
|
||||
$this->pages = count($files) / self::PER_PAGE_ADMIN;
|
||||
|
||||
$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 = $filesystem->listFiles($userCode);
|
||||
$this->pages = count($files) / self::PER_PAGE;
|
||||
|
||||
$offset = $page * self::PER_PAGE;
|
||||
$limit = self::PER_PAGE;
|
||||
}
|
||||
|
||||
array_multisort(array_column($files, 'size'), ($this->orderMode === 'ASC') ? SORT_ASC : SORT_DESC, SORT_NUMERIC, $files);
|
||||
|
||||
$files = array_slice($files, $offset, $limit);
|
||||
$paths = array_column($files, 'path');
|
||||
|
||||
$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();
|
||||
|
||||
$paths = array_flip($paths);
|
||||
foreach ($medias as $media) {
|
||||
$paths[$media->storage_path] = $media;
|
||||
}
|
||||
|
||||
$this->media = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$media = $paths[$file['path']];
|
||||
$media->size = humanFileSize($file['size']);
|
||||
try {
|
||||
$media->mimetype = $filesystem->getMimetype($file['path']);
|
||||
} catch (FileNotFoundException $e) {
|
||||
$media->mimetype = null;
|
||||
}
|
||||
$media->extension = $file['extension'];
|
||||
$this->media[] = $media;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMedia()
|
||||
{
|
||||
return $this->media;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPages()
|
||||
{
|
||||
return $this->pages;
|
||||
}
|
||||
}
|
|
@ -158,6 +158,11 @@ if (!function_exists('isBot')) {
|
|||
}
|
||||
|
||||
if (!function_exists('mime2font')) {
|
||||
/**
|
||||
* Convert get the icon from the file mimetype
|
||||
* @param $mime
|
||||
* @return mixed|string
|
||||
*/
|
||||
function mime2font($mime)
|
||||
{
|
||||
$classes = [
|
||||
|
@ -177,6 +182,7 @@ if (!function_exists('mime2font')) {
|
|||
'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',
|
||||
|
@ -190,3 +196,18 @@ if (!function_exists('mime2font')) {
|
|||
return 'fa-file';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('dd')) {
|
||||
/**
|
||||
* Dumps all the giver vars and halt the execution.
|
||||
*/
|
||||
function dd()
|
||||
{
|
||||
echo '<pre>';
|
||||
array_map(function ($x) {
|
||||
print_r($x);
|
||||
}, func_get_args());
|
||||
echo '</pre>';
|
||||
die();
|
||||
}
|
||||
}
|
|
@ -2,18 +2,24 @@
|
|||
// Auth routes
|
||||
$app->group('', function () {
|
||||
$this->get('/home[/page/{page}]', \App\Controllers\DashboardController::class . ':home')->setName('home');
|
||||
$this->get('/system/deleteOrphanFiles', \App\Controllers\AdminController::class . ':deleteOrphanFiles')->add(\App\Middleware\AdminMiddleware::class)->setName('system.deleteOrphanFiles');
|
||||
$this->get('/system/themes', \App\Controllers\ThemeController::class . ':getThemes')->add(\App\Middleware\AdminMiddleware::class)->setName('theme');
|
||||
$this->post('/system/theme/apply', \App\Controllers\ThemeController::class . ':applyTheme')->add(\App\Middleware\AdminMiddleware::class)->setName('theme.apply');
|
||||
$this->get('/system', \App\Controllers\AdminController::class . ':system')->add(\App\Middleware\AdminMiddleware::class)->setName('system');
|
||||
|
||||
$this->group('', function () {
|
||||
$this->get('/home/switchView', \App\Controllers\DashboardController::class . ':switchView')->setName('switchView');
|
||||
$this->get('/system/deleteOrphanFiles', \App\Controllers\AdminController::class . ':deleteOrphanFiles')->setName('system.deleteOrphanFiles');
|
||||
$this->get('/system/themes', \App\Controllers\ThemeController::class . ':getThemes')->setName('theme');
|
||||
$this->post('/system/theme/apply', \App\Controllers\ThemeController::class . ':applyTheme')->setName('theme.apply');
|
||||
$this->get('/system', \App\Controllers\AdminController::class . ':system')->setName('system');
|
||||
|
||||
$this->get('/users[/page/{page}]', \App\Controllers\UserController::class . ':index')->setName('user.index');
|
||||
$this->get('/user/create', \App\Controllers\UserController::class . ':create')->setName('user.create');
|
||||
$this->post('/user/create', \App\Controllers\UserController::class . ':store')->setName('user.store');
|
||||
$this->get('/user/{id}/edit', \App\Controllers\UserController::class . ':edit')->setName('user.edit');
|
||||
$this->post('/user/{id}', \App\Controllers\UserController::class . ':update')->setName('user.update');
|
||||
$this->get('/user/{id}/delete', \App\Controllers\UserController::class . ':delete')->setName('user.delete');
|
||||
})->add(\App\Middleware\AdminMiddleware::class);
|
||||
|
||||
$this->group('/user', function () {
|
||||
|
||||
$this->get('/create', \App\Controllers\UserController::class . ':create')->setName('user.create');
|
||||
$this->post('/create', \App\Controllers\UserController::class . ':store')->setName('user.store');
|
||||
$this->get('/{id}/edit', \App\Controllers\UserController::class . ':edit')->setName('user.edit');
|
||||
$this->post('/{id}', \App\Controllers\UserController::class . ':update')->setName('user.update');
|
||||
$this->get('/{id}/delete', \App\Controllers\UserController::class . ':delete')->setName('user.delete');
|
||||
})->add(\App\Middleware\AdminMiddleware::class);
|
||||
|
||||
$this->get('/profile', \App\Controllers\UserController::class . ':profile')->setName('profile');
|
||||
|
|
18
composer.lock
generated
18
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "265c1ca72d526b36b50fcec633b5807f",
|
||||
"content-hash": "3ffe3637bbcca9dc78923aca4ffdbbe6",
|
||||
"packages": [
|
||||
{
|
||||
"name": "container-interop/container-interop",
|
||||
|
@ -859,32 +859,32 @@
|
|||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v2.5.0",
|
||||
"version": "v2.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "6a5f676b77a90823c2d4eaf76137b771adf31323"
|
||||
"reference": "a11dd39f5b6589e14f0ff3b36675d06047c589b1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/6a5f676b77a90823c2d4eaf76137b771adf31323",
|
||||
"reference": "6a5f676b77a90823c2d4eaf76137b771adf31323",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a11dd39f5b6589e14f0ff3b36675d06047c589b1",
|
||||
"reference": "a11dd39f5b6589e14f0ff3b36675d06047c589b1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0",
|
||||
"symfony/polyfill-ctype": "^1.8",
|
||||
"symfony/polyfill-mbstring": "~1.0"
|
||||
"symfony/polyfill-mbstring": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/container": "^1.0",
|
||||
"symfony/debug": "^2.7",
|
||||
"symfony/phpunit-bridge": "^3.3"
|
||||
"symfony/phpunit-bridge": "^3.4.19|^4.1.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.5-dev"
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -922,7 +922,7 @@
|
|||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2018-07-13T07:18:09+00:00"
|
||||
"time": "2018-12-16T10:36:48+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
|
|
@ -86,4 +86,7 @@ return [
|
|||
'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',
|
||||
];
|
|
@ -86,4 +86,7 @@ return [
|
|||
'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',
|
||||
];
|
|
@ -31,6 +31,7 @@
|
|||
</a>
|
||||
<div class="dropdown-menu shadow-sm" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item disabled" href="javascript:void(0)">{{ lang('used') }}: {{ session.used_space }}</a>
|
||||
<a class="dropdown-item" href="{{ route('switchView') }}"><i class="fas fa-fw fa-sync"></i> {{ lang('switch_to') }}: {{ session.gallery_view is null or session.gallery_view ? lang('gallery') : lang('table') }}</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="{{ route('profile') }}"><i class="fas fa-fw fa-user"></i> {{ lang('profile') }}</a>
|
||||
<a class="dropdown-item" href="{{ route('logout') }}"><i class="fas fa-fw fa-sign-out-alt"></i> {{ lang('logout') }}</a>
|
||||
|
|
Loading…
Reference in a new issue