diff --git a/apps/controllers/TorrentsController.php b/apps/controllers/TorrentsController.php index 0e8c7bf..bf15612 100644 --- a/apps/controllers/TorrentsController.php +++ b/apps/controllers/TorrentsController.php @@ -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 { @@ -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]); } } diff --git a/apps/models/form/Torrents/SearchForm.php b/apps/models/form/Torrents/SearchForm.php new file mode 100644 index 0000000..bee0b24 --- /dev/null +++ b/apps/models/form/Torrents/SearchForm.php @@ -0,0 +1,62 @@ +_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); + } +} diff --git a/apps/models/form/Torrents/TagsForm.php b/apps/models/form/Torrents/TagsForm.php new file mode 100644 index 0000000..2dcadd9 --- /dev/null +++ b/apps/models/form/Torrents/TagsForm.php @@ -0,0 +1,39 @@ +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(); + } + +} diff --git a/apps/public/static/js/main.js b/apps/public/static/js/main.js index ffe034f..ab7bdd7 100644 --- a/apps/public/static/js/main.js +++ b/apps/public/static/js/main.js @@ -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 diff --git a/apps/views/torrents/list.php b/apps/views/torrents/list.php index 12fceed..e70753f 100644 --- a/apps/views/torrents/list.php +++ b/apps/views/torrents/list.php @@ -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(); @@ -38,7 +35,7 @@ - + getPagerData() as $torrent): /** @var \apps\models\Torrent $torrent */ ?> getCategory(); ?> @@ -96,7 +93,7 @@
- +
diff --git a/apps/views/torrents/tags.php b/apps/views/torrents/tags.php index c3a42c8..a235267 100644 --- a/apps/views/torrents/tags.php +++ b/apps/views/torrents/tags.php @@ -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 */ ?> @@ -26,7 +23,7 @@
- + getPagerData() as $tag): ?>
-
    +
      diff --git a/framework/Validators/Pager.php b/framework/Validators/Pager.php index ba84844..f4dfe29 100644 --- a/framework/Validators/Pager.php +++ b/framework/Validators/Pager.php @@ -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 @@ -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(); @@ -115,7 +115,7 @@ public function getPagerData() return $this->pager_data; } - public function getRemoteData() + protected function getRemoteData() { throw new \RuntimeException('function "getRemoteData()" not implemented.'); } diff --git a/framework/Validators/Validator.php b/framework/Validators/Validator.php index 8f8b240..80c434d 100644 --- a/framework/Validators/Validator.php +++ b/framework/Validators/Validator.php @@ -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) @@ -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;