mirror of
https://github.com/RaspbianFrance/raspisms.git
synced 2025-04-20 16:37:48 +02:00
Merge remote-tracking branch 'RaspbianFrance/master'
This commit is contained in:
commit
4575a24bcb
14 changed files with 251 additions and 9 deletions
|
@ -22,6 +22,13 @@
|
||||||
//On va appeler un modèle, est l'initialiser
|
//On va appeler un modèle, est l'initialiser
|
||||||
$db = new DataBase($bdd);;
|
$db = new DataBase($bdd);;
|
||||||
|
|
||||||
|
//On va ajouter les réglages globaux de RaspiSMS modifiables via l'interface
|
||||||
|
$settings = $db->getFromTableWhere('settings');
|
||||||
|
foreach ($settings as $setting)
|
||||||
|
{
|
||||||
|
define('RASPISMS_SETTINGS_' . mb_convert_case($setting['name'], MB_CASE_UPPER), $setting['value']);
|
||||||
|
}
|
||||||
|
|
||||||
###########
|
###########
|
||||||
# ROUTAGE #
|
# ROUTAGE #
|
||||||
###########
|
###########
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
* @param int... $ids : Les id des commandes à supprimer
|
* @param int... $ids : Les id des commandes à supprimer
|
||||||
* @return boolean;
|
* @return boolean;
|
||||||
*/
|
*/
|
||||||
public function delete($csrf, ...$ids)
|
public function delete($csrf)
|
||||||
{
|
{
|
||||||
if (!internalTools::verifyCSRF($csrf))
|
if (!internalTools::verifyCSRF($csrf))
|
||||||
{
|
{
|
||||||
|
@ -45,6 +45,10 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//On récupère les ids comme étant tous les arguments de la fonction et on supprime le premier (csrf)
|
||||||
|
$ids = func_get_args();
|
||||||
|
unset($ids[0]);
|
||||||
|
|
||||||
//Create de l'object de base de données
|
//Create de l'object de base de données
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
|
@ -65,9 +69,10 @@
|
||||||
* Cette fonction retourne la page d'édition des commandes
|
* Cette fonction retourne la page d'édition des commandes
|
||||||
* @param int... $ids : Les id des commandes à editer
|
* @param int... $ids : Les id des commandes à editer
|
||||||
*/
|
*/
|
||||||
public function edit(...$ids)
|
public function edit()
|
||||||
{
|
{
|
||||||
global $db;
|
global $db;
|
||||||
|
$ids = func_get_args();
|
||||||
|
|
||||||
$commands = $db->getCommandsIn($ids);
|
$commands = $db->getCommandsIn($ids);
|
||||||
$this->render('commands/edit', array(
|
$this->render('commands/edit', array(
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
* @param int... $ids : Les id des commandes à supprimer
|
* @param int... $ids : Les id des commandes à supprimer
|
||||||
* @return Boolean;
|
* @return Boolean;
|
||||||
*/
|
*/
|
||||||
public function delete($csrf, ...$ids)
|
public function delete($csrf)
|
||||||
{
|
{
|
||||||
//On vérifie que le jeton csrf est bon
|
//On vérifie que le jeton csrf est bon
|
||||||
if (!internalTools::verifyCSRF($csrf))
|
if (!internalTools::verifyCSRF($csrf))
|
||||||
|
@ -46,6 +46,10 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//On récupère les ids comme étant tous les arguments de la fonction et on supprime le premier (csrf)
|
||||||
|
$ids = func_get_args();
|
||||||
|
unset($ids[0]);
|
||||||
|
|
||||||
//Create de l'object de base de données
|
//Create de l'object de base de données
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
|
@ -66,10 +70,13 @@
|
||||||
* Cette fonction retourne la page d'édition des contacts
|
* Cette fonction retourne la page d'édition des contacts
|
||||||
* @param int... $ids : Les id des commandes à supprimer
|
* @param int... $ids : Les id des commandes à supprimer
|
||||||
*/
|
*/
|
||||||
public function edit(...$ids)
|
public function edit()
|
||||||
{
|
{
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
|
//On récupère les ids comme étant tous les arguments de la fonction
|
||||||
|
$ids = func_get_args();
|
||||||
|
|
||||||
$contacts = $db->getContactsIn($ids);
|
$contacts = $db->getContactsIn($ids);
|
||||||
$this->render('contacts/edit', array(
|
$this->render('contacts/edit', array(
|
||||||
'contacts' => $contacts,
|
'contacts' => $contacts,
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
* @param int... $ids : Les id des groups à supprimer
|
* @param int... $ids : Les id des groups à supprimer
|
||||||
* @return void;
|
* @return void;
|
||||||
*/
|
*/
|
||||||
public function delete($csrf, ...$ids)
|
public function delete($csrf)
|
||||||
{
|
{
|
||||||
//On vérifie que le jeton csrf est bon
|
//On vérifie que le jeton csrf est bon
|
||||||
if (!internalTools::verifyCSRF($csrf))
|
if (!internalTools::verifyCSRF($csrf))
|
||||||
|
@ -44,6 +44,10 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//On récupère les ids comme étant tous les arguments de la fonction et on supprime le premier (csrf)
|
||||||
|
$ids = func_get_args();
|
||||||
|
unset($ids[0]);
|
||||||
|
|
||||||
//Create de l'object de base de données
|
//Create de l'object de base de données
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
|
@ -64,10 +68,13 @@
|
||||||
* Cette fonction retourne la page d'édition des groupes
|
* Cette fonction retourne la page d'édition des groupes
|
||||||
* @param int... $ids : Les id des groups à modifier
|
* @param int... $ids : Les id des groups à modifier
|
||||||
*/
|
*/
|
||||||
public function edit(...$ids)
|
public function edit()
|
||||||
{
|
{
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
|
//On récupère les ids comme étant tous les arguments de la fonction et on supprime le premier (csrf)
|
||||||
|
$ids = func_get_args();
|
||||||
|
|
||||||
$groups = $db->getGroupsIn($ids);
|
$groups = $db->getGroupsIn($ids);
|
||||||
$blocks = array(); //On défini la variable qui correspondra à un bloc groupe et contacts
|
$blocks = array(); //On défini la variable qui correspondra à un bloc groupe et contacts
|
||||||
|
|
||||||
|
|
|
@ -300,6 +300,12 @@
|
||||||
*/
|
*/
|
||||||
public function sendTransfers ()
|
public function sendTransfers ()
|
||||||
{
|
{
|
||||||
|
if (!RASPISMS_SETTINGS_TRANSFER)
|
||||||
|
{
|
||||||
|
echo "Le transfer de SMS est désactivé ! \n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
global $db;
|
global $db;
|
||||||
$transfers = $db->getFromTableWhere('transfers', ['progress' => false]);
|
$transfers = $db->getFromTableWhere('transfers', ['progress' => false]);
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
$email = isset($_SESSION['email']) ? $_SESSION['email'] : 'Mon compte';
|
$email = isset($_SESSION['email']) ? $_SESSION['email'] : 'Mon compte';
|
||||||
$this->render('internalIncs/nav', array(
|
$this->render('internalIncs/nav', array(
|
||||||
'email' => $email,
|
'email' => $email,
|
||||||
|
'admin' => $_SESSION['admin'],
|
||||||
'page' => $page,
|
'page' => $page,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,16 @@
|
||||||
//Récupération des SMS envoyés triés par date, du plus récent au plus ancien, par paquets de $limit, en ignorant les $offset premiers
|
//Récupération des SMS envoyés triés par date, du plus récent au plus ancien, par paquets de $limit, en ignorant les $offset premiers
|
||||||
$receiveds = $db->getFromTableWhere('receiveds', [], 'at', true, $limit, $offset);
|
$receiveds = $db->getFromTableWhere('receiveds', [], 'at', true, $limit, $offset);
|
||||||
|
|
||||||
|
foreach ($receiveds as $key => $received)
|
||||||
|
{
|
||||||
|
if (!$contacts = $db->getFromTableWhere('contacts', ['number' => $received['send_by']]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$receiveds[$key]['send_by'] = $contacts[0]['name'] . ' (' . $received['send_by'] . ')';
|
||||||
|
}
|
||||||
|
|
||||||
return $this->render('receiveds/showAll', array(
|
return $this->render('receiveds/showAll', array(
|
||||||
'receiveds' => $receiveds,
|
'receiveds' => $receiveds,
|
||||||
'page' => $page,
|
'page' => $page,
|
||||||
|
@ -58,6 +68,16 @@
|
||||||
$now = new DateTime();
|
$now = new DateTime();
|
||||||
$receiveds = $db->getReceivedsSince($now->format('Y-m-d'));
|
$receiveds = $db->getReceivedsSince($now->format('Y-m-d'));
|
||||||
|
|
||||||
|
foreach ($receiveds as $key => $received)
|
||||||
|
{
|
||||||
|
if (!$contacts = $db->getFromTableWhere('contacts', ['number' => $received['send_by']]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$receiveds[$key]['send_by'] = $contacts[0]['name'] . ' (' . $received['send_by'] . ')';
|
||||||
|
}
|
||||||
|
|
||||||
$nbReceiveds = count($receiveds);
|
$nbReceiveds = count($receiveds);
|
||||||
|
|
||||||
if (!isset($_SESSION['popup_nb_receiveds']) || ($_SESSION['popup_nb_receiveds'] > $nbReceiveds))
|
if (!isset($_SESSION['popup_nb_receiveds']) || ($_SESSION['popup_nb_receiveds'] > $nbReceiveds))
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
* @param int... $ids : Les id des commandes à supprimer
|
* @param int... $ids : Les id des commandes à supprimer
|
||||||
* @return boolean;
|
* @return boolean;
|
||||||
*/
|
*/
|
||||||
public function delete($csrf, ...$ids)
|
public function delete($csrf)
|
||||||
{
|
{
|
||||||
//On vérifie que le jeton csrf est bon
|
//On vérifie que le jeton csrf est bon
|
||||||
if (!internalTools::verifyCSRF($csrf))
|
if (!internalTools::verifyCSRF($csrf))
|
||||||
|
@ -44,6 +44,10 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//On récupère les ids comme étant tous les arguments de la fonction et on supprime le premier (csrf)
|
||||||
|
$ids = func_get_args();
|
||||||
|
unset($ids[0]);
|
||||||
|
|
||||||
//Create de l'object de base de données
|
//Create de l'object de base de données
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
|
@ -70,10 +74,13 @@
|
||||||
* Cette fonction retourne la page d'édition des sms programmés
|
* Cette fonction retourne la page d'édition des sms programmés
|
||||||
* @param int... $ids : Les id des commandes à supprimer
|
* @param int... $ids : Les id des commandes à supprimer
|
||||||
*/
|
*/
|
||||||
public function edit(...$ids)
|
public function edit()
|
||||||
{
|
{
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
|
//On récupère les ids comme étant tous les arguments de la fonction et on supprime le premier (csrf)
|
||||||
|
$ids = func_get_args();
|
||||||
|
|
||||||
$scheduleds = $db->getScheduledsIn($ids);
|
$scheduleds = $db->getScheduledsIn($ids);
|
||||||
//Pour chaque groupe, on récupère les contacts liés
|
//Pour chaque groupe, on récupère les contacts liés
|
||||||
foreach ($scheduleds as $key => $scheduled)
|
foreach ($scheduleds as $key => $scheduled)
|
||||||
|
|
69
controllers/settings.php
Executable file
69
controllers/settings.php
Executable file
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Page des réglages de RaspiSMS
|
||||||
|
*/
|
||||||
|
class settings extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Cette fonction est appelée avant toute les autres :
|
||||||
|
* Elle vérifie que l'utilisateur est bien connecté && est admin
|
||||||
|
* @return void;
|
||||||
|
*/
|
||||||
|
public function before()
|
||||||
|
{
|
||||||
|
internalTools::verifyConnect();
|
||||||
|
|
||||||
|
if (!$_SESSION['admin'])
|
||||||
|
{
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cette fonction retourne la page d'accueil des réglages de RaspiSMS
|
||||||
|
*/
|
||||||
|
public function byDefault()
|
||||||
|
{
|
||||||
|
return $this->render('settings/default');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cette fonction permet de mettre à jour l'activation ou la désactivation du transfer des SMS
|
||||||
|
* @param $csrf : Le jeton CSRF
|
||||||
|
* @param string $_POST['transfer'] : Le nouveau transfer de l'utilisateur
|
||||||
|
* @return void;
|
||||||
|
*/
|
||||||
|
public function changeTransfer($csrf)
|
||||||
|
{
|
||||||
|
//On vérifie que le jeton csrf est bon
|
||||||
|
if (!internalTools::verifyCSRF($csrf))
|
||||||
|
{
|
||||||
|
$_SESSION['errormessage'] = 'Jeton CSRF invalide !';
|
||||||
|
header('Location: ' . $this->generateUrl('settings'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Creation de l'object de base de données
|
||||||
|
global $db;
|
||||||
|
|
||||||
|
if (!isset($_POST['transfer']))
|
||||||
|
{
|
||||||
|
$_SESSION['errormessage'] = 'Vous devez renseigner un valeur';
|
||||||
|
header('Location: ' . $this->generateUrl('settings'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$transfer = (int)$_POST['transfer'];
|
||||||
|
|
||||||
|
if (!$db->updateTableWhere('settings', ['value' => $transfer], ['name' => 'transfer']))
|
||||||
|
{
|
||||||
|
$_SESSION['errormessage'] = 'Impossible de mettre les données à jour.';
|
||||||
|
header('Location: ' . $this->generateUrl('settings'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$_SESSION['successmessage'] = 'Les données ont été mises à jour.';
|
||||||
|
header('Location: ' . $this->generateUrl('settings'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -118,7 +118,7 @@
|
||||||
* @param int... $ids : Les id des commandes à supprimer
|
* @param int... $ids : Les id des commandes à supprimer
|
||||||
* @return boolean;
|
* @return boolean;
|
||||||
*/
|
*/
|
||||||
public function delete($csrf, ...$ids)
|
public function delete($csrf)
|
||||||
{
|
{
|
||||||
//On vérifie que le jeton csrf est bon
|
//On vérifie que le jeton csrf est bon
|
||||||
if (!internalTools::verifyCSRF($csrf))
|
if (!internalTools::verifyCSRF($csrf))
|
||||||
|
@ -128,6 +128,10 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//On récupère les ids comme étant tous les arguments de la fonction et on supprime le premier (csrf)
|
||||||
|
$ids = func_get_args();
|
||||||
|
unset($ids[0]);
|
||||||
|
|
||||||
//Create de l'object de base de données
|
//Create de l'object de base de données
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,14 @@
|
||||||
CREATE DATABASE IF NOT EXISTS raspisms;
|
CREATE DATABASE IF NOT EXISTS raspisms;
|
||||||
USE raspisms;
|
USE raspisms;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS settings
|
||||||
|
(
|
||||||
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
|
name VARCHAR(20) NOT NULL,
|
||||||
|
value VARCHAR(1000) NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS receiveds
|
CREATE TABLE IF NOT EXISTS receiveds
|
||||||
(
|
(
|
||||||
id INT NOT NULL AUTO_INCREMENT,
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
|
@ -126,3 +134,7 @@ CREATE TABLE IF NOT EXISTS transfers
|
||||||
PRIMARY KEY (id),
|
PRIMARY KEY (id),
|
||||||
FOREIGN KEY (id_received) REFERENCES receiveds (id) ON DELETE CASCADE ON UPDATE CASCADE
|
FOREIGN KEY (id_received) REFERENCES receiveds (id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#On insert les données par défaut dans les settings
|
||||||
|
INSERT INTO settings (name, value)
|
||||||
|
VALUES ('transfer', '1');
|
||||||
|
|
|
@ -18,6 +18,14 @@
|
||||||
//On va appeler un modèle, est l'initialiser
|
//On va appeler un modèle, est l'initialiser
|
||||||
$db = new DataBase($bdd);;
|
$db = new DataBase($bdd);;
|
||||||
|
|
||||||
|
//On va ajouter les réglages globaux de RaspiSMS modifiables via l'interface
|
||||||
|
$settings = $db->getFromTableWhere('settings');
|
||||||
|
foreach ($settings as $setting)
|
||||||
|
{
|
||||||
|
define('RASPISMS_SETTINGS_' . mb_convert_case($setting['name'], MB_CASE_UPPER), $setting['value']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
###########
|
###########
|
||||||
# ROUTAGE #
|
# ROUTAGE #
|
||||||
###########
|
###########
|
||||||
|
|
|
@ -68,6 +68,11 @@
|
||||||
<li <?php echo $page == 'users' ? 'class="active"' : ''; ?>>
|
<li <?php echo $page == 'users' ? 'class="active"' : ''; ?>>
|
||||||
<a href="<?php echo $this->generateUrl('users'); ?>"><i class="fa fa-fw fa-user"></i> Utilisateurs</a>
|
<a href="<?php echo $this->generateUrl('users'); ?>"><i class="fa fa-fw fa-user"></i> Utilisateurs</a>
|
||||||
</li>
|
</li>
|
||||||
|
<?php if ($admin) { ?>
|
||||||
|
<li <?php echo $page == 'settings' ? 'class="active"' : ''; ?>>
|
||||||
|
<a href="<?php echo $this->generateUrl('settings'); ?>"><i class="fa fa-fw fa-cogs"></i> Réglages</a>
|
||||||
|
</li>
|
||||||
|
<?php } ?>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.navbar-collapse -->
|
<!-- /.navbar-collapse -->
|
||||||
|
|
84
templates/settings/default.php
Executable file
84
templates/settings/default.php
Executable file
|
@ -0,0 +1,84 @@
|
||||||
|
<?php
|
||||||
|
//Template dashboard
|
||||||
|
$incs = new internalIncs();
|
||||||
|
$incs->head('Réglages');
|
||||||
|
?>
|
||||||
|
<div id="wrapper">
|
||||||
|
<?php
|
||||||
|
$incs->nav('settings');
|
||||||
|
?>
|
||||||
|
<div id="page-wrapper">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<h1 class="page-header">
|
||||||
|
Dashboard <small>Réglages</small>
|
||||||
|
</h1>
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li>
|
||||||
|
<i class="fa fa-dashboard"></i> <a href="<?php echo $this->generateUrl('dashboard'); ?>">Dashboard</a>
|
||||||
|
</li>
|
||||||
|
<li class="active">
|
||||||
|
<i class="fa fa-cogs"></i> Réglages
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.row -->
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"><i class="fa fa-cogs fa-fw"></i> Les réglages de RaspiSMS</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="col-xs-12 col-md-6">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h4 class="panel-title"><i class="fa fa-share fa-fw"></i> Transfert des SMS par e-mail</h4>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form action="<?php echo $this->generateUrl('settings', 'changeTransfer', [$_SESSION['csrf']]); ?>" method="POST">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Transfert activé : </label>
|
||||||
|
<select name="transfer" class="form-control">
|
||||||
|
<option value="0">Non</option>
|
||||||
|
<option value="1" <?php echo RASPISMS_SETTINGS_TRANSFER ? 'selected' : ''; ?>>Oui</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="text-center">
|
||||||
|
<button class="btn btn-success">Mettre à jour les données</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 col-md-6">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
jQuery(document).ready(function ()
|
||||||
|
{
|
||||||
|
jQuery('.action-dropdown a').on('click', function (e)
|
||||||
|
{
|
||||||
|
e.preventDefault();
|
||||||
|
var target = jQuery(this).parents('.action-dropdown').attr('target');
|
||||||
|
var url = jQuery(this).attr('href');
|
||||||
|
jQuery(target).find('input:checked').each(function ()
|
||||||
|
{
|
||||||
|
url += '/' + jQuery(this).val();
|
||||||
|
});
|
||||||
|
window.location = url;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<?php
|
||||||
|
$incs->footer();
|
Loading…
Add table
Add a link
Reference in a new issue