Issue #18 Add search engine on admin polls list

This commit is contained in:
Olivier PEREZ 2015-03-27 12:55:32 +01:00
parent 15ecff4488
commit 40d707c96d
11 changed files with 164 additions and 36 deletions

View File

@ -22,13 +22,24 @@ use Framadate\Services\LogService;
use Framadate\Services\PollService;
use Framadate\Services\SecurityService;
use Framadate\Services\SuperAdminService;
use Framadate\Utils;
include_once __DIR__ . '/../app/inc/init.php';
include_once __DIR__ . '/../bandeaux.php';
const POLLS_PER_PAGE = 30;
/* Functions */
function buildSearchQuery($search) {
$query = '';
foreach ($search as $key => $value) {
$query .= $key . '=' . urlencode($value) . '&';
}
return substr($query, 0, -1);
}
/* --------- */
/* Variables */
/* --------- */
@ -49,6 +60,11 @@ $securityService = new SecurityService();
$page = (int)filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
$page = ($page >= 1) ? $page : 1;
// Search
$search['poll'] = filter_input(INPUT_GET, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
$search['title'] = filter_input(INPUT_GET, 'title', FILTER_SANITIZE_STRING);
$search['name'] = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_STRING);
/* PAGE */
/* ---- */
@ -63,17 +79,21 @@ if (!empty($_POST['delete_confirm']) && $securityService->checkCsrf('admin', $_P
$adminPollService->deleteEntirePoll($poll_id);
}
$found = $superAdminService->findAllPolls($page-1, POLLS_PER_PAGE);
$found = $superAdminService->findAllPolls($search, $page - 1, POLLS_PER_PAGE);
$polls = $found['polls'];
$count = $found['count'];
$total = $found['total'];
// Assign data to template
$smarty->assign('polls', $polls);
$smarty->assign('count', $count);
$smarty->assign('total', $total);
$smarty->assign('page', $page);
$smarty->assign('pages', ceil($count / POLLS_PER_PAGE));
$smarty->assign('poll_to_delete', $poll_to_delete);
$smarty->assign('crsf', $securityService->getToken('admin'));
$smarty->assign('search', $search);
$smarty->assign('search_query', buildSearchQuery($search));
$smarty->assign('title', __('Admin\\Polls'));

View File

@ -277,20 +277,29 @@ class FramaDB {
}
/**
* @param array $search Array of search : ['id'=>..., 'title'=>..., 'name'=>...]
* @param $start int The index of the first poll to return
* @param $limit int The limit size
* @return array
*/
public function findAllPolls($start, $limit) {
public function findAllPolls($search, $start, $limit) {
// Polls
$prepared = $this->prepare('
SELECT p.*,
(SELECT count(1) FROM `' . Utils::table('vote') . '` v WHERE p.id=v.poll_id) votes
FROM ' . Utils::table('poll') . ' p
FROM `' . Utils::table('poll') . '` p
WHERE (:id = "" OR p.id LIKE :id)
AND (:title = "" OR p.title LIKE :title)
AND (:name = "" OR p.admin_name LIKE :name)
ORDER BY p.title ASC
LIMIT :start, :limit');
$prepared->bindParam(':start', $start, PDO::PARAM_INT);
$prepared->bindParam(':limit', $limit, PDO::PARAM_INT);
');
$poll = $search['poll'] . '%';
$title = '%' . $search['title'] . '%';
$name = '%' . $search['name'] . '%';
$prepared->bindParam(':id', $poll, PDO::PARAM_STR);
$prepared->bindParam(':title', $title, PDO::PARAM_STR);
$prepared->bindParam(':name', $name, PDO::PARAM_STR);
$prepared->execute();
$polls = $prepared->fetchAll();
@ -299,7 +308,7 @@ SELECT p.*,
$count = $stmt->fetch();
$stmt->closeCursor();
return ['polls' => $polls, 'count' => $count->nb];
return ['polls' => array_slice($polls,$start, $limit), 'count' => $prepared->rowCount(), 'total' => $count->nb];
}
public function countVotesByPollId($poll_id) {

View File

@ -19,13 +19,13 @@ class SuperAdminService {
/**
* Return the list of all polls.
*
* @param $page int The page index (O = first page)
* @param $limit int The limit size
* @return array ['polls' => The {$limit} polls, 'count' => Total count]
* polls, 'count' => Total count]
* @param array $search Array of search : ['id'=>..., 'title'=>..., 'name'=>...]
* @param int $page The page index (O = first page)
* @param int $limit The limit size
* @return array ['polls' => The {$limit} polls, 'count' => Entries found by the query, 'total' => Total count]
*/
public function findAllPolls($page, $limit) {
return $this->connect->findAllPolls($page * $limit, $limit);
public function findAllPolls($search, $page, $limit) {
return $this->connect->findAllPolls($search, $page * $limit, $limit);
}
}

View File

@ -358,3 +358,8 @@ table.results .btn-link.btn-sm {
#md-a-imgModalLabel {
font-size: 24px;
}
/* Admin */
#poll_search {
cursor: pointer;
}

23
js/app/admin/polls.js Normal file
View File

@ -0,0 +1,23 @@
/**
* This software is governed by the CeCILL-B license. If a copy of this license
* is not distributed with this file, you can obtain one at
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
*
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
*
* =============================
*
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
*
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
*/
$(document).ready(function () {
$('#poll_search .panel-heading').on('click', function (e) {
$('#poll_search .panel-body').slideToggle('fast');
});
});

View File

@ -1,3 +1,21 @@
/**
* This software is governed by the CeCILL-B license. If a copy of this license
* is not distributed with this file, you can obtain one at
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
*
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
*
* =============================
*
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
*
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
*/
$(document).ready(function() {
$("#poll_form").submit(function( event ) {

View File

@ -34,7 +34,8 @@
"Page generated in": "Seite generiert in",
"seconds": "Sekunden",
"Choice": "Wahl",
"Link": "Link"
"Link": "Link",
"Search": "Suche"
},
"Date": {
"dd/mm/yyyy": "jj/mm/aaaa",
@ -243,7 +244,7 @@
"Author": "Autor",
"Email": "E-Mail-Adresse",
"Expiration date": "Verfallsdatum",
"Users": "Nutzer",
"Votes": "Stimmen",
"Actions": "Aktionen",
"See the poll": "Umfrage sehen",
"Change the poll": "Umfrage ändern",

View File

@ -34,7 +34,8 @@
"Page generated in": "Page generated in",
"seconds": "seconds",
"Choice": "Choice",
"Link": "Link"
"Link": "Link",
"Search": "Search"
},
"Date" : {
"dd/mm/yyyy": "jj/mm/aaaa",
@ -244,7 +245,7 @@
"Author": "Author",
"Email": "Courriel",
"Expiration date": "Date d'expiration",
"Users": "Users",
"Votes": "Votes",
"Actions": "Actions",
"See the poll": "See the poll",
"Change the poll": "Change the poll",

View File

@ -34,7 +34,8 @@
"Page generated in": "ES_Page générée en",
"seconds": "ES_secondes",
"Choice": "Opciòn",
"Link": "ES_Lien"
"Link": "ES_Lien",
"Search": "Búsqueda"
},
"Date": {
"dd/mm/yyyy": "ES_jj/mm/aaaa",
@ -243,7 +244,7 @@
"Author": "ES_Auteur",
"Email": "ES_Courriel",
"Expiration date": "ES_Date d'expiration",
"Users": "ES_Utilisateurs",
"Votes": "Votos",
"Actions": "Acciones",
"See the poll": "Ver la encuesta",
"Change the poll": "Cambiar la encuesta",

View File

@ -34,7 +34,8 @@
"Page generated in": "Page générée en",
"seconds": "secondes",
"Choice": "Choix",
"Link": "Lien"
"Link": "Lien",
"Search": "Chercher"
},
"Date": {
"dd/mm/yyyy": "jj/mm/aaaa",
@ -242,8 +243,8 @@
"Title": "Titre",
"Author": "Auteur",
"Email": "Courriel",
"Expiration date": "Date d'expiration",
"Users": "Utilisateurs",
"Expiration date": "Expiration",
"Votes": "Votes",
"Actions": "Actions",
"See the poll": "Voir le sondage",
"Change the poll": "Modifier le sondage",

View File

@ -1,8 +1,41 @@
{extends 'admin/admin_page.tpl'}
{block name="header"}
<script src="{"js/app/admin/polls.js"|resource}" type="text/javascript"></script>
{/block}
{block 'admin_main'}
<div class="panel panel-default" id="poll_search">
<div class="panel-heading">{__('Generic\\Search')}</div>
<div class="panel-body" style="display: none;">
<form action="" method="GET">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="poll" class="control-label">{__('Admin\\Poll ID')}</label>
<input type="text" name="poll" id="poll" class="form-control"
value="{$search['poll']|html}"/>
</div>
<div class="form-group">
<label for="name" class="control-label">{__('Admin\\Author')}</label>
<input type="text" name="name" id="name" class="form-control"
value="{$search['name']|html}"/>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="title" class="control-label">{__('Admin\\Title')}</label>
<input type="text" name="title" id="title" class="form-control"
value="{$search['title']|html}"/>
</div>
</div>
</div>
<input type="submit" value="{__('Generic\\Search')}" class="btn btn-default"/>
</form>
</div>
</div>
<form action="" method="POST">
<input type="hidden" name="csrf" value="{$crsf}"/>
{if $poll_to_delete}
<div class="alert alert-warning text-center">
<h3>{__('adminstuds\\Confirm removal of the poll')} "{$poll_to_delete->id|html}"</h3>
@ -15,13 +48,13 @@
</p>
</div>
{/if}
<input type="hidden" name="csrf" value="{$crsf}"/>
<div class="panel panel-default">
<div class="panel-heading">
{$polls|count} / {$count} {__('Admin\\polls in the database at this time')}
{$count} / {$total} {__('Admin\\polls in the database at this time')}
</div>
<table class="table table-bordered table-polls">
<tr align="center">
<th scope="col"></th>
@ -29,7 +62,7 @@
<th scope="col">{__('Admin\\Author')}</th>
<th scope="col">{__('Admin\\Email')}</th>
<th scope="col">{__('Admin\\Expiration date')}</th>
<th scope="col">{__('Admin\\Users')}</th>
<th scope="col">{__('Admin\\Votes')}</th>
<th scope="col">{__('Admin\\Poll ID')}</th>
<th scope="col" colspan="3">{__('Admin\\Actions')}</th>
</tr>
@ -37,9 +70,13 @@
<tr align="center">
<td class="cell-format">
{if $poll->format === 'D'}
<span class="glyphicon glyphicon-calendar" aria-hidden="true" title="{__('Generic\\Date')}"></span><span class="sr-only">{__('Generic\\Date')}</span>
<span class="glyphicon glyphicon-calendar" aria-hidden="true"
title="{__('Generic\\Date')}"></span>
<span class="sr-only">{__('Generic\\Date')}</span>
{else}
<span class="glyphicon glyphicon-list-alt" aria-hidden="true" title="{__('Generic\\Classic')}"></span><span class="sr-only">{__('Generic\\Classic')}</span>
<span class="glyphicon glyphicon-list-alt" aria-hidden="true"
title="{__('Generic\\Classic')}"></span>
<span class="sr-only">{__('Generic\\Classic')}</span>
{/if}
</td>
<td>{$poll->title|html}</td>
@ -47,15 +84,26 @@
<td>{$poll->admin_mail|html}</td>
{if strtotime($poll->end_date) > time()}
<td>{date('d/m/y', strtotime($poll->end_date))}</td>
<td>{date('d/m/y', strtotime($poll->end_date))}</td>
{else}
<td><span class="text-danger">{strtotime($poll->end_date)|date_format:'d/m/Y'}</span></td>
<td><span class="text-danger">{strtotime($poll->end_date)|date_format:'d/m/Y'}</span></td>
{/if}
<td>{$poll->votes|html}</td>
<td>{$poll->id|html}</td>
<td><a href="{$poll->id|poll_url|html}" class="btn btn-link" title="{__('Admin\\See the poll')}"><span class="glyphicon glyphicon-eye-open"></span><span class="sr-only">{__('Admin\\See the poll')}</span></a></td>
<td><a href="{$poll->admin_id|poll_url:true|html}" class="btn btn-link" title="{__('Admin\\Change the poll')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Admin\\Change the poll')}</span></a></td>
<td><button type="submit" name="delete_poll" value="{$poll->id|html}" class="btn btn-link" title="{__('Admin\\Deleted the poll')}"><span class="glyphicon glyphicon-trash text-danger"></span><span class="sr-only">{__('Admin\\Deleted the poll')}</span></td>
<td><a href="{$poll->id|poll_url|html}" class="btn btn-link"
title="{__('Admin\\See the poll')}"><span
class="glyphicon glyphicon-eye-open"></span><span
class="sr-only">{__('Admin\\See the poll')}</span></a></td>
<td><a href="{$poll->admin_id|poll_url:true|html}" class="btn btn-link"
title="{__('Admin\\Change the poll')}"><span
class="glyphicon glyphicon-pencil"></span><span
class="sr-only">{__('Admin\\Change the poll')}</span></a></td>
<td>
<button type="submit" name="delete_poll" value="{$poll->id|html}" class="btn btn-link"
title="{__('Admin\\Deleted the poll')}"><span
class="glyphicon glyphicon-trash text-danger"></span><span
class="sr-only">{__('Admin\\Deleted the poll')}</span>
</td>
</tr>
{/foreach}
</table>
@ -64,9 +112,10 @@
{__('Admin\\Pages:')}
{for $p=1 to $pages}
{if $p===$page}
<a href="{$SERVER_URL}admin/polls.php?page={$p}" class="btn btn-danger" disabled="disabled">{$p}</a>
<a href="{$SERVER_URL}admin/polls.php?page={$p}&{$search_query}" class="btn btn-danger"
disabled="disabled">{$p}</a>
{else}
<a href="{$SERVER_URL}admin/polls.php?page={$p}" class="btn btn-info">{$p}</a>
<a href="{$SERVER_URL}admin/polls.php?page={$p}&{$search_query}" class="btn btn-info">{$p}</a>
{/if}
{/for}
</div>