Add setting "allow_scheduled_announcements" see BT#12901

remotes/angel/1.11.x
jmontoyaa 8 years ago
parent 87732f6dfd
commit 9c6aeb4eab
  1. 8
      main/cron/programmed_announcement.php
  2. 78
      main/inc/ajax/model.ajax.php
  3. 363
      main/inc/lib/ProgrammedAnnouncement.php
  4. 1
      main/inc/lib/model.lib.php
  5. 2
      main/install/configuration.dist.php
  6. 230
      main/session/programmed_announcement.php
  7. 4
      main/session/resume_session.php
  8. 12
      main/template/default/session/resume_session.tpl

@ -0,0 +1,8 @@
<?php
require_once __DIR__.'/../inc/global.inc.php';
$object = new ProgrammedAnnouncement();
$messagesSent = $object->sendPendingMessages();
echo "Messages sent $messagesSent";

@ -191,6 +191,10 @@ if (!$sidx) {
//@todo rework this
switch ($action) {
case 'get_programmed_announcements':
$object = new ProgrammedAnnouncement();
$count = $object->get_count();
break;
case 'get_group_reporting':
$course_id = isset($_REQUEST['course_id']) ? $_REQUEST['course_id'] : null;
$group_id = isset($_REQUEST['gidReq']) ? $_REQUEST['gidReq'] : null;
@ -242,7 +246,6 @@ switch ($action) {
exit;
}
} elseif (api_is_student_boss()) {
$supervisorStudents = UserManager::getUsersFollowedByUser(
api_get_user_id(),
api_is_student_boss() ? null : STUDENT,
@ -671,6 +674,24 @@ $is_allowedToEdit = api_is_allowed_to_edit(null, true) || api_is_allowed_to_edit
$columns = array();
switch ($action) {
case 'get_programmed_announcements':
$columns = array('subject', 'date', 'sent', 'actions');
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : 0;
$result = Database::select(
'*',
$object->table,
array(
'where' => array("session_id = ? " => $sessionId),
'order' => "$sidx $sord",
'LIMIT' => "$start , $limit")
);
if ($result) {
foreach ($result as &$item) {
$item['date'] = api_get_local_time($item['date']);
}
}
break;
case 'get_group_reporting':
$columns = array('name', 'time', 'progress', 'score', 'works', 'messages', 'actions');
@ -1126,9 +1147,19 @@ switch ($action) {
if (!empty($sessions)) {
foreach ($sessions as $session) {
if (api_drh_can_access_all_session_content()) {
$count_courses_in_session = SessionManager::get_course_list_by_session_id($session['id'], '', null, true);
$count_courses_in_session = SessionManager::get_course_list_by_session_id(
$session['id'],
'',
null,
true
);
} else {
$count_courses_in_session = count(Tracking::get_courses_followed_by_coach($user_id, $session['id']));
$count_courses_in_session = count(
Tracking::get_courses_followed_by_coach(
$user_id,
$session['id']
)
);
}
$count_users_in_session = SessionManager::get_users_by_session($session['id'], 0, true);
@ -1418,12 +1449,12 @@ switch ($action) {
);
$sessionId = 0;
if (!empty($_GET['course_id']) && !empty($_GET['session_id'])) {
$sessionId = intval($_GET['session_id']);
$courseId = intval($_GET['course_id']);
$studentId = intval($_GET['student_id']);
$profile = intval($_GET['profile']);
$date_from = intval($_GET['date_from']);
$date_to = intval($_GET['date_to']);
$sessionId = intval($_GET['session_id']);
$courseId = intval($_GET['course_id']);
$studentId = intval($_GET['student_id']);
$profile = intval($_GET['profile']);
$date_from = intval($_GET['date_from']);
$date_to = intval($_GET['date_to']);
}
$result = SessionManager::get_user_data_access_tracking_overview(
@ -1477,7 +1508,11 @@ switch ($action) {
if (!in_array($sidx, $columns)) {
$sidx = 'name';
}
$result = Database::select('*', $obj->table, array('order'=>"$sidx $sord", 'LIMIT'=> "$start , $limit"));
$result = Database::select(
'*',
$obj->table,
array('order' => "$sidx $sord", 'LIMIT' => "$start , $limit")
);
$new_result = array();
foreach ($result as $item) {
if ($item['parent_id'] != 0) {
@ -1515,7 +1550,11 @@ switch ($action) {
if (!in_array($sidx, $columns)) {
$sidx = 'subject';
}
$result = Database::select('*', $obj->table, array('order'=>"$sidx $sord", 'LIMIT'=> "$start , $limit"));
$result = Database::select(
'*',
$obj->table,
array('order' => "$sidx $sord", 'LIMIT' => "$start , $limit")
);
$new_result = array();
foreach ($result as $item) {
$language_info = api_get_language_info($item['language_id']);
@ -1531,7 +1570,11 @@ switch ($action) {
if (!in_array($sidx, $columns)) {
$sidx = 'name';
}
$result = Database::select('*', $obj->table, array('order'=>"$sidx $sord", 'LIMIT'=> "$start , $limit"));
$result = Database::select(
'*',
$obj->table,
array('order' => "$sidx $sord", 'LIMIT' => "$start , $limit")
);
$new_result = array();
foreach ($result as $item) {
if (!$item['status']) {
@ -1567,7 +1610,11 @@ switch ($action) {
if (!in_array($sidx, $columns)) {
$sidx = 'name';
}
$result = Database::select('*', "$obj->table ", array('order' => "$sidx $sord", 'LIMIT' => "$start , $limit"));
$result = Database::select(
'*',
"$obj->table ",
array('order' => "$sidx $sord", 'LIMIT' => "$start , $limit")
);
$new_result = array();
foreach ($result as $item) {
$new_result[] = $item;
@ -1641,7 +1688,7 @@ switch ($action) {
$column_names[] = get_lang('FinalScore');
break;
default:
$title = "";
$title = '';
if (!empty($exercises[$cnt - 4]['title'])) {
$title = ucwords(strtolower(trim($exercises[$cnt - 4]['title'])));
}
@ -1799,7 +1846,8 @@ $allowed_actions = array(
'get_user_course_report_resumed',
'get_exercise_grade',
'get_group_reporting',
'get_course_announcements'
'get_course_announcements',
'get_programmed_announcements'
);
//5. Creating an obj to return a json

@ -0,0 +1,363 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Class ProgrammedAnnouncement
* Requires DB change:
* $sql = "CREATE TABLE IF NOT EXISTS programmed_announcements (
id int UNSIGNED NOT NULL AUTO_INCREMENT,
subject VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
date datetime DEFAULT NULL,
sent INT,
session_id INT NOT NULL,
PRIMARY KEY (id)
)";
*
* Config setting:
* $_configuration['allow_scheduled_announcements'] = true;
*
* Setup linux cron file:
* main/cron/programmed_announcement.php
*
* Requires:
* composer update
*
* @package chamilo.library
*/
class ProgrammedAnnouncement extends Model
{
public $table;
public $columns = array('id', 'subject', 'message', 'date', 'sent', 'session_id');
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->table = 'programmed_announcements';
}
/**
* @param array $where_conditions
*
* @return array
*/
public function get_all($where_conditions = array())
{
return Database::select(
'*',
$this->table,
array('where' => $where_conditions, 'order' => 'subject ASC')
);
}
/**
* @return mixed
*/
public function get_count()
{
$row = Database::select(
'count(*) as count',
$this->table,
array(),
'first'
);
return $row['count'];
}
/**
* Displays the title + grid
*/
public function getGrid($sessionId)
{
// action links
$action = '<div class="actions" style="margin-bottom:20px">';
$action .= '<a href="programmed_announcement.php?session_id='.$sessionId.'">'.
Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM).
'</a>';
$action .= '<a href="'.api_get_self().'?action=add&session_id='.$sessionId.'">'.
Display::return_icon('add.png', get_lang('Add'), '', ICON_SIZE_MEDIUM).'</a>';
$action .= '<a href="programmed_announcement.php?action=run&session_id='.$sessionId.'">'.
Display::return_icon('mail_send.png', get_lang('Send'), '', ICON_SIZE_MEDIUM).
'</a>';
$action .= '</div>';
$html = $action;
$html .= '<div id="session-table" class="table-responsive">';
$html .= Display::grid_html('programmed');
$html .= '</div>';
return $html;
}
/**
* Returns a Form validator Obj
* @param string $url
* @param string $action add, edit
*
* @return FormValidator form validator obj
*/
public function returnSimpleForm($url, $action, $sessionInfo = [])
{
$form = new FormValidator(
'announcement',
'post',
$url
);
$form->addHidden('session_id', $sessionInfo['id']);
$form->addDateTimePicker('date', get_lang('Date'));
$form->addText('subject', get_lang('Subject'));
$form->addHtmlEditor('message', get_lang('Message'));
$this->setTagsInForm($form);
$form->addCheckBox('sent', null, get_lang('MessageSent'));
if ($action == 'edit') {
$form->addButtonUpdate(get_lang('Modify'));
}
return $form;
}
private function setTagsInForm(& $form)
{
$form->addLabel(
get_lang('Tags'),
Display::return_message(
implode('<br />', $this->getTags()),
'normal',
false
)
);
}
/**
* Returns a Form validator Obj
* @todo the form should be auto generated
* @param string $url
* @param string $action add, edit
*
* @return FormValidator form validator obj
*/
public function returnForm($url, $action, $sessionInfo = [])
{
// Setting the form elements
$header = get_lang('Add');
if ($action == 'edit') {
$header = get_lang('Modify');
}
$form = new FormValidator(
'announcement',
'post',
$url
);
$form->addHeader($header);
$form->addHidden('session_id', $sessionInfo['id']);
$useBaseDate = false;
$startDate = $sessionInfo['access_start_date'];
$endDate = $sessionInfo['access_end_date'];
if (!empty($startDate) || !empty($endDate)) {
$useBaseDate = true;
}
$typeOptions = [
'specific_date' => get_lang('SpecificDate')
];
if ($useBaseDate) {
$typeOptions['base_date'] = get_lang('BaseDate');
}
$form->addSelect(
'type',
get_lang('Type'),
$typeOptions,
[
'onchange' => "javascript:
if (this.options[this.selectedIndex].value == 'base_date') {
document.getElementById('options').style.display = 'block';
document.getElementById('specific_date').style.display = 'none';
} else {
document.getElementById('options').style.display = 'none';
document.getElementById('specific_date').style.display = 'block';
}
"]
);
$form->addElement('html', '<div id="specific_date">');
$form->addDateTimePicker('date', get_lang('Date'));
$form->addElement('html', '</div>');
$form->addElement('html', '<div id="options" style="display:none">');
$startDate = $sessionInfo['access_start_date'];
$endDate = $sessionInfo['access_end_date'];
$form->addText(
'days',
get_lang('days'),
false
);
$form->addSelect(
'moment_type',
get_lang('AfterOrBefore'),
[
'after' => get_lang('After'),
'before' => get_lang('before'),
]
);
if (!empty($startDate)) {
$options['start_date'] = get_lang('StartDate').' - '.$startDate;
}
if (!empty($endDate)) {
$options['end_date'] = get_lang('EndDate').' - '.$endDate;
}
if (!empty($options)) {
$form->addSelect('base_date', get_lang('BaseDate'), $options);
}
$form->addElement('html', '</div>');
$form->addText('subject', get_lang('Subject'));
$form->addHtmlEditor('message', get_lang('Message'));
$this->setTagsInForm($form);
if ($action == 'edit') {
$form->addButtonUpdate(get_lang('Modify'));
} else {
$form->addButtonCreate(get_lang('Add'));
}
return $form;
}
/**
* @param array $params
* @param bool $show_query
* @return bool
*/
public function save($params, $show_query = false)
{
$id = parent::save($params, $show_query);
return $id;
}
/**
* @param array $params
*/
public function update($params)
{
parent::update($params);
}
/**
* @param int $id
*/
public function delete($id)
{
parent::delete($id);
}
/**
* @return int
*/
public function sendPendingMessages()
{
if (!$this->allowed()) {
return 0;
}
$messagesSent = 0;
$now = api_get_utc_datetime();
$courseCode = api_get_course_id();
$result = $this->get_all();
foreach ($result as $result) {
if (empty($result['sent'])) {
if (!empty($result['date']) && $result['date'] < $now) {
$sessionId = $result['session_id'];
$sessionInfo = api_get_session_info($sessionId);
//self::update(['id' => $result['id'], 'sent' => 1]);
$users = SessionManager::get_users_by_session($sessionId);
$subject = $result['subject'];
$message = $result['message'];
if ($users) {
foreach ($users as $user) {
$userInfo = api_get_user_info($user['user_id']);
$progress = Tracking::get_avg_student_progress(
$user['user_id'],
$courseCode,
null,
$sessionId
);
if (is_numeric($progress)) {
$progress = $progress.'%';
} else {
$progress = '0%';
}
$tags = [
'((session_name))' => $sessionInfo['name'],
'((user_complete_name))' => $userInfo['complete_name'],
'((lp_progress))' => $progress,
];
$message = str_replace(array_keys($tags), $tags, $message);
MessageManager::send_message(
$user['user_id'],
$subject,
$message
);
}
}
$messagesSent++;
}
}
}
return $messagesSent;
}
/**
* @return array
*/
public function getTags()
{
$tags = [
'((session_name))',
'((user_complete_name))',
'((lp_progress))'
];
return $tags;
}
/**
* @return bool
*/
public function allowed()
{
return api_get_configuration_value('allow_scheduled_announcements');
}
}

@ -62,7 +62,6 @@ class Model
// Database table definition
$result = Database::delete($this->table, $params);
if ($result != 1) {
return false;
}

@ -458,4 +458,6 @@ $_configuration['agenda_legend'] = [
//UPDATE extra_field_values SET updated_at = NULL WHERE CAST(updated_at AS CHAR(20)) = '0000-00-00 00:00:00';
//ALTER TABLE extra_field_values modify column value longtext null;
//$_configuration['allow_career_diagram'] = false;
// Allow scheduled emails to session users. See class ProgrammedAnnouncement
//$_configuration['allow_scheduled_announcements'] = false;

@ -0,0 +1,230 @@
<?php
/* For licensing terms, see /license.txt */
$cidReset = true;
require_once __DIR__.'/../inc/global.inc.php';
api_protect_admin_script();
$sessionId = isset($_GET['session_id']) ? (int) $_GET['session_id'] : 0;
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
$action = isset($_GET['action']) ? $_GET['action'] : '';
$sessionInfo = api_get_session_info($sessionId);
if (!$sessionInfo) {
api_not_allowed(true);
}
$object = new ProgrammedAnnouncement();
if (!$object->allowed()) {
api_not_allowed(true);
}
$htmlHeadXtra[] = api_get_jqgrid_js();
$interbreadcrumb[] = array('url' => "session_list.php", "name" => get_lang('SessionList'));
$interbreadcrumb[] = array(
'url' => "resume_session.php?id_session=".$sessionId,
"name" => get_lang('SessionOverview')
);
$interbreadcrumb[] = array(
'url' => api_get_self()."?session_id=".$sessionId,
"name" => get_lang('ProgrammedAnnouncements')
);
if ($action == 'add') {
$tool_name = get_lang('Add');
} elseif ($action == 'edit') {
$tool_name = get_lang('Edit');
} else {
$tool_name = get_lang('ProgrammedAnnouncements');
}
switch ($action) {
case 'run':
$messagesSent = $object->sendPendingMessages();
Display::addFlash(
Display::return_message(
get_lang('MessageSent').': '.$messagesSent,
'confirmation'
)
);
$content = $object->getGrid($sessionId);
break;
case 'add':
$url = api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&session_id='.$sessionId;
$form = $object->returnForm($url, 'add', $sessionInfo);
// The validation or display
if ($form->validate()) {
$values = $form->getSubmitValues();
switch ($values['type']) {
case 'base_date':
$numberDays = (int) $values['days'];
switch ($values['base_date']) {
case 'start_date':
$baseDate = new DateTime($sessionInfo['access_start_date']);
break;
case 'end_date':
$baseDate = new DateTime($sessionInfo['access_end_date']);
break;
}
$interval = new DateInterval('P'.$numberDays.'D');
switch ($values['moment_type']) {
case 'after':
$newDate = $baseDate->add($interval);
break;
case 'before':
$newDate = $baseDate->sub($interval);
break;
}
$values['date'] = $newDate->format('Y-m-d h:i:s');
break;
case 'specific_date':
$values['date'] = api_get_utc_datetime($values['date']);
break;
}
$res = $object->save($values);
$values['date'] = api_get_utc_datetime($values['date']);
if ($res) {
Display::addFlash(
Display::return_message(
get_lang('ItemAdded'),
'confirmation'
)
);
}
$content = $object->getGrid($sessionId);
} else {
$content = '<div class="actions">';
$content .= '<a href="'.api_get_self().'?session_id='.$sessionId.'">'.
Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM).'</a>';
$content .= '</div>';
$form->addElement('hidden', 'sec_token');
$content .= $form->returnForm();
}
/*if ($form->validate()) {
$values = $form->getSubmitValues();
$values['subject'];
$values['message'];
switch ($values['type']) {
case 'base_date':
$values['date_time'];
break;
case 'specific_date':
break;
}
}*/
break;
case 'edit':
// Action handling: Editing
$url = api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&id='.intval($_GET['id']).'&session_id='.$sessionId;
$form = $object->returnSimpleForm($url, 'edit', $sessionInfo);
if ($form->validate()) {
$values = $form->getSubmitValues();
$values['id'] = $id;
$values['sent'] = isset($values['sent']) ? 1 : '';
$values['date'] = api_get_utc_datetime($values['date']);
$res = $object->update($values);
Display::addFlash(Display::return_message(
get_lang('Updated'),
'confirmation'
));
}
$item = $object->get($id);
$item['date'] = api_get_local_time($item['date']);
$form->setDefaults($item);
$content = $form->returnForm();
break;
case 'delete':
$res = $object->delete($_GET['id']);
$content = $object->getGrid($sessionId);
break;
default:
$content = $object->getGrid($sessionId);
break;
}
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_programmed_announcements&session_id='.$sessionId;
$columns = [
get_lang('Subject'),
get_lang('Date'),
get_lang('Sent'),
get_lang('Actions')
];
$columnModel = [
array(
'name' => 'subject',
'index' => 'subject',
'width' => '250',
'align' => 'left',
),
array(
'name' => 'date',
'index' => 'date',
//'width' => '90',
//'align' => 'left',
'sortable' => 'true',
),
array(
'name' => 'sent',
'index' => 'sent',
//'width' => '90',
//'align' => 'left',
'sortable' => 'true',
),
array(
'name' => 'actions',
'index' => 'actions',
'width' => '100',
'align' => 'left',
'formatter' => 'action_formatter',
'sortable' => 'false',
)
];
$actionLinks = 'function action_formatter(cellvalue, options, rowObject) {
return \'<a href="?action=edit&session_id='.$sessionId.'&id=\'+options.rowId+\'">'.Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL).'</a>'.
'&nbsp;<a onclick="javascript:if(!confirm('."\'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"), ENT_QUOTES))."\'".')) return false;" href="?action=delete&session_id='.$sessionId.'&id=\'+options.rowId+\'">'.Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>'.
'\';
}';
$extraParams = [];
$extraParams['autowidth'] = 'true';
$htmlHeadXtra[] = '<script>
$(function() {
// grid definition see the $obj->display() function
'.Display::grid_js(
'programmed',
$url,
$columns,
$columnModel,
$extraParams,
array(),
$actionLinks,
true
).'
});
</script>';
$tpl = new Template($tool_name);
$tpl->assign('content', $content);
$tpl->display_one_col_template();

@ -358,12 +358,16 @@ if (!empty($sessionInfo['promotion_id'])) {
$promotion = $promotion->find($sessionInfo['promotion_id']);
}
$programmedAnnouncement = new ProgrammedAnnouncement();
$programmedAnnouncement = $programmedAnnouncement->allowed();
$tpl = new Template(get_lang('Session'));
$tpl->assign('session_header', $sessionHeader);
$tpl->assign('title', $sessionTitle);
$tpl->assign('general_coach', $generalCoach);
$tpl->assign('session_admin', api_get_user_info($session->getSessionAdminId()));
$tpl->assign('session', $sessionInfo);
$tpl->assign('programmed_announcement', $programmedAnnouncement);
$tpl->assign('session_category', is_null($sessionCategory) ? null : $sessionCategory->getName());
$tpl->assign('session_dates', SessionManager::parseSessionDates($sessionInfo, true));
$tpl->assign('session_visibility', SessionManager::getSessionVisibility($sessionInfo));

@ -79,6 +79,7 @@
</td>
</tr>
{% endif %}
{% if url_list %}
<tr>
<td>URL</td>
@ -96,6 +97,17 @@
<td>{{ extra_field.value }}</td>
</tr>
{% endfor %}
{% if programmed_announcement %}
<tr>
<td>{{ 'ProgrammedAnnouncements' | get_lang}}</td>
<td>
<a class="btn btn-default" href="{{ _p.web_main }}session/programmed_announcement.php?session_id={{ session.id }}">
{{ 'Edit' | get_lang }}
</a>
</td>
</tr>
{% endif %}
</table>
{{ course_list }}

Loading…
Cancel
Save