diff --git a/adapters/AdapterInterface.php b/adapters/AdapterInterface.php index c967bb2..3a0dc85 100644 --- a/adapters/AdapterInterface.php +++ b/adapters/AdapterInterface.php @@ -119,9 +119,9 @@ interface AdapterInterface * @param array $medias : Array of medias to link to the MMS, [['http_url' => HTTP public url of the media et 'local_uri' => local uri to media file]] * * @return array : [ - * bool 'error' => false if no error, true else, - * ?string 'error_message' => null if no error, else error message, - * array 'uid' => Uid of the sms created on success, + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * array 'uid' => Uid of the sms created on success * ] */ public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []): array; diff --git a/assets/css/style.css b/assets/css/style.css index 204950f..ea2f87d 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -311,8 +311,7 @@ footer img } /* SCHEDULEDS */ -.add-number-button, -.add-phone-limit-button +.add-number-button { display: inline-block; color: #DADFE1; @@ -320,8 +319,7 @@ footer img vertical-align: top; } -.add-number-button:hover, -.add-phone-limit-button:hover +.add-number-button:hover { color: #3498DB; cursor: pointer; @@ -375,8 +373,7 @@ footer img text-align: right; } -.scheduleds-number-groupe, -.phone-limits-group +.scheduleds-number-groupe { padding-top: 15px; padding-bottom: 15px; @@ -386,8 +383,7 @@ footer img position: relative; } -.scheduleds-number-groupe-remove, -.phone-limits-group-remove +.scheduleds-number-groupe-remove { position: absolute; top: 15px; @@ -395,8 +391,7 @@ footer img color: #888; } -.scheduleds-number-groupe-remove:hover, -.phone-limits-group-remove:hover +.scheduleds-number-groupe-remove:hover { color: #555; } @@ -471,16 +466,6 @@ footer img color: #9b2420; } -/* PREVIEW CONTACT */ -.preview-contact-name -{ - font-weight: bold; -} - -.preview-contact-number -{ - font-style: italic; -} /* PHONE */ #adapter-data-container diff --git a/composer.json b/composer.json index 403cedf..935f689 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,8 @@ "symfony/yaml": "^5.0", "phpmailer/phpmailer": "^6.1", "xantios/mimey": ">=2.1", - "kreait/firebase-php": "^5.14", - "benmorel/gsm-charset-converter": "^0.3.0" + "kreait/firebase-php": "^5.14" + }, + "require-dev": { } } diff --git a/controllers/internals/Event.php b/controllers/internals/Event.php index 003fc8d..29f76cb 100644 --- a/controllers/internals/Event.php +++ b/controllers/internals/Event.php @@ -73,6 +73,21 @@ namespace controllers\internals; return $this->get_model()->insert($event); } + /** + * Gets events for a type, since a date and eventually until a date (both included). + * + * @param int $id_user : User id + * @param string $type : Event type we want + * @param \DateTime $since : Date to get events since + * @param ?\DateTime $until (optional) : Date until wich we want events, if not specified no limit + * + * @return array + */ + public function get_events_by_type_and_date_for_user(int $id_user, string $type, \DateTime $since, ?\DateTime $until = null) + { + $this->get_model()->get_events_by_type_and_date_for_user($id_user, $type, $since, $until); + } + /** * Get the model for the Controller. */ diff --git a/controllers/internals/ExpressionProvider.php b/controllers/internals/ExpressionProvider.php index b26ff41..9d056ab 100644 --- a/controllers/internals/ExpressionProvider.php +++ b/controllers/internals/ExpressionProvider.php @@ -44,6 +44,11 @@ class ExpressionProvider implements ExpressionFunctionProviderInterface return sprintf('isset(%1$s) && is_a(%1$s, \'DateTime\') && %1$s->format(\'m-d\') == (new \\DateTime())->format(\'m-d\')', $birthdate); }, function ($arguments, DateTime $birthdate) { + if (!($birthdate ?? false)) + { + return false; + } + return $birthdate->format('m-d') == (new DateTime())->format('m-d'); }); diff --git a/controllers/internals/Phone.php b/controllers/internals/Phone.php index 9bdeac7..0cf8354 100644 --- a/controllers/internals/Phone.php +++ b/controllers/internals/Phone.php @@ -44,15 +44,15 @@ namespace controllers\internals; } /** - * Return a list of phone limits + * Return a phone by his name. * - * @param int $id_phone : Phone id + * @param string $name : Phone name * * @return array */ - public function get_limits(int $id_phone) + public function get_by_name(string $name) { - return $this->get_model()->get_limits($id_phone); + return $this->get_model()->get_by_name($name); } /** @@ -137,46 +137,19 @@ 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 int $priority : Priority with which to use phone to send SMS. Default 0. - * @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, int $priority = 0, array $limits = []) + public function create(int $id_user, string $name, string $adapter, string $adapter_data) { $phone = [ 'id_user' => $id_user, 'name' => $name, - 'priority' => $priority, 'adapter' => $adapter, 'adapter_data' => $adapter_data, ]; - //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); + return $this->get_model()->insert($phone); } /** @@ -186,54 +159,20 @@ namespace controllers\internals; * @param int $id : Phone id * @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 int $priority : Priority with which to use phone to send SMS. Default 0. - * @param array $limits : An array of limits for this phone. Each limit must be an array with a key volume and a key startpoint + * @param array $adapter_data : An array of the data of the adapter (for example credentials for an api) * * @return bool : false on error, true on success */ - public function update_for_user(int $id_user, int $id, string $name, string $adapter, string $adapter_data, int $priority = 0, array $limits = []): bool + public function update_for_user(int $id_user, int $id, string $name, string $adapter, array $adapter_data): bool { $phone = [ 'id_user' => $id_user, 'name' => $name, 'adapter' => $adapter, - 'adapter_data' => $adapter_data, - 'priority' => $priority, + 'adapter_data' => json_encode($adapter_data), ]; - //Use transaction to garanty atomicity - $this->bdd->beginTransaction(); - - $nb_delete = $this->get_model()->delete_phone_limits($id); - - foreach ($limits as $limit) - { - $limit_id = $this->get_model()->insert_phone_limit($id, $limit['volume'], $limit['startpoint']); - - if (!$limit_id) - { - $this->bdd->rollBack(); - - return false; - } - } - - $nb_update = $this->get_model()->update_for_user($id_user, $id, $phone); - - $success = $this->bdd->commit(); - - if (!$success) - { - return false; - } - - if ($nb_update == 0 && count($limits) == 0) - { - return false; - } - - return true; + return (bool) $this->get_model()->update_for_user($id_user, $id, $phone); } /** diff --git a/controllers/internals/Scheduled.php b/controllers/internals/Scheduled.php index 4f0c3f7..25ce51e 100644 --- a/controllers/internals/Scheduled.php +++ b/controllers/internals/Scheduled.php @@ -274,6 +274,236 @@ use Monolog\Logger; return $this->get_model()->gets_after_date_for_number_and_user($id_user, $date, $number); } + /** + * Get all messages to send and the number to use to send theme. + * + * @return array : List of smss to send at this time per scheduled id ['1' => [['id_scheduled', 'text', 'id_phone', 'destination', 'flash', 'mms', 'medias'], ...], ...] + */ + public function get_smss_to_send() + { + $smss_to_send_per_scheduled = []; + + $internal_templating = new \controllers\internals\Templating(); + $internal_setting = new \controllers\internals\Setting($this->bdd); + $internal_group = new \controllers\internals\Group($this->bdd); + $internal_conditional_group = new \controllers\internals\ConditionalGroup($this->bdd); + $internal_phone = new \controllers\internals\Phone($this->bdd); + $internal_smsstop = new \controllers\internals\SmsStop($this->bdd); + + $users_smsstops = []; + $users_settings = []; + $users_phones = []; + $users_mms_phones = []; + + $now = new \DateTime(); + $now = $now->format('Y-m-d H:i:s'); + $scheduleds = $this->get_model()->gets_before_date($now); + foreach ($scheduleds as $scheduled) + { + $smss_to_send_per_scheduled[$scheduled['id']] = []; + + if (!isset($users_settings[$scheduled['id_user']])) + { + $users_settings[$scheduled['id_user']] = []; + + $settings = $internal_setting->gets_for_user($scheduled['id_user']); + foreach ($settings as $name => $value) + { + $users_settings[$scheduled['id_user']][$name] = $value; + } + } + + if (!isset($users_smsstops[$scheduled['id_user']]) && $users_settings[$scheduled['id_user']]['smsstop']) + { + $users_smsstops[$scheduled['id_user']] = []; + + $smsstops = $internal_smsstop->gets_for_user($scheduled['id_user']); + foreach ($smsstops as $smsstop) + { + $users_smsstops[$scheduled['id_user']][] = $smsstop['number']; + } + } + + if (!isset($users_phones[$scheduled['id_user']])) + { + $phones = $internal_phone->gets_for_user($scheduled['id_user']); + $mms_phones = $internal_phone->gets_phone_supporting_mms_for_user($scheduled['id_user'], $internal_phone::MMS_SENDING); + $users_phones[$scheduled['id_user']] = $phones ?: []; + $users_mms_phones[$scheduled['id_user']] = $mms_phones ?: []; + } + + //Add medias to mms + $scheduled['medias'] = []; + if ($scheduled['mms']) + { + $internal_media = new Media($this->bdd); + $scheduled['medias'] = $internal_media->gets_for_scheduled($scheduled['id']); + } + + $phone_to_use = null; + foreach ($users_phones[$scheduled['id_user']] as $phone) + { + if ($phone['id'] !== $scheduled['id_phone']) + { + continue; + } + + $phone_to_use = $phone; + } + + $messages = []; + + //Add messages for numbers + $numbers = $this->get_numbers($scheduled['id']); + foreach ($numbers as $number) + { + if (null === $phone_to_use) + { + if ($scheduled['mms'] && count($users_mms_phones)) + { + $rnd_key = array_rand($users_mms_phones[$scheduled['id_user']]); + $random_phone = $users_mms_phones[$scheduled['id_user']][$rnd_key]; + } + else + { + $rnd_key = array_rand($users_phones[$scheduled['id_user']]); + $random_phone = $users_phones[$scheduled['id_user']][$rnd_key]; + } + } + + $message = [ + 'id_user' => $scheduled['id_user'], + 'id_scheduled' => $scheduled['id'], + 'id_phone' => $phone_to_use['id'] ?? $random_phone['id'], + 'destination' => $number['number'], + 'flash' => $scheduled['flash'], + 'mms' => $scheduled['mms'], + 'medias' => $scheduled['medias'], + ]; + + if ((int) ($users_settings[$scheduled['id_user']]['templating'] ?? false)) + { + $number['data'] = json_decode($number['data'] ?? '[]', true); + + $metas = ['number' => $number['number']]; + $data = ['contact' => $number['data'], 'contact_metas' => $metas]; + + $render = $internal_templating->render($scheduled['text'], $data); + + if (!$render['success']) + { + continue; + } + + $message['text'] = $render['result']; + } + else + { + $message['text'] = $scheduled['text']; + } + + $messages[] = $message; + } + + //Add messages for contacts + $contacts = $this->get_contacts($scheduled['id']); + + $groups = $this->get_groups($scheduled['id']); + foreach ($groups as $group) + { + $contacts_to_add = $internal_group->get_contacts($group['id']); + $contacts = array_merge($contacts, $contacts_to_add); + } + + $conditional_groups = $this->get_conditional_groups($scheduled['id']); + foreach ($conditional_groups as $conditional_group) + { + $contacts_to_add = $internal_conditional_group->get_contacts_for_condition_and_user($scheduled['id_user'], $conditional_group['condition']); + $contacts = array_merge($contacts, $contacts_to_add); + } + + $added_contacts = []; + foreach ($contacts as $contact) + { + if ($added_contacts[$contact['id']] ?? false) + { + continue; + } + + $added_contacts[$contact['id']] = true; + + if (null === $phone_to_use) + { + if ($scheduled['mms'] && count($users_mms_phones)) + { + $rnd_key = array_rand($users_mms_phones[$scheduled['id_user']]); + $random_phone = $users_mms_phones[$scheduled['id_user']][$rnd_key]; + } + else + { + $rnd_key = array_rand($users_phones[$scheduled['id_user']]); + $random_phone = $users_phones[$scheduled['id_user']][$rnd_key]; + } + } + + $message = [ + 'id_user' => $scheduled['id_user'], + 'id_scheduled' => $scheduled['id'], + 'id_phone' => $phone_to_use['id'] ?? $random_phone['id'], + 'destination' => $contact['number'], + 'flash' => $scheduled['flash'], + 'mms' => $scheduled['mms'], + 'medias' => $scheduled['medias'], + ]; + + if ((int) ($users_settings[$scheduled['id_user']]['templating'] ?? false)) + { + $contact['data'] = json_decode($contact['data'], true); + + //Add metas of contact by adding contact without data + $metas = $contact; + unset($metas['data'], $metas['id_user']); + + $data = ['contact' => $contact['data'], 'contact_metas' => $metas]; + + $render = $internal_templating->render($scheduled['text'], $data); + + if (!$render['success']) + { + continue; + } + + $message['text'] = $render['result']; + } + else + { + $message['text'] = $scheduled['text']; + } + + $messages[] = $message; + } + + foreach ($messages as $message) + { + //Remove empty messages + if ('' === trim($message['text']) && !$message['medias']) + { + continue; + } + + //Remove messages to smsstops numbers + if (($users_smsstops[$scheduled['id_user']] ?? false) && in_array($message['destination'], $users_smsstops[$scheduled['id_user']])) + { + continue; + } + + $smss_to_send_per_scheduled[$scheduled['id']][] = $message; + } + } + + return $smss_to_send_per_scheduled; + } + /** * Parse a CSV file of numbers, potentially associated with datas. * @@ -397,292 +627,4 @@ use Monolog\Logger; return $this->model; } - - - /** - * Get all messages to send and the number to use to send theme. - * - * @return array : List of smss to send at this time per scheduled id ['1' => [['id_scheduled', 'text', 'id_phone', 'destination', 'flash', 'mms', 'medias'], ...], ...] - */ - public function get_smss_to_send() - { - $sms_per_scheduled = []; - - $internal_templating = new \controllers\internals\Templating(); - $internal_setting = new \controllers\internals\Setting($this->bdd); - $internal_group = new \controllers\internals\Group($this->bdd); - $internal_conditional_group = new \controllers\internals\ConditionalGroup($this->bdd); - $internal_phone = new \controllers\internals\Phone($this->bdd); - $internal_smsstop = new \controllers\internals\SmsStop($this->bdd); - $internal_sended = new \controllers\internals\Sended($this->bdd); - - $users_smsstops = []; - $users_settings = []; - $users_phones = []; - $users_mms_phones = []; - - $now = new \DateTime(); - $now = $now->format('Y-m-d H:i:s'); - $scheduleds = $this->get_model()->gets_before_date($now); - foreach ($scheduleds as $scheduled) - { - $id_scheduled = $scheduled['id']; - $id_user = $scheduled['id_user']; - - $sms_per_scheduled[$id_scheduled] = []; - - // Forge cache of data about users, sms stops, phones, etc. - if (!isset($users_settings[$id_user])) - { - $users_settings[$id_user] = []; - - $settings = $internal_setting->gets_for_user($id_user); - foreach ($settings as $name => $value) - { - $users_settings[$id_user][$name] = $value; - } - } - - if (!isset($users_smsstops[$id_user]) && $users_settings[$id_user]['smsstop']) - { - $users_smsstops[$id_user] = []; - - $smsstops = $internal_smsstop->gets_for_user($id_user); - foreach ($smsstops as $smsstop) - { - $users_smsstops[$id_user][] = $smsstop['number']; - } - } - - if (!isset($users_phones[$id_user])) - { - $users_phones[$id_user] = []; - $users_mms_phones[$id_user] = []; - - $phones = $internal_phone->gets_for_user($id_user); - foreach ($phones as &$phone) - { - $limits = $internal_phone->get_limits($phone['id']); - - $remaining_volume = PHP_INT_MAX; - foreach ($limits as $limit) - { - $startpoint = new \DateTime($limit['startpoint']); - $consumed = $internal_sended->count_since_for_phone_and_user($id_user, $phone['id'], $startpoint); - $remaining_volume = min(($limit['volume'] - $consumed), $remaining_volume); - } - - $phone['remaining_volume'] = $remaining_volume; - $users_phones[$id_user][$phone['id']] = $phone; - } - - $mms_phones = $internal_phone->gets_phone_supporting_mms_for_user($id_user, $internal_phone::MMS_SENDING); - foreach ($mms_phones as &$mms_phone) - { - $limits = $internal_phone->get_limits($mms_phone['id']); - - $remaining_volume = PHP_INT_MAX; - foreach ($limits as $limit) - { - $startpoint = new \DateTime($limit['startpoint']); - $consumed = $internal_sended->count_since_for_phone_and_user($id_user, $mms_phone['id'], $startpoint); - $remaining_volume = min(($limit['volume'] - $consumed), $remaining_volume); - } - - $mms_phone['remaining_volume'] = $remaining_volume; - $users_mms_phones[$id_user][$mms_phone['id']] = $mms_phone; - } - } - - - //Add medias to mms - $scheduled['medias'] = []; - if ($scheduled['mms']) - { - $internal_media = new Media($this->bdd); - $scheduled['medias'] = $internal_media->gets_for_scheduled($id_scheduled); - } - - $phone_to_use = null; - if ($scheduled['id_phone']) - { - $phone_to_use = $users_phones[$id_user][$scheduled['id_phone']] ?? null; - } - - - // We turn all contacts, groups and conditional groups into just contacts - $contacts = $this->get_contacts($id_scheduled); - - $groups = $this->get_groups($id_scheduled); - foreach ($groups as $group) - { - $contacts_to_add = $internal_group->get_contacts($group['id']); - $contacts = array_merge($contacts, $contacts_to_add); - } - - $conditional_groups = $this->get_conditional_groups($id_scheduled); - foreach ($conditional_groups as $conditional_group) - { - $contacts_to_add = $internal_conditional_group->get_contacts_for_condition_and_user($id_user, $conditional_group['condition']); - $contacts = array_merge($contacts, $contacts_to_add); - } - - - // We turn all numbers and contacts into simple targets with number, data and meta so we can forge all messages from onlye one data source - $targets = []; - - $numbers = $this->get_numbers($id_scheduled); - foreach ($numbers as $number) - { - $metas = ['number' => $number['number']]; - $targets[] = [ - 'number' => $number['number'], - 'data' => $number['data'], - 'metas' => $metas, - ]; - } - - foreach ($contacts as $contact) - { - $metas = $contact; - unset($metas['data'], $metas['id_user']); - - $targets[] = [ - 'number' => $contact['number'], - 'data' => $contact['data'], - 'metas' => $metas, - ]; - } - - - // Pass on all targets to deduplicate destinations, remove number in sms stops, etc. - $used_destinations = []; - foreach ($targets as $key => $target) - { - if (in_array($target['number'], $used_destinations)) - { - unset($targets[$key]); - continue; - } - - //Remove messages to smsstops numbers - if (($users_smsstops[$id_user] ?? false) && in_array($target['number'], $users_smsstops[$id_user])) - { - continue; - } - - $used_destinations[] = $target['number']; - } - - - // Finally, we forge all messages and select phone to use - foreach ($targets as $target) - { - // Forge message if templating enable - $text = $scheduled['text']; - if ((int) ($users_settings[$id_user]['templating'] ?? false)) // Cast to int because it is more reliable than bool on strings - { - $target['data'] = json_decode($target['data'], true); - $data = ['contact' => $target['data'], 'contact_metas' => $target['metas']]; - - $render = $internal_templating->render($scheduled['text'], $data); - - if (!$render['success']) - { - continue; - } - - $text = $render['result']; - } - - // Ignore empty messages - if ('' === trim($text) && !$scheduled['medias']) - { - continue; - } - - // If we must force GSM 7 alphabet - if ((int) ($users_settings[$id_user]['force_gsm_alphabet'] ?? false)) - { - $text = Tool::convert_to_gsm0338($text); - } - - /* - Choose phone if no phone defined for message - Phones are choosen using type, priority and remaining volume : - 1 - If sms is a mms, try to use mms phone if any available. If mms phone available use mms phone, else use default. - 2 - In group of phones, keep only phones with remaining volume. If no phones with remaining volume, use all phones instead. - 3 - Groupe keeped phones by priority get group with biggest priority. - 4 - Get a random phone in this group. - 5 - If their is no phone matching, keep phone at null so sender will directly mark it as failed - */ - $random_phone = null; - if (null === $phone_to_use) - { - $phones_subset = $users_phones[$id_user]; - if ($scheduled['mms']) - { - $phones_subset = $users_mms_phones[$id_user] ?: $phones_subset; - } - - $remaining_volume_phones = array_filter($phones_subset, function ($phone) { - return $phone['remaining_volume'] > 0; - }); - $phones_subset = $remaining_volume_phones ?: $phones_subset; - - $max_priority_phones = []; - $max_priority = PHP_INT_MIN; - foreach ($phones_subset as $phone) - { - if ($phone['priority'] < $max_priority) - { - continue; - } - elseif ($phone['priority'] == $max_priority) - { - $max_priority_phones[] = $phone; - } - elseif ($phone['priority'] > $max_priority) - { - $max_priority_phones = [$phone]; - $max_priority = $phone['priority']; - } - } - - $phones_subset = $max_priority_phones; - if ($phones_subset) - { - $random_phone = $phones_subset[array_rand($phones_subset)]; - } - } - - // This should only happen if the user try to send a message without any phone in his account, then we simply ignore. - if (!$random_phone && !$phone_to_use) - { - continue; - } - - $id_phone = $phone_to_use['id'] ?? $random_phone['id']; - $sms_per_scheduled[$id_scheduled][] = [ - 'id_user' => $id_user, - 'id_scheduled' => $id_scheduled, - 'id_phone' => $id_phone, - 'destination' => $target['number'], - 'flash' => $scheduled['flash'], - 'mms' => $scheduled['mms'], - 'medias' => $scheduled['medias'], - 'text' => $text, - ]; - - // Consume one sms from remaining volume of phone, dont forget to do the same for the entry in mms phones - $users_phones[$id_user][$id_phone]['remaining_volume'] --; - if ($users_mms_phones[$id_user][$id_phone] ?? false) - { - $users_mms_phones[$id_user][$id_phone] --; - } - } - } - - return $sms_per_scheduled; - } } diff --git a/controllers/internals/Sended.php b/controllers/internals/Sended.php index 6a9276c..9cce107 100644 --- a/controllers/internals/Sended.php +++ b/controllers/internals/Sended.php @@ -179,20 +179,6 @@ namespace controllers\internals; return $this->get_model()->get_by_uid_and_adapter_for_user($id_user, $uid, $adapter); } - /** - * Get number of sended SMS since a date for a phone - * - * @param int $id_user : User id - * @param int $id_phone : Phone id we want the number of sended message for - * @param \DateTime $since : Date since which we want sended number - * - * @return int - */ - public function count_since_for_phone_and_user(int $id_user, int $id_phone, \DateTime $since): int - { - return $this->get_model()->count_since_for_phone_and_user($id_user, $id_phone, $since); - } - /** * Get number of sended SMS for every date since a date for a specific user. * @@ -253,6 +239,17 @@ namespace controllers\internals; 'error_message' => null, ]; + //If we reached our max quota, do not send the message + $internal_quota = new Quota($this->bdd); + $nb_credits = $internal_quota::compute_credits_for_message($text); //Calculate how much credit the message require + if (!$internal_quota->has_enough_credit($id_user, $nb_credits)) + { + $return['error'] = false; + $return['error_message'] = 'Not enough credit to send message.'; + + return $return; + } + $at = (new \DateTime())->format('Y-m-d H:i:s'); $media_uris = []; foreach ($medias as $media) @@ -275,56 +272,38 @@ namespace controllers\internals; $text .= "\n" . join(' - ', $media_urls); } - //If we reached our max quota, do not send the message - $internal_quota = new Quota($this->bdd); - $nb_credits = $internal_quota::compute_credits_for_message($text); //Calculate how much credit the message require - if (!$internal_quota->has_enough_credit($id_user, $nb_credits)) + $response = $adapter->send($destination, $text, $flash, $mms, $media_uris); + + if ($response['error']) { $return['error'] = true; - $return['error_message'] = 'Not enough credit to send message.'; + $return['error_message'] = $response['error_message']; + $status = \models\Sended::STATUS_FAILED; + $sended_id = $this->create($id_user, $id_phone, $at, $text, $destination, $response['uid'] ?? uniqid(), $adapter->meta_classname(), $flash, $mms, $medias, $originating_scheduled, $status); + + $sended = [ + 'id' => $sended_id, + 'at' => $at, + 'status' => $status, + 'text' => $text, + 'destination' => $destination, + 'origin' => $id_phone, + 'mms' => $mms, + 'medias' => $medias, + 'originating_scheduled' => $originating_scheduled, + ]; + + $internal_webhook = new Webhook($this->bdd); + $internal_webhook->trigger($id_user, \models\Webhook::TYPE_SEND_SMS, $sended); + + return $return; } - //If we reached limit for this phone, do not send the message - $internal_phone = new Phone($this->bdd); - $internal_sended = new Sended($this->bdd); - $limits = $internal_phone->get_limits($id_phone); + $internal_quota->consume_credit($id_user, $nb_credits); - $remaining_volume = PHP_INT_MAX; - foreach ($limits as $limit) - { - $startpoint = new \DateTime($limit['startpoint']); - $consumed = $internal_sended->count_since_for_phone_and_user($id_user, $id_phone, $startpoint); - $remaining_volume = min(($limit['volume'] - $consumed), $remaining_volume); - } + $sended_id = $this->create($id_user, $id_phone, $at, $text, $destination, $response['uid'] ?? uniqid(), $adapter->meta_classname(), $flash, $mms, $medias, $originating_scheduled, $status); - if ($remaining_volume < 1) - { - $return['error'] = true; - $return['error_message'] = 'Phone send limit have been reached.'; - } - - $uid = uniqid(); - if (!$return['error']) - { - $response = $adapter->send($destination, $text, $flash, $mms, $media_uris); - $uid = $response['uid'] ?? $uid; - - if ($response['error']) - { - $return['error'] = true; - $return['error_message'] = $response['error_message']; - } - else // If send with success, consume credit - { - $internal_quota->consume_credit($id_user, $nb_credits); - } - } - - // If we fail to send or not, we will always save message as sended, only the status will change. - $status = $return['error'] ? \models\Sended::STATUS_FAILED : \models\Sended::STATUS_UNKNOWN; - $sended_id = $this->create($id_user, $id_phone, $at, $text, $destination, $uid, $adapter->meta_classname(), $flash, $mms, $medias, $originating_scheduled, $status); - - $webhook_body = [ + $sended = [ 'id' => $sended_id, 'at' => $at, 'status' => $status, @@ -337,7 +316,7 @@ namespace controllers\internals; ]; $internal_webhook = new Webhook($this->bdd); - $internal_webhook->trigger($id_user, \models\Webhook::TYPE_SEND_SMS, $webhook_body); + $internal_webhook->trigger($id_user, \models\Webhook::TYPE_SEND_SMS, $sended); return $return; } diff --git a/controllers/internals/Tool.php b/controllers/internals/Tool.php index a09fab6..e6b8994 100644 --- a/controllers/internals/Tool.php +++ b/controllers/internals/Tool.php @@ -11,8 +11,6 @@ namespace controllers\internals; -use BenMorel\GsmCharsetConverter\Converter; - /** * Some tools frequently used. * Not a standard controller as it's not linked to a model in any way. @@ -167,24 +165,6 @@ use BenMorel\GsmCharsetConverter\Converter; 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. * @@ -414,17 +394,4 @@ use BenMorel\GsmCharsetConverter\Converter; return "{$scheme}{$user}{$pass}{$host}{$port}{$path}{$query}{$fragment}"; } - - - /** - * Transform an UTF-8 string into a valid GSM 7 string (GSM 03.38), remplacing invalid chars with best equivalent whenever possible - * - * @param string $text : Input text to convert into gsm string - * @return string : An UTF-8 string with GSM alphabet only - */ - public static function convert_to_gsm0338(string $text): string - { - $converter = new Converter(); - return $converter->cleanUpUtf8String($text, true, '?'); - } } diff --git a/controllers/internals/Webhook.php b/controllers/internals/Webhook.php index 6a2e8cf..bb2c3bd 100644 --- a/controllers/internals/Webhook.php +++ b/controllers/internals/Webhook.php @@ -137,10 +137,10 @@ class Webhook extends StandardController $error_code = null; $queue = msg_get_queue(QUEUE_ID_WEBHOOK); - msg_send($queue, QUEUE_TYPE_WEBHOOK, $message, true, true, $error_code); - } + $success = msg_send($queue, QUEUE_TYPE_WEBHOOK, $message, true, true, $error_code); - return true; + return (bool) $success; + } } /** diff --git a/controllers/publics/Api.php b/controllers/publics/Api.php index 7ee0d36..92fb2ea 100644 --- a/controllers/publics/Api.php +++ b/controllers/publics/Api.php @@ -506,8 +506,6 @@ namespace controllers\publics; * @param string $_POST['name'] : Phone name * @param string $_POST['adapter'] : Phone adapter * @param array $_POST['adapter_data'] : Phone adapter data - * @param int $priority : Priority with which to use phone to send SMS. Default 0. - * @param ?array $_POST['limits'] : Array of limits in number of SMS for a period to be applied to this phone. * * @return int : id phone the new phone on success */ @@ -518,10 +516,6 @@ namespace controllers\publics; $name = $_POST['name'] ?? false; $adapter = $_POST['adapter'] ?? false; $adapter_data = !empty($_POST['adapter_data']) ? $_POST['adapter_data'] : []; - $priority = $_POST['priority'] ?? 0; - $priority = max(((int) $priority), 0); - $limits = $_POST['limits'] ?? []; - $limits = is_array($limits) ? $limits : [$limits]; if (!$name) { @@ -541,7 +535,7 @@ namespace controllers\publics; return $this->json($return); } - $name_exist = $this->internal_phone->get_by_name_and_user($this->user['id'], $name); + $name_exist = $this->internal_phone->get_by_name($name); if ($name_exist) { $return['error'] = self::ERROR_CODES['INVALID_PARAMETER']; @@ -551,36 +545,6 @@ namespace controllers\publics; return $this->json($return); } - if ($limits) - { - foreach ($limits as $key => $limit) - { - if (!is_array($limit)) - { - unset($limits[$key]); - continue; - } - - $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) @@ -663,7 +627,7 @@ namespace controllers\publics; return $this->json($return); } - $phone_id = $this->internal_phone->create($this->user['id'], $name, $adapter, $adapter_data, $priority, $limits); + $phone_id = $this->internal_phone->create($this->user['id'], $name, $adapter, $adapter_data); if (false === $phone_id) { $return['error'] = self::ERROR_CODES['CANNOT_CREATE']; @@ -686,7 +650,6 @@ namespace controllers\publics; * @param string (optionnal) $_POST['name'] : New phone name * @param string (optionnal) $_POST['adapter'] : New phone adapter * @param array (optionnal) $_POST['adapter_data'] : New phone adapter data - * @param int $priority : Priority with which to use phone to send SMS. Default 0. * * @return int : id phone the new phone on success */ @@ -704,16 +667,10 @@ namespace controllers\publics; return $this->json($return); } - $limits = $this->internal_phone->get_limits(($phone['id'])); - $name = $_POST['name'] ?? $phone['name']; - $priority = $_POST['priority'] ?? $phone['priority']; - $priority = max(((int) $priority), 0); $adapter = $_POST['adapter'] ?? $phone['adapter']; $adapter_data = !empty($_POST['adapter_data']) ? $_POST['adapter_data'] : json_decode($phone['adapter_data']); $adapter_data = is_array($adapter_data) ? $adapter_data : [$adapter_data]; - $limits = $_POST['limits'] ?? $limits; - $limits = is_array($limits) ? $limits : [$limits]; if (!$name && !$adapter && !$adapter_data) @@ -726,7 +683,7 @@ namespace controllers\publics; } - $phone_with_same_name = $this->internal_phone->get_by_name_and_user($this->user['id'], $name); + $phone_with_same_name = $this->internal_phone->get_by_name($name); if ($phone_with_same_name && $phone_with_same_name['id'] != $phone['id']) { $return['error'] = self::ERROR_CODES['INVALID_PARAMETER']; @@ -736,36 +693,6 @@ namespace controllers\publics; return $this->json($return); } - if ($limits) - { - foreach ($limits as $key => $limit) - { - if (!is_array($limit)) - { - unset($limits[$key]); - continue; - } - - $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) @@ -848,7 +775,7 @@ namespace controllers\publics; return $this->json($return); } - $success = $this->internal_phone->update_for_user($this->user['id'], $phone['id'], $name, $adapter, $adapter_data_json, $priority, $limits); + $success = $this->internal_phone->update_for_user($this->user['id'], $phone['id'], $name, $adapter, $adapter_data); if (!$success) { $return['error'] = self::ERROR_CODES['CANNOT_UPDATE']; diff --git a/controllers/publics/ConditionalGroup.php b/controllers/publics/ConditionalGroup.php index 8f1f3ea..2a1aad8 100644 --- a/controllers/publics/ConditionalGroup.php +++ b/controllers/publics/ConditionalGroup.php @@ -185,45 +185,6 @@ namespace controllers\publics; return $this->redirect(\descartes\Router::url('ConditionalGroup', 'list')); } - /** - * Return contacts of a group as json array - * @param int $id_group = Group id - * - * @return json - */ - public function preview (int $id_group) - { - $return = [ - 'success' => false, - 'result' => 'Une erreur inconnue est survenue.', - ]; - - $group = $this->internal_conditional_group->get_for_user($_SESSION['user']['id'], $id_group); - - if (!$group) - { - $return['result'] = 'Ce groupe n\'existe pas.'; - echo json_encode($return); - - return false; - } - - $contacts = $this->internal_conditional_group->get_contacts_for_condition_and_user($_SESSION['user']['id'], $group['condition']); - if (!$contacts) - { - $return['result'] = 'Aucun contact dans le groupe.'; - echo json_encode($return); - - return false; - } - - $return['success'] = true; - $return['result'] = $contacts; - echo json_encode($return); - - return true; - } - /** * Try to get the preview of contacts for a conditionnal group. * diff --git a/controllers/publics/Contact.php b/controllers/publics/Contact.php index 69b0cc8..78da100 100644 --- a/controllers/publics/Contact.php +++ b/controllers/publics/Contact.php @@ -372,7 +372,6 @@ namespace controllers\publics; else { $invalid_type = true; - $result = false; } } diff --git a/controllers/publics/Group.php b/controllers/publics/Group.php index 2bd2c4f..fa8b8af 100644 --- a/controllers/publics/Group.php +++ b/controllers/publics/Group.php @@ -191,45 +191,6 @@ namespace controllers\publics; return $this->redirect(\descartes\Router::url('Group', 'list')); } - /** - * Return contacts of a group as json array - * @param int $id_group = Group id - * - * @return json - */ - public function preview (int $id_group) - { - $return = [ - 'success' => false, - 'result' => 'Une erreur inconnue est survenue.', - ]; - - $group = $this->internal_group->get_for_user($_SESSION['user']['id'], $id_group); - - if (!$group) - { - $return['result'] = 'Ce groupe n\'existe pas.'; - echo json_encode($return); - - return false; - } - - $contacts = $this->internal_group->get_contacts($id_group); - if (!$contacts) - { - $return['result'] = 'Aucun contact dans le groupe.'; - echo json_encode($return); - - return false; - } - - $return['success'] = true; - $return['result'] = $contacts; - echo json_encode($return); - - return true; - } - /** * Cette fonction retourne la liste des groups sous forme JSON. */ diff --git a/controllers/publics/Phone.php b/controllers/publics/Phone.php index 7451288..14028ea 100644 --- a/controllers/publics/Phone.php +++ b/controllers/publics/Phone.php @@ -55,9 +55,6 @@ class Phone extends \descartes\Controller foreach ($phones as &$phone) { - $limits = $this->internal_phone->get_limits($phone['id']); - $phone['limits'] = $limits; - $adapter = $adapters[$phone['adapter']] ?? false; if (!$adapter) @@ -134,11 +131,9 @@ 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 ?array $_POST['limits'] : Array of limits in number of SMS for a period to be applied to this phone. - * @param int $_POST['priority'] : Priority with which to use phone to send SMS. Default 0. + * @param string $_POST['name'] : Phone name + * @param string $_POST['adapter'] : Phone adapter + * @param array $_POST['adapter_data'] : Phone adapter data */ public function create($csrf) { @@ -151,12 +146,8 @@ class Phone extends \descartes\Controller $id_user = $_SESSION['user']['id']; $name = $_POST['name'] ?? false; - $priority = $_POST['priority'] ?? 0; - $priority = max(((int) $priority), 0); $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) { @@ -165,7 +156,7 @@ class Phone extends \descartes\Controller return $this->redirect(\descartes\Router::url('Phone', 'add')); } - $name_exist = $this->internal_phone->get_by_name_and_user($id_user, $name); + $name_exist = $this->internal_phone->get_by_name($name); if ($name_exist) { \FlashMessage\FlashMessage::push('danger', 'Ce nom est déjà utilisé pour un autre téléphone.'); @@ -173,36 +164,6 @@ class Phone extends \descartes\Controller return $this->redirect(\descartes\Router::url('Phone', 'add')); } - if ($limits) - { - foreach ($limits as $key => $limit) - { - if (!is_array($limit)) - { - unset($limits[$key]); - continue; - } - - $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) @@ -284,7 +245,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, $priority, $limits); + $success = $this->internal_phone->create($id_user, $name, $adapter, $adapter_data); if (!$success) { \FlashMessage\FlashMessage::push('danger', 'Impossible de créer ce téléphone.'); @@ -296,207 +257,4 @@ class Phone extends \descartes\Controller return $this->redirect(\descartes\Router::url('Phone', 'list')); } - - - /** - * Return the edit page for phones - * - * @param int... $ids : Phones ids - */ - public function edit() - { - $ids = $_GET['ids'] ?? []; - $id_user = $_SESSION['user']['id']; - - $phones = $this->internal_phone->gets_in_for_user($id_user, $ids); - - if (!$phones) - { - return $this->redirect(\descartes\Router::url('Phone', 'list')); - } - - $adapters = $this->internal_adapter->list_adapters(); - - foreach ($phones as &$phone) - { - $limits = $this->internal_phone->get_limits($phone['id']); - $phone['limits'] = $limits; - } - - $this->render('phone/edit', [ - 'phones' => $phones, - 'adapters' => $adapters, - ]); - } - - - /** - * Update multiple phones. - * - * @param $csrf : CSRF token - * @param string $_POST['phones']['id']['name'] : Phone name - * @param string $_POST['phones']['id']['adapter'] : Phone adapter - * @param ?array $_POST['phones']['id']['adapter_data'] : Phone adapter data - * @param ?array $_POST['phones']['id']['limits'] : Array of limits in number of SMS for a period to be applied to this phone. - * @param int $_POST['phones']['id']['priority'] : Priority with which to use phone to send SMS. Default 0. - */ - public function update($csrf) - { - if (!$this->verify_csrf($csrf)) - { - \FlashMessage\FlashMessage::push('danger', 'Jeton CSRF invalid !'); - - return $this->redirect(\descartes\Router::url('Phone', 'add')); - } - - if (!$_POST['phones']) - { - return $this->redirect(\descartes\Router::url('Phone', 'list')); - } - - $id_user = $_SESSION['user']['id']; - - $nb_update = 0; - foreach ($_POST['phones'] as $id_phone => $phone) - { - $name = $phone['name'] ?? false; - $priority = $phone['priority'] ?? 0; - $priority = max(((int) $priority), 0); - $adapter = $phone['adapter'] ?? false; - $adapter_data = !empty($phone['adapter_data']) ? $phone['adapter_data'] : []; - $limits = $phone['limits'] ?? []; - $limits = is_array($limits) ? $limits : [$limits]; - - if (!$name || !$adapter) - { - continue; - } - - $phone_with_same_name = $this->internal_phone->get_by_name_and_user($id_user, $name); - if ($phone_with_same_name && $phone_with_same_name['id'] != $id_phone) - { - continue; - } - - if ($limits) - { - foreach ($limits as $key => $limit) - { - if (!is_array($limit)) - { - unset($limits[$key]); - continue; - } - - $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) - { - if ($metas['meta_classname'] === $adapter) - { - $find_adapter = $metas; - - break; - } - } - - if (!$find_adapter) - { - continue; - } - - if ($find_adapter['meta_hidden']) - { - continue; - } - - //If missing required data fields, error - foreach ($find_adapter['meta_data_fields'] as $field) - { - if (false === $field['required']) - { - continue; - } - - if (!empty($adapter_data[$field['name']])) - { - continue; - } - - continue 2; - } - - //If field phone number is invalid - foreach ($find_adapter['meta_data_fields'] as $field) - { - if ('phone_number' !== ($field['type'] ?? false)) - { - continue; - } - - if (!empty($adapter_data[$field['name']])) - { - $adapter_data[$field['name']] = \controllers\internals\Tool::parse_phone($adapter_data[$field['name']]); - - if ($adapter_data[$field['name']]) - { - continue; - } - } - - continue 2; - } - - $adapter_data = json_encode($adapter_data); - - //Check adapter is working correctly with thoses names and data - $adapter_classname = $find_adapter['meta_classname']; - $adapter_instance = new $adapter_classname($adapter_data); - $adapter_working = $adapter_instance->test(); - - if (!$adapter_working) - { - continue; - } - - $success = $this->internal_phone->update_for_user($id_user, $id_phone, $name, $adapter, $adapter_data, $priority, $limits); - if (!$success) - { - continue; - } - - $nb_update ++; - } - - if ($nb_update !== \count($_POST['phones'])) - { - \FlashMessage\FlashMessage::push('danger', 'Certains téléphones n\'ont pas pu êtres mis à jour.'); - - return $this->redirect(\descartes\Router::url('Phone', 'list')); - } - - \FlashMessage\FlashMessage::push('success', 'Tous les téléphones ont été modifiés avec succès.'); - - return $this->redirect(\descartes\Router::url('Phone', 'list')); - } } diff --git a/controllers/publics/Templating.php b/controllers/publics/Templating.php index a667ee7..026622e 100644 --- a/controllers/publics/Templating.php +++ b/controllers/publics/Templating.php @@ -83,12 +83,6 @@ namespace controllers\publics; $result = $this->internal_templating->render($template, $data); $return = $result; - // If we must force GSM 7 alphabet - if ((int) ($_SESSION['user']['settings']['force_gsm_alphabet'] ?? false)) - { - $return['result'] = \controllers\internals\Tool::convert_to_gsm0338($return['result']); - } - if (!trim($result['result'])) { $return['result'] = 'Message vide, il ne sera pas envoyé.'; diff --git a/daemons/Sender.php b/daemons/Sender.php index d462739..6f0176b 100644 --- a/daemons/Sender.php +++ b/daemons/Sender.php @@ -22,7 +22,6 @@ class Sender extends AbstractDaemon private $internal_phone; private $internal_scheduled; private $internal_received; - private $internal_sended; private $bdd; private $msg_queue; @@ -46,7 +45,6 @@ class Sender extends AbstractDaemon { //Create the internal controllers $this->internal_scheduled = new \controllers\internals\Scheduled($this->bdd); - $this->internal_sended = new \controllers\internals\Sended($this->bdd); //Get smss and transmit order to send to appropriate phone daemon $smss_per_scheduled = $this->internal_scheduled->get_smss_to_send(); @@ -64,8 +62,8 @@ class Sender extends AbstractDaemon { foreach ($smss_per_scheduled as $id_scheduled => $smss) { - //If queue not already exists - if (!msg_queue_exists(QUEUE_ID_PHONE) || !isset($this->msg_queue)) + //If queue not already exists + if (!msg_queue_exists(QUEUE_ID_PHONE) || !isset($this->queue)) { $this->msg_queue = msg_get_queue(QUEUE_ID_PHONE); } diff --git a/db/migrations/20230201152658_add_phone_limits.php b/db/migrations/20230201152658_add_phone_limits.php deleted file mode 100644 index debf233..0000000 --- a/db/migrations/20230201152658_add_phone_limits.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -use Phinx\Migration\AbstractMigration; - -class AddPhoneLimits extends AbstractMigration -{ - /** - * Change Method. - * - * Write your reversible migrations using this method. - * - * More information on writing migrations is available here: - * https://book.cakephp.org/phinx/0/en/migrations.html - * - * The following commands can be used in this method and Phinx will - * automatically reverse them when rolling back: - * - * createTable - * renameTable - * addColumn - * addCustomColumn - * renameColumn - * addIndex - * addForeignKey - * - * Any other destructive changes will result in an error when trying to - * rollback the migration. - * - * Remember to call "create()" or "update()" and NOT "save()" when working - * with the Table class. - */ - public function change() - { - $table = $this->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/db/migrations/20230205214319_add_phone_priority.php b/db/migrations/20230205214319_add_phone_priority.php deleted file mode 100644 index 3ce343b..0000000 --- a/db/migrations/20230205214319_add_phone_priority.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -use Phinx\Migration\AbstractMigration; - -class AddPhonePriority extends AbstractMigration -{ - /** - * Change Method. - * - * Write your reversible migrations using this method. - * - * More information on writing migrations is available here: - * https://book.cakephp.org/phinx/0/en/migrations.html - * - * The following commands can be used in this method and Phinx will - * automatically reverse them when rolling back: - * - * createTable - * renameTable - * addColumn - * addCustomColumn - * renameColumn - * addIndex - * addForeignKey - * - * Any other destructive changes will result in an error when trying to - * rollback the migration. - * - * Remember to call "create()" or "update()" and NOT "save()" when working - * with the Table class. - */ - public function change() - { - $table = $this->table('phone'); - $table->addColumn('priority', 'integer', [ - 'null' => false, - 'default' => 0, - 'comment' => 'Priority with which the phone will be used. The higher the more prioritary.', - 'after' => 'name' - ]) - ->update(); - } -} diff --git a/env.php.dist b/env.php.dist index c544ba0..8f7091b 100644 --- a/env.php.dist +++ b/env.php.dist @@ -82,7 +82,6 @@ 'alert_quota_limit_reached' => 1, 'alert_quota_limit_close' => 0.9, 'hide_menus' => '', - 'force_gsm_alphabet' => 0, ], ]; diff --git a/models/Event.php b/models/Event.php index 166d46e..843f442 100644 --- a/models/Event.php +++ b/models/Event.php @@ -84,6 +84,32 @@ namespace models; return $this->_select('event', ['id_user' => $id_user], 'at', true, $nb_entry); } + /** + * Gets events for a type, since a date and eventually until a date (both included). + * + * @param int $id_user : User id + * @param string $type : Event type we want + * @param \DateTime $since : Date to get events since + * @param ?\DateTime $until (optional) : Date until wich we want events, if not specified no limit + * + * @return array + */ + public function get_events_by_type_and_date_for_user(int $id_user, string $type, \DateTime $since, ?\DateTime $until = null) + { + $where = [ + 'id_user' => $id_user, + 'type' => $type, + '>=at' => $since->format('Y-m-d H:i:s'), + ]; + + if (null !== $until) + { + $where['<=at'] = $until->format('Y-m-d H:i:s'); + } + + return $this->_select('event', $where, 'at'); + } + /** * Return table name. */ diff --git a/models/Phone.php b/models/Phone.php index 4579b22..14447f4 100644 --- a/models/Phone.php +++ b/models/Phone.php @@ -15,7 +15,7 @@ namespace models; { /** - * Return all phones that belongs to active users + * Return all hones that belongs to active users * * @return array */ @@ -63,48 +63,6 @@ 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/models/Sended.php b/models/Sended.php index 0acdb20..b401ccc 100644 --- a/models/Sended.php +++ b/models/Sended.php @@ -178,20 +178,6 @@ namespace models; return $this->_select_one('sended', ['id_user' => $id_user, 'uid' => $uid, 'adapter' => $adapter]); } - /** - * Get number of sended SMS since a date for a phone - * - * @param int $id_user : User id - * @param int $id_phone : Phone id we want the number of sended message for - * @param \DateTime $since : Date since which we want sended number - * - * @return int - */ - public function count_since_for_phone_and_user(int $id_user, int $id_phone, \DateTime $since) : int - { - return $this->_count('sended', ['id_user' => $id_user, 'id_phone' => $id_phone, '>=at' => $since->format('c')]); - } - /** * Get number of sended SMS for every date since a date for a specific user. * diff --git a/routes.php b/routes.php index a5e87cd..3eefebd 100644 --- a/routes.php +++ b/routes.php @@ -76,7 +76,6 @@ 'delete' => '/group/delete/{csrf}/', 'edit' => '/group/edit/', 'update' => '/group/update/{csrf}/', - 'preview' => '/group/preview/{id_group}/', 'json_list' => '/groups.json/', ], @@ -89,7 +88,6 @@ 'edit' => '/conditional_group/edit/', 'update' => '/conditional_group/update/{csrf}/', 'contacts_preview' => '/conditional_group/preview/', - 'preview' => '/conditional_group/preview/{id_group}/', 'json_list' => '/conditional_groups.json/', ], @@ -162,8 +160,6 @@ 'add' => '/phone/add/', 'create' => '/phone/create/{csrf}/', 'delete' => '/phone/delete/{csrf}/', - 'edit' => '/phone/edit/', - 'update' => '/phone/update/{csrf}/', ], 'Call' => [ diff --git a/templates/conditional_group/list.php b/templates/conditional_group/list.php index 0ef7726..b688bc4 100644 --- a/templates/conditional_group/list.php +++ b/templates/conditional_group/list.php @@ -43,7 +43,6 @@ <th>Condition</th> <th>Date de création</th> <th>Dernière modification</th> - <th>Preview</th> <th class="checkcolumn"><input type="checkbox" id="check-all"/></th> </tr> </thead> @@ -70,56 +69,9 @@ </div> </div> </div> -<div class="modal fade" tabindex="-1" id="preview-text-modal"> - <div class="modal-dialog modal-lg"> - <div class="modal-content"> - <div class="modal-header"> - <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> - <h4 class="modal-title">Prévisualisation des contacts</h4> - </div> - <div class="modal-body"> - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> - </div> - </div> - </div> -</div> <script> jQuery(document).ready(function () { - jQuery('body').on('click', '.preview-button', function (e) - { - e.preventDefault(); - var group_id = jQuery(this).attr('data-id-group'); - - jQuery.ajax({ - type: "GET", - url: HTTP_PWD + '/conditional_group/preview/' + group_id + '/', - success: function (data) { - if (!data.success) { - jQuery('#preview-text-modal').find('.modal-body').text(data.result); - } else { - html = ''; - - for (contact of data.result) - { - html += '<div class="preview-contact well">'; - html += ' <div class="preview-contact-name">' + jQuery.fn.dataTable.render.text().display(contact.name) + '</div>' - html += ' <div class="preview-contact-number">' + jQuery.fn.dataTable.render.text().display(contact.number) + '</div>' - html += ' <code class="preview-contact-data">' + jQuery.fn.dataTable.render.text().display(contact.data) + '</code>' - html += '</div>'; - console.log(contact); - } - - jQuery('#preview-text-modal').find('.modal-body').html(html); - } - jQuery('#preview-text-modal').modal({'keyboard': true}); - }, - dataType: 'json' - }); - }); - jQuery('.datatable').DataTable({ "pageLength": 25, "lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]], @@ -145,12 +97,6 @@ jQuery(document).ready(function () }, {data: 'created_at'}, {data: 'updated_at'}, - { - data: '_', - render: function (data, type, row, meta) { - return '<a class="btn btn-info preview-button" href="#" data-id-group="' + jQuery.fn.dataTable.render.text().display(row.id) + '"><span class="fa fa-eye"></span></a>'; - }, - }, { data: 'id', render: function (data, type, row, meta) { @@ -160,6 +106,7 @@ jQuery(document).ready(function () ], "deferRender": true }); + }); </script> <?php diff --git a/templates/group/list.php b/templates/group/list.php index 5da0452..eb1e7c1 100644 --- a/templates/group/list.php +++ b/templates/group/list.php @@ -43,7 +43,6 @@ <th>Nombre de contacts</th> <th>Date de création</th> <th>Dernière modification</th> - <th>Preview</th> <th class="checkcolumn"><input type="checkbox" id="check-all"/></th> </tr> </thead> @@ -70,21 +69,6 @@ </div> </div> </div> -<div class="modal fade" tabindex="-1" id="preview-text-modal"> - <div class="modal-dialog modal-lg"> - <div class="modal-content"> - <div class="modal-header"> - <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> - <h4 class="modal-title">Prévisualisation des contacts</h4> - </div> - <div class="modal-body"> - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> - </div> - </div> - </div> -</div> <script> jQuery(document).ready(function () { @@ -108,12 +92,6 @@ jQuery(document).ready(function () {data: 'nb_contact', render: jQuery.fn.dataTable.render.text()}, {data: 'created_at'}, {data: 'updated_at'}, - { - data: '_', - render: function (data, type, row, meta) { - return '<a class="btn btn-info preview-button" href="#" data-id-group="' + jQuery.fn.dataTable.render.text().display(row.id) + '"><span class="fa fa-eye"></span></a>'; - }, - }, { data: 'id', render: function (data, type, row, meta) { @@ -124,38 +102,6 @@ jQuery(document).ready(function () "deferRender": true }); - jQuery('body').on('click', '.preview-button', function (e) - { - e.preventDefault(); - var group_id = jQuery(this).attr('data-id-group'); - - jQuery.ajax({ - type: "GET", - url: HTTP_PWD + '/group/preview/' + group_id + '/', - success: function (data) { - if (!data.success) { - jQuery('#preview-text-modal').find('.modal-body').text(data.result); - } else { - html = ''; - - for (contact of data.result) - { - html += '<div class="preview-contact well">'; - html += ' <div class="preview-contact-name">' + jQuery.fn.dataTable.render.text().display(contact.name) + '</div>' - html += ' <div class="preview-contact-number">' + jQuery.fn.dataTable.render.text().display(contact.number) + '</div>' - html += ' <code class="preview-contact-data">' + jQuery.fn.dataTable.render.text().display(contact.data) + '</code>' - html += '</div>'; - console.log(contact); - } - - jQuery('#preview-text-modal').find('.modal-body').html(html); - } - jQuery('#preview-text-modal').modal({'keyboard': true}); - }, - dataType: 'json' - }); - }); - }); </script> <?php diff --git a/templates/phone/add.php b/templates/phone/add.php index ab2e143..f1e08c3 100644 --- a/templates/phone/add.php +++ b/templates/phone/add.php @@ -48,16 +48,7 @@ </div> </div> <div class="form-group"> - <label>Priorité d'utilisation du téléphone</label> - <p class="italic small help"> - Lors de l'envoi de SMS sans téléphone spécifié, les téléphones avec la plus haute priorité seront utilisés en premier. - </p> - <div class="form-group"> - <input required="required" name="priority" class="form-control" type="number" min="0" placeholder="Priorité d'utilisation" value="<?php $this->s($_SESSION['previous_http_post']['priority'] ?? 0) ?>"> - </div> - </div> - <div class="form-group"> - <label>Type de téléphone</label> + <label>Type de téléphone : </label> <p class="italic small help" id="description-adapter-general"> Le type de téléphone utilisé par RaspiSMS pour envoyer ou recevoir les SMS. Pour plus d'information, consultez <a href="https://documentation.raspisms.fr/users/adapters/overview.html" target="_blank">la documentation de RaspiSMS</a> concernant les différents types de téléphones. </p> @@ -76,7 +67,7 @@ <?php } ?> </select> </div> - <div id="adapter-data-container" class="form-group well"> + <div id="adapter-data-container" class="form-group"> <div id="adapter-data-description-container"> <h4>Description du téléphone</h4> <div id="adapter-data-description"></div> @@ -86,15 +77,6 @@ <h4>Réglages du téléphone</h4> <div id="adapter-data-fields"></div> </div> - </div> - <div class="form-group"> - <label>Limites des volumes d'envoi du téléphone</label> - <p class="italic small help"> - 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. - </p> - <div class="form-group phone-limits-container container-fluid"> - <div class="text-center"><div class="add-phone-limit-button fa fa-plus-circle"></div></div> - </div> </div> <a class="btn btn-danger" href="<?php echo \descartes\Router::url('Phone', 'list'); ?>">Annuler</a> <input type="submit" class="btn btn-success" value="Enregistrer le téléphone" /> @@ -192,47 +174,6 @@ { 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 = '' + - '<div class="row phone-limits-group">'+ - '<div class="col-xs-4">'+ - '<label>Période</label><br/>'+ - '<select name="limits[' + random_id + '][startpoint]" class="form-control" required>'+ - '<option value="" disabled selected>Période sur laquelle appliquer la limite</option>'+ - '<option value="today">Par jour</option>'+ - '<option value="-24 hours">24 heures glissantes</option>'+ - '<option value="this week midnight">Cette semaine</option>'+ - '<option value="-7 days">7 jours glissants</option>'+ - '<option value="this week midnight -1 week">Ces deux dernières semaines</option>'+ - '<option value="-14 days">14 jours glissants</option>'+ - '<option value="this month midnight">Ce mois</option>'+ - '<option value="-1 month">1 mois glissant</option>'+ - '<option value="-28 days">28 jours glissants</option>'+ - '<option value="-30 days">30 jours glissants</option>'+ - '<option value="-31 days">31 jours glissants</option>'+ - '</select>'+ - '</div>'+ - '<div class="scheduleds-number-data-container col-xs-8">'+ - '<label>Volume</label>'+ - '<div class="form-group">'+ - '<input name="limits[' + random_id + '][volume]" class="form-control" type="number" min="1" placeholder="Nombre de SMS maximum sur la période.">'+ - '</div>'+ - '</div>'+ - '<a href="#" class="phone-limits-group-remove"><span class="fa fa-times"></span></a>'+ - '</div>'; - - jQuery(this).parent('div').before(newLimit); - }); }); </script> <?php diff --git a/templates/phone/edit.php b/templates/phone/edit.php deleted file mode 100644 index a1b2446..0000000 --- a/templates/phone/edit.php +++ /dev/null @@ -1,304 +0,0 @@ -<?php - //Template dashboard - - $this->render('incs/head', ['title' => 'Phones - Edit']) -?> -<div id="wrapper"> -<?php - $this->render('incs/nav', ['page' => 'phones']) -?> - <div id="page-wrapper"> - <div class="container-fluid"> - <!-- Page Heading --> - <div class="row"> - <div class="col-lg-12"> - <h1 class="page-header"> - Modification téléphones - </h1> - <ol class="breadcrumb"> - <li> - <i class="fa fa-dashboard"></i> <a href="<?php echo \descartes\Router::url('Dashboard', 'show'); ?>">Dashboard</a> - </li> - <li> - <i class="fa fa-phone"></i> <a href="<?php echo \descartes\Router::url('Phone', 'list'); ?>">Téléphones</a> - </li> - <li class="active"> - <i class="fa fa-edit"></i> Modifier - </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-phone fa-fw"></i> Modification de téléphones</h3> - </div> - <div class="panel-body"> - <form action="<?php echo \descartes\Router::url('Phone', 'update', ['csrf' => $_SESSION['csrf']]);?>" method="POST"> - <?php foreach ($phones as $phone) { ?> - <div class="entry-container" data-entry-id="<?php $this->s($phone['id']); ?>"> - <div class="form-group"> - <label>Nom du téléphone</label> - <p class="italic small help"> - Le nom du téléphone qui enverra et recevra les messages. - </p> - <div class="form-group"> - <input required="required" name="phones[<?php $this->s($phone['id']); ?>][name]" class="form-control" placeholder="Nom du téléphone" value="<?php $this->s($phone['name']); ?>"> - </div> - </div> - <div class="form-group"> - <label>Priorité d'utilisation du téléphone</label> - <p class="italic small help"> - Lors de l'envoi de SMS sans téléphone spécifié, les téléphones avec la plus haute priorité seront utilisés en premier. - </p> - <div class="form-group"> - <input required="required" name="phones[<?php $this->s($phone['id']); ?>][priority]" class="form-control" type="number" min="0" placeholder="Priorité d'utilisation" value="<?php $this->s($phone['priority']) ?>"> - </div> - </div> - <div class="form-group"> - <label>Type de téléphone</label> - <p class="italic small help description-adapter-general"> - Le type de téléphone utilisé par RaspiSMS pour envoyer ou recevoir les SMS. Pour plus d'information, consultez <a href="https://documentation.raspisms.fr/users/adapters/overview.html" target="_blank">la documentation de RaspiSMS</a> concernant les différents types de téléphones. - </p> - <select name="phones[<?php $this->s($phone['id']); ?>][adapter]" class="form-control adapter-select"> - <?php foreach ($adapters as $adapter) { ?> - <?php if ($adapter['meta_hidden'] === false) { ?> - <option - value="<?= $adapter['meta_classname'] ?>" - data-description="<?php $this->s($adapter['meta_description']); ?>" - data-data-fields="<?php $this->s(json_encode($adapter['meta_data_fields'])); ?>" - <?php if ($phone['adapter'] == $adapter['meta_classname']) { ?> - data-phone-adapter-data="<?php $this->s($phone['adapter_data']); ?>" - selected - <?php } ?> - > - <?php $this->s($adapter['meta_name']); ?> - </option> - <?php } ?> - <?php } ?> - </select> - </div> - <div class="form-group well adapter-data-container"> - <div class="adapter-data-description-container"> - <h4>Description du téléphone</h4> - <div class="adapter-data-description"></div> - </div> - - <div class="adapter-data-fields-container"> - <h4>Réglages du téléphone</h4> - <div class="adapter-data-fields"></div> - </div> - </div> - <div class="form-group"> - <label>Limites des volumes d'envoi du téléphone</label> - <p class="italic small help"> - 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. - </p> - <div class="form-group phone-limits-container container-fluid"> - <?php foreach ($phone['limits'] as $limit) { ?> - <div class="row phone-limits-group"> - <div class="col-xs-4"> - <label>Période</label><br/> - <?php $random_id = uniqid(); ?> - <select name="phones[<?= $phone['id']; ?>][limits][<?= $random_id; ?>][startpoint]" class="form-control" required> - <option value="" disabled selected>Période sur laquelle appliquer la limite</option> - <option <?= $limit['startpoint'] == 'today' ? 'selected' : ''; ?> value="today">Par jour</option> - <option <?= $limit['startpoint'] == '-24 hours' ? 'selected' : ''; ?> value="-24 hours">24 heures glissantes</option> - <option <?= $limit['startpoint'] == 'this week midnight' ? 'selected' : ''; ?> value="this week midnight">Cette semaine</option> - <option <?= $limit['startpoint'] == '-7 days' ? 'selected' : ''; ?> value="-7 days">7 jours glissants</option> - <option <?= $limit['startpoint'] == 'this week midnight -1 week' ? 'selected' : ''; ?> value="this week midnight -1 week">Ces deux dernières semaines</option> - <option <?= $limit['startpoint'] == '-14 days' ? 'selected' : ''; ?> value="-14 days">14 jours glissants</option> - <option <?= $limit['startpoint'] == 'this month midnight' ? 'selected' : ''; ?> value="this month midnight">Ce mois</option> - <option <?= $limit['startpoint'] == '-1 month' ? 'selected' : ''; ?> value="-1 month">1 mois glissant</option> - <option <?= $limit['startpoint'] == '-28 days' ? 'selected' : ''; ?> value="-28 days">28 jours glissants</option> - <option <?= $limit['startpoint'] == '-30 days' ? 'selected' : ''; ?> value="-30 days">30 jours glissants</option> - <option <?= $limit['startpoint'] == '-31 days' ? 'selected' : ''; ?> value="-31 days">31 jours glissants</option> - </select> - </div> - <div class="scheduleds-number-data-container col-xs-8"> - <label>Volume</label> - <div class="form-group"> - <input name="phones[<?= $phone['id']; ?>][limits][<?= $random_id; ?>][volume]" class="form-control" type="number" min="1" value="<?php $this->s($limit['volume']); ?>" placeholder="Nombre de SMS maximum sur la période."> - </div> - </div> - <a href="#" class="phone-limits-group-remove"><span class="fa fa-times"></span></a> - </div> - <?php } ?> - <div class="text-center"><div class="add-phone-limit-button fa fa-plus-circle"></div></div> - </div> - </div> - </div> - <hr/> - <?php } ?> - <a class="btn btn-danger" href="<?php echo \descartes\Router::url('Phone', 'list'); ?>">Annuler</a> - <input type="submit" class="btn btn-success" value="Enregistrer le téléphone" /> - </form> - </div> - </div> - </div> - </div> - </div> - </div> -</div> -<script> - - function change_adapter (target) - { - var phone_id = target.parents('.entry-container').attr('data-entry-id'); - - var option = target.find('option:selected'); - target.parents('.entry-container').find('.adapter-data-description').html(option.attr('data-description')); - target.parents('.entry-container').find('.description-adapter-data').text(option.attr('data-data-help')); - - var data_fields = option.attr('data-data-fields'); - data_fields = JSON.parse(data_fields); - - if (option.attr('data-phone-adapter-data')) - { - var phone_adapter_data = option.attr('data-phone-adapter-data'); - phone_adapter_data = JSON.parse(phone_adapter_data); - } - - var numbers = []; - - var html = ''; - jQuery.each(data_fields, function (index, field) - { - if (phone_adapter_data) - { - if (field.name in phone_adapter_data) - { - value = phone_adapter_data[field.name]; - } - else - { - value = field.default_value ? field.default_value : null; - } - } - else - { - value = field.default_value ? field.default_value : null; - } - - - if (field.type == 'phone_number') - { - var random_id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); - html += '' + - '<div class="form-group">' + - '<label>' + field.title + '</label>' + - '<p class="italic small help">' + field.description + '</p>' + - '<div class="form-group">' + - '<input name="" class="form-control phone-international-input" type="tel" id="' + random_id + '" ' + (field.required ? 'required' : '') + ' ' + (value ? 'value="' + value + '"' : '') + '>' + - '</div>' + - '</div>'; - - var number = { - 'id': random_id, - 'name': field.name, - }; - - numbers.push(number); - } - else if (field.type == 'boolean') - { - html += '' + - '<div class="form-group">' + - '<label>' + field.title + '</label>' + - '<p class="italic small help">' + field.description + '</p>' + - '<div class="form-group">' + - '<input type="checkbox" name="phones[' + phone_id + '][adapter_data][' + field.name + ']" class="form-control" ' + (field.required ? 'required' : '') + ' ' + (value ? 'value="' + value + '" checked' : 'value="1"') + '><label class="switch" for="adapter_data[' + field.name + ']"></label>' + - '</div>' + - '</div>'; - } - else - { - html += '' + - '<div class="form-group">' + - '<label>' + field.title + '</label>' + - '<p class="italic small help">' + field.description + '</p>' + - '<div class="form-group">' + - '<input name="phones[' + phone_id + '][adapter_data][' + field.name + ']" class="form-control" ' + (field.required ? 'required' : '') + ' ' + (value ? 'value="' + value + '"' : '') + '>' + - '</div>' + - '</div>'; - } - }); - - if (html == '') - { - html = 'Pas de réglages.'; - } - - target.parents('.entry-container').find('.adapter-data-fields').html(html); - - for (i = 0; i < numbers.length; i++) - { - var iti_number_input = window.intlTelInput(document.getElementById(numbers[i].id), { - hiddenInput: 'phones[' + phone_id + '][adapter_data][' + numbers[i].name + ']', - defaultCountry: '<?php $this->s($_SESSION['user']['settings']['default_phone_country']); ?>', - preferredCountries: <?php $this->s(json_encode(explode(',', $_SESSION['user']['settings']['preferred_phone_country'])), false, false); ?>, - nationalMode: true, - utilsScript: '<?php echo HTTP_PWD_JS; ?>/intlTelInput/utils.js', - }); - } - } - - jQuery('document').ready(function($) - { - jQuery('.adapter-select').each(function () { - change_adapter(jQuery(this)); - }); - - jQuery('.adapter-select').on('change', function (e) - { - change_adapter(jQuery(this)); - }); - - 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 phone_id = jQuery(this).parents('.entry-container').attr('data-entry-id'); - var random_id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); - var newLimit = '' + - '<div class="row phone-limits-group">'+ - '<div class="col-xs-4">'+ - '<label>Période</label><br/>'+ - '<select name="phones[' + phone_id + '][limits][' + random_id + '][startpoint]" class="form-control adapter-select" required>'+ - '<option value="" disabled selected>Période sur laquelle appliquer la limite</option>'+ - '<option value="today">Par jour</option>'+ - '<option value="-24 hours">24 heures glissantes</option>'+ - '<option value="this week midnight">Cette semaine</option>'+ - '<option value="-7 days">7 jours glissants</option>'+ - '<option value="this week midnight -1 week">Ces deux dernières semaines</option>'+ - '<option value="-14 days">14 jours glissants</option>'+ - '<option value="this month midnight">Ce mois</option>'+ - '<option value="-1 month">1 mois glissant</option>'+ - '<option value="-28 days">28 jours glissants</option>'+ - '<option value="-30 days">30 jours glissants</option>'+ - '<option value="-31 days">31 jours glissants</option>'+ - '</select>'+ - '</div>'+ - '<div class="scheduleds-number-data-container col-xs-8">'+ - '<label>Volume</label>'+ - '<div class="form-group">'+ - '<input name="phones[' + phone_id + '][limits][' + random_id + '][volume]" class="form-control" type="number" min="1" placeholder="Nombre de SMS maximum sur la période.">'+ - '</div>'+ - '</div>'+ - '<a href="#" class="phone-limits-group-remove"><span class="fa fa-times"></span></a>'+ - '</div>'; - - jQuery(this).parent('div').before(newLimit); - }); - }); -</script> -<?php - $this->render('incs/footer'); diff --git a/templates/phone/list.php b/templates/phone/list.php index 59a701c..c505a45 100644 --- a/templates/phone/list.php +++ b/templates/phone/list.php @@ -41,10 +41,8 @@ <tr> <th>ID</th> <th>Nom</th> - <th>Priorité</th> <th>Type de téléphone</th> <th>Callbacks</th> - <th>Limites</th> <th class="checkcolumn"><input type="checkbox" id="check-all"/></th> </tr> </thead> @@ -58,7 +56,6 @@ </div> <div class="text-right col-xs-6 no-padding"> <strong>Action pour la séléction :</strong> - <button class="btn btn-default" type="submit" formaction="<?php echo \descartes\Router::url('Phone', 'edit'); ?>"><span class="fa fa-edit"></span> Modifier</button> <button class="btn btn-default btn-confirm" type="submit" formaction="<?php echo \descartes\Router::url('Phone', 'delete', ['csrf' => $_SESSION['csrf']]); ?>"><span class="fa fa-trash-o"></span> Supprimer</button> </div> </div> @@ -91,7 +88,6 @@ jQuery(document).ready(function () "columns" : [ {data: 'id', render: jQuery.fn.dataTable.render.text()}, {data: 'name', render: jQuery.fn.dataTable.render.text()}, - {data: 'priority', render: jQuery.fn.dataTable.render.text()}, {data: 'adapter', render: jQuery.fn.dataTable.render.text()}, { data: '_', @@ -127,61 +123,6 @@ jQuery(document).ready(function () return html; }, }, - { - data: 'limits', - render: function (limits) { - if (!limits.length) - { - return 'Pas de limites.'; - } - - var html = ''; - for (limit of limits) - { - switch (limit.startpoint) - { - case "today" : - var startpoint = 'Par jour'; - break; - case "-24 hours" : - var startpoint = '24 heures glissantes'; - break; - case "this week midnight" : - var startpoint = 'Cette semaine'; - break; - case "-7 days" : - var startpoint = '7 jours glissants'; - break; - case "this week midnight -1 week" : - var startpoint = 'Ces deux dernières semaines'; - break; - case "-14 days" : - var startpoint = '14 jours glissants'; - break; - case "this month midnight" : - var startpoint = 'Ce mois'; - break; - case "-1 month" : - var startpoint = '1 mois glissant'; - break; - case "-28 days" : - var startpoint = '28 jours glissants'; - break; - case "-30 days" : - var startpoint = '30 jours glissants'; - break; - case "-31 days" : - var startpoint = '31 jours glissants'; - break; - default : - var startpoint = 'Inconnu' - } - html += '<div><span class="bold">' + jQuery.fn.dataTable.render.text().display(startpoint) + ' : </span>' + jQuery.fn.dataTable.render.text().display(limit.volume) + '</div>'; - } - - return html; - }, - }, { data: 'id', render: function (data, type, row, meta) { diff --git a/templates/setting/show.php b/templates/setting/show.php index afe8cff..7a6325a 100644 --- a/templates/setting/show.php +++ b/templates/setting/show.php @@ -54,25 +54,6 @@ </form> </div> </div> - <div class="panel panel-default"> - <div class="panel-heading"> - <h4 class="panel-title"><i class="fa fa-font fa-fw"></i> Alphabet SMS optimisé</h4> - </div> - <div class="panel-body"> - <form action="<?php echo \descartes\Router::url('Setting', 'update', ['setting_name' => 'force_gsm_alphabet', 'csrf' => $_SESSION['csrf']]); ?>" method="POST"> - <div class="form-group"> - <label>Optimiser la taille des SMS en remplaçant les caractères spéciaux par leur équivalent GSM 7-bit : </label> - <select name="setting_value" class="form-control"> - <option value="0">Non</option> - <option value="1" <?php echo $_SESSION['user']['settings']['force_gsm_alphabet'] ? '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 class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"><i class="fa fa-picture-o fa-fw"></i> Support des MMS</h4> diff --git a/tests/phpstan/phpstan.phar b/tests/phpstan/phpstan.phar index aee0930..19bead9 100644 Binary files a/tests/phpstan/phpstan.phar and b/tests/phpstan/phpstan.phar differ