diff --git a/.gitignore b/.gitignore index 78ab9f5..2b007f4 100644 --- a/.gitignore +++ b/.gitignore @@ -8,10 +8,8 @@ scripts/ composer.lock env.* phinx.* -descartes/env.php data/test_write_sms.json data/test_read_sms.json -data/public/ !*.dist diff --git a/.htaccess b/.htaccess index ce35d68..e0be5de 100644 --- a/.htaccess +++ b/.htaccess @@ -1,5 +1,4 @@ RewriteEngine on RewriteRule ^assets - [L] RewriteRule ^.well-known - [L] -RewriteRule ^data/public/ - [L] RewriteRule . index.php diff --git a/VERSION b/VERSION index 6c8dc7e..545b772 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.1.0 +v3.0.13 diff --git a/adapters/AdapterInterface.php b/adapters/AdapterInterface.php index b7fa981..8760620 100644 --- a/adapters/AdapterInterface.php +++ b/adapters/AdapterInterface.php @@ -11,196 +11,140 @@ namespace adapters; -/** - * Interface for phones adapters - * Phone's adapters allow RaspiSMS to use a platform to communicate with a phone number. - * Its an adapter between internal and external code, as an API, command line software, physical modem, etc. - * - * All Phone Adapters must implement this interface - */ -interface AdapterInterface -{ /** - * Adapter constructor, called when instanciated by RaspiSMS. + * Interface for phones adapters + * Phone's adapters allow RaspiSMS to use a platform to communicate with a phone number. + * Its an adapter between internal and external code, as an API, command line software, physical modem, etc. * - * @param json string $data : JSON string of the data to configure interaction with the implemented service + * All Phone Adapters must implement this interface */ - public function __construct(string $data); + interface AdapterInterface + { + /** + * Adapter constructor, called when instanciated by RaspiSMS. + * + * @param json string $data : JSON string of the data to configure interaction with the implemented service + */ + public function __construct(string $data); - /** - * Classname of the adapter. - */ - public static function meta_classname(): string; + /** + * Classname of the adapter. + */ + public static function meta_classname(): string; - /** - * Uniq name of the adapter - * It should be the classname of the adapter un snakecase. - */ - public static function meta_uid(): string; + /** + * Uniq name of the adapter + * It should be the classname of the adapter un snakecase. + */ + public static function meta_uid(): string; - /** - * Should this adapter be hidden in user interface for phone creation and - * available to creation through API only. - */ - public static function meta_hidden(): bool; + /** + * Should this adapter be hidden in user interface for phone creation and + * available to creation through API only. + */ + public static function meta_hidden(): bool; - /** - * Name of the adapter. - * It should probably be the name of the service it adapt (e.g : Gammu SMSD, OVH SMS, SIM800L, etc.). - */ - public static function meta_name(): string; + /** + * Name of the adapter. + * It should probably be the name of the service it adapt (e.g : Gammu SMSD, OVH SMS, SIM800L, etc.). + */ + public static function meta_name(): string; - /** - * Description of the adapter. - * A short description of the service the adapter implements. - */ - public static function meta_description(): string; + /** + * Description of the adapter. + * A short description of the service the adapter implements. + */ + public static function meta_description(): string; - /** - * List of entries we want in data for the adapter. - * - * @return array : Eachline line is a field as an array with keys : name, title, description, required - */ - public static function meta_data_fields(): array; + /** + * List of entries we want in data for the adapter. + * + * @return array : Eachline line is a field as an array with keys : name, title, description, required + */ + public static function meta_data_fields(): array; - /** - * Does the implemented service support flash smss. - */ - public static function meta_support_flash(): bool; + /** + * Does the implemented service support flash smss. + */ + public static function meta_support_flash(): bool; - /** - * Does the implemented service support reading smss. - */ - public static function meta_support_read(): bool; + /** + * Does the implemented service support reading smss. + */ + public static function meta_support_read(): bool; - /** - * Does the implemented service support reception callback. - */ - public static function meta_support_reception(): bool; + /** + * Does the implemented service support reception callback. + */ + public static function meta_support_reception(): bool; - /** - * Does the implemented service support status change callback. - */ - public static function meta_support_status_change(): bool; + /** + * Does the implemented service support status change callback. + */ + public static function meta_support_status_change(): bool; - /** - * Does the implemented service support mms reception - */ - public static function meta_support_mms_reception(): bool; + /** + * Method called to send a SMS to a number. + * + * @param string $destination : Phone number to send the sms to + * @param string $text : Text of the SMS to send + * @param bool $flash : Is the SMS a Flash SMS + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * ?string 'uid' => Uid of the sms created on success + * ] + */ + public function send(string $destination, string $text, bool $flash = false); - /** - * Does the implemented service support mms sending - */ - public static function meta_support_mms_sending(): bool; - - /** - * Does the implemented service support inbound call callback - */ - public static function meta_support_inbound_call_callback(): bool; - - /** - * Does the implemented service support end call callback - */ - public static function meta_support_end_call_callback(): bool; + /** + * Method called to read SMSs of the number. + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * array 'smss' => Array of the sms reads + * [ + * [ + * string 'at' => sms reception date, + * string 'text' => sms text, + * string 'origin' => phone number who sent the sms + * ], + * ... + * ] + * ] + */ + public function read(): array; - /** - * Method called to send a SMS to a number. - * - * @param string $destination : Phone number to send the sms to - * @param string $text : Text of the SMS to send - * @param bool $flash : Is the SMS a Flash SMS - * @param bool $mms : Is the SMS a MMS - * @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 - * ] - */ - public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array; + /** + * Method called to verify if the adapter is working correctly + * should be use for exemple to verify that credentials and number are both valid. + * + * @return bool : False on error, true else + */ + public function test(): bool; - /** - * Method called to read SMSs of the number. - * - * @return array : [ - * bool 'error' => false if no error, true else - * ?string 'error_message' => null if no error, else error message - * array 'smss' => Array of the sms reads [[ - * (optional) bool 'mms' => default to false, true if mms - * (optional) array 'medias' => default to [], list of array representing medias to link to sms, with [ - * 'filepath' => local file copy of the media, - * 'extension' (optional) => extension of the media, - * 'mimetype' (optional) => mimetype of the media - * ] - * ], ...] - * ] - */ - public function read(): array; + /** + * Method called on reception of a status update notification for a SMS. + * + * @return mixed : False on error, else array ['uid' => uid of the sms, 'status' => New status of the sms (\models\Sended::STATUS_UNKNOWN, \models\Sended::STATUS_DELIVERED, \models\Sended::STATUS_FAILED)] + */ + public static function status_change_callback(); - /** - * Method called to verify if the adapter is working correctly - * should be use for exemple to verify that credentials and number are both valid. - * - * @return bool : False on error, true else - */ - public function test(): bool; - - /** - * Method called on reception of a status update notification for a SMS. - * - * @return mixed : False on error, else array ['uid' => uid of the sms, 'status' => New status of the sms (\models\Sended::STATUS_UNKNOWN, \models\Sended::STATUS_DELIVERED, \models\Sended::STATUS_FAILED)] - */ - public static function status_change_callback(); - - /** - * Method called on reception of a sms notification. - * - * @return array : [ - * bool 'error' => false on success, true on error - * ?string 'error_message' => null on success, error message else - * array 'sms' => array [ - * string 'at' : Recepetion date format Y-m-d H:i:s, - * string 'text' : SMS body, - * string 'origin' : SMS sender, - * (optional) array 'medias' => default to [], list of array representing medias to link to sms, with [ - * 'filepath' => local file copy of the media, - * 'extension' (optional) => extension of the media, - * 'mimetype' (optional) => mimetype of the media - * ] - * ] - * ] - */ - public static function reception_callback(): array; - - /** - * Method called on reception of an inbound_call notification - * - * @return array : [ - * bool 'error' => false on success, true on error - * ?string 'error_message' => null on success, error message else - * array 'call' => array [ - * string 'uid' : Uid of the call on the adapter plateform - * string 'start' : Start of the call date format Y-m-d H:i:s, - * ?string 'end' : End of the call date format Y-m-d H:i:s. If no known end, NULL - * string 'origin' : Emitter phone call number. International format. - * ] - * ] - */ - public function inbound_call_callback(): array; - - - /** - * Method called on reception of a end call notification - * - * @return array : [ - * bool 'error' => false on success, true on error - * ?string 'error_message' => null on success, error message else - * array 'call' => array [ - * string 'uid' : Uid of the call on the adapter plateform. Used to find the raspisms local call to update. - * string 'end' : End of the call date format Y-m-d H:i:s. - * ] - * ] - */ - public function end_call_callback(): array; -} + /** + * Method called on reception of a sms notification. + * + * @return array : [ + * bool 'error' => false on success, true on error + * ?string 'error_message' => null on success, error message else + * array 'sms' => array [ + * string 'at' : Recepetion date format Y-m-d H:i:s, + * string 'text' : SMS body, + * string 'origin' : SMS sender, + * ] + * + * ] + */ + public static function reception_callback(): array; + } diff --git a/adapters/BenchmarkAdapter.php b/adapters/BenchmarkAdapter.php index c872782..e874c8f 100644 --- a/adapters/BenchmarkAdapter.php +++ b/adapters/BenchmarkAdapter.php @@ -125,34 +125,21 @@ namespace adapters; { return false; } - - /** - * Does the implemented service support mms reception - */ - public static function meta_support_mms_reception(): bool - { - return false; - } /** - * Does the implemented service support mms sending + * Method called to send a SMS to a number. + * + * @param string $destination : Phone number to send the sms to + * @param string $text : Text of the SMS to send + * @param bool $flash : Is the SMS a Flash SMS + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * int 'uid' => Uid of the sms created on success + * ] */ - public static function meta_support_mms_sending(): bool - { - return false; - } - - public static function meta_support_inbound_call_callback(): bool - { - return false; - } - - public static function meta_support_end_call_callback(): bool - { - return false; - } - - public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array + public function send(string $destination, string $text, bool $flash = false) { $response = [ 'error' => false, @@ -226,18 +213,14 @@ namespace adapters; return []; } + /** + * Method called to verify if the adapter is working correctly + * should be use for exemple to verify that credentials and number are both valid. + * + * @return bool : False on error, true else + */ public function test(): bool { return true; } - - public function inbound_call_callback(): array - { - return []; - } - - public function end_call_callback(): array - { - return []; - } } diff --git a/adapters/GammuAdapter.php b/adapters/GammuAdapter.php index 3fd8a45..cf1bb18 100644 --- a/adapters/GammuAdapter.php +++ b/adapters/GammuAdapter.php @@ -135,34 +135,21 @@ namespace adapters; { return false; } - - /** - * Does the implemented service support mms reception - */ - public static function meta_support_mms_reception(): bool - { - return false; - } /** - * Does the implemented service support mms sending + * Method called to send a SMS to a number. + * + * @param string $destination : Phone number to send the sms to + * @param string $text : Text of the SMS to send + * @param bool $flash : Is the SMS a Flash SMS + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * ?string 'uid' => Uid of the sms created on success, null on error + * ] */ - public static function meta_support_mms_sending(): bool - { - return false; - } - - public static function meta_support_inbound_call_callback(): bool - { - return false; - } - - public static function meta_support_end_call_callback(): bool - { - return false; - } - - public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array + public function send(string $destination, string $text, bool $flash = false) { $response = [ 'error' => false, @@ -243,6 +230,15 @@ namespace adapters; return $response; } + /** + * Method called to read SMSs of the number. + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * array 'sms' => Array of the sms reads + * ] + */ public function read(): array { $response = [ @@ -291,31 +287,46 @@ namespace adapters; return $response; } + /** + * Method called to verify if the adapter is working correctly + * should be use for exemple to verify that credentials and number are both valid. + * + * @return bool : False on error, true else + */ public function test(): bool { //Always return true as we cannot test because we would be needing a root account return true; } + /** + * Method called on reception of a status update notification for a SMS. + * + * @return mixed : False on error, else array ['uid' => uid of the sms, 'status' => New status of the sms (\models\Sended::STATUS_UNKNOWN, \models\Sended::STATUS_DELIVERED, \models\Sended::STATUS_FAILED)] + */ public static function status_change_callback() { return false; } + /** + * Method called on reception of a sms notification. + * + * @return array : [ + * bool 'error' => false on success, true on error + * ?string 'error_message' => null on success, error message else + * array 'sms' => array [ + * string 'at' : Recepetion date format Y-m-d H:i:s, + * string 'text' : SMS body, + * string 'origin' : SMS sender, + * ] + * + * ] + */ public static function reception_callback(): array { return []; } - - public function inbound_call_callback(): array - { - return []; - } - - public function end_call_callback(): array - { - return []; - } /** * Function to unlock pin. diff --git a/adapters/OctopushShortcodeAdapter.php b/adapters/OctopushShortcodeAdapter.php index e2d4240..667a872 100644 --- a/adapters/OctopushShortcodeAdapter.php +++ b/adapters/OctopushShortcodeAdapter.php @@ -172,34 +172,21 @@ class OctopushShortcodeAdapter implements AdapterInterface { return true; } - - /** - * Does the implemented service support mms reception - */ - public static function meta_support_mms_reception(): bool - { - return false; - } /** - * Does the implemented service support mms sending + * Method called to send a SMS to a number. + * + * @param string $destination : Phone number to send the sms to + * @param string $text : Text of the SMS to send + * @param bool $flash : Is the SMS a Flash SMS + * + * @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 + * ] */ - public static function meta_support_mms_sending(): bool - { - return false; - } - - public static function meta_support_inbound_call_callback(): bool - { - return false; - } - - public static function meta_support_end_call_callback(): bool - { - return false; - } - - public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array + public function send(string $destination, string $text, bool $flash = false) { $response = [ 'error' => false, @@ -281,11 +268,26 @@ class OctopushShortcodeAdapter implements AdapterInterface } } + /** + * Method called to read SMSs of the number. + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * array 'sms' => Array of the sms reads + * ] + */ public function read(): array { return []; } + /** + * Method called to verify if the adapter is working correctly + * should be use for exemple to verify that credentials and number are both valid. + * + * @return bool : False on error, true else + */ public function test(): bool { try @@ -337,6 +339,11 @@ class OctopushShortcodeAdapter implements AdapterInterface } } + /** + * Method called on reception of a status update notification for a SMS. + * + * @return mixed : False on error, else array ['uid' => uid of the sms, 'status' => New status of the sms (\models\Sended::STATUS_UNKNOWN, \models\Sended::STATUS_DELIVERED, \models\Sended::STATUS_FAILED)] + */ public static function status_change_callback() { header('Connection: close'); @@ -376,6 +383,20 @@ class OctopushShortcodeAdapter implements AdapterInterface return ['uid' => $uid, 'status' => $status]; } + /** + * Method called on reception of a sms notification. + * + * @return array : [ + * bool 'error' => false on success, true on error + * ?string 'error_message' => null on success, error message else + * array 'sms' => array [ + * string 'at' : Recepetion date format Y-m-d H:i:s, + * string 'text' : SMS body, + * string 'origin' : SMS sender, + * ] + * + * ] + */ public static function reception_callback(): array { $response = [ @@ -417,14 +438,4 @@ class OctopushShortcodeAdapter implements AdapterInterface return $response; } - - public function inbound_call_callback(): array - { - return []; - } - - public function end_call_callback(): array - { - return []; - } } diff --git a/adapters/OctopushVirtualNumberAdapter.php b/adapters/OctopushVirtualNumberAdapter.php index d38eb29..1fc5305 100644 --- a/adapters/OctopushVirtualNumberAdapter.php +++ b/adapters/OctopushVirtualNumberAdapter.php @@ -177,34 +177,21 @@ class OctopushVirtualNumberAdapter implements AdapterInterface { return true; } - - /** - * Does the implemented service support mms reception - */ - public static function meta_support_mms_reception(): bool - { - return false; - } /** - * Does the implemented service support mms sending + * Method called to send a SMS to a number. + * + * @param string $destination : Phone number to send the sms to + * @param string $text : Text of the SMS to send + * @param bool $flash : Is the SMS a Flash SMS + * + * @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 + * ] */ - public static function meta_support_mms_sending(): bool - { - return false; - } - - public static function meta_support_inbound_call_callback(): bool - { - return false; - } - - public static function meta_support_end_call_callback(): bool - { - return false; - } - - public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array + public function send(string $destination, string $text, bool $flash = false) { $response = [ 'error' => false, @@ -281,11 +268,26 @@ class OctopushVirtualNumberAdapter implements AdapterInterface } } + /** + * Method called to read SMSs of the number. + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * array 'sms' => Array of the sms reads + * ] + */ public function read(): array { return []; } + /** + * Method called to verify if the adapter is working correctly + * should be use for exemple to verify that credentials and number are both valid. + * + * @return bool : False on error, true else + */ public function test(): bool { try @@ -337,6 +339,11 @@ class OctopushVirtualNumberAdapter implements AdapterInterface } } + /** + * Method called on reception of a status update notification for a SMS. + * + * @return mixed : False on error, else array ['uid' => uid of the sms, 'status' => New status of the sms (\models\Sended::STATUS_UNKNOWN, \models\Sended::STATUS_DELIVERED, \models\Sended::STATUS_FAILED)] + */ public static function status_change_callback() { header('Connection: close'); @@ -376,6 +383,20 @@ class OctopushVirtualNumberAdapter implements AdapterInterface return ['uid' => $uid, 'status' => $status]; } + /** + * Method called on reception of a sms notification. + * + * @return array : [ + * bool 'error' => false on success, true on error + * ?string 'error_message' => null on success, error message else + * array 'sms' => array [ + * string 'at' : Recepetion date format Y-m-d H:i:s, + * string 'text' : SMS body, + * string 'origin' : SMS sender, + * ] + * + * ] + */ public static function reception_callback(): array { $response = [ @@ -417,14 +438,4 @@ class OctopushVirtualNumberAdapter implements AdapterInterface return $response; } - - public function inbound_call_callback(): array - { - return []; - } - - public function end_call_callback(): array - { - return []; - } } diff --git a/adapters/OvhSmsShortcodeAdapter.php b/adapters/OvhSmsShortcodeAdapter.php index 9c6137b..dd68aff 100644 --- a/adapters/OvhSmsShortcodeAdapter.php +++ b/adapters/OvhSmsShortcodeAdapter.php @@ -169,34 +169,21 @@ namespace adapters; { return false; } - - /** - * Does the implemented service support mms reception - */ - public static function meta_support_mms_reception(): bool - { - return false; - } /** - * Does the implemented service support mms sending + * Method called to send a SMS to a number. + * + * @param string $destination : Phone number to send the sms to + * @param string $text : Text of the SMS to send + * @param bool $flash : Is the SMS a Flash SMS + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * ?string 'uid' => Uid of the sms created on success + * ] */ - public static function meta_support_mms_sending(): bool - { - return false; - } - - public static function meta_support_inbound_call_callback(): bool - { - return false; - } - - public static function meta_support_end_call_callback(): bool - { - return false; - } - - public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array + public function send(string $destination, string $text, bool $flash = false) { $response = [ 'error' => false, @@ -254,6 +241,15 @@ namespace adapters; } } + /** + * Method called to read SMSs of the number. + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * array 'sms' => Array of the sms reads + * ] + */ public function read(): array { $response = [ @@ -310,6 +306,12 @@ namespace adapters; } } + /** + * Method called to verify if the adapter is working correctly + * should be use for exemple to verify that credentials and number are both valid. + * + * @return bool : False on error, true else + */ public function test(): bool { try @@ -333,6 +335,11 @@ namespace adapters; } } + /** + * Method called on reception of a status update notification for a SMS. + * + * @return mixed : False on error, else array ['uid' => uid of the sms, 'status' => New status of the sms (\models\Sended::STATUS_UNKNOWN, \models\Sended::STATUS_DELIVERED, \models\Sended::STATUS_FAILED)] + */ public static function status_change_callback() { $uid = $_GET['id'] ?? false; @@ -365,18 +372,22 @@ namespace adapters; return ['uid' => $uid, 'status' => $status]; } + /** + * Method called on reception of a sms notification. + * + * @return array : [ + * bool 'error' => false on success, true on error + * ?string 'error_message' => null on success, error message else + * array 'sms' => array [ + * string 'at' : Recepetion date format Y-m-d H:i:s, + * string 'text' : SMS body, + * string 'origin' : SMS sender, + * ] + * + * ] + */ public static function reception_callback(): array { return []; } - - public function inbound_call_callback(): array - { - return []; - } - - public function end_call_callback(): array - { - return []; - } } diff --git a/adapters/OvhSmsVirtualNumberAdapter.php b/adapters/OvhSmsVirtualNumberAdapter.php index 35925a3..1217295 100644 --- a/adapters/OvhSmsVirtualNumberAdapter.php +++ b/adapters/OvhSmsVirtualNumberAdapter.php @@ -180,34 +180,21 @@ namespace adapters; { return false; } - - /** - * Does the implemented service support mms reception - */ - public static function meta_support_mms_reception(): bool - { - return false; - } /** - * Does the implemented service support mms sending + * Method called to send a SMS to a number. + * + * @param string $destination : Phone number to send the sms to + * @param string $text : Text of the SMS to send + * @param bool $flash : Is the SMS a Flash SMS + * + * @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 + * ] */ - public static function meta_support_mms_sending(): bool - { - return false; - } - - public static function meta_support_inbound_call_callback(): bool - { - return false; - } - - public static function meta_support_end_call_callback(): bool - { - return false; - } - - public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array + public function send(string $destination, string $text, bool $flash = false) { $response = [ 'error' => false, @@ -258,6 +245,15 @@ namespace adapters; } } + /** + * Method called to read SMSs of the number. + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * array 'sms' => Array of the sms reads + * ] + */ public function read(): array { $response = [ @@ -308,6 +304,12 @@ namespace adapters; } } + /** + * Method called to verify if the adapter is working correctly + * should be use for exemple to verify that credentials and number are both valid. + * + * @return bool : False on error, true else + */ public function test(): bool { try @@ -332,6 +334,11 @@ namespace adapters; } } + /** + * Method called on reception of a status update notification for a SMS. + * + * @return mixed : False on error, else array ['uid' => uid of the sms, 'status' => New status of the sms (\models\Sended::STATUS_UNKNOWN, \models\Sended::STATUS_DELIVERED, \models\Sended::STATUS_FAILED)] + */ public static function status_change_callback() { $uid = $_GET['id'] ?? false; @@ -364,18 +371,22 @@ namespace adapters; return ['uid' => $uid, 'status' => $status]; } + /** + * Method called on reception of a sms notification. + * + * @return array : [ + * bool 'error' => false on success, true on error + * ?string 'error_message' => null on success, error message else + * array 'sms' => array [ + * string 'at' : Recepetion date format Y-m-d H:i:s, + * string 'text' : SMS body, + * string 'origin' : SMS sender, + * ] + * + * ] + */ public static function reception_callback(): array { return []; } - - public function inbound_call_callback(): array - { - return []; - } - - public function end_call_callback(): array - { - return []; - } } diff --git a/adapters/TestAdapter.php b/adapters/TestAdapter.php index 3745c71..2851fb6 100644 --- a/adapters/TestAdapter.php +++ b/adapters/TestAdapter.php @@ -130,34 +130,21 @@ namespace adapters; { return false; } - - /** - * Does the implemented service support mms reception - */ - public static function meta_support_mms_reception(): bool - { - return true; - } /** - * Does the implemented service support mms sending + * Method called to send a SMS to a number. + * + * @param string $destination : Phone number to send the sms to + * @param string $text : Text of the SMS to send + * @param bool $flash : Is the SMS a Flash SMS + * + * @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 + * ] */ - public static function meta_support_mms_sending(): bool - { - return true; - } - - public static function meta_support_inbound_call_callback(): bool - { - return true; - } - - public static function meta_support_end_call_callback(): bool - { - return true; - } - - public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array + public function send(string $destination, string $text, bool $flash = false) { $response = [ 'error' => false, @@ -168,7 +155,7 @@ namespace adapters; $uid = uniqid(); $at = (new \DateTime())->format('Y-m-d H:i:s'); - $success = file_put_contents($this->test_file_write, json_encode(['uid' => $uid, 'at' => $at, 'destination' => $destination, 'text' => $text, 'flash' => $flash, 'mms' => $mms, 'medias' => $medias]) . "\n", FILE_APPEND); + $success = file_put_contents($this->test_file_write, json_encode(['uid' => $uid, 'at' => $at, 'destination' => $destination, 'text' => $text, 'flash' => $flash]) . "\n", FILE_APPEND); if (false === $success) { $response['error'] = true; @@ -183,19 +170,14 @@ namespace adapters; } /** - * Read from a files to simulate sms reception. - * In the file we expect a series of lines, each line beeing a SMS as a json string of format : - * { - * "at" : "2021-03-26 11:21:48", - * "medias" : [ - * "https://unsplash.com/photos/q4DJVtxES0w/download?force=true&w=640", - * "/tmp/somelocalfile.jpg" - * ], - * "mms" : true, - * "origin" : "+33612345678", - * "text" : "SMS Text" - * } - */ + * Method called to read SMSs of the number. + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * array 'sms' => Array of the sms reads + * ] + */ public function read(): array { $response = [ @@ -235,36 +217,7 @@ namespace adapters; continue; } - $clean_sms = [ - 'at' => $decode_sms['at'], - 'text' => $decode_sms['text'], - 'origin' => $decode_sms['origin'], - 'mms' => $decode_sms['mms'], - 'medias' => [], - ]; - - //In medias we want a media URI or URL - foreach ($decode_sms['medias'] ?? [] as $media) - { - $tempfile = tempnam('/tmp', 'raspisms-media-'); - if (!$tempfile) - { - continue; - } - - $copy = copy($media, $tempfile); - if (!$copy) - { - continue; - } - - $clean_sms['medias'][] = [ - 'filepath' => $tempfile, - 'extension' => pathinfo($media, PATHINFO_EXTENSION) ?: null, - ]; - } - - $response['smss'][] = $clean_sms; + $response['smss'][] = $decode_sms; } return $response; @@ -278,11 +231,20 @@ namespace adapters; } } + /** + * Method called to verify if the adapter is working correctly + * should be use for exemple to verify that credentials and number are both valid. + * + * @return bool : False on error, true else + */ public function test(): bool { return true; } + /** + * Method called on reception of a status update notification for a SMS. + */ public static function status_change_callback() { $uid = $_GET['uid'] ?? false; @@ -319,62 +281,22 @@ namespace adapters; return $return; } + /** + * Method called on reception of a sms notification. + * + * @return array : [ + * bool 'error' => false on success, true on error + * ?string 'error_message' => null on success, error message else + * array 'sms' => array [ + * string 'at' : Recepetion date format Y-m-d H:i:s, + * string 'text' : SMS body, + * string 'origin' : SMS sender, + * ] + * + * ] + */ public static function reception_callback(): array { return []; } - - public function inbound_call_callback(): array - { - $response = [ - 'error' => false, - 'error_message' => null, - 'call' => [], - ]; - - $uid = $_POST['uid'] ?? false; - $start = $_POST['start'] ?? false; - $end = $_POST['end'] ?? null; - $origin = $_POST['origin'] ?? false; - - if (!$uid || !$start || !$origin) - { - $response['error'] = true; - $response['error_message'] = 'Missing required argument.'; - - return $response; - } - - $response['call']['uid'] = $uid; - $response['call']['start'] = $start; - $response['call']['end'] = $end; - $response['call']['origin'] = $origin; - - return $response; - } - - public function end_call_callback(): array - { - $response = [ - 'error' => false, - 'error_message' => null, - 'call' => [], - ]; - - $uid = $_POST['uid'] ?? false; - $end = $_POST['end'] ?? null; - - if (!$uid || !$end) - { - $response['error'] = true; - $response['error_message'] = 'Missing required argument.'; - - return $response; - } - - $response['call']['uid'] = $uid; - $response['call']['end'] = $end; - - return $response; - } } diff --git a/adapters/TwilioVirtualNumberAdapter.php b/adapters/TwilioVirtualNumberAdapter.php index a753d9e..2835d84 100644 --- a/adapters/TwilioVirtualNumberAdapter.php +++ b/adapters/TwilioVirtualNumberAdapter.php @@ -176,32 +176,19 @@ class TwilioVirtualNumberAdapter implements AdapterInterface } /** - * Does the implemented service support mms reception + * Method called to send a SMS to a number. + * + * @param string $destination : Phone number to send the sms to + * @param string $text : Text of the SMS to send + * @param bool $flash : Is the SMS a Flash SMS + * + * @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 + * ] */ - public static function meta_support_mms_reception(): bool - { - return false; - } - - /** - * Does the implemented service support mms sending - */ - public static function meta_support_mms_sending(): bool - { - return false; - } - - public static function meta_support_inbound_call_callback(): bool - { - return false; - } - - public static function meta_support_end_call_callback(): bool - { - return false; - } - - public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array + public function send(string $destination, string $text, bool $flash = false) { $response = [ 'error' => false, @@ -241,6 +228,15 @@ class TwilioVirtualNumberAdapter implements AdapterInterface } } + /** + * Method called to read SMSs of the number. + * + * @return array : [ + * bool 'error' => false if no error, true else + * ?string 'error_message' => null if no error, else error message + * array 'sms' => Array of the sms reads + * ] + */ public function read(): array { $response = [ @@ -286,6 +282,12 @@ class TwilioVirtualNumberAdapter implements AdapterInterface } } + /** + * Method called to verify if the adapter is working correctly + * should be use for exemple to verify that credentials and number are both valid. + * + * @return bool : False on error, true else + */ public function test(): bool { try @@ -311,6 +313,11 @@ class TwilioVirtualNumberAdapter implements AdapterInterface } } + /** + * Method called on reception of a status update notification for a SMS. + * + * @return mixed : False on error, else array ['uid' => uid of the sms, 'status' => New status of the sms (\models\Sended::STATUS_UNKNOWN, \models\Sended::STATUS_DELIVERED, \models\Sended::STATUS_FAILED)] + */ public static function status_change_callback() { $sid = $_REQUEST['MessageSid'] ?? false; @@ -342,18 +349,22 @@ class TwilioVirtualNumberAdapter implements AdapterInterface return ['uid' => $sid, 'status' => $status]; } + /** + * Method called on reception of a sms notification. + * + * @return array : [ + * bool 'error' => false on success, true on error + * ?string 'error_message' => null on success, error message else + * array 'sms' => array [ + * string 'at' : Recepetion date format Y-m-d H:i:s, + * string 'text' : SMS body, + * string 'origin' : SMS sender, + * ] + * + * ] + */ public static function reception_callback(): array { return []; } - - public function inbound_call_callback(): array - { - return []; - } - - public function end_call_callback(): array - { - return []; - } } diff --git a/assets/css/style.css b/assets/css/style.css index 1bda82d..8be577c 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -205,34 +205,6 @@ footer img font-size: 0.9em; } -.discussion-message-medias img -{ - transition-duration: 0.1s; - max-width: 150px; - max-height: 150px; - line-height: 150px; - width: auto; - height: auto; -} - -.discussion-message-medias img:hover -{ - opacity: 0.6; -} - -.discussion-message-media -{ - display: inline-block; - line-height: 160px; - width: 160px; - height: 160px; - padding: 5px; - background-color: rgba(255, 255, 255, 0.3); - vertical-align: middle; - text-align: center; - margin: 5px; -} - .message-container { margin-bottom: 10px; @@ -282,12 +254,6 @@ footer img margin-top: 8px; } -.message-input input[type="file"] -{ - margin-top: 8px; - display: inline-block; -} - .message-in-progress-hover { position: absolute; @@ -442,21 +408,3 @@ footer img { margin-bottom: 30px; } - - -/** - * Contacts conditional deletion - */ -.conditional-deletion-preview-container -{ - margin-top: 10px; - margin-bottom: 20px; - text-align: right; -} - -.conditional-deletion-preview-container label, -.conditional-deletion-preview-container select -{ - display: inline-block; - width: auto; -} diff --git a/assets/js/custom.js b/assets/js/custom.js index b25910a..eb2b6f9 100644 --- a/assets/js/custom.js +++ b/assets/js/custom.js @@ -45,9 +45,8 @@ function verifReceived() /** * Cette fonction permet de scroller au dernier message - * @param force: bool : should we force the scroll */ -function scrollDownDiscussion(force) +function scrollDownDiscussion() { var discussion_height = jQuery('.discussion-container').innerHeight(); var discussion_scroll_height = jQuery('.discussion-container')[0].scrollHeight; @@ -55,7 +54,7 @@ function scrollDownDiscussion(force) var scroll_before_end = discussion_scroll_height - (discussion_scroll_top + discussion_height); //On scroll uniquement si on a pas remonté plus haut que la moitié de la fenetre de discussion - if (force || scroll_before_end <= discussion_height / 2) + if (scroll_before_end <= discussion_height / 2) { jQuery('.discussion-container').animate({scrollTop: 1000000}); } @@ -116,8 +115,8 @@ jQuery(document).ready(function() var form = jQuery(this); var message = form.find('textarea').val(); var formData = new FormData(form[0]); - jQuery('.discussion-container').find('#send-message-spinner').remove(); - jQuery('.discussion-container').append('
'); + jQuery('.discussion-container').find('#send-message-spiner').remove(); + jQuery('.discussion-container').append('
'); scrollDownDiscussion(); jQuery.ajax({ url: form.attr('action'), @@ -131,7 +130,7 @@ jQuery(document).ready(function() if (!data.success) { showMessage(data.message.replace(//g, ">"), 0); - jQuery('.discussion-container').find('#send-message-spinner').remove(); + jQuery('.discussion-container').find('#send-message-spiner').remove(); } } }).done(function() diff --git a/composer.json b/composer.json index 7522544..608752a 100644 --- a/composer.json +++ b/composer.json @@ -12,9 +12,7 @@ "ovh/ovh": "^2.0", "twilio/sdk": "^6.1", "symfony/yaml": "^5.0", - "phpmailer/phpmailer": "^6.1", - "ralouphie/mimey": "^2.1", - "kreait/firebase-php": "^5.14" + "phpmailer/phpmailer": "^6.1" }, "require-dev": { } diff --git a/controllers/internals/Adapter.php b/controllers/internals/Adapter.php index 1fae465..50ef643 100644 --- a/controllers/internals/Adapter.php +++ b/controllers/internals/Adapter.php @@ -20,9 +20,9 @@ namespace controllers\internals; private const ADAPTERS_META_START = 'meta_'; /** - * List adapters with filepath and internal metas. + * List adapters using internal metas. * - * @return array : ['adapter_filepath' => ['meta...' => value, ...], ...] + * @return array */ public function list_adapters() { @@ -42,7 +42,7 @@ namespace controllers\internals; continue; } - $adapters[$file] = $metas; + $adapters[] = $metas; } return $adapters; @@ -116,29 +116,4 @@ namespace controllers\internals; return $metas; } - - /** - * List all adapters for a meta value - * - * @param $search_name : Name of the meta - * @param $search_value : Value of the meta - * - * @return array : Array with ['adapter filepath' => ['search_name' => value, ...], ...] - */ - public function list_adapters_with_meta_equal($search_name, $search_value) - { - $adapters = $this->list_adapters(); - return array_filter($adapters, function($metas) use ($search_name, $search_value) { - $match = false; - foreach ($metas as $name => $value) - { - if ($name === $search_name && $value === $search_value) - { - $match = true; - } - } - - return $match; - }); - } } diff --git a/controllers/internals/Call.php b/controllers/internals/Call.php deleted file mode 100644 index 4852c72..0000000 --- a/controllers/internals/Call.php +++ /dev/null @@ -1,138 +0,0 @@ - - * - * 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; - - class Call extends StandardController - { - protected $model; - - /** - * Create a call. - * - * @param int $id_user : Id of the user - * @param int $id_phone : Id of the phone that emitted (outbound) or received (inbound) the call - * @param string $uid : Uid of the phone call - * @param string $direction : Direction of the call, \models\Call::DIRECTION_INBOUND | \models\Call::DIRECTION_OUTBOUND - * @param string $start : Date of the call beginning - * @param ?string $end : Date of the call end - * @param ?string $origin : Origin of the call or null if outbound - * @param ?string $destination : Destination of the call or null if inbound - * - * @return mixed bool|int : false on error, new call id else - */ - public function create(int $id_user, int $id_phone, string $uid, string $direction, string $start, ?string $end = null, ?string $origin = null, ?string $destination = null) - { - $call = [ - 'id_user' => $id_user, - 'id_phone' => $id_phone, - 'uid' => $uid, - 'start' => $start, - 'end' => $end, - 'direction' => $direction, - 'origin' => $origin, - 'destination' => $destination, - ]; - - if (!$origin && !$destination) - { - return false; - } - - switch ($direction) - { - case \models\Call::DIRECTION_OUTBOUND : - if (null === $destination) { return false; } - break; - - case \models\Call::DIRECTION_INBOUND : - if (null === $origin) { return false; } - break; - - default : - return false; - } - - if (!\controllers\internals\Tool::validate_date($start, 'Y-m-d H:i:s')) - { - return false; - } - - if (null !== $end && !\controllers\internals\Tool::validate_date($end, 'Y-m-d H:i:s')) - { - return false; - } - - if (null !== $end && new \DateTime($end) < new \DateTime($start)) - { - return false; - } - - $new_call_id = $this->get_model()->insert($call); - if (!$new_call_id) - { - return false; - } - - $call['id'] = $new_call_id; - - $internal_webhook = new Webhook($this->bdd); - $internal_webhook->trigger($id_user, \models\Webhook::TYPE_INBOUND_CALL, $call); - - return $new_call_id; - } - - - /** - * End a call - * - * @param int $id_user : Id of the user to end call for - * @param int $id_phone : If of the phone to end call for - * @param string $uid : Uid of the call to end - * @param string $end : End date of the call, format Y-m-d H:i:s - * - * @return bool : False if cannot end phone call, true else - */ - public function end(int $id_user, int $id_phone, string $uid, string $end) - { - if (!\controllers\internals\Tool::validate_date($end, 'Y-m-d H:i:s')) - { - return false; - } - - $call = $this->get_model()->get_by_uid_and_phone_for_user($id_user, $id_phone, $uid); - if (!$call) - { - return false; - } - - if (new \DateTime($end) < new \DateTime($call['start'])) - { - return false; - } - - $datas = [ - 'end' => $end, - ]; - - return (bool) $this->get_model()->update_for_user($id_user, $call['id'], $datas); - } - - /** - * Get the model for the Controller. - */ - protected function get_model(): \descartes\Model - { - $this->model = $this->model ?? new \models\Call($this->bdd); - - return $this->model; - } - } diff --git a/controllers/internals/Console.php b/controllers/internals/Console.php index f2f3986..ccb48b6 100644 --- a/controllers/internals/Console.php +++ b/controllers/internals/Console.php @@ -151,23 +151,4 @@ namespace controllers\internals; exit($success ? 0 : 1); } - - - /** - * Delete medias that are no longer usefull - */ - public function clean_unused_medias() - { - $bdd = \descartes\Model::_connect(DATABASE_HOST, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD, 'UTF8'); - $internal_media = new \controllers\internals\Media($bdd); - - $medias = $internal_media->gets_unused(); - - foreach ($medias as $media) - { - $success = $internal_media->delete_for_user($media['id_user'], $media['id']); - - echo ($success === false ? '[KO]' : '[OK]') . ' - ' . $media['path'] . "\n"; - } - } } diff --git a/controllers/internals/Mailer.php b/controllers/internals/Mailer.php index 04d7204..2df5d3c 100755 --- a/controllers/internals/Mailer.php +++ b/controllers/internals/Mailer.php @@ -101,11 +101,10 @@ class Mailer extends \descartes\Controller * @param string $destination : email address to send email to * @param array $settings : Email settings * @param array $data : Data to inject into email template - * @param array $attachments : List of paths of files to attach to the mail * * @return bool : true on success, false on error */ - public function enqueue(string $destination, array $settings, array $data, array $attachments = []): bool + public function enqueue(string $destination, array $settings, array $data): bool { $response = $this->generate_body($settings, $data); @@ -114,7 +113,6 @@ class Mailer extends \descartes\Controller 'subject' => $settings['subject'], 'body' => $response['body'], 'alt_body' => $response['alt_body'], - 'attachments' => $attachments, ]; $error_code = null; diff --git a/controllers/internals/Media.php b/controllers/internals/Media.php index 2722aab..b02ff5f 100644 --- a/controllers/internals/Media.php +++ b/controllers/internals/Media.php @@ -11,299 +11,129 @@ namespace controllers\internals; -class Media extends StandardController -{ - const DEFAULT_CHMOD = 0660; - - protected $model; - - /** - * Create a media. - * - * @param int $id_user : Id of the user - * @param string $tmpfile_path : Path of the temporary local copy of the media - * @param ?string $extension : Extension to use for the media - * - * @return int : Exception on error, new media id else - */ - public function create(int $id_user, string $tmpfile_path, ?string $extension = null) + class Media extends StandardController { - $user_path = \controllers\internals\Tool::create_user_public_path($id_user); - if (!file_exists($tmpfile_path)) + protected $model; + + /** + * Create a media. + * + * @param int $id_user : Id of the user + * @param int $id_scheduled : Id of the scheduled + * @param array $media : $_FILES media array + * + * @return bool : false on error, new media id else + */ + public function create(int $id_user, int $id_scheduled, array $media): bool { - throw new \Exception('File ' . $tmpfile_path . ' does not exists.'); - } - - if (!is_readable($tmpfile_path)) - { - throw new \Exception('File ' . $tmpfile_path . ' is not readable.'); - } - - $mimey = new \Mimey\MimeTypes; - $extension = $extension ?? $mimey->getExtension(mime_content_type($tmpfile_path)); - - $new_file_name = \controllers\internals\Tool::random_uuid() . '.' . $extension; - $new_file_path = $user_path . '/' . $new_file_name; - $new_file_relpath = $id_user . '/' . $new_file_name; - - if (!file_put_contents($new_file_path, 'a')) - { - throw new \Exception('pute de merde'); - } - - if (!rename($tmpfile_path, $new_file_path)) - { - throw new \Exception('Cannot create file ' . $new_file_path); - } - - if (!chown($new_file_path, fileowner($user_path))) - { - throw new \Exception('Cannot give file ' . $new_file_path . ' to user : ' . fileowner($user_path)); - } - - if (!chgrp($new_file_path, filegroup($user_path))) - { - throw new \Exception('Cannot give file ' . $new_file_path . ' to group : ' . filegroup($user_path)); - } - - if (!chmod($new_file_path, self::DEFAULT_CHMOD)) - { - throw new \Exception('Cannot give file ' . $new_file_path . ' rights : ' . self::DEFAULT_CHMOD); - } - - $data = [ - 'path' => $new_file_relpath, - 'id_user' => $id_user, - ]; - - $new_media_id = $this->get_model()->insert($data); - if (!$new_media_id) - { - throw new \Exception('Cannot insert media in database.'); - } - - return $new_media_id; - } - - /** - * Upload and create a media - * - * @param int $id_user : Id of the user - * @param array $file : array representing uploaded file, extracted from $_FILES['yourfile'] - * @return int : Raise exception on error or return new media id on success - */ - public function create_from_uploaded_file_for_user(int $id_user, array $file) - { - $upload_result = \controllers\internals\Tool::read_uploaded_file($file); - if ($upload_result['success'] !== true) - { - throw new \Exception($upload_result['content']); - } - - //Move uploaded file to a tmp file - if (!$tmp_file = tempnam('/tmp', 'raspisms-media-')) - { - throw new \Exception('Cannot create tmp file in /tmp to store the uploaded file.'); - } - - if (!move_uploaded_file($upload_result['tmp_name'], $tmp_file)) - { - throw new \Exception('Cannot move uploaded file to : ' . $tmp_file); - } - - return $this->create($id_user, $tmp_file, $upload_result['extension']); - } - - /** - * Link a media to a scheduled, a received or a sended message - * @param int $id_media : Id of the media - * @param string $resource_type : Type of resource to link the media to ('scheduled', 'received' or 'sended') - * @param int $resource_id : Id of the resource to link the media to - * - * @return mixed bool|int : false on error, the new link id else - */ - public function link_to(int $id_media, string $resource_type, int $resource_id) - { - switch ($resource_type) - { - case 'scheduled': - return $this->get_model()->insert_media_scheduled($id_media, $resource_id); - break; - - case 'received': - return $this->get_model()->insert_media_received($id_media, $resource_id); - break; - - case 'sended': - return $this->get_model()->insert_media_sended($id_media, $resource_id); - break; - - default: - return false; - } - } - - - /** - * Unlink a media of a scheduled, a received or a sended message - * @param int $id_media : Id of the media - * @param string $resource_type : Type of resource to unlink the media of ('scheduled', 'received' or 'sended') - * @param int $resource_id : Id of the resource to unlink the media of - * - * @return mixed bool : false on error, true on success - */ - public function unlink_of(int $id_media, int $resource_type, int $resource_id) - { - switch ($resource_type) - { - case 'scheduled': - return $this->get_model()->delete_media_scheduled($id_media, $resource_id); - break; - - case 'received': - return $this->get_model()->delete_media_received($id_media, $resource_id); - break; - - case 'sended': - return $this->get_model()->delete_media_sended($id_media, $resource_id); - break; - - default: - return false; - } - } - - /** - * Unlink all medias of a scheduled, a received or a sended message - * @param string $resource_type : Type of resource to unlink the media of ('scheduled', 'received' or 'sended') - * @param int $resource_id : Id of the resource to unlink the media of - * - * @return mixed bool : false on error, true on success - */ - public function unlink_all_of(string $resource_type, int $resource_id) - { - switch ($resource_type) - { - case 'scheduled': - return $this->get_model()->delete_all_for_scheduled($resource_id); - break; - - case 'received': - return $this->get_model()->delete_all_for_received($resource_id); - break; - - case 'sended': - return $this->get_model()->delete_all_for_sended($resource_id); - break; - - default: - return false; - } - } - - /** - * Update a media for a user. - * - * @param int $id_user : user id - * @param int $id_media : Media id - * @param string $path : Path of the file - * - * @return bool : false on error, true on success - */ - public function update_for_user(int $id_user, int $id_media, string $path): bool - { - $media = [ - 'path' => $path, - ]; - - return (bool) $this->get_model()->update_for_user($id_user, $id_media, $media); - } - - /** - * Delete a media for a user. - * - * @param int $id_user : User id - * @param int $id : Entry id - * - * @return mixed bool|int : False on error, else number of removed rows - */ - public function delete_for_user(int $id_user, int $id_media): bool - { - $media = $this->get_model()->get_for_user($id_user, $id_media); - if (!$media) - { - return false; - } - - //Delete file - try - { - $filepath = PWD_DATA_PUBLIC . '/' . $media['path']; - if (file_exists($filepath)) + $internal_scheduled = new Scheduled($this->bdd); + $scheduled = $internal_scheduled->get_for_user($id_user, $id_scheduled); + if (!$scheduled) { - unlink($filepath); + return false; } + + $result_upload_media = \controllers\internals\Tool::upload_file($media); + if (false === $result_upload_media['success']) + { + return false; + } + + $data = [ + 'id_scheduled' => $id_scheduled, + 'path' => $result_upload_media['content'], + ]; + + return (bool) $this->get_model()->insert($data); } - catch (\Throwable $t) + + /** + * Update a media for a user. + * + * @param int $id_user : user id + * @param int $id_media : Media id + * @param int $id_scheduled : Id of the scheduled + * @param string $path : Path of the file + * + * @return bool : false on error, true on success + */ + public function update_for_user(int $id_user, int $id_media, int $id_scheduled, string $path): bool { - return false; + $media = [ + 'id_scheduled' => $id_scheduled, + 'path' => $path, + ]; + + $internal_scheduled = new Scheduled($this->bdd); + $scheduled = $this->get_for_user($id_user, $id_scheduled); + if (!$scheduled) + { + return false; + } + + return (bool) $this->get_model()->update_for_user($id_user, $id_media, $media); } - return $this->get_model()->delete_for_user($id_user, $id_media); - } + /** + * Delete a media for a user. + * + * @param int $id_user : User id + * @param int $id : Entry id + * + * @return int : Number of removed rows + */ + public function delete_for_user(int $id_user, int $id_media): bool + { + $media = $this->get_model()->get_for_user($id_user, $id_media); + if (!$media) + { + return false; + } - /** - * Find medias for a scheduled. - * - * @param int $id_scheduled : Scheduled id to fin medias for - * - * @return mixed : Medias || false - */ - public function gets_for_scheduled(int $id_scheduled) - { - return $this->get_model()->gets_for_scheduled($id_scheduled); - } + unlink($media['path']); - /** - * Find medias for a sended and a user. - * - * @param int $id_sended : Scheduled id to fin medias for - * - * @return mixed : Medias || false - */ - public function gets_for_sended(int $id_sended) - { - return $this->get_model()->gets_for_sended($id_sended); - } + return $this->get_model()->delete_for_user($id_user, $id_media); + } - /** - * Find medias for a received and a user. - * - * @param int $id_received : Scheduled id to fin medias for - * - * @return mixed : Medias || false - */ - public function gets_for_received(int $id_received) - { - return $this->get_model()->gets_for_received($id_received); - } + /** + * Delete a media for a scheduled and a user. + * + * @param int $id_user : User id + * @param int $id_scheduled : Scheduled id to delete medias for + * + * @return int : Number of removed rows + */ + public function delete_for_scheduled_and_user(int $id_user, int $id_scheduled): bool + { + $media = $this->get_model()->get_for_scheduled_and_user($id_user, $id_scheduled); + if ($media) + { + unlink($media['path']); + } - /** - * Find medias that are not used - * @return array - */ - public function gets_unused() - { - return $this->get_model()->gets_unused(); - } + return $this->get_model()->delete_for_scheduled_and_user($id_user, $id_scheduled); + } - /** - * Get the model for the Controller. - */ - protected function get_model(): \descartes\Model - { - $this->model = $this->model ?? new \models\Media($this->bdd); + /** + * Find medias for a scheduled and a user. + * + * @param int $id_user : User id + * @param int $id_scheduled : Scheduled id to delete medias for + * + * @return mixed : Medias || false + */ + public function get_for_scheduled_and_user(int $id_user, int $id_scheduled) + { + return $this->get_model()->get_for_scheduled_and_user($id_user, $id_scheduled); + } - return $this->model; + /** + * Get the model for the Controller. + */ + protected function get_model(): \descartes\Model + { + $this->model = $this->model ?? new \models\Media($this->bdd); + + return $this->model; + } } -} diff --git a/controllers/internals/Phone.php b/controllers/internals/Phone.php index 3b54c86..63a0b96 100644 --- a/controllers/internals/Phone.php +++ b/controllers/internals/Phone.php @@ -13,10 +13,6 @@ namespace controllers\internals; class Phone extends StandardController { - const MMS_SENDING = 'sending'; - const MMS_RECEPTION = 'reception'; - const MMS_BOTH = 'both'; - protected $model; /** @@ -43,63 +39,6 @@ namespace controllers\internals; return $this->get_model()->get_by_name($name); } - /** - * Check if a phone support mms - * - * @param int $id : id of the phone to check - * @param $type : type of sms support, a const from Phone, MMS_SENDING, MMS_RECEPTION or MMS_BOTH - * @return bool : true if support, false else - */ - public function support_mms (int $id, string $type) - { - $phone = $this->get_model()->get($id); - if (!$phone) - { - return false; - } - - switch ($type) - { - case self::MMS_SENDING : - return $phone['adapter']::meta_support_mms_sending(); - break; - - case self::MMS_RECEPTION : - return $phone['adapter']::meta_support_mms_reception(); - break; - - case self::MMS_BOTH : - return $phone['adapter']::meta_support_mms_sending() && $phone['adapter']::meta_support_mms_reception(); - break; - - default: - return false; - } - } - - /** - * Get all phones supporting mms for a user - * - * @param int $id_user : id of the user - * @param $type : type of sms support, a const from Phone, MMS_SENDING, MMS_RECEPTION or MMS_BOTH - * @return array : array of phones supporting mms - */ - public function gets_phone_supporting_mms_for_user (int $id_user, string $type) - { - $phones = $this->get_model()->gets_for_user($id_user); - - $valid_phones = []; - foreach ($phones as $phone) - { - if ($this->support_mms($phone['id'], $type)) - { - $valid_phones[] = $phone; - } - } - - return $valid_phones; - } - /** * Return a phone for a user by a name. * diff --git a/controllers/internals/Received.php b/controllers/internals/Received.php index c7c2b79..2293693 100644 --- a/controllers/internals/Received.php +++ b/controllers/internals/Received.php @@ -39,12 +39,10 @@ namespace controllers\internals; * @param string $origin : Number of the sender * @param string $status : Status of the received message * @param bool $command : Is the sms a command - * @param bool $mms : Is the sms a mms - * @param array $media_ids : Ids of the medias to link to received * * @return mixed : false on error, new received id else */ - public function create(int $id_user, int $id_phone, $at, string $text, string $origin, string $status = 'unread', bool $command = false, bool $mms = false, array $media_ids = []) + public function create(int $id_user, int $id_phone, $at, string $text, string $origin, string $status = 'unread', bool $command = false) { $received = [ 'id_user' => $id_user, @@ -54,39 +52,9 @@ namespace controllers\internals; 'origin' => $origin, 'status' => $status, 'command' => $command, - 'mms' => $mms, ]; - //use a transaction to ensure received and media links are created at the same time - $this->bdd->beginTransaction(); - - $id_received = $this->get_model()->insert($received); - if (!$id_received) - { - $this->bdd->rollBack(); - return false; - } - - //Link medias - $internal_media = new Media($this->bdd); - foreach ($media_ids as $media_id) - { - $id_media_received = $internal_media->link_to($media_id, 'received', $id_received); - if (!$id_media_received) - { - $this->bdd->rollBack(); - return false; - } - } - - //All ok, commit - $success = $this->bdd->commit(); - if (!$success) - { - return false; - } - - return $id_received; + return $this->get_model()->insert($received); } /** @@ -161,19 +129,6 @@ namespace controllers\internals; return $this->get_model()->gets_by_origin_and_user($id_user, $origin); } - /** - * Return receiveds for an origin and a user since a date. - * - * @param int $id_user : User id - * @param string $since : Date we want messages since format Y-m-d H:i:s - * @param string $origin : Number who sent the message - * @return array - */ - public function gets_since_date_by_origin_and_user(int $id_user, string $since, string $origin) - { - return $this->get_model()->gets_since_date_by_origin_and_user($id_user, $since, $origin); - } - /** * Get number of sended SMS for every date since a date for a specific user. * @@ -256,18 +211,13 @@ namespace controllers\internals; * @param string $origin : Number of the sender * @param ?string $at : Message reception date, if null use current date * @param string $status : Status of a the sms. By default \models\Received::STATUS_UNREAD - * @param bool $mms : Is the sms a mms - * @param array $medias : Empty array if no medias, or medias to create and link to the received message. Format : [[ - * string 'filepath' => local path to a readable copy of the media, - * ?string 'extension' => extension to use for the file or null - * ], ...] * * @return array : [ * bool 'error' => false if success, true else * ?string 'error_message' => null if success, error message else * ] */ - public function receive(int $id_user, int $id_phone, string $text, string $origin, ?string $at = null, string $status = \models\Received::STATUS_UNREAD, bool $mms = false, array $medias = []): array + public function receive(int $id_user, int $id_phone, string $text, string $origin, ?string $at = null, string $status = \models\Received::STATUS_UNREAD): array { $return = [ 'error' => false, @@ -285,28 +235,8 @@ namespace controllers\internals; $is_command = true; $text = $response; } - - //We create medias to link to the sms - $internal_media = new Media($this->bdd); - $media_ids = []; - if ($mms) - { - foreach ($medias as $media) - { - try - { - $new_media_id = $internal_media->create($id_user, $media['filepath'], $media['extension']); - $media_ids[] = $new_media_id; - } - catch (\Throwable $t) - { - $return['error_message'] = $t->getMessage(); - continue; //Better loose the media than the message - } - } - } - $received_id = $this->create($id_user, $id_phone, $at, $text, $origin, $status, $is_command, $mms, $media_ids); + $received_id = $this->create($id_user, $id_phone, $at, $text, $origin, $status, $is_command); if (!$received_id) { $return['error'] = true; @@ -321,13 +251,10 @@ namespace controllers\internals; 'text' => $text, 'destination' => $id_phone, 'origin' => $origin, - 'command' => $is_command, - 'mms' => $mms, - 'medias' => $internal_media->gets_in_for_user($id_user, $media_ids), ]; $internal_webhook = new Webhook($this->bdd); - $internal_webhook->trigger($id_user, \models\Webhook::TYPE_RECEIVE_SMS, $received); + $internal_webhook->trigger($id_user, \models\Webhook::TYPE_RECEIVE, $received); $internal_user = new User($this->bdd); $internal_user->transfer_received($id_user, $received); diff --git a/controllers/internals/Scheduled.php b/controllers/internals/Scheduled.php index a7c65df..ae99361 100644 --- a/controllers/internals/Scheduled.php +++ b/controllers/internals/Scheduled.php @@ -23,16 +23,14 @@ namespace controllers\internals; * @param string $text : Text of the message * @param ?int $id_phone : Id of the phone to send message with, null by default * @param bool $flash : Is the sms a flash sms, by default false - * @param bool $mms : Is the sms a mms, by default false * @param array $numbers : Numbers to send message to * @param array $contacts_ids : Contact ids to send message to * @param array $groups_ids : Group ids to send message to * @param array $conditional_group_ids : Conditional Groups ids to send message to - * @param array $media_ids : Ids of the medias to link to scheduled message * * @return bool : false on error, new id on success */ - public function create(int $id_user, $at, string $text, ?int $id_phone = null, bool $flash = false, bool $mms = false, array $numbers = [], array $contacts_ids = [], array $groups_ids = [], array $conditional_group_ids = [], array $media_ids = []) + public function create(int $id_user, $at, string $text, ?int $id_phone = null, bool $flash = false, array $numbers = [], array $contacts_ids = [], array $groups_ids = [], array $conditional_group_ids = []) { $scheduled = [ 'id_user' => $id_user, @@ -40,14 +38,8 @@ namespace controllers\internals; 'text' => $text, 'id_phone' => $id_phone, 'flash' => $flash, - 'mms' => $mms, ]; - if ($text === '') - { - return false; - } - if (null !== $id_phone) { $internal_phone = new Phone($this->bdd); @@ -59,28 +51,12 @@ namespace controllers\internals; } } - //Use transaction to garanty atomicity - $this->bdd->beginTransaction(); - $id_scheduled = $this->get_model()->insert($scheduled); if (!$id_scheduled) { - $this->bdd->rollBack(); return false; } - $internal_media = new Media($this->bdd); - foreach ($media_ids as $media_id) - { - $id_media_scheduled = $internal_media->link_to($media_id, 'scheduled', $id_scheduled); - if (!$id_media_scheduled) - { - $this->bdd->rollBack(); - return false; - } - } - - foreach ($numbers as $number) { $this->get_model()->insert_scheduled_number($id_scheduled, $number); @@ -122,12 +98,6 @@ namespace controllers\internals; $this->get_model()->insert_scheduled_conditional_group_relation($id_scheduled, $conditional_group_id); } - $success = $this->bdd->commit(); - if (!$success) - { - return false; - } - $date = date('Y-m-d H:i:s'); $internal_event = new Event($this->bdd); $internal_event->create($id_user, 'SCHEDULED_ADD', 'Ajout d\'un Sms pour le ' . $date . '.'); @@ -144,23 +114,20 @@ namespace controllers\internals; * @param string $text : Text of the message * @param ?int $id_phone : Id of the phone to send message with, null by default * @param bool $flash : Is the sms a flash sms, by default false - * @param bool $mms : Is the sms a mms, by default false * @param array $numbers : Numbers to send message to * @param array $contacts_ids : Contact ids to send message to * @param array $groups_ids : Group ids to send message to * @param array $conditional_group_ids : Conditional Groups ids to send message to - * @param array $media_ids : Ids of the medias to link to scheduled message * - * @return bool : false on error, true on success + * @return bool : false on error, new id on success */ - public function update_for_user(int $id_user, int $id_scheduled, $at, string $text, ?string $id_phone = null, bool $flash = false, bool $mms = false, array $numbers = [], array $contacts_ids = [], array $groups_ids = [], array $conditional_group_ids = [], array $media_ids = []) + public function update_for_user(int $id_user, int $id_scheduled, $at, string $text, ?string $id_phone = null, bool $flash = false, array $numbers = [], array $contacts_ids = [], array $groups_ids = [], array $conditional_group_ids = []) { $scheduled = [ 'id_user' => $id_user, 'at' => $at, 'text' => $text, 'id_phone' => $id_phone, - 'mms' => $mms, 'flash' => $flash, ]; @@ -175,27 +142,12 @@ namespace controllers\internals; } } - //Ensure atomicity - $this->bdd->beginTransaction(); - $success = (bool) $this->get_model()->update_for_user($id_user, $id_scheduled, $scheduled); $this->get_model()->delete_scheduled_numbers($id_scheduled); $this->get_model()->delete_scheduled_contact_relations($id_scheduled); $this->get_model()->delete_scheduled_group_relations($id_scheduled); $this->get_model()->delete_scheduled_conditional_group_relations($id_scheduled); - $internal_media = new Media($this->bdd); - $internal_media->unlink_all_of('scheduled', $id_scheduled); - - foreach ($media_ids as $media_id) - { - $id_media_scheduled = $internal_media->link_to($media_id, 'scheduled', $id_scheduled); - if (!$id_media_scheduled) - { - $this->bdd->rollBack(); - return false; - } - } foreach ($numbers as $number) { @@ -238,7 +190,7 @@ namespace controllers\internals; $this->get_model()->insert_scheduled_conditional_group_relation($id_scheduled, $conditional_group_id); } - return $this->bdd->commit(); + return true; } /** @@ -254,25 +206,11 @@ namespace controllers\internals; { return $this->get_model()->gets_before_date_for_number_and_user($id_user, $date, $number); } - - /** - * Get messages scheduled after a date for a number and a user. - * - * @param int $id_user : User id - * @param $date : Date after which we want messages - * @param string $number : Number for which we want messages - * - * @return array - */ - public function gets_after_date_for_number_and_user(int $id_user, $date, string $number) - { - 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 : [['id_scheduled', 'text', 'id_phone', 'destination', 'flash', 'mms', 'medias'], ...] + * @return array : [['id_scheduled', 'text', 'id_phone', 'destination', 'flash'], ...] */ public function get_smss_to_send() { @@ -286,7 +224,6 @@ namespace controllers\internals; $users_settings = []; $users_phones = []; - $users_mms_phones = []; $now = new \DateTime(); $now = $now->format('Y-m-d H:i:s'); @@ -307,16 +244,7 @@ namespace controllers\internals; 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 - if ($scheduled['mms']) - { - $internal_media = new Media($this->bdd); - $scheduled['medias'] = $internal_media->gets_for_scheduled($scheduled['id']); } $phone_to_use = null; @@ -338,16 +266,8 @@ namespace controllers\internals; { 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]; - } + $rnd_key = array_rand($users_phones[$scheduled['id_user']]); + $random_phone = $users_phones[$scheduled['id_user']][$rnd_key]; } $message = [ @@ -356,8 +276,6 @@ namespace controllers\internals; '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)) @@ -408,16 +326,8 @@ namespace controllers\internals; 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]; - } + $rnd_key = array_rand($users_phones[$scheduled['id_user']]); + $random_phone = $users_phones[$scheduled['id_user']][$rnd_key]; } $message = [ @@ -426,8 +336,6 @@ namespace controllers\internals; '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)) @@ -460,7 +368,7 @@ namespace controllers\internals; foreach ($messages as $message) { //Remove empty messages - if ('' === trim($message['text']) && !$message['medias']) + if ('' === trim($message['text'])) { continue; } diff --git a/controllers/internals/Sended.php b/controllers/internals/Sended.php index 2e24327..82bd14e 100644 --- a/controllers/internals/Sended.php +++ b/controllers/internals/Sended.php @@ -26,13 +26,11 @@ namespace controllers\internals; * @param string $uid : Uid of the sms on the adapter service used * @param string $adapter : Name of the adapter service used to send the message * @param bool $flash : Is the sms a flash - * @param bool $mms : Is the sms a MMS. By default false. - * @param array $medias : Array of medias to link to the MMS. * @param string $status : Status of a the sms. By default \models\Sended::STATUS_UNKNOWN * * @return mixed : false on error, new sended id else */ - public function create(int $id_user, int $id_phone, $at, string $text, string $destination, string $uid, string $adapter, bool $flash = false, bool $mms = false, array $medias = [], ?string $status = \models\Sended::STATUS_UNKNOWN) + public function create(int $id_user, int $id_phone, $at, string $text, string $destination, string $uid, string $adapter, bool $flash = false, ?string $status = \models\Sended::STATUS_UNKNOWN) { $sended = [ 'id_user' => $id_user, @@ -43,33 +41,10 @@ namespace controllers\internals; 'uid' => $uid, 'adapter' => $adapter, 'flash' => $flash, - 'mms' => $mms, 'status' => $status, ]; - //Ensure atomicity - $this->bdd->beginTransaction(); - - $id_sended = $this->get_model()->insert($sended); - if (!$id_sended) - { - $this->bdd->rollback(); - return false; - } - - //Link medias - $internal_media = new Media($this->bdd); - foreach ($medias as $media) - { - $internal_media->link_to($media['id'], 'sended', $id_sended); //No rollback on error, keeping track of mms is more important than integrity - } - - if (!$this->bdd->commit()) - { - return false; - } - - return $id_sended; + return $this->get_model()->insert($sended); } /** @@ -132,19 +107,6 @@ namespace controllers\internals; { return $this->get_model()->gets_by_destination_and_user($id_user, $origin); } - - /** - * Return sendeds for a destination and a user since a date. - * - * @param int $id_user : User id - * @param string $since : Date we want messages since format Y-m-d H:i:s - * @param string $origin : Number who sent the message - * @return array - */ - public function gets_since_date_by_destination_and_user(int $id_user, string $since, string $origin) - { - return $this->get_model()->gets_since_date_by_destination_and_user($id_user, $since, $origin); - } /** * Return sended for an uid and an adapter. @@ -203,8 +165,6 @@ namespace controllers\internals; * @param $text : Text of the message * @param string $destination : Number of the receiver * @param bool $flash : Is the sms a flash. By default false. - * @param bool $mms : Is the sms a MMS. By default false. - * @param array $medias : Array of medias to link to the MMS. * @param string $status : Status of a the sms. By default \models\Sended::STATUS_UNKNOWN * * @return array : [ @@ -212,7 +172,7 @@ namespace controllers\internals; * ?string 'error_message' => null if success, error message else * ] */ - public function send(\adapters\AdapterInterface $adapter, int $id_user, int $id_phone, string $text, string $destination, bool $flash = false, bool $mms = false, array $medias = [], string $status = \models\Sended::STATUS_UNKNOWN): array + public function send(\adapters\AdapterInterface $adapter, int $id_user, int $id_phone, string $text, string $destination, bool $flash = false, string $status = \models\Sended::STATUS_UNKNOWN): array { $return = [ 'error' => false, @@ -220,40 +180,19 @@ namespace controllers\internals; ]; $at = (new \DateTime())->format('Y-m-d H:i:s'); - $media_uris = []; - foreach ($medias as $media) - { - $media_uris[] = [ - 'path' => $media['path'], - 'local_uri' => PWD_DATA_PUBLIC . '/' . $media['path'], - ]; - } - - //If adapter does not support mms and the message is a mms, add medias as link - if (!$adapter::meta_support_mms_sending() && $mms) - { - $media_urls = []; - foreach ($media_uris as $media_uri) - { - $media_urls[] = STATIC_HTTP_URL . '/data/public/' . $media_uri['path']; - } - - $text .= "\n" . join(' - ', $media_urls); - } - - $response = $adapter->send($destination, $text, $flash, $mms, $media_uris); + $response = $adapter->send($destination, $text, $flash); if ($response['error']) { $return['error'] = true; $return['error_message'] = $response['error_message']; $status = \models\Sended::STATUS_FAILED; - $this->create($id_user, $id_phone, $at, $text, $destination, $response['uid'] ?? uniqid(), $adapter->meta_classname(), $flash, $mms, $medias, $status); + $this->create($id_user, $id_phone, $at, $text, $destination, $response['uid'] ?? uniqid(), $adapter->meta_classname(), $flash, $status); return $return; } - $sended_id = $this->create($id_user, $id_phone, $at, $text, $destination, $response['uid'] ?? uniqid(), $adapter->meta_classname(), $flash, $mms, $medias, $status); + $sended_id = $this->create($id_user, $id_phone, $at, $text, $destination, $response['uid'] ?? uniqid(), $adapter->meta_classname(), $flash, $status); $sended = [ 'id' => $sended_id, @@ -261,12 +200,10 @@ namespace controllers\internals; 'text' => $text, 'destination' => $destination, 'origin' => $id_phone, - 'mms' => $mms, - 'medias' => $medias, ]; $internal_webhook = new Webhook($this->bdd); - $internal_webhook->trigger($id_user, \models\Webhook::TYPE_SEND_SMS, $sended); + $internal_webhook->trigger($id_user, \models\Webhook::TYPE_SEND, $sended); return $return; } diff --git a/controllers/internals/Tool.php b/controllers/internals/Tool.php index a207185..843d066 100644 --- a/controllers/internals/Tool.php +++ b/controllers/internals/Tool.php @@ -205,7 +205,7 @@ namespace controllers\internals; * * @param array $file : The array extracted from $_FILES['file'] * - * @return array : ['success' => bool, 'content' => file handler | error message, 'error_code' => $file['error'], 'mime_type' => server side calculated mimetype, 'extension' => original extension, 'tmp_name' => name of the tmp_file] + * @return array : ['success' => bool, 'content' => file handler | error message, 'error_code' => $file['error']] */ public static function read_uploaded_file(array $file) { @@ -213,9 +213,8 @@ namespace controllers\internals; 'success' => false, 'content' => 'Une erreur inconnue est survenue.', 'error_code' => $file['error'] ?? 99, - 'mime_type' => null, - 'extension' => null, - 'tmp_name' => null, + 'mime_type' => false, + 'extension' => false, ]; if (UPLOAD_ERR_OK !== $file['error']) @@ -267,8 +266,7 @@ namespace controllers\internals; return $result; } - $result['tmp_name'] = $tmp_filename; - $result['extension'] = pathinfo($file['name'], PATHINFO_EXTENSION); + $result['extension'] = pathinfo($file['name'])['extension']; $result['mime_type'] = mime_content_type($tmp_filename); $file_handler = fopen($tmp_filename, 'r'); @@ -279,55 +277,96 @@ namespace controllers\internals; } /** - * Generate a highly random uuid based on timestamp and strong cryptographic random + * Allow to upload file. * - * @return string - */ - public static function random_uuid() - { - $bytes = random_bytes(16); - return time() . '-' . bin2hex($bytes); - } - - - /** - * Create a user data public path - * @param int $id_user : The user id + * @param array $file : The array extracted from $_FILES['file'] * - * @return string : The created path - - * @exception Raise exception on error + * @return array : ['success' => bool, 'content' => file path | error message, 'error_code' => $file['error']] */ - public static function create_user_public_path (int $id_user) + public static function upload_file(array $file) { - $new_dir = PWD_DATA_PUBLIC . '/' . $id_user; - if (file_exists($new_dir)) + $result = [ + 'success' => false, + 'content' => 'Une erreur inconnue est survenue.', + 'error_code' => $file['error'] ?? 99, + ]; + + if (UPLOAD_ERR_OK !== $file['error']) { - return $new_dir; + switch ($file['error']) + { + case UPLOAD_ERR_INI_SIZE: + $result['content'] = 'Impossible de télécharger le fichier car il dépasse les ' . ini_get('upload_max_filesize') / (1000 * 1000) . ' Mégaoctets.'; + + break; + + case UPLOAD_ERR_FORM_SIZE: + $result['content'] = 'Le fichier dépasse la limite de taille.'; + + break; + + case UPLOAD_ERR_PARTIAL: + $result['content'] = 'L\'envoi du fichier a été interrompu.'; + + break; + + case UPLOAD_ERR_NO_FILE: + $result['content'] = 'Aucun fichier n\'a été envoyé.'; + + break; + + case UPLOAD_ERR_NO_TMP_DIR: + $result['content'] = 'Le serveur ne dispose pas de fichier temporaire permettant l\'envoi de fichiers.'; + + break; + + case UPLOAD_ERR_CANT_WRITE: + $result['content'] = 'Impossible d\'envoyer le fichier car il n\'y a plus de place sur le serveur.'; + + break; + + case UPLOAD_ERR_EXTENSION: + $result['content'] = 'Le serveur a interrompu l\'envoi du fichier.'; + + break; + } + + return $result; } - clearstatcache(); - if (!mkdir($new_dir)) + $tmp_filename = $file['tmp_name'] ?? false; + if (!$tmp_filename || !is_readable($tmp_filename)) { - throw new \Exception('Cannot create dir ' . $new_dir); + return $result; } - //We do chmod in two times because else umask fuck mkdir permissions - if (!chmod($new_dir, fileperms(PWD_DATA_PUBLIC) & 0777)) //Fileperms return garbage in addition to perms. Perms are only in weak bytes. We must use an octet notation with 0 + $md5_filename = md5_file($tmp_filename); + if (!$md5_filename) { - throw new \Exception('Cannot give dir ' . $new_dir . ' rights : ' . decoct(fileperms(PWD_DATA_PUBLIC) & 0777)); //Show error in dec + return $result; } - if (posix_getuid() === 0 && !chown($new_dir, fileowner(PWD_DATA_PUBLIC))) //If we are root, try to give the file to a proper user + $new_file_path = PWD_DATA . '/' . $md5_filename; + + if (file_exists($new_file_path)) { - throw new \Exception('Cannot give dir ' . $new_dir . ' to user : ' . fileowner(PWD_DATA_PUBLIC)); + $result['success'] = true; + $result['content'] = $new_file_path; + + return $result; } - if (posix_getuid() === 0 && !chgrp($new_dir, filegroup(PWD_DATA_PUBLIC))) //If we are root, try to give the file to a proper group + $success = move_uploaded_file($tmp_filename, $new_file_path); + if (!$success) { - throw new \Exception('Cannot give dir ' . $new_dir . ' to group : ' . filegroup(PWD_DATA_PUBLIC)); + $result['content'] = 'Impossible d\'écrire le fichier sur le serveur.'; + + return $result; } - return $new_dir; + $result['success'] = true; + $result['content'] = $new_file_path; + + return $result; } } diff --git a/controllers/internals/User.php b/controllers/internals/User.php index 427cceb..99a47cf 100644 --- a/controllers/internals/User.php +++ b/controllers/internals/User.php @@ -264,7 +264,6 @@ namespace controllers\internals; * string 'text' => sms content, * string 'destination' => id of phone the sms was sent to * string 'origin' => phone number that sent the sms - * bool 'mms' => is the sms a mms * ] * * @return bool : False if no transfer, true else @@ -291,20 +290,12 @@ namespace controllers\internals; } $mailer = new Mailer(); - - $attachments = []; - - foreach ($received['medias'] ?? [] as $media) - { - $attachments[] = PWD_DATA_PUBLIC . '/' . $media['path']; - } return $mailer->enqueue($user['email'], EMAIL_TRANSFER_SMS, [ 'at' => $received['at'], 'origin' => $received['origin'], 'destination' => $phone['name'], 'text' => $received['text'], - 'mms' => $received['mms'] ?? false, - ], $attachments); + ]); } } diff --git a/controllers/internals/Webhook.php b/controllers/internals/Webhook.php index 3cbaff0..8d25108 100644 --- a/controllers/internals/Webhook.php +++ b/controllers/internals/Webhook.php @@ -94,11 +94,17 @@ class Webhook extends StandardController * * @param int $id_user : User to trigger the webhook for * @param string $type : Type of webhook to trigger - * @param array $body : The body, an array depending on webhook type + * @param array $sms : The sms [ + * int 'id' => SMS id, + * string 'at' => SMS date, + * string 'text' => sms body, + * string 'origin' => sms origin (number or phone id) + * string 'destination' => sms destination (number or phone id) + * ] * * @return bool : False if no trigger, true else */ - public function trigger(int $id_user, string $type, array $body) + public function trigger(int $id_user, string $type, array $sms) { $internal_setting = new Setting($this->bdd); $internal_user = new User($this->bdd); @@ -131,7 +137,11 @@ class Webhook extends StandardController 'webhook_type' => $webhook['type'], 'webhook_random_id' => $webhook_random_id, 'webhook_signature' => $webhook_signature, - 'body' => json_encode($body), + 'id' => $sms['id'], + 'at' => $sms['at'], + 'text' => $sms['text'], + 'origin' => $sms['origin'], + 'destination' => $sms['destination'], ], ]; diff --git a/controllers/publics/Api.php b/controllers/publics/Api.php index c153e85..02b09d7 100644 --- a/controllers/publics/Api.php +++ b/controllers/publics/Api.php @@ -32,7 +32,6 @@ namespace controllers\publics; 'CANNOT_CREATE' => 8, 'SUSPENDED_USER' => 16, 'CANNOT_DELETE' => 32, - 'CANNOT_UPLOAD_FILE' => 64, ]; const ERROR_MESSAGES = [ @@ -42,7 +41,6 @@ namespace controllers\publics; 'CANNOT_CREATE' => 'Cannot create a new entry.', 'SUSPENDED_USER' => 'This user account is currently suspended.', 'CANNOT_DELETE' => 'Cannot delete this entry.', - 'CANNOT_UPLOAD_FILE' => 'Failed to upload or save an uploaded file : ', ]; private $internal_user; @@ -54,8 +52,6 @@ namespace controllers\publics; private $internal_group; private $internal_conditional_group; private $internal_adapter; - private $internal_media; - private $internal_setting; private $user; /** @@ -77,8 +73,6 @@ namespace controllers\publics; $this->internal_group = new \controllers\internals\Group($bdd); $this->internal_conditional_group = new \controllers\internals\ConditionalGroup($bdd); $this->internal_adapter = new \controllers\internals\Adapter(); - $this->internal_media = new \controllers\internals\Media($bdd); - $this->internal_setting = new \controllers\internals\Setting($bdd); //If no user, quit with error $this->user = false; @@ -99,8 +93,6 @@ namespace controllers\publics; exit(self::ERROR_CODES['INVALID_CREDENTIALS']); } - $this->user['settings'] = $this->internal_setting->gets_for_user($this->user['id']); - if (\models\User::STATUS_ACTIVE !== $this->user['status']) { $return = self::DEFAULT_RETURN; @@ -116,14 +108,14 @@ namespace controllers\publics; /** * List all entries of a certain type for the current user, sorted by id. * - * @param string $entry_type : Type of entries we want to list ['sended', 'received', 'scheduled', 'contact', 'group', 'conditional_group', 'phone', 'media'] + * @param string $entry_type : Type of entries we want to list ['sended', 'received', 'scheduled', 'contact', 'group', 'conditional_group', 'phone'] * @param int $page : Pagination number, Default = 0. Group of 25 results. * * @return : List of entries */ public function get_entries(string $entry_type, int $page = 0) { - $entry_types = ['sended', 'received', 'scheduled', 'contact', 'group', 'conditional_group', 'phone', 'media']; + $entry_types = ['sended', 'received', 'scheduled', 'contact', 'group', 'conditional_group', 'phone']; if (!\in_array($entry_type, $entry_types, true)) { @@ -151,21 +143,6 @@ namespace controllers\publics; $entries[$key]['contacts'] = $this->internal_scheduled->get_contacts($entry['id']); $entries[$key]['groups'] = $this->internal_scheduled->get_groups($entry['id']); $entries[$key]['conditional_groups'] = $this->internal_scheduled->get_conditional_groups($entry['id']); - $entries[$key]['medias'] = $this->internal_media->gets_for_scheduled($entry['id']); - } - } - elseif ('received' === $entry_type) - { - foreach ($entries as $key => $entry) - { - $entries[$key]['medias'] = $this->internal_media->gets_for_received($entry['id']); - } - } - elseif ('sended' === $entry_type) - { - foreach ($entries as $key => $entry) - { - $entries[$key]['medias'] = $this->internal_media->gets_for_sended($entry['id']); } } //Special case for group we must add contact because its a join @@ -202,7 +179,6 @@ namespace controllers\publics; * @param string $_POST['text'] : Text of the message to send * @param string $_POST['id_phone'] : Default null. Id of phone to send the message from. If null use a random phone * @param string $_POST['flash'] : Default false. Is the sms a flash sms. - * @param string $_POST['mms'] : Default false. Is the sms a mms. * @param string $_POST['numbers'] : Array of numbers to send message to * @param string $_POST['contacts'] : Array of ids of contacts to send message to * @param string $_POST['groups'] : Array of ids of groups to send message to @@ -216,47 +192,16 @@ namespace controllers\publics; $text = $_POST['text'] ?? false; $id_phone = empty($_POST['id_phone']) ? null : $_POST['id_phone']; $flash = (bool) ($_POST['flash'] ?? false); - $mms = (bool) ($_POST['mms'] ?? false); $numbers = $_POST['numbers'] ?? []; $contacts = $_POST['contacts'] ?? []; $groups = $_POST['groups'] ?? []; $conditional_groups = $_POST['conditional_groups'] ?? []; - $files = $_FILES['medias'] ?? false; $numbers = \is_array($numbers) ? $numbers : [$numbers]; $contacts = \is_array($contacts) ? $contacts : [$contacts]; $groups = \is_array($groups) ? $groups : [$groups]; $conditional_groups = \is_array($conditional_groups) ? $conditional_groups : [$conditional_groups]; - //Iterate over files to re-create individual $_FILES array - $files_arrays = []; - - if ($files === false) - { - $files_arrays = []; - } - elseif (!is_array($files['name'])) //Only one file uploaded - { - $files_arrays[] = $files; - } - else //multiple files - { - foreach ($files as $property_name => $files_values) - { - foreach ($files_values as $file_key => $property_value) - { - if (!isset($files_arrays[$file_key])) - { - $files_arrays[$file_key] = []; - } - - $files_arrays[$file_key][$property_name] = $property_value; - } - } - } - - $media_ids = []; - if (!$at) { $at = (new \DateTime())->format('Y-m-d H:i:s'); @@ -282,16 +227,6 @@ namespace controllers\publics; return $this->json($return); } - if (($this->user['settings']['mms'] ?? false) && $mms) - { - $return = self::DEFAULT_RETURN; - $return['error'] = self::ERROR_CODES['INVALID_PARAMETER']; - $return['message'] = self::ERROR_MESSAGES['INVALID_PARAMETER'] . 'mms is set to true, but mms are disabled in settings.'; - $this->auto_http_code(false); - - return $this->json($return); - } - foreach ($numbers as $key => $number) { $number = \controllers\internals\Tool::parse_phone($number); @@ -316,13 +251,7 @@ namespace controllers\publics; return $this->json($return); } - $phone = null; - if ($id_phone) - { - $phone = $this->internal_phone->get_for_user($this->user['id'], $id_phone); - } - - if ($id_phone && !$phone) + if ($id_phone && !$this->internal_phone->get_for_user($this->user['id'], $id_phone)) { $return = self::DEFAULT_RETURN; $return['error'] = self::ERROR_CODES['INVALID_PARAMETER']; @@ -332,29 +261,7 @@ namespace controllers\publics; return $this->json($return); } - if ($mms) - { - foreach ($files_arrays as $file) - { - try - { - $new_media_id = $this->internal_media->upload_and_create_for_user($this->user['id'], $file); - } - catch (\Exception $e) - { - $return = self::DEFAULT_RETURN; - $return['error'] = self::ERROR_CODES['CANNOT_CREATE']; - $return['message'] = self::ERROR_MESSAGES['CANNOT_CREATE'] . ' : Cannot upload and create media file ' . $file['name'] . ' : ' . $e->getMessage(); - $this->auto_http_code(false); - - return $this->json($return); - } - - $media_ids[] = $new_media_id; - } - } - - $scheduled_id = $this->internal_scheduled->create($this->user['id'], $at, $text, $id_phone, $flash, $mms, $numbers, $contacts, $groups, $conditional_groups, $media_ids); + $scheduled_id = $this->internal_scheduled->create($this->user['id'], $at, $text, $id_phone, $flash, $numbers, $contacts, $groups, $conditional_groups); if (!$scheduled_id) { $return = self::DEFAULT_RETURN; diff --git a/controllers/publics/Call.php b/controllers/publics/Call.php deleted file mode 100644 index fb05bc2..0000000 --- a/controllers/publics/Call.php +++ /dev/null @@ -1,93 +0,0 @@ - - * - * 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 calls. - */ - class Call extends \descartes\Controller - { - private $internal_call; - - /** - * 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_call = new \controllers\internals\Call($bdd); - - \controllers\internals\Tool::verifyconnect(); - } - - /** - * Page for showing calls list - */ - public function list() - { - $this->render('call/list'); - } - - /** - * Return calls list as json. - */ - public function list_json() - { - $entities = $this->internal_call->list_for_user($_SESSION['user']['id']); - foreach ($entities as &$entity) - { - switch ($entity['direction']) - { - case \models\Call::DIRECTION_INBOUND : - $entity['origin_formatted'] = \controllers\internals\Tool::phone_link($entity['origin']); - break; - - case \models\Call::DIRECTION_OUTBOUND : - $entity['destination_formatted'] = \controllers\internals\Tool::phone_link($entity['destination']); - break; - } - } - - header('Content-Type: application/json'); - echo json_encode(['data' => $entities]); - } - - /** - * Delete a list of calls - * - * @param array int $_GET['ids'] : Ids of calls to delete - * @param string $csrf : csrf token - * - * @return boolean; - */ - public function delete(string $csrf) - { - if (!$this->verify_csrf($csrf)) - { - \FlashMessage\FlashMessage::push('danger', 'Jeton CSRF invalid !'); - - return $this->redirect(\descartes\Router::url('Call', 'list')); - } - - $ids = $_GET['ids'] ?? []; - foreach ($ids as $id) - { - $this->internal_call->delete_for_user($_SESSION['user']['id'], $id); - } - - return $this->redirect(\descartes\Router::url('Call', 'list')); - } - } diff --git a/controllers/publics/Callback.php b/controllers/publics/Callback.php index d97a2e6..c7d905d 100644 --- a/controllers/publics/Callback.php +++ b/controllers/publics/Callback.php @@ -25,9 +25,6 @@ use Monolog\Logger; private $internal_sended; private $internal_received; private $internal_adapter; - private $internal_media; - private $internal_phone; - private $internal_call; public function __construct() { @@ -36,10 +33,7 @@ use Monolog\Logger; $this->internal_user = new \controllers\internals\User($bdd); $this->internal_sended = new \controllers\internals\Sended($bdd); $this->internal_received = new \controllers\internals\Received($bdd); - $this->internal_media = new \controllers\internals\Media($bdd); $this->internal_adapter = new \controllers\internals\Adapter(); - $this->internal_phone = new \controllers\internals\Phone($bdd); - $this->internal_call = new \controllers\internals\Call($bdd); //Logger $this->logger = new Logger('Callback ' . uniqid()); @@ -183,10 +177,8 @@ use Monolog\Logger; } $sms = $response['sms']; - $mms = (bool) $sms['mms'] ?? false; - $medias = empty($sms['medias']) ? [] : $sms['medias']; - $response = $this->internal_received->receive($this->user['id'], $id_phone, $sms['text'], $sms['origin'], $sms['at'], \models\Received::STATUS_UNREAD, $mms, $medias); + $response = $this->internal_received->receive($this->user['id'], $id_phone, $sms['text'], $sms['origin'], $sms['at']); if ($response['error']) { $this->logger->error('Failed receive message : ' . json_encode($sms) . ' with error : ' . $response['error_message']); @@ -198,135 +190,4 @@ use Monolog\Logger; return true; } - - - /** - * Function call on call reception notification - * We return nothing, and we let the adapter do his things. - * - * @param int $id_phone : Phone id - * - * @return bool : true on success, false on error - */ - public function inbound_call(int $id_phone) - { - $this->logger->info('Callback inbound_call call with phone : ' . $id_phone); - $phone = $this->internal_phone->get_for_user($this->user['id'], $id_phone); - - if (!$phone) - { - $this->logger->error('Callback inbound_call use non existing phone : ' . $id_phone); - - return false; - } - - if (!class_exists($phone['adapter'])) - { - $this->logger->error('Callback inbound_call use non existing adapter : ' . $phone['adapter']); - - return false; - } - - if (!$phone['adapter']::meta_support_inbound_call_callback()) - { - $this->logger->error('Callback inbound_call use adapter ' . $phone['adapter'] . ' which does not support inbound_call callback.'); - - return false; - } - - $response = $phone['adapter']::inbound_call_callback(); - if ($response['error']) - { - $this->logger->error('Callback inbound_call failed : ' . $response['error_message']); - - return false; - } - - $call = $response['call']; - - if (empty($call) || empty($call['uid']) || empty($call['start']) || empty($call['origin'])) - { - $this->logger->error('Callback inbound_call failed : missing required param in call return'); - - return false; - } - - $result = $this->internal_call->create($this->user['id'], $id_phone, $call['uid'], \models\Call::DIRECTION_INBOUND, $call['start'], $call['end'] ?? null, $call['origin']); - - if (!$result) - { - $this->logger->error('Callback inbound_call failed because cannot create call ' . json_encode($call)); - - return false; - } - - $this->logger->info('Callback inbound_call successfully received inbound call : ' . json_encode($call)); - - return true; - } - - - /** - * Function call on end call notification - * We return nothing, and we let the adapter do his things. - * - * @param int $id_phone : Phone id - * - * @return bool : true on success, false on error - */ - public function end_call(int $id_phone) - { - $this->logger->info('Callback end call with phone : ' . $id_phone); - $phone = $this->internal_phone->get_for_user($this->user['id'], $id_phone); - - if (!$phone) - { - $this->logger->error('Callback end call use non existing phone : ' . $id_phone); - - return false; - } - - if (!class_exists($phone['adapter'])) - { - $this->logger->error('Callback end call use non existing adapter : ' . $phone['adapter']); - - return false; - } - - if (!$phone['adapter']::meta_support_end_call_callback()) - { - $this->logger->error('Callback end call use adapter ' . $phone['adapter'] . ' which does not support end call callback.'); - - return false; - } - - $response = $phone['adapter']::end_call_callback(); - if ($response['error']) - { - $this->logger->error('Callback end call failed : ' . $response['error_message']); - - return false; - } - - $call = $response['call']; - if (empty($call) || empty($call['uid']) || empty($call['end'])) - { - $this->logger->error('Callback end call failed : missing required param in call return'); - - return false; - } - - $result = $this->internal_call->end($this->user['id'], $id_phone, $call['uid'], $call['end']); - - if (!$result) - { - $this->logger->error('Callback end call failed because cannot update call ' . json_encode($call)); - - return false; - } - - $this->logger->info('Callback end call successfully update call : ' . json_encode($call)); - - return true; - } } diff --git a/controllers/publics/ConditionalGroup.php b/controllers/publics/ConditionalGroup.php index 9ba60f9..28ad23e 100644 --- a/controllers/publics/ConditionalGroup.php +++ b/controllers/publics/ConditionalGroup.php @@ -234,17 +234,7 @@ namespace controllers\publics; $contacts_name[] = $contact['name']; } - $visible_names = array_slice($contacts_name, 0, 5); - $how_many_more = count($contacts_name) - count($visible_names); - - $result_text = 'Contacts du groupe : ' . implode(', ', $visible_names); - - if ($how_many_more > 0) - { - $result_text .= ", et $how_many_more autres."; - } - - $return['result'] = $result_text; + $return['result'] = 'Contacts du groupe : ' . implode(', ', $contacts_name); $return['success'] = true; echo json_encode($return); diff --git a/controllers/publics/Contact.php b/controllers/publics/Contact.php index 9d6e98f..2e2b8b6 100644 --- a/controllers/publics/Contact.php +++ b/controllers/publics/Contact.php @@ -18,7 +18,6 @@ namespace controllers\publics; { private $internal_contact; private $internal_event; - private $internal_conditional_group; /** * Cette fonction est appelée avant toute les autres : @@ -32,7 +31,6 @@ namespace controllers\publics; $this->internal_contact = new \controllers\internals\Contact($bdd); $this->internal_event = new \controllers\internals\Event($bdd); - $this->internal_conditional_group = new \controllers\internals\ConditionalGroup($bdd); \controllers\internals\Tool::verifyconnect(); } @@ -85,40 +83,6 @@ namespace controllers\publics; return $this->redirect(\descartes\Router::url('Contact', 'list')); } - - /** - * This function will delete a list of contacts depending on a condition - * - * @param string $_POST['condition'] : Condition to use to delete contacts - * @param mixed $csrf - * - * @return boolean; - */ - public function conditional_delete($csrf) - { - if (!$this->verify_csrf($csrf)) - { - \FlashMessage\FlashMessage::push('danger', 'Jeton CSRF invalid !'); - - return $this->redirect(\descartes\Router::url('Contact', 'list')); - } - - $condition = $_POST['condition'] ?? false; - if (!$condition) - { - \FlashMessage\FlashMessage::push('danger', 'Vous devez fournir une condition !'); - - return $this->redirect(\descartes\Router::url('Contact', 'list')); - } - - $contacts_to_delete = $this->internal_conditional_group->get_contacts_for_condition_and_user($_SESSION['user']['id'], $condition); - foreach ($contacts_to_delete as $contact) - { - $this->internal_contact->delete_for_user($_SESSION['user']['id'], $contact['id']); - } - - return $this->redirect(\descartes\Router::url('Contact', 'list')); - } /** * Cette fonction retourne la page d'ajout d'un contact. diff --git a/controllers/publics/Discussion.php b/controllers/publics/Discussion.php index 1d385d8..7c7b79a 100644 --- a/controllers/publics/Discussion.php +++ b/controllers/publics/Discussion.php @@ -21,7 +21,6 @@ namespace controllers\publics; private $internal_received; private $internal_contact; private $internal_phone; - private $internal_media; /** * Cette fonction est appelée avant toute les autres : @@ -38,7 +37,6 @@ namespace controllers\publics; $this->internal_received = new \controllers\internals\Received($bdd); $this->internal_contact = new \controllers\internals\Contact($bdd); $this->internal_phone = new \controllers\internals\Phone($bdd); - $this->internal_media = new \controllers\internals\Media($bdd); \controllers\internals\Tool::verifyconnect(); } @@ -114,27 +112,12 @@ namespace controllers\publics; foreach ($sendeds as $sended) { - $medias = []; - if ($sended['mms']) - { - $medias = $this->internal_media->gets_for_sended($sended['id']); - foreach ($medias as &$media) - { - $media = HTTP_PWD_DATA_PUBLIC . '/' . $media['path']; - } - } - - $message = [ - 'uid' => 'sended-' . $sended['id'], + $messages[] = [ 'date' => htmlspecialchars($sended['at']), 'text' => htmlspecialchars($sended['text']), 'type' => 'sended', - 'medias' => $medias, 'status' => $sended['status'], ]; - - - $messages[] = $message; } foreach ($receiveds as $received) @@ -143,44 +126,21 @@ namespace controllers\publics; { $this->internal_received->mark_as_read_for_user($id_user, $received['id']); } - - $medias = []; - if ($received['mms']) - { - $medias = $this->internal_media->gets_for_received($received['id']); - foreach ($medias as &$media) - { - $media = HTTP_PWD_DATA_PUBLIC . '/' . $media['path']; - } - } $messages[] = [ - 'uid' => 'received-' . $received['id'], 'date' => htmlspecialchars($received['at']), 'text' => htmlspecialchars($received['text']), 'type' => 'received', - 'medias' => $medias, + 'md5' => md5($received['at'] . $received['text']), ]; } foreach ($scheduleds as $scheduled) { - $medias = []; - if ($scheduled['mms']) - { - $medias = $this->internal_media->gets_for_scheduled($scheduled['id']); - foreach ($medias as &$media) - { - $media = HTTP_PWD_DATA_PUBLIC . '/' . $media['path']; - } - } - $messages[] = [ - 'uid' => 'scheduled-' . $scheduled['id'], 'date' => htmlspecialchars($scheduled['at']), 'text' => htmlspecialchars($scheduled['text']), 'type' => 'inprogress', - 'medias' => $medias, ]; } @@ -190,15 +150,10 @@ namespace controllers\publics; return strtotime($a['date']) - strtotime($b['date']); }); - //Récupère uniquement les 25 derniers messages sur l'ensemble pour limiter la charge + //On récupère uniquement les 25 derniers messages sur l'ensemble $messages = \array_slice($messages, -25); - $response = [ - 'transaction_id' => $transaction_id, - 'messages' => $messages, - ]; - - echo json_encode($response); + echo json_encode(['transaction_id' => $transaction_id, 'messages' => $messages]); return true; } @@ -210,7 +165,6 @@ namespace controllers\publics; * @param string $_POST['text'] : Le contenu du Sms * @param string $_POST['destination'] : Number to send sms to * @param string $_POST['id_phone'] : If of phone to send sms with - * @param array $_FILES['medias'] : Medias to upload and link to sms * * @return string : json string Le statut de l'envoi */ @@ -236,43 +190,6 @@ namespace controllers\publics; $text = $_POST['text'] ?? ''; $destination = $_POST['destination'] ?? false; $id_phone = $_POST['id_phone'] ?? false; - $files = $_FILES['medias'] ?? false; - - //Iterate over files to re-create individual $_FILES array - $files_arrays = []; - if ($files && is_array($files['name'])) - { - foreach ($files as $property_name => $files_values) - { - foreach ($files_values as $file_key => $property_value) - { - if (!isset($files_arrays[$file_key])) - { - $files_arrays[$file_key] = []; - } - - $files_arrays[$file_key][$property_name] = $property_value; - } - } - } - - //Remove empty files input - foreach ($files_arrays as $key => $file) - { - if ($file['error'] === UPLOAD_ERR_NO_FILE) - { - unset($files_arrays[$key]); - } - } - - if (!$text) - { - $return['success'] = false; - $return['message'] = 'Vous devez renseigner le texte de votre sms.'; - echo json_encode($return); - - return false; - } if (!$destination) { @@ -288,36 +205,10 @@ namespace controllers\publics; $id_phone = null; } - - //If mms is enable and we have medias uploaded - $media_ids = []; - if ($_SESSION['user']['settings']['mms'] && $files_arrays) - { - foreach ($files_arrays as $file) - { - try - { - $new_media_id = $this->internal_media->create_from_uploaded_file_for_user($_SESSION['user']['id'], $file); - } - catch (\Exception $e) - { - $return['success'] = false; - $return['message'] = $e->getMessage(); - echo json_encode($return); - - return false; - } - - $media_ids[] = $new_media_id; - } - } - - $mms = (bool) count($media_ids); - //Destinations must be an array of number $destinations = [$destination]; - if (!$this->internal_scheduled->create($id_user, $at, $text, $id_phone, false, $mms, $destinations, [], [], [], $media_ids)) + if (!$this->internal_scheduled->create($id_user, $at, $text, $id_phone, false, $destinations)) { $return['success'] = false; $return['message'] = 'Impossible de créer le Sms'; diff --git a/controllers/publics/Phone.php b/controllers/publics/Phone.php index 81d6249..329572a 100644 --- a/controllers/publics/Phone.php +++ b/controllers/publics/Phone.php @@ -33,7 +33,43 @@ class Phone extends \descartes\Controller */ public function list() { - $this->render('phone/list'); + $id_user = $_SESSION['user']['id']; + $api_key = $_SESSION['user']['api_key']; + $phones = $this->internal_phone->list_for_user($id_user); + + $adapters = []; + $adapters = $this->internal_adapter->list_adapters(); + foreach ($adapters as $key => $adapter) + { + unset($adapters[$key]); + $adapters[$adapter['meta_classname']] = $adapter; + } + + foreach ($phones as &$phone) + { + $adapter = $adapters[$phone['adapter']] ?? false; + + if (!$adapter) + { + $phone['adapter'] = 'Inconnu'; + + continue; + } + + $phone['adapter'] = $adapter['meta_name']; + + if ($adapter['meta_support_reception']) + { + $phone['callback_reception'] = \descartes\Router::url('Callback', 'reception', ['adapter_uid' => $adapter['meta_uid'], 'id_phone' => $phone['id']], ['api_key' => $api_key]); + } + + if ($adapter['meta_support_status_change']) + { + $phone['callback_status'] = \descartes\Router::url('Callback', 'update_sended_status', ['adapter_uid' => $adapter['meta_uid']], ['api_key' => $api_key]); + } + } + + $this->render('phone/list', ['phones' => $phones]); } /** @@ -75,16 +111,6 @@ class Phone extends \descartes\Controller { $phone['callback_status'] = \descartes\Router::url('Callback', 'update_sended_status', ['adapter_uid' => $adapter['meta_uid']], ['api_key' => $api_key]); } - - if ($adapter['meta_support_inbound_call_callback']) - { - $phone['callback_inbound_call'] = \descartes\Router::url('Callback', 'inbound_call', ['id_phone' => $phone['id']], ['api_key' => $api_key]); - } - - if ($adapter['meta_support_end_call_callback']) - { - $phone['callback_end_call'] = \descartes\Router::url('Callback', 'end_call', ['id_phone' => $phone['id']], ['api_key' => $api_key]); - } } header('Content-Type: application/json'); diff --git a/controllers/publics/Received.php b/controllers/publics/Received.php index d6ab5a4..e5ba67e 100644 --- a/controllers/publics/Received.php +++ b/controllers/publics/Received.php @@ -19,7 +19,6 @@ namespace controllers\publics; private $internal_received; private $internal_contact; private $internal_phone; - private $internal_media; /** * Cette fonction est appelée avant toute les autres : @@ -33,7 +32,6 @@ namespace controllers\publics; $this->internal_received = new \controllers\internals\Received($bdd); $this->internal_contact = new \controllers\internals\Contact($bdd); $this->internal_phone = new \controllers\internals\Phone($bdd); - $this->internal_media = new \controllers\internals\Media($bdd); \controllers\internals\Tool::verifyconnect(); } @@ -55,10 +53,6 @@ namespace controllers\publics; foreach ($entities as &$entity) { $entity['origin_formatted'] = \controllers\internals\Tool::phone_link($entity['origin']); - if ($entity['mms']) - { - $entity['medias'] = $this->internal_media->gets_for_received($entity['id']); - } } header('Content-Type: application/json'); @@ -82,10 +76,6 @@ namespace controllers\publics; foreach ($entities as &$entity) { $entity['origin_formatted'] = \controllers\internals\Tool::phone_link($entity['origin']); - if ($entity['mms']) - { - $entity['medias'] = $this->internal_media->gets_for_received($entity['id']); - } } header('Content-Type: application/json'); diff --git a/controllers/publics/Scheduled.php b/controllers/publics/Scheduled.php index b96c58d..8f270df 100644 --- a/controllers/publics/Scheduled.php +++ b/controllers/publics/Scheduled.php @@ -56,13 +56,6 @@ namespace controllers\publics; public function list_json() { $entities = $this->internal_scheduled->list_for_user($_SESSION['user']['id']); - foreach ($entities as &$entity) - { - if ($entity['mms']) - { - $entity['medias'] = $this->internal_media->gets_for_scheduled($entity['id']); - } - } header('Content-Type: application/json'); echo json_encode(['data' => $entities]); @@ -212,8 +205,8 @@ namespace controllers\publics; $scheduleds[$key]['groups'][] = (int) $group['id']; } - $medias = $this->internal_media->gets_for_scheduled($scheduled['id']); - $scheduleds[$key]['medias'] = $medias; + $media = $this->internal_media->get_for_scheduled_and_user($id_user, $scheduled['id']); + $scheduleds[$key]['media'] = $media; $conditional_groups = $this->internal_scheduled->get_conditional_groups($scheduled['id']); foreach ($conditional_groups as $conditional_group) @@ -242,7 +235,7 @@ namespace controllers\publics; * @param ?array $_POST['contacts'] : Numbers to send the message to * @param ?array $_POST['groups'] : Numbers to send the message to * @param ?array $_POST['conditional_groups'] : Numbers to send the message to - * @param ?array $_FILES['medias'] : The media to link to a scheduled + * @param ?array $_FILES['media'] : The media to link to a scheduled */ public function create($csrf) { @@ -262,34 +255,7 @@ namespace controllers\publics; $contacts = $_POST['contacts'] ?? []; $groups = $_POST['groups'] ?? []; $conditional_groups = $_POST['conditional_groups'] ?? []; - $files = $_FILES['medias'] ?? false; - - //Iterate over files to re-create individual $_FILES array - $files_arrays = []; - if ($files && is_array($files['name'])) - { - foreach ($files as $property_name => $files_values) - { - foreach ($files_values as $file_key => $property_value) - { - if (!isset($files_arrays[$file_key])) - { - $files_arrays[$file_key] = []; - } - - $files_arrays[$file_key][$property_name] = $property_value; - } - } - } - - //Remove empty files input - foreach ($files_arrays as $key => $file) - { - if ($file['error'] === UPLOAD_ERR_NO_FILE) - { - unset($files_arrays[$key]); - } - } + $media = $_FILES['media'] ?? false; if (empty($text)) { @@ -325,30 +291,8 @@ namespace controllers\publics; return $this->redirect(\descartes\Router::url('Scheduled', 'add')); } - - //If mms is enable and we have medias uploaded - $media_ids = []; - if ($_SESSION['user']['settings']['mms'] && $files_arrays) - { - foreach ($files_arrays as $file) - { - try - { - $new_media_id = $this->internal_media->create_from_uploaded_file_for_user($_SESSION['user']['id'], $file); - } - catch (\Exception $e) - { - \FlashMessage\FlashMessage::push('danger', 'Impossible d\'upload et d\'enregistrer le fichier ' . $file['name'] . ':' . $e->getMessage()); - return $this->redirect(\descartes\Router::url('Scheduled', 'add')); - } - $media_ids[] = $new_media_id; - } - } - - $mms = (bool) count($media_ids); - - $scheduled_id = $this->internal_scheduled->create($id_user, $at, $text, $id_phone, $flash, $mms, $numbers, $contacts, $groups, $conditional_groups, $media_ids); + $scheduled_id = $this->internal_scheduled->create($id_user, $at, $text, $id_phone, $flash, $numbers, $contacts, $groups, $conditional_groups); if (!$scheduled_id) { \FlashMessage\FlashMessage::push('danger', 'Impossible de créer le Sms.'); @@ -356,6 +300,22 @@ namespace controllers\publics; return $this->redirect(\descartes\Router::url('Scheduled', 'add')); } + //If mms is enabled, try to process a media to link to the scheduled + if (!($_SESSION['user']['settings']['mms'] ?? false) || !$media) + { + \FlashMessage\FlashMessage::push('success', 'Le Sms a bien été créé pour le ' . $at . '.'); + + return $this->redirect(\descartes\Router::url('Scheduled', 'list')); + } + + $success = $this->internal_media->create($id_user, $scheduled_id, $media); + if (!$success) + { + \FlashMessage\FlashMessage::push('success', 'Le SMS a bien été créé mais le média n\'as pas pu être enregistré.'); + + return $this->redirect(\descartes\Router::url('Scheduled', 'list')); + } + \FlashMessage\FlashMessage::push('success', 'Le Sms a bien été créé pour le ' . $at . '.'); return $this->redirect(\descartes\Router::url('Scheduled', 'list')); @@ -392,43 +352,13 @@ namespace controllers\publics; $contacts = $scheduled['contacts'] ?? []; $groups = $scheduled['groups'] ?? []; $conditional_groups = $scheduled['conditional_groups'] ?? []; - $files = $_FILES['scheduleds_' . $id_scheduled . '_medias'] ?? false; - $media_ids = $scheduled['media_ids'] ?? []; - //Check scheduled exists and belong to user $scheduled = $this->internal_scheduled->get($id_scheduled); if (!$scheduled || $scheduled['id_user'] !== $id_user) { continue; } - //Iterate over files to re-create individual $_FILES array - $files_arrays = []; - if ($files && is_array($files['name'])) - { - foreach ($files as $property_name => $files_values) - { - foreach ($files_values as $file_key => $property_value) - { - if (!isset($files_arrays[$file_key])) - { - $files_arrays[$file_key] = []; - } - - $files_arrays[$file_key][$property_name] = $property_value; - } - } - } - - //Remove empty files input - foreach ($files_arrays as $key => $file) - { - if ($file['error'] === UPLOAD_ERR_NO_FILE) - { - unset($files_arrays[$key]); - } - } - if (empty($text)) { continue; @@ -456,39 +386,32 @@ namespace controllers\publics; { continue; } - - //If mms is enable and we have medias uploaded - if ($_SESSION['user']['settings']['mms'] && $files_arrays) - { - foreach ($files_arrays as $file) - { - try - { - $new_media_id = $this->internal_media->create_from_uploaded_file_for_user($_SESSION['user']['id'], $file); - } - catch (\Exception $e) - { - continue 2; - } - $media_ids[] = $new_media_id; - } + $success = $this->internal_scheduled->update_for_user($id_user, $id_scheduled, $at, $text, $id_phone, $flash, $numbers, $contacts, $groups, $conditional_groups); + + //Check for media + /* + $current_media = $scheduled['current_media'] ?? false; + if (!$current_media) + { + $this->internal_media->delete_for_scheduled_and_user($id_user, $id_scheduled); } - //Ensure media_ids point to medias belongings to the current user - foreach ($media_ids as $key => $media_id) + $media = $_FILES['media_' . $id_scheduled] ?? false; + if (!$media) { - $media = $this->internal_media->get($media_id); - if (!$media || $media['id_user'] !== $_SESSION['user']['id']) - { - unset($media_ids[$key]); - } + $nb_update += (int) $success; + continue; } - $mms = (bool) count($media_ids); + $success = $this->internal_media->create($id_user, $id_scheduled, $media); + if (!$success) + { + continue; + } + */ - $this->internal_scheduled->update_for_user($id_user, $id_scheduled, $at, $text, $id_phone, $flash, $mms, $numbers, $contacts, $groups, $conditional_groups, $media_ids); - $nb_update++; + ++$nb_update; } if ($nb_update !== \count($scheduleds)) diff --git a/controllers/publics/Sended.php b/controllers/publics/Sended.php index 8227e38..fa0a67c 100644 --- a/controllers/publics/Sended.php +++ b/controllers/publics/Sended.php @@ -19,7 +19,6 @@ namespace controllers\publics; private $internal_sended; private $internal_phone; private $internal_contact; - private $internal_media; /** * Cette fonction est appelée avant toute les autres : @@ -33,7 +32,6 @@ namespace controllers\publics; $this->internal_sended = new \controllers\internals\Sended($bdd); $this->internal_phone = new \controllers\internals\Phone($bdd); $this->internal_contact = new \controllers\internals\Contact($bdd); - $this->internal_media = new \controllers\internals\Media($bdd); \controllers\internals\Tool::verifyconnect(); } @@ -57,10 +55,6 @@ namespace controllers\publics; foreach ($entities as &$entity) { $entity['destination_formatted'] = \controllers\internals\Tool::phone_link($entity['destination']); - if ($entity['mms']) - { - $entity['medias'] = $this->internal_media->gets_for_sended($entity['id']); - } } header('Content-Type: application/json'); diff --git a/daemons/Mailer.php b/daemons/Mailer.php index a25b253..c9f1ac9 100644 --- a/daemons/Mailer.php +++ b/daemons/Mailer.php @@ -74,7 +74,7 @@ class Mailer extends AbstractDaemon $this->logger->info('Try sending email : ' . json_encode($message)); $mailer = new \controllers\internals\Mailer(); - $success = $mailer->send($message['destinations'], $message['subject'], $message['body'], $message['alt_body'], $message['attachments']); + $success = $mailer->send($message['destinations'], $message['subject'], $message['body'], $message['alt_body']); if (!$success) { $this->logger->error('Failed sending email'); diff --git a/daemons/Phone.php b/daemons/Phone.php index 48b99e9..83a4b01 100644 --- a/daemons/Phone.php +++ b/daemons/Phone.php @@ -139,7 +139,7 @@ class Phone extends AbstractDaemon //Do message sending $this->logger->info('Try send message : ' . json_encode($message)); - $response = $internal_sended->send($this->adapter, $this->phone['id_user'], $this->phone['id'], $message['text'], $message['destination'], $message['flash'], $message['mms'], $message['medias']); + $response = $internal_sended->send($this->adapter, $this->phone['id_user'], $this->phone['id'], $message['text'], $message['destination'], $message['flash']); if ($response['error']) { $this->logger->error('Failed send message : ' . json_encode($message) . ' with error : ' . $response['error_message']); @@ -181,7 +181,7 @@ class Phone extends AbstractDaemon foreach ($response['smss'] as $sms) { $this->logger->info('Receive message : ' . json_encode($sms)); - $response = $internal_received->receive($this->phone['id_user'], $this->phone['id'], $sms['text'], $sms['origin'], $sms['at'], \models\Received::STATUS_UNREAD, $sms['mms'] ?? false, $sms['medias'] ?? []); + $response = $internal_received->receive($this->phone['id_user'], $this->phone['id'], $sms['text'], $sms['origin']); if ($response['error']) { diff --git a/daemons/Sender.php b/daemons/Sender.php index a5504bb..202349f 100644 --- a/daemons/Sender.php +++ b/daemons/Sender.php @@ -76,8 +76,6 @@ class Sender extends AbstractDaemon 'id_phone' => $sms['id_phone'], 'destination' => $sms['destination'], 'flash' => $sms['flash'], - 'mms' => $sms['mms'], - 'medias' => $sms['medias'] ?? [], ]; msg_send($this->queues[$queue_id], QUEUE_TYPE_SEND_MSG, $msg); diff --git a/data/public/.tokeep b/data/public/.tokeep deleted file mode 100644 index e69de29..0000000 diff --git a/db/migrations/20210317214910_add_media_links_to_sms.php b/db/migrations/20210317214910_add_media_links_to_sms.php deleted file mode 100644 index 93e63a2..0000000 --- a/db/migrations/20210317214910_add_media_links_to_sms.php +++ /dev/null @@ -1,87 +0,0 @@ -table('media'); - - if ($table->hasColumn('id_scheduled')) - { - if ($table->hasForeignKey('id_scheduled')) - { - $table->dropForeignKey('id_scheduled'); - } - - $table->removeColumn('id_scheduled'); - $table->update(); - } - - if ($table->hasColumn('id_user')) - { - if ($table->hasForeignKey('id_user')) - { - $table->dropForeignKey('id_user'); - } - - $table->removeColumn('id_user'); - $table->update(); - } - - $table->addColumn('id_user', 'integer') - ->addForeignKey('id_user', 'user', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) - ->update(); - - //Add table to join scheduled and media - $table = $this->table('media_scheduled'); - $table->addColumn('id_media', 'integer') - ->addColumn('id_scheduled', 'integer') - ->addForeignKey('id_media', 'media', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) - ->addForeignKey('id_scheduled', 'scheduled', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) - ->create(); - - //Add table to join sended and media - $table = $this->table('media_sended'); - $table->addColumn('id_media', 'integer') - ->addColumn('id_sended', 'integer') - ->addForeignKey('id_media', 'media', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) - ->addForeignKey('id_sended', 'sended', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) - ->create(); - - //Add table to join received and media - $table = $this->table('media_received'); - $table->addColumn('id_media', 'integer') - ->addColumn('id_received', 'integer') - ->addForeignKey('id_media', 'media', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) - ->addForeignKey('id_received', 'received', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) - ->create(); - } -} diff --git a/db/migrations/20210318142759_add_is_mms.php b/db/migrations/20210318142759_add_is_mms.php deleted file mode 100644 index 1e7ec14..0000000 --- a/db/migrations/20210318142759_add_is_mms.php +++ /dev/null @@ -1,46 +0,0 @@ -table('scheduled'); - $table->addColumn('mms', 'boolean', ['default' => 0, 'null' => false]) - ->update(); - - $table = $this->table('sended'); - $table->addColumn('mms', 'boolean', ['default' => 0, 'null' => false]) - ->update(); - - $table = $this->table('received'); - $table->addColumn('mms', 'boolean', ['default' => 0, 'null' => false]) - ->update(); - } -} diff --git a/db/migrations/20210322193953_update_webhook_types.php b/db/migrations/20210322193953_update_webhook_types.php deleted file mode 100644 index 80f2392..0000000 --- a/db/migrations/20210322193953_update_webhook_types.php +++ /dev/null @@ -1,16 +0,0 @@ -execute('ALTER TABLE `webhook` MODIFY `type` ENUM(\'send_sms\', \'receive_sms\', \'inbound_call\')'); - } - - public function down() - { - $this->execute('ALTER TABLE `webhook` MODIFY `type` ENUM(\'send_sms\', \'receive_sms\')'); - } -} diff --git a/db/migrations/20210322223812_create_call.php b/db/migrations/20210322223812_create_call.php deleted file mode 100644 index 6060c09..0000000 --- a/db/migrations/20210322223812_create_call.php +++ /dev/null @@ -1,47 +0,0 @@ -table('call'); - $table->addColumn('id_user', 'integer') - ->addColumn('id_phone', 'integer', ['null' => true]) - ->addColumn('uid', 'string', ['limit' => 500]) - ->addColumn('start', 'datetime') - ->addColumn('end', 'datetime', ['null' => true]) - ->addColumn('direction', 'enum', ['values' => ['inbound', 'outbound']]) - ->addColumn('origin', 'string', ['limit' => 20, 'null' => true]) - ->addColumn('destination', 'string', ['limit' => 20, 'null' => true]) - ->addForeignKey('id_user', 'user', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) - ->addForeignKey('id_phone', 'phone', 'id', ['delete' => 'SET_NULL', 'update' => 'CASCADE']) - ->create(); - } -} diff --git a/db/migrations/20210423172422_add_created_at_and_updated_at.php b/db/migrations/20210423172422_add_created_at_and_updated_at.php deleted file mode 100644 index 31a19a5..0000000 --- a/db/migrations/20210423172422_add_created_at_and_updated_at.php +++ /dev/null @@ -1,53 +0,0 @@ -getAdapter()->getOption('name'); - $query = 'SELECT table_name FROM information_schema.tables WHERE table_schema = \'' . $database_name . '\''; - $tables = $this->query($query)->fetchAll(); - foreach ($tables as $table) - { - //Do not modify phinxlog - if ($table['table_name'] == 'phinxlog') - { - continue; - } - - //Foreach table add timestamps, created_at and updated_at whith default values - $table = $this->table($table['table_name']); - $table->addColumn('created_at', 'timestamp', ['null' => false, 'default' => 'CURRENT_TIMESTAMP']); - $table->addColumn('updated_at', 'timestamp', ['null' => true, 'update' => 'CURRENT_TIMESTAMP']); - $table->update(); - } - - } -} diff --git a/env.php.dist b/env.php.dist index 5aa3260..3c18bd8 100644 --- a/env.php.dist +++ b/env.php.dist @@ -16,9 +16,6 @@ 'HTTP_PWD_SOUND' => HTTP_PWD_ASSETS . '/sounds', 'PWD_ADAPTERS' => PWD . '/adapters', 'PWD_DATA' => PWD . '/data', - 'HTTP_PWD_DATA' => HTTP_PWD . '/data', - 'PWD_DATA_PUBLIC' => PWD . '/data/public', - 'HTTP_PWD_DATA_PUBLIC' => HTTP_PWD . '/data/public', 'PWD_LOGS' => '/var/log/raspisms', 'PWD_PID' => '/var/run/raspisms', 'APP_SECRET' => '%APP_SECRET%', @@ -69,7 +66,7 @@ 'preferred_phone_country' => 'fr,be,ca', 'default_phone_country' => 'fr', 'authorized_phone_country' => 'fr,be,ca', - 'mms' => 1, + 'mms' => 0, ], ]; diff --git a/env.prod.php.dist b/env.prod.php.dist index 8ff5fd5..e41509d 100644 --- a/env.prod.php.dist +++ b/env.prod.php.dist @@ -1,8 +1,5 @@ '%APP_STATIC_HTTP_URL%', - //Database access 'DATABASE_HOST' => '%APP_DATABASE_HOST%', 'DATABASE_NAME' => '%APP_DATABASE_NAME%', diff --git a/models/Call.php b/models/Call.php deleted file mode 100644 index e8e08ce..0000000 --- a/models/Call.php +++ /dev/null @@ -1,91 +0,0 @@ - - * - * This source file is subject to the GPL-3.0 license that is bundled - * with this source code in the file LICENSE. - */ - -namespace models; - - /** - * Manage bdd operations for calls - */ - class Call extends StandardModel - { - const DIRECTION_INBOUND = 'inbound'; - const DIRECTION_OUTBOUND = 'outbound'; - - /** - * Return a list of call for a user. - * Add a column contact_name and phone_name when available. - * - * @param int $id_user : user id - * @param ?int $limit : Number of entry to return or null - * @param ?int $offset : Number of entry to ignore or null - * - * @return array - */ - public function list_for_user(int $id_user, $limit, $offset) - { - $query = ' - SELECT `call`.*, contact.name as contact_name, phone.name as phone_name - FROM `call` - LEFT JOIN contact - ON contact.number = `call`.destination - OR contact.number = `call`.origin - LEFT JOIN phone - ON phone.id = `call`.id_phone - WHERE `call`.id_user = :id_user - '; - - if (null !== $limit) - { - $limit = (int) $limit; - - $query .= ' LIMIT ' . $limit; - if (null !== $offset) - { - $offset = (int) $offset; - $query .= ' OFFSET ' . $offset; - } - } - - $params = [ - 'id_user' => $id_user, - ]; - - return $this->_run_query($query, $params); - } - - /** - * Get a call for a user by his phone and uid - * - * @param int $id_user : user id - * @param int $id_phone : phone id - * @param int $uid : call uid - * - * @return array : the call or an empty array - */ - public function get_by_uid_and_phone_for_user($id_user, $id_phone, $uid) - { - $where = [ - 'id_user' => $id_user, - 'id_phone' => $id_phone, - 'uid' => $uid, - ]; - - return $this->_select_one($this->get_table_name(), $where); - } - - /** - * Return table name. - */ - protected function get_table_name(): string - { - return 'call'; - } - } diff --git a/models/Media.php b/models/Media.php index 830acd7..7b7cd83 100644 --- a/models/Media.php +++ b/models/Media.php @@ -17,255 +17,226 @@ namespace models; class Media extends StandardModel { /** - * Return all medias for a scheduled. + * Return an entry by his id for a user. * + * @param int $id_user : user id + * @param int $id : entry id + * + * @return array + */ + public function get_for_user(int $id_user, int $id) + { + $query = ' + SELECT * FROM `' . $this->get_table_name() . '` + WHERE id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user) + AND id = :id + '; + + $params = [ + 'id' => $id, + 'id_user' => $id_user, + ]; + + $receiveds = $this->_run_query($query, $params); + + return $receiveds[0] ?? []; + } + + /** + * Return all entries for a user. + * + * @param int $id_user : user id + * + * @return array + */ + public function gets_for_user(int $id_user) + { + $query = ' + SELECT * FROM `' . $this->get_table_name() . '` + WHERE id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user) + '; + + $params = [ + 'id_user' => $id_user, + ]; + + $receiveds = $this->_run_query($query, $params); + } + + /** + * Return a media for a user and a scheduled. + * + * @param int $id_user : user id * @param int $id_scheduled : scheduled id * * @return array */ - public function gets_for_scheduled(int $id_scheduled) + public function get_for_scheduled_and_user(int $id_user, int $id_scheduled) { $query = ' - SELECT m.id as id, m.id_user as id_user, m.path as path - FROM `' . $this->get_table_name() . '` as m - INNER JOIN media_scheduled as ms - ON m.id = ms.id_media - WHERE ms.id_scheduled = :id_scheduled + SELECT * FROM `' . $this->get_table_name() . '` + WHERE id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user) + AND id_scheduled = :id_scheduled '; $params = [ + 'id_user' => $id_user, 'id_scheduled' => $id_scheduled, ]; + $receiveds = $this->_run_query($query, $params); + if (!$receiveds) + { + return false; + } + + return $receiveds[0]; + } + + /** + * Return a list of media for a user. + * + * @param int $id_user : User id + * @param int $limit : Max results to return + * @param int $offset : Number of results to ignore + */ + public function list_for_user($id_user, $limit, $offset) + { + $limit = (int) $limit; + $offset = (int) $offset; + + $query = ' + SELECT * FROM media + WHERE id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user) + LIMIT ' . $limit . ' OFFSET ' . $offset; + + $params = [ + 'id_user' => $id_user, + ]; + return $this->_run_query($query, $params); } - + /** - * Return all medias for a sended. + * Return a list of medias in a group of ids and for a user. * - * @param int $id_sended : sended id + * @param int $id_user : user id + * @param array $ids : ids of medias to find * * @return array */ - public function gets_for_sended(int $id_sended) + public function gets_in_for_user(int $id_user, $ids) { $query = ' - SELECT m.id as id, m.id_user as id_user, m.path as path - FROM `' . $this->get_table_name() . '` as m - INNER JOIN media_sended as ms - ON m.id = ms.id_media - WHERE ms.id_sended = :id_sended - '; + SELECT * FROM media + WHERE id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user) + AND id '; - $params = [ - 'id_sended' => $id_sended, - ]; + //On génère la clause IN et les paramètres adaptés depuis le tableau des id + $generated_in = $this->_generate_in_from_array($ids); + $query .= $generated_in['QUERY']; + $params = $generated_in['PARAMS']; + $params['id_user'] = $id_user; return $this->_run_query($query, $params); } - + /** - * Return all medias for a received. + * Delete a entry by his id for a user. * - * @param int $id_received : received id + * @param int $id_user : User id + * @param int $id : Entry id * - * @return array + * @return int : Number of removed rows */ - public function gets_for_received(int $id_received) + public function delete_for_user(int $id_user, int $id) { $query = ' - SELECT m.id as id, m.id_user as id_user, m.path as path - FROM `' . $this->get_table_name() . '` as m - INNER JOIN media_received as mr - ON m.id = mr.id_media - WHERE mr.id_received = :id_received + DELETE FROM media + WHERE id = :id + AND id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user) + '; + + $params = ['id_user' => $id_user, 'id' => $id]; + + return $this->_run_query($query, $params, self::ROWCOUNT); + } + + /** + * Delete a entry by his id for a user. + * + * @param int $id_user : User id + * @param int $id_scheduled : Scheduled id + * + * @return int : Number of removed rows + */ + public function delete_for_scheduled_and_user(int $id_user, int $id_scheduled) + { + $query = ' + DELETE FROM media + WHERE id_scheduled = :id_scheduled + AND id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user) + '; + + $params = ['id_user' => $id_user, 'id_scheduled' => $id_scheduled]; + + return $this->_run_query($query, $params, self::ROWCOUNT); + } + + /** + * Update a media sms for a user. + * + * @param int $id_user : User id + * @param int $id : Entry id + * @param array $data : data to update + * + * @return int : number of modified rows + */ + public function update_for_user(int $id_user, int $id, array $data) + { + $params = []; + $sets = []; + + foreach ($data as $label => $value) + { + $label = preg_replace('#[^a-zA-Z0-9_]#', '', $label); + $params['set_' . $label] = $value; + $sets[] = '`' . $label . '` = :set_' . $label . ' '; + } + + $query = ' + UPDATE `media` + SET ' . implode(', ', $sets) . ' + WHERE id = :id + AND id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user) + '; + + $params['id'] = $id; + $params['id_user'] = $id_user; + + return $this->_run_query($query, $params, self::ROWCOUNT); + } + + /** + * Count number of media sms for user. + * + * @param int $id_user : user id + * + * @return int : Number of media SMS for user + */ + public function count_for_user($id_user) + { + $query = ' + SELECT COUNT(id) as nb + FROM media + WHERE id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user) '; $params = [ - 'id_received' => $id_received, + 'id_user' => $id_user, ]; - return $this->_run_query($query, $params); - } - - /** - * Link a media to a scheduled - * - * @param int $id_media : Media id - * @param int $id_scheduled : Scheduled id - * - * @return bool | int - */ - public function insert_media_scheduled (int $id_media, int $id_scheduled) - { - $entry = [ - 'id_media' => $id_media, - 'id_scheduled' => $id_scheduled, - ]; - - return $this->_insert('media_scheduled', $entry) ? $this->_last_id() : false; - } - - /** - * Link a media to a received - * - * @param int $id_media : Media id - * @param int $id_received : Scheduled id - * - * @return bool | int - */ - public function insert_media_received (int $id_media, int $id_received) - { - $entry = [ - 'id_media' => $id_media, - 'id_received' => $id_received, - ]; - - return $this->_insert('media_received', $entry) ? $this->_last_id() : false; - } - - /** - * Link a media to a sended - * - * @param int $id_media : Media id - * @param int $id_sended : Scheduled id - * - * @return bool | int - */ - public function insert_media_sended (int $id_media, int $id_sended) - { - $entry = [ - 'id_media' => $id_media, - 'id_sended' => $id_sended, - ]; - - return $this->_insert('media_sended', $entry) ? $this->_last_id() : false; - } - - /** - * Unlink a media of a scheduled - * - * @param int $id_media : Media id - * @param int $id_scheduled : Scheduled id - * - * @return bool | int - */ - public function delete_media_scheduled (int $id_media, int $id_scheduled) - { - $where = [ - 'id_media' => $id_media, - 'id_scheduled' => $id_scheduled, - ]; - - return $this->_delete('media_scheduled', $where); - } - - /** - * Unlink a media of a received - * - * @param int $id_media : Media id - * @param int $id_received : Scheduled id - * - * @return bool | int - */ - public function delete_media_received (int $id_media, int $id_received) - { - $where = [ - 'id_media' => $id_media, - 'id_received' => $id_received, - ]; - - return $this->_delete('media_received', $where); - } - - /** - * Unlink a media of a sended - * - * @param int $id_media : Media id - * @param int $id_sended : Scheduled id - * - * @return bool | int - */ - public function delete_media_sended (int $id_media, int $id_sended) - { - $where = [ - 'id_media' => $id_media, - 'id_sended' => $id_sended, - ]; - - return $this->_delete('media_sended', $where); - } - - - /** - * Unlink all medias of a scheduled - * - * @param int $id_scheduled : Scheduled id - * - * @return bool | int - */ - public function delete_all_for_scheduled (int $id_scheduled) - { - $where = [ - 'id_scheduled' => $id_scheduled, - ]; - - return $this->_delete('media_scheduled', $where); - } - - /** - * Unlink all medias of a received - * - * @param int $id_received : Scheduled id - * - * @return bool | int - */ - public function delete_all_for_received (int $id_received) - { - $where = [ - 'id_received' => $id_received, - ]; - - return $this->_delete('media_received', $where); - } - - /** - * Unlink all medias of a sended - * - * @param int $id_sended : Scheduled id - * - * @return bool | int - */ - public function delete_all_for_sended (int $id_sended) - { - $where = [ - 'id_sended' => $id_sended, - ]; - - return $this->_delete('media_sended', $where); - } - - /** - * Find all unused medias - * @return array - */ - public function gets_unused () - { - $query = ' - SELECT `media`.* - FROM `media` - LEFT JOIN `media_sended` - ON `media`.id = `media_sended`.id_media - LEFT JOIN `media_received` - ON `media`.id = `media_received`.id_media - LEFT JOIN `media_scheduled` - ON `media`.id = `media_scheduled`.id_media - WHERE `media_sended`.id IS NULL - AND `media_received`.id IS NULL - AND `media_scheduled`.id IS NULL - '; - - return $this->_run_query($query); + return $this->_run_query($query, $params)[0]['nb'] ?? 0; } /** diff --git a/models/Received.php b/models/Received.php index 28fabef..23a8c05 100644 --- a/models/Received.php +++ b/models/Received.php @@ -178,34 +178,6 @@ namespace models; return $this->_run_query($query, $params); } - - /** - * Return sendeds for an origin and a user since a date. - * - * @param int $id_user : User id - * @param string $since : Date we want messages since - * @param string $origin : Number who sent the message - * - * @return array - */ - public function gets_since_date_by_origin_and_user(int $id_user, string $since, string $origin) - { - $query = ' - SELECT * - FROM received - WHERE id_user = :id_user - AND origin = :origin - AND at > :since - '; - - $params = [ - 'id_user' => $id_user, - 'origin' => $origin, - 'since' => $since, - ]; - - return $this->_run_query($query, $params); - } /** * Get number of sended SMS for every date since a date for a specific user. diff --git a/models/Scheduled.php b/models/Scheduled.php index f1b2cdd..7d7bc90 100644 --- a/models/Scheduled.php +++ b/models/Scheduled.php @@ -233,63 +233,6 @@ namespace models; return $this->_run_query($query, $params); } - - - /** - * Get messages scheduled after a date for a number and a user. - * - * @param int $id_user : User id - * @param $date : Date after which we want messages - * @param string $number : Number for which we want messages - * - * @return array - */ - public function gets_after_date_for_number_and_user(int $id_user, $date, string $number) - { - $query = ' - SELECT * - FROM scheduled - WHERE at > :date - AND id_user = :id_user - AND ( - id IN ( - SELECT id_scheduled - FROM scheduled_number - WHERE number = :number - ) - OR id IN ( - SELECT id_scheduled - FROM scheduled_contact - WHERE id_contact IN ( - SELECT id - FROM contact - WHERE number = :number - ) - ) - OR id IN ( - SELECT id_scheduled - FROM scheduled_group - WHERE id_group IN ( - SELECT id_group - FROM `group_contact` - WHERE id_contact IN ( - SELECT id - FROM contact - WHERE number = :number - ) - ) - ) - ) - '; - - $params = [ - 'id_user' => $id_user, - 'date' => $date, - 'number' => $number, - ]; - - return $this->_run_query($query, $params); - } /** * Get scheduleds before a date. diff --git a/models/Sended.php b/models/Sended.php index fa91346..f0235ba 100644 --- a/models/Sended.php +++ b/models/Sended.php @@ -112,35 +112,6 @@ namespace models; return $this->_run_query($query, $params); } - - - /** - * Return sendeds for an destination and a user since a date. - * - * @param int $id_user : User id - * @param string $since : Date we want messages since - * @param string $destination : Number who sent the message - * - * @return array - */ - public function gets_since_date_by_destination_and_user(int $id_user, string $since, string $destination) - { - $query = ' - SELECT * - FROM sended - WHERE id_user = :id_user - AND destination = :destination - AND at > :since - '; - - $params = [ - 'id_user' => $id_user, - 'destination' => $destination, - 'since' => $since, - ]; - - return $this->_run_query($query, $params); - } /** * Return sended for an uid and an adapter. diff --git a/models/StandardModel.php b/models/StandardModel.php index 45bf967..32b9686 100644 --- a/models/StandardModel.php +++ b/models/StandardModel.php @@ -158,9 +158,9 @@ namespace models; * * @return int : number of modified rows */ - public function update_for_user(int $id_user, int $id, array $data) + public function update_for_user(int $id_user, int $id, array $entry) { - return $this->_update($this->get_table_name(), $data, ['id_user' => $id_user, 'id' => $id]); + return $this->_update($this->get_table_name(), $entry, ['id_user' => $id_user, 'id' => $id]); } /** diff --git a/models/Webhook.php b/models/Webhook.php index 48d4998..945cd82 100644 --- a/models/Webhook.php +++ b/models/Webhook.php @@ -13,9 +13,8 @@ namespace models; class Webhook extends StandardModel { - const TYPE_SEND_SMS = 'send_sms'; - const TYPE_RECEIVE_SMS = 'receive_sms'; - const TYPE_INBOUND_CALL = 'inbound_call'; + const TYPE_SEND = 'send_sms'; + const TYPE_RECEIVE = 'receive_sms'; /** * Find all webhooks for a user and for a type of webhook. diff --git a/routes.php b/routes.php index 1e3adb1..121d4ba 100644 --- a/routes.php +++ b/routes.php @@ -43,7 +43,6 @@ 'update' => '/contact/update/{csrf}/', 'import' => '/contact/import/{csrf}/', 'export' => '/contact/export/{format}/', - 'conditional_delete' => '/contact/conditional_delete/{csrf}/', 'json_list' => '/contacts.json/', ], @@ -55,14 +54,14 @@ 'list_json' => '/discussion/json/', 'show' => '/discussion/show/{number}/', 'send' => '/discussion/send/{csrf}/', - 'get_messages' => [ - '/discussion/getmessage/{number}/{transaction_id}/', - '/discussion/getmessage/{number}/{transaction_id}/{since}/', - ], + 'get_messages' => '/discussion/getmessage/{number}/{transaction_id}/', ], 'Event' => [ - 'list' => '/event/', + 'list' => [ + '/event/', + '/event/p/{page}/', + ], 'list_json' => '/event/json/', 'delete' => '/event/delete/{csrf}/', ], @@ -156,12 +155,6 @@ 'delete' => '/phone/delete/{csrf}/', ], - 'Call' => [ - 'list' => '/call/', - 'list_json' => '/call/json/', - 'delete' => '/call/delete/{csrf}/', - ], - 'Webhook' => [ 'list' => '/webhook/', 'list_json' => '/webhook/json/', @@ -175,8 +168,6 @@ 'Callback' => [ 'update_sended_status' => '/callback/status/{adapter_uid}/', 'reception' => '/callback/reception/{adapter_uid}/{id_phone}/', - 'inbound_call' => '/callback/inbound_call/{id_phone}/', - 'end_call' => '/callback/end_call/{id_phone}/', ], 'Api' => [ diff --git a/templates/call/list.php b/templates/call/list.php deleted file mode 100644 index 76d2eaf..0000000 --- a/templates/call/list.php +++ /dev/null @@ -1,145 +0,0 @@ -render('incs/head', ['title' => 'Appels - Show All']) -?> -
-render('incs/nav', ['page' => 'calls']) -?> -
-
- -
-
-

- Dashboard Appels -

- -
-
- - -
-
-
-
-

Liste des appels

-
-
-
-
- - - - - - - - - - - - -
OrigineDestinataireDébut de l'appelFin de l'appelDirection
-
-
-
- Action pour la séléction : - -
-
-
-
-
-
-
-
-
-
- -render('incs/footer'); diff --git a/templates/command/list.php b/templates/command/list.php index df6b555..89a2ab1 100644 --- a/templates/command/list.php +++ b/templates/command/list.php @@ -72,7 +72,7 @@ jQuery(document).ready(function () { jQuery('.datatable').DataTable({ "pageLength": 25, - "lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]], + "bLengthChange": false, "language": { "url": HTTP_PWD + "/assets/js/datatables/french.json", }, diff --git a/templates/conditional_group/add.php b/templates/conditional_group/add.php index 13a0ac9..6e517ab 100644 --- a/templates/conditional_group/add.php +++ b/templates/conditional_group/add.php @@ -48,7 +48,7 @@

- Les conditions vous permettent de définir dynamiquement les contacts qui appartiennent au groupe en utilisant leurs données additionnelles. Pour plus d'informations consultez la documentation relative à l'utilisation des groupes conditionnels.
+ Les conditions vous permettent de définir dynamiquement les contacts qui appartiennent au groupe en utilisant leurs données additionnelles. Pour plus d'informations consultez la documentation relative à l'utilisation des groupes conditionnels.
Vous pouvez prévisualiser les contacts qui feront parti du groupe en cliquant sur le bouton "Prévisualiser les contacts".

diff --git a/templates/conditional_group/list.php b/templates/conditional_group/list.php index bca9c0f..ecb104e 100644 --- a/templates/conditional_group/list.php +++ b/templates/conditional_group/list.php @@ -1,7 +1,7 @@ render('incs/head', ['title' => 'Groupes Conditionnels - Show All']) + $this->render('incs/head', ['title' => 'ConditionalGroupes Conditionnels - Show All']) ?>
Nom Condition - Date de création - Dernière modification ✓ @@ -74,7 +72,7 @@ jQuery(document).ready(function () { jQuery('.datatable').DataTable({ "pageLength": 25, - "lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]], + "bLengthChange": false, "language": { "url": HTTP_PWD + "/assets/js/datatables/french.json", }, @@ -89,14 +87,7 @@ jQuery(document).ready(function () }, "columns" : [ {data: 'name', render: jQuery.fn.dataTable.render.text()}, - { - data: 'condition', - render: function (data, type, row, meta) { - return '' + jQuery.fn.dataTable.render.text().display(data) + ''; - }, - }, - {data: 'created_at'}, - {data: 'updated_at'}, + {data: 'condition', render: jQuery.fn.dataTable.render.text()}, { data: 'id', render: function (data, type, row, meta) { diff --git a/templates/contact/list.php b/templates/contact/list.php index c8f17e1..47e3d18 100644 --- a/templates/contact/list.php +++ b/templates/contact/list.php @@ -14,8 +14,7 @@

Dashboard Contacts - Supprimer une liste dynamique de contacts - Exporter la liste des contacts + Exporter la liste des contacts Importer une liste de contacts

-