Skip to content
This repository has been archived by the owner on Nov 2, 2020. It is now read-only.

Commit

Permalink
feat(Pager): Torrents/{SearchForm,TagsForm}
Browse files Browse the repository at this point in the history
  • Loading branch information
Rhilip committed Aug 6, 2019
1 parent 8dcd064 commit 07820ea
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 96 deletions.
83 changes: 19 additions & 64 deletions apps/controllers/TorrentsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

namespace apps\controllers;

use apps\models\form\Torrents\SearchForm;
use apps\models\form\Torrents\TagsForm;
use Rid\Http\Controller;

use apps\models\Torrent;

class TorrentsController extends Controller
{
Expand All @@ -22,78 +23,32 @@ public function actionIndex()

public function actionSearch()
{
// FIXME use model to support SQL-search or elesticsearch
// TODO add URI level Cache

$limit = app()->request->get('limit',50);
if (!filter_var($limit,FILTER_VALIDATE_INT) || $limit > 100) {
$limit = 100;
}
$page = app()->request->get('page',1);
if (!filter_var($page,FILTER_VALIDATE_INT)) {
$page = 1;
}

$_tags = app()->request->get('tags');
if ($_tags) {
$tags = array_map('trim', explode(',', $_tags));
} else {
$tags = [];
$pager = new SearchForm();
$pager->setData(app()->request->get());
$success = $pager->validate();
if (!$success) {
return $this->render('action/action_fail');
}

$fetch = app()->pdo->createCommand([
['SELECT DISTINCT t.`id`, t.`added_at` FROM `torrents` t '],
['INNER JOIN map_torrents_tags mtt on t.id = mtt.torrent_id INNER JOIN tags t2 on mtt.tag_id = t2.id ', 'if' => count($tags)],
['WHERE 1=1 '],
['AND t2.tag IN(:tags) ', 'if' => count($tags), 'params' => ['tags' => $tags]],
['ORDER BY `t`.`added_at` DESC '],
['LIMIT :offset, :rows', 'params' => ['offset' => ($page - 1) * $limit, 'rows' => $limit]],
])->queryColumn();

$count = app()->pdo->createCommand([
['SELECT COUNT(t.`id`) FROM `torrents` t '],
['INNER JOIN map_torrents_tags mtt on t.id = mtt.torrent_id INNER JOIN tags t2 on mtt.tag_id = t2.id ', 'if' => count($tags)],
['WHERE 1=1 '],
['AND t2.tag IN(:tags) ', 'if' => count($tags), 'params' => ['tags' => $tags]],
])->queryScalar();

$torrents = array_map(function ($id) {
return new Torrent($id);
}, $fetch);

return $this->render('torrents/list', [
'count' => $count,
'limit' => $limit,
'torrents' => $torrents
]);
return $this->render('torrents/list', ['pager' => $pager]);
}

public function actionTags()
{
$search = trim(app()->request->get('search', ''));
$limit = app()->request->get('limit',50);
if (!filter_var($limit,FILTER_VALIDATE_INT) || $limit > 100) {
$limit = 100;
}
$page = app()->request->get('page',1);
if (!filter_var($page,FILTER_VALIDATE_INT)) $page = 1;
$pager = new TagsForm();
$pager->setData(app()->request->get());
$success = $pager->validate();

$tags = app()->pdo->createCommand([
['SELECT tags.*,COUNT(mtt.id) as `count` FROM tags LEFT JOIN map_torrents_tags mtt on tags.id = mtt.tag_id '],
['WHERE `tags`.`tag` LIKE :tag', 'if' => !empty($search), 'params' => ['tag' => '%' . $search . '%']],
['GROUP BY tags.id ORDER BY `tags`.`pinned`,`count` DESC '],
['LIMIT :offset, :rows', 'params' => ['offset' => ($page - 1) * $limit, 'rows' => $limit]],
])->queryAll();

if (count($tags) == 1 && $tags[0]['tag'] == $search) { // If this search tag is unique and equal to the wanted, just redirect to search page
return app()->response->redirect('/torrents/search?tags=' . $search);
if (!$success) {
return $this->render('action/action_fail');
} else {
$tags = $pager->getPagerData();
if (count($tags) == 1 && $tags[0]['tag'] == $pager->search) { // If this search tag is unique and equal to the wanted, just redirect to search page
return app()->response->redirect('/torrents/search?tags=' . $pager->search);
}
return $this->render('torrents/tags', ['pager' => $pager]);
}

$tag_count = app()->pdo->createCommand([
['SELECT COUNT(tags.id) as `count` FROM tags'],
['WHERE `tags`.`tag` LIKE :tag', 'if' => !empty($search), 'params' => ['tag' => '%' . $search . '%']],
])->queryScalar();

return $this->render('torrents/tags', ['search' => $search, 'tags' => $tags, 'count' => $tag_count]);
}
}
62 changes: 62 additions & 0 deletions apps/models/form/Torrents/SearchForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
/**
* Created by PhpStorm.
* User: Rhilip
* Date: 8/6/2019
* Time: 9:10 PM
*/

namespace apps\models\form\Torrents;


use apps\models\Torrent;
use Rid\Validators\Pager;

class SearchForm extends Pager
{
public $tags;

static $max_limit = 100;

private $_tags;

private function getTagsArray()
{
if (is_null($this->_tags)) {
$tags = $this->getData('tags');
$this->_tags = $tags ? array_map('trim', explode(',', $tags)) : [];
}

return $this->_tags;
}

protected function getRemoteTotal()
{
$tags = $this->getTagsArray();

return app()->pdo->createCommand([
['SELECT COUNT(t.`id`) FROM `torrents` t '],
['INNER JOIN map_torrents_tags mtt on t.id = mtt.torrent_id INNER JOIN tags t2 on mtt.tag_id = t2.id ', 'if' => count($tags)],
['WHERE 1=1 '],
['AND t2.tag IN(:tags) ', 'if' => count($tags), 'params' => ['tags' => $tags]],
])->queryScalar();
}

protected function getRemoteData()
{
$tags = $this->getTagsArray();

$fetch = app()->pdo->createCommand([
['SELECT DISTINCT t.`id`, t.`added_at` FROM `torrents` t '],
['INNER JOIN map_torrents_tags mtt on t.id = mtt.torrent_id INNER JOIN tags t2 on mtt.tag_id = t2.id ', 'if' => count($tags)],
['WHERE 1=1 '],
['AND t2.tag IN(:tags) ', 'if' => count($tags), 'params' => ['tags' => $tags]],
['ORDER BY `t`.`added_at` DESC '],
['LIMIT :offset, :rows', 'params' => ['offset' => $this->offset, 'rows' => $this->limit]],
])->queryColumn();

return array_map(function ($id) {
return new Torrent($id);
}, $fetch);
}
}
39 changes: 39 additions & 0 deletions apps/models/form/Torrents/TagsForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/**
* Created by PhpStorm.
* User: Rhilip
* Date: 8/6/2019
* Time: 8:52 PM
*/

namespace apps\models\form\Torrents;


use Rid\Validators\Pager;

class TagsForm extends Pager
{
public $search;

static $max_limit = 100;

public function getRemoteTotal()
{
return app()->pdo->createCommand([
['SELECT COUNT(tags.id) as `count` FROM tags'],
['WHERE `tags`.`tag` LIKE :tag', 'if' => !empty($search), 'params' => ['tag' => '%' . $this->getData('search') . '%']],
])->queryScalar();
}

public function getRemoteData()
{
$search = $this->search;
return app()->pdo->createCommand([
['SELECT tags.*,COUNT(mtt.id) as `count` FROM tags LEFT JOIN map_torrents_tags mtt on tags.id = mtt.tag_id '],
['WHERE `tags`.`tag` LIKE :tag', 'if' => !empty($search), 'params' => ['tag' => '%' . $search . '%']],
['GROUP BY tags.id ORDER BY `tags`.`pinned`,`count` DESC '],
['LIMIT :offset, :rows', 'params' => ['offset' => $this->offset, 'rows' => $this->limit]],
])->queryAll();
}

}
6 changes: 1 addition & 5 deletions apps/public/static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,7 @@ jQuery(document).ready(function () {
let help_info = $(this).children('i');
let old_type_is_password = password_input.attr('type') === 'password';
password_input.attr('type', old_type_is_password ? 'text' : 'password');
if (old_type_is_password) {
help_info.removeClass('fa-eye').addClass('fa-eye-slash');
} else {
help_info.removeClass('fa-eye-slash').addClass('fa-eye');
}
help_info.toggleClass('fa-eye-slash', old_type_is_password).toggleClass('fa-eye', !old_type_is_password);
});

// Torrent favour Add/Remove action
Expand Down
9 changes: 3 additions & 6 deletions apps/views/torrents/list.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
* Time: 20:40
*
* @var League\Plates\Template\Template $this
* @var array $torrents
* @var \apps\models\Torrent $torrent
* @var int $count
* @var int $limit
* @var \apps\models\form\Torrents\SearchForm $pager
*/

$time_now = time();
Expand Down Expand Up @@ -38,7 +35,7 @@
</tr>
</thead>
<tbody>
<?php foreach ($torrents as $torrent): ?>
<?php foreach ($pager->getPagerData() as $torrent): /** @var \apps\models\Torrent $torrent */ ?>
<tr data-tid="<?= $torrent->getId() ?>">
<td class="text-center" data-item="category" style="margin: 0;padding: 0">
<?php $cat = $torrent->getCategory(); ?>
Expand Down Expand Up @@ -96,7 +93,7 @@
</tbody>
</table>
<div class="text-center">
<ul class="pager pager-unset-margin" data-ride="remote_pager" data-rec-total="<?= $count ?>" data-rec-per-page="<?= $limit ?? 50 ?>"></ul>
<ul class="pager pager-unset-margin" data-ride="remote_pager" data-rec-total="<?= $pager->getDataTotal() ?>" data-rec-per-page="<?= $pager->getLimit() ?>"></ul>
</div>
</div>
</div>
Expand Down
11 changes: 4 additions & 7 deletions apps/views/torrents/tags.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
* Time: 7:39 PM
*
* @var League\Plates\Template\Template $this
* @var array $tags
* @var string $search
* @var int $count
* @var int $limit
* @var \apps\models\form\Torrents\TagsForm $pager
*/
?>

Expand All @@ -26,7 +23,7 @@
<div class="input-group">
<div class="input-control search-box search-box-circle has-icon-left has-icon-righ"
id="tags_search_div">
<input id="tags_search_input" type="text" name="search" class="form-control search-input" value="<?= $search ?? '' ?>">
<input id="tags_search_input" type="text" name="search" class="form-control search-input" value="<?= $pager->search ?? '' ?>">
<label for="tags_search_input" class="input-control-icon-left search-icon">
<i class="icon icon-search"></i>
</label>
Expand All @@ -41,12 +38,12 @@
</div>
<div class="col-md-10 col-md-offset-1">
<div id="tags_list">
<?php foreach ($tags as $tag): ?>
<?php foreach ($pager->getPagerData() as $tag): ?>
<a class="btn" href="/torrents/search?tags=<?= $tag['tag'] ?>"><?= $tag['tag'] ?> <span class="label label-badge <?= $tag['class_name'] ?>"><?= $tag['count'] ?></span></a>
<?php endforeach; ?>
</div>
<div class="text-center">
<ul class="pager" data-ride="remote_pager" data-rec-total="<?= $count ?>" data-rec-per-page="<?= $limit ?? 50 ?>"></ul>
<ul class="pager" data-ride="remote_pager" data-rec-total="<?= $pager->getTotal() ?>" data-rec-per-page="<?= $pager->getLimit() ?>"></ul>
</div>
</div>
</div>
Expand Down
16 changes: 8 additions & 8 deletions framework/Validators/Pager.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ protected function checkPager()
if ($limit > static::$max_limit) $limit = static::$max_limit;
$page = $this->getData('page', static::$default_page);

self::setData(['limit' => $limit,'page' => $page]);
$this->setData(['limit' => $limit, 'page' => $page]);

$this->total = $total = $this->getDataTotal();
$this->total = $this->getDataTotal();
$this->offset = ($page - 1) * $limit;

$offset = ($page - 1) * $limit;
if (($offset * $limit) > $total) $offset = intval($total / ($offset * $limit)) * $limit;
$this->offset = $offset;
// Quick return empty array when offset is much bigger than total, So we needn't hit remote or local data
if ($this->offset > $this->total) $this->pager_data = [];
}

final public function getDataTotal(): int
Expand All @@ -101,12 +101,12 @@ final public function getDataTotal(): int
return $this->pager_data_total;
}

public function getRemoteTotal()
protected function getRemoteTotal()
{
throw new \RuntimeException('function "getRemoteTotal()" not implemented.');
}

public function getPagerData()
final public function getPagerData()
{
if (is_null($this->pager_data)) {
if (static::$data_source == 'remote') $this->pager_data = $this->getRemoteData();
Expand All @@ -115,7 +115,7 @@ public function getPagerData()
return $this->pager_data;
}

public function getRemoteData()
protected function getRemoteData()
{
throw new \RuntimeException('function "getRemoteData()" not implemented.');
}
Expand Down
8 changes: 2 additions & 6 deletions framework/Validators/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ final protected function buildCallbackFailMsg($field, $msg)
*/
final public function setData($config)
{
$this->_data += $config;
$this->_data = array_merge($this->_data, $config);
}

final public function setFileData($config)
Expand Down Expand Up @@ -125,11 +125,7 @@ final protected function releaseDataToProperties()

foreach ($this->_data as $name => $value) {
if (in_array($name, $public_props)) {
if (in_array($name, $this->_file_data_name)) {
$this->$name = new UploadFile($value);
} else {
$this->$name = $value;
}
$this->$name = $this->getData($name);
} elseif (in_array($name, $no_change_props)) {
$this->buildCallbackFailMsg('harking', 'User post may hack.');
return;
Expand Down

0 comments on commit 07820ea

Please sign in to comment.