Internal: Add justification plugin from 1.11.x

pull/3513/head
Julio Montoya 6 years ago
parent 32d53c3cbd
commit d5a822104f
  1. 99
      public/plugin/justification/Justification.php
  2. 5
      public/plugin/justification/README.md
  3. 68
      public/plugin/justification/add.php
  4. 88
      public/plugin/justification/cron.php
  5. 76
      public/plugin/justification/edit.php
  6. 4
      public/plugin/justification/index.php
  7. 8
      public/plugin/justification/install.php
  8. 113
      public/plugin/justification/justification_by_user.php
  9. 21
      public/plugin/justification/lang/english.php
  10. 21
      public/plugin/justification/lang/french.php
  11. 21
      public/plugin/justification/lang/spanish.php
  12. 60
      public/plugin/justification/list.php
  13. 6
      public/plugin/justification/plugin.php
  14. 57
      public/plugin/justification/set_course.php
  15. 8
      public/plugin/justification/uninstall.php
  16. 48
      public/plugin/justification/view/add.tpl
  17. 38
      public/plugin/justification/view/justification_user_list.tpl
  18. 33
      public/plugin/justification/view/list.tpl

@ -0,0 +1,99 @@
<?php
/* For license terms, see /license.txt */
class Justification extends Plugin
{
protected function __construct()
{
parent::__construct(
'1.1',
'Julio Montoya',
[
'tool_enable' => 'boolean',
'default_course_id' => 'text',
]
);
}
/**
* @return $this
*/
public static function create()
{
static $result = null;
return $result ? $result : $result = new self();
}
public function getJustification($id)
{
$id = (int) $id;
$sql = 'SELECT * FROM justification_document WHERE id = '.$id;
$query = Database::query($sql);
return Database::fetch_array($query, 'ASSOC');
}
public function getUserJustificationList($userId)
{
$userId = (int) $userId;
$sql = "SELECT * FROM justification_document_rel_users WHERE user_id = $userId ";
$query = Database::query($sql);
return Database::store_result($query, 'ASSOC');
}
public function getUserJustification($id)
{
$id = (int) $id;
$sql = "SELECT * FROM justification_document_rel_users WHERE id = $id ";
$query = Database::query($sql);
return Database::fetch_array($query, 'ASSOC');
}
public function getList()
{
$sql = 'SELECT * FROM justification_document ORDER BY name ';
$query = Database::query($sql);
return Database::store_result($query, 'ASSOC');
}
/**
* Install.
*/
public function install()
{
$sql = "CREATE TABLE IF NOT EXISTS justification_document (
id INT unsigned NOT NULL auto_increment PRIMARY KEY,
code TEXT NULL,
name TEXT NULL,
validity_duration INT,
comment TEXT NULL,
date_manual_on INT
)";
Database::query($sql);
$sql = "CREATE TABLE IF NOT EXISTS justification_document_rel_users (
id INT unsigned NOT NULL auto_increment PRIMARY KEY,
justification_document_id INT NOT NULL,
file_path VARCHAR(255),
user_id INT,
date_validity DATE
)";
Database::query($sql);
}
public function uninstall()
{
$sql = 'DROP TABLE IF EXISTS justification_document';
Database::query($sql);
$sql = 'DROP TABLE IF EXISTS justification_document_rel_users';
Database::query($sql);
}
}

@ -0,0 +1,5 @@
Justification
==============
1. Enable the plugin.
2. Create the justification files in plugin/justification/list.php

@ -0,0 +1,68 @@
<?php
/* For license terms, see /license.txt */
require_once __DIR__.'/../../main/inc/global.inc.php';
api_protect_admin_script();
$tool = 'justification';
$plugin = Justification::create();
$tpl = new Template($tool);
$fields = [];
$form = new FormValidator('add');
$form->addText('name', get_lang('Name'));
$form->addText('code', $plugin->get_lang('JustificationCode'));
$form->addNumeric('validity_duration', $plugin->get_lang('ValidityDuration'));
$form->addCheckBox('date_manual_on', $plugin->get_lang('DateManualOn'));
$form->addTextarea('comment', get_lang('Comment'));
$form->addButtonSave(get_lang('Save'));
if ($form->validate()) {
$values = $form->getSubmitValues();
$dateManual = isset($values['date_manual_on']) ? 1 : 0;
$cleanedCode = api_replace_dangerous_char($values['code']);
$code = Database::escape_string($cleanedCode);
$sql = "SELECT * FROM justification_document WHERE code = '$code' ";
$result = Database::query($sql);
$data = Database::fetch_array($result);
$message = Display::return_message(get_lang('ThisCodeAlradyExists'), 'warning');
if (empty($data)) {
$params = [
'name' => $values['name'],
'code' => $cleanedCode,
'validity_duration' => $values['validity_duration'],
'date_manual_on' => $dateManual,
'comment' => $values['comment'],
];
Database::insert('justification_document', $params);
$message = Display::return_message(get_lang('Saved'));
}
Display::addFlash($message);
$url = api_get_path(WEB_PLUGIN_PATH).'justification/list.php?';
header('Location: '.$url);
exit;
}
$actionLinks = Display::toolbarButton(
$plugin->get_lang('Back'),
api_get_path(WEB_PLUGIN_PATH).'justification/list.php',
'arrow-left',
'primary'
);
$tpl->assign(
'actions',
Display::toolbarAction('toolbar', [$actionLinks])
);
$content = $form->returnForm();
$tpl->assign('content', $content);
$tpl->display_one_col_template();

@ -0,0 +1,88 @@
<?php
/* For license terms, see /license.txt */
require_once __DIR__.'/../../main/inc/global.inc.php';
$plugin = Justification::create();
$courseId = api_get_setting('justification_default_course_id', 'justification');
echo 'Justification CRON - '.api_get_local_time().PHP_EOL;
if (empty($courseId)) {
echo 'No course was set';
exit;
}
$courseInfo = api_get_course_info_by_id($courseId);
if (empty($courseInfo)) {
echo "Course #$courseId doesn't exist";
exit;
}
$fieldList = $plugin->getList();
$totalFields = count($fieldList);
if (empty($fieldList)) {
echo 'No fields to check. Please add them in the justification plugin';
exit;
}
$userList = UserManager::get_user_list();
$count = count($userList);
echo "#$count users found".PHP_EOL;
$currentDate = api_get_utc_datetime();
foreach ($userList as $user) {
$userId = $user['id'];
echo "Checking user id #$userId".PHP_EOL;
$userJustificationList = $plugin->getUserJustificationList($userId);
$userJustificationDocumentList = array_column($userJustificationList, 'date_validity', 'justification_document_id');
if (count($userJustificationList) < $totalFields) {
unsubscribeUser($userId, $courseInfo);
continue;
}
if (count($userJustificationList) >= $totalFields) {
$successList = [];
foreach ($fieldList as $field) {
if (isset($userJustificationDocumentList[$field['id']])) {
$dateValidity = $userJustificationDocumentList[$field['id']];
if ($dateValidity > $currentDate) {
$successList[] = true;
}
}
}
$countSuccess = count($successList);
if ($countSuccess === $totalFields) {
subscribeUser($userId, $courseInfo);
continue;
} else {
echo "User #$userId only got $countSuccess justification(s) out of $totalFields.".PHP_EOL;
}
}
unsubscribeUser($userId, $courseInfo);
}
function unsubscribeUser($userId, $courseInfo)
{
$courseId = $courseInfo['real_id'];
CourseManager::unsubscribe_user($userId, $courseInfo['code']);
echo "Unsubscribe user id #$userId to course #$courseId".PHP_EOL;
}
function subscribeUser($userId, $courseInfo)
{
$courseId = $courseInfo['real_id'];
$isUserSubscribed = CourseManager::is_user_subscribed_in_course($userId, $courseInfo['code']);
if ($isUserSubscribed === false) {
CourseManager::subscribeUser($userId, $courseInfo['code'], STUDENT);
echo "Subscribe user id #$userId to course #$courseId".PHP_EOL;
} else {
echo "Nothing to do user id #$userId is already subscribed to #$courseId".PHP_EOL;
}
}

@ -0,0 +1,76 @@
<?php
/* For license terms, see /license.txt */
require_once __DIR__.'/../../main/inc/global.inc.php';
api_protect_admin_script();
$tool = 'justification';
$plugin = Justification::create();
$id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
if (empty($id)) {
api_not_allowed();
}
$justification = $plugin->getJustification($id);
$tpl = new Template($tool);
$fields = [];
$form = new FormValidator('add', 'post', api_get_self().'?id='.$id);
$form->addText('name', get_lang('Name'));
$form->addText('code', $plugin->get_lang('JustificationCode'));
$form->addNumeric('validity_duration', $plugin->get_lang('ValidityDuration'));
$form->addCheckBox('date_manual_on', $plugin->get_lang('DateManualOn'));
$form->addTextarea('comment', get_lang('Comment'));
$form->addButtonSave(get_lang('Update'));
$form->setDefaults($justification);
if ($form->validate()) {
$values = $form->getSubmitValues();
$cleanedCode = api_replace_dangerous_char($values['code']);
$code = Database::escape_string($cleanedCode);
$sql = "SELECT * FROM justification_document WHERE code = '$code' AND id <> $id";
$result = Database::query($sql);
$data = Database::fetch_array($result);
$message = Display::return_message(get_lang('ThisCodeAlradyExists'), 'warning');
if (empty($data)) {
$params = [
'name' => $values['name'],
'code' => $cleanedCode,
'validity_duration' => $values['validity_duration'],
'date_manual_on' => (int) $values['date_manual_on'],
'comment' => $values['comment'],
];
Database::update('justification_document', $params, ['id = ?' => $id]);
$message = Display::return_message(get_lang('Saved'));
}
Display::addFlash($message);
$url = api_get_path(WEB_PLUGIN_PATH).'justification/list.php?';
header('Location: '.$url);
exit;
}
$actionLinks = Display::toolbarButton(
$plugin->get_lang('Back'),
api_get_path(WEB_PLUGIN_PATH).'justification/list.php',
'arrow-left',
'primary'
);
$tpl->assign(
'actions',
Display::toolbarAction('toolbar', [$actionLinks])
);
$content = $form->returnForm();
$tpl->assign('content', $content);
$tpl->display_one_col_template();

@ -0,0 +1,4 @@
<?php
/* For license terms, see /license.txt */
$plugin = Justification::create();

@ -0,0 +1,8 @@
<?php
/* For license terms, see /license.txt */
require_once __DIR__.'/../../main/inc/global.inc.php';
api_protect_admin_script();
Justification::create()->install();

@ -0,0 +1,113 @@
<?php
/* For license terms, see /license.txt */
require_once __DIR__.'/../../main/inc/global.inc.php';
api_protect_admin_script();
$tool = 'justification';
$plugin = Justification::create();
$tpl = new Template($tool);
$fields = [];
$form = new FormValidator('search', 'get');
$form->addHeader('Search');
$form->addSelectAjax(
'user_id',
get_lang('User'),
[],
[
'url' => api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=get_user_like',
]
);
$form->addButtonSearch(get_lang('Search'));
$tpl->assign('form', $form->returnForm());
$userId = isset($_REQUEST['user_id']) ? (int) $_REQUEST['user_id'] : 0;
if ($form->validate()) {
$userId = $form->getSubmitValue('user_id');
}
if ($userId) {
$tpl->assign('user_info', api_get_user_info($userId));
$list = $plugin->getUserJustificationList($userId);
if ($list) {
foreach ($list as &$item) {
if ($item['date_validity'] < api_get_local_time()) {
$item['date_validity'] = Display::label($item['date_validity'], 'warning');
}
$item['justification'] = $plugin->getJustification($item['justification_document_id']);
$item['file_path'] = Display::url(
$item['file_path'],
api_get_uploaded_web_url('justification', $item['id'], $item['file_path']),
['target' => '_blank']
);
}
}
if (empty($list)) {
Display::addFlash(Display::return_message($plugin->get_lang('NoJustificationFound')));
}
$tpl->assign('list', $list);
}
$tpl->assign('user_id', $userId);
$content = $tpl->fetch('justification/view/justification_user_list.tpl');
$actionLinks = '';
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : '';
$id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
switch ($action) {
case 'edit':
$userJustification = $plugin->getUserJustification($id);
$userInfo = api_get_user_info($userJustification['user_id']);
$form = new FormValidator('edit', 'post', api_get_self().'?a=edit&id='.$id.'&user_id='.$userId);
$form->addHeader($userInfo['complete_name']);
$element = $form->addDatePicker('date_validity', $plugin->get_lang('ValidityDate'));
$element->setValue($userJustification['date_validity']);
$form->addButtonUpdate(get_lang('Update'));
$form->setDefaults($userJustification);
$content = $form->returnForm();
if ($form->validate()) {
$values = $form->getSubmitValues();
$date = Database::escape_string($values['date_validity']);
$sql = "UPDATE justification_document_rel_users SET date_validity = '$date' WHERE id = $id";
Database::query($sql);
Display::addFlash(Display::return_message(get_lang('Updated')));
header('Location: '.api_get_self().'?user_id='.$userId);
exit;
}
break;
case 'delete':
$userJustification = $plugin->getUserJustification($id);
if ($userJustification) {
api_remove_uploaded_file_by_id('justification', $id, $userJustification['file_path']);
$sql = "DELETE FROM justification_document_rel_users WHERE id = $id";
Database::query($sql);
Display::addFlash(Display::return_message(get_lang('Deleted')));
}
header('Location: '.api_get_self().'?user_id='.$userId);
exit;
break;
}
$actionLinks .= Display::toolbarButton(
$plugin->get_lang('Back'),
api_get_path(WEB_PLUGIN_PATH).'justification/list.php',
'arrow-left',
'primary'
);
$tpl->assign(
'actions',
Display::toolbarAction('toolbar', [$actionLinks])
);
$tpl->assign('content', $content);
$tpl->display_one_col_template();

@ -0,0 +1,21 @@
<?php
$strings['plugin_title'] = "Justification Plugin";
$strings['plugin_comment'] = "";
$strings['tool_enable'] = "Enable";
$strings['ValidityDuration'] = "Validity Duration";
$strings['DateManualOn'] = "Date Manual On";
$strings['JustificationCode'] = "Justification code";
$strings['NoJustificationFound'] = "No justification found";
$strings['ValidityDate'] = "Validity date";
$strings['Justification'] = "Justification";
$strings['MyJustifications'] = "My justifications";
$strings['JustificationSaved'] = "Justification saved";
$strings['default_course_id'] = "Course id";
$strings['SetNewCourse'] = "Set new course";
$strings['SubscribeToASession'] = "Subscribe to a session";
$strings['JustificationName'] = "Justification name";
$strings['JustificationDate'] = "Justification date";
$strings['DocumentListForUserX'] = "Document list of user %s";

@ -0,0 +1,21 @@
<?php
$strings['plugin_title'] = "Justification Plugin";
$strings['plugin_comment'] = "";
$strings['tool_enable'] = "Activer le plugin";
$strings['ValidityDuration'] = "Durée de validité en jour";
$strings['DateManualOn'] = "Autoriser la modification de la date";
$strings['JustificationCode'] = "Code du justificatif";
$strings['NoJustificationFound'] = "Aucun justificatif trouvé";
$strings['ValidityDate'] = "Date de validitée";
$strings['Justification'] = "Justificatif";
$strings['MyJustifications'] = "Mes justificatifs";
$strings['JustificationSaved'] = "Justificatif enregistré";
$strings['default_course_id'] = "id du cours par défaut";
$strings['SetNewCourse'] = "Sélectionner un cours";
$strings['JustificationName'] = "Nom du justificatif";
$strings['JustificationDate'] = "Date du justificatif";
$strings['SubscribeToASession'] = "S'inscrire à une session d'examen";
$strings['DocumentListForUserX'] = "Liste des documents pour %s";

@ -0,0 +1,21 @@
<?php
$strings['plugin_title'] = "Justification Plugin";
$strings['plugin_comment'] = "";
$strings['tool_enable'] = "Activar el plugin";
$strings['ValidityDuration'] = "Periodo de validez en días";
$strings['DateManualOn'] = "Permitir modificación de fecha";
$strings['JustificationCode'] = "Código del justificativo";
$strings['NoJustificationFound'] = "Ningun justificativo encontrado";
$strings['ValidityDate'] = "Fecha de validez";
$strings['Justification'] = "Justificativo";
$strings['MyJustifications'] = "Mis justificativos";
$strings['JustificationSaved'] = "Justificativo guardado";
$strings['default_course_id'] = "id del courso por defecto";
$strings['SetNewCourse'] = "Eligir un curso";
$strings['JustificationName'] = "Nombre del justificativo";
$strings['JustificationDate'] = "Fecha del justificativo";
$strings['SubscribeToASession'] = "Inscribirse a una sesion de examen";
$strings['DocumentListForUserX'] = "Lista de documentos para %s";

@ -0,0 +1,60 @@
<?php
/* For license terms, see /license.txt */
require_once __DIR__.'/../../main/inc/global.inc.php';
api_protect_admin_script();
$tool = 'justification';
$plugin = Justification::create();
$tpl = new Template($tool);
$fields = [];
$list = $plugin->getList();
$tpl->assign('list', $list);
$content = $tpl->fetch('justification/view/list.tpl');
$actionLinks = '';
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : '';
$id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
switch ($action) {
case 'delete':
$sql = "DELETE FROM justification_document WHERE id = $id";
Database::query($sql);
Display::addFlash(Display::return_message(get_lang('Deleted')));
header('Location: '.api_get_self());
exit;
break;
}
$actionLinks .= Display::toolbarButton(
$plugin->get_lang('Add'),
api_get_path(WEB_PLUGIN_PATH).'justification/add.php',
'plus',
'primary'
);
$actionLinks .= Display::toolbarButton(
$plugin->get_lang('Users'),
api_get_path(WEB_PLUGIN_PATH).'justification/justification_by_user.php',
'user',
'primary'
);
$actionLinks .= Display::toolbarButton(
$plugin->get_lang('SetNewCourse'),
api_get_path(WEB_PLUGIN_PATH).'justification/set_course.php',
'book',
'primary'
);
$tpl->assign(
'actions',
Display::toolbarAction('toolbar', [$actionLinks])
);
$tpl->assign('content', $content);
$tpl->display_one_col_template();

@ -0,0 +1,6 @@
<?php
/* For license terms, see /license.txt */
require_once __DIR__.'/../../main/inc/global.inc.php';
$plugin_info = Justification::create()->get_info();

@ -0,0 +1,57 @@
<?php
/* For license terms, see /license.txt */
require_once __DIR__.'/../../main/inc/global.inc.php';
api_protect_admin_script();
$tool = 'justification';
$plugin = Justification::create();
$tpl = new Template($tool);
$fields = [];
$form = new FormValidator('add');
$form->addHeader($plugin->get_lang('SetNewCourse'));
$currentCourse = api_get_setting('justification_default_course_id', 'justification');
if (!empty($currentCourse)) {
$courseInfo = api_get_course_info_by_id($currentCourse);
Display::addFlash(Display::return_message(get_lang('Course').': '.$courseInfo['title']));
}
$form->addSelectAjax(
'course_id',
get_lang('Course'),
null,
[
'url' => api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=search_course',
]
);
$form->addButtonSave(get_lang('Save'));
if ($form->validate()) {
$values = $form->getSubmitValues();
api_set_setting('justification_default_course_id', $values['course_id']);
Display::addFlash(Display::return_message(get_lang('Saved')));
$url = api_get_path(WEB_PLUGIN_PATH).'justification/list.php?';
header('Location: '.$url);
exit;
}
$actionLinks = Display::toolbarButton(
$plugin->get_lang('Back'),
api_get_path(WEB_PLUGIN_PATH).'justification/list.php',
'arrow-left',
'primary'
);
$tpl->assign(
'actions',
Display::toolbarAction('toolbar', [$actionLinks])
);
$content = $form->returnForm();
$tpl->assign('content', $content);
$tpl->display_one_col_template();

@ -0,0 +1,8 @@
<?php
/* For license terms, see /license.txt */
require_once __DIR__.'/../../main/inc/global.inc.php';
api_protect_admin_script();
Justification::create()->uninstall();

@ -0,0 +1,48 @@
{{ search_form }}
<table class="table table-hover table-striped">
<thead>
<tr>
<th>{{ 'CreatedAt'|get_lang }}</th>
<th>{{ 'Status'|get_lang }}</th>
<th>{{ 'Records'|get_plugin_lang('BBBPlugin') }}</th>
<th>{{ 'Course'|get_lang }}</th>
<th>{{ 'Session'|get_lang }}</th>
<th>{{ 'Participants'|get_lang }}</th>
<th>{{ 'Actions'|get_lang }}</th>
</tr>
</thead>
<tbody>
{% for meeting in meetings %}
<tr id="meeting-{{ meeting.id }}">
{% if meeting.visibility == 0 %}
<td class="muted">{{ meeting.created_at }}</td>
{% else %}
<td>{{ meeting.created_at }}</td>
{% endif %}
<td>
{% if meeting.status == 1 %}
<span class="label label-success">{{ 'MeetingOpened'|get_plugin_lang('BBBPlugin') }}</span>
{% else %}
<span class="label label-info">{{ 'MeetingClosed'|get_plugin_lang('BBBPlugin') }}</span>
{% endif %}
</td>
<td>
{% if meeting.record == 1 %}
{# Record list #}
{{ meeting.show_links }}
{% else %}
{{ 'NoRecording'|get_plugin_lang('BBBPlugin') }}
{% endif %}
</td>
<td>{{ meeting.course ?: '-' }}</td>
<td>{{ meeting.session ?: '-' }}</td>
<td>
{{ meeting.participants ? meeting.participants|join('<br>') : '-' }}
</td>
<td>
{{ meeting.action_links }}
</td>
</tr>
{% endfor %}
</tbody>
</table>

@ -0,0 +1,38 @@
{{ form }}
{% if list %}
<div class ="row">
<div class ="col-md-12">
<div class="page-header">
<h2>{{ 'DocumentListForUserX'| get_plugin_lang('Justification')|format(user_info.complete_name) }}</h2>
</div>
<table class="table">
<tr>
<th>{{ 'Justification'| get_plugin_lang('Justification') }}</th>
<th>{{ 'File'| get_lang }}</th>
<th>{{ 'Date'| get_lang('Date') }}</th>
<th>{{ 'Actions'| get_lang }}</th>
</tr>
{% for item in list %}
<tr>
<td >{{ item.justification.name }} </td>
<td >{{ item.file_path }} </td>
<td >
{{ item.date_validity }}
</td>
<td>
<a href="{{_p.web_plugin }}justification/justification_by_user.php?a=edit&user_id={{ user_id }}&id={{ item.id }}"
class="btn btn-primary">
{{'Edit' | get_lang}}
</a>
<a href="{{_p.web_plugin }}justification/justification_by_user.php?a=delete&user_id={{ user_id }}&id={{ item.id }}"
class="btn btn-danger">
{{'Delete' | get_lang}}
</a>
</td>
</tr>
{% endfor %}
</table>
</div>
</div>
{% endif %}

@ -0,0 +1,33 @@
<div class ="row">
<div class ="col-md-12">
<div class="page-header">
<h2>{{ 'List'| get_lang }}</h2>
</div>
<table class="table">
<tr>
<th>{{ 'Name'| get_lang }}</th>
<th>{{ 'ValidityDuration'| get_plugin_lang('Justification') }}</th>
<th>{{ 'DateManualOn'| get_plugin_lang('Justification') }}</th>
<th>{{ 'Actions'| get_lang }}</th>
</tr>
{% for item in list %}
<tr>
<td >{{ item.name }} ({{ item.code }})</td>
<td >{{ item.validity_duration }}</td>
<td >{{ item.date_manual_on }}</td>
<td>
<a href="{{_p.web_plugin }}justification/edit.php?id={{ item.id }}" class="btn btn-primary">
{{'Edit' | get_lang}}
</a>
<a href="{{_p.web_plugin }}justification/list.php?a=delete&id={{ item.id }}" class="btn btn-danger">
{{'Delete' | get_lang}}
</a>
</td>
</tr>
{% endfor %}
</table>
</div>
</div>
Loading…
Cancel
Save