Skip to content

Commit

Permalink
Add functions to clean up feedback
Browse files Browse the repository at this point in the history
- Update datatables
- Refactor + Fix annoying bug with double sorting/asc/desc
- Add new functionality for filtering, cleaning and purging
  • Loading branch information
xiaohutai committed Jun 16, 2020
1 parent 5a1cc46 commit 123ccad
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 32 deletions.
103 changes: 102 additions & 1 deletion src/Controller/BackendController.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ public function addRoutes(ControllerCollection $ctr)
->bind('is_useful.feedback.status')
;

$ctr
->get('/clean', [$this, 'cleanGet'])
->before([$this, 'before'])
->bind('is_useful.feedback.clean')
;

$ctr
->post('/clean', [$this, 'cleanPost'])
->before([$this, 'before'])
->bind('is_useful.feedback.clean.post')
;

return $ctr;
}

Expand Down Expand Up @@ -251,7 +263,7 @@ public function deleteFeedback(Application $app, Request $request, $id)
}

/**
*
* Set feedback status
*/
public function setFeedbackStatus(Application $app, Request $request, $id, $status)
{
Expand All @@ -266,4 +278,93 @@ public function setFeedbackStatus(Application $app, Request $request, $id, $stat

return $this->redirect( $request->headers->get('referer') );
}

/**
* Clean up feedback using simple rules
*/
public function cleanGet(Application $app, Request $request)
{
$feedback = [];

$originalValue = $request->query->get('filter', false);
if (! empty($originalValue)) {
$likeValue = '%' . $originalValue . '%';
$status = FeedbackStatus::REMOVED;

$stmt = $app['db']->prepare("SELECT * FROM `bolt_is_useful_feedback` WHERE `status` != :status AND ( `message` LIKE :msg OR `ip` = :ip)");
$stmt->bindParam('status', $status);
$stmt->bindParam('msg', $likeValue);
$stmt->bindParam('ip', $originalValue);
$stmt->execute();

$feedback = $stmt->fetchAll();
}

return $this->render('@is_useful/backend/clean.twig', [
'title' => 'Feedback » Clean',
//'data' => $data,
'feedback' => $feedback,
'total_unread' => count($this->getUnreadFeedback($app['db'])),
], []);
}

/**
* Cleans up feedback. Two options:
* (A) as filtered by user
* (B) general clean up inconsistencies
*/
public function cleanPost(Application $app, Request $request)
{
$status = FeedbackStatus::REMOVED;

$originalValue = $request->request->get('filter', false);

// (A) Remove feedback via a LIKE query.
if (! empty($originalValue)) {
$likeValue = '%' . $originalValue . '%';

$stmt = $app['db']->prepare("UPDATE `bolt_is_useful_feedback` SET `status` = :status WHERE ( `message` LIKE :msg OR `ip` = :ip )");
$stmt->bindParam('status', $status);
$stmt->bindParam('msg', $likeValue);
$stmt->bindParam('ip', $originalValue);
$stmt->execute();

$app['logger.system']->info("[IsUseful] Purging feedback with [$originalValue]", [ 'event' => 'extensions' ]);
}
// (B) Clean up
else {
$app['logger.system']->info("[IsUseful] Cleaning feedback", [ 'event' => 'extensions' ]);

// A deep get doesn't work?
$ipBanlist = $app['is_useful.config']->get('ipBanlist');
if (empty($ipBanlist)) {
$ipBanlist = [];
}

// (1) Remove where is_useful_id = NULL
$stmt = $app['db']->prepare("UPDATE `bolt_is_useful_feedback` SET `status` = :status WHERE `is_useful_id` IS NULL");
$stmt->bindParam('status', $status);
$stmt->execute();

// (2) Remove where message = NULL
$stmt = $app['db']->prepare("UPDATE `bolt_is_useful_feedback` SET `status` = :status WHERE `message` IS NULL");
$stmt->bindParam('status', $status);
$stmt->execute();

// (3) Remove where ip is in ipBanlist (add it to `ipBanlist` in `isuseful.twokings_local.yml`)
$sql = "UPDATE `bolt_is_useful_feedback` SET `status` = :status WHERE `ip` IN (:ip)";
$values = [
'status' => $status,
'ip' => $ipBanlist,
];
$types = [
'status' => \PDO::PARAM_STR,
'ip' => \Doctrine\DBAL\Connection::PARAM_STR_ARRAY,
];
$stmt = $app['db']->executeQuery($sql, $values, $types);
$stmt->execute();
}

return $this->redirect( $app['url_generator']->generate('is_useful.feedback.clean') );
}
}
2 changes: 1 addition & 1 deletion src/EventListener/FormListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function onFeedback(ProcessorEvent $event) {

foreach (['id', 'message', 'type'] as $key) {
if (empty($data->get($key))) {
$this->app['logger.system']->error("[IsUseful] Ignored request: $key is empty!");
$this->app['logger.system']->error("[IsUseful] Ignored request: $key is empty!", [ 'event' => 'extensions' ]);
return;
}
}
Expand Down
23 changes: 23 additions & 0 deletions templates/backend/_datatables.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css">
<script type="text/javascript" src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>





<script>
$(document).ready(function(){
$('[data-table]').DataTable({
pageLength: 100
});
});
</script>

<style>
/* Fixes a clash with Bootstrap/Bolt annoying double indicators */
table.dataTable thead .sorting_asc:after,
table.dataTable thead .sorting_desc:after,
table.dataTable thead .sorting:after {
content: '' !important;
}
</style>
8 changes: 7 additions & 1 deletion templates/backend/_navigation.twig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{% set indexActiveClass = global.request.get('_route') == 'is_useful.index' ? 'active' : '' %}
{% set indexActiveClass = global.request.get('_route') == 'is_useful.index' ? 'active' : '' %}
{% set unreadActiveClass = global.request.get('_route') == 'is_useful.unread' ? 'active' : '' %}
{% set cleanActiveClass = global.request.get('_route') == 'is_useful.feedback.clean' ? 'active' : '' %}

<nav class="navbar navbar-default is-useful-navbar">
<ul class="nav navbar-nav ">
Expand All @@ -18,5 +19,10 @@
{% endif %}
</a>
</li>
<li class="{{ cleanActiveClass }}">
<a href="{{ path('is_useful.feedback.clean') }}"><i class="fa fa-trash"></i>
Clean
</a>
</li>
</ul>
</nav>
94 changes: 94 additions & 0 deletions templates/backend/clean.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{% extends '_base/_page-nav.twig' %}

{% block page_nav title %}

{% block page_title __(title) %}

{% block page_main %}

{{ include('@is_useful/backend/_navigation.twig') }}

<h3>Filter</h3>
<p>Filter using a part of a message or an IP address. Afterwards you can purge records.</p>
<form class="form-inline" action="{{ path('is_useful.feedback.clean') }}" method="get">
<input class="form-control" type="text" name="filter" value="{{ app.request.query.get('filter') }}">
<button class="btn btn-primary" type="submit">
<i class="fa fa-filter"></i> Filter
</button>
</form>
<hr>
<h3>Clean</h3>
<p>Clean up records. This will remove empty and invalid records.</p>
<form action="{{ path('is_useful.feedback.clean.post') }}" method="post">
<button class="btn btn-secondary" type="submit">
<i class="fa fa-ban"></i> Clean
</button>
</form>

{% if feedback is not empty and app.request.query.get('filter') %}
<hr>
<h3>Purge</h3>
<p>Remove all records that are shown below.</p>
<form action="{{ path('is_useful.feedback.clean.post') }}" method="post">
<input type="hidden" name="filter" value="{{ app.request.query.get('filter') }}">
<button class="btn btn-danger" type="submit">
<i class="fa fa-ban"></i> Remove all records with: [{{ app.request.query.get('filter') }}]
</button>
</form>
<hr>
{% endif %}


{% if feedback is not empty %}
<table data-table>
<thead>
<th>Page</th>
<th>IP</th>
<th>Date</th>
<th>Message</th>
{# <th>Actions</th> #}
</thead>
<tbody>
{% for item in feedback %}
{% set ip = item.ip %}
{% set datetime = item.datetime %}
{% set message = item.message %}
{% set deleteLink = path('is_useful.feedback.delete', { id: item.id }) %}
{% set statusReadLink = path('is_useful.feedback.status', { id: item.id, status: 'read' }) %}
{% set statusDoneLink = path('is_useful.feedback.status', { id: item.id, status: 'done' }) %}
{% set viewLink = item.is_useful_id is not empty ? path('is_useful.view', { id: item.is_useful_id }) : '' %}

<tr>
{% setcontent record = "#{item.contenttype}/#{item.contentid}" %}
<td class="is-useful">
<a href="{{ viewLink }}" title="View detailed feedback for this page">
{{ record.title|default('(Untitled)') }}
</a>
</td>
<td class="is-useful-ip">{{ ip }}</td>
<td class="is-useful-datetime">{{ datetime }}</td>
<td class="is-useful-message">
{% if message is not empty %}
<div class="well well-sm">
{{ message }}
</div>
{% endif %}
</td>
{#
<td>
<a class="btn btn-secondary" href="{{ statusReadLink }}"><i class="fa fa-eye"></i> <span class="visible-md-inline visible-lg-inline">Mark as read</span></a>
<a class="btn btn-secondary btn-success" href="{{ statusDoneLink }}"><i class="fa fa-check"></i> <span class="visible-md-inline visible-lg-inline">Mark as done</span></a>
<a class="btn btn-tertiary" href="{{ deleteLink }}" onclick="return confirm('Are you sure?')"><i class="fa fa-trash"></i></a>
</td>
#}
</tr>
{% endfor %}
</tbody>
</table>
{% else %}

{% endif %}

{{ include('@is_useful/backend/_datatables.twig') }}

{% endblock page_main %}
10 changes: 1 addition & 9 deletions templates/backend/feedback.twig
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,6 @@
This item has no feedback yet.
{% endif %}

<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css">
<script type="text/javascript" src="//cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function(){
$('[data-table]').DataTable({
pageLength: 100
});
});
</script>
{{ include('@is_useful/backend/_datatables.twig') }}

{% endblock page_main %}
12 changes: 1 addition & 11 deletions templates/backend/index.twig
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,6 @@
</tbody>
</table>



<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css">
<script type="text/javascript" src="//cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function(){
$('[data-table]').DataTable({
pageLength: 100
});
});
</script>
{{ include('@is_useful/backend/_datatables.twig') }}

{% endblock page_main %}
10 changes: 1 addition & 9 deletions templates/backend/unread.twig
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,6 @@
This item has no feedback yet.
{% endif %}

<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css">
<script type="text/javascript" src="//cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function(){
$('[data-table]').DataTable({
pageLength: 100
});
});
</script>
{{ include('@is_useful/backend/_datatables.twig') }}

{% endblock page_main %}

0 comments on commit 123ccad

Please sign in to comment.