Issue #18 Add search engine on admin polls list
This commit is contained in:
parent
15ecff4488
commit
40d707c96d
@ -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'));
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
23
js/app/admin/polls.js
Normal 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');
|
||||
});
|
||||
});
|
@ -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 ) {
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user