mirror of
https://github.com/RaspbianFrance/raspisms.git
synced 2025-07-21 20:38:46 +02:00
Add first valid expression ruler. Still not linked to scheduleds.
This commit is contained in:
parent
f59f7bd757
commit
f4bbfa0152
16 changed files with 1049 additions and 18 deletions
|
@ -41,7 +41,9 @@ namespace controllers\internals;
|
|||
'condition' => $condition,
|
||||
];
|
||||
|
||||
if (!$this->validate_condition($condition))
|
||||
$internal_ruler = new Ruler();
|
||||
$valid_condition = $internal_ruler->validate_condition($condition, ['contact' => (object) ['datas' => (object) null]]);
|
||||
if (!$valid_condition)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -73,8 +75,10 @@ namespace controllers\internals;
|
|||
'name' => $name,
|
||||
'condition' => $condition,
|
||||
];
|
||||
|
||||
if (!$this->validate_condition($condition))
|
||||
|
||||
$internal_ruler = new Ruler();
|
||||
$valid_condition = $internal_ruler->validate_condition($condition, ['contact' => (object) ['datas' => (object) null]]);
|
||||
if (!$valid_condition)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -102,11 +106,39 @@ namespace controllers\internals;
|
|||
|
||||
|
||||
/**
|
||||
* Verify if a condition string is valid (i.e we can parse it without error)
|
||||
* Gets the user's contacts that respects a condition
|
||||
* @param int $id_user : User id
|
||||
* @param string $condition : Condition string to verify
|
||||
* @return bool
|
||||
*/
|
||||
public function validate_condition (string $condition) : bool
|
||||
public function get_contacts_for_condition_and_user (int $id_user, string $condition) : bool
|
||||
{
|
||||
$internal_contacts = new Contacts($this->bdd);
|
||||
$contacts = $internal_contacts->gets_for_user($id_user);
|
||||
|
||||
$ruler = new Ruler();
|
||||
|
||||
foreach ($contacts as $key => $contact)
|
||||
{
|
||||
if ($contact['datas'] != null)
|
||||
{
|
||||
$contact['datas'] = json_decode($contact['datas']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$contact['datas'] = new \stdClass();
|
||||
}
|
||||
|
||||
$contact = (object) $contact;
|
||||
|
||||
$datas = ['contact' => $contact];
|
||||
$is_valid = $ruler->evaluate_condition($condition, $datas);
|
||||
if (!$is_valid)
|
||||
{
|
||||
unset($contacts[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $contacts;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace controllers\internals;
|
|||
* @param string $datas : Contact datas
|
||||
* @return mixed bool|int : False if cannot create contact, id of the new contact else
|
||||
*/
|
||||
public function create($id_user, $number, $name, $datas)
|
||||
public function create($id_user, $number, $name, ?string $datas = null)
|
||||
{
|
||||
$contact = [
|
||||
'id_user' => $id_user,
|
||||
|
|
21
controllers/internals/ExpressionProvider.php
Normal file
21
controllers/internals/ExpressionProvider.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace controllers\internals;
|
||||
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
|
||||
|
||||
class ExpressionProvider implements ExpressionFunctionProviderInterface
|
||||
{
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
ExpressionFunction::fromPhp('is_null', 'exists'),
|
||||
ExpressionFunction::fromPhp('mb_strtolower', 'lower'),
|
||||
ExpressionFunction::fromPhp('mb_strtoupper', 'upper'),
|
||||
ExpressionFunction::fromPhp('mb_substr', 'substr'),
|
||||
ExpressionFunction::fromPhp('abs', 'abs'),
|
||||
ExpressionFunction::fromPhp('strtotime', 'date'),
|
||||
];
|
||||
}
|
||||
}
|
75
controllers/internals/Ruler.php
Executable file
75
controllers/internals/Ruler.php
Executable file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of RaspiSMS.
|
||||
*
|
||||
* (c) Pierre-Lin Bonnemaison <plebwebsas@gmail.com>
|
||||
*
|
||||
* This source file is subject to the GPL-3.0 license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace controllers\internals;
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
|
||||
|
||||
/**
|
||||
* Class to analyse rules used by conditional groups
|
||||
*/
|
||||
class Ruler extends \descartes\InternalController
|
||||
{
|
||||
private $expression_language;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct ()
|
||||
{
|
||||
$this->expression_language = new ExpressionLanguage();
|
||||
|
||||
//Add custom functions
|
||||
$this->expression_language->registerProvider(new ExpressionProvider());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify if a condition is valid. i.e we can evaluate it without error.
|
||||
* @param string $condition : The condition to evaluate.
|
||||
* @param array $datas : The datas to made available to condition
|
||||
* @return bool : false if invalid, true else
|
||||
*/
|
||||
public function validate_condition (string $condition, array $datas = []) : bool
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->expression_language->evaluate($condition, $datas);
|
||||
return true;
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
echo "Error : ";
|
||||
echo $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Evaluate a condition
|
||||
* @param string $condition : The condition to evaluate.
|
||||
* @param array $datas : The datas to made available to condition
|
||||
* @return ?bool : false if invalid, true else, null only on error
|
||||
*/
|
||||
public function evaluate_condition (string $condition, array $datas = []) : ?bool
|
||||
{
|
||||
try
|
||||
{
|
||||
$result = $this->expression_language->evaluate($condition, $datas);
|
||||
return (bool) $result;
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
181
controllers/publics/ConditionalGroup.php
Executable file
181
controllers/publics/ConditionalGroup.php
Executable file
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of RaspiSMS.
|
||||
*
|
||||
* (c) Pierre-Lin Bonnemaison <plebwebsas@gmail.com>
|
||||
*
|
||||
* This source file is subject to the GPL-3.0 license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace controllers\publics;
|
||||
|
||||
/**
|
||||
* Page des groups.
|
||||
*/
|
||||
class ConditionalGroup extends \descartes\Controller
|
||||
{
|
||||
private $internal_conditional_group;
|
||||
private $internal_contact;
|
||||
private $internal_ruler;
|
||||
private $internal_event;
|
||||
|
||||
/**
|
||||
* Cette fonction est appelée avant toute les autres :
|
||||
* Elle vérifie que l'utilisateur est bien connecté.
|
||||
*
|
||||
* @return void;
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$bdd = \descartes\Model::_connect(DATABASE_HOST, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD);
|
||||
|
||||
$this->internal_conditional_group = new \controllers\internals\ConditionalGroup($bdd);
|
||||
$this->internal_contact = new \controllers\internals\Contact($bdd);
|
||||
$this->internal_event = new \controllers\internals\Event($bdd);
|
||||
$this->internal_ruler = new \controllers\internals\Ruler($bdd);
|
||||
|
||||
\controllers\internals\Tool::verifyconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all conditionnals groups for administration
|
||||
*
|
||||
* @param mixed $page
|
||||
*/
|
||||
public function list($page = 0)
|
||||
{
|
||||
$page = (int) $page;
|
||||
|
||||
|
||||
$groups = $this->internal_conditional_group->list_for_user($_SESSION['user']['id'], 25, $page);
|
||||
$this->render('conditional_group/list', ['groups' => $groups]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cette fonction va supprimer une liste de groups.
|
||||
*
|
||||
* @param array int $_GET['ids'] : Les id des groups à supprimer
|
||||
* @param mixed $csrf
|
||||
*
|
||||
* @return boolean;
|
||||
*/
|
||||
public function delete($csrf)
|
||||
{
|
||||
if (!$this->verify_csrf($csrf))
|
||||
{
|
||||
\FlashMessage\FlashMessage::push('danger', 'Jeton CSRF invalid !');
|
||||
|
||||
return $this->redirect(\descartes\Router::url('ConditionalGroup', 'list'));
|
||||
}
|
||||
|
||||
$ids = $_GET['ids'] ?? [];
|
||||
foreach ($ids as $id)
|
||||
{
|
||||
$this->internal_conditional_group->delete_for_user($_SESSION['user']['id'], $id);
|
||||
}
|
||||
|
||||
return $this->redirect(\descartes\Router::url('ConditionalGroup', 'list'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cette fonction retourne la page d'ajout d'un group.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->render('conditional_group/add');
|
||||
}
|
||||
|
||||
/**
|
||||
* Cette fonction retourne la page d'édition des groups.
|
||||
*
|
||||
* @param int... $ids : Les id des groups à supprimer
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$ids = $_GET['ids'] ?? [];
|
||||
|
||||
$groups = $this->internal_conditional_group->gets_in_for_user($_SESSION['user']['id'], $ids);
|
||||
|
||||
$this->render('conditional_group/edit', [
|
||||
'groups' => $groups,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cette fonction insert un nouveau group.
|
||||
*
|
||||
* @param $csrf : Le jeton CSRF
|
||||
* @param string $_POST['name'] : Le nom du group
|
||||
* @param array $_POST['condition'] : The condition to used
|
||||
*/
|
||||
public function create($csrf)
|
||||
{
|
||||
if (!$this->verify_csrf($csrf))
|
||||
{
|
||||
\FlashMessage\FlashMessage::push('danger', 'Jeton CSRF invalid !');
|
||||
|
||||
return $this->redirect(\descartes\Router::url('ConditionalGroup', 'add'));
|
||||
}
|
||||
|
||||
$name = $_POST['name'] ?? false;
|
||||
$condition = $_POST['condition'] ?? false;
|
||||
|
||||
if (!$name || !$condition)
|
||||
{
|
||||
\FlashMessage\FlashMessage::push('danger', 'Des champs sont manquants !');
|
||||
|
||||
return $this->redirect(\descartes\Router::url('ConditionalGroup', 'add'));
|
||||
}
|
||||
|
||||
$id_group = $this->internal_conditional_group->create($_SESSION['user']['id'], $name, $condition);
|
||||
if (!$id_group)
|
||||
{
|
||||
\FlashMessage\FlashMessage::push('danger', 'Impossible de créer ce groupe.');
|
||||
|
||||
return $this->redirect(\descartes\Router::url('ConditionalGroup', 'add'));
|
||||
}
|
||||
|
||||
\FlashMessage\FlashMessage::push('success', 'Le groupe a bien été créé.');
|
||||
|
||||
return $this->redirect(\descartes\Router::url('ConditionalGroup', 'list'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cette fonction met à jour une group.
|
||||
*
|
||||
* @param $csrf : Le jeton CSRF
|
||||
* @param array $_POST['groups'] : Un tableau des groups avec leur nouvelle valeurs & une entrée 'contacts_id' avec les ids des contacts pour chaque group
|
||||
*
|
||||
* @return boolean;
|
||||
*/
|
||||
public function update($csrf)
|
||||
{
|
||||
if (!$this->verify_csrf($csrf))
|
||||
{
|
||||
\FlashMessage\FlashMessage::push('danger', 'Jeton CSRF invalid !');
|
||||
|
||||
return $this->redirect(\descartes\Router::url('ConditionalGroup', 'list'));
|
||||
}
|
||||
|
||||
$groups = $_POST['groups'] ?? [];
|
||||
|
||||
$nb_groups_update = 0;
|
||||
foreach ($groups as $id => $group)
|
||||
{
|
||||
$nb_groups_update += (int) $this->internal_conditional_group->update_for_user($_SESSION['user']['id'], $id, $group['name'], $group['condition']);
|
||||
}
|
||||
|
||||
if ($nb_groups_update !== \count($groups))
|
||||
{
|
||||
\FlashMessage\FlashMessage::push('danger', 'Certains groupes n\'ont pas pu êtres mis à jour.');
|
||||
|
||||
return $this->redirect(\descartes\Router::url('ConditionalGroup', 'list'));
|
||||
}
|
||||
|
||||
\FlashMessage\FlashMessage::push('success', 'Tous les groupes ont été modifiés avec succès.');
|
||||
|
||||
return $this->redirect(\descartes\Router::url('ConditionalGroup', 'list'));
|
||||
}
|
||||
}
|
|
@ -131,7 +131,7 @@ namespace controllers\publics;
|
|||
$name = $_POST['name'] ?? false;
|
||||
$number = $_POST['number'] ?? false;
|
||||
$id_user = $_SESSION['user']['id'];
|
||||
$datas = empty($_POST['datas']) ? null : $_POST['datas'];
|
||||
$datas = $_POST['datas'] ?? [];
|
||||
|
||||
if (!$name || !$number)
|
||||
{
|
||||
|
@ -162,7 +162,11 @@ namespace controllers\publics;
|
|||
$key = mb_ereg_replace('[\W]', '', $key);
|
||||
$clean_datas[$key] = (string) $value;
|
||||
}
|
||||
|
||||
}
|
||||
$clean_datas = $clean_datas ?: null;
|
||||
|
||||
if ($clean_datas)
|
||||
{
|
||||
$clean_datas = json_encode($clean_datas);
|
||||
}
|
||||
|
||||
|
@ -206,7 +210,7 @@ namespace controllers\publics;
|
|||
$name = $contact['name'] ?? false;
|
||||
$number = $contact['number'] ?? false;
|
||||
$id_user = $_SESSION['user']['id'];
|
||||
$datas = empty($contact['datas']) ? null : $contact['datas'];
|
||||
$datas = $contact['datas'] ?? null;
|
||||
|
||||
if (!$name || !$number)
|
||||
{
|
||||
|
@ -218,7 +222,7 @@ namespace controllers\publics;
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$clean_datas = null;
|
||||
if ($datas)
|
||||
{
|
||||
|
@ -233,9 +237,14 @@ namespace controllers\publics;
|
|||
$key = mb_ereg_replace('[\W]', '', $key);
|
||||
$clean_datas[$key] = (string) $value;
|
||||
}
|
||||
|
||||
}
|
||||
$clean_datas = $clean_datas ?: null;
|
||||
|
||||
if ($clean_datas)
|
||||
{
|
||||
$clean_datas = json_encode($clean_datas);
|
||||
}
|
||||
|
||||
|
||||
$nb_contacts_update += (int) $this->internal_contact->update_for_user($id_user, $id_contact, $number, $name, $clean_datas);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue