2019-10-29 14:57:13 +01:00
< ? php
2019-10-30 00:30:39 +01:00
/*
2019-11-10 17:48:54 +01:00
* This file is part of RaspiSMS .
2019-10-30 00:30:39 +01:00
*
2019-11-10 17:48:54 +01:00
* ( c ) Pierre - Lin Bonnemaison < plebwebsas @ gmail . com >
2019-10-30 00:30:39 +01:00
*
2019-11-10 17:48:54 +01:00
* This source file is subject to the GPL - 3.0 license that is bundled
2019-10-30 00:30:39 +01:00
* with this source code in the file LICENSE .
*/
namespace controllers\internals ;
2019-10-29 14:57:13 +01:00
2019-11-14 02:02:50 +01:00
/**
* Some tools frequently used .
2020-01-17 18:19:25 +01:00
* Not a standard controller as it ' s not linked to a model in any way .
2019-11-14 02:02:50 +01:00
*/
2019-10-29 18:36:25 +01:00
class Tool extends \descartes\InternalController
{
/**
* Cette fonction parse un numéro pour le retourner sans espaces , etc .
2019-10-30 00:30:39 +01:00
*
2019-10-29 18:36:25 +01:00
* @ param string $number : Le numéro de téléphone à parser
2019-10-30 00:30:39 +01:00
*
2019-10-29 18:36:25 +01:00
* @ return mixed : Si le numéro est bien un numéro de téléphone , on retourne le numéro parsé . Sinon , on retourne faux
*/
public static function parse_phone ( $number )
{
2019-11-30 05:31:20 +01:00
try
2019-10-30 00:30:39 +01:00
{
2019-11-30 05:31:20 +01:00
$phone_number_util = \libphonenumber\PhoneNumberUtil :: getInstance ();
$phone_number_o = $phone_number_util -> parse ( $number , null );
$valid = $phone_number_util -> isValidNumber ( $phone_number_o );
if ( ! $valid )
{
return false ;
}
2019-10-30 00:30:39 +01:00
2019-11-30 05:31:20 +01:00
return $phone_number_util -> format ( $phone_number_o , \libphonenumber\PhoneNumberFormat :: E164 );
}
2020-01-17 18:19:25 +01:00
catch ( \Exception $e )
2019-11-30 05:31:20 +01:00
{
return false ;
}
2019-10-29 18:36:25 +01:00
}
2019-10-29 14:57:13 +01:00
2019-10-29 18:36:25 +01:00
/**
* Cette fonction parse un numéro pour le retourner avec des espaces , etc .
2019-10-30 00:30:39 +01:00
*
2019-10-29 18:36:25 +01:00
* @ param string $number : Le numéro de téléphone à parser
2019-10-30 00:30:39 +01:00
*
2019-10-29 18:36:25 +01:00
* @ return mixed : Si le numéro est bien un numéro de téléphone , on retourne le numéro parsé . Sinon , on retourne faux
*/
2019-11-10 01:17:28 +01:00
public static function phone_format ( $number )
2019-10-29 18:36:25 +01:00
{
2019-11-30 05:31:20 +01:00
try
{
$phone_number_util = \libphonenumber\PhoneNumberUtil :: getInstance ();
$phone_number_o = $phone_number_util -> parse ( $number , null );
2019-11-10 17:36:42 +01:00
2019-11-30 05:31:20 +01:00
return $phone_number_util -> format ( $phone_number_o , \libphonenumber\PhoneNumberFormat :: INTERNATIONAL );
}
2020-01-17 18:19:25 +01:00
catch ( \Exception $e )
2019-11-30 05:31:20 +01:00
{
2020-04-03 03:38:35 +02:00
return false ;
2019-11-30 05:31:20 +01:00
}
2019-10-29 18:36:25 +01:00
}
2019-10-29 14:57:13 +01:00
2019-11-29 05:29:03 +01:00
/**
2020-01-17 18:19:25 +01:00
* Format a number and make a link to a discussion with this number .
*
2019-11-29 05:29:03 +01:00
* @ param string $number : Number to format and make a link for
2020-01-17 18:19:25 +01:00
*
2019-11-29 05:29:03 +01:00
* @ return string : Link to the number
*/
2020-01-17 18:19:25 +01:00
public static function phone_link ( $number )
2019-11-29 05:29:03 +01:00
{
2020-01-17 18:19:25 +01:00
$number_format = self :: phone_format ( $number );
2019-11-29 05:29:03 +01:00
$url = \descartes\Router :: url ( 'Discussion' , 'show' , [ 'number' => $number ]);
2020-01-17 18:19:25 +01:00
2020-01-17 18:47:08 +01:00
return '<a href="' . self :: s ( $url , false , true , false ) . '">' . self :: s ( $number_format , false , true , false ) . '</a>' ;
2019-11-29 05:29:03 +01:00
}
2019-10-29 18:36:25 +01:00
/**
* Cette fonction fait la correspondance entre un type d ' evenement et une icone font awesome .
2019-10-30 00:30:39 +01:00
*
2019-10-29 18:36:25 +01:00
* @ param string $type : Le type de l ' évenement à analyser
2019-10-30 00:30:39 +01:00
*
2019-10-29 18:36:25 +01:00
* @ return string : Le nom de l ' icone à afficher ( ex : fa - user )
*/
public static function event_type_to_icon ( $type )
{
switch ( $type ) {
case 'USER_ADD' :
$logo = 'fa-user' ;
2019-10-30 00:30:39 +01:00
2019-10-29 18:36:25 +01:00
break ;
2021-01-14 03:32:17 +01:00
2019-10-29 18:36:25 +01:00
case 'CONTACT_ADD' :
$logo = 'fa-user' ;
2019-10-30 00:30:39 +01:00
2019-10-29 18:36:25 +01:00
break ;
2021-01-14 03:32:17 +01:00
2019-10-29 18:36:25 +01:00
case 'GROUP_ADD' :
$logo = 'fa-group' ;
2019-10-30 00:30:39 +01:00
2020-09-27 02:01:29 +02:00
break ;
2021-01-14 03:32:17 +01:00
2020-09-27 02:01:29 +02:00
case 'CONDITIONAL_GROUP_ADD' :
$logo = 'fa-bullseye' ;
2019-10-29 18:36:25 +01:00
break ;
2021-01-14 03:32:17 +01:00
2019-10-29 18:36:25 +01:00
case 'SCHEDULED_ADD' :
$logo = 'fa-calendar' ;
2019-10-30 00:30:39 +01:00
2019-10-29 18:36:25 +01:00
break ;
2021-01-14 03:32:17 +01:00
2019-10-29 18:36:25 +01:00
case 'COMMAND_ADD' :
$logo = 'fa-terminal' ;
2019-10-30 00:30:39 +01:00
2019-10-29 18:36:25 +01:00
break ;
2021-01-14 03:32:17 +01:00
2021-06-14 20:21:06 +02:00
case 'QUOTA_LIMIT_CLOSE' :
$logo = 'fa-exclamation' ;
break ;
case 'QUOTA_LIMIT_REACHED' :
$logo = 'fa-exclamation-triangle' ;
break ;
case 'QUOTA_RENEWAL' :
$logo = 'fa-retweet' ;
break ;
case 'QUOTA_CONSUME' :
$logo = 'fa-euro' ;
break ;
2019-10-29 18:36:25 +01:00
default :
$logo = 'fa-question' ;
}
2019-10-29 14:57:13 +01:00
2019-10-29 18:36:25 +01:00
return $logo ;
}
2019-10-29 14:57:13 +01:00
2019-10-29 18:36:25 +01:00
/**
2019-10-30 00:30:39 +01:00
* Cette fonction vérifie une date .
*
* @ param string $date : La date a valider
2019-10-29 18:36:25 +01:00
* @ param string $format : Le format de la date
2019-10-30 00:30:39 +01:00
*
* @ return bool : Vrai si la date et valide , faux sinon
2019-10-29 18:36:25 +01:00
*/
public static function validate_date ( $date , $format )
{
$objectDate = \DateTime :: createFromFormat ( $format , $date );
2019-10-30 00:30:39 +01:00
return $objectDate && $objectDate -> format ( $format ) === $date ;
2019-10-29 18:36:25 +01:00
}
2021-06-12 23:23:15 +02:00
/**
* Check if a sting represent a valid PHP period for creating an interval .
*
* @ param string $period : Period string to check
*
* @ return bool : True if valid period , false else
*/
public static function validate_period ( $period )
{
try
{
$interval = new \DateInterval ( $period );
}
catch ( \Throwable $e )
{
return false ;
}
return true ;
}
2019-10-29 14:57:13 +01:00
2019-10-29 18:36:25 +01:00
/**
2019-10-30 00:30:39 +01:00
* Cette fonction retourne un mot de passe généré aléatoirement .
*
2019-10-29 18:36:25 +01:00
* @ param int $length : Taille du mot de passe à générer
2019-10-30 00:30:39 +01:00
*
2019-10-29 18:36:25 +01:00
* @ return string : Le mot de passe aléatoire
*/
public static function generate_password ( $length )
{
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-@()?.:!%*$&/' ;
$password = '' ;
$chars_length = mb_strlen ( $chars ) - 1 ;
$i = 0 ;
2019-10-30 00:30:39 +01:00
while ( $i < $length )
{
++ $i ;
2019-10-29 18:36:25 +01:00
$password .= $chars [ rand ( 0 , $chars_length )];
}
2019-10-30 00:30:39 +01:00
2019-10-29 18:36:25 +01:00
return $password ;
}
/**
2019-10-30 00:30:39 +01:00
* Cette fonction vérifie si un utilisateur et connecté , et si il ne l ' est pas , redirige sur la page de connexion .
2019-10-29 18:36:25 +01:00
*/
2019-10-30 00:17:10 +01:00
public static function verifyconnect ()
2019-10-29 18:36:25 +01:00
{
2019-10-30 00:30:39 +01:00
if ( ! isset ( $_SESSION [ 'connect' ]) || ! $_SESSION [ 'connect' ])
{
2019-10-29 18:36:25 +01:00
header ( 'Location: /' );
2021-01-14 03:32:17 +01:00
exit ();
2019-10-29 18:36:25 +01:00
}
2019-10-29 14:57:13 +01:00
}
2019-10-30 00:30:39 +01:00
2019-11-11 00:22:40 +01:00
/**
* Check if the user connected .
*
* @ return bool : True if connected , False else
*/
public static function is_connected ()
{
return ( bool ) ( $_SESSION [ 'connect' ] ? ? false );
}
2019-10-29 14:57:13 +01:00
/**
* Check if the user is admin .
2019-10-30 00:30:39 +01:00
*
* @ return bool : True if admin , False else
2019-10-29 18:36:25 +01:00
*/
public static function is_admin ()
{
2019-11-10 00:27:42 +01:00
return ( bool ) ( $_SESSION [ 'user' ][ 'admin' ] ? ? false );
2019-10-29 14:57:13 +01:00
}
2019-11-30 05:31:20 +01:00
/**
2020-01-17 18:19:25 +01:00
* Allow to read an uploaded file .
*
2019-11-30 05:31:20 +01:00
* @ param array $file : The array extracted from $_FILES [ 'file' ]
2020-01-17 18:19:25 +01:00
*
2021-03-26 23:32:29 +01:00
* @ 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 ]
2019-11-30 05:31:20 +01:00
*/
public static function read_uploaded_file ( array $file )
{
$result = [
'success' => false ,
'content' => 'Une erreur inconnue est survenue.' ,
'error_code' => $file [ 'error' ] ? ? 99 ,
2021-03-26 23:32:29 +01:00
'mime_type' => null ,
'extension' => null ,
'tmp_name' => null ,
2019-11-30 05:31:20 +01:00
];
2020-01-17 18:19:25 +01:00
if ( UPLOAD_ERR_OK !== $file [ 'error' ])
2019-11-30 05:31:20 +01:00
{
switch ( $file [ 'error' ])
{
2020-01-17 18:19:25 +01:00
case UPLOAD_ERR_INI_SIZE :
2020-01-17 18:47:08 +01:00
$result [ 'content' ] = 'Impossible de télécharger le fichier car il dépasse les ' . ini_get ( 'upload_max_filesize' ) / ( 1000 * 1000 ) . ' Mégaoctets.' ;
2020-01-17 18:19:25 +01:00
2019-11-30 05:31:20 +01:00
break ;
2021-01-14 03:32:17 +01:00
2020-01-17 18:19:25 +01:00
case UPLOAD_ERR_FORM_SIZE :
2019-11-30 05:31:20 +01:00
$result [ 'content' ] = 'Le fichier dépasse la limite de taille.' ;
2020-01-17 18:19:25 +01:00
2019-11-30 05:31:20 +01:00
break ;
2021-01-14 03:32:17 +01:00
2020-01-17 18:19:25 +01:00
case UPLOAD_ERR_PARTIAL :
2019-11-30 05:31:20 +01:00
$result [ 'content' ] = 'L\'envoi du fichier a été interrompu.' ;
2020-01-17 18:19:25 +01:00
break ;
2021-01-14 03:32:17 +01:00
2020-01-17 18:19:25 +01:00
case UPLOAD_ERR_NO_FILE :
2019-11-30 05:31:20 +01:00
$result [ 'content' ] = 'Aucun fichier n\'a été envoyé.' ;
2020-01-17 18:19:25 +01:00
2019-11-30 05:31:20 +01:00
break ;
2021-01-14 03:32:17 +01:00
2020-01-17 18:19:25 +01:00
case UPLOAD_ERR_NO_TMP_DIR :
2019-11-30 05:31:20 +01:00
$result [ 'content' ] = 'Le serveur ne dispose pas de fichier temporaire permettant l\'envoi de fichiers.' ;
break ;
2021-01-14 03:32:17 +01:00
2020-01-17 18:19:25 +01:00
case UPLOAD_ERR_CANT_WRITE :
$result [ 'content' ] = 'Impossible d\'envoyer le fichier car il n\'y a plus de place sur le serveur.' ;
2019-11-30 05:31:20 +01:00
2020-01-17 18:19:25 +01:00
break ;
2021-01-14 03:32:17 +01:00
2020-01-17 18:19:25 +01:00
case UPLOAD_ERR_EXTENSION :
2019-11-30 05:31:20 +01:00
$result [ 'content' ] = 'Le serveur a interrompu l\'envoi du fichier.' ;
2020-01-17 18:19:25 +01:00
2019-11-30 05:31:20 +01:00
break ;
}
2020-01-17 18:19:25 +01:00
return $result ;
2019-11-30 05:31:20 +01:00
}
$tmp_filename = $file [ 'tmp_name' ] ? ? false ;
if ( ! $tmp_filename || ! is_readable ( $tmp_filename ))
{
return $result ;
}
2021-03-19 02:45:12 +01:00
$result [ 'tmp_name' ] = $tmp_filename ;
$result [ 'extension' ] = pathinfo ( $file [ 'name' ], PATHINFO_EXTENSION );
2020-07-03 03:59:37 +02:00
$result [ 'mime_type' ] = mime_content_type ( $tmp_filename );
2019-11-30 05:31:20 +01:00
$file_handler = fopen ( $tmp_filename , 'r' );
$result [ 'success' ] = true ;
$result [ 'content' ] = $file_handler ;
return $result ;
}
2020-01-17 18:19:25 +01:00
2019-12-04 03:04:45 +01:00
/**
2021-03-26 23:32:29 +01:00
* Generate a highly random uuid based on timestamp and strong cryptographic random
2020-01-17 18:19:25 +01:00
*
2021-03-26 23:32:29 +01:00
* @ return string
2019-12-04 03:04:45 +01:00
*/
2021-03-26 23:32:29 +01:00
public static function random_uuid ()
2019-12-04 03:04:45 +01:00
{
2021-03-26 23:32:29 +01:00
$bytes = random_bytes ( 16 );
return time () . '-' . bin2hex ( $bytes );
}
2019-12-04 03:04:45 +01:00
2021-03-26 23:32:29 +01:00
/**
* 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 )
{
$new_dir = PWD_DATA_PUBLIC . '/' . $id_user ;
if ( file_exists ( $new_dir ))
2019-12-04 03:04:45 +01:00
{
2021-03-26 23:32:29 +01:00
return $new_dir ;
2019-12-04 03:04:45 +01:00
}
2021-03-27 01:15:09 +01:00
clearstatcache ();
if ( ! mkdir ( $new_dir ))
2019-12-04 03:04:45 +01:00
{
2021-03-26 23:32:29 +01:00
throw new \Exception ( 'Cannot create dir ' . $new_dir );
2019-12-04 03:04:45 +01:00
}
2021-03-27 01:15:09 +01:00
//We do chmod in two times because else umask fuck mkdir permissions
if ( ! chmod ( $new_dir , fileperms ( PWD_DATA_PUBLIC ) & 0777 )) //Fileperms return garbage in addition to perms. Perms are only in weak bytes. We must use an octet notation with 0
2019-12-04 03:04:45 +01:00
{
2021-03-27 01:15:09 +01:00
throw new \Exception ( 'Cannot give dir ' . $new_dir . ' rights : ' . decoct ( fileperms ( PWD_DATA_PUBLIC ) & 0777 )); //Show error in dec
}
if ( posix_getuid () === 0 && ! chown ( $new_dir , fileowner ( PWD_DATA_PUBLIC ))) //If we are root, try to give the file to a proper user
{
throw new \Exception ( 'Cannot give dir ' . $new_dir . ' to user : ' . fileowner ( PWD_DATA_PUBLIC ));
2019-12-04 03:04:45 +01:00
}
2021-04-03 18:30:05 +02:00
if ( posix_getuid () === 0 && ! chgrp ( $new_dir , filegroup ( PWD_DATA_PUBLIC ))) //If we are root, try to give the file to a proper group
2019-12-04 03:04:45 +01:00
{
2021-03-27 01:15:09 +01:00
throw new \Exception ( 'Cannot give dir ' . $new_dir . ' to group : ' . filegroup ( PWD_DATA_PUBLIC ));
2019-12-04 03:04:45 +01:00
}
2021-03-26 23:32:29 +01:00
return $new_dir ;
2021-03-19 02:45:12 +01:00
}
2019-10-29 18:36:25 +01:00
}