Merge branch 'feature/ajax_submission_for_comments' into 'develop'
Feature - ajax submission for comments The sending of comments has been ajaxified, in order to prevent the lose of vote data while commenting. The comment list is also refreshed while commenting. See merge request !72
This commit is contained in:
commit
3f1f957c5e
88
action/add_comment.php
Normal file
88
action/add_comment.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\NotificationService;
|
||||
use Framadate\Message;
|
||||
use Framadate\Utils;
|
||||
use Framadate\Editable;
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
|
||||
/* Variables */
|
||||
/* --------- */
|
||||
|
||||
$poll_id = null;
|
||||
$poll = null;
|
||||
$message = null;
|
||||
$result = false;
|
||||
|
||||
/* Services */
|
||||
/*----------*/
|
||||
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$inputService = new InputService();
|
||||
$mailService = new MailService($config['use_smtp']);
|
||||
$notificationService = new NotificationService($mailService);
|
||||
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
||||
if (!empty($_POST['poll'])) {
|
||||
$poll_id = filter_input(INPUT_POST, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
if (strlen($poll_id) === 16) {
|
||||
$poll = $pollService->findById($poll_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$poll) {
|
||||
$message = new Message('error', __('Error', 'This poll doesn\'t exist !'));
|
||||
} else {
|
||||
$name = $inputService->filterName($_POST['name']);
|
||||
$comment = $inputService->filterComment($_POST['comment']);
|
||||
|
||||
if ($name == null) {
|
||||
$message = new Message('danger', __('Error', 'The name is invalid.'));
|
||||
}
|
||||
|
||||
if ($message == null) {
|
||||
// Add comment
|
||||
$result = $pollService->addComment($poll_id, $name, $comment);
|
||||
if ($result) {
|
||||
$message = new Message('success', __('Comments', 'Comment added'));
|
||||
$notificationService->sendUpdateNotification($poll, $mailService, $name, NotificationService::ADD_COMMENT);
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Comment failed'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$comments = $pollService->allCommentsByPollId($poll_id);
|
||||
|
||||
$smarty->error_reporting = E_ALL & ~E_NOTICE;
|
||||
$smarty->assign('comments', $comments);
|
||||
$comments_html = $smarty->fetch('part/comments_list.tpl');
|
||||
|
||||
$response = array('result' => $result, 'message' => $message, 'comments' => $comments_html);
|
||||
|
||||
echo json_encode($response);
|
@ -23,15 +23,11 @@ use Framadate\Services\InputService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\NotificationService;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
/* Constants */
|
||||
/* --------- */
|
||||
const UPDATE_POLL = 1;
|
||||
const DELETED_POLL = 2;
|
||||
|
||||
/* Variables */
|
||||
/* --------- */
|
||||
|
||||
@ -49,40 +45,7 @@ $pollService = new PollService($connect, $logService);
|
||||
$adminPollService = new AdminPollService($connect, $pollService, $logService);
|
||||
$inputService = new InputService();
|
||||
$mailService = new MailService($config['use_smtp']);
|
||||
|
||||
/* Functions */
|
||||
/*-----------*/
|
||||
|
||||
/**
|
||||
* Send a notification to the poll admin to notify him about an update.
|
||||
*
|
||||
* @param stdClass $poll The poll
|
||||
* @param MailService $mailService The mail service
|
||||
* @param int $type cf: Constants on the top of this page
|
||||
*/
|
||||
function sendUpdateNotification($poll, $mailService, $type) {
|
||||
if (!isset($_SESSION['mail_sent'])) {
|
||||
$_SESSION['mail_sent'] = [];
|
||||
}
|
||||
|
||||
if ($poll->receiveNewVotes) {
|
||||
|
||||
$subject = '[' . NOMAPPLICATION . '] ' . __f('Mail', 'Notification of poll: %s', $poll->title);
|
||||
|
||||
$message = '';
|
||||
switch ($type) {
|
||||
case UPDATE_POLL:
|
||||
$message = __f('Mail', 'Someone just change your poll available at the following link %s.', Utils::getUrlSondage($poll->admin_id, true)) . "\n\n";
|
||||
break;
|
||||
case DELETED_POLL:
|
||||
$message = __f('Mail', 'Someone just delete your poll %s.', Utils::htmlEscape($poll->title)) . "\n\n";
|
||||
break;
|
||||
}
|
||||
|
||||
$messageTypeKey = $type . '-' . $poll->id;
|
||||
$mailService->send($poll->admin_mail, $subject, $message, $messageTypeKey);
|
||||
}
|
||||
}
|
||||
$notificationService = new NotificationService($mailService);
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
@ -176,7 +139,7 @@ if (isset($_POST['update_poll_info'])) {
|
||||
// Update poll in database
|
||||
if ($updated && $adminPollService->updatePoll($poll)) {
|
||||
$message = new Message('success', __('adminstuds', 'Poll saved'));
|
||||
sendUpdateNotification($poll, $mailService, UPDATE_POLL);
|
||||
$notificationService->sendUpdateNotification($poll, NotificationService::UPDATE_POLL);
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Failed to save poll'));
|
||||
$poll = $pollService->findById($poll_id);
|
||||
@ -341,7 +304,7 @@ if (isset($_POST['delete_poll'])) {
|
||||
if (isset($_POST['confirm_delete_poll'])) {
|
||||
if ($adminPollService->deleteEntirePoll($poll_id)) {
|
||||
$message = new Message('success', __('adminstuds', 'Poll fully deleted'));
|
||||
sendUpdateNotification($poll, $mailService, DELETED_POLL);
|
||||
$notificationService->sendUpdateNotification($poll, NotificationService::DELETED_POLL);
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Failed to delete the poll'));
|
||||
}
|
||||
|
88
app/classes/Framadate/Services/NotificationService.php
Normal file
88
app/classes/Framadate/Services/NotificationService.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Framadate\Services;
|
||||
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Utils;
|
||||
use \stdClass;
|
||||
|
||||
|
||||
class NotificationService {
|
||||
|
||||
const UPDATE_VOTE = 1;
|
||||
const ADD_VOTE = 2;
|
||||
const ADD_COMMENT = 3;
|
||||
const UPDATE_POLL = 10;
|
||||
const DELETED_POLL = 11;
|
||||
|
||||
private $mailService;
|
||||
|
||||
function __construct(MailService $mailService) {
|
||||
$this->mailService = $mailService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a notification to the poll admin to notify him about an update.
|
||||
*
|
||||
* @param $poll stdClass The poll
|
||||
* @param $name string The name user who triggered the notification
|
||||
* @param $type int cf: Constants on the top of this page
|
||||
*/
|
||||
function sendUpdateNotification(stdClass $poll, $type, $name='') {
|
||||
if (!isset($_SESSION['mail_sent'])) {
|
||||
$_SESSION['mail_sent'] = [];
|
||||
}
|
||||
|
||||
if ($poll->receiveNewVotes) {
|
||||
|
||||
if (self::isParticipation($type)) {
|
||||
$translationString = 'Poll\'s participation: %s';
|
||||
} else {
|
||||
$translationString = 'Notification of poll: %s';
|
||||
}
|
||||
|
||||
$subject = '[' . NOMAPPLICATION . '] ' . __f('Mail', $translationString, $poll->title);
|
||||
|
||||
|
||||
$message = '';
|
||||
|
||||
$urlSondage = Utils::getUrlSondage($poll->admin_id, true);
|
||||
$link = '<a href="' . $urlSondage . '">' . $urlSondage . '</a>' . "\n\n";
|
||||
|
||||
switch ($type) {
|
||||
case self::UPDATE_VOTE:
|
||||
$message .= $name . ' ';
|
||||
$message .= __('Mail', "updated a vote.\nYou can find your poll at the link") . " :\n\n";
|
||||
$message .= $link;
|
||||
break;
|
||||
case self::ADD_VOTE:
|
||||
$message .= $name . ' ';
|
||||
$message .= __('Mail', "filled a vote.\nYou can find your poll at the link") . " :\n\n";
|
||||
$message .= $link;
|
||||
break;
|
||||
case self::ADD_COMMENT:
|
||||
$message .= $name . ' ';
|
||||
$message .= __('Mail', "wrote a comment.\nYou can find your poll at the link") . " :\n\n";
|
||||
$message .= $link;
|
||||
break;
|
||||
case self::UPDATE_POLL:
|
||||
$message = __f('Mail', 'Someone just change your poll available at the following link %s.', Utils::getUrlSondage($poll->admin_id, true)) . "\n\n";
|
||||
break;
|
||||
case self::DELETED_POLL:
|
||||
$message = __f('Mail', 'Someone just delete your poll %s.', Utils::htmlEscape($poll->title)) . "\n\n";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
$messageTypeKey = $type . '-' . $poll->id;
|
||||
$this->mailService->send($poll->admin_mail, $subject, $message, $messageTypeKey);
|
||||
}
|
||||
}
|
||||
|
||||
function isParticipation($type)
|
||||
{
|
||||
return $type >= self::UPDATE_POLL;
|
||||
}
|
||||
|
||||
}
|
7
css/jquery-ui.min.css
vendored
Normal file
7
css/jquery-ui.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -18,18 +18,19 @@
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
$("#poll_form").submit(function (event) {
|
||||
var name = $("#name").val();
|
||||
name = name.trim();
|
||||
$('#poll_form').submit(function (event) {
|
||||
var name = $('#name').val().trim();
|
||||
|
||||
if (name.length == 0) {
|
||||
event.preventDefault();
|
||||
var newMessage = $("#nameErrorMessage").clone();
|
||||
$("#message-container").empty();
|
||||
$("#message-container").append(newMessage);
|
||||
newMessage.removeClass("hidden");
|
||||
var newMessage = $('#nameErrorMessage').clone();
|
||||
var messageContainer = $('#message-container');
|
||||
messageContainer
|
||||
.empty()
|
||||
.append(newMessage);
|
||||
newMessage.removeClass('hidden');
|
||||
$('html, body').animate({
|
||||
scrollTop: $("#message-container").offset().top
|
||||
scrollTop: messageContainer.offset().top
|
||||
}, 750);
|
||||
}
|
||||
});
|
||||
@ -44,4 +45,46 @@ $(document).ready(function () {
|
||||
$(this).next().removeClass('startunchecked');
|
||||
});
|
||||
|
||||
var form = $('#comment_form');
|
||||
form.submit(function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: form.attr('action'),
|
||||
data: form.serialize(),
|
||||
dataType: 'json',
|
||||
success: function(data)
|
||||
{
|
||||
$('#comment').val('');
|
||||
|
||||
if (data.result) {
|
||||
$('#comments_list')
|
||||
.replaceWith(data.comments);
|
||||
var lastComment = $('#comments_list')
|
||||
.find('div.comment')
|
||||
.last();
|
||||
lastComment.effect('highlight', {color: 'green'}, 401);
|
||||
$('html, body').animate({
|
||||
scrollTop: lastComment.offset().top
|
||||
}, 750);
|
||||
} else {
|
||||
var newMessage = $('#genericErrorTemplate').clone();
|
||||
newMessage
|
||||
.find('.contents')
|
||||
.text(data.message.message);
|
||||
var commentsAlert = $('#comments_alerts');
|
||||
commentsAlert
|
||||
.empty()
|
||||
.append(newMessage);
|
||||
$('html, body').animate({
|
||||
scrollTop: commentsAlert.offset().top
|
||||
}, 750);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
|
6
js/jquery-ui.min.js
vendored
Normal file
6
js/jquery-ui.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
54
studs.php
54
studs.php
@ -20,18 +20,13 @@ use Framadate\Services\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\NotificationService;
|
||||
use Framadate\Message;
|
||||
use Framadate\Utils;
|
||||
use Framadate\Editable;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
/* Constants */
|
||||
/* --------- */
|
||||
const UPDATE_VOTE = 1;
|
||||
const ADD_VOTE = 2;
|
||||
const ADD_COMMENT = 3;
|
||||
|
||||
/* Variables */
|
||||
/* --------- */
|
||||
|
||||
@ -47,46 +42,8 @@ $logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$inputService = new InputService();
|
||||
$mailService = new MailService($config['use_smtp']);
|
||||
$notificationService = new NotificationService($mailService);
|
||||
|
||||
/* Functions */
|
||||
/*-----------*/
|
||||
|
||||
/**
|
||||
* Send a notification to the poll admin to notify him about an update.
|
||||
*
|
||||
* @param $poll stdClass The poll
|
||||
* @param $mailService MailService The mail service
|
||||
* @param $name string The name user who triggered the notification
|
||||
* @param $type int cf: Constants on the top of this page
|
||||
*/
|
||||
function sendUpdateNotification($poll, $mailService, $name, $type) {
|
||||
if (!isset($_SESSION['mail_sent'])) {
|
||||
$_SESSION['mail_sent'] = [];
|
||||
}
|
||||
|
||||
if ($poll->receiveNewVotes) {
|
||||
|
||||
$subject = '[' . NOMAPPLICATION . '] ' . __f('Mail', 'Poll\'s participation: %s', $poll->title);
|
||||
|
||||
$message = $name . ' ';
|
||||
switch ($type) {
|
||||
case UPDATE_VOTE:
|
||||
$message .= __('Mail', "updated a vote.\nYou can find your poll at the link") . " :\n\n";
|
||||
break;
|
||||
case ADD_VOTE:
|
||||
$message .= __('Mail', "filled a vote.\nYou can find your poll at the link") . " :\n\n";
|
||||
break;
|
||||
case ADD_COMMENT:
|
||||
$message .= __('Mail', "wrote a comment.\nYou can find your poll at the link") . " :\n\n";
|
||||
break;
|
||||
}
|
||||
$urlSondage = Utils::getUrlSondage($poll->admin_id, true);
|
||||
$message .= '<a href="' . $urlSondage . '">' . $urlSondage . '</a>' . "\n\n";
|
||||
|
||||
$messageTypeKey = $type . '-' . $poll->id;
|
||||
$mailService->send($poll->admin_mail, $subject, $message, $messageTypeKey);
|
||||
}
|
||||
}
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
@ -139,7 +96,7 @@ if (!empty($_POST['save'])) { // Save edition of an old vote
|
||||
} else {
|
||||
$message = new Message('success', __('studs', 'Update vote succeeded'));
|
||||
}
|
||||
sendUpdateNotification($poll, $mailService, $name, UPDATE_VOTE);
|
||||
$notificationService->sendUpdateNotification($poll, NotificationService::UPDATE_VOTE, $name);
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Update vote failed'));
|
||||
}
|
||||
@ -165,7 +122,7 @@ if (!empty($_POST['save'])) { // Save edition of an old vote
|
||||
} else {
|
||||
$message = new Message('success', __('studs', 'Adding the vote succeeded'));
|
||||
}
|
||||
sendUpdateNotification($poll, $mailService, $name, ADD_VOTE);
|
||||
$notificationService->sendUpdateNotification($poll, NotificationService::ADD_VOTE, $name);
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Adding vote failed'));
|
||||
}
|
||||
@ -189,12 +146,11 @@ if (isset($_POST['add_comment'])) {
|
||||
$result = $pollService->addComment($poll_id, $name, $comment);
|
||||
if ($result) {
|
||||
$message = new Message('success', __('Comments', 'Comment added'));
|
||||
sendUpdateNotification($poll, $mailService, $name, ADD_COMMENT);
|
||||
$notificationService->sendUpdateNotification($poll, NotificationService::ADD_COMMENT, $name);
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Comment failed'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Retrieve data
|
||||
|
@ -1,21 +1,11 @@
|
||||
<hr role="presentation" id="comments" class="hidden-print"/>
|
||||
<form action="#comments" method="POST">
|
||||
|
||||
{* Comment list *}
|
||||
{* Comment list *}
|
||||
{include 'part/comments_list.tpl'}
|
||||
|
||||
{if $comments|count > 0}
|
||||
<h3>{__('Comments', 'Comments of polled people')}</h3>
|
||||
{foreach $comments as $comment}
|
||||
<div class="comment">
|
||||
{if $admin && !$expired}
|
||||
<button type="submit" name="delete_comment" value="{$comment->id|html}" class="btn btn-link" title="{__('Comments', 'Remove the comment')}"><span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span></button>
|
||||
{/if}
|
||||
<span class="comment_date">{$comment->date|date_format:$date_format['txt_datetime_short']}</span>
|
||||
<b>{$comment->name|html}</b>
|
||||
<span class="comment">{$comment->comment|escape|nl2br}</span>
|
||||
</div>
|
||||
{/foreach}
|
||||
{/if}
|
||||
<form action="action/add_comment.php" method="POST" id="comment_form">
|
||||
|
||||
<input type="hidden" name="poll" value="{$poll_id}"/>
|
||||
|
||||
{* Add comment form *}
|
||||
{if $active && !$expired}
|
||||
|
16
tpl/part/comments_list.tpl
Normal file
16
tpl/part/comments_list.tpl
Normal file
@ -0,0 +1,16 @@
|
||||
<div id="comments_list">
|
||||
{if $comments|count > 0}
|
||||
<h3>{__('Comments', 'Comments of polled people')}</h3>
|
||||
{foreach $comments as $comment}
|
||||
<div class="comment">
|
||||
{if $admin && !$expired}
|
||||
<button type="submit" name="delete_comment" value="{$comment->id|html}" class="btn btn-link" title="{__('Comments', 'Remove the comment')}"><span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span></button>
|
||||
{/if}
|
||||
<span class="comment_date">{$comment->date|date_format:$date_format['txt_datetime_short']}</span>
|
||||
<b>{$comment->name|html}</b>
|
||||
<span>{$comment->comment|escape|nl2br}</span>
|
||||
</div>
|
||||
{/foreach}
|
||||
{/if}
|
||||
<div id="comments_alerts"></div>
|
||||
</div>
|
@ -1,9 +1,12 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name="header"}
|
||||
<script src="{"js/jquery-ui.min.js"|resource}" type="text/javascript"></script>
|
||||
<script src="{"js/Chart.min.js"|resource}" type="text/javascript"></script>
|
||||
<script src="{"js/Chart.StackedBar.js"|resource}" type="text/javascript"></script>
|
||||
<script src="{"js/app/studs.js"|resource}" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="{'css/jquery-ui.min.css'|resource}">
|
||||
|
||||
{/block}
|
||||
|
||||
{block name=main}
|
||||
@ -15,6 +18,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div id="nameErrorMessage" class="hidden alert alert-dismissible alert-danger hidden-print" role="alert">{__('Error', 'The name is invalid.')}<button type="button" class="close" data-dismiss="alert" aria-label="{__('Generic', 'CLose')}"><span aria-hidden="true">×</span></button></div>
|
||||
<div id="genericErrorTemplate" class="hidden alert alert-dismissible alert-danger hidden-print" role="alert"><span class="contents"></span><button type="button" class="close" data-dismiss="alert" aria-label="{__('Generic', 'CLose')}"><span aria-hidden="true">×</span></button></div>
|
||||
|
||||
|
||||
{* Global informations about the current poll *}
|
||||
|
Loading…
Reference in New Issue
Block a user