From 298bba0c39d16c367ff261a6ca818840dbeac8cd Mon Sep 17 00:00:00 2001 From: osaajani <> Date: Thu, 2 Feb 2023 01:12:30 +0100 Subject: [PATCH] Add phone limit creation to phone creation --- assets/css/style.css | 15 ++++-- controllers/internals/Phone.php | 37 ++++++++++--- controllers/internals/Tool.php | 18 +++++++ controllers/publics/Api.php | 4 +- controllers/publics/Phone.php | 37 +++++++++++-- .../20230201152658_add_phone_limits.php | 43 +++++++++++++++ models/Phone.php | 44 ++++++++++++++- templates/phone/add.php | 54 ++++++++++++++++++- 8 files changed, 231 insertions(+), 21 deletions(-) create mode 100644 db/migrations/20230201152658_add_phone_limits.php diff --git a/assets/css/style.css b/assets/css/style.css index ea2f87d..7bff7cb 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -311,7 +311,8 @@ footer img } /* SCHEDULEDS */ -.add-number-button +.add-number-button, +.add-phone-limit-button { display: inline-block; color: #DADFE1; @@ -319,7 +320,8 @@ footer img vertical-align: top; } -.add-number-button:hover +.add-number-button:hover, +.add-phone-limit-button:hover { color: #3498DB; cursor: pointer; @@ -373,7 +375,8 @@ footer img text-align: right; } -.scheduleds-number-groupe +.scheduleds-number-groupe, +.phone-limits-group { padding-top: 15px; padding-bottom: 15px; @@ -383,7 +386,8 @@ footer img position: relative; } -.scheduleds-number-groupe-remove +.scheduleds-number-groupe-remove, +.phone-limits-group-remove { position: absolute; top: 15px; @@ -391,7 +395,8 @@ footer img color: #888; } -.scheduleds-number-groupe-remove:hover +.scheduleds-number-groupe-remove:hover, +.phone-limits-group-remove:hover { color: #555; } diff --git a/controllers/internals/Phone.php b/controllers/internals/Phone.php index 0cf8354..f92df71 100644 --- a/controllers/internals/Phone.php +++ b/controllers/internals/Phone.php @@ -44,15 +44,15 @@ namespace controllers\internals; } /** - * Return a phone by his name. + * Return a list of phone limits * - * @param string $name : Phone name + * @param int $id_phone : Phone id * * @return array */ - public function get_by_name(string $name) + public function get_limits(int $id_phone) { - return $this->get_model()->get_by_name($name); + return $this->get_model()->get_limits($id_phone); } /** @@ -137,10 +137,11 @@ namespace controllers\internals; * @param string $name : The name of the phone * @param string $adapter : The adapter to use the phone * @param string json $adapter_data : A JSON string representing adapter's data (for example credentials for an api) + * @param array $limits : An array of limits for this phone. Each limit must be an array with a key volume and a key startpoint * * @return bool|int : false on error, new id on success */ - public function create(int $id_user, string $name, string $adapter, string $adapter_data) + public function create(int $id_user, string $name, string $adapter, string $adapter_data, array $limits = []) { $phone = [ 'id_user' => $id_user, @@ -149,7 +150,31 @@ namespace controllers\internals; 'adapter_data' => $adapter_data, ]; - return $this->get_model()->insert($phone); + //Use transaction to garanty atomicity + $this->bdd->beginTransaction(); + + $new_phone_id = $this->get_model()->insert($phone); + if (!$new_phone_id) + { + $this->bdd->rollBack(); + + return false; + } + + foreach ($limits as $limit) + { + $limit_id = $this->get_model()->insert_phone_limit($new_phone_id, $limit['volume'], $limit['startpoint']); + + if (!$limit_id) + { + $this->bdd->rollBack(); + + return false; + } + } + + $success = $this->bdd->commit(); + return ($success ? $new_phone_id : false); } /** diff --git a/controllers/internals/Tool.php b/controllers/internals/Tool.php index e6b8994..fef0375 100644 --- a/controllers/internals/Tool.php +++ b/controllers/internals/Tool.php @@ -165,6 +165,24 @@ namespace controllers\internals; return $objectDate && $objectDate->format($format) === $date; } + /** + * Check if a relative format date (see https://www.php.net/manual/en/datetime.formats.relative.php) is valid. + * + * @param string $date : Relative date + * + * @return bool : True if valid, false else + */ + public static function validate_relative_date($date) + { + try { + $d = new \DateTime($date); + } catch (\Throwable $th) { + return false; + } + + return true; + } + /** * Check if a sting represent a valid PHP period for creating an interval. * diff --git a/controllers/publics/Api.php b/controllers/publics/Api.php index 92fb2ea..2010231 100644 --- a/controllers/publics/Api.php +++ b/controllers/publics/Api.php @@ -535,7 +535,7 @@ namespace controllers\publics; return $this->json($return); } - $name_exist = $this->internal_phone->get_by_name($name); + $name_exist = $this->internal_phone->get_by_name_and_user($this->user['id'], $name); if ($name_exist) { $return['error'] = self::ERROR_CODES['INVALID_PARAMETER']; @@ -683,7 +683,7 @@ namespace controllers\publics; } - $phone_with_same_name = $this->internal_phone->get_by_name($name); + $phone_with_same_name = $this->internal_phone->get_by_name_and_user($this->user['id'], $name); if ($phone_with_same_name && $phone_with_same_name['id'] != $phone['id']) { $return['error'] = self::ERROR_CODES['INVALID_PARAMETER']; diff --git a/controllers/publics/Phone.php b/controllers/publics/Phone.php index 14028ea..52e8753 100644 --- a/controllers/publics/Phone.php +++ b/controllers/publics/Phone.php @@ -131,9 +131,10 @@ class Phone extends \descartes\Controller * Create a new phone. * * @param $csrf : CSRF token - * @param string $_POST['name'] : Phone name - * @param string $_POST['adapter'] : Phone adapter - * @param array $_POST['adapter_data'] : Phone adapter data + * @param string $_POST['name'] : Phone name + * @param string $_POST['adapter'] : Phone adapter + * @param ?array $_POST['adapter_data'] : Phone adapter data + * @param ?array $_POST['limits'] : Limits in number of SMS for a period to be applied to this phone. */ public function create($csrf) { @@ -148,6 +149,8 @@ class Phone extends \descartes\Controller $name = $_POST['name'] ?? false; $adapter = $_POST['adapter'] ?? false; $adapter_data = !empty($_POST['adapter_data']) ? $_POST['adapter_data'] : []; + $limits = $_POST['limits'] ?? []; + $limits = is_array($limits) ? $limits : [$limits]; if (!$name || !$adapter) { @@ -156,7 +159,7 @@ class Phone extends \descartes\Controller return $this->redirect(\descartes\Router::url('Phone', 'add')); } - $name_exist = $this->internal_phone->get_by_name($name); + $name_exist = $this->internal_phone->get_by_name_and_user($id_user, $name); if ($name_exist) { \FlashMessage\FlashMessage::push('danger', 'Ce nom est déjà utilisé pour un autre téléphone.'); @@ -164,6 +167,30 @@ class Phone extends \descartes\Controller return $this->redirect(\descartes\Router::url('Phone', 'add')); } + if ($limits) + { + foreach ($limits as $key => $limit) + { + $startpoint = $limit['startpoint'] ?? false; + $volume = $limit['volume'] ?? false; + + if (!$startpoint || !$volume) + { + unset($limits[$key]); + continue; + } + + $volume = (int) $volume; + $limits[$key]['volume'] = max($volume, 1); + + if (!\controllers\internals\Tool::validate_relative_date($startpoint)) + { + unset($limits[$key]); + continue; + } + } + } + $adapters = $this->internal_adapter->list_adapters(); $find_adapter = false; foreach ($adapters as $metas) @@ -245,7 +272,7 @@ class Phone extends \descartes\Controller return $this->redirect(\descartes\Router::url('Phone', 'add')); } - $success = $this->internal_phone->create($id_user, $name, $adapter, $adapter_data); + $success = $this->internal_phone->create($id_user, $name, $adapter, $adapter_data, $limits); if (!$success) { \FlashMessage\FlashMessage::push('danger', 'Impossible de créer ce téléphone.'); diff --git a/db/migrations/20230201152658_add_phone_limits.php b/db/migrations/20230201152658_add_phone_limits.php new file mode 100644 index 0000000..debf233 --- /dev/null +++ b/db/migrations/20230201152658_add_phone_limits.php @@ -0,0 +1,43 @@ +table('phone_limit'); + $table->addColumn('id_phone', 'integer', ['null' => false]) + ->addColumn('volume', 'integer', ['null' => false]) + ->addColumn('startpoint', 'string', ['null' => false, 'limit' => 254]) # A relative time to use as startpoint for counting volume. See https://www.php.net/manual/en/datetime.formats.relative.php + ->addColumn('created_at', 'timestamp', ['null' => false, 'default' => 'CURRENT_TIMESTAMP']) + ->addColumn('updated_at', 'timestamp', ['null' => true, 'update' => 'CURRENT_TIMESTAMP']) + ->addForeignKey('id_phone', 'phone', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) + ->create(); + } +} diff --git a/models/Phone.php b/models/Phone.php index 14447f4..4579b22 100644 --- a/models/Phone.php +++ b/models/Phone.php @@ -15,7 +15,7 @@ namespace models; { /** - * Return all hones that belongs to active users + * Return all phones that belongs to active users * * @return array */ @@ -63,6 +63,48 @@ namespace models; return $this->_select_one('phone', ['name' => $name]); } + + /** + * Return a list of phone limits + * + * @param int $id_phone : Phone id + * + * @return array + */ + public function get_limits(int $id_phone) + { + return $this->_select('phone_limit', ['id_phone' => $id_phone]); + } + + /** + * Add a limit for a phone. + * + * @param int $id_phone : Phone id + * @param int $volume : Limit in volume of SMS + * @param string $startpoint : A relative time to use as startpoint for counting volume. See https://www.php.net/manual/en/datetime.formats.relative.php + * + * @return mixed (bool|int) : False on error, new row id else + */ + public function insert_phone_limit(int $id_phone, int $volume, string $startpoint) + { + $success = $this->_insert('phone_limit', ['id_phone' => $id_phone, 'volume' => $volume, 'startpoint' => $startpoint]); + + return $success ? $this->_last_id() : false; + } + + /** + * Delete limits for a phone + * + * @param array $id_phone : Phone id + * + * @return array + */ + public function delete_phone_limits(int $id_phone) + { + return $this->_delete('phone_limit', ['id_phone' => $id_phone]); + } + + /** * Return table name. */ diff --git a/templates/phone/add.php b/templates/phone/add.php index f1e08c3..58a3550 100644 --- a/templates/phone/add.php +++ b/templates/phone/add.php @@ -48,7 +48,7 @@
- +

Le type de téléphone utilisé par RaspiSMS pour envoyer ou recevoir les SMS. Pour plus d'information, consultez la documentation de RaspiSMS concernant les différents types de téléphones.

@@ -67,7 +67,7 @@
-
+

Description du téléphone

@@ -77,6 +77,15 @@

Réglages du téléphone

+
+
+ +

+ Défini le nombre maximum de SMS qui pourront être envoyés avec ce téléphone sur des périodes de temps données. +

+
+
+
Annuler @@ -174,6 +183,47 @@ { change_adapter(); }); + + jQuery('body').on('click', '.phone-limits-group-remove', function (e) + { + e.preventDefault(); + jQuery(this).parent('.phone-limits-group').remove(); + return false; + }); + + jQuery('body').on('click', '.add-phone-limit-button', function(e) + { + var random_id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); + var newLimit = '' + + '
'+ + '
'+ + '
'+ + ''+ + '
'+ + '
'+ + ''+ + '
'+ + ''+ + '
'+ + '
'+ + ''+ + '
'; + + jQuery(this).parent('div').before(newLimit); + }); });