Пример #1
0
 /**
  * Cette fonction reçoit un SMS, et l'enregistre, en essayant de trouver une commande au passage.
  */
 public function parseReceivedSMS()
 {
     //On créer l'objet de base de données
     global $db;
     for ($i = 0; $i < 30; $i++) {
         foreach (scandir(PWD_RECEIVEDS) as $dir) {
             //Si le fichier est un fichier système, on passe à l'itération suivante
             if ($dir == '.' || $dir == '..') {
                 continue;
             }
             echo "Analyse du SMS " . $dir . "\n";
             //On récupère la date du SMS à la seconde près grâce au nom du fichier (Cf. parseSMS.sh)
             //Il faut mettre la date au format Y-m-d H:i:s
             $date = substr($dir, 0, 4) . '-' . substr($dir, 4, 2) . '-' . substr($dir, 6, 2) . ' ' . substr($dir, 8, 2) . ':' . substr($dir, 10, 2) . ':' . substr($dir, 12, 2);
             //On récupère le fichier, et on récupère la chaine jusqu'au premier ':' pour le numéro de téléphone source, et la fin pour le message
             $content_file = file_get_contents(PWD_RECEIVEDS . $dir);
             //Si on ne peux pas ouvrir le fichier, on quitte en logant une erreur
             if ($content_file == false) {
                 $this->wlog('Unable to read file "' . $dir);
                 die(4);
             }
             //On supprime le fichier. Si on n'y arrive pas, alors on log
             if (!unlink(PWD_RECEIVEDS . $dir)) {
                 $this->wlog('Unable to delete file "' . $dir);
                 die(8);
             }
             $content_file = explode(':', $content_file, 2);
             //Si on a pas passé de numéro ou de message, alors on lève une erreur
             if (!isset($content_file[0], $content_file[1])) {
                 $this->wlog('Missing params in file "' . $dir);
                 die(5);
             }
             $number = $content_file[0];
             $number = internalTools::parsePhone($number);
             $text = $content_file[1];
             //On gère les SMS STOP
             if (trim($text) == 'STOP') {
                 echo 'STOP SMS detected ' . $number . "\n";
                 $this->wlog('STOP SMS detected ' . $number);
                 $db->insertIntoTable('sms_stop', ['number' => $number]);
                 continue;
             }
             //On gère les accusés de reception
             if (trim($text) == 'Delivered' || trim($text) == 'Failed') {
                 echo 'Delivered or Failed SMS for ' . $number . "\n";
                 $this->wlog('Delivered or Failed SMS for ' . $number);
                 //On récupère les SMS pas encore validé, uniquement sur les dernières 12h
                 $now = new DateTime();
                 $interval = new DateInterval('PT12H');
                 $sinceDate = $now->sub($interval)->format('Y-m-d H:i:s');
                 if (!($sendeds = $db->getFromTableWhere('sendeds', ['target' => $number, 'delivered' => false, 'failed' => false, '>at' => $sinceDate], 'at', false, 1))) {
                     continue;
                 }
                 $sended = $sendeds[0];
                 //On gère les echecs
                 if (trim($text) == 'Failed') {
                     $db->updateTableWhere('sendeds', ['before_delivered' => 0, 'failed' => true], ['id' => $sended['id']]);
                     echo "Sended SMS id " . $sended['id'] . " pass to failed status\n";
                     continue;
                 }
                 //On gère le cas des messages de plus de 160 caractères, lesquels impliquent plusieurs accusés
                 if ($sended['before_delivered'] > 1) {
                     $db->updateTableWhere('sendeds', ['before_delivered' => $sended['before_delivered'] - 1], ['id' => $sended['id']]);
                     echo "Sended SMS id " . $sended['id'] . " before_delivered decrement\n";
                     continue;
                 }
                 //Si tout est bon, que nous avons assez d'accusés, nous validons !
                 $db->updateTableWhere('sendeds', ['before_delivered' => 0, 'delivered' => true], ['id' => $sended['id']]);
                 echo "Sended SMS id " . $sended['id'] . " to delivered status\n";
                 continue;
             }
             if (!$number) {
                 $this->wlog('Invalid phone number in file "' . $dir);
                 die(6);
             }
             //On va vérifier si on a reçu une commande, et des identifiants
             $flags = internalTools::parseForFlag($text);
             //On créer le tableau qui permettra de stocker les commandes trouvées
             $found_commands = array();
             //On va passer en revue toutes les commandes, pour voir si on en trouve dans ce message
             $commands = $db->getFromTableWhere('commands');
             $this->wlog('We found ' . count($commands) . ' commands');
             foreach ($commands as $command) {
                 $command_name = mb_strtoupper($command['name']);
                 if (array_key_exists($command_name, $flags)) {
                     $this->wlog('We found command ' . $command_name);
                     if (!$command['anonymous']) {
                         //Si on reçu des identifiants
                         if (array_key_exists('LOGIN', $flags) && array_key_exists('PASSWORD', $flags)) {
                             //Si on a bien un utilisateur avec les identifiants reçus
                             $user = $db->getUserFromEmail($flags['LOGIN']);
                             $this->wlog('We found ' . count($user) . ' users');
                             if ($user && $user['password'] == sha1($flags['PASSWORD'])) {
                                 $this->wlog('Password is valid');
                                 //Si la commande ne nécessite pas d'être admin, ou si on est admin
                                 if (!$command['admin'] || $user['admin']) {
                                     $this->wlog('And the count is ok');
                                     $found_commands[$command_name] = PWD_SCRIPTS . $command['script'] . escapeshellcmd($flags[$command_name]);
                                 }
                             }
                         }
                     } else {
                         $this->wlog('And the count is ok');
                         $found_commands[$command_name] = PWD_SCRIPTS . $command['script'] . escapeshellcmd($flags[$command_name]);
                     }
                 }
             }
             //On va supprimer le mot de passe du SMS pour pouvoir l'enregistrer sans danger
             if (isset($flags['PASSWORD'])) {
                 $text = str_replace($flags['PASSWORD'], '*****', $text);
             }
             //On map les données et on créer le SMS reçu
             $send_by = $number;
             $content = $text;
             $is_command = count($found_commands);
             if (!$db->insertIntoTable('receiveds', ['at' => $date, 'send_by' => $send_by, 'content' => $content, 'is_command' => $is_command])) {
                 echo "Erreur lors de l'enregistrement du SMS\n";
                 $this->wlog('Unable to process the SMS in file "' . $dir);
                 die(7);
             }
             //On insert le SMS dans le tableau des sms à envoyer par mail
             $db->insertIntoTable('transfers', ['id_received' => $db->lastId(), 'progress' => false]);
             //Chaque commande sera executée.
             foreach ($found_commands as $command_name => $command) {
                 echo 'Execution de la commande : ' . $command_name . ' :: ' . $command . "\n";
                 exec($command);
             }
         }
         //On attend 2 secondes
         sleep(2);
     }
 }