Working on search by tag

This commit is contained in:
Sergio Brighenti 2020-03-29 21:41:48 +02:00
parent 3b4f0ad24e
commit 6a58bc4a32
4 changed files with 64 additions and 4 deletions

View file

@ -56,6 +56,7 @@ class DashboardController extends Controller
->orderBy($order, param($request, 'order', 'DESC')) ->orderBy($order, param($request, 'order', 'DESC'))
->withUserId($this->session->get('user_id')) ->withUserId($this->session->get('user_id'))
->search(param($request, 'search', null)) ->search(param($request, 'search', null))
->filterByTag(param($request, 'tag'))
->run($page); ->run($page);
return view()->render( return view()->render(

View file

@ -35,7 +35,7 @@ class TagController extends Controller
])->fetchAll(PDO::FETCH_COLUMN, 0); ])->fetchAll(PDO::FETCH_COLUMN, 0);
if (!$tag && count($connectedIds) < self::PER_MEDIA_LIMIT) { if (!$tag && count($connectedIds) < self::PER_MEDIA_LIMIT) {
$this->database->query('INSERT INTO `tags`(`name`) VALUES (?)', param($request, 'tag')); $this->database->query('INSERT INTO `tags`(`name`) VALUES (?)', strtolower(param($request, 'tag')));
$tagId = $this->database->getPdo()->lastInsertId(); $tagId = $this->database->getPdo()->lastInsertId();
@ -47,6 +47,7 @@ class TagController extends Controller
return json($response, [ return json($response, [
'limitReached' => false, 'limitReached' => false,
'tagId' => $tagId, 'tagId' => $tagId,
'href' => queryParams(['tag' => $tagId]),
]); ]);
} }
@ -54,6 +55,7 @@ class TagController extends Controller
return json($response, [ return json($response, [
'limitReached' => true, 'limitReached' => true,
'tagId' => null, 'tagId' => null,
'href' => null,
]); ]);
} }
@ -65,6 +67,7 @@ class TagController extends Controller
return json($response, [ return json($response, [
'limitReached' => false, 'limitReached' => false,
'tagId' => $tag->id, 'tagId' => $tag->id,
'href' => queryParams(['tag' => $tag->id]),
]); ]);
} }
@ -78,7 +81,7 @@ 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);

View file

@ -41,6 +41,11 @@ class MediaQuery
private $pages; private $pages;
private $media; private $media;
/**
* @var int
*/
private $tagId;
/** /**
* MediaQuery constructor. * MediaQuery constructor.
* *
@ -104,6 +109,15 @@ class MediaQuery
return $this; return $this;
} }
public function filterByTag($tagId)
{
if ($tagId !== null) {
$this->tagId = (int) $tagId;
}
return $this;
}
public function run(int $page) public function run(int $page)
{ {
@ -242,9 +256,25 @@ class MediaQuery
$queryPages = 'SELECT COUNT(*) AS `count` FROM `uploads`'; $queryPages = 'SELECT COUNT(*) AS `count` FROM `uploads`';
$queryMedia = 'SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id`'; $queryMedia = 'SELECT `uploads`.*, `users`.`user_code`, `users`.`username` FROM `uploads` LEFT JOIN `users` ON `uploads`.`user_id` = `users`.`id`';
if ($this->text !== null || $this->tagId !== null) {
$queryMedia .= ' WHERE';
$queryPages .= ' WHERE';
}
if ($this->text !== null) { if ($this->text !== null) {
$queryMedia .= ' WHERE `uploads`.`filename` LIKE ? '; $queryMedia .= ' `uploads`.`filename` LIKE ?';
$queryPages .= ' WHERE `filename` LIKE ?'; $queryPages .= ' `filename` LIKE ?';
}
if ($this->tagId !== null) {
if ($this->text !== null) {
$queryMedia .= ' AND';
$queryPages .= ' AND';
}
$ids = $this->getMediaIdsByTagId($this->tagId);
$queryMedia .= ' `uploads`.`id` IN ('.implode(',', $ids).')';
$queryPages .= ' `uploads`.`id` IN ('.implode(',', $ids).')';
} }
return [$queryMedia, $queryPages]; return [$queryMedia, $queryPages];
@ -260,6 +290,12 @@ class MediaQuery
$queryPages .= ' AND `filename` LIKE ?'; $queryPages .= ' AND `filename` LIKE ?';
} }
if ($this->tagId !== null) {
$ids = $this->getMediaIdsByTagId($this->tagId);
$queryMedia .= ' AND `uploads`.`id` IN ('.implode(',', $ids).')';
$queryPages .= ' AND `uploads`.`id` IN ('.implode(',', $ids).')';
}
return [$queryMedia, $queryPages]; return [$queryMedia, $queryPages];
} }
@ -277,6 +313,10 @@ class MediaQuery
} }
} }
/**
* @param array $mediaIds
* @return array
*/
protected function getTags(array $mediaIds) protected function getTags(array $mediaIds)
{ {
$allTags = $this->db->query('SELECT `uploads_tags`.`upload_id`,`tags`.`id`, `tags`.`name` FROM `uploads_tags` INNER JOIN `tags` ON `uploads_tags`.`tag_id` = `tags`.`id` WHERE `uploads_tags`.`upload_id` IN ("'.implode('","', $mediaIds).'") ORDER BY `tags`.`timestamp`')->fetchAll(); $allTags = $this->db->query('SELECT `uploads_tags`.`upload_id`,`tags`.`id`, `tags`.`name` FROM `uploads_tags` INNER JOIN `tags` ON `uploads_tags`.`tag_id` = `tags`.`id` WHERE `uploads_tags`.`upload_id` IN ("'.implode('","', $mediaIds).'") ORDER BY `tags`.`timestamp`')->fetchAll();
@ -287,6 +327,20 @@ class MediaQuery
return $tags; return $tags;
} }
/**
* @param $tagId
* @return array
*/
protected function getMediaIdsByTagId($tagId)
{
$mediaIds = $this->db->query('SELECT `upload_id` FROM `uploads_tags` WHERE `tag_id` = ?', $tagId)->fetchAll();
$ids = [];
foreach ($mediaIds as $pivot) {
$ids[] = $pivot->upload_id;
}
return $ids;
}
/** /**
* @return mixed * @return mixed
*/ */

View file

@ -154,6 +154,7 @@ var app = {
.attr('data-id', $caller.data('id')) .attr('data-id', $caller.data('id'))
.attr('maxlength', 32) .attr('maxlength', 32)
.css('width', '90px') .css('width', '90px')
.attr('onchange', 'this.value = this.value.toLowerCase();')
.keydown(function (e) { .keydown(function (e) {
if (e.keyCode === 13) { // enter -> save tag if (e.keyCode === 13) { // enter -> save tag
app.saveTag.call($(this)); // change context app.saveTag.call($(this)); // change context
@ -192,6 +193,7 @@ var app = {
.addClass('badge badge-pill badge-light shadow-sm tag-item mr-1') .addClass('badge badge-pill badge-light shadow-sm tag-item mr-1')
.attr('data-id', data.tagId) .attr('data-id', data.tagId)
.attr('data-media', mediaId) .attr('data-media', mediaId)
.attr('href', data.href)
.contextmenu(app.removeTag) .contextmenu(app.removeTag)
.text(tag) .text(tag)
); );