diff --git a/module/VuFind/src/VuFind/Db/Table/ResourceTags.php b/module/VuFind/src/VuFind/Db/Table/ResourceTags.php index 68b377995ee75fdd0015aa5347de8f8f8d704e0c..dd208444b6d85ae50ff9b32b44788852e45442f2 100644 --- a/module/VuFind/src/VuFind/Db/Table/ResourceTags.php +++ b/module/VuFind/src/VuFind/Db/Table/ResourceTags.php @@ -166,9 +166,11 @@ class ResourceTags extends Gateway /** * Get statistics on use of tags. * + * @param bool $extended Include extended (unique/anonymous) stats. + * * @return array */ - public function getStatistics() + public function getStatistics($extended = false) { $select = $this->sql->select(); $select->columns( @@ -186,7 +188,12 @@ class ResourceTags extends Gateway ); $statement = $this->sql->prepareStatementForSqlObject($select); $result = $statement->execute(); - return (array)$result->current(); + $stats = (array)$result->current(); + if ($extended) { + $stats['unique'] = count($this->getUniqueTags()); + $stats['anonymous'] = count($this->getAnonymousCount()); + } + return $stats; } /** @@ -275,4 +282,185 @@ class ResourceTags extends Gateway }; $this->update(array('user_id' => $id), $callback); } + + /** + * Gets unique resources from the table + * + * @param string $userId ID of user + * @param string $resourceId ID of the resource + * @param string $tagId ID of the tag + * + * @return \Zend\Db\ResultSet\AbstractResultSet + */ + public function getUniqueResources( + $userId = null, $resourceId = null, $tagId = null + ) { + $callback = function ($select) use ($userId, $resourceId, $tagId) { + $select->join( + array('r' => 'resource'), + 'resource_tags.resource_id = r.id', + array("title" => "title") + ); + if (!is_null($userId)) { + $select->where->equalTo('resource_tags.user_id', $userId); + } + if (!is_null($resourceId)) { + $select->where->equalTo('resource_tags.resource_id', $resourceId); + } + if (!is_null($tagId)) { + $select->where->equalTo('resource_tags.tag_id', $tagId); + } + $select->group(array("resource_id")); + $select->order(array("title")); + }; + return $this->select($callback); + } + + /** + * Gets unique tags from the table + * + * @param string $userId ID of user + * @param string $resourceId ID of the resource + * @param string $tagId ID of the tag + * + * @return \Zend\Db\ResultSet\AbstractResultSet + */ + public function getUniqueTags($userId = null, $resourceId = null, $tagId = null) + { + + $callback = function ($select) use ($userId, $resourceId, $tagId) { + $select->join( + array('t' => 'tags'), + 'resource_tags.tag_id = t.id', + array("tag" => "tag") + ); + if (!is_null($userId)) { + $select->where->equalTo('resource_tags.user_id', $userId); + } + if (!is_null($resourceId)) { + $select->where->equalTo('resource_tags.resource_id', $resourceId); + } + if (!is_null($tagId)) { + $select->where->equalTo('resource_tags.tag_id', $tagId); + } + $select->group(array("tag_id")); + $select->order(array("tag")); + }; + return $this->select($callback); + } + + /** + * Gets unique users from the table + * + * @param string $userId ID of user + * @param string $resourceId ID of the resource + * @param string $tagId ID of the tag + * + * @return \Zend\Db\ResultSet\AbstractResultSet + */ + public function getUniqueUsers($userId = null, $resourceId = null, $tagId = null) + { + $callback = function ($select) use ($userId, $resourceId, $tagId) { + $select->join( + array('u' => 'user'), + 'resource_tags.user_id = u.id', + array("username" => "username") + ); + if (!is_null($userId)) { + $select->where->equalTo('resource_tags.user_id', $userId); + } + if (!is_null($resourceId)) { + $select->where->equalTo('resource_tags.resource_id', $resourceId); + } + if (!is_null($tagId)) { + $select->where->equalTo('resource_tags.tag_id', $tagId); + } + $select->group(array("user_id")); + $select->order(array("username")); + }; + return $this->select($callback); + } + + /** + * Get Resource Tags + * + * @param string $userId ID of user + * @param string $resourceId ID of the resource + * @param string $tagId ID of the tag + * @param string $order The order in which to return the data + * @param string $page The page number to select + * @param string $limit The number of items to fetch + * + * @return \Zend\Paginator\Paginator + */ + public function getResourceTags( + $userId = null, $resourceId = null, $tagId = null, + $order = null, $page = null, $limit = 20 + ) { + $order = (null !== $order) + ? array($order) + : array("username", "tag", "title"); + + $sql = $this->getSql(); + $select = $sql->select(); + $select->join( + array('t' => 'tags'), + 'resource_tags.tag_id = t.id', + array("tag" => "tag") + ); + $select->join( + array('u' => 'user'), + 'resource_tags.user_id = u.id', + array("username" => "username") + ); + $select->join( + array('r' => 'resource'), + 'resource_tags.resource_id = r.id', + array("title" => "title") + ); + if (null !== $userId) { + $select->where->equalTo('resource_tags.user_id', $userId); + } + if (null !== $resourceId) { + $select->where->equalTo('resource_tags.resource_id', $resourceId); + } + if (null !== $tagId) { + $select->where->equalTo('resource_tags.tag_id', $tagId); + } + $select->order($order); + + if (null !== $page) { + $select->limit($limit); + $select->offset($limit * ($page - 1)); + } + + $adapter = new \Zend\Paginator\Adapter\DbSelect($select, $sql); + $paginator = new \Zend\Paginator\Paginator($adapter); + $paginator->setItemCountPerPage($limit); + if (null !== $page) { + $paginator->setCurrentPageNumber($page); + } + return $paginator; + } + + /** + * Delete a group of tags. + * + * @param array $ids IDs of tags to delete. + * + * @return int Count of $ids + */ + public function deleteByIdArray($ids) + { + // Do nothing if we have no IDs to delete! + if (empty($ids)) { + return; + } + + $callback = function ($select) use ($ids) { + $select->where->in('id', $ids); + }; + $this->delete($callback); + return count($ids); + } } diff --git a/module/VuFindAdmin/config/module.config.php b/module/VuFindAdmin/config/module.config.php index 196344a9c0d323205cb10b2ae1572a0535e0b734..882ace30efec0a4e6c13b3451cd346479d28778a 100644 --- a/module/VuFindAdmin/config/module.config.php +++ b/module/VuFindAdmin/config/module.config.php @@ -9,6 +9,7 @@ $config = array( 'adminsocial' => 'VuFindAdmin\Controller\SocialstatsController', 'adminmaintenance' => 'VuFindAdmin\Controller\MaintenanceController', 'adminstatistics' => 'VuFindAdmin\Controller\StatisticsController', + 'admintags' => 'VuFindAdmin\Controller\TagsController', ), ), 'router' => array( @@ -74,6 +75,16 @@ $config = array( ) ) ), + 'tags' => array( + 'type' => 'Zend\Mvc\Router\Http\Segment', + 'options' => array( + 'route' => '/Tags[/:action]', + 'defaults' => array( + 'controller' => 'AdminTags', + 'action' => 'Home', + ) + ) + ), ), ), ), diff --git a/module/VuFindAdmin/src/VuFindAdmin/Controller/TagsController.php b/module/VuFindAdmin/src/VuFindAdmin/Controller/TagsController.php new file mode 100644 index 0000000000000000000000000000000000000000..eaf03679da5b495a1daa5d8c8fba7a83f9f7b65a --- /dev/null +++ b/module/VuFindAdmin/src/VuFindAdmin/Controller/TagsController.php @@ -0,0 +1,422 @@ +<?php +/** + * Admin Tag Controller + * + * PHP version 5 + * + * Copyright (C) Villanova University 2010. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package Controller + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ +namespace VuFindAdmin\Controller; + +/** + * Class controls distribution of tags and resource tags. + * + * @category VuFind2 + * @package Controller + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ + +class TagsController extends AbstractAdmin +{ + /** + * Params + * + * @var array + */ + protected $params; + + /** + * Get the url parameters + * + * @param string $param A key to check the url params for + * + * @return string + */ + protected function getParam($param) + { + return (isset($this->params[$param])) + ? $this->params[$param] + : $this->params()->fromPost( + $param, + $this->params()->fromQuery($param, null) + ); + } + + /** + * Tag Details + * + * @return \Zend\View\Model\ViewModel + */ + public function homeAction() + { + $view = $this->createViewModel(); + $view->setTemplate('admin/tags/home'); + $view->statistics = $this->getTable('resourcetags')->getStatistics(true); + return $view; + } + + /** + * Manage Tags + * + * @return \Zend\View\Model\ViewModel + */ + public function manageAction() + { + $this->params = $this->params()->fromQuery(); + + $view = $this->createViewModel(); + $view->setTemplate('admin/tags/manage'); + $view->type = !is_null($this->params()->fromPost('type', null)) + ? $this->params()->fromPost('type') + : $this->params()->fromQuery('type', null); + $view->uniqueTags = $this->getUniqueTags()->toArray(); + $view->uniqueUsers = $this->getUniqueUsers()->toArray(); + $view->uniqueResources = $this->getUniqueResources()->toArray(); + $view->params = $this->params; + return $view; + } + + /** + * List Tags + * + * @return \Zend\View\Model\ViewModel + */ + public function listAction() + { + $this->params = $this->params()->fromQuery(); + + $view = $this->createViewModel(); + $view->setTemplate('admin/tags/list'); + $view->uniqueTags = $this->getUniqueTags()->toArray(); + $view->uniqueUsers = $this->getUniqueUsers()->toArray(); + $view->uniqueResources = $this->getUniqueResources()->toArray(); + $view->results = $this->getResourceTags(); + $view->params = $this->params; + return $view; + } + + /** + * Delete Tags + * + * @return \Zend\View\Model\ViewModel + */ + public function deleteAction() + { + $this->params = $this->params()->fromPost(); + $tags = $this->getTable('ResourceTags'); + + $origin = $this->params() + ->fromPost('origin', $this->params()->fromQuery('origin')); + + $action = ("list" == $origin) ? 'List' : 'Manage'; + + $originUrl = $this->url() + ->fromRoute('admin/tags', array('action' => $action)); + if ($action == 'List') { + $originUrl .= '?' . http_build_query( + array( + 'user_id' => $this->getParam('user_id'), + 'resource_id' => $this->getParam('resource_id'), + 'tag_id' => $this->getParam('tag_id'), + ) + ); + } + $newUrl = $this->url()->fromRoute('admin/tags', array('action' => 'Delete')); + + $confirm = $this->params()->fromPost('confirm', false); + + // Delete All + if ("manage" == $origin + || !is_null($this->getRequest()->getPost('deleteFilter')) + || !is_null($this->getRequest()->getQuery('deleteFilter')) + ) { + if (false === $confirm) { + return $this->confirmTagsDeleteByFilter($tags, $originUrl, $newUrl); + } + $delete = $this->deleteResourceTagsByFilter(); + } else { + // Delete by ID + // Fail if we have nothing to delete: + $ids = is_null($this->getRequest()->getPost('deletePage')) + ? $this->params()->fromPost('ids') + : $this->params()->fromPost('idsAll'); + + if (!is_array($ids) || empty($ids)) { + $this->flashMessenger()->setNamespace('error') + ->addMessage('bulk_noitems_advice'); + return $this->redirect()->toUrl($originUrl); + } + + if (false === $confirm) { + return $this->confirmTagsDelete($tags, $ids, $originUrl, $newUrl); + } + $delete = $tags->deleteByIdArray($ids); + + } + + if (0 == $delete) { + $this->flashMessenger()->setNamespace('error') + ->addMessage('tags_delete_fail'); + return $this->redirect()->toUrl($originUrl); + } + + $this->flashMessenger()->setNamespace('info') + ->addMessage( + array( + 'msg' => 'tags_deleted', + 'tokens' => array('%count%' => $delete) + ) + ); + return $this->redirect()->toUrl($originUrl); + } + + /** + * Confirm Delete by Id + * + * @param object $tagModel A tag object + * @param array $ids A list of resource tag Ids + * @param string $originUrl An origin url + * @param string $newUrl The url of the desired action + * + * @return $this->confirmAction + */ + protected function confirmTagsDelete($tagModel, $ids, $originUrl, $newUrl) + { + $messages = array(); + $count = count($ids); + + $user = $this->getTable('user') + ->select(array('id' => $this->getParam('user_id'))) + ->current(); + $userMsg = (false !== $user) + ? $user->username . " (" . $user->id . ")" : "All"; + + $tag = $this->getTable('tags') + ->select(array('id' => $this->getParam('tag_id'))) + ->current(); + $tagMsg = (false !== $tag) ? $tag->tag. " (" . $tag->id . ")" : " All"; + + $resource = $this->getTable('resource') + ->select(array('id' => $this->getParam('resource_id'))) + ->current(); + $resourceMsg = (false !== $resource) + ? $resource->title. " (" . $resource->id . ")" : " All"; + + $messages[] = array( + 'msg' => 'tag_delete_warning', + 'tokens' => array('%count%' => $count) + ); + if (false !== $user || false!== $tag || false !== $resource) { + $messages[] = array( + 'msg' => 'tag_delete_filter', + 'tokens' => array( + '%username%' => $userMsg, + '%tag%' => $tagMsg, + '%resource%' => $resourceMsg + ) + ); + } + $data = array( + 'data' => array( + 'confirm' => $newUrl, + 'cancel' => $originUrl, + 'title' => "confirm_delete_tags_brief", + 'messages' => $messages, + 'ids' => $ids, + 'extras' => array( + 'origin' => 'list', + 'user_id' => $this->getParam('user_id'), + 'tag_id' => $this->getParam('tag_id'), + 'resource_id' => $this->getParam('resource_id'), + 'ids' => $ids + ) + ) + ); + + return $this->forwardTo('Confirm', 'Confirm', $data); + } + + /** + * Confirm Tag Delete by Filter + * + * @param object $tagModel A Tag object + * @param string $originUrl An origin url + * @param string $newUrl The url of the desired action + * + * @return $this->confirmAction + */ + protected function confirmTagsDeleteByFilter($tagModel, $originUrl, $newUrl) + { + $messages = array(); + $count = $tagModel->getResourceTags( + $this->convertFilter($this->getParam('user_id')), + $this->convertFilter($this->getParam('resource_id')), + $this->convertFilter($this->getParam('tag_id')) + )->getTotalItemCount(); + + $user = $this->getTable('user') + ->select(array('id' => $this->getParam('user_id'))) + ->current(); + $userMsg = (false !== $user) + ? $user->username . " (" . $user->id . ")" : "All"; + + $tag = $this->getTable('tags') + ->select(array('id' => $this->getParam('tag_id'))) + ->current(); + + $tagMsg = (false !== $tag) + ? $tag->tag. " (" . $tag->id . ")" : " All"; + + $resource = $this->getTable('resource') + ->select(array('id' => $this->getParam('resource_id'))) + ->current(); + + $resourceMsg = (false !== $resource) + ? $resource->title. " (" . $resource->id . ")" : " All"; + + $messages[] = array( + 'msg' => 'tag_delete_warning', + 'tokens' => array('%count%' => $count) + ); + + if (false !== $user || false!== $tag || false !== $resource) { + $messages[] = array( + 'msg' => 'tag_delete_filter', + 'tokens' => array( + '%username%' => $userMsg, + '%tag%' => $tagMsg, + '%resource%' => $resourceMsg + ) + ); + } + + $data = array( + 'data' => array( + 'confirm' => $newUrl, + 'cancel' => $originUrl, + 'title' => "confirm_delete_tags_brief", + 'messages' => $messages, + 'origin' => 'manage', + 'extras' => array( + 'type' => $this->getParam('type'), + 'user_id' => $this->getParam('user_id'), + 'tag_id' => $this->getParam('tag_id'), + 'resource_id' => $this->getParam('resource_id'), + 'deleteFilter' => $this->getParam('deleteFilter') + ) + ) + ); + + return $this->forwardTo('Confirm', 'Confirm', $data); + } + + /** + * Gets a list of unique resources based on the url params + * + * @return \Zend\Db\ResultSet + */ + protected function getUniqueResources() + { + return $this->getTable('ResourceTags')->getUniqueResources( + $this->convertFilter($this->getParam('user_id')), + $this->convertFilter($this->getParam('resource_id')), + $this->convertFilter($this->getParam('tag_id')) + ); + } + + /** + * Gets a list of unique tags based on the url params + * + * @return \Zend\Db\ResultSet + */ + protected function getUniqueTags() + { + return $this->getTable('ResourceTags')->getUniqueTags( + $this->convertFilter($this->getParam('user_id')), + $this->convertFilter($this->getParam('resource_id')), + $this->convertFilter($this->getParam('tag_id')) + ); + } + + /** + * Gets a list of unique users based on the url params + * + * @return \Zend\Db\ResultSet + */ + protected function getUniqueUsers() + { + return $this->getTable('ResourceTags')->getUniqueUsers( + $this->convertFilter($this->getParam('user_id')), + $this->convertFilter($this->getParam('resource_id')), + $this->convertFilter($this->getParam('tag_id')) + ); + } + + /** + * Converts empty params and "ALL" to null + * + * @param string $value A parameter to check + * + * @return string|null A modified parameter + */ + protected function convertFilter($value) + { + return ("ALL" !== $value && "" !== $value && null !== $value) + ? $value : null; + } + + /** + * Get and set a list of resource tags + * + * @return \Zend\Paginator\Paginator + */ + protected function getResourceTags() + { + $currentPage = isset($this->params['page']) ? $this->params['page'] : "1"; + $resourceTags = $this->getTable('ResourceTags'); + $tags = $resourceTags->getResourceTags( + $this->convertFilter($this->getParam('user_id')), + $this->convertFilter($this->getParam('resource_id')), + $this->convertFilter($this->getParam('tag_id')), + $this->getParam('order'), + $currentPage + ); + return $tags; + } + + /** + * Delete tags based on filter settings. + * + * @return int Number of IDs deleted + */ + protected function deleteResourceTagsByFilter() + { + $tags = $this->getResourceTags(); + $ids = array(); + foreach ($tags as $tag) { + $ids[] = $tag->id; + } + return $this->getTable('ResourceTags')->deleteByIdArray($ids); + } +} diff --git a/themes/blueprint/css/styles.css b/themes/blueprint/css/styles.css index 8b44022e7046432d47bac8baf2f1fdd3f5fedf5a..fc0402a36ab20cc6a05cf7e5588e6e5faeaf5d66 100644 --- a/themes/blueprint/css/styles.css +++ b/themes/blueprint/css/styles.css @@ -2269,4 +2269,9 @@ div.handle { #authcontainer { float:left; width:100%; +} + +/* Admin styling */ +.tagForm select { + width:200px; } \ No newline at end of file diff --git a/themes/blueprint/templates/admin/menu.phtml b/themes/blueprint/templates/admin/menu.phtml index 14b5a7e95549e6cca3804143bceacce49fee8ca2..9a023bad3b30cb83b1dc5b74dd062867902ee033 100644 --- a/themes/blueprint/templates/admin/menu.phtml +++ b/themes/blueprint/templates/admin/menu.phtml @@ -4,4 +4,5 @@ <li<?=strtolower($this->layout()->templateName) == "statistics" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/statistics')?>"><?=$this->transEsc('Statistics')?></a></li> <li<?=strtolower($this->layout()->templateName) == "config" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/config')?>"><?=$this->transEsc('Configuration')?></a> <li<?=strtolower($this->layout()->templateName) == "maintenance" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/maintenance')?>"><?=$this->transEsc('System Maintenance')?></a></li> + <li<?=strtolower($this->layout()->templateName) == "tags" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/tags')?>"><?=$this->transEsc('Tag Maintenance')?></a></li> </ul> diff --git a/themes/blueprint/templates/admin/tags/checkbox.phtml b/themes/blueprint/templates/admin/tags/checkbox.phtml new file mode 100644 index 0000000000000000000000000000000000000000..35067fbf4329bc346624e06c73074e6cd50a6c26 --- /dev/null +++ b/themes/blueprint/templates/admin/tags/checkbox.phtml @@ -0,0 +1,3 @@ +<label for="<?=$this->prefix?>checkbox_<?=$this->tag['id']?>" class="offscreen"><?=$this->transEsc('Select this tag')?></label> +<input id="<?=$this->prefix?>checkbox_<?=$this->tag['id']?>" type="checkbox" name="ids[]" value="<?=$this->escapeHtml($this->tag['id'])?>" class="checkbox_ui"/> +<input type="hidden" name="idsAll[]" value="<?=$this->escapeHtml($this->tag['id'])?>" /> diff --git a/themes/blueprint/templates/admin/tags/home.phtml b/themes/blueprint/templates/admin/tags/home.phtml new file mode 100644 index 0000000000000000000000000000000000000000..bdac36a176289114270f34ca0a1e07976fb36d77 --- /dev/null +++ b/themes/blueprint/templates/admin/tags/home.phtml @@ -0,0 +1,22 @@ +<? + // Set page title. + $this->headTitle($this->translate('VuFind Administration - Tag Management')); +?> +<div class="span-5"> + <?=$this->render("admin/menu.phtml")?> +</div> + +<div class="span-18 last"> + <h1><?=$this->translate('Tag Management')?></h1> + + <?=$this->render("admin/tags/menu.phtml")?> + + <h2><?=$this->translate('Statistics')?></h2> +<table> + <tr><th><?=$this->transEsc('total_users')?></th><th><?=$this->transEsc('total_resources')?></th><th><?=$this->transEsc('total_tags')?></th><th><?=$this->transEsc('unique_tags')?></th><th><?=$this->transEsc('anonymous_tags')?></th></tr> + <tr><td><?=$statistics['users']?></td><td><?=$statistics['resources']?></td><td><?=$statistics['total']?></td><td><?=$statistics['unique']?></td><td><?=$statistics['anonymous']?></td></tr> + </table> + +</div> + +<div class="clear"></div> diff --git a/themes/blueprint/templates/admin/tags/list.phtml b/themes/blueprint/templates/admin/tags/list.phtml new file mode 100644 index 0000000000000000000000000000000000000000..39dd3b8b1e8b08d72e31388ccfb181b98edb68af --- /dev/null +++ b/themes/blueprint/templates/admin/tags/list.phtml @@ -0,0 +1,112 @@ +<?php + // Set page title. + $this->headTitle($this->translate('VuFind Administration - Tag Management')); +?> +<div class="span-5"> + <?=$this->render("admin/menu.phtml")?> +</div> + +<div class="span-18 last"> + <h1><?=$this->translate('Tag Management')?></h1> + <h2><?=$this->translate('List Tags')?></h2> + + <?=$this->render("admin/tags/menu.phtml")?> + + <?=$this->flashmessages()?> + + <div class="tagForm"> + <form action="<?= $this->url('admin/tags', array('action' => 'List'))?>" method="get"> + + <fieldset> + <legend><?=$this->translate('filter_tags')?></legend> + + <table> + <tr> + <th><label for="user_id"><?=$this->translate('Username')?></label></th> + <th><label for="tag_id"><?=$this->translate('Tag')?></label></th> + <th><label for="resource_id"><?=$this->translate('Title')?></label></th> + </tr> + <tr> + <td> + <select name="user_id" id="user_id"> + <option value="ALL"><?=$this->translate('All')?></option> + <? foreach($this->uniqueUsers as $user):?> + <option value="<?= $user['user_id'] ?>"<? if(isset($this->params['user_id']) && $user['user_id'] == $this->params['user_id']): ?> selected="selected"<? endif;?>> + <?=$user['username'] ?> + </option> + <? endforeach;?> + </select> + </td> + <td> + <select name="tag_id" id="tag_id"> + <option value="ALL"><?=$this->translate('All')?></option> + <? foreach($this->uniqueTags as $tag):?> + <option value="<?= $tag['tag_id'] ?>"<? if(isset($this->params['tag_id']) && $tag['tag_id'] == $this->params['tag_id']): ?> selected="selected"<? endif;?>> + <?=$tag['tag'] ?> + </option> + <? endforeach;?> + </select> + </td> + <td> + <select name="resource_id" id="resource_id"> + <option value="ALL"><?=$this->translate('All')?></option> + <? foreach($this->uniqueResources as $resource):?> + <option value="<?= $resource['resource_id']; ?>" title="<?=$resource['title'] ?>"<? if(isset($this->params['resource_id']) && $resource['resource_id'] == $this->params['resource_id']): ?> selected="selected"<? endif;?>> + <?=$this->truncate($resource['title'], 80) ?> (<?=$resource['resource_id'] ?>) + </option> + <? endforeach;?> + </select> + </td> + </tr> + </table> + + <input type="submit" value="<?=$this->transEsc('Filter')?>"> + <? if((isset($this->params['user_id']) && !is_null($this->params['user_id'])) || (isset($this->params['tag_id']) && !is_null($this->params['tag_id'])) || (isset($this->params['resource_id']) && !is_null($this->params['resource_id']))):?> + <a href="<?= $this->url('admin/tags', array('action' => 'List')); ?>"><?=$this->translate('clear_tag_filter')?></a> + <? endif;?> + + </fieldset> + + </form> + </div> + + <? if(count($this->results) > 0):?> + <div class="tagsList"> + <form action="<?= $this->url('admin/tags', array('action' => 'Delete'))?>" method="post"> + <input type="hidden" name="user_id" value="<?=isset($this->params['user_id']) ? $this->params['user_id'] : '' ?>" /> + <input type="hidden" name="tag_id" value="<?=isset($this->params['tag_id']) ? $this->params['tag_id'] : '' ?>" /> + <input type="hidden" name="resource_id" value="<?=isset($this->params['resource_id']) ? $this->params['resource_id'] : '' ?>" /> + <input type="hidden" name="origin" value="list" /> + + <table class="citation"> + + <tr> + <th> </th> + <th><?=$this->translate('Username')?></th> + <th><?=$this->translate('Tag')?></th> + <th><?=$this->translate('Title')?></th> + </tr> + + <? foreach ($this->results as $tag): ?> + <tr> + <td><?=$this->render('admin/tags/checkbox', array('tag'=>$tag)) ; ?></td> + <td><?=$tag->username ?> (<?= $tag->user_id?>)</td> + <td><?=$tag->tag?> (<?= $tag->tag_id?>)</td> + <td><?=$tag->title?> (<?= $tag->resource_id?>)</td> + </tr> + <? endforeach;?> + </table> + + <input type="submit" name="deleteSelected" value="<?=$this->transEsc('delete_selected')?>"> + <input type="submit" name="deletePage" value="<?=$this->transEsc('delete_page')?>"> + <input type="submit" name="deleteFilter" value="<?=$this->transEsc('delete_all')?>"> + + </form> + </div> + <?=$this->paginationControl($this->results, 'Sliding', 'admin/tags/pagination.phtml', array('params' => $this->params))?> + <? else:?> + <p><?=$this->translate('tag_filter_empty')?></p> + <? endif;?> +</div> + +<div class="clear"></div> diff --git a/themes/blueprint/templates/admin/tags/manage.phtml b/themes/blueprint/templates/admin/tags/manage.phtml new file mode 100644 index 0000000000000000000000000000000000000000..70c26bc2bf7c69c24cd88566503c19195d8e9275 --- /dev/null +++ b/themes/blueprint/templates/admin/tags/manage.phtml @@ -0,0 +1,89 @@ +<? + // Set page title. + $this->headTitle($this->translate('VuFind Administration - Tag Maintenance')); +?> +<div class="span-5"> + <?=$this->render("admin/menu.phtml")?> +</div> + +<div class="span-18 last"> + <h1><?=$this->translate('Tag Management')?></h1> + <h2><?=$this->translate('Manage Tags')?></h2> + + <?=$this->render("admin/tags/menu.phtml")?> + + <?=$this->flashmessages()?> + + <form action="<?= $this->url('admin/tags', array('action' => 'Manage'));?>" method="post"> + + <label for="type"><?=$this->translate('delete_tags_by')?>:</label> + + <select id="type" name="type"> + <option value="user" <? if("user" == $this->type) echo " selected=selected";?>><?=$this->translate('Username')?></option> + <option value="tag" <? if("tag" == $this->type) echo " selected=selected";?>><?=$this->translate('Tag')?></option> + <option value="resource" <? if("resource" == $this->type) echo " selected=selected";?>><?=$this->translate('Title')?></option> + </select> + + <input type="submit" value="<?=$this->translate('Submit')?>" /> + + </form> + + <? if(false !== $this->type):?> + + <form action="<?= $this->url('admin/tags', array('action' => 'Delete'))?>" method="post"> + <input type="hidden" name="origin" value="manage" /> + <input type="hidden" name="type" value="<?= $this->type; ?>" /> + + <? if("user" == $type):?> + + <label for="user_id"><?=$this->translate('Username')?></label> + + <select name="user_id" id="user_id"> + <? foreach($this->uniqueUsers as $user):?> + <option value="<?= $user['user_id'] ?>"> + <?= $user['username'] ?> + </option> + <? endforeach;?> + </select> + + <input type="submit" name="deleteFilter" value="<?=$this->translate('delete_tags')?>" /> + + <? elseif("tag" == $type):?> + + <label for="tag_id"><?=$this->translate('Tag')?></label> + + <select name="tag_id" id="tag_id"> + <? foreach($this->uniqueTags as $tag):?> + <option value="<?= $tag['tag_id'] ?>"> + <?= $tag['tag'] ?> + </option> + <? endforeach;?> + </select> + + <input type="submit" name="deleteFilter" value="<?=$this->translate('delete_tags')?>" /> + + <? elseif("resource" == $type):?> + + <label for="resource_id"><?=$this->translate('Title')?></label> + + <select name="resource_id" id="resource_id"> + <? foreach($this->uniqueResources as $resource):?> + <option value="<?=$resource['resource_id'] ?>" title="<?=$resource['title'] ?>"> + <?=$this->truncate($resource['title'], 80) ?> (<?= $resource['resource_id'] ?>) + </option> + <? endforeach;?> + </select> + + <input type="submit" name="deleteFilter" value="<?=$this->translate('delete_tags')?>" /> + + <? endif;?> + + </form> + + <? endif;?> + + </form> + +</div> + +<div class="clear"></div> diff --git a/themes/blueprint/templates/admin/tags/menu.phtml b/themes/blueprint/templates/admin/tags/menu.phtml new file mode 100644 index 0000000000000000000000000000000000000000..e837b008b63672c5440a761d04df84b2dd850440 --- /dev/null +++ b/themes/blueprint/templates/admin/tags/menu.phtml @@ -0,0 +1,6 @@ +<div class="toolbar"> + <ul> + <li<?=strtolower($this->layout()->templateName) == "tagslist" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/tags', array('action' => 'List'))?>"><?=$this->transEsc('List Tags')?></a></li> + <li<?=strtolower($this->layout()->templateName) == "tagsmanage" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/tags', array('action' => 'Manage'))?>"><?=$this->transEsc('Manage Tags')?></a></li> + </ul> +</div> diff --git a/themes/blueprint/templates/admin/tags/pagination.phtml b/themes/blueprint/templates/admin/tags/pagination.phtml new file mode 100644 index 0000000000000000000000000000000000000000..02a3fab78ba590353967cb1771ae3d41a9e79f1a --- /dev/null +++ b/themes/blueprint/templates/admin/tags/pagination.phtml @@ -0,0 +1,61 @@ +<!-- +See http://developer.yahoo.com/ypatterns/pattern.php?pattern=searchpagination +--> +<?php if ($this->pageCount): ?> +<div class="paginationControl"> + +<!-- Previous page link --> +<?php if (isset($this->previous)): ?> + <? $newParams = $this->params; $newParams['page'] = $this->previous; ?> + <a href="<?= $this->currentPath() . '?' . http_build_query($newParams); ?>"> + < <?=$this->translate('Previous')?> + </a> | +<?php else: ?> + <span class="disabled">< <?=$this->translate('Previous')?></span> | +<?php endif; ?> + +<!-- First page link --> +<?php if (isset($this->first) && $this->first != $this->current): ?> + <? $newParams = $this->params; $newParams['page'] = $this->first; ?> + <a href="<?= $this->currentPath() . '?' . http_build_query($newParams); ?>"> + <?=$this->translate('First')?> + </a>| +<?php else: ?> + <span class="disabled"><?=$this->translate('First')?> </span>| +<?php endif; ?> + +<!-- Numbered page links --> +<?php foreach ($this->pagesInRange as $page): ?> + <?php if ($page != $this->current): ?> + <? $newParams = $this->params; $newParams['page'] = $page; ?> + <a href="<?= $this->currentPath() . '?' . http_build_query($newParams); ?>"> + <?php echo $page; ?> + </a> | + <?php else: ?> + <?php echo $page; ?> | + <?php endif; ?> +<?php endforeach; ?> + +<!-- Last page link --> +<?php if (isset($this->last) && $this->last != $this->current): ?> + <? $newParams = $this->params; $newParams['page'] = $this->last; ?> + <a href="<?= $this->currentPath() . '?' . http_build_query($newParams); ?>"> + <?=$this->translate('Last')?> + </a> + | +<?php else: ?> + <span class="disabled"><?=$this->translate('Last')?> </span>| +<?php endif; ?> + +<!-- Next page link --> +<?php if (isset($this->next)): ?> + <? $newParams = $this->params; $newParams['page'] = $this->next; ?> + <a href="<?= $this->currentPath() . '?' . http_build_query($newParams); ?>"> + <?=$this->translate('Next')?> > + </a> +<?php else: ?> + <span class="disabled"><?=$this->translate('Next')?> ></span> +<?php endif; ?> + +</div> +<?php endif; ?> diff --git a/themes/bootstrap/templates/admin/menu.phtml b/themes/bootstrap/templates/admin/menu.phtml index f9a2ebcda2fbe6f16a2d172936e143b5910d0ab8..8e225d26b5ded756639031f26314e8caea29144e 100644 --- a/themes/bootstrap/templates/admin/menu.phtml +++ b/themes/bootstrap/templates/admin/menu.phtml @@ -4,4 +4,5 @@ <li<?=strtolower($this->layout()->templateName) == "statistics" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/statistics')?>"><?=$this->transEsc('Statistics')?></a></li> <li<?=strtolower($this->layout()->templateName) == "config" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/config')?>"><?=$this->transEsc('Configuration')?></a> <li<?=strtolower($this->layout()->templateName) == "maintenance" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/maintenance')?>"><?=$this->transEsc('System Maintenance')?></a></li> + <li<?=strtolower($this->layout()->templateName) == "tags" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/tags')?>"><?=$this->transEsc('Tag Maintenance')?></a></li> </ul> diff --git a/themes/bootstrap/templates/admin/tags/checkbox.phtml b/themes/bootstrap/templates/admin/tags/checkbox.phtml new file mode 100644 index 0000000000000000000000000000000000000000..bde8b4f84c119a44a72fd279095ff373b5aa9b64 --- /dev/null +++ b/themes/bootstrap/templates/admin/tags/checkbox.phtml @@ -0,0 +1,4 @@ +<label for="<?=$this->prefix?>checkbox_<?=$this->tag['id']?>" class="checkbox"> + <input id="<?=$this->prefix?>checkbox_<?=$this->tag['id']?>" type="checkbox" name="ids[]" value="<?=$this->escapeHtml($this->tag['id'])?>" class="checkbox_ui"/> + <input type="hidden" name="idsAll[]" value="<?=$this->escapeHtml($this->tag['id'])?>" /> +</label> \ No newline at end of file diff --git a/themes/bootstrap/templates/admin/tags/home.phtml b/themes/bootstrap/templates/admin/tags/home.phtml new file mode 100644 index 0000000000000000000000000000000000000000..4afe094691b13b56c342e1ed5820f37f8c647b47 --- /dev/null +++ b/themes/bootstrap/templates/admin/tags/home.phtml @@ -0,0 +1,20 @@ +<? + // Set page title. + $this->headTitle($this->translate('VuFind Administration - Tag Management')); +?> +<div class="<?=$this->layoutClass('mainbody')?>"> + <h2><?=$this->translate('Tag Management')?></h2> + + <?=$this->render("admin/tags/menu.phtml")?> + + <h3><?=$this->translate('Statistics')?></h3> + <table class="table table-striped"> + <tr><th><?=$this->transEsc('total_users')?></th><th><?=$this->transEsc('total_resources')?></th><th><?=$this->transEsc('total_tags')?></th><th><?=$this->transEsc('unique_tags')?></th><th><?=$this->transEsc('anonymous_tags')?></th></tr> + <tr><td><?=$statistics['users']?></td><td><?=$statistics['resources']?></td><td><?=$statistics['total']?></td><td><?=$statistics['unique']?></td><td><?=$statistics['anonymous']?></td></tr> + </table> + +</div> + +<div class="<?=$this->layoutClass('sidebar')?>"> + <?=$this->render("admin/menu.phtml")?> +</div> \ No newline at end of file diff --git a/themes/bootstrap/templates/admin/tags/list.phtml b/themes/bootstrap/templates/admin/tags/list.phtml new file mode 100644 index 0000000000000000000000000000000000000000..6cae43183399a24e2a231800d61541a9196116b5 --- /dev/null +++ b/themes/bootstrap/templates/admin/tags/list.phtml @@ -0,0 +1,109 @@ +<?php + // Set page title. + $this->headTitle($this->translate('VuFind Administration - Tag Management')); +?> +<div class="<?=$this->layoutClass('mainbody')?>"> + <h2><?=$this->translate('Tag Management')?></h2> + <h3><?=$this->translate('List Tags')?></h3> + + <?=$this->render("admin/tags/menu.phtml")?> + + <?=$this->flashmessages()?> + + <div class="tagForm"> + <form action="<?= $this->url('admin/tags', array('action' => 'List'))?>" method="get"> + + <fieldset> + <legend><?=$this->translate('filter_tags')?></legend> + + <table> + <tr> + <th><label for="user_id"><?=$this->translate('Username')?></label></th> + <th><label for="tag_id"><?=$this->translate('Tag')?></label></th> + <th><label for="resource_id"><?=$this->translate('Title')?></label></th> + </tr> + <tr> + <td> + <select name="user_id" id="user_id"> + <option value="ALL"><?=$this->translate('All')?></option> + <? foreach($this->uniqueUsers as $user):?> + <option value="<?= $user['user_id'] ?>"<? if(isset($this->params['user_id']) && $user['user_id'] == $this->params['user_id']): ?> selected="selected"<? endif;?>> + <?=$user['username'] ?> + </option> + <? endforeach;?> + </select> + </td> + <td> + <select name="tag_id" id="tag_id"> + <option value="ALL"><?=$this->translate('All')?></option> + <? foreach($this->uniqueTags as $tag):?> + <option value="<?= $tag['tag_id'] ?>"<? if(isset($this->params['tag_id']) && $tag['tag_id'] == $this->params['tag_id']): ?> selected="selected"<? endif;?>> + <?=$tag['tag'] ?> + </option> + <? endforeach;?> + </select> + </td> + <td> + <select name="resource_id" id="resource_id"> + <option value="ALL"><?=$this->translate('All')?></option> + <? foreach($this->uniqueResources as $resource):?> + <option value="<?= $resource['resource_id']; ?>" title="<?=$resource['title'] ?>"<? if(isset($this->params['resource_id']) && $resource['resource_id'] == $this->params['resource_id']): ?> selected="selected"<? endif;?>> + <?=$this->truncate($resource['title'], 80) ?> (<?=$resource['resource_id'] ?>) + </option> + <? endforeach;?> + </select> + </td> + </tr> + </table> + + <input type="submit" value="<?=$this->transEsc('Filter')?>"> + <? if((isset($this->params['user_id']) && !is_null($this->params['user_id'])) || (isset($this->params['tag_id']) && !is_null($this->params['tag_id'])) || (isset($this->params['resource_id']) && !is_null($this->params['resource_id']))):?> + <a href="<?= $this->url('admin/tags', array('action' => 'List')); ?>"><?=$this->translate('clear_tag_filter')?></a> + <? endif;?> + + </fieldset> + + </form> + </div> + + <? if(count($this->results) > 0):?> + <div class="tagsList"> + <form action="<?= $this->url('admin/tags', array('action' => 'Delete'))?>" method="post"> + <input type="hidden" name="user_id" value="<?=isset($this->params['user_id']) ? $this->params['user_id'] : '' ?>" /> + <input type="hidden" name="tag_id" value="<?=isset($this->params['tag_id']) ? $this->params['tag_id'] : '' ?>" /> + <input type="hidden" name="resource_id" value="<?=isset($this->params['resource_id']) ? $this->params['resource_id'] : '' ?>" /> + <input type="hidden" name="origin" value="list" /> + + <table class="table table-striped"> + <tr> + <th> </th> + <th><?=$this->translate('Username')?></th> + <th><?=$this->translate('Tag')?></th> + <th><?=$this->translate('Title')?></th> + </tr> + + <? foreach ($this->results as $tag): ?> + <tr> + <td><?=$this->render('admin/tags/checkbox', array('tag'=>$tag)) ; ?></td> + <td><?=$tag->username ?> (<?= $tag->user_id?>)</td> + <td><?=$tag->tag?> (<?= $tag->tag_id?>)</td> + <td><?=$tag->title?> (<?= $tag->resource_id?>)</td> + </tr> + <? endforeach;?> + </table> + + <input type="submit" name="deleteSelected" value="<?=$this->transEsc('delete_selected')?>"> + <input type="submit" name="deletePage" value="<?=$this->transEsc('delete_page')?>"> + <input type="submit" name="deleteFilter" value="<?=$this->transEsc('delete_all')?>"> + + </form> + </div> + <?=$this->paginationControl($this->results, 'Sliding', 'admin/tags/pagination.phtml', array('params' => $this->params))?> + <? else:?> + <p><?=$this->translate('tag_filter_empty')?></p> + <? endif;?> +</div> + +<div class="<?=$this->layoutClass('sidebar')?>"> + <?=$this->render("admin/menu.phtml")?> +</div> \ No newline at end of file diff --git a/themes/bootstrap/templates/admin/tags/manage.phtml b/themes/bootstrap/templates/admin/tags/manage.phtml new file mode 100644 index 0000000000000000000000000000000000000000..27f6a0471411398777d4595433963315b6985cdf --- /dev/null +++ b/themes/bootstrap/templates/admin/tags/manage.phtml @@ -0,0 +1,88 @@ +<? + // Set page title. + $this->headTitle($this->translate('VuFind Administration - Tag Maintenance')); +?> +<div class="<?=$this->layoutClass('mainbody')?>"> + <h2><?=$this->translate('Tag Management')?></h2> + <h3><?=$this->translate('Manage Tags')?></h3> + + <?=$this->render("admin/tags/menu.phtml")?> + + <?=$this->flashmessages()?> + + <form class="form-horizontal" action="<?= $this->url('admin/tags', array('action' => 'Manage'));?>" method="post"> + + <label for="type"><?=$this->translate('delete_tags_by')?>:</label> + + <select id="type" name="type"> + <option value="user" <? if("user" == $this->type) echo " selected=selected";?>><?=$this->translate('Username')?></option> + <option value="tag" <? if("tag" == $this->type) echo " selected=selected";?>><?=$this->translate('Tag')?></option> + <option value="resource" <? if("resource" == $this->type) echo " selected=selected";?>><?=$this->translate('Title')?></option> + </select> + + <input type="submit" value="<?=$this->translate('Submit')?>" /> + + </form> + + <? if(false !== $this->type):?> + + <form action="<?= $this->url('admin/tags', array('action' => 'Delete'))?>" method="post"> + + <input type="hidden" name="origin" value="manage" /> + <input type="hidden" name="type" value="<?= $this->type; ?>" /> + + <? if("user" == $type):?> + + <label for="user_id"><?=$this->translate('Username')?></label> + + <select name="user_id" id="user_id"> + <? foreach($this->uniqueUsers as $user):?> + <option value="<?= $user['user_id'] ?>"> + <?= $user['username'] ?> + </option> + <? endforeach;?> + </select> + + <input type="submit" name="deleteFilter" value="<?=$this->translate('delete_tags')?>" /> + + <? elseif("tag" == $type):?> + + <label for="tag_id"><?=$this->translate('Tag')?></label> + + <select name="tag_id" id="tag_id"> + <? foreach($this->uniqueTags as $tag):?> + <option value="<?= $tag['tag_id'] ?>"> + <?= $tag['tag'] ?> + </option> + <? endforeach;?> + </select> + + <input type="submit" name="deleteFilter" value="<?=$this->translate('delete_tags')?>" /> + + <? elseif("resource" == $type):?> + + <label for="resource_id"><?=$this->translate('Title')?></label> + + <select name="resource_id" id="resource_id"> + <? foreach($this->uniqueResources as $resource):?> + <option value="<?=$resource['resource_id'] ?>" title="<?=$resource['title'] ?>"> + <?=$this->truncate($resource['title'], 80) ?> (<?= $resource['resource_id'] ?>) + </option> + <? endforeach;?> + </select> + + <input type="submit" name="deleteFilter" value="<?=$this->translate('delete_tags')?>" /> + + <? endif;?> + + </form> + + <? endif;?> + + </form> + +</div> + +<div class="<?=$this->layoutClass('sidebar')?>"> + <?=$this->render("admin/menu.phtml")?> +</div> \ No newline at end of file diff --git a/themes/bootstrap/templates/admin/tags/menu.phtml b/themes/bootstrap/templates/admin/tags/menu.phtml new file mode 100644 index 0000000000000000000000000000000000000000..bc7506521a182f4db31d498812ba73ccd341e702 --- /dev/null +++ b/themes/bootstrap/templates/admin/tags/menu.phtml @@ -0,0 +1,6 @@ +<div class="toolbar"> +<ul class="nav nav-pills"> + <li<?=strtolower($this->layout()->templateName) == "tagslist" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/tags', array('action' => 'List'))?>"><?=$this->transEsc('List Tags')?></a></li> + <li<?=strtolower($this->layout()->templateName) == "tagsmanage" ? ' class="active"' : ''?>><a href="<?=$this->url('admin/tags', array('action' => 'Manage'))?>"><?=$this->transEsc('Manage Tags')?></a></li> +</ul> +</div> diff --git a/themes/bootstrap/templates/admin/tags/pagination.phtml b/themes/bootstrap/templates/admin/tags/pagination.phtml new file mode 100644 index 0000000000000000000000000000000000000000..a4bea21cd5e8e71202bff5d7b6c9d234b4331206 --- /dev/null +++ b/themes/bootstrap/templates/admin/tags/pagination.phtml @@ -0,0 +1,62 @@ +<? if ($this->pageCount): ?> + <div class="pagination"> + <ul> + <!-- Previous page link --> + <li<? if (isset($this->previous)): ?>> + <? $newParams = $this->params; $newParams['page'] = $this->previous; ?> + <a href="<?= $this->currentPath() . '?' . http_build_query($newParams); ?>"> + < <?=$this->translate('Previous')?> + </a> + <? else: ?> + class="disabled"> <span><?=$this->translate('Previous')?></span> + <? endif; ?> + </li> + + <!-- First page link --> + <li<? if (isset($this->first) && $this->first != $this->current): ?>> + <? $newParams = $this->params; $newParams['page'] = $this->first; ?> + <a href="<?= $this->currentPath() . '?' . http_build_query($newParams); ?>"> + <?=$this->translate('First')?> + </a> + <? else: ?> + class="disabled"> <span><?=$this->translate('First')?></span> + <? endif; ?> + </li> + + <!-- Numbered page links --> + <? foreach ($this->pagesInRange as $page): ?> + <li<? if ($page != $this->current): ?>> + <? $newParams = $this->params; $newParams['page'] = $page; ?> + <a href="<?= $this->currentPath() . '?' . http_build_query($newParams); ?>"> + <? echo $page; ?> + </a> + <? else: ?> + class="active"> <span><? echo $page; ?></span> + <? endif; ?> + </li> + <? endforeach; ?> + + <!-- Last page link --> + <li<? if (isset($this->last) && $this->last != $this->current): ?>> + <? $newParams = $this->params; $newParams['page'] = $this->last; ?> + <a href="<?= $this->currentPath() . '?' . http_build_query($newParams); ?>"> + <?=$this->translate('Last')?> + </a> + <? else: ?> + class="disabled"> <span><?=$this->translate('Last')?></span> + <? endif; ?> + </li> + + <!-- Next page link --> + <li<? if (isset($this->next)): ?>> + <? $newParams = $this->params; $newParams['page'] = $this->next; ?> + <a href="<?= $this->currentPath() . '?' . http_build_query($newParams); ?>"> + <?=$this->translate('Next')?> > + </a> + <? else: ?> + class="disabled"> <span><?=$this->translate('Next')?> ></span> + <? endif; ?> + </li> + </ul> + </div> +<? endif; ?>