Merge modifications for version 3.1, special thanks to EMC2STUDIO for investing in free software.
This commit is contained in:
commit
b325ae1a7e
|
@ -8,8 +8,10 @@ scripts/
|
||||||
composer.lock
|
composer.lock
|
||||||
env.*
|
env.*
|
||||||
phinx.*
|
phinx.*
|
||||||
|
descartes/env.php
|
||||||
|
|
||||||
data/test_write_sms.json
|
data/test_write_sms.json
|
||||||
data/test_read_sms.json
|
data/test_read_sms.json
|
||||||
|
data/public/
|
||||||
|
|
||||||
!*.dist
|
!*.dist
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
RewriteEngine on
|
RewriteEngine on
|
||||||
RewriteRule ^assets - [L]
|
RewriteRule ^assets - [L]
|
||||||
RewriteRule ^.well-known - [L]
|
RewriteRule ^.well-known - [L]
|
||||||
|
RewriteRule ^data/public/ - [L]
|
||||||
RewriteRule . index.php
|
RewriteRule . index.php
|
||||||
|
|
|
@ -83,20 +83,42 @@ namespace adapters;
|
||||||
*/
|
*/
|
||||||
public static function meta_support_status_change(): bool;
|
public static function meta_support_status_change(): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the implemented service support mms reception
|
||||||
|
*/
|
||||||
|
public static function meta_support_mms_reception(): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 send a SMS to a number.
|
* Method called to send a SMS to a number.
|
||||||
*
|
*
|
||||||
* @param string $destination : Phone number to send the sms to
|
* @param string $destination : Phone number to send the sms to
|
||||||
* @param string $text : Text of the SMS to send
|
* @param string $text : Text of the SMS to send
|
||||||
* @param bool $flash : Is the SMS a Flash SMS
|
* @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 : [
|
* @return array : [
|
||||||
* bool 'error' => false if no error, true else
|
* bool 'error' => false if no error, true else
|
||||||
* ?string 'error_message' => null if no error, else error message
|
* ?string 'error_message' => null if no error, else error message
|
||||||
* ?string 'uid' => Uid of the sms created on success
|
* array 'uid' => Uid of the sms created on success
|
||||||
* ]
|
* ]
|
||||||
*/
|
*/
|
||||||
public function send(string $destination, string $text, bool $flash = false);
|
public function send(string $destination, string $text, bool $flash = false, bool $mms = false, array $medias = []) : array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called to read SMSs of the number.
|
* Method called to read SMSs of the number.
|
||||||
|
@ -104,15 +126,14 @@ namespace adapters;
|
||||||
* @return array : [
|
* @return array : [
|
||||||
* bool 'error' => false if no error, true else
|
* bool 'error' => false if no error, true else
|
||||||
* ?string 'error_message' => null if no error, else error message
|
* ?string 'error_message' => null if no error, else error message
|
||||||
* array 'smss' => Array of the sms reads
|
* 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 [
|
||||||
* string 'at' => sms reception date,
|
* 'filepath' => local file copy of the media,
|
||||||
* string 'text' => sms text,
|
* 'extension' (optional) => extension of the media,
|
||||||
* string 'origin' => phone number who sent the sms
|
* 'mimetype' (optional) => mimetype of the media
|
||||||
* ],
|
|
||||||
* ...
|
|
||||||
* ]
|
* ]
|
||||||
|
* ], ...]
|
||||||
* ]
|
* ]
|
||||||
*/
|
*/
|
||||||
public function read(): array;
|
public function read(): array;
|
||||||
|
@ -142,9 +163,44 @@ namespace adapters;
|
||||||
* string 'at' : Recepetion date format Y-m-d H:i:s,
|
* string 'at' : Recepetion date format Y-m-d H:i:s,
|
||||||
* string 'text' : SMS body,
|
* string 'text' : SMS body,
|
||||||
* string 'origin' : SMS sender,
|
* 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;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,19 +127,32 @@ namespace adapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called to send a SMS to a number.
|
* Does the implemented service support mms reception
|
||||||
*
|
|
||||||
* @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 function send(string $destination, string $text, bool $flash = false)
|
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
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
'error' => false,
|
'error' => false,
|
||||||
|
@ -213,14 +226,18 @@ namespace adapters;
|
||||||
return [];
|
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
|
public function test(): bool
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function inbound_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function end_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,19 +137,32 @@ namespace adapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called to send a SMS to a number.
|
* Does the implemented service support mms reception
|
||||||
*
|
|
||||||
* @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 function send(string $destination, string $text, bool $flash = false)
|
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
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
'error' => false,
|
'error' => false,
|
||||||
|
@ -230,15 +243,6 @@ namespace adapters;
|
||||||
return $response;
|
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
|
public function read(): array
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
|
@ -287,47 +291,32 @@ namespace adapters;
|
||||||
return $response;
|
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
|
public function test(): bool
|
||||||
{
|
{
|
||||||
//Always return true as we cannot test because we would be needing a root account
|
//Always return true as we cannot test because we would be needing a root account
|
||||||
return true;
|
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()
|
public static function status_change_callback()
|
||||||
{
|
{
|
||||||
return false;
|
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
|
public static function reception_callback(): array
|
||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function inbound_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function end_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to unlock pin.
|
* Function to unlock pin.
|
||||||
*
|
*
|
||||||
|
|
|
@ -174,19 +174,32 @@ class OctopushShortcodeAdapter implements AdapterInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called to send a SMS to a number.
|
* Does the implemented service support mms reception
|
||||||
*
|
|
||||||
* @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 function send(string $destination, string $text, bool $flash = false)
|
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
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
'error' => false,
|
'error' => false,
|
||||||
|
@ -268,26 +281,11 @@ 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
|
public function read(): array
|
||||||
{
|
{
|
||||||
return [];
|
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
|
public function test(): bool
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -339,11 +337,6 @@ 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()
|
public static function status_change_callback()
|
||||||
{
|
{
|
||||||
header('Connection: close');
|
header('Connection: close');
|
||||||
|
@ -383,20 +376,6 @@ class OctopushShortcodeAdapter implements AdapterInterface
|
||||||
return ['uid' => $uid, 'status' => $status];
|
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
|
public static function reception_callback(): array
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
|
@ -438,4 +417,14 @@ class OctopushShortcodeAdapter implements AdapterInterface
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function inbound_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function end_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,19 +179,32 @@ class OctopushVirtualNumberAdapter implements AdapterInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called to send a SMS to a number.
|
* Does the implemented service support mms reception
|
||||||
*
|
|
||||||
* @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 function send(string $destination, string $text, bool $flash = false)
|
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
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
'error' => false,
|
'error' => false,
|
||||||
|
@ -268,26 +281,11 @@ 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
|
public function read(): array
|
||||||
{
|
{
|
||||||
return [];
|
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
|
public function test(): bool
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -339,11 +337,6 @@ 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()
|
public static function status_change_callback()
|
||||||
{
|
{
|
||||||
header('Connection: close');
|
header('Connection: close');
|
||||||
|
@ -383,20 +376,6 @@ class OctopushVirtualNumberAdapter implements AdapterInterface
|
||||||
return ['uid' => $uid, 'status' => $status];
|
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
|
public static function reception_callback(): array
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
|
@ -438,4 +417,14 @@ class OctopushVirtualNumberAdapter implements AdapterInterface
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function inbound_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function end_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,19 +171,32 @@ namespace adapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called to send a SMS to a number.
|
* Does the implemented service support mms reception
|
||||||
*
|
|
||||||
* @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)
|
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
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
'error' => false,
|
'error' => false,
|
||||||
|
@ -241,15 +254,6 @@ 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
|
public function read(): array
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
|
@ -306,12 +310,6 @@ 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
|
public function test(): bool
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -335,11 +333,6 @@ 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()
|
public static function status_change_callback()
|
||||||
{
|
{
|
||||||
$uid = $_GET['id'] ?? false;
|
$uid = $_GET['id'] ?? false;
|
||||||
|
@ -372,22 +365,18 @@ namespace adapters;
|
||||||
return ['uid' => $uid, 'status' => $status];
|
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
|
public static function reception_callback(): array
|
||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function inbound_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function end_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,19 +182,32 @@ namespace adapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called to send a SMS to a number.
|
* Does the implemented service support mms reception
|
||||||
*
|
|
||||||
* @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 function send(string $destination, string $text, bool $flash = false)
|
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
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
'error' => false,
|
'error' => false,
|
||||||
|
@ -245,15 +258,6 @@ 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
|
public function read(): array
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
|
@ -304,12 +308,6 @@ 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
|
public function test(): bool
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -334,11 +332,6 @@ 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()
|
public static function status_change_callback()
|
||||||
{
|
{
|
||||||
$uid = $_GET['id'] ?? false;
|
$uid = $_GET['id'] ?? false;
|
||||||
|
@ -371,22 +364,18 @@ namespace adapters;
|
||||||
return ['uid' => $uid, 'status' => $status];
|
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
|
public static function reception_callback(): array
|
||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function inbound_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function end_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,19 +132,32 @@ namespace adapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called to send a SMS to a number.
|
* Does the implemented service support mms reception
|
||||||
*
|
|
||||||
* @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 function send(string $destination, string $text, bool $flash = false)
|
public static function meta_support_mms_reception(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the implemented service support mms sending
|
||||||
|
*/
|
||||||
|
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
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
'error' => false,
|
'error' => false,
|
||||||
|
@ -155,7 +168,7 @@ namespace adapters;
|
||||||
$uid = uniqid();
|
$uid = uniqid();
|
||||||
|
|
||||||
$at = (new \DateTime())->format('Y-m-d H:i:s');
|
$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]) . "\n", FILE_APPEND);
|
$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);
|
||||||
if (false === $success)
|
if (false === $success)
|
||||||
{
|
{
|
||||||
$response['error'] = true;
|
$response['error'] = true;
|
||||||
|
@ -170,13 +183,18 @@ namespace adapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called to read SMSs of the number.
|
* 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 :
|
||||||
* @return array : [
|
* {
|
||||||
* bool 'error' => false if no error, true else
|
* "at" : "2021-03-26 11:21:48",
|
||||||
* ?string 'error_message' => null if no error, else error message
|
* "medias" : [
|
||||||
* array 'sms' => Array of the sms reads
|
* "https://unsplash.com/photos/q4DJVtxES0w/download?force=true&w=640",
|
||||||
* ]
|
* "/tmp/somelocalfile.jpg"
|
||||||
|
* ],
|
||||||
|
* "mms" : true,
|
||||||
|
* "origin" : "+33612345678",
|
||||||
|
* "text" : "SMS Text"
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
public function read(): array
|
public function read(): array
|
||||||
{
|
{
|
||||||
|
@ -217,7 +235,36 @@ namespace adapters;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response['smss'][] = $decode_sms;
|
$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;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
|
@ -231,20 +278,11 @@ 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
|
public function test(): bool
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called on reception of a status update notification for a SMS.
|
|
||||||
*/
|
|
||||||
public static function status_change_callback()
|
public static function status_change_callback()
|
||||||
{
|
{
|
||||||
$uid = $_GET['uid'] ?? false;
|
$uid = $_GET['uid'] ?? false;
|
||||||
|
@ -281,22 +319,62 @@ namespace adapters;
|
||||||
return $return;
|
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
|
public static function reception_callback(): array
|
||||||
{
|
{
|
||||||
return [];
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,19 +176,32 @@ class TwilioVirtualNumberAdapter implements AdapterInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called to send a SMS to a number.
|
* Does the implemented service support mms reception
|
||||||
*
|
|
||||||
* @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 function send(string $destination, string $text, bool $flash = false)
|
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
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
'error' => false,
|
'error' => false,
|
||||||
|
@ -228,15 +241,6 @@ 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
|
public function read(): array
|
||||||
{
|
{
|
||||||
$response = [
|
$response = [
|
||||||
|
@ -282,12 +286,6 @@ 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
|
public function test(): bool
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -313,11 +311,6 @@ 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()
|
public static function status_change_callback()
|
||||||
{
|
{
|
||||||
$sid = $_REQUEST['MessageSid'] ?? false;
|
$sid = $_REQUEST['MessageSid'] ?? false;
|
||||||
|
@ -349,22 +342,18 @@ class TwilioVirtualNumberAdapter implements AdapterInterface
|
||||||
return ['uid' => $sid, 'status' => $status];
|
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
|
public static function reception_callback(): array
|
||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function inbound_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function end_call_callback(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,6 +205,34 @@ footer img
|
||||||
font-size: 0.9em;
|
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
|
.message-container
|
||||||
{
|
{
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
@ -254,6 +282,12 @@ footer img
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-input input[type="file"]
|
||||||
|
{
|
||||||
|
margin-top: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.message-in-progress-hover
|
.message-in-progress-hover
|
||||||
{
|
{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -408,3 +442,21 @@ footer img
|
||||||
{
|
{
|
||||||
margin-bottom: 30px;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -45,8 +45,9 @@ function verifReceived()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cette fonction permet de scroller au dernier message
|
* Cette fonction permet de scroller au dernier message
|
||||||
|
* @param force: bool : should we force the scroll
|
||||||
*/
|
*/
|
||||||
function scrollDownDiscussion()
|
function scrollDownDiscussion(force)
|
||||||
{
|
{
|
||||||
var discussion_height = jQuery('.discussion-container').innerHeight();
|
var discussion_height = jQuery('.discussion-container').innerHeight();
|
||||||
var discussion_scroll_height = jQuery('.discussion-container')[0].scrollHeight;
|
var discussion_scroll_height = jQuery('.discussion-container')[0].scrollHeight;
|
||||||
|
@ -54,7 +55,7 @@ function scrollDownDiscussion()
|
||||||
var scroll_before_end = discussion_scroll_height - (discussion_scroll_top + discussion_height);
|
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
|
//On scroll uniquement si on a pas remonté plus haut que la moitié de la fenetre de discussion
|
||||||
if (scroll_before_end <= discussion_height / 2)
|
if (force || scroll_before_end <= discussion_height / 2)
|
||||||
{
|
{
|
||||||
jQuery('.discussion-container').animate({scrollTop: 1000000});
|
jQuery('.discussion-container').animate({scrollTop: 1000000});
|
||||||
}
|
}
|
||||||
|
@ -115,8 +116,8 @@ jQuery(document).ready(function()
|
||||||
var form = jQuery(this);
|
var form = jQuery(this);
|
||||||
var message = form.find('textarea').val();
|
var message = form.find('textarea').val();
|
||||||
var formData = new FormData(form[0]);
|
var formData = new FormData(form[0]);
|
||||||
jQuery('.discussion-container').find('#send-message-spiner').remove();
|
jQuery('.discussion-container').find('#send-message-spinner').remove();
|
||||||
jQuery('.discussion-container').append('<div class="text-center" id="send-message-spiner"><i class="fa fa-spinner fa-spin"></i></div>');
|
jQuery('.discussion-container').append('<div class="text-center" id="send-message-spinner"><i class="fa fa-spinner fa-spin"></i></div>');
|
||||||
scrollDownDiscussion();
|
scrollDownDiscussion();
|
||||||
jQuery.ajax({
|
jQuery.ajax({
|
||||||
url: form.attr('action'),
|
url: form.attr('action'),
|
||||||
|
@ -130,7 +131,7 @@ jQuery(document).ready(function()
|
||||||
if (!data.success)
|
if (!data.success)
|
||||||
{
|
{
|
||||||
showMessage(data.message.replace(/</g, "<").replace(/>/g, ">"), 0);
|
showMessage(data.message.replace(/</g, "<").replace(/>/g, ">"), 0);
|
||||||
jQuery('.discussion-container').find('#send-message-spiner').remove();
|
jQuery('.discussion-container').find('#send-message-spinner').remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).done(function()
|
}).done(function()
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
"ovh/ovh": "^2.0",
|
"ovh/ovh": "^2.0",
|
||||||
"twilio/sdk": "^6.1",
|
"twilio/sdk": "^6.1",
|
||||||
"symfony/yaml": "^5.0",
|
"symfony/yaml": "^5.0",
|
||||||
"phpmailer/phpmailer": "^6.1"
|
"phpmailer/phpmailer": "^6.1",
|
||||||
|
"ralouphie/mimey": "^2.1",
|
||||||
|
"kreait/firebase-php": "^5.14"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@ namespace controllers\internals;
|
||||||
private const ADAPTERS_META_START = 'meta_';
|
private const ADAPTERS_META_START = 'meta_';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List adapters using internal metas.
|
* List adapters with filepath and internal metas.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array : ['adapter_filepath' => ['meta...' => value, ...], ...]
|
||||||
*/
|
*/
|
||||||
public function list_adapters()
|
public function list_adapters()
|
||||||
{
|
{
|
||||||
|
@ -42,7 +42,7 @@ namespace controllers\internals;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$adapters[] = $metas;
|
$adapters[$file] = $metas;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $adapters;
|
return $adapters;
|
||||||
|
@ -116,4 +116,29 @@ namespace controllers\internals;
|
||||||
|
|
||||||
return $metas;
|
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;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of RaspiSMS.
|
||||||
|
*
|
||||||
|
* (c) Pierre-Lin Bonnemaison <plebwebsas@gmail.com>
|
||||||
|
*
|
||||||
|
* This source file is subject to the GPL-3.0 license that is bundled
|
||||||
|
* with this source code in the file LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace controllers\internals;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -151,4 +151,23 @@ namespace controllers\internals;
|
||||||
|
|
||||||
exit($success ? 0 : 1);
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,10 +101,11 @@ class Mailer extends \descartes\Controller
|
||||||
* @param string $destination : email address to send email to
|
* @param string $destination : email address to send email to
|
||||||
* @param array $settings : Email settings
|
* @param array $settings : Email settings
|
||||||
* @param array $data : Data to inject into email template
|
* @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
|
* @return bool : true on success, false on error
|
||||||
*/
|
*/
|
||||||
public function enqueue(string $destination, array $settings, array $data): bool
|
public function enqueue(string $destination, array $settings, array $data, array $attachments = []): bool
|
||||||
{
|
{
|
||||||
$response = $this->generate_body($settings, $data);
|
$response = $this->generate_body($settings, $data);
|
||||||
|
|
||||||
|
@ -113,6 +114,7 @@ class Mailer extends \descartes\Controller
|
||||||
'subject' => $settings['subject'],
|
'subject' => $settings['subject'],
|
||||||
'body' => $response['body'],
|
'body' => $response['body'],
|
||||||
'alt_body' => $response['alt_body'],
|
'alt_body' => $response['alt_body'],
|
||||||
|
'attachments' => $attachments,
|
||||||
];
|
];
|
||||||
|
|
||||||
$error_code = null;
|
$error_code = null;
|
||||||
|
|
|
@ -13,38 +13,192 @@ namespace controllers\internals;
|
||||||
|
|
||||||
class Media extends StandardController
|
class Media extends StandardController
|
||||||
{
|
{
|
||||||
|
const DEFAULT_CHMOD = 0660;
|
||||||
|
|
||||||
protected $model;
|
protected $model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a media.
|
* Create a media.
|
||||||
*
|
*
|
||||||
* @param int $id_user : Id of the user
|
* @param int $id_user : Id of the user
|
||||||
* @param int $id_scheduled : Id of the scheduled
|
* @param string $tmpfile_path : Path of the temporary local copy of the media
|
||||||
* @param array $media : $_FILES media array
|
* @param ?string $extension : Extension to use for the media
|
||||||
*
|
*
|
||||||
* @return bool : false on error, new media id else
|
* @return int : Exception on error, new media id else
|
||||||
*/
|
*/
|
||||||
public function create(int $id_user, int $id_scheduled, array $media): bool
|
public function create(int $id_user, string $tmpfile_path, ?string $extension = null)
|
||||||
{
|
{
|
||||||
$internal_scheduled = new Scheduled($this->bdd);
|
$user_path = \controllers\internals\Tool::create_user_public_path($id_user);
|
||||||
$scheduled = $internal_scheduled->get_for_user($id_user, $id_scheduled);
|
if (!file_exists($tmpfile_path))
|
||||||
if (!$scheduled)
|
|
||||||
{
|
{
|
||||||
return false;
|
throw new \Exception('File ' . $tmpfile_path . ' does not exists.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$result_upload_media = \controllers\internals\Tool::upload_file($media);
|
if (!is_readable($tmpfile_path))
|
||||||
if (false === $result_upload_media['success'])
|
|
||||||
{
|
{
|
||||||
return false;
|
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 = [
|
$data = [
|
||||||
'id_scheduled' => $id_scheduled,
|
'path' => $new_file_relpath,
|
||||||
'path' => $result_upload_media['content'],
|
'id_user' => $id_user,
|
||||||
];
|
];
|
||||||
|
|
||||||
return (bool) $this->get_model()->insert($data);
|
$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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,25 +206,16 @@ namespace controllers\internals;
|
||||||
*
|
*
|
||||||
* @param int $id_user : user id
|
* @param int $id_user : user id
|
||||||
* @param int $id_media : Media id
|
* @param int $id_media : Media id
|
||||||
* @param int $id_scheduled : Id of the scheduled
|
|
||||||
* @param string $path : Path of the file
|
* @param string $path : Path of the file
|
||||||
*
|
*
|
||||||
* @return bool : false on error, true on success
|
* @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
|
public function update_for_user(int $id_user, int $id_media, string $path): bool
|
||||||
{
|
{
|
||||||
$media = [
|
$media = [
|
||||||
'id_scheduled' => $id_scheduled,
|
|
||||||
'path' => $path,
|
'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 (bool) $this->get_model()->update_for_user($id_user, $id_media, $media);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +225,7 @@ namespace controllers\internals;
|
||||||
* @param int $id_user : User id
|
* @param int $id_user : User id
|
||||||
* @param int $id : Entry id
|
* @param int $id : Entry id
|
||||||
*
|
*
|
||||||
* @return int : Number of removed rows
|
* @return mixed bool|int : False on error, else number of removed rows
|
||||||
*/
|
*/
|
||||||
public function delete_for_user(int $id_user, int $id_media): bool
|
public function delete_for_user(int $id_user, int $id_media): bool
|
||||||
{
|
{
|
||||||
|
@ -90,41 +235,66 @@ namespace controllers\internals;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink($media['path']);
|
//Delete file
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$filepath = PWD_DATA_PUBLIC . '/' . $media['path'];
|
||||||
|
if (file_exists($filepath))
|
||||||
|
{
|
||||||
|
unlink($filepath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (\Throwable $t)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->get_model()->delete_for_user($id_user, $id_media);
|
return $this->get_model()->delete_for_user($id_user, $id_media);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a media for a scheduled and a user.
|
* Find medias for a scheduled.
|
||||||
*
|
*
|
||||||
* @param int $id_user : User id
|
* @param int $id_scheduled : Scheduled id to fin medias for
|
||||||
* @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']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->get_model()->delete_for_scheduled_and_user($id_user, $id_scheduled);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* @return mixed : Medias || false
|
||||||
*/
|
*/
|
||||||
public function get_for_scheduled_and_user(int $id_user, int $id_scheduled)
|
public function gets_for_scheduled(int $id_scheduled)
|
||||||
{
|
{
|
||||||
return $this->get_model()->get_for_scheduled_and_user($id_user, $id_scheduled);
|
return $this->get_model()->gets_for_scheduled($id_scheduled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find medias that are not used
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function gets_unused()
|
||||||
|
{
|
||||||
|
return $this->get_model()->gets_unused();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,6 +13,10 @@ namespace controllers\internals;
|
||||||
|
|
||||||
class Phone extends StandardController
|
class Phone extends StandardController
|
||||||
{
|
{
|
||||||
|
const MMS_SENDING = 'sending';
|
||||||
|
const MMS_RECEPTION = 'reception';
|
||||||
|
const MMS_BOTH = 'both';
|
||||||
|
|
||||||
protected $model;
|
protected $model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +43,63 @@ namespace controllers\internals;
|
||||||
return $this->get_model()->get_by_name($name);
|
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.
|
* Return a phone for a user by a name.
|
||||||
*
|
*
|
||||||
|
|
|
@ -39,10 +39,12 @@ namespace controllers\internals;
|
||||||
* @param string $origin : Number of the sender
|
* @param string $origin : Number of the sender
|
||||||
* @param string $status : Status of the received message
|
* @param string $status : Status of the received message
|
||||||
* @param bool $command : Is the sms a command
|
* @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
|
* @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)
|
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 = [])
|
||||||
{
|
{
|
||||||
$received = [
|
$received = [
|
||||||
'id_user' => $id_user,
|
'id_user' => $id_user,
|
||||||
|
@ -52,9 +54,39 @@ namespace controllers\internals;
|
||||||
'origin' => $origin,
|
'origin' => $origin,
|
||||||
'status' => $status,
|
'status' => $status,
|
||||||
'command' => $command,
|
'command' => $command,
|
||||||
|
'mms' => $mms,
|
||||||
];
|
];
|
||||||
|
|
||||||
return $this->get_model()->insert($received);
|
//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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,6 +161,19 @@ namespace controllers\internals;
|
||||||
return $this->get_model()->gets_by_origin_and_user($id_user, $origin);
|
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.
|
* Get number of sended SMS for every date since a date for a specific user.
|
||||||
*
|
*
|
||||||
|
@ -211,13 +256,18 @@ namespace controllers\internals;
|
||||||
* @param string $origin : Number of the sender
|
* @param string $origin : Number of the sender
|
||||||
* @param ?string $at : Message reception date, if null use current date
|
* @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 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 : [
|
* @return array : [
|
||||||
* bool 'error' => false if success, true else
|
* bool 'error' => false if success, true else
|
||||||
* ?string 'error_message' => null if success, error message 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): array
|
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
|
||||||
{
|
{
|
||||||
$return = [
|
$return = [
|
||||||
'error' => false,
|
'error' => false,
|
||||||
|
@ -236,7 +286,27 @@ namespace controllers\internals;
|
||||||
$text = $response;
|
$text = $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
$received_id = $this->create($id_user, $id_phone, $at, $text, $origin, $status, $is_command);
|
//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);
|
||||||
if (!$received_id)
|
if (!$received_id)
|
||||||
{
|
{
|
||||||
$return['error'] = true;
|
$return['error'] = true;
|
||||||
|
@ -251,10 +321,13 @@ namespace controllers\internals;
|
||||||
'text' => $text,
|
'text' => $text,
|
||||||
'destination' => $id_phone,
|
'destination' => $id_phone,
|
||||||
'origin' => $origin,
|
'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 = new Webhook($this->bdd);
|
||||||
$internal_webhook->trigger($id_user, \models\Webhook::TYPE_RECEIVE, $received);
|
$internal_webhook->trigger($id_user, \models\Webhook::TYPE_RECEIVE_SMS, $received);
|
||||||
|
|
||||||
$internal_user = new User($this->bdd);
|
$internal_user = new User($this->bdd);
|
||||||
$internal_user->transfer_received($id_user, $received);
|
$internal_user->transfer_received($id_user, $received);
|
||||||
|
|
|
@ -23,14 +23,16 @@ namespace controllers\internals;
|
||||||
* @param string $text : Text of the message
|
* @param string $text : Text of the message
|
||||||
* @param ?int $id_phone : Id of the phone to send message with, null by default
|
* @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 $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 $numbers : Numbers to send message to
|
||||||
* @param array $contacts_ids : Contact ids 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 $groups_ids : Group ids to send message to
|
||||||
* @param array $conditional_group_ids : Conditional Groups 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
|
* @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, array $numbers = [], array $contacts_ids = [], array $groups_ids = [], array $conditional_group_ids = [])
|
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 = [])
|
||||||
{
|
{
|
||||||
$scheduled = [
|
$scheduled = [
|
||||||
'id_user' => $id_user,
|
'id_user' => $id_user,
|
||||||
|
@ -38,8 +40,14 @@ namespace controllers\internals;
|
||||||
'text' => $text,
|
'text' => $text,
|
||||||
'id_phone' => $id_phone,
|
'id_phone' => $id_phone,
|
||||||
'flash' => $flash,
|
'flash' => $flash,
|
||||||
|
'mms' => $mms,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if ($text === '')
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (null !== $id_phone)
|
if (null !== $id_phone)
|
||||||
{
|
{
|
||||||
$internal_phone = new Phone($this->bdd);
|
$internal_phone = new Phone($this->bdd);
|
||||||
|
@ -51,12 +59,28 @@ namespace controllers\internals;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Use transaction to garanty atomicity
|
||||||
|
$this->bdd->beginTransaction();
|
||||||
|
|
||||||
$id_scheduled = $this->get_model()->insert($scheduled);
|
$id_scheduled = $this->get_model()->insert($scheduled);
|
||||||
if (!$id_scheduled)
|
if (!$id_scheduled)
|
||||||
{
|
{
|
||||||
|
$this->bdd->rollBack();
|
||||||
return false;
|
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)
|
foreach ($numbers as $number)
|
||||||
{
|
{
|
||||||
$this->get_model()->insert_scheduled_number($id_scheduled, $number);
|
$this->get_model()->insert_scheduled_number($id_scheduled, $number);
|
||||||
|
@ -98,6 +122,12 @@ namespace controllers\internals;
|
||||||
$this->get_model()->insert_scheduled_conditional_group_relation($id_scheduled, $conditional_group_id);
|
$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');
|
$date = date('Y-m-d H:i:s');
|
||||||
$internal_event = new Event($this->bdd);
|
$internal_event = new Event($this->bdd);
|
||||||
$internal_event->create($id_user, 'SCHEDULED_ADD', 'Ajout d\'un Sms pour le ' . $date . '.');
|
$internal_event->create($id_user, 'SCHEDULED_ADD', 'Ajout d\'un Sms pour le ' . $date . '.');
|
||||||
|
@ -114,20 +144,23 @@ namespace controllers\internals;
|
||||||
* @param string $text : Text of the message
|
* @param string $text : Text of the message
|
||||||
* @param ?int $id_phone : Id of the phone to send message with, null by default
|
* @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 $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 $numbers : Numbers to send message to
|
||||||
* @param array $contacts_ids : Contact ids 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 $groups_ids : Group ids to send message to
|
||||||
* @param array $conditional_group_ids : Conditional Groups 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
|
* @return bool : false on error, true on success
|
||||||
*/
|
*/
|
||||||
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 = [])
|
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 = [])
|
||||||
{
|
{
|
||||||
$scheduled = [
|
$scheduled = [
|
||||||
'id_user' => $id_user,
|
'id_user' => $id_user,
|
||||||
'at' => $at,
|
'at' => $at,
|
||||||
'text' => $text,
|
'text' => $text,
|
||||||
'id_phone' => $id_phone,
|
'id_phone' => $id_phone,
|
||||||
|
'mms' => $mms,
|
||||||
'flash' => $flash,
|
'flash' => $flash,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -142,12 +175,27 @@ namespace controllers\internals;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Ensure atomicity
|
||||||
|
$this->bdd->beginTransaction();
|
||||||
|
|
||||||
$success = (bool) $this->get_model()->update_for_user($id_user, $id_scheduled, $scheduled);
|
$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_numbers($id_scheduled);
|
||||||
$this->get_model()->delete_scheduled_contact_relations($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_group_relations($id_scheduled);
|
||||||
$this->get_model()->delete_scheduled_conditional_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)
|
foreach ($numbers as $number)
|
||||||
{
|
{
|
||||||
|
@ -190,7 +238,7 @@ namespace controllers\internals;
|
||||||
$this->get_model()->insert_scheduled_conditional_group_relation($id_scheduled, $conditional_group_id);
|
$this->get_model()->insert_scheduled_conditional_group_relation($id_scheduled, $conditional_group_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return $this->bdd->commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -207,10 +255,24 @@ namespace controllers\internals;
|
||||||
return $this->get_model()->gets_before_date_for_number_and_user($id_user, $date, $number);
|
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.
|
* Get all messages to send and the number to use to send theme.
|
||||||
*
|
*
|
||||||
* @return array : [['id_scheduled', 'text', 'id_phone', 'destination', 'flash'], ...]
|
* @return array : [['id_scheduled', 'text', 'id_phone', 'destination', 'flash', 'mms', 'medias'], ...]
|
||||||
*/
|
*/
|
||||||
public function get_smss_to_send()
|
public function get_smss_to_send()
|
||||||
{
|
{
|
||||||
|
@ -224,6 +286,7 @@ namespace controllers\internals;
|
||||||
|
|
||||||
$users_settings = [];
|
$users_settings = [];
|
||||||
$users_phones = [];
|
$users_phones = [];
|
||||||
|
$users_mms_phones = [];
|
||||||
|
|
||||||
$now = new \DateTime();
|
$now = new \DateTime();
|
||||||
$now = $now->format('Y-m-d H:i:s');
|
$now = $now->format('Y-m-d H:i:s');
|
||||||
|
@ -244,7 +307,16 @@ namespace controllers\internals;
|
||||||
if (!isset($users_phones[$scheduled['id_user']]))
|
if (!isset($users_phones[$scheduled['id_user']]))
|
||||||
{
|
{
|
||||||
$phones = $internal_phone->gets_for_user($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_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;
|
$phone_to_use = null;
|
||||||
|
@ -265,10 +337,18 @@ namespace controllers\internals;
|
||||||
foreach ($numbers as $number)
|
foreach ($numbers as $number)
|
||||||
{
|
{
|
||||||
if (null === $phone_to_use)
|
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']]);
|
$rnd_key = array_rand($users_phones[$scheduled['id_user']]);
|
||||||
$random_phone = $users_phones[$scheduled['id_user']][$rnd_key];
|
$random_phone = $users_phones[$scheduled['id_user']][$rnd_key];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$message = [
|
$message = [
|
||||||
'id_user' => $scheduled['id_user'],
|
'id_user' => $scheduled['id_user'],
|
||||||
|
@ -276,6 +356,8 @@ namespace controllers\internals;
|
||||||
'id_phone' => $phone_to_use['id'] ?? $random_phone['id'],
|
'id_phone' => $phone_to_use['id'] ?? $random_phone['id'],
|
||||||
'destination' => $number['number'],
|
'destination' => $number['number'],
|
||||||
'flash' => $scheduled['flash'],
|
'flash' => $scheduled['flash'],
|
||||||
|
'mms' => $scheduled['mms'],
|
||||||
|
'medias' => $scheduled['medias'],
|
||||||
];
|
];
|
||||||
|
|
||||||
if ((int) ($users_settings[$scheduled['id_user']]['templating'] ?? false))
|
if ((int) ($users_settings[$scheduled['id_user']]['templating'] ?? false))
|
||||||
|
@ -325,10 +407,18 @@ namespace controllers\internals;
|
||||||
$added_contacts[$contact['id']] = true;
|
$added_contacts[$contact['id']] = true;
|
||||||
|
|
||||||
if (null === $phone_to_use)
|
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']]);
|
$rnd_key = array_rand($users_phones[$scheduled['id_user']]);
|
||||||
$random_phone = $users_phones[$scheduled['id_user']][$rnd_key];
|
$random_phone = $users_phones[$scheduled['id_user']][$rnd_key];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$message = [
|
$message = [
|
||||||
'id_user' => $scheduled['id_user'],
|
'id_user' => $scheduled['id_user'],
|
||||||
|
@ -336,6 +426,8 @@ namespace controllers\internals;
|
||||||
'id_phone' => $phone_to_use['id'] ?? $random_phone['id'],
|
'id_phone' => $phone_to_use['id'] ?? $random_phone['id'],
|
||||||
'destination' => $contact['number'],
|
'destination' => $contact['number'],
|
||||||
'flash' => $scheduled['flash'],
|
'flash' => $scheduled['flash'],
|
||||||
|
'mms' => $scheduled['mms'],
|
||||||
|
'medias' => $scheduled['medias'],
|
||||||
];
|
];
|
||||||
|
|
||||||
if ((int) ($users_settings[$scheduled['id_user']]['templating'] ?? false))
|
if ((int) ($users_settings[$scheduled['id_user']]['templating'] ?? false))
|
||||||
|
@ -368,7 +460,7 @@ namespace controllers\internals;
|
||||||
foreach ($messages as $message)
|
foreach ($messages as $message)
|
||||||
{
|
{
|
||||||
//Remove empty messages
|
//Remove empty messages
|
||||||
if ('' === trim($message['text']))
|
if ('' === trim($message['text']) && !$message['medias'])
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,13 @@ namespace controllers\internals;
|
||||||
* @param string $uid : Uid of the sms on the adapter service used
|
* @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 string $adapter : Name of the adapter service used to send the message
|
||||||
* @param bool $flash : Is the sms a flash
|
* @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
|
* @param string $status : Status of a the sms. By default \models\Sended::STATUS_UNKNOWN
|
||||||
*
|
*
|
||||||
* @return mixed : false on error, new sended id else
|
* @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, ?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, bool $mms = false, array $medias = [], ?string $status = \models\Sended::STATUS_UNKNOWN)
|
||||||
{
|
{
|
||||||
$sended = [
|
$sended = [
|
||||||
'id_user' => $id_user,
|
'id_user' => $id_user,
|
||||||
|
@ -41,10 +43,33 @@ namespace controllers\internals;
|
||||||
'uid' => $uid,
|
'uid' => $uid,
|
||||||
'adapter' => $adapter,
|
'adapter' => $adapter,
|
||||||
'flash' => $flash,
|
'flash' => $flash,
|
||||||
|
'mms' => $mms,
|
||||||
'status' => $status,
|
'status' => $status,
|
||||||
];
|
];
|
||||||
|
|
||||||
return $this->get_model()->insert($sended);
|
//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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,6 +133,19 @@ namespace controllers\internals;
|
||||||
return $this->get_model()->gets_by_destination_and_user($id_user, $origin);
|
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.
|
* Return sended for an uid and an adapter.
|
||||||
*
|
*
|
||||||
|
@ -165,6 +203,8 @@ namespace controllers\internals;
|
||||||
* @param $text : Text of the message
|
* @param $text : Text of the message
|
||||||
* @param string $destination : Number of the receiver
|
* @param string $destination : Number of the receiver
|
||||||
* @param bool $flash : Is the sms a flash. By default false.
|
* @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
|
* @param string $status : Status of a the sms. By default \models\Sended::STATUS_UNKNOWN
|
||||||
*
|
*
|
||||||
* @return array : [
|
* @return array : [
|
||||||
|
@ -172,7 +212,7 @@ namespace controllers\internals;
|
||||||
* ?string 'error_message' => null if success, error message else
|
* ?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, 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, bool $mms = false, array $medias = [], string $status = \models\Sended::STATUS_UNKNOWN): array
|
||||||
{
|
{
|
||||||
$return = [
|
$return = [
|
||||||
'error' => false,
|
'error' => false,
|
||||||
|
@ -180,19 +220,40 @@ namespace controllers\internals;
|
||||||
];
|
];
|
||||||
|
|
||||||
$at = (new \DateTime())->format('Y-m-d H:i:s');
|
$at = (new \DateTime())->format('Y-m-d H:i:s');
|
||||||
$response = $adapter->send($destination, $text, $flash);
|
$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);
|
||||||
|
|
||||||
if ($response['error'])
|
if ($response['error'])
|
||||||
{
|
{
|
||||||
$return['error'] = true;
|
$return['error'] = true;
|
||||||
$return['error_message'] = $response['error_message'];
|
$return['error_message'] = $response['error_message'];
|
||||||
$status = \models\Sended::STATUS_FAILED;
|
$status = \models\Sended::STATUS_FAILED;
|
||||||
$this->create($id_user, $id_phone, $at, $text, $destination, $response['uid'] ?? uniqid(), $adapter->meta_classname(), $flash, $status);
|
$this->create($id_user, $id_phone, $at, $text, $destination, $response['uid'] ?? uniqid(), $adapter->meta_classname(), $flash, $mms, $medias, $status);
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sended_id = $this->create($id_user, $id_phone, $at, $text, $destination, $response['uid'] ?? uniqid(), $adapter->meta_classname(), $flash, $status);
|
$sended_id = $this->create($id_user, $id_phone, $at, $text, $destination, $response['uid'] ?? uniqid(), $adapter->meta_classname(), $flash, $mms, $medias, $status);
|
||||||
|
|
||||||
$sended = [
|
$sended = [
|
||||||
'id' => $sended_id,
|
'id' => $sended_id,
|
||||||
|
@ -200,10 +261,12 @@ namespace controllers\internals;
|
||||||
'text' => $text,
|
'text' => $text,
|
||||||
'destination' => $destination,
|
'destination' => $destination,
|
||||||
'origin' => $id_phone,
|
'origin' => $id_phone,
|
||||||
|
'mms' => $mms,
|
||||||
|
'medias' => $medias,
|
||||||
];
|
];
|
||||||
|
|
||||||
$internal_webhook = new Webhook($this->bdd);
|
$internal_webhook = new Webhook($this->bdd);
|
||||||
$internal_webhook->trigger($id_user, \models\Webhook::TYPE_SEND, $sended);
|
$internal_webhook->trigger($id_user, \models\Webhook::TYPE_SEND_SMS, $sended);
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,7 +205,7 @@ namespace controllers\internals;
|
||||||
*
|
*
|
||||||
* @param array $file : The array extracted from $_FILES['file']
|
* @param array $file : The array extracted from $_FILES['file']
|
||||||
*
|
*
|
||||||
* @return array : ['success' => bool, 'content' => file handler | error message, 'error_code' => $file['error']]
|
* @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]
|
||||||
*/
|
*/
|
||||||
public static function read_uploaded_file(array $file)
|
public static function read_uploaded_file(array $file)
|
||||||
{
|
{
|
||||||
|
@ -213,8 +213,9 @@ namespace controllers\internals;
|
||||||
'success' => false,
|
'success' => false,
|
||||||
'content' => 'Une erreur inconnue est survenue.',
|
'content' => 'Une erreur inconnue est survenue.',
|
||||||
'error_code' => $file['error'] ?? 99,
|
'error_code' => $file['error'] ?? 99,
|
||||||
'mime_type' => false,
|
'mime_type' => null,
|
||||||
'extension' => false,
|
'extension' => null,
|
||||||
|
'tmp_name' => null,
|
||||||
];
|
];
|
||||||
|
|
||||||
if (UPLOAD_ERR_OK !== $file['error'])
|
if (UPLOAD_ERR_OK !== $file['error'])
|
||||||
|
@ -266,7 +267,8 @@ namespace controllers\internals;
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result['extension'] = pathinfo($file['name'])['extension'];
|
$result['tmp_name'] = $tmp_filename;
|
||||||
|
$result['extension'] = pathinfo($file['name'], PATHINFO_EXTENSION);
|
||||||
$result['mime_type'] = mime_content_type($tmp_filename);
|
$result['mime_type'] = mime_content_type($tmp_filename);
|
||||||
|
|
||||||
$file_handler = fopen($tmp_filename, 'r');
|
$file_handler = fopen($tmp_filename, 'r');
|
||||||
|
@ -277,96 +279,55 @@ namespace controllers\internals;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow to upload file.
|
* Generate a highly random uuid based on timestamp and strong cryptographic random
|
||||||
*
|
*
|
||||||
* @param array $file : The array extracted from $_FILES['file']
|
* @return string
|
||||||
*
|
|
||||||
* @return array : ['success' => bool, 'content' => file path | error message, 'error_code' => $file['error']]
|
|
||||||
*/
|
*/
|
||||||
public static function upload_file(array $file)
|
public static function random_uuid()
|
||||||
{
|
{
|
||||||
$result = [
|
$bytes = random_bytes(16);
|
||||||
'success' => false,
|
return time() . '-' . bin2hex($bytes);
|
||||||
'content' => 'Une erreur inconnue est survenue.',
|
}
|
||||||
'error_code' => $file['error'] ?? 99,
|
|
||||||
];
|
|
||||||
|
|
||||||
if (UPLOAD_ERR_OK !== $file['error'])
|
|
||||||
|
/**
|
||||||
|
* Create a user data public path
|
||||||
|
* @param int $id_user : The user id
|
||||||
|
*
|
||||||
|
* @return string : The created path
|
||||||
|
|
||||||
|
* @exception Raise exception on error
|
||||||
|
*/
|
||||||
|
public static function create_user_public_path (int $id_user)
|
||||||
{
|
{
|
||||||
switch ($file['error'])
|
$new_dir = PWD_DATA_PUBLIC . '/' . $id_user;
|
||||||
|
if (file_exists($new_dir))
|
||||||
{
|
{
|
||||||
case UPLOAD_ERR_INI_SIZE:
|
return $new_dir;
|
||||||
$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))
|
|
||||||
{
|
{
|
||||||
return $result;
|
throw new \Exception('Cannot create dir ' . $new_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
$md5_filename = md5_file($tmp_filename);
|
//We do chmod in two times because else umask fuck mkdir permissions
|
||||||
if (!$md5_filename)
|
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
|
||||||
{
|
{
|
||||||
return $result;
|
throw new \Exception('Cannot give dir ' . $new_dir . ' rights : ' . decoct(fileperms(PWD_DATA_PUBLIC) & 0777)); //Show error in dec
|
||||||
}
|
}
|
||||||
|
|
||||||
$new_file_path = PWD_DATA . '/' . $md5_filename;
|
if (posix_getuid() === 0 && !chown($new_dir, fileowner(PWD_DATA_PUBLIC))) //If we are root, try to give the file to a proper user
|
||||||
|
|
||||||
if (file_exists($new_file_path))
|
|
||||||
{
|
{
|
||||||
$result['success'] = true;
|
throw new \Exception('Cannot give dir ' . $new_dir . ' to user : ' . fileowner(PWD_DATA_PUBLIC));
|
||||||
$result['content'] = $new_file_path;
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$success = move_uploaded_file($tmp_filename, $new_file_path);
|
if (posix_getuid() === 0 && !chgrp($new_dir, filegroup(PWD_DATA_PUBLIC))) //If we are root, try to give the file to a proper group
|
||||||
if (!$success)
|
|
||||||
{
|
{
|
||||||
$result['content'] = 'Impossible d\'écrire le fichier sur le serveur.';
|
throw new \Exception('Cannot give dir ' . $new_dir . ' to group : ' . filegroup(PWD_DATA_PUBLIC));
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$result['success'] = true;
|
return $new_dir;
|
||||||
$result['content'] = $new_file_path;
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,6 +264,7 @@ namespace controllers\internals;
|
||||||
* string 'text' => sms content,
|
* string 'text' => sms content,
|
||||||
* string 'destination' => id of phone the sms was sent to
|
* string 'destination' => id of phone the sms was sent to
|
||||||
* string 'origin' => phone number that sent the sms
|
* string 'origin' => phone number that sent the sms
|
||||||
|
* bool 'mms' => is the sms a mms
|
||||||
* ]
|
* ]
|
||||||
*
|
*
|
||||||
* @return bool : False if no transfer, true else
|
* @return bool : False if no transfer, true else
|
||||||
|
@ -291,11 +292,19 @@ namespace controllers\internals;
|
||||||
|
|
||||||
$mailer = new Mailer();
|
$mailer = new Mailer();
|
||||||
|
|
||||||
|
$attachments = [];
|
||||||
|
|
||||||
|
foreach ($received['medias'] ?? [] as $media)
|
||||||
|
{
|
||||||
|
$attachments[] = PWD_DATA_PUBLIC . '/' . $media['path'];
|
||||||
|
}
|
||||||
|
|
||||||
return $mailer->enqueue($user['email'], EMAIL_TRANSFER_SMS, [
|
return $mailer->enqueue($user['email'], EMAIL_TRANSFER_SMS, [
|
||||||
'at' => $received['at'],
|
'at' => $received['at'],
|
||||||
'origin' => $received['origin'],
|
'origin' => $received['origin'],
|
||||||
'destination' => $phone['name'],
|
'destination' => $phone['name'],
|
||||||
'text' => $received['text'],
|
'text' => $received['text'],
|
||||||
]);
|
'mms' => $received['mms'] ?? false,
|
||||||
|
], $attachments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,17 +94,11 @@ class Webhook extends StandardController
|
||||||
*
|
*
|
||||||
* @param int $id_user : User to trigger the webhook for
|
* @param int $id_user : User to trigger the webhook for
|
||||||
* @param string $type : Type of webhook to trigger
|
* @param string $type : Type of webhook to trigger
|
||||||
* @param array $sms : The sms [
|
* @param array $body : The body, an array depending on webhook type
|
||||||
* 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
|
* @return bool : False if no trigger, true else
|
||||||
*/
|
*/
|
||||||
public function trigger(int $id_user, string $type, array $sms)
|
public function trigger(int $id_user, string $type, array $body)
|
||||||
{
|
{
|
||||||
$internal_setting = new Setting($this->bdd);
|
$internal_setting = new Setting($this->bdd);
|
||||||
$internal_user = new User($this->bdd);
|
$internal_user = new User($this->bdd);
|
||||||
|
@ -137,11 +131,7 @@ class Webhook extends StandardController
|
||||||
'webhook_type' => $webhook['type'],
|
'webhook_type' => $webhook['type'],
|
||||||
'webhook_random_id' => $webhook_random_id,
|
'webhook_random_id' => $webhook_random_id,
|
||||||
'webhook_signature' => $webhook_signature,
|
'webhook_signature' => $webhook_signature,
|
||||||
'id' => $sms['id'],
|
'body' => json_encode($body),
|
||||||
'at' => $sms['at'],
|
|
||||||
'text' => $sms['text'],
|
|
||||||
'origin' => $sms['origin'],
|
|
||||||
'destination' => $sms['destination'],
|
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace controllers\publics;
|
||||||
'CANNOT_CREATE' => 8,
|
'CANNOT_CREATE' => 8,
|
||||||
'SUSPENDED_USER' => 16,
|
'SUSPENDED_USER' => 16,
|
||||||
'CANNOT_DELETE' => 32,
|
'CANNOT_DELETE' => 32,
|
||||||
|
'CANNOT_UPLOAD_FILE' => 64,
|
||||||
];
|
];
|
||||||
|
|
||||||
const ERROR_MESSAGES = [
|
const ERROR_MESSAGES = [
|
||||||
|
@ -41,6 +42,7 @@ namespace controllers\publics;
|
||||||
'CANNOT_CREATE' => 'Cannot create a new entry.',
|
'CANNOT_CREATE' => 'Cannot create a new entry.',
|
||||||
'SUSPENDED_USER' => 'This user account is currently suspended.',
|
'SUSPENDED_USER' => 'This user account is currently suspended.',
|
||||||
'CANNOT_DELETE' => 'Cannot delete this entry.',
|
'CANNOT_DELETE' => 'Cannot delete this entry.',
|
||||||
|
'CANNOT_UPLOAD_FILE' => 'Failed to upload or save an uploaded file : ',
|
||||||
];
|
];
|
||||||
|
|
||||||
private $internal_user;
|
private $internal_user;
|
||||||
|
@ -52,6 +54,8 @@ namespace controllers\publics;
|
||||||
private $internal_group;
|
private $internal_group;
|
||||||
private $internal_conditional_group;
|
private $internal_conditional_group;
|
||||||
private $internal_adapter;
|
private $internal_adapter;
|
||||||
|
private $internal_media;
|
||||||
|
private $internal_setting;
|
||||||
private $user;
|
private $user;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,6 +77,8 @@ namespace controllers\publics;
|
||||||
$this->internal_group = new \controllers\internals\Group($bdd);
|
$this->internal_group = new \controllers\internals\Group($bdd);
|
||||||
$this->internal_conditional_group = new \controllers\internals\ConditionalGroup($bdd);
|
$this->internal_conditional_group = new \controllers\internals\ConditionalGroup($bdd);
|
||||||
$this->internal_adapter = new \controllers\internals\Adapter();
|
$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
|
//If no user, quit with error
|
||||||
$this->user = false;
|
$this->user = false;
|
||||||
|
@ -93,6 +99,8 @@ namespace controllers\publics;
|
||||||
exit(self::ERROR_CODES['INVALID_CREDENTIALS']);
|
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'])
|
if (\models\User::STATUS_ACTIVE !== $this->user['status'])
|
||||||
{
|
{
|
||||||
$return = self::DEFAULT_RETURN;
|
$return = self::DEFAULT_RETURN;
|
||||||
|
@ -108,14 +116,14 @@ namespace controllers\publics;
|
||||||
/**
|
/**
|
||||||
* List all entries of a certain type for the current user, sorted by id.
|
* 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']
|
* @param string $entry_type : Type of entries we want to list ['sended', 'received', 'scheduled', 'contact', 'group', 'conditional_group', 'phone', 'media']
|
||||||
* @param int $page : Pagination number, Default = 0. Group of 25 results.
|
* @param int $page : Pagination number, Default = 0. Group of 25 results.
|
||||||
*
|
*
|
||||||
* @return : List of entries
|
* @return : List of entries
|
||||||
*/
|
*/
|
||||||
public function get_entries(string $entry_type, int $page = 0)
|
public function get_entries(string $entry_type, int $page = 0)
|
||||||
{
|
{
|
||||||
$entry_types = ['sended', 'received', 'scheduled', 'contact', 'group', 'conditional_group', 'phone'];
|
$entry_types = ['sended', 'received', 'scheduled', 'contact', 'group', 'conditional_group', 'phone', 'media'];
|
||||||
|
|
||||||
if (!\in_array($entry_type, $entry_types, true))
|
if (!\in_array($entry_type, $entry_types, true))
|
||||||
{
|
{
|
||||||
|
@ -143,6 +151,21 @@ namespace controllers\publics;
|
||||||
$entries[$key]['contacts'] = $this->internal_scheduled->get_contacts($entry['id']);
|
$entries[$key]['contacts'] = $this->internal_scheduled->get_contacts($entry['id']);
|
||||||
$entries[$key]['groups'] = $this->internal_scheduled->get_groups($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]['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
|
//Special case for group we must add contact because its a join
|
||||||
|
@ -179,6 +202,7 @@ namespace controllers\publics;
|
||||||
* @param string $_POST['text'] : Text of the message to send
|
* @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['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['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['numbers'] : Array of numbers to send message to
|
||||||
* @param string $_POST['contacts'] : Array of ids of contacts 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
|
* @param string $_POST['groups'] : Array of ids of groups to send message to
|
||||||
|
@ -192,16 +216,47 @@ namespace controllers\publics;
|
||||||
$text = $_POST['text'] ?? false;
|
$text = $_POST['text'] ?? false;
|
||||||
$id_phone = empty($_POST['id_phone']) ? null : $_POST['id_phone'];
|
$id_phone = empty($_POST['id_phone']) ? null : $_POST['id_phone'];
|
||||||
$flash = (bool) ($_POST['flash'] ?? false);
|
$flash = (bool) ($_POST['flash'] ?? false);
|
||||||
|
$mms = (bool) ($_POST['mms'] ?? false);
|
||||||
$numbers = $_POST['numbers'] ?? [];
|
$numbers = $_POST['numbers'] ?? [];
|
||||||
$contacts = $_POST['contacts'] ?? [];
|
$contacts = $_POST['contacts'] ?? [];
|
||||||
$groups = $_POST['groups'] ?? [];
|
$groups = $_POST['groups'] ?? [];
|
||||||
$conditional_groups = $_POST['conditional_groups'] ?? [];
|
$conditional_groups = $_POST['conditional_groups'] ?? [];
|
||||||
|
$files = $_FILES['medias'] ?? false;
|
||||||
|
|
||||||
$numbers = \is_array($numbers) ? $numbers : [$numbers];
|
$numbers = \is_array($numbers) ? $numbers : [$numbers];
|
||||||
$contacts = \is_array($contacts) ? $contacts : [$contacts];
|
$contacts = \is_array($contacts) ? $contacts : [$contacts];
|
||||||
$groups = \is_array($groups) ? $groups : [$groups];
|
$groups = \is_array($groups) ? $groups : [$groups];
|
||||||
$conditional_groups = \is_array($conditional_groups) ? $conditional_groups : [$conditional_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)
|
if (!$at)
|
||||||
{
|
{
|
||||||
$at = (new \DateTime())->format('Y-m-d H:i:s');
|
$at = (new \DateTime())->format('Y-m-d H:i:s');
|
||||||
|
@ -227,6 +282,16 @@ namespace controllers\publics;
|
||||||
return $this->json($return);
|
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)
|
foreach ($numbers as $key => $number)
|
||||||
{
|
{
|
||||||
$number = \controllers\internals\Tool::parse_phone($number);
|
$number = \controllers\internals\Tool::parse_phone($number);
|
||||||
|
@ -251,7 +316,13 @@ namespace controllers\publics;
|
||||||
return $this->json($return);
|
return $this->json($return);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($id_phone && !$this->internal_phone->get_for_user($this->user['id'], $id_phone))
|
$phone = null;
|
||||||
|
if ($id_phone)
|
||||||
|
{
|
||||||
|
$phone = $this->internal_phone->get_for_user($this->user['id'], $id_phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($id_phone && !$phone)
|
||||||
{
|
{
|
||||||
$return = self::DEFAULT_RETURN;
|
$return = self::DEFAULT_RETURN;
|
||||||
$return['error'] = self::ERROR_CODES['INVALID_PARAMETER'];
|
$return['error'] = self::ERROR_CODES['INVALID_PARAMETER'];
|
||||||
|
@ -261,7 +332,29 @@ namespace controllers\publics;
|
||||||
return $this->json($return);
|
return $this->json($return);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scheduled_id = $this->internal_scheduled->create($this->user['id'], $at, $text, $id_phone, $flash, $numbers, $contacts, $groups, $conditional_groups);
|
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);
|
||||||
if (!$scheduled_id)
|
if (!$scheduled_id)
|
||||||
{
|
{
|
||||||
$return = self::DEFAULT_RETURN;
|
$return = self::DEFAULT_RETURN;
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of RaspiSMS.
|
||||||
|
*
|
||||||
|
* (c) Pierre-Lin Bonnemaison <plebwebsas@gmail.com>
|
||||||
|
*
|
||||||
|
* This source file is subject to the GPL-3.0 license that is bundled
|
||||||
|
* with this source code in the file LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace controllers\publics;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page des 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'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,9 @@ use Monolog\Logger;
|
||||||
private $internal_sended;
|
private $internal_sended;
|
||||||
private $internal_received;
|
private $internal_received;
|
||||||
private $internal_adapter;
|
private $internal_adapter;
|
||||||
|
private $internal_media;
|
||||||
|
private $internal_phone;
|
||||||
|
private $internal_call;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
@ -33,7 +36,10 @@ use Monolog\Logger;
|
||||||
$this->internal_user = new \controllers\internals\User($bdd);
|
$this->internal_user = new \controllers\internals\User($bdd);
|
||||||
$this->internal_sended = new \controllers\internals\Sended($bdd);
|
$this->internal_sended = new \controllers\internals\Sended($bdd);
|
||||||
$this->internal_received = new \controllers\internals\Received($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_adapter = new \controllers\internals\Adapter();
|
||||||
|
$this->internal_phone = new \controllers\internals\Phone($bdd);
|
||||||
|
$this->internal_call = new \controllers\internals\Call($bdd);
|
||||||
|
|
||||||
//Logger
|
//Logger
|
||||||
$this->logger = new Logger('Callback ' . uniqid());
|
$this->logger = new Logger('Callback ' . uniqid());
|
||||||
|
@ -177,8 +183,10 @@ use Monolog\Logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sms = $response['sms'];
|
$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']);
|
$response = $this->internal_received->receive($this->user['id'], $id_phone, $sms['text'], $sms['origin'], $sms['at'], \models\Received::STATUS_UNREAD, $mms, $medias);
|
||||||
if ($response['error'])
|
if ($response['error'])
|
||||||
{
|
{
|
||||||
$this->logger->error('Failed receive message : ' . json_encode($sms) . ' with error : ' . $response['error_message']);
|
$this->logger->error('Failed receive message : ' . json_encode($sms) . ' with error : ' . $response['error_message']);
|
||||||
|
@ -190,4 +198,135 @@ use Monolog\Logger;
|
||||||
|
|
||||||
return true;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,7 +234,17 @@ namespace controllers\publics;
|
||||||
$contacts_name[] = $contact['name'];
|
$contacts_name[] = $contact['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$return['result'] = 'Contacts du groupe : ' . implode(', ', $contacts_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['success'] = true;
|
$return['success'] = true;
|
||||||
echo json_encode($return);
|
echo json_encode($return);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace controllers\publics;
|
||||||
{
|
{
|
||||||
private $internal_contact;
|
private $internal_contact;
|
||||||
private $internal_event;
|
private $internal_event;
|
||||||
|
private $internal_conditional_group;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cette fonction est appelée avant toute les autres :
|
* Cette fonction est appelée avant toute les autres :
|
||||||
|
@ -31,6 +32,7 @@ namespace controllers\publics;
|
||||||
|
|
||||||
$this->internal_contact = new \controllers\internals\Contact($bdd);
|
$this->internal_contact = new \controllers\internals\Contact($bdd);
|
||||||
$this->internal_event = new \controllers\internals\Event($bdd);
|
$this->internal_event = new \controllers\internals\Event($bdd);
|
||||||
|
$this->internal_conditional_group = new \controllers\internals\ConditionalGroup($bdd);
|
||||||
|
|
||||||
\controllers\internals\Tool::verifyconnect();
|
\controllers\internals\Tool::verifyconnect();
|
||||||
}
|
}
|
||||||
|
@ -84,6 +86,40 @@ namespace controllers\publics;
|
||||||
return $this->redirect(\descartes\Router::url('Contact', 'list'));
|
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.
|
* Cette fonction retourne la page d'ajout d'un contact.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace controllers\publics;
|
||||||
private $internal_received;
|
private $internal_received;
|
||||||
private $internal_contact;
|
private $internal_contact;
|
||||||
private $internal_phone;
|
private $internal_phone;
|
||||||
|
private $internal_media;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cette fonction est appelée avant toute les autres :
|
* Cette fonction est appelée avant toute les autres :
|
||||||
|
@ -37,6 +38,7 @@ namespace controllers\publics;
|
||||||
$this->internal_received = new \controllers\internals\Received($bdd);
|
$this->internal_received = new \controllers\internals\Received($bdd);
|
||||||
$this->internal_contact = new \controllers\internals\Contact($bdd);
|
$this->internal_contact = new \controllers\internals\Contact($bdd);
|
||||||
$this->internal_phone = new \controllers\internals\Phone($bdd);
|
$this->internal_phone = new \controllers\internals\Phone($bdd);
|
||||||
|
$this->internal_media = new \controllers\internals\Media($bdd);
|
||||||
|
|
||||||
\controllers\internals\Tool::verifyconnect();
|
\controllers\internals\Tool::verifyconnect();
|
||||||
}
|
}
|
||||||
|
@ -112,12 +114,27 @@ namespace controllers\publics;
|
||||||
|
|
||||||
foreach ($sendeds as $sended)
|
foreach ($sendeds as $sended)
|
||||||
{
|
{
|
||||||
$messages[] = [
|
$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'],
|
||||||
'date' => htmlspecialchars($sended['at']),
|
'date' => htmlspecialchars($sended['at']),
|
||||||
'text' => htmlspecialchars($sended['text']),
|
'text' => htmlspecialchars($sended['text']),
|
||||||
'type' => 'sended',
|
'type' => 'sended',
|
||||||
|
'medias' => $medias,
|
||||||
'status' => $sended['status'],
|
'status' => $sended['status'],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
$messages[] = $message;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($receiveds as $received)
|
foreach ($receiveds as $received)
|
||||||
|
@ -127,20 +144,43 @@ namespace controllers\publics;
|
||||||
$this->internal_received->mark_as_read_for_user($id_user, $received['id']);
|
$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[] = [
|
$messages[] = [
|
||||||
|
'uid' => 'received-' . $received['id'],
|
||||||
'date' => htmlspecialchars($received['at']),
|
'date' => htmlspecialchars($received['at']),
|
||||||
'text' => htmlspecialchars($received['text']),
|
'text' => htmlspecialchars($received['text']),
|
||||||
'type' => 'received',
|
'type' => 'received',
|
||||||
'md5' => md5($received['at'] . $received['text']),
|
'medias' => $medias,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($scheduleds as $scheduled)
|
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[] = [
|
$messages[] = [
|
||||||
|
'uid' => 'scheduled-' . $scheduled['id'],
|
||||||
'date' => htmlspecialchars($scheduled['at']),
|
'date' => htmlspecialchars($scheduled['at']),
|
||||||
'text' => htmlspecialchars($scheduled['text']),
|
'text' => htmlspecialchars($scheduled['text']),
|
||||||
'type' => 'inprogress',
|
'type' => 'inprogress',
|
||||||
|
'medias' => $medias,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,10 +190,15 @@ namespace controllers\publics;
|
||||||
return strtotime($a['date']) - strtotime($b['date']);
|
return strtotime($a['date']) - strtotime($b['date']);
|
||||||
});
|
});
|
||||||
|
|
||||||
//On récupère uniquement les 25 derniers messages sur l'ensemble
|
//Récupère uniquement les 25 derniers messages sur l'ensemble pour limiter la charge
|
||||||
$messages = \array_slice($messages, -25);
|
$messages = \array_slice($messages, -25);
|
||||||
|
|
||||||
echo json_encode(['transaction_id' => $transaction_id, 'messages' => $messages]);
|
$response = [
|
||||||
|
'transaction_id' => $transaction_id,
|
||||||
|
'messages' => $messages,
|
||||||
|
];
|
||||||
|
|
||||||
|
echo json_encode($response);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -165,6 +210,7 @@ namespace controllers\publics;
|
||||||
* @param string $_POST['text'] : Le contenu du Sms
|
* @param string $_POST['text'] : Le contenu du Sms
|
||||||
* @param string $_POST['destination'] : Number to send sms to
|
* @param string $_POST['destination'] : Number to send sms to
|
||||||
* @param string $_POST['id_phone'] : If of phone to send sms with
|
* @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
|
* @return string : json string Le statut de l'envoi
|
||||||
*/
|
*/
|
||||||
|
@ -190,6 +236,43 @@ namespace controllers\publics;
|
||||||
$text = $_POST['text'] ?? '';
|
$text = $_POST['text'] ?? '';
|
||||||
$destination = $_POST['destination'] ?? false;
|
$destination = $_POST['destination'] ?? false;
|
||||||
$id_phone = $_POST['id_phone'] ?? 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)
|
if (!$destination)
|
||||||
{
|
{
|
||||||
|
@ -205,10 +288,36 @@ namespace controllers\publics;
|
||||||
$id_phone = null;
|
$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 must be an array of number
|
||||||
$destinations = [$destination];
|
$destinations = [$destination];
|
||||||
|
|
||||||
if (!$this->internal_scheduled->create($id_user, $at, $text, $id_phone, false, $destinations))
|
if (!$this->internal_scheduled->create($id_user, $at, $text, $id_phone, false, $mms, $destinations, [], [], [], $media_ids))
|
||||||
{
|
{
|
||||||
$return['success'] = false;
|
$return['success'] = false;
|
||||||
$return['message'] = 'Impossible de créer le Sms';
|
$return['message'] = 'Impossible de créer le Sms';
|
||||||
|
|
|
@ -33,43 +33,7 @@ class Phone extends \descartes\Controller
|
||||||
*/
|
*/
|
||||||
public function list()
|
public function list()
|
||||||
{
|
{
|
||||||
$id_user = $_SESSION['user']['id'];
|
$this->render('phone/list');
|
||||||
$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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,6 +75,16 @@ class Phone extends \descartes\Controller
|
||||||
{
|
{
|
||||||
$phone['callback_status'] = \descartes\Router::url('Callback', 'update_sended_status', ['adapter_uid' => $adapter['meta_uid']], ['api_key' => $api_key]);
|
$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');
|
header('Content-Type: application/json');
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace controllers\publics;
|
||||||
private $internal_received;
|
private $internal_received;
|
||||||
private $internal_contact;
|
private $internal_contact;
|
||||||
private $internal_phone;
|
private $internal_phone;
|
||||||
|
private $internal_media;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cette fonction est appelée avant toute les autres :
|
* Cette fonction est appelée avant toute les autres :
|
||||||
|
@ -32,6 +33,7 @@ namespace controllers\publics;
|
||||||
$this->internal_received = new \controllers\internals\Received($bdd);
|
$this->internal_received = new \controllers\internals\Received($bdd);
|
||||||
$this->internal_contact = new \controllers\internals\Contact($bdd);
|
$this->internal_contact = new \controllers\internals\Contact($bdd);
|
||||||
$this->internal_phone = new \controllers\internals\Phone($bdd);
|
$this->internal_phone = new \controllers\internals\Phone($bdd);
|
||||||
|
$this->internal_media = new \controllers\internals\Media($bdd);
|
||||||
|
|
||||||
\controllers\internals\Tool::verifyconnect();
|
\controllers\internals\Tool::verifyconnect();
|
||||||
}
|
}
|
||||||
|
@ -53,6 +55,10 @@ namespace controllers\publics;
|
||||||
foreach ($entities as &$entity)
|
foreach ($entities as &$entity)
|
||||||
{
|
{
|
||||||
$entity['origin_formatted'] = \controllers\internals\Tool::phone_link($entity['origin']);
|
$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');
|
header('Content-Type: application/json');
|
||||||
|
@ -76,6 +82,10 @@ namespace controllers\publics;
|
||||||
foreach ($entities as &$entity)
|
foreach ($entities as &$entity)
|
||||||
{
|
{
|
||||||
$entity['origin_formatted'] = \controllers\internals\Tool::phone_link($entity['origin']);
|
$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');
|
header('Content-Type: application/json');
|
||||||
|
|
|
@ -56,6 +56,13 @@ namespace controllers\publics;
|
||||||
public function list_json()
|
public function list_json()
|
||||||
{
|
{
|
||||||
$entities = $this->internal_scheduled->list_for_user($_SESSION['user']['id']);
|
$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');
|
header('Content-Type: application/json');
|
||||||
echo json_encode(['data' => $entities]);
|
echo json_encode(['data' => $entities]);
|
||||||
|
@ -205,8 +212,8 @@ namespace controllers\publics;
|
||||||
$scheduleds[$key]['groups'][] = (int) $group['id'];
|
$scheduleds[$key]['groups'][] = (int) $group['id'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$media = $this->internal_media->get_for_scheduled_and_user($id_user, $scheduled['id']);
|
$medias = $this->internal_media->gets_for_scheduled($scheduled['id']);
|
||||||
$scheduleds[$key]['media'] = $media;
|
$scheduleds[$key]['medias'] = $medias;
|
||||||
|
|
||||||
$conditional_groups = $this->internal_scheduled->get_conditional_groups($scheduled['id']);
|
$conditional_groups = $this->internal_scheduled->get_conditional_groups($scheduled['id']);
|
||||||
foreach ($conditional_groups as $conditional_group)
|
foreach ($conditional_groups as $conditional_group)
|
||||||
|
@ -235,7 +242,7 @@ namespace controllers\publics;
|
||||||
* @param ?array $_POST['contacts'] : Numbers to send the message to
|
* @param ?array $_POST['contacts'] : Numbers to send the message to
|
||||||
* @param ?array $_POST['groups'] : 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 $_POST['conditional_groups'] : Numbers to send the message to
|
||||||
* @param ?array $_FILES['media'] : The media to link to a scheduled
|
* @param ?array $_FILES['medias'] : The media to link to a scheduled
|
||||||
*/
|
*/
|
||||||
public function create($csrf)
|
public function create($csrf)
|
||||||
{
|
{
|
||||||
|
@ -255,7 +262,34 @@ namespace controllers\publics;
|
||||||
$contacts = $_POST['contacts'] ?? [];
|
$contacts = $_POST['contacts'] ?? [];
|
||||||
$groups = $_POST['groups'] ?? [];
|
$groups = $_POST['groups'] ?? [];
|
||||||
$conditional_groups = $_POST['conditional_groups'] ?? [];
|
$conditional_groups = $_POST['conditional_groups'] ?? [];
|
||||||
$media = $_FILES['media'] ?? 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 (empty($text))
|
if (empty($text))
|
||||||
{
|
{
|
||||||
|
@ -292,7 +326,29 @@ namespace controllers\publics;
|
||||||
return $this->redirect(\descartes\Router::url('Scheduled', 'add'));
|
return $this->redirect(\descartes\Router::url('Scheduled', 'add'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$scheduled_id = $this->internal_scheduled->create($id_user, $at, $text, $id_phone, $flash, $numbers, $contacts, $groups, $conditional_groups);
|
//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);
|
||||||
if (!$scheduled_id)
|
if (!$scheduled_id)
|
||||||
{
|
{
|
||||||
\FlashMessage\FlashMessage::push('danger', 'Impossible de créer le Sms.');
|
\FlashMessage\FlashMessage::push('danger', 'Impossible de créer le Sms.');
|
||||||
|
@ -300,22 +356,6 @@ namespace controllers\publics;
|
||||||
return $this->redirect(\descartes\Router::url('Scheduled', 'add'));
|
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 . '.');
|
\FlashMessage\FlashMessage::push('success', 'Le Sms a bien été créé pour le ' . $at . '.');
|
||||||
|
|
||||||
return $this->redirect(\descartes\Router::url('Scheduled', 'list'));
|
return $this->redirect(\descartes\Router::url('Scheduled', 'list'));
|
||||||
|
@ -352,13 +392,43 @@ namespace controllers\publics;
|
||||||
$contacts = $scheduled['contacts'] ?? [];
|
$contacts = $scheduled['contacts'] ?? [];
|
||||||
$groups = $scheduled['groups'] ?? [];
|
$groups = $scheduled['groups'] ?? [];
|
||||||
$conditional_groups = $scheduled['conditional_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);
|
$scheduled = $this->internal_scheduled->get($id_scheduled);
|
||||||
if (!$scheduled || $scheduled['id_user'] !== $id_user)
|
if (!$scheduled || $scheduled['id_user'] !== $id_user)
|
||||||
{
|
{
|
||||||
continue;
|
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))
|
if (empty($text))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -387,31 +457,38 @@ namespace controllers\publics;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$success = $this->internal_scheduled->update_for_user($id_user, $id_scheduled, $at, $text, $id_phone, $flash, $numbers, $contacts, $groups, $conditional_groups);
|
//If mms is enable and we have medias uploaded
|
||||||
|
if ($_SESSION['user']['settings']['mms'] && $files_arrays)
|
||||||
//Check for media
|
|
||||||
/*
|
|
||||||
$current_media = $scheduled['current_media'] ?? false;
|
|
||||||
if (!$current_media)
|
|
||||||
{
|
{
|
||||||
$this->internal_media->delete_for_scheduled_and_user($id_user, $id_scheduled);
|
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 = $_FILES['media_' . $id_scheduled] ?? false;
|
$media_ids[] = $new_media_id;
|
||||||
if (!$media)
|
}
|
||||||
{
|
|
||||||
$nb_update += (int) $success;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$success = $this->internal_media->create($id_user, $id_scheduled, $media);
|
//Ensure media_ids point to medias belongings to the current user
|
||||||
if (!$success)
|
foreach ($media_ids as $key => $media_id)
|
||||||
{
|
{
|
||||||
continue;
|
$media = $this->internal_media->get($media_id);
|
||||||
|
if (!$media || $media['id_user'] !== $_SESSION['user']['id'])
|
||||||
|
{
|
||||||
|
unset($media_ids[$key]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
++$nb_update;
|
$mms = (bool) count($media_ids);
|
||||||
|
|
||||||
|
$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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($nb_update !== \count($scheduleds))
|
if ($nb_update !== \count($scheduleds))
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace controllers\publics;
|
||||||
private $internal_sended;
|
private $internal_sended;
|
||||||
private $internal_phone;
|
private $internal_phone;
|
||||||
private $internal_contact;
|
private $internal_contact;
|
||||||
|
private $internal_media;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cette fonction est appelée avant toute les autres :
|
* Cette fonction est appelée avant toute les autres :
|
||||||
|
@ -32,6 +33,7 @@ namespace controllers\publics;
|
||||||
$this->internal_sended = new \controllers\internals\Sended($bdd);
|
$this->internal_sended = new \controllers\internals\Sended($bdd);
|
||||||
$this->internal_phone = new \controllers\internals\Phone($bdd);
|
$this->internal_phone = new \controllers\internals\Phone($bdd);
|
||||||
$this->internal_contact = new \controllers\internals\Contact($bdd);
|
$this->internal_contact = new \controllers\internals\Contact($bdd);
|
||||||
|
$this->internal_media = new \controllers\internals\Media($bdd);
|
||||||
|
|
||||||
\controllers\internals\Tool::verifyconnect();
|
\controllers\internals\Tool::verifyconnect();
|
||||||
}
|
}
|
||||||
|
@ -55,6 +57,10 @@ namespace controllers\publics;
|
||||||
foreach ($entities as &$entity)
|
foreach ($entities as &$entity)
|
||||||
{
|
{
|
||||||
$entity['destination_formatted'] = \controllers\internals\Tool::phone_link($entity['destination']);
|
$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');
|
header('Content-Type: application/json');
|
||||||
|
|
|
@ -74,7 +74,7 @@ class Mailer extends AbstractDaemon
|
||||||
$this->logger->info('Try sending email : ' . json_encode($message));
|
$this->logger->info('Try sending email : ' . json_encode($message));
|
||||||
|
|
||||||
$mailer = new \controllers\internals\Mailer();
|
$mailer = new \controllers\internals\Mailer();
|
||||||
$success = $mailer->send($message['destinations'], $message['subject'], $message['body'], $message['alt_body']);
|
$success = $mailer->send($message['destinations'], $message['subject'], $message['body'], $message['alt_body'], $message['attachments']);
|
||||||
if (!$success)
|
if (!$success)
|
||||||
{
|
{
|
||||||
$this->logger->error('Failed sending email');
|
$this->logger->error('Failed sending email');
|
||||||
|
|
|
@ -139,7 +139,7 @@ class Phone extends AbstractDaemon
|
||||||
//Do message sending
|
//Do message sending
|
||||||
$this->logger->info('Try send message : ' . json_encode($message));
|
$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']);
|
$response = $internal_sended->send($this->adapter, $this->phone['id_user'], $this->phone['id'], $message['text'], $message['destination'], $message['flash'], $message['mms'], $message['medias']);
|
||||||
if ($response['error'])
|
if ($response['error'])
|
||||||
{
|
{
|
||||||
$this->logger->error('Failed send message : ' . json_encode($message) . ' with error : ' . $response['error_message']);
|
$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)
|
foreach ($response['smss'] as $sms)
|
||||||
{
|
{
|
||||||
$this->logger->info('Receive message : ' . json_encode($sms));
|
$this->logger->info('Receive message : ' . json_encode($sms));
|
||||||
$response = $internal_received->receive($this->phone['id_user'], $this->phone['id'], $sms['text'], $sms['origin']);
|
$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'] ?? []);
|
||||||
|
|
||||||
if ($response['error'])
|
if ($response['error'])
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,6 +76,8 @@ class Sender extends AbstractDaemon
|
||||||
'id_phone' => $sms['id_phone'],
|
'id_phone' => $sms['id_phone'],
|
||||||
'destination' => $sms['destination'],
|
'destination' => $sms['destination'],
|
||||||
'flash' => $sms['flash'],
|
'flash' => $sms['flash'],
|
||||||
|
'mms' => $sms['mms'],
|
||||||
|
'medias' => $sms['medias'] ?? [],
|
||||||
];
|
];
|
||||||
|
|
||||||
msg_send($this->queues[$queue_id], QUEUE_TYPE_SEND_MSG, $msg);
|
msg_send($this->queues[$queue_id], QUEUE_TYPE_SEND_MSG, $msg);
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
class AddMediaLinksToSms extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Change Method.
|
||||||
|
*
|
||||||
|
* Write your reversible migrations using this method.
|
||||||
|
*
|
||||||
|
* More information on writing migrations is available here:
|
||||||
|
* https://book.cakephp.org/phinx/0/en/migrations.html
|
||||||
|
*
|
||||||
|
* The following commands can be used in this method and Phinx will
|
||||||
|
* automatically reverse them when rolling back:
|
||||||
|
*
|
||||||
|
* createTable
|
||||||
|
* renameTable
|
||||||
|
* addColumn
|
||||||
|
* addCustomColumn
|
||||||
|
* renameColumn
|
||||||
|
* addIndex
|
||||||
|
* addForeignKey
|
||||||
|
*
|
||||||
|
* Any other destructive changes will result in an error when trying to
|
||||||
|
* rollback the migration.
|
||||||
|
*
|
||||||
|
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||||
|
* with the Table class.
|
||||||
|
*/
|
||||||
|
public function change()
|
||||||
|
{
|
||||||
|
//Remove useless column from media
|
||||||
|
$table = $this->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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
class AddIsMms extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Change Method.
|
||||||
|
*
|
||||||
|
* Write your reversible migrations using this method.
|
||||||
|
*
|
||||||
|
* More information on writing migrations is available here:
|
||||||
|
* https://book.cakephp.org/phinx/0/en/migrations.html
|
||||||
|
*
|
||||||
|
* The following commands can be used in this method and Phinx will
|
||||||
|
* automatically reverse them when rolling back:
|
||||||
|
*
|
||||||
|
* createTable
|
||||||
|
* renameTable
|
||||||
|
* addColumn
|
||||||
|
* addCustomColumn
|
||||||
|
* renameColumn
|
||||||
|
* addIndex
|
||||||
|
* addForeignKey
|
||||||
|
*
|
||||||
|
* Any other destructive changes will result in an error when trying to
|
||||||
|
* rollback the migration.
|
||||||
|
*
|
||||||
|
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||||
|
* with the Table class.
|
||||||
|
*/
|
||||||
|
public function change()
|
||||||
|
{
|
||||||
|
$table = $this->table('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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
class UpdateWebhookTypes extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->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\')');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
class CreateCall extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Change Method.
|
||||||
|
*
|
||||||
|
* Write your reversible migrations using this method.
|
||||||
|
*
|
||||||
|
* More information on writing migrations is available here:
|
||||||
|
* https://book.cakephp.org/phinx/0/en/migrations.html
|
||||||
|
*
|
||||||
|
* The following commands can be used in this method and Phinx will
|
||||||
|
* automatically reverse them when rolling back:
|
||||||
|
*
|
||||||
|
* createTable
|
||||||
|
* renameTable
|
||||||
|
* addColumn
|
||||||
|
* addCustomColumn
|
||||||
|
* renameColumn
|
||||||
|
* addIndex
|
||||||
|
* addForeignKey
|
||||||
|
*
|
||||||
|
* Any other destructive changes will result in an error when trying to
|
||||||
|
* rollback the migration.
|
||||||
|
*
|
||||||
|
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||||
|
* with the Table class.
|
||||||
|
*/
|
||||||
|
public function change()
|
||||||
|
{
|
||||||
|
$table = $this->table('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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
class AddCreatedAtAndUpdatedAt extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Change Method.
|
||||||
|
*
|
||||||
|
* Write your reversible migrations using this method.
|
||||||
|
*
|
||||||
|
* More information on writing migrations is available here:
|
||||||
|
* https://book.cakephp.org/phinx/0/en/migrations.html
|
||||||
|
*
|
||||||
|
* The following commands can be used in this method and Phinx will
|
||||||
|
* automatically reverse them when rolling back:
|
||||||
|
*
|
||||||
|
* createTable
|
||||||
|
* renameTable
|
||||||
|
* addColumn
|
||||||
|
* addCustomColumn
|
||||||
|
* renameColumn
|
||||||
|
* addIndex
|
||||||
|
* addForeignKey
|
||||||
|
*
|
||||||
|
* Any other destructive changes will result in an error when trying to
|
||||||
|
* rollback the migration.
|
||||||
|
*
|
||||||
|
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||||
|
* with the Table class.
|
||||||
|
*/
|
||||||
|
public function change()
|
||||||
|
{
|
||||||
|
$database_name = $this->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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,9 @@
|
||||||
'HTTP_PWD_SOUND' => HTTP_PWD_ASSETS . '/sounds',
|
'HTTP_PWD_SOUND' => HTTP_PWD_ASSETS . '/sounds',
|
||||||
'PWD_ADAPTERS' => PWD . '/adapters',
|
'PWD_ADAPTERS' => PWD . '/adapters',
|
||||||
'PWD_DATA' => PWD . '/data',
|
'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_LOGS' => '/var/log/raspisms',
|
||||||
'PWD_PID' => '/var/run/raspisms',
|
'PWD_PID' => '/var/run/raspisms',
|
||||||
'APP_SECRET' => '%APP_SECRET%',
|
'APP_SECRET' => '%APP_SECRET%',
|
||||||
|
@ -66,7 +69,7 @@
|
||||||
'preferred_phone_country' => 'fr,be,ca',
|
'preferred_phone_country' => 'fr,be,ca',
|
||||||
'default_phone_country' => 'fr',
|
'default_phone_country' => 'fr',
|
||||||
'authorized_phone_country' => 'fr,be,ca',
|
'authorized_phone_country' => 'fr,be,ca',
|
||||||
'mms' => 0,
|
'mms' => 1,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
$env = [
|
$env = [
|
||||||
|
//Public static URL
|
||||||
|
'STATIC_HTTP_URL' => '%APP_STATIC_HTTP_URL%',
|
||||||
|
|
||||||
//Database access
|
//Database access
|
||||||
'DATABASE_HOST' => '%APP_DATABASE_HOST%',
|
'DATABASE_HOST' => '%APP_DATABASE_HOST%',
|
||||||
'DATABASE_NAME' => '%APP_DATABASE_NAME%',
|
'DATABASE_NAME' => '%APP_DATABASE_NAME%',
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of RaspiSMS.
|
||||||
|
*
|
||||||
|
* (c) Pierre-Lin Bonnemaison <plebwebsas@gmail.com>
|
||||||
|
*
|
||||||
|
* This source file is subject to the GPL-3.0 license that is bundled
|
||||||
|
* with this source code in the file LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace 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';
|
||||||
|
}
|
||||||
|
}
|
391
models/Media.php
391
models/Media.php
|
@ -17,226 +17,255 @@ namespace models;
|
||||||
class Media extends StandardModel
|
class Media extends StandardModel
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Return an entry by his id for a user.
|
* Return all medias for a scheduled.
|
||||||
*
|
*
|
||||||
* @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
|
* @param int $id_scheduled : scheduled id
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function get_for_scheduled_and_user(int $id_user, int $id_scheduled)
|
public function gets_for_scheduled(int $id_scheduled)
|
||||||
{
|
{
|
||||||
$query = '
|
$query = '
|
||||||
SELECT * FROM `' . $this->get_table_name() . '`
|
SELECT m.id as id, m.id_user as id_user, m.path as path
|
||||||
WHERE id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user)
|
FROM `' . $this->get_table_name() . '` as m
|
||||||
AND id_scheduled = :id_scheduled
|
INNER JOIN media_scheduled as ms
|
||||||
|
ON m.id = ms.id_media
|
||||||
|
WHERE ms.id_scheduled = :id_scheduled
|
||||||
';
|
';
|
||||||
|
|
||||||
$params = [
|
$params = [
|
||||||
'id_user' => $id_user,
|
|
||||||
'id_scheduled' => $id_scheduled,
|
'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 $this->_run_query($query, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of medias in a group of ids and for a user.
|
* Return all medias for a sended.
|
||||||
*
|
*
|
||||||
* @param int $id_user : user id
|
* @param int $id_sended : sended id
|
||||||
* @param array $ids : ids of medias to find
|
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function gets_in_for_user(int $id_user, $ids)
|
public function gets_for_sended(int $id_sended)
|
||||||
{
|
{
|
||||||
$query = '
|
$query = '
|
||||||
SELECT * FROM media
|
SELECT m.id as id, m.id_user as id_user, m.path as path
|
||||||
WHERE id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user)
|
FROM `' . $this->get_table_name() . '` as m
|
||||||
AND id ';
|
INNER JOIN media_sended as ms
|
||||||
|
ON m.id = ms.id_media
|
||||||
|
WHERE ms.id_sended = :id_sended
|
||||||
|
';
|
||||||
|
|
||||||
//On génère la clause IN et les paramètres adaptés depuis le tableau des id
|
$params = [
|
||||||
$generated_in = $this->_generate_in_from_array($ids);
|
'id_sended' => $id_sended,
|
||||||
$query .= $generated_in['QUERY'];
|
];
|
||||||
$params = $generated_in['PARAMS'];
|
|
||||||
$params['id_user'] = $id_user;
|
|
||||||
|
|
||||||
return $this->_run_query($query, $params);
|
return $this->_run_query($query, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a entry by his id for a user.
|
* Return all medias for a received.
|
||||||
*
|
*
|
||||||
* @param int $id_user : User id
|
* @param int $id_received : received id
|
||||||
* @param int $id : Entry id
|
|
||||||
*
|
*
|
||||||
* @return int : Number of removed rows
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function delete_for_user(int $id_user, int $id)
|
public function gets_for_received(int $id_received)
|
||||||
{
|
{
|
||||||
$query = '
|
$query = '
|
||||||
DELETE FROM media
|
SELECT m.id as id, m.id_user as id_user, m.path as path
|
||||||
WHERE id = :id
|
FROM `' . $this->get_table_name() . '` as m
|
||||||
AND id_scheduled IN (SELECT id FROM scheduled WHERE id_user = :id_user)
|
INNER JOIN media_received as mr
|
||||||
';
|
ON m.id = mr.id_media
|
||||||
|
WHERE mr.id_received = :id_received
|
||||||
$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 = [
|
$params = [
|
||||||
'id_user' => $id_user,
|
'id_received' => $id_received,
|
||||||
];
|
];
|
||||||
|
|
||||||
return $this->_run_query($query, $params)[0]['nb'] ?? 0;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -179,6 +179,34 @@ namespace models;
|
||||||
return $this->_run_query($query, $params);
|
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.
|
* Get number of sended SMS for every date since a date for a specific user.
|
||||||
*
|
*
|
||||||
|
|
|
@ -234,6 +234,63 @@ namespace models;
|
||||||
return $this->_run_query($query, $params);
|
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.
|
* Get scheduleds before a date.
|
||||||
*
|
*
|
||||||
|
|
|
@ -113,6 +113,35 @@ namespace models;
|
||||||
return $this->_run_query($query, $params);
|
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.
|
* Return sended for an uid and an adapter.
|
||||||
*
|
*
|
||||||
|
|
|
@ -158,9 +158,9 @@ namespace models;
|
||||||
*
|
*
|
||||||
* @return int : number of modified rows
|
* @return int : number of modified rows
|
||||||
*/
|
*/
|
||||||
public function update_for_user(int $id_user, int $id, array $entry)
|
public function update_for_user(int $id_user, int $id, array $data)
|
||||||
{
|
{
|
||||||
return $this->_update($this->get_table_name(), $entry, ['id_user' => $id_user, 'id' => $id]);
|
return $this->_update($this->get_table_name(), $data, ['id_user' => $id_user, 'id' => $id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,8 +13,9 @@ namespace models;
|
||||||
|
|
||||||
class Webhook extends StandardModel
|
class Webhook extends StandardModel
|
||||||
{
|
{
|
||||||
const TYPE_SEND = 'send_sms';
|
const TYPE_SEND_SMS = 'send_sms';
|
||||||
const TYPE_RECEIVE = 'receive_sms';
|
const TYPE_RECEIVE_SMS = 'receive_sms';
|
||||||
|
const TYPE_INBOUND_CALL = 'inbound_call';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all webhooks for a user and for a type of webhook.
|
* Find all webhooks for a user and for a type of webhook.
|
||||||
|
|
19
routes.php
19
routes.php
|
@ -43,6 +43,7 @@
|
||||||
'update' => '/contact/update/{csrf}/',
|
'update' => '/contact/update/{csrf}/',
|
||||||
'import' => '/contact/import/{csrf}/',
|
'import' => '/contact/import/{csrf}/',
|
||||||
'export' => '/contact/export/{format}/',
|
'export' => '/contact/export/{format}/',
|
||||||
|
'conditional_delete' => '/contact/conditional_delete/{csrf}/',
|
||||||
'json_list' => '/contacts.json/',
|
'json_list' => '/contacts.json/',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -54,14 +55,14 @@
|
||||||
'list_json' => '/discussion/json/',
|
'list_json' => '/discussion/json/',
|
||||||
'show' => '/discussion/show/{number}/',
|
'show' => '/discussion/show/{number}/',
|
||||||
'send' => '/discussion/send/{csrf}/',
|
'send' => '/discussion/send/{csrf}/',
|
||||||
'get_messages' => '/discussion/getmessage/{number}/{transaction_id}/',
|
'get_messages' => [
|
||||||
|
'/discussion/getmessage/{number}/{transaction_id}/',
|
||||||
|
'/discussion/getmessage/{number}/{transaction_id}/{since}/',
|
||||||
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
'Event' => [
|
'Event' => [
|
||||||
'list' => [
|
'list' => '/event/',
|
||||||
'/event/',
|
|
||||||
'/event/p/{page}/',
|
|
||||||
],
|
|
||||||
'list_json' => '/event/json/',
|
'list_json' => '/event/json/',
|
||||||
'delete' => '/event/delete/{csrf}/',
|
'delete' => '/event/delete/{csrf}/',
|
||||||
],
|
],
|
||||||
|
@ -155,6 +156,12 @@
|
||||||
'delete' => '/phone/delete/{csrf}/',
|
'delete' => '/phone/delete/{csrf}/',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'Call' => [
|
||||||
|
'list' => '/call/',
|
||||||
|
'list_json' => '/call/json/',
|
||||||
|
'delete' => '/call/delete/{csrf}/',
|
||||||
|
],
|
||||||
|
|
||||||
'Webhook' => [
|
'Webhook' => [
|
||||||
'list' => '/webhook/',
|
'list' => '/webhook/',
|
||||||
'list_json' => '/webhook/json/',
|
'list_json' => '/webhook/json/',
|
||||||
|
@ -168,6 +175,8 @@
|
||||||
'Callback' => [
|
'Callback' => [
|
||||||
'update_sended_status' => '/callback/status/{adapter_uid}/',
|
'update_sended_status' => '/callback/status/{adapter_uid}/',
|
||||||
'reception' => '/callback/reception/{adapter_uid}/{id_phone}/',
|
'reception' => '/callback/reception/{adapter_uid}/{id_phone}/',
|
||||||
|
'inbound_call' => '/callback/inbound_call/{id_phone}/',
|
||||||
|
'end_call' => '/callback/end_call/{id_phone}/',
|
||||||
],
|
],
|
||||||
|
|
||||||
'Api' => [
|
'Api' => [
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
<?php
|
||||||
|
//Template dashboard
|
||||||
|
|
||||||
|
$this->render('incs/head', ['title' => 'Appels - Show All'])
|
||||||
|
?>
|
||||||
|
<div id="wrapper">
|
||||||
|
<?php
|
||||||
|
$this->render('incs/nav', ['page' => 'calls'])
|
||||||
|
?>
|
||||||
|
<div id="page-wrapper">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<h1 class="page-header">
|
||||||
|
Dashboard <small>Appels</small>
|
||||||
|
</h1>
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li>
|
||||||
|
<i class="fa fa-dashboard"></i> <a href="<?php echo \descartes\Router::url('Dashboard', 'show'); ?>">Dashboard</a>
|
||||||
|
</li>
|
||||||
|
<li class="active">
|
||||||
|
<i class="fa fa-clock-o"></i> Appels
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.row -->
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i> Liste des appels</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form method="GET">
|
||||||
|
<div class="table-events">
|
||||||
|
<table class="table table-bordered table-hover table-striped datatable" id="table-calls">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Origine</th>
|
||||||
|
<th>Destinataire</th>
|
||||||
|
<th>Début de l'appel</th>
|
||||||
|
<th>Fin de l'appel</th>
|
||||||
|
<th>Direction</th>
|
||||||
|
<th class="checkcolumn">✓</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="text-right col-xs-12 no-padding">
|
||||||
|
<strong>Action pour la séléction :</strong>
|
||||||
|
<button class="btn btn-default btn-confirm" type="submit" formaction="<?php echo \descartes\Router::url('Call', 'delete', ['csrf' => $_SESSION['csrf']]); ?>"><span class="fa fa-trash-o"></span> Supprimer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
jQuery(document).ready(function ()
|
||||||
|
{
|
||||||
|
jQuery('.datatable').DataTable({
|
||||||
|
"pageLength": 25,
|
||||||
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
|
"language": {
|
||||||
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
|
},
|
||||||
|
"columnDefs": [{
|
||||||
|
'targets': 'checkcolumn',
|
||||||
|
'orderable': false,
|
||||||
|
}],
|
||||||
|
|
||||||
|
"ajax": {
|
||||||
|
'url': '<?php echo \descartes\Router::url('Call', 'list_json'); ?>',
|
||||||
|
'dataSrc': 'data',
|
||||||
|
},
|
||||||
|
"columns" : [
|
||||||
|
{
|
||||||
|
data: 'origin',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
if (row.direction === 'outbound') {
|
||||||
|
return row.phone_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.contact_name) {
|
||||||
|
return row.origin_formatted + ' (' + jQuery.fn.dataTable.render.text().display(row.contact_name) + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return row.origin_formatted;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'destination',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
if (row.direction === 'inbound') {
|
||||||
|
return row.phone_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.contact_name) {
|
||||||
|
return row.destination_formatted + ' (' + jQuery.fn.dataTable.render.text().display(row.contact_name) + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return row.destination_formatted;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{data: 'start', render: jQuery.fn.dataTable.render.text()},
|
||||||
|
{data: 'end', render: jQuery.fn.dataTable.render.text()},
|
||||||
|
{
|
||||||
|
data: 'direction',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
switch (data) {
|
||||||
|
case 'inbound':
|
||||||
|
return 'Appel entrant';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'outbound':
|
||||||
|
return 'Appel sortant';
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 'Inconnu';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'id',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
return '<input name="ids[]" type="checkbox" value="' + data + '">';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"deferRender": true
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<?php
|
||||||
|
$this->render('incs/footer');
|
|
@ -72,7 +72,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Condition</label>
|
<label>Condition</label>
|
||||||
<p class="italic small help">
|
<p class="italic small help">
|
||||||
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 à <a href="#">l'utilisation des groupes conditionnels.</a><br/>
|
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 à <a href="https://documentation.raspisms.fr/users/groups_and_contacts/conditionnals_groups.html" target="_blank">l'utilisation des groupes conditionnels.</a><br/>
|
||||||
Vous pouvez prévisualiser les contacts qui feront parti du groupe en cliquant sur le bouton <b>"Prévisualiser les contacts"</b>.
|
Vous pouvez prévisualiser les contacts qui feront parti du groupe en cliquant sur le bouton <b>"Prévisualiser les contacts"</b>.
|
||||||
</p>
|
</p>
|
||||||
<input class="form-control" name="condition" placeholder="Ex : contact.gender == 'male'" value="<?php $this->s($_SESSION['previous_http_post']['condition'] ?? '') ?>"/>
|
<input class="form-control" name="condition" placeholder="Ex : contact.gender == 'male'" value="<?php $this->s($_SESSION['previous_http_post']['condition'] ?? '') ?>"/>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
//Template dashboard
|
//Template dashboard
|
||||||
|
|
||||||
$this->render('incs/head', ['title' => 'ConditionalGroupes Conditionnels - Show All'])
|
$this->render('incs/head', ['title' => 'Groupes Conditionnels - Show All'])
|
||||||
?>
|
?>
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<?php
|
<?php
|
||||||
|
@ -41,6 +41,8 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>Nom</th>
|
<th>Nom</th>
|
||||||
<th>Condition</th>
|
<th>Condition</th>
|
||||||
|
<th>Date de création</th>
|
||||||
|
<th>Dernière modification</th>
|
||||||
<th class="checkcolumn">✓</th>
|
<th class="checkcolumn">✓</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -72,7 +74,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
@ -87,7 +89,14 @@ jQuery(document).ready(function ()
|
||||||
},
|
},
|
||||||
"columns" : [
|
"columns" : [
|
||||||
{data: 'name', render: jQuery.fn.dataTable.render.text()},
|
{data: 'name', render: jQuery.fn.dataTable.render.text()},
|
||||||
{data: 'condition', render: jQuery.fn.dataTable.render.text()},
|
{
|
||||||
|
data: 'condition',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
return '<code>' + jQuery.fn.dataTable.render.text().display(data) + '</code>';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{data: 'created_at'},
|
||||||
|
{data: 'updated_at'},
|
||||||
{
|
{
|
||||||
data: 'id',
|
data: 'id',
|
||||||
render: function (data, type, row, meta) {
|
render: function (data, type, row, meta) {
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<h1 class="page-header">
|
<h1 class="page-header">
|
||||||
Dashboard <small>Contacts</small>
|
Dashboard <small>Contacts</small>
|
||||||
<a class="btn btn-info float-right" id="btn-export" href="#"><span class="fa fa-upload"></span> Exporter la liste des contacts</a>
|
<a class="btn btn-warning float-right" id="btn-conditional-deletion" href="#"><span class="fa fa-trash-o"></span> Supprimer une liste dynamique de contacts</a>
|
||||||
|
<a class="btn btn-info float-right" id="btn-export" href="#" style="margin-right: 10px;"><span class="fa fa-upload"></span> Exporter la liste des contacts</a>
|
||||||
<a class="btn btn-info float-right" id="btn-import" href="#" style="margin-right: 10px;"><span class="fa fa-download"></span> Importer une liste de contacts</a>
|
<a class="btn btn-info float-right" id="btn-import" href="#" style="margin-right: 10px;"><span class="fa fa-download"></span> Importer une liste de contacts</a>
|
||||||
</h1>
|
</h1>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
|
@ -43,6 +44,8 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>Nom</th>
|
<th>Nom</th>
|
||||||
<th>Numéro</th>
|
<th>Numéro</th>
|
||||||
|
<th>Date de création</th>
|
||||||
|
<th>Dernière modification</th>
|
||||||
<th class="checkcolumn">✓</th>
|
<th class="checkcolumn">✓</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -110,6 +113,32 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal fade" tabindex="-1" id="conditional-deletion-modal">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<form action="<?php $this->s(\descartes\Router::url('Contact', 'conditional_delete', ['csrf' => $_SESSION['csrf']])); ?>" method="POST" enctype="multipart/form-data">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title">Supprimer des contacts de façon conditionnelle</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body text-center">
|
||||||
|
<div class="form-group">
|
||||||
|
<p>Vous pouvez supprimer une liste dynamique de contacts, construite selon des règles basées sur les données de ces contacts. Pour plus d'informations consultez la documentation relative à <a href="https://documentation.raspisms.fr/users/groups_and_contacts/conditionnals_groups.html" target="_blank">l'utilisation des groupes conditionnels.</a><br/></p>
|
||||||
|
<input class="form-control" name="condition" placeholder="Ex : contact.gender == 'male'" required/>
|
||||||
|
<div class="conditional-deletion-preview-container">
|
||||||
|
<div class="conditional-deletion-preview-text"></div>
|
||||||
|
<a class="btn btn-info conditional-deletion-preview-button" href="#">Prévisualiser les contacts qui seront supprimés</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a type="button" class="btn btn-danger" data-dismiss="modal">Annuler</a>
|
||||||
|
<button class="btn btn-default btn-confirm" type="submit"><span class="fa fa-trash-o"></span> Supprimer les contacts</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
jQuery(document).ready(function()
|
jQuery(document).ready(function()
|
||||||
{
|
{
|
||||||
|
@ -124,11 +153,36 @@ jQuery(document).ready(function()
|
||||||
jQuery('#export-modal').modal({'keyboard': true});
|
jQuery('#export-modal').modal({'keyboard': true});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jQuery('body').on('click', '#btn-conditional-deletion', function ()
|
||||||
|
{
|
||||||
|
jQuery('#conditional-deletion-modal').modal({'keyboard': true});
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery('body').on('click', '.conditional-deletion-preview-button', function (e)
|
||||||
|
{
|
||||||
|
e.preventDefault();
|
||||||
|
var condition = jQuery(this).parents('.form-group').find('input').val();
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
'condition' : condition,
|
||||||
|
};
|
||||||
|
|
||||||
|
jQuery.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: HTTP_PWD + '/conditional_group/preview/',
|
||||||
|
data: data,
|
||||||
|
success: function (data) {
|
||||||
|
jQuery('.conditional-deletion-preview-text').text(data.result);
|
||||||
|
},
|
||||||
|
dataType: 'json'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
//Datatable
|
//Datatable
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
@ -144,6 +198,8 @@ jQuery(document).ready(function()
|
||||||
"columns" : [
|
"columns" : [
|
||||||
{data: 'name', render: jQuery.fn.dataTable.render.text()},
|
{data: 'name', render: jQuery.fn.dataTable.render.text()},
|
||||||
{data: 'number_formatted'},
|
{data: 'number_formatted'},
|
||||||
|
{data: 'created_at'},
|
||||||
|
{data: 'updated_at'},
|
||||||
{
|
{
|
||||||
data: 'id',
|
data: 'id',
|
||||||
render: function (data, type, row, meta) {
|
render: function (data, type, row, meta) {
|
||||||
|
|
|
@ -64,7 +64,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 discussion-container">
|
<div class="col-lg-12 discussion-container">
|
||||||
<div class="text-center"><i class="fa fa-spinner fa-spin"></i></div>
|
<div class="text-center" id="load-message-spinner"><i class="fa fa-spinner fa-spin"></i></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-12 message-input-container">
|
<div class="col-lg-12 message-input-container">
|
||||||
<div class="discussion-message message-input">
|
<div class="discussion-message message-input">
|
||||||
|
@ -41,6 +41,9 @@
|
||||||
<input type="hidden" name="destination" value="<?php $this->s($number); ?>" />
|
<input type="hidden" name="destination" value="<?php $this->s($number); ?>" />
|
||||||
<?php if ($response_phone ) { ?>
|
<?php if ($response_phone ) { ?>
|
||||||
<input type="hidden" name="id_phone" value="<?php $this->s($response_phone['id']); ?>" />
|
<input type="hidden" name="id_phone" value="<?php $this->s($response_phone['id']); ?>" />
|
||||||
|
<?php } ?>
|
||||||
|
<?php if ($_SESSION['user']['settings']['mms'] ?? false) { ?>
|
||||||
|
<input name="medias[]" type="file" multiple />
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<button class="btn" ><span class="fa fa-fw fa-send-o"></span> Envoyer</button>
|
<button class="btn" ><span class="fa fa-fw fa-send-o"></span> Envoyer</button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -53,7 +56,8 @@
|
||||||
<script>
|
<script>
|
||||||
jQuery(document).ready(function () {
|
jQuery(document).ready(function () {
|
||||||
|
|
||||||
var alreadyReceivedMessages = [];
|
//List of messages already loaded
|
||||||
|
var cachedMessages = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cette fonction vérifie régulièrement les sms pour mettre à jour l'affichage
|
* Cette fonction vérifie régulièrement les sms pour mettre à jour l'affichage
|
||||||
|
@ -61,56 +65,104 @@
|
||||||
function getmessages ()
|
function getmessages ()
|
||||||
{
|
{
|
||||||
ajaxTransactionId = Date.now();
|
ajaxTransactionId = Date.now();
|
||||||
jQuery.getJSON(HTTP_PWD + "/discussion/getmessage/<?php echo htmlspecialchars(urlencode($number)); ?>/" + ajaxTransactionId , function( data ) {
|
var first_load = true;
|
||||||
|
url = HTTP_PWD + "/discussion/getmessage/<?php echo htmlspecialchars(urlencode($number)); ?>/" + ajaxTransactionId;
|
||||||
|
var newMessages = false;
|
||||||
|
|
||||||
|
jQuery.getJSON(url, function( data ) {
|
||||||
|
|
||||||
if (data.transaction_id != ajaxTransactionId)
|
if (data.transaction_id != ajaxTransactionId)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
jQuery('.discussion-container').html('');
|
jQuery('.discussion-container #load-message-spinner').remove();
|
||||||
|
jQuery('.discussion-container #send-message-spinner').remove();
|
||||||
|
|
||||||
|
//We also remove all in-progress messages because they are added again in the new response if not sended yet, and if sended they should not appear in double
|
||||||
|
jQuery('.discussion-container .message-in-progress-container').remove();
|
||||||
|
|
||||||
$.each(data.messages, function(key, message) {
|
$.each(data.messages, function(key, message) {
|
||||||
|
//If message already loaded, continue
|
||||||
|
if (message.uid in cachedMessages)
|
||||||
|
{
|
||||||
|
if (cachedMessages[message.uid]['type'] == 'sended')
|
||||||
|
{
|
||||||
|
if (message.status != cachedMessages[message.uid]['status'])
|
||||||
|
{
|
||||||
|
cachedMessages[message.uid] = message;
|
||||||
|
var htmlStatus = (message.status == 'delivered' ? '<span class="message-status fa fa-check-circle fa-fw text-success"></span>' : (message.status == 'failed' ? '<span class="message-status fa fa-times-circle fa-fw text-danger"></span>' : '<span class="message-status fa fa-clock-o fa-fw text-info"></span>' ));
|
||||||
|
jQuery('.discussion-container #' + message.uid + " .message-status").replaceWith(htmlStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add the message to the list of already receiveds once
|
||||||
|
cachedMessages[message.uid] = message;
|
||||||
|
newMessages = true;
|
||||||
|
|
||||||
<?php if ($_SESSION['user']['settings']['detect_url']) { ?>
|
<?php if ($_SESSION['user']['settings']['detect_url']) { ?>
|
||||||
//On ajoute la detection de lien dans le texte du message
|
//On ajoute la detection de lien dans le texte du message
|
||||||
message.text = Autolinker.link(message.text, {newWindow:true});
|
message.text = Autolinker.link(message.text, {newWindow:true});
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
|
var medias = message.medias.map((mediaUrl, index) => {
|
||||||
|
var extension = mediaUrl.split('.').pop();
|
||||||
|
if (['jpg', 'jpeg', 'png', 'gif'].includes(extension))
|
||||||
|
{
|
||||||
|
return '<div class="discussion-message-media"><a href="' + mediaUrl + '" target="_blank"><img src="' + mediaUrl + '"/></a></div>';
|
||||||
|
}
|
||||||
|
else if (['webm', 'ogv', 'mp4'].includes(extension))
|
||||||
|
{
|
||||||
|
return '<video controls class="discussion-message-media"><source src="' + mediaUrl + '"/></video>';
|
||||||
|
}
|
||||||
|
else if (['wav', 'ogg', 'mp3'].includes(extension))
|
||||||
|
{
|
||||||
|
return '<audio controls class="discussion-message-media"><source src="' + mediaUrl + '"/></audio>';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return '<div class="discussion-message-media"><a href="' + mediaUrl + '" target="_blank">Voir le fichier ' + (Number(index) + 1) + '</a></div>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var medias_html = '<div class="discussion-message-medias">' + medias.join('') + '</div>';
|
||||||
|
|
||||||
switch (message.type)
|
switch (message.type)
|
||||||
{
|
{
|
||||||
case 'received' :
|
case 'received' :
|
||||||
var texte = '' +
|
var texte = '' +
|
||||||
'<div class="clearfix message-container">' +
|
'<div class="clearfix message-container" id="' + message.uid + '">' +
|
||||||
'<div class="discussion-message message-received">' +
|
'<div class="discussion-message message-received">' +
|
||||||
'<div class="discussion-message-text">' + message.text + '</div>' +
|
'<div class="discussion-message-text">' + message.text.replace(/\n/g,"<br>") + '</div>' +
|
||||||
|
medias_html +
|
||||||
'<div class="discussion-message-date">' + message.date + '</div>' +
|
'<div class="discussion-message-date">' + message.date + '</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
if (alreadyReceivedMessages.indexOf(message.md5) == -1)
|
if (!first_load) //If new message received and not first time loading
|
||||||
{
|
{
|
||||||
playReceptionSound();
|
playReceptionSound();
|
||||||
alreadyReceivedMessages.push(message.md5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'sended' :
|
case 'sended' :
|
||||||
var texte = '' +
|
var texte = '' +
|
||||||
'<div class="clearfix message-container">' +
|
'<div class="clearfix message-container" id="' + message.uid + '">' +
|
||||||
'<div class="discussion-message message-sended">' +
|
'<div class="discussion-message message-sended">' +
|
||||||
'<div class="discussion-message-text">' + message.text + '</div>' +
|
'<div class="discussion-message-text">' + message.text.replace(/\n/g,"<br>") + '</div>' +
|
||||||
'<div class="discussion-message-date">' + message.date + ' ' + (message.status == 'delivered' ? '<span class="fa fa-check-circle fa-fw text-success"></span>' : (message.status == 'failed' ? '<span class="fa fa-times-circle fa-fw text-danger"></span>' : '<span class="fa fa-clock-o fa-fw text-info"></span>' )) + '</div>' +
|
medias_html +
|
||||||
|
'<div class="discussion-message-date">' + message.date + ' ' + (message.status == 'delivered' ? '<span class="message-status fa fa-check-circle fa-fw text-success"></span>' : (message.status == 'failed' ? '<span class="message-status fa fa-times-circle fa-fw text-danger"></span>' : '<span class="message-status fa fa-clock-o fa-fw text-info"></span>' )) + '</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
break;
|
break;
|
||||||
case 'inprogress' :
|
case 'inprogress' :
|
||||||
var texte = '' +
|
var texte = '' +
|
||||||
'<div class="clearfix message-container">' +
|
'<div class="clearfix message-container message-in-progress-container" id="' + message.uid + '">' +
|
||||||
'<div class="discussion-message message-sended">' +
|
'<div class="discussion-message message-sended">' +
|
||||||
'<div class="message-in-progress-hover"><i class="fa fa-spinner fa-spin"></i></div>' +
|
'<div class="message-in-progress-hover"><i class="fa fa-spinner fa-spin"></i></div>' +
|
||||||
'<div class="discussion-message-text">' + message.text + '</div>' +
|
'<div class="discussion-message-text">' + message.text.replace(/\n/g,"<br>") + '</div>' +
|
||||||
|
medias_html +
|
||||||
'<div class="discussion-message-date">' + message.date + '</div>' +
|
'<div class="discussion-message-date">' + message.date + '</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
@ -122,7 +174,10 @@
|
||||||
|
|
||||||
jQuery('.discussion-container').append(texte);
|
jQuery('.discussion-container').append(texte);
|
||||||
});
|
});
|
||||||
scrollDownDiscussion();
|
|
||||||
|
if (newMessages) {
|
||||||
|
scrollDownDiscussion(first_load);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,9 +191,6 @@
|
||||||
var messageInputContainer = jQuery('.message-input-container').outerHeight();
|
var messageInputContainer = jQuery('.message-input-container').outerHeight();
|
||||||
var footerHeight = jQuery('footer').outerHeight();
|
var footerHeight = jQuery('footer').outerHeight();
|
||||||
|
|
||||||
console.log(windowHeight);
|
|
||||||
console.log(containerPosition.top);
|
|
||||||
|
|
||||||
var containerHeight = Math.floor(windowHeight - (containerPosition.top + messageInputContainer) - 20); //-20 px for aesthetic
|
var containerHeight = Math.floor(windowHeight - (containerPosition.top + messageInputContainer) - 20); //-20 px for aesthetic
|
||||||
|
|
||||||
jQuery('.discussion-container').outerHeight(containerHeight);
|
jQuery('.discussion-container').outerHeight(containerHeight);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Vous avez reçu un nouveau SMS :
|
Vous avez reçu un nouveau <?= $mms ? 'MMS' : 'SMS'; ?> :
|
||||||
Date : <?= $at ?>
|
Date : <?= $at ?>
|
||||||
|
|
||||||
Origine : <?= $origin ?>
|
Origine : <?= $origin ?>
|
||||||
|
|
|
@ -71,7 +71,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>Nom</th>
|
<th>Nom</th>
|
||||||
<th>Nombre de contacts</th>
|
<th>Nombre de contacts</th>
|
||||||
|
<th>Date de création</th>
|
||||||
|
<th>Dernière modification</th>
|
||||||
<th class="checkcolumn">✓</th>
|
<th class="checkcolumn">✓</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -72,7 +74,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
@ -88,6 +90,8 @@ jQuery(document).ready(function ()
|
||||||
"columns" : [
|
"columns" : [
|
||||||
{data: 'name', render: jQuery.fn.dataTable.render.text()},
|
{data: 'name', render: jQuery.fn.dataTable.render.text()},
|
||||||
{data: 'nb_contact', render: jQuery.fn.dataTable.render.text()},
|
{data: 'nb_contact', render: jQuery.fn.dataTable.render.text()},
|
||||||
|
{data: 'created_at'},
|
||||||
|
{data: 'updated_at'},
|
||||||
{
|
{
|
||||||
data: 'id',
|
data: 'id',
|
||||||
render: function (data, type, row, meta) {
|
render: function (data, type, row, meta) {
|
||||||
|
|
|
@ -71,10 +71,13 @@
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="javascript:;" data-toggle="collapse" data-target="#logs"><i class="fa fa-fw fa-file-text"></i> Logs <i class="fa fa-fw fa-caret-down"></i></a>
|
<a href="javascript:;" data-toggle="collapse" data-target="#logs"><i class="fa fa-fw fa-file-text"></i> Logs <i class="fa fa-fw fa-caret-down"></i></a>
|
||||||
<ul id="logs" class="collapse <?php echo in_array($page, array('events', 'smsstop')) ? 'in' : ''; ?>">
|
<ul id="logs" class="collapse <?php echo in_array($page, array('events', 'smsstop', 'calls')) ? 'in' : ''; ?>">
|
||||||
<li <?php echo $page == 'smsstop' ? 'class="active"' : ''; ?>>
|
<li <?php echo $page == 'smsstop' ? 'class="active"' : ''; ?>>
|
||||||
<a href="<?php echo \descartes\Router::url('SmsStop', 'list'); ?>"><i class="fa fa-fw fa-ban"></i> SMS STOP</a>
|
<a href="<?php echo \descartes\Router::url('SmsStop', 'list'); ?>"><i class="fa fa-fw fa-ban"></i> SMS STOP</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li <?php echo $page == 'calls' ? 'class="active"' : ''; ?>>
|
||||||
|
<a href="<?php echo \descartes\Router::url('Call', 'list'); ?>"><i class="fa fa-fw fa-file-audio-o"></i> Appels</a>
|
||||||
|
</li>
|
||||||
<li <?php echo $page == 'events' ? 'class="active"' : ''; ?>>
|
<li <?php echo $page == 'events' ? 'class="active"' : ''; ?>>
|
||||||
<a href="<?php echo \descartes\Router::url('Event', 'list'); ?>"><i class="fa fa-fw fa-clock-o"></i> Évènements</a>
|
<a href="<?php echo \descartes\Router::url('Event', 'list'); ?>"><i class="fa fa-fw fa-clock-o"></i> Évènements</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -72,7 +72,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
@ -109,6 +109,23 @@ jQuery(document).ready(function ()
|
||||||
html += '<div>Non disponible.</div>';
|
html += '<div>Non disponible.</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html += '<br/>';
|
||||||
|
html += '<div class="bold">Notification d\'appel entrant : </div>';
|
||||||
|
|
||||||
|
if (row.callback_inbound_call) {
|
||||||
|
html += '<div><code>' + row.callback_inbound_call + '</code></div>';
|
||||||
|
} else {
|
||||||
|
html += '<div>Non disponible.</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '<br/>';
|
||||||
|
html += '<div class="bold">Notification de fin d\'appel : </div>';
|
||||||
|
console.log(row);
|
||||||
|
if (row.callback_end_call) {
|
||||||
|
html += '<div><code>' + row.callback_end_call + '</code></div>';
|
||||||
|
} else {
|
||||||
|
html += '<div>Non disponible.</div>';
|
||||||
|
}
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
},
|
},
|
||||||
|
|
|
@ -45,8 +45,8 @@
|
||||||
<table class="table table-bordered table-hover table-striped datatable" id="table-receiveds">
|
<table class="table table-bordered table-hover table-striped datatable" id="table-receiveds">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>De</th>
|
<th>Expéditeur</th>
|
||||||
<th>À</th>
|
<th>Destinataire</th>
|
||||||
<th>Message</th>
|
<th>Message</th>
|
||||||
<th>Date</th>
|
<th>Date</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
|
@ -79,7 +79,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
@ -104,7 +104,21 @@ jQuery(document).ready(function ()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{data: 'phone_name', render: jQuery.fn.dataTable.render.text()},
|
{data: 'phone_name', render: jQuery.fn.dataTable.render.text()},
|
||||||
{data: 'text', render: jQuery.fn.dataTable.render.text()},
|
{
|
||||||
|
data: 'text',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
if (row.mms == 1) {
|
||||||
|
var medias = [];
|
||||||
|
for (i = 0; i < row.medias.length; i++) {
|
||||||
|
medias.push('<a href="' + HTTP_PWD + '/data/public/' + jQuery.fn.dataTable.render.text().display(row.medias[i].path) + '" target="_blank">Fichier ' + (i + 1) + '</a>');
|
||||||
|
}
|
||||||
|
html = data + '<br/>' + medias.join(' - ');
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
},
|
||||||
{data: 'at', render: jQuery.fn.dataTable.render.text()},
|
{data: 'at', render: jQuery.fn.dataTable.render.text()},
|
||||||
{
|
{
|
||||||
data: 'status',
|
data: 'status',
|
||||||
|
|
|
@ -64,12 +64,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($_SESSION['user']['settings']['mms'] ?? false) { ?>
|
<?php if ($_SESSION['user']['settings']['mms'] ?? false) { ?>
|
||||||
<div class="form-group">
|
<div class="form-group scheduled-media-group">
|
||||||
<label>Ajouter un média</label>
|
<label>Ajouter un média au SMS</label>
|
||||||
<p class="italic small help description-scheduled-media">
|
<p class="italic small help description-scheduled-media">
|
||||||
Le média sera utilisé uniquement si le téléphone utilisé supporte l'envoi de MMS. Pour plus d'information, consultez la documentation sur <a href="#">l'utilisation des MMS.</a>
|
L'ajout d'un média nécessite un téléphone supportant l'envoi de MMS. Pour plus d'information, consultez la documentation sur <a href="#">l'utilisation des MMS.</a>.
|
||||||
</p>
|
</p>
|
||||||
<input class="" name="media" value="" type="file" />
|
<div class="form-group">
|
||||||
|
<input class="" name="medias[]" value="" type="file" multiple />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -64,17 +64,21 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Ajouter un média</label>
|
<label>Ajouter un média</label>
|
||||||
<p class="italic small help description-scheduled-media">
|
<p class="italic small help description-scheduled-media">
|
||||||
Le média sera utilisé uniquement si le téléphone utilisé supporte l'envoi de MMS. Pour plus d'information, consultez la documentation sur <a href="#">l'utilisation des MMS.</a>
|
L'ajout d'un média nécessite un téléphone supportant l'envoi de MMS. Pour plus d'information, consultez la documentation sur <a href="#">l'utilisation des MMS.</a>.
|
||||||
</p>
|
</p>
|
||||||
<?php if ($scheduled['media']) { ?>
|
<div class="form-group">
|
||||||
<div class="current-media-container">
|
<input class="" name="scheduleds_<?php $this->s($scheduled['id']); ?>_medias[]" value="" type="file" multiple />
|
||||||
<input type="hidden" name="scheduleds[<?php $this->s($scheduled['id']); ?>][current_media]" value="1">
|
</div>
|
||||||
<p class="inline-block">Un média est déjà lié à ce message.</p>
|
<?php if ($scheduled['medias']) { ?>
|
||||||
<a href="#" class="btn btn-warning btn-delete-media">Supprimer le média</a>
|
<div class="current-medias-container">
|
||||||
|
<label>Médias déjà attachés au SMS</label>
|
||||||
|
<?php foreach ($scheduled['medias'] as $key => $media) { ?>
|
||||||
|
<p class="current-media">
|
||||||
|
<input type="hidden" name="scheduleds[<?php $this->s($scheduled['id']); ?>][media_ids][]" value="<?php $this->s($media['id']); ?>">
|
||||||
|
<label>Fichier <?= $key + 1 ?> :</label><br/> <a href="<?php $this->s(HTTP_PWD_DATA_PUBLIC . '/' . $media['path']); ?>" class="btn btn-info btn-sm" target="_blank">Voir le média</a> <a href="#" class="btn btn-warning btn-delete-media btn-sm">Supprimer le média</a>
|
||||||
|
</p>
|
||||||
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
<input class="hidden" name="media_<?php $this->s($scheduled['id']); ?>" type="file" />
|
|
||||||
<?php } else { ?>
|
|
||||||
<input name="media_<?php $this->s($scheduled['id']); ?>" type="file" />
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
@ -246,8 +250,7 @@
|
||||||
jQuery('body').on('click', '.btn-delete-media', function (e)
|
jQuery('body').on('click', '.btn-delete-media', function (e)
|
||||||
{
|
{
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
jQuery(this).parents('.form-group').find('input').removeClass('hidden');
|
jQuery(this).parents('.current-media').remove();
|
||||||
jQuery(this).parents('.form-group').find('.current-media-container').remove();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
jQuery('body').on('click', '.preview-button', function (e)
|
jQuery('body').on('click', '.preview-button', function (e)
|
||||||
|
|
|
@ -72,7 +72,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
@ -87,7 +87,21 @@ jQuery(document).ready(function ()
|
||||||
},
|
},
|
||||||
"columns" : [
|
"columns" : [
|
||||||
{data: 'at', render: jQuery.fn.dataTable.render.text()},
|
{data: 'at', render: jQuery.fn.dataTable.render.text()},
|
||||||
{data: 'text', render: jQuery.fn.dataTable.render.text()},
|
{
|
||||||
|
data: 'text',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
if (row.mms == 1) {
|
||||||
|
var medias = [];
|
||||||
|
for (i = 0; i < row.medias.length; i++) {
|
||||||
|
medias.push('<a href="' + HTTP_PWD + '/data/public/' + jQuery.fn.dataTable.render.text().display(row.medias[i].path) + '" target="_blank">Fichier ' + (i + 1) + '</a>');
|
||||||
|
}
|
||||||
|
html = data + '<br/>' + medias.join(' - ');
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
data: 'id',
|
data: 'id',
|
||||||
render: function (data, type, row, meta) {
|
render: function (data, type, row, meta) {
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
<table class="table table-bordered table-hover table-striped datatable" id="table-sendeds">
|
<table class="table table-bordered table-hover table-striped datatable" id="table-sendeds">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>De</th>
|
<th>Expéditeur</th>
|
||||||
<th>À</th>
|
<th>Destinataire</th>
|
||||||
<th>Message</th>
|
<th>Message</th>
|
||||||
<th>Date</th>
|
<th>Date</th>
|
||||||
<th>Statut</th>
|
<th>Statut</th>
|
||||||
|
@ -69,7 +69,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
@ -94,7 +94,21 @@ jQuery(document).ready(function ()
|
||||||
return row.destination_formatted;
|
return row.destination_formatted;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{data: 'text', render: jQuery.fn.dataTable.render.text()},
|
{
|
||||||
|
data: 'text',
|
||||||
|
render: function (data, type, row, meta) {
|
||||||
|
if (row.mms == 1) {
|
||||||
|
var medias = [];
|
||||||
|
for (i = 0; i < row.medias.length; i++) {
|
||||||
|
medias.push('<a href="' + HTTP_PWD + '/data/public/' + jQuery.fn.dataTable.render.text().display(row.medias[i].path) + '" target="_blank">Fichier ' + (i + 1) + '</a>');
|
||||||
|
}
|
||||||
|
html = data + '<br/>' + medias.join(' - ');
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
},
|
||||||
{data: 'at', render: jQuery.fn.dataTable.render.text()},
|
{data: 'at', render: jQuery.fn.dataTable.render.text()},
|
||||||
{
|
{
|
||||||
data: 'status',
|
data: 'status',
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4 class="panel-title"><i class="fa fa-picture-o fa-fw"></i> Support des MMS</h4>
|
<h4 class="panel-title"><i class="fa fa-picture-o fa-fw"></i> Support des MMS</h4>
|
||||||
|
@ -74,7 +73,6 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
-->
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4 class="panel-title"><i class="fa fa-link fa-fw"></i> Détection des URL dans les discussions</h4>
|
<h4 class="panel-title"><i class="fa fa-link fa-fw"></i> Détection des URL dans les discussions</h4>
|
||||||
|
|
|
@ -70,7 +70,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
|
|
@ -74,7 +74,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
<select name="type" class="form-control" required>
|
<select name="type" class="form-control" required>
|
||||||
<option value="receive_sms" <?= ($_SESSION['previous_http_post']['type'] ?? '') == 'receive_sms' ? 'selected' : '' ?>>Réception d'un SMS</option>
|
<option value="receive_sms" <?= ($_SESSION['previous_http_post']['type'] ?? '') == 'receive_sms' ? 'selected' : '' ?>>Réception d'un SMS</option>
|
||||||
<option value="send_sms" <?= ($_SESSION['previous_http_post']['type'] ?? '') == 'send_sms' ? 'selected' : '' ?>>Envoi d'un SMS</option>
|
<option value="send_sms" <?= ($_SESSION['previous_http_post']['type'] ?? '') == 'send_sms' ? 'selected' : '' ?>>Envoi d'un SMS</option>
|
||||||
|
<option value="inbound_call" <?= ($_SESSION['previous_http_post']['type'] ?? '') == 'inbound_call' ? 'selected' : '' ?>>Réception d'un appel téléphonique</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<a class="btn btn-danger" href="<?php echo \descartes\Router::url('Webhook', 'list'); ?>">Annuler</a>
|
<a class="btn btn-danger" href="<?php echo \descartes\Router::url('Webhook', 'list'); ?>">Annuler</a>
|
||||||
|
|
|
@ -69,7 +69,7 @@ jQuery(document).ready(function ()
|
||||||
{
|
{
|
||||||
jQuery('.datatable').DataTable({
|
jQuery('.datatable').DataTable({
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"bLengthChange": false,
|
"lengthMenu": [[25, 50, 100, 1000, 10000, -1], [25, 50, 100, 1000, 10000, "All"]],
|
||||||
"language": {
|
"language": {
|
||||||
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
"url": HTTP_PWD + "/assets/js/datatables/french.json",
|
||||||
},
|
},
|
||||||
|
@ -92,6 +92,8 @@ jQuery(document).ready(function ()
|
||||||
return 'Envoi de SMS';
|
return 'Envoi de SMS';
|
||||||
case 'receive_sms':
|
case 'receive_sms':
|
||||||
return 'Réception de SMS';
|
return 'Réception de SMS';
|
||||||
|
case 'inbound_call':
|
||||||
|
return 'Réception d\'un appel téléphonique';
|
||||||
default:
|
default:
|
||||||
return 'Inconnu';
|
return 'Inconnu';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue