parent
5990d5fba1
commit
6326f52bd1
|
@ -1,5 +1,6 @@
|
||||||
## v.3.1 (WIP)
|
## v.3.1 (WIP)
|
||||||
+ Added tagging system (add, delete, search of tagged files).
|
+ Added tagging system (add, delete, search of tagged files).
|
||||||
|
+ Added basic media auto-tagging on upload.
|
||||||
+ Added registration system.
|
+ Added registration system.
|
||||||
+ Added password recovery system.
|
+ Added password recovery system.
|
||||||
+ Added ability to export all media of an account.
|
+ Added ability to export all media of an account.
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
namespace App\Controllers;
|
namespace App\Controllers;
|
||||||
|
|
||||||
|
use App\Database\Queries\TagQuery;
|
||||||
use App\Web\ValidationChecker;
|
use App\Web\ValidationChecker;
|
||||||
use PDO;
|
use PDO;
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
|
@ -28,46 +29,12 @@ class TagController extends Controller
|
||||||
throw new HttpBadRequestException($request);
|
throw new HttpBadRequestException($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$tag = $this->database->query('SELECT * FROM `tags` WHERE `name` = ? LIMIT 1', param($request, 'tag'))->fetch();
|
[$id, $limit] = make(TagQuery::class)->addTag(param($request, 'tag'), param($request, 'mediaId'));
|
||||||
|
|
||||||
$connectedIds = $this->database->query('SELECT `tag_id` FROM `uploads_tags` WHERE `upload_id` = ?', [
|
|
||||||
param($request, 'mediaId'),
|
|
||||||
])->fetchAll(PDO::FETCH_COLUMN, 0);
|
|
||||||
|
|
||||||
if (!$tag && count($connectedIds) < self::PER_MEDIA_LIMIT) {
|
|
||||||
$this->database->query('INSERT INTO `tags`(`name`) VALUES (?)', strtolower(param($request, 'tag')));
|
|
||||||
|
|
||||||
$tagId = $this->database->getPdo()->lastInsertId();
|
|
||||||
|
|
||||||
$this->database->query('INSERT INTO `uploads_tags`(`upload_id`, `tag_id`) VALUES (?, ?)', [
|
|
||||||
param($request, 'mediaId'),
|
|
||||||
$tagId,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return json($response, [
|
|
||||||
'limitReached' => false,
|
|
||||||
'tagId' => $tagId,
|
|
||||||
'href' => queryParams(['tag' => $tagId]),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($connectedIds) >= self::PER_MEDIA_LIMIT || in_array($tag->id, $connectedIds)) {
|
|
||||||
return json($response, [
|
|
||||||
'limitReached' => true,
|
|
||||||
'tagId' => null,
|
|
||||||
'href' => null,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->database->query('INSERT INTO `uploads_tags`(`upload_id`, `tag_id`) VALUES (?, ?)', [
|
|
||||||
param($request, 'mediaId'),
|
|
||||||
$tag->id,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return json($response, [
|
return json($response, [
|
||||||
'limitReached' => false,
|
'limitReached' => $limit,
|
||||||
'tagId' => $tag->id,
|
'tagId' => $id,
|
||||||
'href' => queryParams(['tag' => $tag->id]),
|
'href' => queryParams(['tag' => $id]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,28 +47,18 @@ class TagController extends Controller
|
||||||
*/
|
*/
|
||||||
public function removeTag(Request $request, Response $response): Response
|
public function removeTag(Request $request, Response $response): Response
|
||||||
{
|
{
|
||||||
$validator = $this->validateTag($request)
|
$validator = $this->validateTag($request)->removeRule('tag.notEmpty');
|
||||||
->removeRule('tag.notEmpty');
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
throw new HttpBadRequestException($request);
|
throw new HttpBadRequestException($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$tag = $this->database->query('SELECT * FROM `tags` WHERE `id` = ? LIMIT 1', param($request, 'tagId'))->fetch();
|
$result = make(TagQuery::class)->removeTag(param($request, 'tagId'), param($request, 'mediaId'));
|
||||||
|
|
||||||
if (!$tag) {
|
if (!$result) {
|
||||||
throw new HttpNotFoundException($request);
|
throw new HttpNotFoundException($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->database->query('DELETE FROM `uploads_tags` WHERE `upload_id` = ? AND `tag_id` = ?', [
|
|
||||||
param($request, 'mediaId'),
|
|
||||||
$tag->id,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($this->database->query('SELECT COUNT(*) AS `count` FROM `uploads_tags` WHERE `tag_id` = ?', $tag->id)->fetch()->count == 0) {
|
|
||||||
$this->database->query('DELETE FROM `tags` WHERE `id` = ? ', $tag->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Controllers;
|
namespace App\Controllers;
|
||||||
|
|
||||||
|
use App\Database\Queries\TagQuery;
|
||||||
use App\Database\Queries\UserQuery;
|
use App\Database\Queries\UserQuery;
|
||||||
use App\Exceptions\ValidationException;
|
use App\Exceptions\ValidationException;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
@ -183,6 +184,7 @@ class UploadController extends Controller
|
||||||
* @param $user
|
* @param $user
|
||||||
* @return Response
|
* @return Response
|
||||||
* @throws \League\Flysystem\FileExistsException
|
* @throws \League\Flysystem\FileExistsException
|
||||||
|
* @throws \League\Flysystem\FileNotFoundException
|
||||||
*/
|
*/
|
||||||
protected function saveMedia(Response $response, UploadedFileInterface $file, $user)
|
protected function saveMedia(Response $response, UploadedFileInterface $file, $user)
|
||||||
{
|
{
|
||||||
|
@ -207,12 +209,35 @@ class UploadController extends Controller
|
||||||
$storagePath,
|
$storagePath,
|
||||||
$published,
|
$published,
|
||||||
]);
|
]);
|
||||||
|
$mediaId = $this->database->getPdo()->lastInsertId();
|
||||||
|
|
||||||
|
$this->autoTag($mediaId, $storagePath);
|
||||||
|
|
||||||
$this->json['message'] = 'OK';
|
$this->json['message'] = 'OK';
|
||||||
$this->json['url'] = urlFor("/{$user->user_code}/{$code}.{$fileInfo['extension']}");
|
$this->json['url'] = urlFor("/{$user->user_code}/{$code}.{$fileInfo['extension']}");
|
||||||
|
|
||||||
$this->logger->info("User $user->username uploaded new media.", [$this->database->getPdo()->lastInsertId()]);
|
$this->logger->info("User $user->username uploaded new media.", [$mediaId]);
|
||||||
|
|
||||||
return json($response, $this->json, 201);
|
return json($response, $this->json, 201);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $mediaId
|
||||||
|
* @param $storagePath
|
||||||
|
* @throws \League\Flysystem\FileNotFoundException
|
||||||
|
*/
|
||||||
|
protected function autoTag($mediaId, $storagePath)
|
||||||
|
{
|
||||||
|
$mime = $this->storage->getMimetype($storagePath);
|
||||||
|
|
||||||
|
[$type, $subtype] = explode('/', $mime);
|
||||||
|
|
||||||
|
/** @var TagQuery $query */
|
||||||
|
$query = make(TagQuery::class);
|
||||||
|
$query->addTag($type, $mediaId);
|
||||||
|
|
||||||
|
if ($type === 'application') {
|
||||||
|
$query->addTag($subtype, $mediaId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
86
app/Database/Queries/TagQuery.php
Normal file
86
app/Database/Queries/TagQuery.php
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Database\Queries;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Database\DB;
|
||||||
|
use PDO;
|
||||||
|
|
||||||
|
class TagQuery
|
||||||
|
{
|
||||||
|
|
||||||
|
const PER_MEDIA_LIMIT = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DB
|
||||||
|
*/
|
||||||
|
private $db;
|
||||||
|
|
||||||
|
public function __construct(DB $db)
|
||||||
|
{
|
||||||
|
$this->db = $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $tagName
|
||||||
|
* @param $mediaId
|
||||||
|
* @return array [id, limit]
|
||||||
|
*/
|
||||||
|
public function addTag(string $tagName, $mediaId)
|
||||||
|
{
|
||||||
|
$tag = $this->db->query('SELECT * FROM `tags` WHERE `name` = ? LIMIT 1', $tagName)->fetch();
|
||||||
|
|
||||||
|
$connectedIds = $this->db->query('SELECT `tag_id` FROM `uploads_tags` WHERE `upload_id` = ?', $mediaId)->fetchAll(PDO::FETCH_COLUMN, 0);
|
||||||
|
|
||||||
|
if (!$tag && count($connectedIds) < self::PER_MEDIA_LIMIT) {
|
||||||
|
$this->db->query('INSERT INTO `tags`(`name`) VALUES (?)', strtolower($tagName));
|
||||||
|
|
||||||
|
$tagId = $this->db->getPdo()->lastInsertId();
|
||||||
|
|
||||||
|
$this->db->query('INSERT INTO `uploads_tags`(`upload_id`, `tag_id`) VALUES (?, ?)', [
|
||||||
|
$mediaId,
|
||||||
|
$tagId,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [$tagId, false];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($connectedIds) >= self::PER_MEDIA_LIMIT || in_array($tag->id, $connectedIds)) {
|
||||||
|
return [null, true];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->query('INSERT INTO `uploads_tags`(`upload_id`, `tag_id`) VALUES (?, ?)', [
|
||||||
|
$mediaId,
|
||||||
|
$tag->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [$tag->id, false];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $tagId
|
||||||
|
* @param $mediaId
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function removeTag($tagId, $mediaId)
|
||||||
|
{
|
||||||
|
$tag = $this->db->query('SELECT * FROM `tags` WHERE `id` = ? LIMIT 1', $tagId)->fetch();
|
||||||
|
|
||||||
|
if ($tag) {
|
||||||
|
$this->db->query('DELETE FROM `uploads_tags` WHERE `upload_id` = ? AND `tag_id` = ?', [
|
||||||
|
$mediaId,
|
||||||
|
$tag->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($this->db->query('SELECT COUNT(*) AS `count` FROM `uploads_tags` WHERE `tag_id` = ?', $tag->id)->fetch()->count == 0) {
|
||||||
|
$this->db->query('DELETE FROM `tags` WHERE `id` = ? ', $tag->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue