lib/Controller/SmsrelentlessController.php
ea796f48
 <?php
 /**
  * @copyright 2021 Double Bastion LLC <www.doublebastion.com>
  *
  * @author Double Bastion LLC
  *
  * @license GNU AGPL version 3 or any later version
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  * License as published by the Free Software Foundation; either
  * version 3 of the License, or any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  *
  * You should have received a copy of the GNU Affero General Public
  * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 declare(strict_types=1);
 
 namespace OCA\SMSRelentless\Controller;
 
 use OCP\IRequest;
 use OCP\AppFramework\Controller;
 use OCA\SMSRelentless\Service\SmsrelentlessService;
 use OCP\AppFramework\App;
 use OC\Http\Client\Client;
 use OCP\Files\SimpleFS\ISimpleFile;
 use OCP\Files\SimpleFS\ISimpleFolder;
 use OCP\IL10N;
 use OCP\Files\Folder;
 use OCP\IConfig;
 use OC\Files\Filesystem;
 use OC\Files\View;
 use \ReflectionClass;
 use \FilesystemIterator;
 use \DateTime;
 use \DateInterval;
 use OCP\AppFramework\Http\DataResponse;
 use OCP\Files\NotFoundException;
 use OCP\Files\NotPermittedException;
 use Plivo\RestClient;
 use OCP\Share\IManager;
 use OCP\Constants;
 use OCP\IGroupManager;
 use OCP\IDBConnection;
 use OCP\IUserManager;
 use OC\URLGenerator;
 
 class SmsrelentlessController extends Controller {
 
     private $service;
     private $config;
     private $userId;
     private $folder;
     private $filesystem;
     private $view;
     private $shareManager;
     private $groupManager;
     private $connection;
     private $userManager;
     private $urlGenerator;
 
     public function __construct($appName, IRequest $request, SmsrelentlessService $service, IConfig $config, $userId, Folder $folder, Filesystem $filesystem, View $view, IManager $shareManager, IGroupManager $groupManager, IDBConnection $connection, IUserManager $userManager, URLGenerator $urlGenerator) {
         parent::__construct($appName, $request);
         $this->service = $service;
         $this->config = $config;
         $this->userId = $userId;
         $this->folder = $folder;
         $this->filesystem = $filesystem;
         $this->view = $view;
 	$this->shareManager = $shareManager;
         $this->groupManager = $groupManager;
         $this->connection = $connection;
         $this->userManager = $userManager;
         $this->urlGenerator = $urlGenerator;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function object_to_array($obj) {
         if (is_object($obj)) $obj = (array)$this->dismount($obj);
         if (is_array($obj)) {
            $new = array();
            foreach($obj as $key => $val) {
                $new[$key] = $this->object_to_array($val);
            }
         }
         else $new = $obj;
         return $new;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function dismount($object) {
         $reflectionClass = new ReflectionClass(get_class($object));
         $array = array();
         foreach ($reflectionClass->getProperties() as $property) {
            $property->setAccessible(true);
            $array[$property->getName()] = $property->getValue($object);
            $property->setAccessible(false);
         }
         return $array;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function getappdirectory($userId) {
         $apprelpath = $this->urlGenerator->linkTo('sms_relentless', 'COPYING.txt');
         $apprelpatharr = explode("/", $apprelpath);
         $currentappdir = $apprelpatharr[1];
         return $currentappdir;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function getbalancetel($userId) {
 
         $telsmsapicred = $this->service->getapicredentials($this->userId);
 
         $telapikey = $telsmsapicred[0];
         $ch = curl_init();
         $headerstel = array("Content-Type: application/json", "Accept: application/json", "Authorization: Bearer ".$telapikey);
 
         curl_setopt($ch, CURLOPT_URL, "https://api.telnyx.com/v2/balance");
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
         curl_setopt($ch, CURLOPT_HTTPHEADER, $headerstel);
         $responsetel = curl_exec($ch);
         $recdatatel = json_decode($responsetel, TRUE);
         $telbalresponse = $recdatatel['data']['balance'];
         $currentbalancetel = round(floatval($telbalresponse), 3);
         curl_close($ch);
 
         return $currentbalancetel;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function getbalancenex($userId) {
 
         $smsapicred = $this->service->getapicredentials($this->userId);
         $smsapikey = $smsapicred[5];
         $smsapisecret = $smsapicred[6];
 
         if ($smsapikey == '' || $smsapisecret == '') {
             $currentbalancenex = "N/A";
         } else {
             $getmesdata = "https://".$smsapikey.":".$smsapisecret."@api.plivo.com/v1/Account/".$smsapikey."/";
             $mesdata = file_get_contents($getmesdata);
             $datainit = json_decode($mesdata);
             $balancenex = $datainit->cash_credits;
             $currentbalancenex = round(floatval($balancenex), 3);
         }
         return $currentbalancenex;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function getbalancetwil($userId) {
 
         $smsapicred = $this->service->getapicredentials($this->userId);
         $smsapisid = $smsapicred[15];
         $smsapitoken = $smsapicred[16];
 
         if ($smsapisid == '' || $smsapitoken == '') {
             $currentbalancetwil = "N/A";
         } else {
 
             $twilbalance = json_decode(file_get_contents("https://".$smsapisid.":".$smsapitoken."@api.twilio.com/2010-04-01/Accounts/".$smsapisid."/Balance.json"));
             $balancetwil = $twilbalance->balance;
 
             $currentbalancetwil = round(floatval($balancetwil), 3);
         }
         return $currentbalancetwil;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function getbalanceflow($userId) {
 
         $currentbalanceflow = 'n/a';
         return $currentbalanceflow;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function getsmsnumbers($userId) {
 
         return $this->service->getsmsnumbers($this->userId);
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function refreshavailablenumbers($userId) {
 
         return $this->service->refreshavailablenumbers($this->userId);
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function cleantempdir($userId) {
 
         // Create the temporary folder if it doesn't exist
         if ($this->folder->nodeExists('SMS_Relentless/temp_files') == false) {
             $this->folder->newFolder('SMS_Relentless/temp_files');
         }
         $datadir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/';
         $targetdir = $datadir . $this->userId . "/files/SMS_Relentless/temp_files";
         $fileSystemIterator = new FilesystemIterator($targetdir);
 
         $dirfiles = [];
         foreach ($fileSystemIterator as $fileInfo) {
                  $dirfiles[] = $fileInfo->getFilename();
         }
 
         foreach ($dirfiles as $key => $indfile) {
                  $thisuserroot = $this->view->getRoot();
                  $tempfile = $thisuserroot . "/SMS_Relentless/temp_files/" . $indfile;
                  $removetmpfile = $this->filesystem->unlink($tempfile);
         }
      }
 
 
     /**
      * @NoAdminRequired
      */
     public function cleanmultrecdir($userId) {
 
         // Create the temporary folder if it doesn't exist
         if ($this->folder->nodeExists('SMS_Relentless/multiple_recipients') == false) {
             $this->folder->newFolder('SMS_Relentless/multiple_recipients');
         }
         $datadirmrc = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/';
         $targetdirmrc = $datadirmrc . $this->userId . "/files/SMS_Relentless/multiple_recipients";
         $fileSystemIteratormrc = new FilesystemIterator($targetdirmrc);
 
         $dirfilesmrc = [];
         foreach ($fileSystemIteratormrc as $fileInfomrc){
                  $dirfilesmrc[] = $fileInfomrc->getFilename();
         }
 
         foreach ($dirfilesmrc as $mreckey => $mrecfile) {
                  $thisuserrootmrc = $this->view->getRoot();
                  $mrectempfile = $thisuserrootmrc . "/SMS_Relentless/multiple_recipients/" . $mrecfile;
                  $removemrectmpfile = $this->filesystem->unlink($mrectempfile);
         }
      }
 
 
     /**
      * @NoAdminRequired
      */
     public function uploadNumbersFile($userId, $uploadfileforsms) {
 
         // Create the temporary folder if it doesn't exist
         if ($this->folder->nodeExists('SMS_Relentless/multiple_recipients') == false) {
             $this->folder->newFolder('SMS_Relentless/multiple_recipients');
         }
 
         // First delete any file that has been previously uploaded
         $datadir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/';
         $targetdir = $datadir . $this->userId . "/files/SMS_Relentless/multiple_recipients";
         $fileSystemIterator = new FilesystemIterator($targetdir);
 
         $dirfiles = [];
         foreach ($fileSystemIterator as $fileInfo){
                  $dirfiles[] = $fileInfo->getFilename();
         }
 
         foreach ($dirfiles as $key => $indfile) {
                  $thisuserroot = $this->view->getRoot();
                  $tempfile = $thisuserroot . "/SMS_Relentless/multiple_recipients/" . $indfile;
                  $removetmpfile = $this->filesystem->unlink($tempfile);
         }
 
         // Upload the new file
         $fileContent = file_get_contents($_FILES['uploadfileforsms']['tmp_name']);
         $fileName = $_FILES['uploadfileforsms']['name'];
 
         $userroot = $this->view->getRoot();
         $targetfile = $userroot . "/SMS_Relentless/multiple_recipients/" . $fileName;
 
         $target = $this->folder->newFile($targetfile);
         $target->putContent($fileContent);
 
         // Extract the phone numbers from the file
         $numberarraysec = str_replace(array(";", "|", "\r\n", "\r", "\n", "\t"), ",", $fileContent);
         $numberarraytert = preg_replace("/[^0-9,]/", "", $numberarraysec);
         $numberarrayfourth = explode(",", $numberarraytert);
         $numberarrayfifth = array_filter(array_map('trim', $numberarrayfourth));
         $numberarray = array_unique($numberarrayfifth);
 
         return $numberarray;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function uploadfile($uploadfileformms) {
 
            $fileContent = file_get_contents($_FILES['uploadfileformms']['tmp_name']);
            $fileName = $_FILES['uploadfileformms']['name'];
            $fileSizeinit = $_FILES['uploadfileformms']['size'];
            $fileSize = $fileSizeinit / 1024;
 
            if ($this->folder->nodeExists('SMS_Relentless/temp_files') == false) {
                $this->folder->newFolder('SMS_Relentless/temp_files');
            }
 
            $userroot = $this->view->getRoot();
            $targetfile = $userroot . "/SMS_Relentless/temp_files/" . $fileName;
 
            $target = $this->folder->newFile($targetfile);
            $target->putContent($fileContent);
 
            // Get the cumulative files size of the uploaded files
            $datadir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/';
            $targetdir = $datadir . $this->userId . "/files/SMS_Relentless/temp_files";
 
            $fileSystemIterator = new FilesystemIterator($targetdir);
 
            $dirfiles = [];
            foreach ($fileSystemIterator as $fileInfo){
                     $dirfiles[] = $fileInfo->getFilename();
            }
 
            $totalflsizeinit = 0;
            foreach ($dirfiles as $key => $indfile) {
                     $fileSizeinit = $this->filesystem->filesize($userroot . "/SMS_Relentless/temp_files/" . $indfile);
                     $mbSize = round($fileSizeinit / 1024, 4);
                     $totalflsizeinit += $mbSize;
            }
 
            $totalflsize = round($totalflsizeinit, 4);
 
            return $totalflsize;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function pickfile($path) {
 
            if ($this->folder->nodeExists('SMS_Relentless/temp_files') == false) {
                $this->folder->newFolder('SMS_Relentless/temp_files');
            }
 
            $datadir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/';
 
            $fltgt = $datadir . $this->userId . "/files" . $path;
 
            $fileContent = file_get_contents($fltgt);
 
            $pkfilesize = round(filesize($fltgt) / 1024, 4);
 
            $patharr = explode("/", $path);
 
            $revarr = array_reverse($patharr);
 
            $relflpath = "/SMS_Relentless/temp_files/" . $revarr[0]; 
 
            $target = $this->folder->newFile($relflpath);
 
            $target->putContent($fileContent);
 
            // Get the cumulative files size of the uploaded files
            $targetdir = $datadir . $this->userId . "/files/SMS_Relentless/temp_files";
 
            $fileSystemIterator = new FilesystemIterator($targetdir);
 
            $dirfiles = [];
            foreach ($fileSystemIterator as $fileInfo) {
                     $dirfiles[] = $fileInfo->getFilename();
            }
 
            $totalflsizeinit = 0;
 
            foreach ($dirfiles as $key => $indfile) {
 
                     $fileSizeinit = $this->filesystem->filesize("/SMS_Relentless/temp_files/" . $indfile);
                     $mbSize = round($fileSizeinit / 1024, 4);
                     $totalflsizeinit += $mbSize;
            }
 
            $totalflsize = round($totalflsizeinit, 4);
 
            $pickresult = [$totalflsize, $pkfilesize];
 
            return $pickresult;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function removeupfile($removedfilename) {
 
            $tmpfl = "/" . $this->userId . "/files/SMS_Relentless/temp_files/" . $removedfilename;
 
            $removefile = $this->view->unlink($tmpfl);
 
            // Get the cumulative files size of the uploaded files
            $datadir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/';
            $targetdir = $datadir . $this->userId . "/files/SMS_Relentless/temp_files";
            $fileSystemIterator = new FilesystemIterator($targetdir);
 
            $dirfiles = [];
            foreach ($fileSystemIterator as $fileInfo){
                     $dirfiles[] = $fileInfo->getFilename();
            }
 
            $totalflsizeinit = 0;
 
            foreach ($dirfiles as $key => $indfile) {
                     $fileSizeinit = $this->filesystem->filesize("/SMS_Relentless/temp_files/" . $indfile);
                     $mbSize = round($fileSizeinit / 1024, 4);
                     $totalflsizeinit += $mbSize;
            }
 
            $totalflsize = round($totalflsizeinit, 4);
 
            return $totalflsize;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function sendsmstel($userId, $receiversPhoneNbs, $fromsender, $waitinterval, $sentsmstext, $ismms, $mmsfiles) {
 
          $telsmsapicred = $this->service->getapicredentials($this->userId);
          $telnyxkey = $telsmsapicred[0];
          $teldelrecurl = $telsmsapicred[3];
          $messagingprofid = $telsmsapicred[4];
          $addDisplName = $telsmsapicred[24];
 
          // Get the Display Name of the current user
          $crtuser = $this->userManager->get($this->userId);
          $displayname = $crtuser->getDisplayName();
 
          if ($addDisplName == 1) {
              $sentsmstext = $displayname . ": " . $sentsmstext;
          }
 
          \Telnyx\Telnyx::setApiKey($telnyxkey);
 
          $microinterval = $waitinterval * 1000;
 
          foreach ($receiversPhoneNbs as $keytel => $tonumber) {
 
              usleep($microinterval);
 
              $messagedate = date("Y-m-d H:i:s");
 
              if ($ismms == 0) {
 
                  if (preg_match('/[A-Za-z]+/', $fromsender)) {
                      $message = \Telnyx\Message::Create(["from" => $fromsender, "to" => $tonumber, "text" => $sentsmstext, "webhook_url" => $teldelrecurl, "messaging_profile_id" => $messagingprofid]);
                  } else {
                      $message = \Telnyx\Message::Create(["from" => $fromsender, "to" => $tonumber, "text" => $sentsmstext, "webhook_url" => $teldelrecurl]);
                  }
 
                  $messagetexttel = $sentsmstext;
 
              } else {
 
                  $mediaURLarr = [];
                  $includedMediaFiles = '';
 
                  for ($p = 0; $p < count($mmsfiles); $p++ ) {
 
                       $userroot = $this->view->getRoot();
                       $filetoshare = $userroot . "/SMS_Relentless/temp_files/".$mmsfiles[$p]."";
 
                       $flsharetarget = $this->folder->newFile($filetoshare);
 
 	              $share = $this->shareManager->newShare();
 	              $share->setNode($flsharetarget);
 	              $share->setPermissions(Constants::PERMISSION_READ);
 	              $share->setShareType(\OC\Share\Constants::SHARE_TYPE_LINK);
 	              $share->setSharedBy($this->userId);
                       $expirydate = DateTime::createFromFormat('Y-m-d H:i:s', $messagedate);
                       $expirydate->add(new \DateInterval('P1D'));
                       $share->setExpirationDate($expirydate);
                       $shared = $this->shareManager->createShare($share);
                       $shareToken = $shared->getToken();
 
                       $hostnm = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'];
 
                       $mediaURLarr[] = $hostnm . "/s/" . $shareToken . "/download/" . $mmsfiles[$p];
 
                       $includedMediaFiles .= "<div id='mmsTblUrl-" . mt_rand(1, 10000) . "' class='mmstblUrls' title='Download this file only if you trust the sender and the domain of the URL.'>" . $hostnm . "/s/" . $shareToken . "/download/" . $mmsfiles[$p] . "</div><br><br>";
                  }
 
                  if (preg_match('/[A-Za-z]+/', $fromsender)) {
                      $message = \Telnyx\Message::Create(["from" => $fromsender, "to" => $tonumber, "text" => $sentsmstext, "webhook_url" => $teldelrecurl, "messaging_profile_id" => $messagingprofid, "subject" => "MMS", "media_urls" => $mediaURLarr]);
                  } else {
                      $message = \Telnyx\Message::Create(["from" => $fromsender, "to" => $tonumber, "text" => $sentsmstext, "webhook_url" => $teldelrecurl, "subject" => "MMS", "media_urls" => $mediaURLarr]);
                  }
 
                  $messagetexttel = $sentsmstext . "<br><br><br>--- File(s) included in MMS ---<br><br>" . $includedMediaFiles;
              }
 
              $messageid = $message['id'];
              $messagefrom = "Telnyx: " . $fromsender;
              $messageto = $tonumber;
              $messagenetwork = null;
              $messageprice = null;
              $messagestatus = $message['to'][0]['status'];
              $messagedelivery = null;
 
              $sentmessagearr = [$messageid, $messagedate, $messagefrom, $messageto, $messagenetwork, $messageprice, $messagestatus, $messagedelivery, $messagetexttel];
 
              $this->service->insertsentsms($this->userId, $displayname, $sentmessagearr);
          }
          return $displayname;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function sendsmsnex($userId, $receiversPhoneNbs, $fromsender, $waitinterval, $sentsmstext, $ismms, $mmsfiles) {
 
          $plsmsapicred = $this->service->getapicredentials($this->userId);
 
          $smsapikey = $plsmsapicred[5];
          $smsapisecret = $plsmsapicred[6];
          $smsapideliveryrecurl = $plsmsapicred[8];
          $addDisplName = $plsmsapicred[24];
 
          // Get the Display Name of the current user
          $crtuser = $this->userManager->get($this->userId);
          $displayname = $crtuser->getDisplayName();
 
          if ($addDisplName == 1) {
              $sentsmstext = $displayname . ": " . $sentsmstext;
          }
 
          $microinterval = $waitinterval * 1000;
 
          foreach ($receiversPhoneNbs as $keynex => $tonumber) {
 
              usleep($microinterval);
 
              $messagedatepl = date("Y-m-d H:i:s");
 
              if ($ismms == 0) {
 
                  $client = new RestClient($smsapikey, $smsapisecret);
                  $response = $client->messages->create($fromsender,[$tonumber],$sentsmstext,["url" => $smsapideliveryrecurl]);
                  $messagetextpl = $sentsmstext;
 	         $messageidinit = $response->getmessageUuid(0);
                  $messageid = $messageidinit[0];
 
                  if (property_exists($response, 'error')) { 
                      $messagestatus = "Error: " . $response->error;
                  } else { $messagestatus = 'The message has been accepted for delivery.'; }
 
              } else {
 
                  $mediaURLarr = [];
                  $includedMediaFiles = '';
 
                  for ($p = 0; $p < count($mmsfiles); $p++ ) {
 
                       $userroot = $this->view->getRoot();
                       $filetoshare = $userroot . "/SMS_Relentless/temp_files/".$mmsfiles[$p]."";
 
                       $flsharetarget = $this->folder->newFile($filetoshare);
 
 	              $share = $this->shareManager->newShare();
 	              $share->setNode($flsharetarget);
 	              $share->setPermissions(Constants::PERMISSION_READ);
 	              $share->setShareType(\OC\Share\Constants::SHARE_TYPE_LINK);
 	              $share->setSharedBy($this->userId);
                       $expirydate = DateTime::createFromFormat('Y-m-d H:i:s', $messagedatepl);
                       $expirydate->add(new \DateInterval('P1D'));
                       $share->setExpirationDate($expirydate);
                       $shared = $this->shareManager->createShare($share);
                       $shareToken = $shared->getToken();
 
                       $hostnm = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'];
 
                       $mediaURLarr[] = $hostnm . "/s/" . $shareToken . "/download/" . $mmsfiles[$p];
 
                       $includedMediaFiles .= "<div id='mmsTblUrl-" . mt_rand(1, 10000) . "' class='mmstblUrls' title='Download this file only if you trust the sender and the domain of the URL.'>" . $hostnm . "/s/" . $shareToken . "/download/" . $mmsfiles[$p] . "</div><br><br>";
                  }
 
 		 $datatosendpl = ["src" => $fromsender, "dst" => $tonumber, "text" => $sentsmstext, "url" => $smsapideliveryrecurl, "type" => "mms", "media_urls" => $mediaURLarr];
 		 $postedparamspl = json_encode($datatosendpl);
 
 		 $chpl = curl_init();
 		 curl_setopt($chpl, CURLOPT_URL, 'https://'.$smsapikey.':'.$smsapisecret.'@api.plivo.com/v1/Account/'.$smsapikey.'/Message/');
 		 curl_setopt($chpl, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
 		 curl_setopt($chpl, CURLOPT_TIMEOUT, 300);
 		 curl_setopt($chpl, CURLOPT_RETURNTRANSFER, 1);
 		 curl_setopt($chpl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
 		 curl_setopt($chpl, CURLOPT_POST, 1);
 		 curl_setopt($chpl, CURLOPT_POSTFIELDS, $postedparamspl);
 		 $resultpl = curl_exec ($chpl);
 		 $statusCodepl = curl_getinfo($chpl, CURLINFO_HTTP_CODE);
 		 curl_close ($chpl);
 
 		 $decresultpl = json_decode($resultpl);
 
                  if ($decresultpl) {
                      if (property_exists($decresultpl, 'message_uuid')) {
                          $messageidinit = $decresultpl->message_uuid;
                          $messageid = $messageidinit[0];
                      } else { $messageid = 'n/a'; }
                  } else { $messageid = 'n/a'; }
 
 	         if (in_array($statusCodepl, [200, 201, 202, 203, 204, 205, 206])) {
 
                      if (property_exists($decresultpl, 'error')) {
                          $messagestatus = "Error: " . $decresultpl->error;
                      } else { $messagestatus = 'The message has been accepted for delivery.'; }
 
                  } else { $messagestatus = 'An error occurred while trying to send the message.'; }
 
                  $messagetextpl = $sentsmstext . "<br><br><br>--- File(s) included in MMS ---<br><br>" . $includedMediaFiles;
              }
 
              if (preg_match('/[A-Za-z]+/', $fromsender)) {
                  $messagefrom = "Plivo: " . $fromsender;
              } else { $messagefrom = "Plivo: +" . $fromsender; }
 
              $messageto = $tonumber;
              $messagenetwork = '';
              $messageprice = '';
 
              $messagedelivery = '';
 
              $sentmessagearr = [$messageid, $messagedatepl, $messagefrom, $messageto, $messagenetwork, $messageprice, $messagestatus, $messagedelivery, $messagetextpl];
 
              $this->service->insertsentsms($this->userId, $displayname, $sentmessagearr);
          }
          return $displayname;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function sendsmstwil($userId, $receiversPhoneNbs, $fromsender, $waitinterval, $sentsmstext, $ismms, $mmsfiles) {
 
          $twsmsapicred = $this->service->getapicredentials($this->userId);
 
          $sid = $twsmsapicred[15];
          $token = $twsmsapicred[16];
          $smsapirecurltw = $twsmsapicred[18];
          $addDisplName = $twsmsapicred[24];
 
          // Get the Display Name of the current user
          $crtuser = $this->userManager->get($this->userId);
          $displayname = $crtuser->getDisplayName();
 
          if ($addDisplName == 1) {
              $sentsmstext = $displayname . ": " . $sentsmstext;
          }
 
          $microinterval = $waitinterval * 1000;
 
          foreach ($receiversPhoneNbs as $keytwil => $tonumbertw) {
 
              usleep($microinterval);
 
              $messagedatetw = date("Y-m-d H:i:s");
 
              if ($ismms == 0) {
 
                  $datatoposttw = [["To" => $tonumbertw, "From" => $fromsender, "Body" => $sentsmstext, "StatusCallback" => $smsapirecurltw]];
                  $sentsmstextfintw = $sentsmstext;
 
              } else {
 
                  $mediaURLs = [];
                  $includedMediaFiles = '';
 
                  for ($p = 0; $p < count($mmsfiles); $p++ ) {
 
                       $userroot = $this->view->getRoot();
                       $filetoshare = $userroot . "/SMS_Relentless/temp_files/".$mmsfiles[$p]."";
 
                       $flsharetarget = $this->folder->newFile($filetoshare);
 
 	              $share = $this->shareManager->newShare();
 	              $share->setNode($flsharetarget);
 	              $share->setPermissions(Constants::PERMISSION_READ);
 	              $share->setShareType(\OC\Share\Constants::SHARE_TYPE_LINK);
 	              $share->setSharedBy($this->userId);
                       $expirydate = DateTime::createFromFormat('Y-m-d H:i:s', $messagedatetw);
                       $expirydate->add(new \DateInterval('P1D'));
                       $share->setExpirationDate($expirydate);
                       $shared = $this->shareManager->createShare($share);
                       $shareToken = $shared->getToken();
 
                       $hostnm = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'];
 
                       $mediaURLs[] = $hostnm . "/s/" . $shareToken . "/download/" . $mmsfiles[$p];
 
                       $includedMediaFiles .= "<div id='mmsTblUrl-" . mt_rand(1, 10000) . "' class='mmstblUrls' title='Download this file only if you trust the sender and the domain of the URL.'>" . $hostnm . "/s/" . $shareToken . "/download/" . $mmsfiles[$p] . "</div><br><br>";
                  }
 
                  $datatoposttw = [["To" => $tonumbertw, "From" => $fromsender, "Body" => $sentsmstext, "StatusCallback" => $smsapirecurltw]];
 
                  for ($m = 0; $m < count($mediaURLs); $m++) {
                       array_push($datatoposttw, ["MediaUrl" => $mediaURLs[$m]]);
                  }
 
                  $sentsmstextfintw = $sentsmstext . "<br><br><br>--- File(s) included in MMS ---<br><br>" . $includedMediaFiles;
              }
 
              $postedsendingfl = implode('&', array_map('http_build_query', $datatoposttw));
 
 	     $chtw = curl_init();
 	     curl_setopt($chtw, CURLOPT_URL, 'https://api.twilio.com/2010-04-01/Accounts/'.$sid.'/Messages.json');
 	     curl_setopt($chtw, CURLOPT_TIMEOUT, 300);
 	     curl_setopt($chtw, CURLOPT_RETURNTRANSFER, 1);
 	     curl_setopt($chtw, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
              curl_setopt($chtw, CURLOPT_USERPWD, "$sid:$token");
 	     curl_setopt($chtw, CURLOPT_POST, 1);
              curl_setopt($chtw, CURLOPT_POSTFIELDS, $postedsendingfl);
 
 	     $resulttw = curl_exec ($chtw);
 	     $statusCodetw = curl_getinfo($chtw, CURLINFO_HTTP_CODE);
 	     curl_close ($chtw);
 
              $decresulttw = json_decode($resulttw);
 
              if ($decresulttw) {
                  if (property_exists($decresulttw, 'sid')) { $messageidtw = $decresulttw->sid; } else { $messageidtw = 'n/a'; }
              } else { $messageidtw = 'n/a'; }
 
 	     if (in_array($statusCodetw, [200, 201, 202, 203, 204, 205, 206])) {
                  $messagestatustw = 'The message has been accepted for delivery.';
              } else {
                  $messagestatustw = 'An error occurred while trying to send the message.';
              }
 
              if (preg_match('/[A-Za-z]+/', $fromsender)) {
                  $messagefromtw = "Twilio: " . $fromsender;
              } else { $messagefromtw = "Twilio: " . $fromsender; }
 
              $messagenetworktw = '';
              $messagepricetw = '';
              $messagedeliverytw = '';
 
              $sentmessagearr = [$messageidtw, $messagedatetw, $messagefromtw, $tonumbertw, $messagenetworktw, $messagepricetw, $messagestatustw, $messagedeliverytw, $sentsmstextfintw];
 
              $this->service->insertsentsms($this->userId, $displayname, $sentmessagearr);
          }
          return $displayname;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function sendsmsflow($userId, $receiversPhoneNbs, $fromsender, $waitinterval, $sentsmstext, $ismms, $mmsfiles) {
 
          $flsmsapicred = $this->service->getapicredentials($this->userId);
 
          $flowapikey = $flsmsapicred[20];
          $flowapisecret = $flsmsapicred[21];
          $flowdelrecurl = $flsmsapicred[23];
          $addDisplName = $flsmsapicred[24];
 
          // Get the Display Name of the current user
          $crtuser = $this->userManager->get($this->userId);
          $displayname = $crtuser->getDisplayName();
 
          if ($addDisplName == 1) {
              $sentsmstext = $displayname . ": " . $sentsmstext;
          }
 
          $sentsmstextproc = str_replace('"','\\"', $sentsmstext);
 
          $microinterval = $waitinterval * 1000;
 
          foreach ($receiversPhoneNbs as $keyflow => $tonumberfl) {
 
              usleep($microinterval);
 
              $messagedatefl = date("Y-m-d H:i:s");
 
              if ($ismms == 0) {
 
                  $messagetextfinfl = $sentsmstext;
                  $postedparamsfl = json_encode(["to" => $tonumberfl, "from" => $fromsender, "body" => $sentsmstextproc, "dlr_callback" => $flowdelrecurl]);
 
              } else {
 
 		 $mediaurlsarr = [];
 		 $includedMediaFiles = '';
 
 		 for ($p = 0; $p < count($mmsfiles); $p++ ) {
 
 		      $userroot = $this->view->getRoot();
 		      $filetoshare = $userroot . "/SMS_Relentless/temp_files/".$mmsfiles[$p]."";
 
 		      $flsharetarget = $this->folder->newFile($filetoshare);
 
 		      $share = $this->shareManager->newShare();
 		      $share->setNode($flsharetarget);
 		      $share->setPermissions(Constants::PERMISSION_READ);
 		      $share->setShareType(\OC\Share\Constants::SHARE_TYPE_LINK);
 		      $share->setSharedBy($this->userId);
                       $expirydate = DateTime::createFromFormat('Y-m-d H:i:s', $messagedatefl);
                       $expirydate->add(new \DateInterval('P1D'));
                       $share->setExpirationDate($expirydate);
 		      $shared = $this->shareManager->createShare($share);
 		      $shareToken = $shared->getToken();
 
                       $hostnm = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'];
 
 		      $mediaurlsarr[] = $hostnm . "/s/" . $shareToken . "/download/" . $mmsfiles[$p];
 
                       $includedMediaFiles .= "<div id='mmsTblUrl-" . mt_rand(1, 10000) . "' class='mmstblUrls' title='Download this file only if you trust the sender and the domain of the URL.'>" . $hostnm . "/s/" . $shareToken . "/download/" . $mmsfiles[$p] . "</div><br><br>";
 		 }
 
                  $messagetextfinfl = $sentsmstext . "<br><br><br>--- File(s) included in MMS ---<br><br>" . $includedMediaFiles;
 
                  $postedparamsfl = json_encode(["to" => $tonumberfl, "from" => $fromsender, "body" => $sentsmstextproc, "dlr_callback" => $flowdelrecurl, "media_urls" => $mediaurlsarr]);
              }
 
 	     $chfl = curl_init();
 	     curl_setopt($chfl, CURLOPT_URL, 'https://'.$flowapikey.':'.$flowapisecret.'@api.flowroute.com/v2.1/messages');
 	     curl_setopt($chfl, CURLOPT_HTTPHEADER, array("Content-Type: application/vnd.api+json"));
 	     curl_setopt($chfl, CURLOPT_TIMEOUT, 300);
 	     curl_setopt($chfl, CURLOPT_RETURNTRANSFER, 1);
 	     curl_setopt($chfl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
 	     curl_setopt($chfl, CURLOPT_POST, 1);
              curl_setopt($chfl, CURLOPT_POSTFIELDS, $postedparamsfl);
 	     $resultfl = curl_exec ($chfl);
 	     $statusCode = curl_getinfo($chfl, CURLINFO_HTTP_CODE);
 	     curl_close ($chfl);
 
              $decresultfl = json_decode($resultfl);
 
              if ($decresultfl) {
                  if (property_exists($decresultfl, 'data')) { 
                      $messageidfl = $decresultfl->data->id;
                  } else { $messageidfl = 'n/a'; }
              } else { $messageidfl = 'n/a'; }
 
 	     if (in_array($statusCode, [200, 201, 202, 203, 204, 205, 206])) {
                  $messagestatusfl = 'The message has been accepted for delivery.'; 
              } else { 
                  $messagestatusfl = 'An error occurred while trying to send the message.'; 
              }
 
              if (preg_match('/[A-Za-z]+/', $fromsender)) {
                  $messagefromfl = "Flowroute: " . $fromsender;
              } else { $messagefromfl = "Flowroute: " . $fromsender; }
 
              $messagetofl = $tonumberfl;
              $messagenetworkfl = '';
              $messagepricefl = '';
              $messagedeliveryfl = '';
 
              $sentmessagearr = [$messageidfl, $messagedatefl, $messagefromfl, $messagetofl, $messagenetworkfl, $messagepricefl, $messagestatusfl, $messagedeliveryfl, $messagetextfinfl];
 
              $this->service->insertsentsms($this->userId, $displayname, $sentmessagearr);
          }
          return $displayname;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function saveoldrecrows($userId, $oldrecRows) {
 
            // Create the folder for removed messages if it doesn't exist
            if ($this->folder->nodeExists('SMS_Relentless/removed_received_messages') == false) {
                $this->folder->newFolder('SMS_Relentless/removed_received_messages');
            }
            $savecheck = 0;
 
            if (count($oldrecRows) > 1) {
                $msfileContent = implode("", $oldrecRows);
 
                $delrowsdate = date("Y-m-d_H-i-s");
                $msfileName = "Received_Messages_Deleted_On_" . $delrowsdate . ".csv";
 
                $userroot = $this->view->getRoot();
                $targetfile = $userroot . "/SMS_Relentless/removed_received_messages/" . $msfileName;
 
                $target = $this->folder->newFile($targetfile);
                $target->putContent($msfileContent);
 
                if ($this->filesystem->file_get_contents($targetfile) != '') {
                    $savecheck = 1;
                }
            }
 
            return $savecheck;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function saveoldsentrows($userId, $oldsentRows) {
 
            // Create the folder for removed messages if it doesn't exist
            if ($this->folder->nodeExists('SMS_Relentless/removed_sent_messages') == false) {
                $this->folder->newFolder('SMS_Relentless/removed_sent_messages');
            }
            $savesentcheck = 0;
 
            if (count($oldsentRows) > 1) {
                $sntfileContent = implode("", $oldsentRows);
 
                $delsentrowsdate = date("Y-m-d_H-i-s");
                $sntfileName = "Sent_Messages_Deleted_On_" . $delsentrowsdate . ".csv";
 
                $userroot = $this->view->getRoot();
                $snttargetfile = $userroot . "/SMS_Relentless/removed_sent_messages/" . $sntfileName;
 
                $snttarget = $this->folder->newFile($snttargetfile);
                $snttarget->putContent($sntfileContent);
 
                if ($this->filesystem->file_get_contents($snttargetfile) != '') {
                    $savesentcheck = 1;
                }
            }
 
            return $savesentcheck;
     }
 
 
     /**
      * @NoAdminRequired
      */
     public function getreceivedtable($userId) {
            return $this->service->getreceivedtable($this->userId);
     }
 
     /**
      * @NoAdminRequired
      */
     public function getreceivedtablefordel($userId) {
            return $this->service->getreceivedtablefordel($this->userId);
     }
 
     /**
      * @NoAdminRequired
      */
     public function removerecrows($userId, $recmessagedbIDs) {
            return $this->service->removerecrows($this->userId, $recmessagedbIDs);
     }
 
     /**
      * @NoAdminRequired
      */
     public function getsenttable($userId) {
            return $this->service->getsenttable($this->userId);
     }
 
     /**
      * @NoAdminRequired
      */
     public function getsenttablefordel($userId) {
            return $this->service->getsenttablefordel($this->userId);
     }
 
     /**
      * @NoAdminRequired
      */
     public function removesentrows($userId, $sentmessagedbIDs) {
            return $this->service->removesentrows($this->userId, $sentmessagedbIDs);
     }
 
     /**
      * @NoAdminRequired
      */
     public function getgroupedtable($userId) {
            return $this->service->getgroupedtable($this->userId);
     }
 
     /**
      * @NoAdminRequired
      */
     public function savedisplayname($userId, $authorDisplayname, $from) {
            return $this->service->savedisplayname($this->userId, $authorDisplayname, $from);
     }
 
     /**
      * @NoAdminRequired
      */
     public function getmsgsperpagenewmsg($userId) {
            return $this->service->getmsgsperpagenewmsg($this->userId);
     }
 
     /**
      * @NoAdminRequired
      */
     public function getnewmsgindicator($userId) {
            return $this->service->getnewmsgindicator($this->userId);
     }
 
     /**
      * @NoAdminRequired
      */
     public function getdelrecsettings($userId) {
            return $this->service->getdelrecsettings($this->userId);
     }
 
     public function updatenumberrestrictions($userId, $savedByDsplname, $phoneNumber, $groups, $users) {
            return $this->service->updatenumberrestrictions($this->userId, $savedByDsplname, $phoneNumber, $groups, $users);
     }
 
     public function updatekeysallowedusers($userId, $groups, $users, $provider) {
            return $this->service->updatekeysallowedusers($this->userId, $groups, $users, $provider);
     }
 
     public function removenumberrestrictions($userId, $phoneNumber) {
            return $this->service->removenumberrestrictions($this->userId, $phoneNumber);
     }
 
     /**
      * @NoAdminRequired
      */
     public function updateautoreplies($userId, $savedByDsplname, $phoneNumber, $daysOfWeek, $dailyStart, $dailyEnd, $vacationStart, $vacationEnd, $messageText) {
            return $this->service->updateautoreplies($this->userId, $savedByDsplname, $phoneNumber, $daysOfWeek, $dailyStart, $dailyEnd, $vacationStart, $vacationEnd, $messageText);
     }
 
     /**
      * @NoAdminRequired
      */
     public function removeautoreplies($userId, $phoneNumber) {
            return $this->service->removeautoreplies($this->userId, $phoneNumber);
     }
 
     /**
      * @NoAdminRequired
      */
     public function getsettings($userId) {
            return $this->service->getsettings($this->userId);
     }
 
     public function getadminsettings($userId) {
            return $this->service->getadminsettings($this->userId);
     }
 
     /**
      * @NoAdminRequired
      */
     public function getautoreplyconf($userId) {
 
            // Get the available phone numbers for the current user (the restricted phone numbers are excluded)
            $availphonenmbrs = $this->getsmsnumbers($this->userId);
 
            // Get the display name of the current user
            $usrid = $this->userId;
            $getusrdnm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
 	   $getusrdnmres = $getusrdnm->execute([$usrid, 'displayname']);
 	   $getusrdnmdata = $getusrdnmres->fetch();
 	   $userDisplayNm = $getusrdnmdata['value'];
 	   $getusrdnmres->closeCursor();
 
            // Get the auto-replies for the available phone numbers
            $getautorpl = $this->connection->prepare('SELECT `saved_by_dsplname`, `phone_number`, `days_of_week`, `daily_start`, `daily_end`, `vacation_start`, `vacation_end`, 
                                                     `message_text` FROM `*PREFIX*sms_relent_autorply`');
 	   $getautorplres = $getautorpl->execute();
            $autorplconf = [];
 	   while ($acdatausrdnadm = $getautorplres->fetch()) {
                   $autorplconf[] = $acdatausrdnadm;
            }
 	   $getautorplres->closeCursor();
 
            if ($autorplconf) {
 
                $autoreplyconf = [];
                foreach ($autorplconf as $arkey => $arvalue) {
                         if (in_array($arvalue['phone_number'], $availphonenmbrs)) {
                             $autoreplyconf[] = $arvalue;
                         }
                }
 
            } else { $autoreplyconf = ''; }
 
            $autoreplyfdb = ['userdisplayname' => $userDisplayNm, 'phonenumbers' => $availphonenmbrs, 'autoreplies' => $autoreplyconf];
 
            return $autoreplyfdb;
     }
 
     /**
      * @NoAdminRequired
      */
     public function getgroupedpernumber($userId, $phoneNumber) {
            return $this->service->getgroupedpernumber($this->userId, $phoneNumber);
     }
 
     /**
      * @NoAdminRequired
      */
     public function getgroupedforreply($userId, $phoneNmbrFrom, $phoneNmbrTo) {
            return $this->service->getgroupedforreply($this->userId, $phoneNmbrFrom, $phoneNmbrTo);
     }
 
     /**
      * @NoAdminRequired
      */
     public function updatesettings($userId, $telapiUrlRec, $telapiUrl, $nexapiUrlRec, $nexapiUrl, $twilapiUrlRec, $twilapiUrl, $flowapiUrlRec, $flowapiUrl, $messagesperpage, $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval) {
            return $this->service->updatesettings($this->userId, $telapiUrlRec, $telapiUrl, $nexapiUrlRec, $nexapiUrl, $twilapiUrlRec, $twilapiUrl, $flowapiUrlRec, $flowapiUrl, $messagesperpage, $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval);
     }
 
     public function updateadminsettings($userId, $telapiKey, $telPubKey, $telapiUrlRec, $telapiUrl, $messagingProfileId, $nexapiKey, $nexapiSecret, $nexapiUrlRec, $nexapiUrl, $telSenderName, $nexSenderName, $twilapiKey, $twilapiSecret, $twilapiUrlRec, $twilapiUrl, $twilSenderName, $flowapiKey, $flowapiSecret, $flowapiUrlRec, $flowapiUrl, $showAllMessages) {
            return $this->service->updateadminsettings($this->userId, $telapiKey, $telPubKey, $telapiUrlRec, $telapiUrl, $messagingProfileId, $nexapiKey, $nexapiSecret, $nexapiUrlRec, $nexapiUrl, $telSenderName, $nexSenderName, $twilapiKey, $twilapiSecret, $twilapiUrlRec, $twilapiUrl, $twilSenderName, $flowapiKey, $flowapiSecret, $flowapiUrlRec, $flowapiUrl, $showAllMessages);
     }
 
     public function updatepersadmnsettings($userId, $messagesperpage, $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval) {
            return $this->service->updatepersadmnsettings($this->userId, $messagesperpage, $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval);
     }
 }