<?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\Service;

use OCP\IDBConnection;
use OCP\Security\ICrypto;
use OCP\AppFramework\ApiController;
use OCP\AppFramework\Controller;
use OCP\IRequest;
use OCP\IGroupManager;
use \ReflectionClass;

class SmsrelentlessService {

     private $connection;
     private $crypto;
     private $groupManager;

     public function __construct(IDBConnection $connection, ICrypto $crypto, IGroupManager $groupManager) {

                $this->connection = $connection;
                $this->crypto = $crypto;
                $this->groupManager = $groupManager;
     }


     /**
      * @NoAdminRequired
      *
      */
     public function insertrecsms($userId, $recmessagearr) {

            $authorDisplayNm = '';
            $internalSender = 0;

            // Search for the associated Display Name in the previous messages sent from the same phone number, in the 'sms_relent_sent' table
            $recmsgfromprc = '%' . $recmessagearr[2];
            $getdspnmst = $this->connection->prepare('SELECT `from`, `author_displayname` FROM `*PREFIX*sms_relent_sent` WHERE `from` LIKE ?');
            $getdspnmstres = $getdspnmst->execute([$recmsgfromprc]);

            $dispnamearr = [];
            while ($dspnmstfetched = $getdspnmstres->fetch()) {
                   $dispnamearr[] = $dspnmstfetched['author_displayname'];
            }
	    $getdspnmstres->closeCursor();

            if ($dispnamearr) {
                $descdspnmarr = array_reverse($dispnamearr);
                $authorDisplayNm = $descdspnmarr[0];
                $internalSender = 1;
            } else { $authorDisplayNm = ''; $internalSender = 0; }


            if (!$authorDisplayNm) {

                // Search for the associated Display Name in the previous messages coming from the same phone number, in the 'sms_relent_received' table
                $getdspnm = $this->connection->prepare('SELECT `from`, `author_displayname` FROM `*PREFIX*sms_relent_received` WHERE `from` = ?');
                $getdspnmres = $getdspnm->execute([$recmessagearr[2]]);

                $dspnmearr = [];
                while ($dspnmfetched = $getdspnmres->fetch()) {
                       if ($dspnmfetched['author_displayname']) {
                           $dspnmearr[] = $dspnmfetched['author_displayname'];
                       }
                }
	        $getdspnmres->closeCursor();

                if ($dspnmearr) {
                    $descdisplaynmarr = array_reverse($dspnmearr);
                    $authorDisplayNm = $descdisplaynmarr[0];
                    $internalSender = 0;
                } else { $authorDisplayNm = ''; $internalSender = 0; }
            }

            // Insert the received message in the 'sms_relent_received' table
            $escapedmessagepre = $recmessagearr[4];
            $escapedmessage = nl2br($escapedmessagepre);

            $sql = $this->connection->prepare('
				INSERT INTO `*PREFIX*sms_relent_received`
					(`user_id`, `message_id`, `date`, `from`, `to`, `message`, `author_displayname`, `internal_sender`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?)
			');
	    $sql->execute([$userId, $recmessagearr[0], $recmessagearr[1], $recmessagearr[2], $recmessagearr[3], $escapedmessage, $authorDisplayNm, $internalSender]);

            // Save a 'new message received' indicator in the 'sms_relent_settings' table, for the (admin) user who received the message
            $newMessageRcd = 1;
	    $sqlupdatenm = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_settings`
			SET `new_message_rcd` = ?
	                WHERE `user_id` = ?');
	    $updatenmRes = $sqlupdatenm->execute([$newMessageRcd, $userId]);
	    $updatenmRes->closeCursor();


            // Save a 'new message received' indicator in the 'sms_relent_settings' table, for the non-admin users with whom the admin receiving the message shared his API keys

            // Get the groups and users that were allowed access to the API keys
            $getgrps = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed`, `tnx_users_allowed`, `plv_groups_allowed`, `plv_users_allowed`,
                                                  `twl_groups_allowed`, `twl_users_allowed`, `flr_groups_allowed`, `flr_users_allowed` FROM `*PREFIX*sms_relent_subac`
                                                   WHERE `user_id` = ?');
            $getgrpsres = $getgrps->execute([$userId]);
            $getgrpsusr = $getgrpsres->fetch();
            $getgrpsres->closeCursor();

            if ($getgrpsusr) {

                if ($getgrpsusr['tnx_users_allowed']) { $tnxusers = explode("|", $getgrpsusr['tnx_users_allowed']); } else { $tnxusers = []; }
                if ($getgrpsusr['plv_users_allowed']) { $plvusers = explode("|", $getgrpsusr['plv_users_allowed']); } else { $plvusers = []; }
                if ($getgrpsusr['twl_users_allowed']) { $twlusers = explode("|", $getgrpsusr['twl_users_allowed']); } else { $twlusers = []; }
                if ($getgrpsusr['flr_users_allowed']) { $flrusers = explode("|", $getgrpsusr['flr_users_allowed']); } else { $flrusers = []; }

                $allwdusersarr = array_merge($tnxusers, $plvusers, $twlusers, $flrusers);
                $allwdusersunq = array_filter(array_unique($allwdusersarr));

                if ($getgrpsusr['tnx_groups_allowed']) { $tnxgroups = explode("|", $getgrpsusr['tnx_groups_allowed']); } else { $tnxgroups = []; }
                if ($getgrpsusr['plv_groups_allowed']) { $plvgroups = explode("|", $getgrpsusr['plv_groups_allowed']); } else { $plvgroups = []; }
                if ($getgrpsusr['twl_groups_allowed']) { $twlgroups = explode("|", $getgrpsusr['twl_groups_allowed']); } else { $twlgroups = []; }
                if ($getgrpsusr['flr_groups_allowed']) { $flrgroups = explode("|", $getgrpsusr['flr_groups_allowed']); } else { $flrgroups = []; }

                $allwdgroupsarr = array_merge($tnxgroups, $plvgroups, $twlgroups, $flrgroups);
                $allwdgroupsunq = array_filter(array_unique($allwdgroupsarr));

            } else {
                $allwdusersunq = [];
                $allwdgroupsunq = [];
            }

            // Get the username for each Display Name of the allowed users
            $allwdusersfnl = [];
            foreach ($allwdusersunq as $alwdusrkey => $alwdusrvalue) {

                         $getacdatausrnm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		         $getacdatausrnmres = $getacdatausrnm->execute(['displayname', $alwdusrvalue]);
		         $acdatausrname = $getacdatausrnmres->fetch();
                         if ($acdatausrname) {
                             $allwdusersfnl[] = $acdatausrname['uid'];
                         }
                         $getacdatausrnmres->closeCursor();
            }

            // Get the users from all the allowed groups
            $allwdusersgrpmlt = [];
            foreach ($allwdgroupsunq as $prgrpkey => $prgrpvalue) {

                     // Get all the users that belong to the current group, if the current group is different from 'admin'
                     if ($prgrpvalue != 'admin') {

                         $getusringroup = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
		         $getusringroupres = $getusringroup->execute([$prgrpvalue]);

		         while ($getusrname = $getusringroupres->fetch()) {
                                $allwdusersgrpmlt[] = $getusrname['uid'];
                         }
		         $getusringroupres->closeCursor();
                     }
            }
            $allwdusersgrpfnl = array_unique($allwdusersgrpmlt);
            
            $allusr = array_merge($allwdusersfnl, $allwdusersgrpfnl);
            $allusruniquest = array_unique($allusr);

            foreach ($allusruniquest as $alwdk => $allwdusr) {
		     $newMsgRcd = 1;
		     $sqlupdatenmsc = $this->connection->prepare('
				UPDATE `*PREFIX*sms_relent_settings`
				SET `new_message_rcd` = ?
			        WHERE `user_id` = ?');
		     $updatenmResc = $sqlupdatenmsc->execute([$newMsgRcd, $allwdusr]);
		     $updatenmResc->closeCursor();
            }
     }


     /**
      * @NoAdminRequired
      *
      */
     public function insertsentsms($userId, $displayname, $sentmessagearr) {

            $msgsentfrompre = explode("+", $sentmessagearr[2]);
            $msgsentfrom = "+" . $msgsentfrompre[1];

            $textwithnl = nl2br($sentmessagearr[8]);
            $sql = $this->connection->prepare('
				INSERT INTO `*PREFIX*sms_relent_sent`
					(`user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`, `author_displayname`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
			');
	    $sql->execute([$userId, $sentmessagearr[0], $sentmessagearr[1], $sentmessagearr[2], $sentmessagearr[3], $sentmessagearr[4], $sentmessagearr[5], $sentmessagearr[6], 
                           $sentmessagearr[7], $textwithnl, $displayname]);
     }


     /**
      * @NoAdminRequired
      *
      */
     public function updatedeliverystatustel($ncuserfortelnyxdel, $messageid, $network, $messageprice, $messagestatus, $deliverystatus) {

	    $sqlupdateds = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_sent`
			SET `price` = ?, `status` = ?, `deliveryreceipt` = ?, `network` = ?
                        WHERE `message_id` = ? AND `user_id` = ? ');
	    $updateRes = $sqlupdateds->execute([$messageprice, $messagestatus, $deliverystatus, $network, $messageid, $ncuserfortelnyxdel]);
	    $updateRes->closeCursor();
     }


     /**
      * @NoAdminRequired
      *
      */
     public function updatedeliverystatusnex($ncuserforplivodel, $messageid, $networkcode, $messageprice, $mStatus, $deliverystatus) {

	    $sqlupdatedspl = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_sent`
			SET `price` = ?, `deliveryreceipt` = ?, `status` = ?, `network` = ?
                        WHERE `message_id` = ? AND `user_id` = ? ');
	    $updateResdspl = $sqlupdatedspl->execute([$messageprice, $deliverystatus, $mStatus, $networkcode, $messageid, $ncuserforplivodel]);
	    $updateResdspl->closeCursor();
     }


     /**
      * @NoAdminRequired
      *
      */
     public function updatedeliverystatustwil($ncuserfortwildel, $messageid, $networkcode, $messageprice, $mStatus, $deliverystatus) {

	    $sqlupdatedstw = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_sent`
			SET `price` = ?, `deliveryreceipt` = ?, `status` = ?, `network` = ?
                        WHERE `message_id` = ? AND `user_id` = ? ');
	    $updateResdstw = $sqlupdatedstw->execute([$messageprice, $deliverystatus, $mStatus, $networkcode, $messageid, $ncuserfortwildel]);
	    $updateResdstw->closeCursor();
     }


     /**
      * @NoAdminRequired
      *
      */
     public function updatedeliverystatusflow($ncuserforflowdel, $messageid, $networkcode, $messageprice, $mStatus, $deliverystatus) {

	    $sqlupdatedsfl = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_sent`
			SET `price` = ?, `deliveryreceipt` = ?, `status` = ?, `network` = ?
                        WHERE `message_id` = ? AND `user_id` = ? ');
	    $updateResdsfl = $sqlupdatedsfl->execute([$messageprice, $deliverystatus, $mStatus, $networkcode, $messageid, $ncuserforflowdel]);
	    $updateResdsfl->closeCursor();
     }


     /**
      * @NoAdminRequired
      */
     public function getreceivedtable($userId) {

        // Get the user's preferences from the settings
        $getgamcheckrc = $this->connection->prepare('
		       SELECT `user_id`, `show_all_messages`, `show_display_names`
		       FROM  `*PREFIX*sms_relent_settings` WHERE `user_id` = ?');
        $getgamcheckrcres = $getgamcheckrc->execute([$userId]);
        $getcrgamsrcpref = $getgamcheckrcres->fetch();
        $crgamsrcpref = $getcrgamsrcpref['show_all_messages'];
        $crdnmsrcpref = $getcrgamsrcpref['show_display_names'];
        $getgamcheckrcres->closeCursor();


        // Collect the users with whom the current admin is sharing his API keys and whose messages he will be able to see
        if ($crgamsrcpref == 1 && $this->groupManager->isAdmin($userId)) {

            // Get the groups and users that were allowed access to the API keys
            $getgrps = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed`, `tnx_users_allowed`, `plv_groups_allowed`, `plv_users_allowed`,
                                                  `twl_groups_allowed`, `twl_users_allowed`, `flr_groups_allowed`, `flr_users_allowed` FROM `*PREFIX*sms_relent_subac`
                                                   WHERE `user_id` = ?');
            $getgrpsres = $getgrps->execute([$userId]);
            $getgrpsusr = $getgrpsres->fetch();
            $getgrpsres->closeCursor();

            if ($getgrpsusr) {

                if ($getgrpsusr['tnx_users_allowed']) { $tnxusers = explode("|", $getgrpsusr['tnx_users_allowed']); } else { $tnxusers = []; }
                if ($getgrpsusr['plv_users_allowed']) { $plvusers = explode("|", $getgrpsusr['plv_users_allowed']); } else { $plvusers = []; }
                if ($getgrpsusr['twl_users_allowed']) { $twlusers = explode("|", $getgrpsusr['twl_users_allowed']); } else { $twlusers = []; }
                if ($getgrpsusr['flr_users_allowed']) { $flrusers = explode("|", $getgrpsusr['flr_users_allowed']); } else { $flrusers = []; }

                $allwdusersarr = array_merge($tnxusers, $plvusers, $twlusers, $flrusers);
                $allwdusersunq = array_filter(array_unique($allwdusersarr));

                if ($getgrpsusr['tnx_groups_allowed']) { $tnxgroups = explode("|", $getgrpsusr['tnx_groups_allowed']); } else { $tnxgroups = []; }
                if ($getgrpsusr['plv_groups_allowed']) { $plvgroups = explode("|", $getgrpsusr['plv_groups_allowed']); } else { $plvgroups = []; }
                if ($getgrpsusr['twl_groups_allowed']) { $twlgroups = explode("|", $getgrpsusr['twl_groups_allowed']); } else { $twlgroups = []; }
                if ($getgrpsusr['flr_groups_allowed']) { $flrgroups = explode("|", $getgrpsusr['flr_groups_allowed']); } else { $flrgroups = []; }

                $allwdgroupsarr = array_merge($tnxgroups, $plvgroups, $twlgroups, $flrgroups);
                $allwdgroupsunq = array_filter(array_unique($allwdgroupsarr));

            } else {
                $allwdusersunq = [];
                $allwdgroupsunq = [];
            }

            // Get the username for each Display Name of the allowed users
            $allwdusersfnl = [];
            foreach ($allwdusersunq as $alwdusrkey => $alwdusrvalue) {

                         $getacdatausrnm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		         $getacdatausrnmres = $getacdatausrnm->execute(['displayname', $alwdusrvalue]);
		         $acdatausrname = $getacdatausrnmres->fetch();
                         if ($acdatausrname) {
                             $allwdusersfnl[] = $acdatausrname['uid'];
                         }
                         $getacdatausrnmres->closeCursor();
            }

            // Get the users from all the allowed groups
            $allwdusersgrpmlt = [];
            foreach ($allwdgroupsunq as $prgrpkey => $prgrpvalue) {

                     // Get all the users that belong to the current group, if the current group is different from 'admin'
                     if ($prgrpvalue != 'admin') {
                         $getusringroup = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
		         $getusringroupres = $getusringroup->execute([$prgrpvalue]);

		         while ($getusrname = $getusringroupres->fetch()) {

                                $allwdusersgrpmlt[] = $getusrname['uid'];
                         }
		         $getusringroupres->closeCursor();
                     }
            }
            $allwdusersgrpfnl = array_unique($allwdusersgrpmlt);
            
            $allusr = array_merge($allwdusersfnl, $allwdusersgrpfnl);
            $allusruniquest = array_unique($allusr);

            if ($allusruniquest) {
                array_unshift($allusruniquest, $userId);
                $allusruniquerc = $allusruniquest;
            } else { $allusruniquerc = [$userId]; }

            $procardatarcsec = "'" . implode("','", $allusruniquerc) . "'";

        }

        // If the user is an admin and he wants to see his messages and the messages of all the users with whom he shares his API keys
        if ($crgamsrcpref == 1 && $this->groupManager->isAdmin($userId)) {

            if ($crdnmsrcpref == 1) {

                $rcresult = $this->connection->executeQuery("
                                   SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `author_displayname`, `internal_sender`
			           FROM `*PREFIX*sms_relent_received` 
                                   WHERE `user_id` IN (" . $procardatarcsec . ")");

            } else {

                $rcresult = $this->connection->executeQuery("
			SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `internal_sender`
			FROM `*PREFIX*sms_relent_received` 
                        WHERE `user_id` IN (" . $procardatarcsec . ")");
            }

        // If the user is an admin and he wants to see only his messages
        } elseif ($crgamsrcpref == 0 && $this->groupManager->isAdmin($userId)) {

            if ($crdnmsrcpref == 1) {
	        $getrectable = $this->connection->prepare('
			SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `author_displayname`, `internal_sender`
			FROM `*PREFIX*sms_relent_received` 
                        WHERE `user_id` = ?');
	        $rcresult = $getrectable->execute([$userId]);
            } else {
	        $getrectable = $this->connection->prepare('
			SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `internal_sender`
			FROM `*PREFIX*sms_relent_received` 
                        WHERE `user_id` = ?');
	        $rcresult = $getrectable->execute([$userId]);
            }

        // If the user is not an admin 
        } elseif (!$this->groupManager->isAdmin($userId)) {

	    // Get the Display Name of the current user
	    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
	    $getacdatadnres = $getacdatadn->execute([$userId, 'displayname']);
	    $acdatausrdnadm = $getacdatadnres->fetch();
	    $cruserdname = $acdatausrdnadm['value'];
	    $getacdatadnres->closeCursor();

            // Get the groups to which the current user belongs
            $getusrgrp = $this->connection->prepare('
	          SELECT `gid`, `uid`
	          FROM  `*PREFIX*group_user`
                  WHERE `uid` = ?');
            $getusrgrpres = $getusrgrp->execute([$userId]);

            $usergrps = [];
            while ($fetchedgrps = $getusrgrpres->fetch()) {
                   $usergrps[] = $fetchedgrps['gid'];
            }
            $getusrgrpres->closeCursor();

            // Get the restrictions from the 'sms_relent_restrict' table
            $getrestr = $this->connection->prepare('
		       SELECT `phone_number`, `groups`, `users`
		       FROM  `*PREFIX*sms_relent_restrict`');
            $getrestrres = $getrestr->execute();

            $restrdata = [];
            while ($restrfetched = $getrestrres->fetch()) {
                   $restrdata[] = $restrfetched;
            }
            $getrestrres->closeCursor();

            // Get the phone numbers that the user is allowed/not allowed to use
            if ($restrdata) {

                $restrPhoneNmbrs = [];
                $allowedPhoneNmbrs = [];
                foreach ($restrdata as $rskey => $rsvalue) {

                         $chck = 0;
                         $restrgrparr = explode("|", $rsvalue['groups']);
                         foreach ($restrgrparr as $rkey => $rvalue) {
                                  if ($rvalue) {
                                      if (strpos(implode("|", $usergrps), $rvalue) !== false) { $chck++; }
                                  }
                         }
                         if (strpos($rsvalue['users'], $cruserdname) !== false) { $chck++; }

                         if ($chck == 0) {
                             $restrPhoneNmbrs[] = $rsvalue['phone_number'];
                         }
                }

		$allowedPhNmbrs = $this->getsmsnumbers($userId);

		foreach ($allowedPhNmbrs as $apnkey => $apnvalue) {
			 $crphnmbr = explode(": ", $apnvalue);
			 if ($crphnmbr[0] == 'Tx') {
			     $allowedPhoneNmbrs[] = 'Telnyx: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Pl') {
			     $allowedPhoneNmbrs[] = 'Plivo: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Tw') {
			     $allowedPhoneNmbrs[] = 'Twilio: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Fl') {
			     $allowedPhoneNmbrs[] = 'Flowroute: ' . $crphnmbr[1];
			 }
		}

                $procalwduid = $allowedPhoneNmbrs;
                $procalwduidsec = "'" . implode("','", $procalwduid) . "'";

                if ($crdnmsrcpref == 1) {

                    if ($procalwduidsec != "''") {

                        $rcresult = $this->connection->executeQuery("
			                   SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `author_displayname`, `internal_sender`
			                   FROM `*PREFIX*sms_relent_received`
			                   WHERE `user_id` = '$userId' OR `to` IN (" . $procalwduidsec . ")");

                    } else {

	                $getrectable = $this->connection->prepare('
			    SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `author_displayname`, `internal_sender`
			    FROM `*PREFIX*sms_relent_received`
			    WHERE `user_id` = ?');
	                $rcresult = $getrectable->execute([$userId]);
                    }

                } else {

                    if ($procalwduidsec) {

                        $rcresult = $this->connection->executeQuery("
			    SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `internal_sender`
			    FROM `*PREFIX*sms_relent_received`
			    WHERE `user_id` = '$userId' OR `to` IN (" . $procalwduidsec . ")");
                    } else {
	                $getrectable = $this->connection->prepare('
			    SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `internal_sender`
			    FROM `*PREFIX*sms_relent_received`
			    WHERE `user_id` = ?');
	                $rcresult = $getrectable->execute([$userId]);
                    }
                }

            } else {

		$allowedPhNmbrs = $this->getsmsnumbers($userId);

		foreach ($allowedPhNmbrs as $apnkey => $apnvalue) {
			 $crphnmbr = explode(": ", $apnvalue);
			 if ($crphnmbr[0] == 'Tx') {
			     $allowedPhoneNmbrs[] = 'Telnyx: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Pl') {
			     $allowedPhoneNmbrs[] = 'Plivo: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Tw') {
			     $allowedPhoneNmbrs[] = 'Twilio: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Fl') {
			     $allowedPhoneNmbrs[] = 'Flowroute: ' . $crphnmbr[1];
			 }
		}

                $procalwduid = $allowedPhoneNmbrs;
                $procalwduidsec = "'" . implode("','", $procalwduid) . "'";

                if ($crdnmsrcpref == 1) {

                    if ($procalwduidsec != "''") {

                        $rcresult = $this->connection->executeQuery("
			                   SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `author_displayname`, `internal_sender`
			                   FROM `*PREFIX*sms_relent_received`
			                   WHERE `user_id` = '$userId' OR `to` IN (" . $procalwduidsec . ")");

                    } else {

	                $getrectable = $this->connection->prepare('
			    SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `author_displayname`, `internal_sender`
			    FROM `*PREFIX*sms_relent_received`
			    WHERE `user_id` = ?');
	                $rcresult = $getrectable->execute([$userId]);
                    }

                } else {

                    if ($procalwduidsec) {

                        $rcresult = $this->connection->executeQuery("
			    SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `internal_sender`
			    FROM `*PREFIX*sms_relent_received`
			    WHERE `user_id` = '$userId' OR `to` IN (" . $procalwduidsec . ")");
                    } else {
	                $getrectable = $this->connection->prepare('
			    SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `internal_sender`
			    FROM `*PREFIX*sms_relent_received`
			    WHERE `user_id` = ?');
	                $rcresult = $getrectable->execute([$userId]);
                    }
                }
            }
        }

        $recdatatable = [];
        while ($rowfetched = $rcresult->fetch()) {
               $recdatatable[] = $rowfetched;
        }
	$rcresult->closeCursor();

        $recdatafromdb = $recdatatable;


        if ($this->groupManager->isAdmin($userId)) {

              $recdatafdb = ['datarows' => $recdatafromdb, 'showdispnm' => $crdnmsrcpref];
              return $recdatafdb;

        } else {

            if ($restrdata) {

                // Clean the 'not allowed' phone numbers from tags
                $restrPhfin = [];
                foreach ($restrPhoneNmbrs as $phkey => $phvalue) {

                    $restrpharr = explode(": ", $phvalue);
                    $restrPhfin[] = $restrpharr[1];
                }

                // Assemble the array of message rows that excludes the rows for the 'not allowed' phone numbers
                foreach ($recdatafromdb as $mdkey => $mdvalue) {

                    if (str_contains($mdvalue['to'], "+")) {
                        $fromnmbrarr = explode("+", $mdvalue['to']);
                        if (in_array("+" . $fromnmbrarr[1], $restrPhfin)) {
                            unset($recdatafromdb[$mdkey]);
                        }
                    } else {
                        $tonmbrarr = explode(": ", $mdvalue['to']);
                        if (count($tonmbrarr) == 2) {
                            $tonmbrtbcmprd = $tonmbrarr[1];
                        } else {
                            $tonmbrtbcmprd = $tonmbrarr[0];
                        }
                        if (in_array($tonmbrtbcmprd, $restrPhfin)) {
                            unset($recdatafromdb[$mdkey]);
                        }
                    }
                }

                $recdatafdbproc = array_values($recdatafromdb);

                $recdataproc = ['datarows' => $recdatafdbproc, 'showdispnm' => $crdnmsrcpref];
                return $recdataproc;

            } else {

                $recdatafdb = ['datarows' => $recdatafromdb, 'showdispnm' => $crdnmsrcpref];
                return $recdatafdb;
            }
        }
     }


     /**
      * @NoAdminRequired
      */
     public function getreceivedtablefordel($userId) {

        if ($this->groupManager->isAdmin($userId)) {

            $getrecfordl = $this->connection->prepare('
			SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `message`, `author_displayname`, `internal_sender`
			FROM  `*PREFIX*sms_relent_received`
			WHERE `user_id` = ?');
	    $resultdl = $getrecfordl->execute([$userId]);

            $recdatatable = [];
            while ($rowfetched = $resultdl->fetch()) {
                   $recdatatable[] = $rowfetched;
            }
            $resultdl->closeCursor();

            $recdatafromdb = $recdatatable;

            return $recdatafromdb;

        } else { return "not permitted"; }
     }


     /**
      * @NoAdminRequired
      */
     public function removerecrows($userId, $recmessagedbIDs) {

        foreach ($recmessagedbIDs as $key => $rowtodel) {
		 $query = $this->connection->prepare('
		       DELETE FROM `*PREFIX*sms_relent_received`
		       WHERE `id` = ?');
		 $deleteResult = $query->execute([$rowtodel]);
		 $deleteResult->closeCursor();
        }

	$sqlupdate = $this->connection->prepare('
                  SET @resetrec = 0;
		  UPDATE `*PREFIX*sms_relent_received`
		  SET `id` = @resetrec := @resetrec + 1;
                  ALTER TABLE `*PREFIX*sms_relent_received` auto_increment=1;');
	$updateRes = $sqlupdate->execute();
	$updateRes->closeCursor();
     }


     /**
      * @NoAdminRequired
      */
     public function getsenttable($userId) {

        // Get the user's preferences from the settings
        $getgamcheck = $this->connection->prepare('
		       SELECT `user_id`, `show_all_messages`, `show_display_names`
		       FROM  `*PREFIX*sms_relent_settings` WHERE `user_id` = ?');
        $getgamcheckres = $getgamcheck->execute([$userId]);
        $getcrgamspref = $getgamcheckres->fetch();
        $crgamspref = $getcrgamspref['show_all_messages'];
        $crdnamespref = $getcrgamspref['show_display_names'];
        $getgamcheckres->closeCursor();


        // Collect the users with whom the current admin is sharing his API keys and whose messages he will be able to see
        if ($crgamspref == 1 && $this->groupManager->isAdmin($userId)) {

            // Get the groups and users that were allowed access to the API keys
            $getgrps = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed`, `tnx_users_allowed`, `plv_groups_allowed`, `plv_users_allowed`,
                                                  `twl_groups_allowed`, `twl_users_allowed`, `flr_groups_allowed`, `flr_users_allowed` FROM `*PREFIX*sms_relent_subac`
                                                   WHERE `user_id` = ?');
            $getgrpsres = $getgrps->execute([$userId]);
            $getgrpsusr = $getgrpsres->fetch();
            $getgrpsres->closeCursor();

            if ($getgrpsusr) {

                if ($getgrpsusr['tnx_users_allowed']) { $tnxusers = explode("|", $getgrpsusr['tnx_users_allowed']); } else { $tnxusers = []; }
                if ($getgrpsusr['plv_users_allowed']) { $plvusers = explode("|", $getgrpsusr['plv_users_allowed']); } else { $plvusers = []; }
                if ($getgrpsusr['twl_users_allowed']) { $twlusers = explode("|", $getgrpsusr['twl_users_allowed']); } else { $twlusers = []; }
                if ($getgrpsusr['flr_users_allowed']) { $flrusers = explode("|", $getgrpsusr['flr_users_allowed']); } else { $flrusers = []; }

                $allwdusersarr = array_merge($tnxusers, $plvusers, $twlusers, $flrusers);
                $allwdusersunq = array_filter(array_unique($allwdusersarr));

                if ($getgrpsusr['tnx_groups_allowed']) { $tnxgroups = explode("|", $getgrpsusr['tnx_groups_allowed']); } else { $tnxgroups = []; }
                if ($getgrpsusr['plv_groups_allowed']) { $plvgroups = explode("|", $getgrpsusr['plv_groups_allowed']); } else { $plvgroups = []; }
                if ($getgrpsusr['twl_groups_allowed']) { $twlgroups = explode("|", $getgrpsusr['twl_groups_allowed']); } else { $twlgroups = []; }
                if ($getgrpsusr['flr_groups_allowed']) { $flrgroups = explode("|", $getgrpsusr['flr_groups_allowed']); } else { $flrgroups = []; }

                $allwdgroupsarr = array_merge($tnxgroups, $plvgroups, $twlgroups, $flrgroups);
                $allwdgroupsunq = array_filter(array_unique($allwdgroupsarr));

            } else {
                $allwdusersunq = [];
                $allwdgroupsunq = [];
            }

            // Get the username for each Display Name of the allowed users
            $allwdusersfnl = [];
            foreach ($allwdusersunq as $alwdusrkey => $alwdusrvalue) {

                         $getacdatausrnm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		         $getacdatausrnmres = $getacdatausrnm->execute(['displayname', $alwdusrvalue]);
		         $acdatausrname = $getacdatausrnmres->fetch();
                         if ($acdatausrname) {
                             $allwdusersfnl[] = $acdatausrname['uid'];
                         }
                         $getacdatausrnmres->closeCursor();
            }

            // Get the users from all the allowed groups
            $allwdusersgrpmlt = [];
            foreach ($allwdgroupsunq as $prgrpkey => $prgrpvalue) {

                     // Get all the users that belong to the current group, if the current group is different from 'admin'
                     if ($prgrpvalue != 'admin') {
                         $getusringroup = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
		         $getusringroupres = $getusringroup->execute([$prgrpvalue]);

		         while ($getusrname = $getusringroupres->fetch()) {

                                $allwdusersgrpmlt[] = $getusrname['uid'];
                         }
		         $getusringroupres->closeCursor();
                     }
            }
            $allwdusersgrpfnl = array_unique($allwdusersgrpmlt);
            
            $allusr = array_merge($allwdusersfnl, $allwdusersgrpfnl);
            $allusruniquest = array_unique($allusr);

            if ($allusruniquest) {
                array_unshift($allusruniquest, $userId);
                $allusrunique = $allusruniquest;
            } else { $allusrunique = [$userId]; }

            $allusruniquesec = "'" . implode("','", $allusrunique) . "'";
        }

        // If the user is an admin and he wants to see his messages and the messages of all the users with whom he shares his API keys
        if ($crgamspref == 1 && $this->groupManager->isAdmin($userId)) {

            if ($crdnamespref == 1) {

                $resultsent = $this->connection->executeQuery("
                       SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`, `author_displayname`
		       FROM  `*PREFIX*sms_relent_sent` 
                       WHERE `user_id` IN (" . $allusruniquesec . ")");
            } else {

                $resultsent = $this->connection->executeQuery("
                       SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`
		       FROM  `*PREFIX*sms_relent_sent`
                       WHERE `user_id` IN (" . $allusruniquesec . ")");
            }

        // If the user is an admin and he wants to see only his messages
        } elseif ($crgamspref == 0 && $this->groupManager->isAdmin($userId)) {

            if ($crdnamespref == 1) {
                $getsenttbl = $this->connection->prepare('
		       SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`, `author_displayname`
		       FROM  `*PREFIX*sms_relent_sent` 
                       WHERE `user_id` = ?');
                $resultsent = $getsenttbl->execute([$userId]);
            } else {
                $getsenttbl = $this->connection->prepare('
		       SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`
		       FROM  `*PREFIX*sms_relent_sent` 
                       WHERE `user_id` = ?');
                $resultsent = $getsenttbl->execute([$userId]);
            }

        // If the user is not an admin 
        } elseif (!$this->groupManager->isAdmin($userId)) {

	    // Get the Display Name of the current user
	    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
	    $getacdatadnres = $getacdatadn->execute([$userId, 'displayname']);
	    $acdatausrdnadm = $getacdatadnres->fetch();
	    $cruserdname = $acdatausrdnadm['value'];
	    $getacdatadnres->closeCursor();

            // Get the groups to which the current user belongs
            $getusrgrp = $this->connection->prepare('
	          SELECT `gid`, `uid`
	          FROM  `*PREFIX*group_user`
                  WHERE `uid` = ?');
            $getusrgrpres = $getusrgrp->execute([$userId]);

            $usergrps = [];
            while ($fetchedgrps = $getusrgrpres->fetch()) {
                   $usergrps[] = $fetchedgrps['gid'];
            }
            $getusrgrpres->closeCursor();

            // Get the restrictions from the 'sms_relent_restrict' table
            $getrestr = $this->connection->prepare('
		       SELECT `phone_number`, `groups`, `users`
		       FROM  `*PREFIX*sms_relent_restrict`');
            $getrestrres = $getrestr->execute();

            $restrdata = [];
            while ($restrfetched = $getrestrres->fetch()) {
                   $restrdata[] = $restrfetched;
            }
            $getrestrres->closeCursor();

            // Get the phone numbers that the user is allowed/not allowed to use
            if ($restrdata) {

                $restrPhoneNmbrs = [];
                $allowedPhoneNmbrs = [];
                foreach ($restrdata as $rskey => $rsvalue) {

                         $chck = 0;
                         $restrgrparr = explode("|", $rsvalue['groups']);
                         foreach ($restrgrparr as $rkey => $rvalue) {
                                  if ($rvalue) {
                                      if (strpos(implode("|", $usergrps), $rvalue) !== false) { $chck++; }
                                  }
                         }
                         if (strpos($rsvalue['users'], $cruserdname) !== false) { $chck++; }

                         if ($chck == 0) { 
                             $restrPhoneNmbrs[] = $rsvalue['phone_number']; 
                         }
                }

		$allowedPhNmbrs = $this->getsmsnumbers($userId);

		foreach ($allowedPhNmbrs as $apnkey => $apnvalue) {
			 $crphnmbr = explode(": ", $apnvalue);
			 if ($crphnmbr[0] == 'Tx') {
			     $allowedPhoneNmbrs[] = 'Telnyx: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Pl') {
			     $allowedPhoneNmbrs[] = 'Plivo: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Tw') {
			     $allowedPhoneNmbrs[] = 'Twilio: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Fl') {
			     $allowedPhoneNmbrs[] = 'Flowroute: ' . $crphnmbr[1];
			 }
		}

                $procalwduid = $allowedPhoneNmbrs;
                $procalwduidsec = "'" . implode("','", $procalwduid) . "'";

                if ($crdnamespref == 1) {
                    if ($procalwduidsec != "''") {

                        $resultsent = $this->connection->executeQuery("
		            SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`, `author_displayname`
		            FROM `*PREFIX*sms_relent_sent`
			    WHERE `user_id` = '$userId' OR `from` IN (" . $procalwduidsec . ")");
                    } else {
	                $getsenttbl = $this->connection->prepare('
		            SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`, `author_displayname`
		            FROM `*PREFIX*sms_relent_sent`
			    WHERE `user_id` = ?');
	                $resultsent = $getsenttbl->execute([$userId]);
                    }
                } else {
                    if ($procalwduidsec != "''") {

                        $resultsent = $this->connection->executeQuery("
		            SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`
		            FROM `*PREFIX*sms_relent_sent`
			    WHERE `user_id` = '$userId' OR `from` IN (" . $procalwduidsec . ")");

                    } else {
	                $getsenttbl = $this->connection->prepare('
		            SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`
		            FROM `*PREFIX*sms_relent_sent`
			    WHERE `user_id` = ?');
	                $resultsent = $getsenttbl->execute([$userId]);
                    }
                }

            } else {

                if ($crdnamespref == 1) {
                    $getsenttbl = $this->connection->prepare('
		       SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`, `author_displayname`
		       FROM `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ?');
                    $resultsent = $getsenttbl->execute([$userId]);
                } else {
                    $getsenttbl = $this->connection->prepare('
		       SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`
		       FROM `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ?');
                    $resultsent = $getsenttbl->execute([$userId]);
                }
            }
        }


        $sentdatatable = [];
        while ($rowfetched = $resultsent->fetch()){
               $sentdatatable[] = $rowfetched;
        }
        $resultsent->closeCursor();

        $sentdatafromdb = $sentdatatable;


        if ($this->groupManager->isAdmin($userId)) {

            $sentdatafdb = ['datarows' => $sentdatafromdb, 'showdispnm' => $crdnamespref];
            return $sentdatafdb;

        } else {

            if ($restrdata) {

                // Clean the phone numbers from tags
                $restrPhfin = [];
                foreach ($restrPhoneNmbrs as $phkey => $phvalue) {

                    $restrpharr = explode(": ", $phvalue);
                    $restrPhfin[] = $restrpharr[1];
                }

                // Assemble the array of message rows that excludes the rows for the restricted phone numbers
                foreach ($sentdatafromdb as $smdkey => $smdvalue) {

                    if (str_contains($smdvalue['from'], "+")) {
                        $fromnmbrarr = explode("+", $smdvalue['from']);
                        if (in_array("+" . $fromnmbrarr[1], $restrPhfin)) {
                            unset($sentdatafromdb[$smdkey]);
                        }
                    } else {
                        $frmnmbrarr = explode(": ", $smdvalue['from']);
                        if (count($frmnmbrarr) == 2) {
                            $nmbtbcmprd = $frmnmbrarr[1];
                        } else { 
                            $nmbtbcmprd = $frmnmbrarr[0];
                        }

                        if (in_array($nmbtbcmprd, $restrPhfin)) {
                            unset($sentdatafromdb[$smdkey]);
                        }
                    }
                }

                $sentdatadbproc = array_values($sentdatafromdb);

                $sentdatafdb = ['datarows' => $sentdatadbproc, 'showdispnm' => $crdnamespref];
                return $sentdatafdb;

            } else {

                $sentdatafdb = ['datarows' => $sentdatafromdb, 'showdispnm' => $crdnamespref];
                return $sentdatafdb;
            }
        }
     }


     /**
      * @NoAdminRequired
      */
     public function getsenttablefordel($userId) {

        if ($this->groupManager->isAdmin($userId)) {

            $getsenttbldel = $this->connection->prepare('
		          SELECT `id`, `user_id`, `message_id`, `date`, `from`, `to`, `network`, `price`, `status`, `deliveryreceipt`, `message`, `author_displayname`
		          FROM  `*PREFIX*sms_relent_sent`
		          WHERE `user_id` = ?');
            $resultsentdl = $getsenttbldel->execute([$userId]);

            $sentdatatable = [];
            while ($rowfetched = $resultsentdl->fetch()){
                   $sentdatatable[] = $rowfetched;
            }
            $resultsentdl->closeCursor();

            $sentdatafromdb = $sentdatatable;

            return $sentdatafromdb;

        } else { return "not permitted"; }
     }


     /**
      * @NoAdminRequired
      */
     public function removesentrows($userId, $sentmessagedbIDs) {

        foreach ($sentmessagedbIDs as $key => $sentrowtodel) {
		 $query = $this->connection->prepare('
		       DELETE FROM `*PREFIX*sms_relent_sent`
		       WHERE `id` = ?');
		 $deleteResult = $query->execute([$sentrowtodel]);
		 $deleteResult->closeCursor();
        }

	$sqlupdate = $this->connection->prepare('
                  SET @resetsent = 0;
		  UPDATE `*PREFIX*sms_relent_sent`
		  SET `id` = @resetsent := @resetsent + 1;
                  ALTER TABLE `*PREFIX*sms_relent_sent` auto_increment=1;');
	$updateRes = $sqlupdate->execute();
	$updateRes->closeCursor();
     }


     /**
      * @NoAdminRequired
      */
     public function getgroupedtable($userId) {


        // Get the user's preferences from the settings
        $getpref = $this->connection->prepare('
		       SELECT `user_id`, `show_all_messages`
		       FROM  `*PREFIX*sms_relent_settings` WHERE `user_id` = ?');
        $getprefres = $getpref->execute([$userId]);
        $getprefresdata = $getprefres->fetch();
        $crsampref = $getprefresdata['show_all_messages'];
        $getprefres->closeCursor();


        // Collect the users with whom the current admin is sharing his API keys and whose messages he will be able to see
        if ($crsampref == 1 && $this->groupManager->isAdmin($userId)) {

            // Get the groups and users that were allowed access to the API keys
            $getgrps = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed`, `tnx_users_allowed`, `plv_groups_allowed`, `plv_users_allowed`,
                                                  `twl_groups_allowed`, `twl_users_allowed`, `flr_groups_allowed`, `flr_users_allowed` FROM `*PREFIX*sms_relent_subac`
                                                   WHERE `user_id` = ?');
            $getgrpsres = $getgrps->execute([$userId]);
            $getgrpsusr = $getgrpsres->fetch();
            $getgrpsres->closeCursor();

            if ($getgrpsusr) {

                if ($getgrpsusr['tnx_users_allowed']) { $tnxusers = explode("|", $getgrpsusr['tnx_users_allowed']); } else { $tnxusers = []; }
                if ($getgrpsusr['plv_users_allowed']) { $plvusers = explode("|", $getgrpsusr['plv_users_allowed']); } else { $plvusers = []; }
                if ($getgrpsusr['twl_users_allowed']) { $twlusers = explode("|", $getgrpsusr['twl_users_allowed']); } else { $twlusers = []; }
                if ($getgrpsusr['flr_users_allowed']) { $flrusers = explode("|", $getgrpsusr['flr_users_allowed']); } else { $flrusers = []; }

                $allwdusersarr = array_merge($tnxusers, $plvusers, $twlusers, $flrusers);
                $allwdusersunq = array_filter(array_unique($allwdusersarr));

                if ($getgrpsusr['tnx_groups_allowed']) { $tnxgroups = explode("|", $getgrpsusr['tnx_groups_allowed']); } else { $tnxgroups = []; }
                if ($getgrpsusr['plv_groups_allowed']) { $plvgroups = explode("|", $getgrpsusr['plv_groups_allowed']); } else { $plvgroups = []; }
                if ($getgrpsusr['twl_groups_allowed']) { $twlgroups = explode("|", $getgrpsusr['twl_groups_allowed']); } else { $twlgroups = []; }
                if ($getgrpsusr['flr_groups_allowed']) { $flrgroups = explode("|", $getgrpsusr['flr_groups_allowed']); } else { $flrgroups = []; }

                $allwdgroupsarr = array_merge($tnxgroups, $plvgroups, $twlgroups, $flrgroups);
                $allwdgroupsunq = array_filter(array_unique($allwdgroupsarr));

            } else {
                $allwdusersunq = [];
                $allwdgroupsunq = [];
            }

            // Get the username for each Display Name of the allowed users
            $allwdusersfnl = [];
            foreach ($allwdusersunq as $alwdusrkey => $alwdusrvalue) {

                         $getacdatausrnm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		         $getacdatausrnmres = $getacdatausrnm->execute(['displayname', $alwdusrvalue]);
		         $acdatausrname = $getacdatausrnmres->fetch();
                         if ($acdatausrname) {
                             $allwdusersfnl[] = $acdatausrname['uid'];
                         }
                         $getacdatausrnmres->closeCursor();
            }

            // Get the users from all the allowed groups
            $allwdusersgrpmlt = [];
            foreach ($allwdgroupsunq as $prgrpkey => $prgrpvalue) {

                     // Get all the users that belong to the current group, if the current group is different from 'admin'
                     if ($prgrpvalue != 'admin') {
                         $getusringroup = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
		         $getusringroupres = $getusringroup->execute([$prgrpvalue]);

		         while ($getusrname = $getusringroupres->fetch()) {

                                $allwdusersgrpmlt[] = $getusrname['uid'];
                         }
		         $getusringroupres->closeCursor();
                     }
            }
            $allwdusersgrpfnl = array_unique($allwdusersgrpmlt);
            
            $allusr = array_merge($allwdusersfnl, $allwdusersgrpfnl);
            $allusruniquest = array_unique($allusr);

            if ($allusruniquest) {
                array_unshift($allusruniquest, $userId);
                $allusruniquegr = $allusruniquest;
            } else { $allusruniquegr = [$userId]; }

            $allusruniquegrsec = "'" . implode("','", $allusruniquegr) . "'";
        }

        // Get received messages

        // If the user is an admin and he wants to see his messages and the messages of all the users with whom he shares his API keys
        if ($crsampref == 1 && $this->groupManager->isAdmin($userId)) {

            $getrecmsgsres = $this->connection->executeQuery("
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received` WHERE `user_id` IN (" . $allusruniquegrsec . ")");

        // If the user is an admin and he wants to see only his messages
        } elseif ($crsampref == 0 && $this->groupManager->isAdmin($userId)) {

            $getrecmsgs = $this->connection->prepare('
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received` WHERE `user_id` = ?');
	    $getrecmsgsres = $getrecmsgs->execute([$userId]);

        // If the user is not an admin 
        } elseif (!$this->groupManager->isAdmin($userId)) {

	    // Get the Display Name of the current user
	    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
	    $getacdatadnres = $getacdatadn->execute([$userId, 'displayname']);
	    $acdatausrdnadm = $getacdatadnres->fetch();
	    $cruserdname = $acdatausrdnadm['value'];
	    $getacdatadnres->closeCursor();

            // Get the groups to which the current user belongs
            $getusrgrp = $this->connection->prepare('
	          SELECT `gid`, `uid`
	          FROM  `*PREFIX*group_user`
                  WHERE `uid` = ?');
            $getusrgrpres = $getusrgrp->execute([$userId]);

            $usergrps = [];
            while ($fetchedgrps = $getusrgrpres->fetch()) {
                   $usergrps[] = $fetchedgrps['gid'];
            }
            $getusrgrpres->closeCursor();

            // Get the restrictions from the 'sms_relent_restrict' table
            $getrestr = $this->connection->prepare('
		       SELECT `phone_number`, `groups`, `users`
		       FROM  `*PREFIX*sms_relent_restrict`');
            $getrestrres = $getrestr->execute();

            $restrdata = [];
            while ($restrfetched = $getrestrres->fetch()) {
                   $restrdata[] = $restrfetched;
            }
            $getrestrres->closeCursor();

            // Get the phone numbers that the user is allowed/not allowed to use
            if ($restrdata) {

                $restrPhoneNmbrs = [];
                $allowedPhoneNmbrs = [];
                foreach ($restrdata as $rskey => $rsvalue) {

                         $chck = 0;
                         $restrgrparr = explode("|", $rsvalue['groups']);
                         foreach ($restrgrparr as $rkey => $rvalue) {
                                  if ($rvalue) {
                                      if (strpos(implode("|", $usergrps), $rvalue) !== false) { $chck++; }
                                  }
                         }
                         if (strpos($rsvalue['users'], $cruserdname) !== false) { $chck++; }

                         if ($chck == 0) { 
                             $restrPhoneNmbrs[] = $rsvalue['phone_number']; 
                         }
                }

		$allowedPhNmbrs = $this->getsmsnumbers($userId);

		foreach ($allowedPhNmbrs as $apnkey => $apnvalue) {
			 $crphnmbr = explode(": ", $apnvalue);
			 if ($crphnmbr[0] == 'Tx') {
			     $allowedPhoneNmbrs[] = 'Telnyx: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Pl') {
			     $allowedPhoneNmbrs[] = 'Plivo: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Tw') {
			     $allowedPhoneNmbrs[] = 'Twilio: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Fl') {
			     $allowedPhoneNmbrs[] = 'Flowroute: ' . $crphnmbr[1];
			 }
		}

                $procalwduid = $allowedPhoneNmbrs;
                $procalwduidsec = "'" . implode("','", $procalwduid) . "'";

                if ($procalwduidsec != "''") {

                    $getrecmsgsres = $this->connection->executeQuery("
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE `user_id` = '$userId' OR `to` IN (" . $procalwduidsec . ")");

                } else {
	            $getrectable = $this->connection->prepare('
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE `user_id` = ?');
	            $getrecmsgsres = $getrectable->execute([$userId]);
                }

            } else {

		$allowedPhNmbrs = $this->getsmsnumbers($userId);

		foreach ($allowedPhNmbrs as $apnkey => $apnvalue) {
			 $crphnmbr = explode(": ", $apnvalue);
			 if ($crphnmbr[0] == 'Tx') {
			     $allowedPhoneNmbrs[] = 'Telnyx: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Pl') {
			     $allowedPhoneNmbrs[] = 'Plivo: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Tw') {
			     $allowedPhoneNmbrs[] = 'Twilio: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Fl') {
			     $allowedPhoneNmbrs[] = 'Flowroute: ' . $crphnmbr[1];
			 }
		}

                $procalwduid = $allowedPhoneNmbrs;
                $procalwduidsec = "'" . implode("','", $procalwduid) . "'";

                if ($procalwduidsec != "''") {

                    $getrecmsgsres = $this->connection->executeQuery("
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE `user_id` = '$userId' OR `to` IN (" . $procalwduidsec . ")");

                } else {
	            $getrectable = $this->connection->prepare('
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE `user_id` = ?');
	            $getrecmsgsres = $getrectable->execute([$userId]);
                }
            }
        }

        $recmsgs = [];
        while ($rcrowsfetch = $getrecmsgsres->fetch()) {
               $rcrowsfetch['deliveryreceipt'] = '';
               $rcrowsfetch['table'] = 'received';
               $recmsgs[] = $rcrowsfetch;
        }
	$getrecmsgsres->closeCursor();


        // Get sent messages

        // If the user is an admin and he wants to see his messages and the messages of all the users with whom he shares his API keys
        if ($crsampref == 1 && $this->groupManager->isAdmin($userId)) {

            $getsentmsgsres = $this->connection->executeQuery("
		       SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		       FROM  `*PREFIX*sms_relent_sent` 
                       WHERE `user_id` IN (" . $allusruniquegrsec . ")");

        // If the user is an admin and he wants to see only his messages
        } elseif ($crsampref == 0 && $this->groupManager->isAdmin($userId)) {

            $getsentmsgs = $this->connection->prepare('
		       SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ?');
            $getsentmsgsres = $getsentmsgs->execute([$userId]);

        // If the user is not an admin 
        } elseif (!$this->groupManager->isAdmin($userId)) {

            if ($restrdata) {
                if ($procalwduidsec != "''") {

	            $getsentmsgsres = $this->connection->executeQuery("
		        SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		        FROM  `*PREFIX*sms_relent_sent`
			WHERE `user_id` = '$userId' OR `from` IN (" . $procalwduidsec . ")");

                } else {
                    $getsentmsgs = $this->connection->prepare('
		        SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		        FROM  `*PREFIX*sms_relent_sent`
			WHERE `user_id` = ?');
	            $getsentmsgsres = $getsentmsgs->execute([$userId]);
                }

            } else {

                $getsentmsgs = $this->connection->prepare('
		       SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ?');
                $getsentmsgsres = $getsentmsgs->execute([$userId]);
            }
        }


        $sentmsgs = [];
        while ($rowfetchedsmsg = $getsentmsgsres->fetch()) {
               $rowfetchedsmsg['table'] = 'sent';
               $sentmsgs[] = $rowfetchedsmsg;
        }
        $getsentmsgsres->closeCursor();

        $groupedfromdb = array_merge($recmsgs, $sentmsgs);

        if ($this->groupManager->isAdmin($userId)) {

            return $groupedfromdb;

        } else {

            if ($restrdata) {

                // Clean the phone numbers from tags
                $restrPhfin = [];
                foreach ($restrPhoneNmbrs as $phkey => $phvalue) {

                    $restrpharr = explode(": ", $phvalue);
                    $restrPhfin[] = $restrpharr[1];
                }

                // Assemble the array of message rows that excludes the rows for the restricted phone numbers
                foreach ($groupedfromdb as $gmdkey => $gmdvalue) {

                         if ($gmdvalue['table'] == 'sent') {

                             if (str_contains($gmdvalue['from'], "+")) {
                                 $fromnmbrarr = explode("+", $gmdvalue['from']);
                                 if (in_array("+" . $fromnmbrarr[1], $restrPhfin)) {
                                     unset($groupedfromdb[$gmdkey]);
                                 }
                             } else {
                                 $frmnmbrarr = explode(": ", $gmdvalue['from']);
                                 if (count($frmnmbrarr) == 2) {
                                     $nmbtbcmprd = $frmnmbrarr[1];
                                 } else { 
                                     $nmbtbcmprd = $frmnmbrarr[0];
                                 }
                                 if (in_array($nmbtbcmprd, $restrPhfin)) {
                                     unset($groupedfromdb[$gmdkey]);
                                 }
                             }

                         } elseif ($gmdvalue['table'] == 'received') {

                             if (str_contains($gmdvalue['to'], "+")) {
                                 $fromnmbrarr = explode("+", $gmdvalue['to']);
                                 if (in_array("+" . $fromnmbrarr[1], $restrPhfin)) {
                                     unset($groupedfromdb[$gmdkey]);
                                 }
                             } else {
                                 $tonmbrarr = explode(": ", $gmdvalue['to']);
                                 if (count($tonmbrarr) == 2) {
                                     $tonmbrtbcmprd = $tonmbrarr[1];
                                 } else {
                                     $tonmbrtbcmprd = $tonmbrarr[0];
                                 }
                                 if (in_array($tonmbrtbcmprd, $restrPhfin)) {
                                     unset($groupedfromdb[$gmdkey]);
                                 }
                             }
                         }

                }

                $groupedfdbproc = array_values($groupedfromdb);

                return $groupedfdbproc;

            } else { return $groupedfromdb; }
        }
     }


     /**
      * @NoAdminRequired
      */
     public function getgroupedpernumber($userId, $phoneNumber) {

        $phoneNumberpr = "%" . $phoneNumber;

        // Get the user's preferences from the settings
        $getpref = $this->connection->prepare('
		       SELECT `user_id`, `show_all_messages`
		       FROM  `*PREFIX*sms_relent_settings` WHERE `user_id` = ?');
        $getprefres = $getpref->execute([$userId]);
        $getprefresdata = $getprefres->fetch();
        $crsampref = $getprefresdata['show_all_messages'];
        $getprefres->closeCursor();


        // Collect the users with whom the current admin is sharing his API keys and whose messages he will be able to see
        if ($crsampref == 1 && $this->groupManager->isAdmin($userId)) {

            // Get the groups and users that were allowed access to the API keys
            $getgrps = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed`, `tnx_users_allowed`, `plv_groups_allowed`, `plv_users_allowed`,
                                                  `twl_groups_allowed`, `twl_users_allowed`, `flr_groups_allowed`, `flr_users_allowed` FROM `*PREFIX*sms_relent_subac`
                                                   WHERE `user_id` = ?');
            $getgrpsres = $getgrps->execute([$userId]);
            $getgrpsusr = $getgrpsres->fetch();
            $getgrpsres->closeCursor();

            if ($getgrpsusr) {

                if ($getgrpsusr['tnx_users_allowed']) { $tnxusers = explode("|", $getgrpsusr['tnx_users_allowed']); } else { $tnxusers = []; }
                if ($getgrpsusr['plv_users_allowed']) { $plvusers = explode("|", $getgrpsusr['plv_users_allowed']); } else { $plvusers = []; }
                if ($getgrpsusr['twl_users_allowed']) { $twlusers = explode("|", $getgrpsusr['twl_users_allowed']); } else { $twlusers = []; }
                if ($getgrpsusr['flr_users_allowed']) { $flrusers = explode("|", $getgrpsusr['flr_users_allowed']); } else { $flrusers = []; }

                $allwdusersarr = array_merge($tnxusers, $plvusers, $twlusers, $flrusers);
                $allwdusersunq = array_filter(array_unique($allwdusersarr));

                if ($getgrpsusr['tnx_groups_allowed']) { $tnxgroups = explode("|", $getgrpsusr['tnx_groups_allowed']); } else { $tnxgroups = []; }
                if ($getgrpsusr['plv_groups_allowed']) { $plvgroups = explode("|", $getgrpsusr['plv_groups_allowed']); } else { $plvgroups = []; }
                if ($getgrpsusr['twl_groups_allowed']) { $twlgroups = explode("|", $getgrpsusr['twl_groups_allowed']); } else { $twlgroups = []; }
                if ($getgrpsusr['flr_groups_allowed']) { $flrgroups = explode("|", $getgrpsusr['flr_groups_allowed']); } else { $flrgroups = []; }

                $allwdgroupsarr = array_merge($tnxgroups, $plvgroups, $twlgroups, $flrgroups);
                $allwdgroupsunq = array_filter(array_unique($allwdgroupsarr));

            } else {
                $allwdusersunq = [];
                $allwdgroupsunq = [];
            }

            // Get the username for each Display Name of the allowed users
            $allwdusersfnl = [];
            foreach ($allwdusersunq as $alwdusrkey => $alwdusrvalue) {

                         $getacdatausrnm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		         $getacdatausrnmres = $getacdatausrnm->execute(['displayname', $alwdusrvalue]);
		         $acdatausrname = $getacdatausrnmres->fetch();
                         if ($acdatausrname) {
                             $allwdusersfnl[] = $acdatausrname['uid'];
                         }
                         $getacdatausrnmres->closeCursor();
            }

            // Get the users from all the allowed groups
            $allwdusersgrpmlt = [];
            foreach ($allwdgroupsunq as $prgrpkey => $prgrpvalue) {

                     // Get all the users that belong to the current group, if the current group is different from 'admin'
                     if ($prgrpvalue != 'admin') {
                         $getusringroup = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
		         $getusringroupres = $getusringroup->execute([$prgrpvalue]);

		         while ($getusrname = $getusringroupres->fetch()) {

                                $allwdusersgrpmlt[] = $getusrname['uid'];
                         }
		         $getusringroupres->closeCursor();
                     }
            }
            $allwdusersgrpfnl = array_unique($allwdusersgrpmlt);
            
            $allusr = array_merge($allwdusersfnl, $allwdusersgrpfnl);
            $allusruniquest = array_unique($allusr);

            if ($allusruniquest) {
                array_unshift($allusruniquest, $userId);
                $allusruniquepn = $allusruniquest;
            } else { $allusruniquepn = [$userId]; }

            $allusruniquepnst = $allusruniquepn;

            $procardatapn = "'" . implode("','", $allusruniquepn) . "'";

            array_unshift($allusruniquepn, $phoneNumber, $phoneNumberpr);
            $allusruniquead = $allusruniquepn;

            array_unshift($allusruniquepnst, $phoneNumberpr, $phoneNumber);
            $allusruniqueadst = $allusruniquepnst;
        }


        // Get received messages

        // If the user is an admin and he wants to see his messages and the messages of all the users with whom he shares his API keys
        if ($crsampref == 1 && $this->groupManager->isAdmin($userId)) {

	    $getrecmsgsres = $this->connection->executeQuery("
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received` 
                        WHERE (`from` = '$phoneNumber' OR `to` LIKE '$phoneNumberpr') AND `user_id` IN (" . $procardatapn . ")");

        // If the user is an admin and he wants to see only his messages
        } elseif ($crsampref == 0 && $this->groupManager->isAdmin($userId)) {

            $getrecmsgs = $this->connection->prepare('
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received` 
                        WHERE `user_id` = ? AND (`from` = ? OR `to` LIKE ?)');
	    $getrecmsgsres = $getrecmsgs->execute([$userId, $phoneNumber, $phoneNumberpr]);

        // If the user is not an admin 
        } elseif (!$this->groupManager->isAdmin($userId)) {

	    // Get the Display Name of the current user
	    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
	    $getacdatadnres = $getacdatadn->execute([$userId, 'displayname']);
	    $acdatausrdnadm = $getacdatadnres->fetch();
	    $cruserdname = $acdatausrdnadm['value'];
	    $getacdatadnres->closeCursor();

            // Get the groups to which the current user belongs
            $getusrgrp = $this->connection->prepare('
	          SELECT `gid`, `uid`
	          FROM  `*PREFIX*group_user`
                  WHERE `uid` = ?');
            $getusrgrpres = $getusrgrp->execute([$userId]);

            $usergrps = [];
            while ($fetchedgrps = $getusrgrpres->fetch()) {
                   $usergrps[] = $fetchedgrps['gid'];
            }
            $getusrgrpres->closeCursor();

            // Get the restrictions from the 'sms_relent_restrict' table
            $getrestr = $this->connection->prepare('
		       SELECT `phone_number`, `groups`, `users`
		       FROM  `*PREFIX*sms_relent_restrict`');
            $getrestrres = $getrestr->execute();

            $restrdata = [];
            while ($restrfetched = $getrestrres->fetch()) {
                   $restrdata[] = $restrfetched;
            }
            $getrestrres->closeCursor();

            // Get the phone numbers that the user is allowed/not allowed to use
            if ($restrdata) {

                $restrPhoneNmbrs = [];
                $allowedPhoneNmbrs = [];
                foreach ($restrdata as $rskey => $rsvalue) {

                         $chck = 0;
                         $restrgrparr = explode("|", $rsvalue['groups']);
                         foreach ($restrgrparr as $rkey => $rvalue) {
                                  if ($rvalue) {
                                      if (strpos(implode("|", $usergrps), $rvalue) !== false) { $chck++; }
                                  }
                         }
                         if (strpos($rsvalue['users'], $cruserdname) !== false) { $chck++; }

                         if ($chck == 0) { 
                             $restrPhoneNmbrs[] = $rsvalue['phone_number']; 
                         }
                }

		$allowedPhNmbrs = $this->getsmsnumbers($userId);

		foreach ($allowedPhNmbrs as $apnkey => $apnvalue) {
			 $crphnmbr = explode(": ", $apnvalue);
			 if ($crphnmbr[0] == 'Tx') {
			     $allowedPhoneNmbrs[] = 'Telnyx: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Pl') {
			     $allowedPhoneNmbrs[] = 'Plivo: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Tw') {
			     $allowedPhoneNmbrs[] = 'Twilio: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Fl') {
			     $allowedPhoneNmbrs[] = 'Flowroute: ' . $crphnmbr[1];
			 }
		}

                $allowedPhoneNmbrscp = $allowedPhoneNmbrs;

                $procalwdphnmbrs = "'" . implode("','", $allowedPhoneNmbrs) . "'";

                if ($procalwdphnmbrs != "''") {

	            $getrecmsgsres = $this->connection->executeQuery("
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE (`user_id` = '$userId' OR `to` IN (" . $procalwdphnmbrs . ")) AND (`from` = '$phoneNumber' OR `to` LIKE '$phoneNumberpr')");

                } else {
	            $getrecmsgs = $this->connection->prepare('
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE `user_id` = ? AND (`from` = ? OR `to` LIKE ?)');
	            $getrecmsgsres = $getrecmsgs->execute([$userId, $phoneNumber, $phoneNumberpr]);
                }

            } else {

		$allowedPhNmbrs = $this->getsmsnumbers($userId);

		foreach ($allowedPhNmbrs as $apnkey => $apnvalue) {
			 $crphnmbr = explode(": ", $apnvalue);
			 if ($crphnmbr[0] == 'Tx') {
			     $allowedPhoneNmbrs[] = 'Telnyx: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Pl') {
			     $allowedPhoneNmbrs[] = 'Plivo: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Tw') {
			     $allowedPhoneNmbrs[] = 'Twilio: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Fl') {
			     $allowedPhoneNmbrs[] = 'Flowroute: ' . $crphnmbr[1];
			 }
		}

                $allowedPhoneNmbrscp = $allowedPhoneNmbrs;

                $procalwdphnmbrs = "'" . implode("','", $allowedPhoneNmbrs) . "'";

                if ($procalwdphnmbrs != "''") {

	            $getrecmsgsres = $this->connection->executeQuery("
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE (`user_id` = '$userId' OR `to` IN (" . $procalwdphnmbrs . ")) AND (`from` = '$phoneNumber' OR `to` LIKE '$phoneNumberpr')");

                } else {
	            $getrecmsgs = $this->connection->prepare('
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE `user_id` = ? AND (`from` = ? OR `to` LIKE ?)');
	            $getrecmsgsres = $getrecmsgs->execute([$userId, $phoneNumber, $phoneNumberpr]);
                }
            }
        }


        $recmsgs = [];
        while ($rcrowsfetch = $getrecmsgsres->fetch()) {
               $rcrowsfetch['deliveryreceipt'] = '';
               $rcrowsfetch['table'] = 'received';
               $recmsgs[] = $rcrowsfetch;
        }
	$getrecmsgsres->closeCursor();


        // Get sent messages

        // If the user is an admin and he wants to see his messages and the messages of all the users with whom he shares his API keys
        if ($crsampref == 1 && $this->groupManager->isAdmin($userId)) {

            $getsentmsgsres = $this->connection->executeQuery("
		       SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		       FROM  `*PREFIX*sms_relent_sent` 
                       WHERE (`from` LIKE '$phoneNumberpr' OR `to` = '$phoneNumber') AND `user_id` IN (" . $procardatapn . ")");

        // If the user is an admin and he wants to see only his messages
        } elseif ($crsampref == 0 && $this->groupManager->isAdmin($userId)) {

            $getsentmsgs = $this->connection->prepare('
		       SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND (`from` LIKE ? OR `to` = ?)');
            $getsentmsgsres = $getsentmsgs->execute([$userId, $phoneNumberpr, $phoneNumber]);


        // If the user is not an admin 
        } elseif (!$this->groupManager->isAdmin($userId)) {

            if ($restrdata) {
                if ($procalwdphnmbrs != "''") {

                    $getsentmsgsres = $this->connection->executeQuery("
		        SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		        FROM  `*PREFIX*sms_relent_sent`
			WHERE (`user_id` = '$userId' OR `from` IN (" . $procalwdphnmbrs . ")) AND (`from` LIKE '$phoneNumberpr' OR `to` = '$phoneNumber')");

                } else {
                    $getsentmsgs = $this->connection->prepare('
		        SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		        FROM  `*PREFIX*sms_relent_sent`
			WHERE `user_id` = ? AND (`from` LIKE ? OR `to` = ?)');
	            $getsentmsgsres = $getsentmsgs->execute([$userId, $phoneNumberpr, $phoneNumber]);
                }

            } else {

                $getsentmsgs = $this->connection->prepare('
		       SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND (`from` LIKE ? OR `to` = ?)');
                $getsentmsgsres = $getsentmsgs->execute([$userId, $phoneNumberpr, $phoneNumber]);
            }
        }

        $sentmsgs = [];
        while ($rowfetchedsmsg = $getsentmsgsres->fetch()) {
               $rowfetchedsmsg['table'] = 'sent';
               $sentmsgs[] = $rowfetchedsmsg;
        }
        $getsentmsgsres->closeCursor();

        $groupedpernb = array_merge($recmsgs, $sentmsgs);

        if ($this->groupManager->isAdmin($userId)) {

            return $groupedpernb;

        } else {

            if ($restrdata) {

                // Clean the phone numbers from tags
                $restrPhfin = [];
                foreach ($restrPhoneNmbrs as $phkey => $phvalue) {

                    $restrpharr = explode(": ", $phvalue);
                    $restrPhfin[] = $restrpharr[1];
                }

                // Assemble the array of message rows that excludes the rows for the restricted phone numbers
                foreach ($groupedpernb as $gmdkey => $gmdvalue) {

                         if ($gmdvalue['table'] == 'sent') {

                             if (str_contains($gmdvalue['from'], "+")) {
                                 $fromnmbrarr = explode("+", $gmdvalue['from']);
                                 if (in_array("+" . $fromnmbrarr[1], $restrPhfin)) {
                                     unset($groupedpernb[$gmdkey]);
                                 }
                             } else {
                                 $frmnmbrarr = explode(": ", $gmdvalue['from']);
                                 if (count($frmnmbrarr) == 2) {
                                     $nmbtbcmprd = $frmnmbrarr[1];
                                 } else { 
                                     $nmbtbcmprd = $frmnmbrarr[0];
                                 }
                                 if (in_array($nmbtbcmprd, $restrPhfin)) {
                                     unset($groupedpernb[$gmdkey]);
                                 }
                             }

                         } elseif ($gmdvalue['table'] == 'received') {

                             if (str_contains($gmdvalue['to'], "+")) {
                                 $fromnmbrarr = explode("+", $gmdvalue['to']);
                                 if (in_array("+" . $fromnmbrarr[1], $restrPhfin)) {
                                     unset($groupedpernb[$gmdkey]);
                                 }
                             } else {
                                 $tonmbrarr = explode(": ", $gmdvalue['to']);
                                 if (count($tonmbrarr) == 2) {
                                     $tonmbrtbcmprd = $tonmbrarr[1];
                                 } else {
                                     $tonmbrtbcmprd = $tonmbrarr[0];
                                 }
                                 if (in_array($tonmbrtbcmprd, $restrPhfin)) {
                                     unset($groupedpernb[$gmdkey]);
                                 }
                             }
                         }

                }

                $groupedpernbprc = array_values($groupedpernb);

                return $groupedpernbprc;

            } else { return $groupedpernb; }
        }
     }


     /**
      * @NoAdminRequired
      */
     public function getgroupedforreply($userId, $phoneNmbrFrom, $phoneNmbrTo) {

        $phoneNmbrFrompr = "%" . $phoneNmbrFrom;
        $phoneNmbrTopr = "%" . $phoneNmbrTo;

        // Get the user's preferences from the settings
        $getpref = $this->connection->prepare('
		       SELECT `user_id`, `show_all_messages`
		       FROM  `*PREFIX*sms_relent_settings` WHERE `user_id` = ?');
        $getprefres = $getpref->execute([$userId]);
        $getprefresdata = $getprefres->fetch();
        $crsampref = $getprefresdata['show_all_messages'];
        $getprefres->closeCursor();


        // Collect the users with whom the current admin is sharing his API keys and whose messages he will be able to see
        if ($crsampref == 1 && $this->groupManager->isAdmin($userId)) {

            // Get the groups and users that were allowed access to the API keys
            $getgrps = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed`, `tnx_users_allowed`, `plv_groups_allowed`, `plv_users_allowed`,
                                                  `twl_groups_allowed`, `twl_users_allowed`, `flr_groups_allowed`, `flr_users_allowed` FROM `*PREFIX*sms_relent_subac`
                                                   WHERE `user_id` = ?');
            $getgrpsres = $getgrps->execute([$userId]);
            $getgrpsusr = $getgrpsres->fetch();
            $getgrpsres->closeCursor();

            if ($getgrpsusr) {

                if ($getgrpsusr['tnx_users_allowed']) { $tnxusers = explode("|", $getgrpsusr['tnx_users_allowed']); } else { $tnxusers = []; }
                if ($getgrpsusr['plv_users_allowed']) { $plvusers = explode("|", $getgrpsusr['plv_users_allowed']); } else { $plvusers = []; }
                if ($getgrpsusr['twl_users_allowed']) { $twlusers = explode("|", $getgrpsusr['twl_users_allowed']); } else { $twlusers = []; }
                if ($getgrpsusr['flr_users_allowed']) { $flrusers = explode("|", $getgrpsusr['flr_users_allowed']); } else { $flrusers = []; }

                $allwdusersarr = array_merge($tnxusers, $plvusers, $twlusers, $flrusers);
                $allwdusersunq = array_filter(array_unique($allwdusersarr));

                if ($getgrpsusr['tnx_groups_allowed']) { $tnxgroups = explode("|", $getgrpsusr['tnx_groups_allowed']); } else { $tnxgroups = []; }
                if ($getgrpsusr['plv_groups_allowed']) { $plvgroups = explode("|", $getgrpsusr['plv_groups_allowed']); } else { $plvgroups = []; }
                if ($getgrpsusr['twl_groups_allowed']) { $twlgroups = explode("|", $getgrpsusr['twl_groups_allowed']); } else { $twlgroups = []; }
                if ($getgrpsusr['flr_groups_allowed']) { $flrgroups = explode("|", $getgrpsusr['flr_groups_allowed']); } else { $flrgroups = []; }

                $allwdgroupsarr = array_merge($tnxgroups, $plvgroups, $twlgroups, $flrgroups);
                $allwdgroupsunq = array_filter(array_unique($allwdgroupsarr));

            } else {
                $allwdusersunq = [];
                $allwdgroupsunq = [];
            }

            // Get the username for each Display Name of the allowed users
            $allwdusersfnl = [];
            foreach ($allwdusersunq as $alwdusrkey => $alwdusrvalue) {

                         $getacdatausrnm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		         $getacdatausrnmres = $getacdatausrnm->execute(['displayname', $alwdusrvalue]);
		         $acdatausrname = $getacdatausrnmres->fetch();
                         if ($acdatausrname) {
                             $allwdusersfnl[] = $acdatausrname['uid'];
                         }
                         $getacdatausrnmres->closeCursor();
            }

            // Get the users from all the allowed groups
            $allwdusersgrpmlt = [];
            foreach ($allwdgroupsunq as $prgrpkey => $prgrpvalue) {

                     // Get all the users that belong to the current group, if the current group is different from 'admin'
                     if ($prgrpvalue != 'admin') {
                         $getusringroup = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
		         $getusringroupres = $getusringroup->execute([$prgrpvalue]);

		         while ($getusrname = $getusringroupres->fetch()) {

                                $allwdusersgrpmlt[] = $getusrname['uid'];
                         }
		         $getusringroupres->closeCursor();
                     }
            }
            $allwdusersgrpfnl = array_unique($allwdusersgrpmlt);
            
            $allusr = array_merge($allwdusersfnl, $allwdusersgrpfnl);
            $allusruniquest = array_unique($allusr);

            if ($allusruniquest) {
                array_unshift($allusruniquest, $userId);
                $allusruniquerp = $allusruniquest;
            } else { $allusruniquerp = [$userId]; }

            $allusruniquerpst = $allusruniquerp;

            $procardatarp = "'" . implode("','", $allusruniquerp) . "'";
        }


        // Get received messages

        // If the user is an admin and he wants to see his messages and the messages of all the users with whom he shares his API keys
        if ($crsampref == 1 && $this->groupManager->isAdmin($userId)) {

            $getrecmsgsres = $this->connection->executeQuery("
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received` 
                        WHERE ((`from` = '$phoneNmbrFrom' AND `to` LIKE '$phoneNmbrTopr') OR (`from` = '$phoneNmbrTo' AND `to` LIKE '$phoneNmbrFrompr')) AND 
                        `user_id` IN (" . $procardatarp . ")");

        // If the user is an admin and he wants to see only his messages
        } elseif ($crsampref == 0 && $this->groupManager->isAdmin($userId)) {

            $getrecmsgs = $this->connection->prepare('
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM  `*PREFIX*sms_relent_received`
			WHERE `user_id` = ? AND ((`from` = ? AND `to` LIKE ?) OR (`from` = ? AND `to` LIKE ?))');
	    $getrecmsgsres = $getrecmsgs->execute([$userId, $phoneNmbrFrom, $phoneNmbrTopr, $phoneNmbrTo, $phoneNmbrFrompr]);

        // If the user is not an admin 
        } elseif (!$this->groupManager->isAdmin($userId)) {

	    // Get the Display Name of the current user
	    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
	    $getacdatadnres = $getacdatadn->execute([$userId, 'displayname']);
	    $acdatausrdnadm = $getacdatadnres->fetch();
	    $cruserdname = $acdatausrdnadm['value'];
	    $getacdatadnres->closeCursor();

            // Get the groups to which the current user belongs
            $getusrgrp = $this->connection->prepare('
	          SELECT `gid`, `uid`
	          FROM  `*PREFIX*group_user`
                  WHERE `uid` = ?');
            $getusrgrpres = $getusrgrp->execute([$userId]);

            $usergrps = [];
            while ($fetchedgrps = $getusrgrpres->fetch()) {
                   $usergrps[] = $fetchedgrps['gid'];
            }
            $getusrgrpres->closeCursor();

            // Get the restrictions from the 'sms_relent_restrict' table
            $getrestr = $this->connection->prepare('
		       SELECT `phone_number`, `groups`, `users`
		       FROM  `*PREFIX*sms_relent_restrict`');
            $getrestrres = $getrestr->execute();

            $restrdata = [];
            while ($restrfetched = $getrestrres->fetch()) {
                   $restrdata[] = $restrfetched;
            }
            $getrestrres->closeCursor();

            // Get the phone numbers that the user is allowed/not allowed to use
            if ($restrdata) {

                $restrPhoneNmbrs = [];
                $allowedPhoneNmbrs = [];
                foreach ($restrdata as $rskey => $rsvalue) {

                         $chck = 0;
                         $restrgrparr = explode("|", $rsvalue['groups']);
                         foreach ($restrgrparr as $rkey => $rvalue) {
                                  if ($rvalue) {
                                      if (strpos(implode("|", $usergrps), $rvalue) !== false) { $chck++; }
                                  }
                         }
                         if (strpos($rsvalue['users'], $cruserdname) !== false) { $chck++; }

                         if ($chck == 0) { 
                             $restrPhoneNmbrs[] = $rsvalue['phone_number']; 
                         }
                }

		$allowedPhNmbrs = $this->getsmsnumbers($userId);

		foreach ($allowedPhNmbrs as $apnkey => $apnvalue) {
			 $crphnmbr = explode(": ", $apnvalue);
			 if ($crphnmbr[0] == 'Tx') {
			     $allowedPhoneNmbrs[] = 'Telnyx: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Pl') {
			     $allowedPhoneNmbrs[] = 'Plivo: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Tw') {
			     $allowedPhoneNmbrs[] = 'Twilio: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Fl') {
			     $allowedPhoneNmbrs[] = 'Flowroute: ' . $crphnmbr[1];
			 }
		}

                $allowedPhoneNmbrscpr = $allowedPhoneNmbrs;

                $procalwdphnmbrs = "'" . implode("','", $allowedPhoneNmbrs) . "'";

                if ($procalwdphnmbrs != "''") {

                    $getrecmsgsres = $this->connection->executeQuery("
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE (`user_id` = '$userId' OR `to` IN (" . $procalwdphnmbrs . ")) AND ((`from` = '$phoneNmbrFrom' AND `to` LIKE '$phoneNmbrTopr') OR (`from` = '$phoneNmbrTo' 
                                AND `to` LIKE '$phoneNmbrFrompr'))");

                } else {
	            $getrecmsgs = $this->connection->prepare('
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE `user_id` = ? AND ((`from` = ? AND `to` LIKE ?) OR (`from` = ? AND `to` LIKE ?))');
	            $getrecmsgsres = $getrecmsgs->execute([$userId, $phoneNmbrFrom, $phoneNmbrTopr, $phoneNmbrTo, $phoneNmbrFrompr]);
                }

            } else {

		$allowedPhNmbrs = $this->getsmsnumbers($userId);

		foreach ($allowedPhNmbrs as $apnkey => $apnvalue) {
			 $crphnmbr = explode(": ", $apnvalue);
			 if ($crphnmbr[0] == 'Tx') {
			     $allowedPhoneNmbrs[] = 'Telnyx: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Pl') {
			     $allowedPhoneNmbrs[] = 'Plivo: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Tw') {
			     $allowedPhoneNmbrs[] = 'Twilio: ' . $crphnmbr[1];
			 } elseif ($crphnmbr[0] == 'Fl') {
			     $allowedPhoneNmbrs[] = 'Flowroute: ' . $crphnmbr[1];
			 }
		}

                $allowedPhoneNmbrscpr = $allowedPhoneNmbrs;

                $procalwdphnmbrs = "'" . implode("','", $allowedPhoneNmbrs) . "'";

                if ($procalwdphnmbrs != "''") {

                    $getrecmsgsres = $this->connection->executeQuery("
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE (`user_id` = '$userId' OR `to` IN (" . $procalwdphnmbrs . ")) AND ((`from` = '$phoneNmbrFrom' AND `to` LIKE '$phoneNmbrTopr') OR (`from` = '$phoneNmbrTo' 
                                AND `to` LIKE '$phoneNmbrFrompr'))");

                } else {
	            $getrecmsgs = $this->connection->prepare('
			SELECT `id`, `user_id`, `date`, `from`, `to`, `message`, `author_displayname`
			FROM `*PREFIX*sms_relent_received`
			WHERE `user_id` = ? AND ((`from` = ? AND `to` LIKE ?) OR (`from` = ? AND `to` LIKE ?))');
	            $getrecmsgsres = $getrecmsgs->execute([$userId, $phoneNmbrFrom, $phoneNmbrTopr, $phoneNmbrTo, $phoneNmbrFrompr]);
                }
            }
        }

        $recmsgs = [];
        while ($rcrowsfetch = $getrecmsgsres->fetch()) {
               $rcrowsfetch['deliveryreceipt'] = '';
               $rcrowsfetch['table'] = 'received';
               $recmsgs[] = $rcrowsfetch;
        }
	$getrecmsgsres->closeCursor();


        // Get sent messages

        // If the user is an admin and he wants to see his messages and the messages of all the users with whom he shares his API keys
        if ($crsampref == 1 && $this->groupManager->isAdmin($userId)) {

            $getsentmsgsres = $this->connection->executeQuery("
		       SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		       FROM  `*PREFIX*sms_relent_sent` 
                       WHERE ((`from` LIKE '$phoneNmbrFrompr' AND `to` = '$phoneNmbrTo') OR (`from` LIKE '$phoneNmbrTopr' AND `to` = '$phoneNmbrFrom')) AND `user_id` IN 
                       (" . $procardatarp . ")");

        // If the user is an admin and he wants to see only his messages
        } elseif ($crsampref == 0 && $this->groupManager->isAdmin($userId)) {

            $getsentmsgs = $this->connection->prepare('
		       SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		       FROM `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND ((`from` LIKE ? AND `to` = ?) OR (`from` LIKE ? AND `to` = ?))');
            $getsentmsgsres = $getsentmsgs->execute([$userId, $phoneNmbrFrompr, $phoneNmbrTo, $phoneNmbrTopr, $phoneNmbrFrom]);

        // If the user is not an admin
        } elseif (!$this->groupManager->isAdmin($userId)) {

            if ($restrdata) {
                if ($procalwdphnmbrs != "''") {

	            $getsentmsgsres = $this->connection->executeQuery("
		       SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		       FROM `*PREFIX*sms_relent_sent`
		       WHERE (`user_id` = '$userId' OR `from` IN (" . $procalwdphnmbrs . ")) AND ((`from` LIKE '$phoneNmbrFrompr' AND `to` = '$phoneNmbrTo') OR 
                       (`from` LIKE '$phoneNmbrTopr' AND `to` = '$phoneNmbrFrom'))");

                } else {
                    $getsentmsgs = $this->connection->prepare('
		       SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		       FROM `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND ((`from` LIKE ? AND `to` = ?) OR (`from` LIKE ? AND `to` = ?))');
	            $getsentmsgsres = $getsentmsgs->execute([$userId, $phoneNmbrFrompr, $phoneNmbrTo, $phoneNmbrTopr, $phoneNmbrFrom]);
                }

            } else {

                $getsentmsgs = $this->connection->prepare('
		       SELECT `id`, `user_id`, `date`, `from`, `to`,`message`, `author_displayname`, `deliveryreceipt`
		       FROM `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND ((`from` LIKE ? AND `to` = ?) OR (`from` LIKE ? AND `to` = ?))');
                $getsentmsgsres = $getsentmsgs->execute([$userId, $phoneNmbrFrompr, $phoneNmbrTo, $phoneNmbrTopr, $phoneNmbrFrom]);
            }
        }

        $sentmsgs = [];
        while ($rowfetchedsmsg = $getsentmsgsres->fetch()) {
               $rowfetchedsmsg['table'] = 'sent';
               $sentmsgs[] = $rowfetchedsmsg;
        }
        $getsentmsgsres->closeCursor();

        $groupedpernb = array_merge($recmsgs, $sentmsgs);

        if ($this->groupManager->isAdmin($userId)) {

            return $groupedpernb;

        } else {

            if ($restrdata) {

                // Clean the phone numbers from tags
                $restrPhfin = [];
                foreach ($restrPhoneNmbrs as $phkey => $phvalue) {

                    $restrpharr = explode(": ", $phvalue);
                    $restrPhfin[] = $restrpharr[1];
                }

                // Assemble the array of message rows that excludes the rows for the restricted phone numbers
                foreach ($groupedpernb as $gmdkey => $gmdvalue) {

                         if ($gmdvalue['table'] == 'sent') {

                             if (str_contains($gmdvalue['from'], "+")) {
                                 $fromnmbrarr = explode("+", $gmdvalue['from']);
                                 if (in_array("+" . $fromnmbrarr[1], $restrPhfin)) {
                                     unset($groupedpernb[$gmdkey]);
                                 }
                             } else {
                                 $frmnmbrarr = explode(": ", $gmdvalue['from']);
                                 if (count($frmnmbrarr) == 2) {
                                     $nmbtbcmprd = $frmnmbrarr[1];
                                 } else { 
                                     $nmbtbcmprd = $frmnmbrarr[0];
                                 }
                                 if (in_array($nmbtbcmprd, $restrPhfin)) {
                                     unset($groupedpernb[$gmdkey]);
                                 }
                             }

                         } elseif ($gmdvalue['table'] == 'received') {

                             if (str_contains($gmdvalue['to'], "+")) {
                                 $fromnmbrarr = explode("+", $gmdvalue['to']);
                                 if (in_array("+" . $fromnmbrarr[1], $restrPhfin)) {
                                     unset($groupedpernb[$gmdkey]);
                                 }
                             } else {
                                 $tonmbrarr = explode(": ", $gmdvalue['to']);
                                 if (count($tonmbrarr) == 2) {
                                     $tonmbrtbcmprd = $tonmbrarr[1];
                                 } else {
                                     $tonmbrtbcmprd = $tonmbrarr[0];
                                 }
                                 if (in_array($tonmbrtbcmprd, $restrPhfin)) {
                                     unset($groupedpernb[$gmdkey]);
                                 }
                             }
                         }

                }

                $groupedperconv = array_values($groupedpernb);

                return $groupedperconv;

            } else { return $groupedpernb; }
        }
     }



     /**
      * @NoAdminRequired
      */
     public function savedisplayname($userId, $authorDisplayname, $from) {

        if ($this->groupManager->isAdmin($userId)) {

	    $updatedispnm = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_received`
			SET `author_displayname` = ?
                        WHERE `from` = ?');
	    $updatedispnmres = $updatedispnm->execute([$authorDisplayname, $from]);

            if ($updatedispnmres) {
                return $respupdname = "The new Display Name has been saved. If on the Settings page, the option 'Add the display name of the message author, before each message' is checked, when you refresh the page you will see the new Display Name before the messages.";
            } else {
                return $respupdname = "Error while trying to save the new Display Name to the database.";
            }
	    $updatedispnmres->closeCursor();

        } else { return $respupdname = "Only admins can save Display Names for phone numbers that are not associated with Nextcloud users."; }
     }

     /**
      * @NoAdminRequired
      */
     public function getmsgsperpagenewmsg($userId) {

        $sqlmpp = $this->connection->prepare('
	       SELECT `user_id`, `messagesperpage`, `msg_check_interval` 
               FROM `*PREFIX*sms_relent_settings`
               WHERE `user_id` = ?');
	$result = $sqlmpp->execute([$userId]);
        $mesppdata = $result->fetch();
        $result->closeCursor();
        if ($mesppdata) {
            $mesperpagedb = ['msgsperpage' => $mesppdata['messagesperpage'], 'newmsgcheck' => $mesppdata['msg_check_interval']];
            return $mesperpagedb;
        }
     }

     /**
      * @NoAdminRequired
      */
     public function getnewmsgindicator($userId) {

        $sqlnmsg = $this->connection->prepare('
	       SELECT `user_id`, `new_message_rcd` 
               FROM `*PREFIX*sms_relent_settings`
               WHERE `user_id` = ?');
	$resultnmsg = $sqlnmsg->execute([$userId]);
        $nmsgdata = $resultnmsg->fetch();
        $resultnmsg->closeCursor();

        if ($nmsgdata) {
            $newmsgdb = $nmsgdata['new_message_rcd'];

            if ($newmsgdb == 1) {
                // Change the 'new message received' indicator to 0 in the 'sms_relent_settings' table, for the current user
                $newMsgRcd = 0;
	        $sqlupdnmsc = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_settings`
			SET `new_message_rcd` = ?
	                WHERE `user_id` = ?');
	        $updatenmRcd = $sqlupdnmsc->execute([$newMsgRcd, $userId]);
	        $updatenmRcd->closeCursor();
            }

            return $newmsgdb;
        }
     }

     /**
      * @NoAdminRequired
      */
     public function getsettings($userId) {

        $getsettings = $this->connection->prepare('
                    SELECT `id`, `user_id`, `telapi_url_rec`, `telapi_url`, `nexapi_url_rec`, `nexapi_url`, `twilapi_url_rec`, `twilapi_url`, `flowapi_url_rec`, `flowapi_url`, 
                           `messagesperpage`, `get_notify`, `notification_email`, `getsmsinemail`, `show_display_names`, `add_display_names`, `msg_check_interval`                           
		    FROM  `*PREFIX*sms_relent_settings`
		    WHERE `user_id` = ?');
        $resultsettings = $getsettings->execute([$userId]);

        $settingsfromdb = $resultsettings->fetch();

        $resultsettings->closeCursor();

        if ($settingsfromdb) {

            if ($this->groupManager->isAdmin($userId)) { $adminreguser = 'admin'; } else { $adminreguser = 'reguser'; }
            $settingsfromdb['adminornot'] = $adminreguser;

            return $settingsfromdb;
        }

     }


     public function updatenumberrestrictions($userId, $savedByDsplname, $phoneNumber, $groups, $users) {

        if ($this->groupManager->isAdmin($userId)) {

            $groupsproc = implode("|", $groups);
            $usersproc = implode("|", $users);

            // Get the restrictions for the current number from the 'sms_relent_restrict' table
            $getrestr = $this->connection->prepare('SELECT `user_id`, `saved_by_dsplname`, `phone_number`, `groups`, `users` FROM `*PREFIX*sms_relent_restrict` WHERE
                                                   `phone_number` = ?');
            $getrestrresult = $getrestr->execute([$phoneNumber]);
            $crntrestr = $getrestrresult->fetch();
            $getrestrresult->closeCursor();

            if ($getrestrresult && !$crntrestr) {

	        $insertphrestr = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_restrict` (`user_id`, `saved_by_dsplname`, `phone_number`, `groups`, `users`) VALUES
                                                             (?, ?, ?, ?, ?)');
	        if ($insertphrestr->execute([$userId, $savedByDsplname, $phoneNumber, $groupsproc, $usersproc])) { $messagetosend = 'success'; } else { $messagetosend = 'failure'; }  
         
            } elseif ($getrestrresult && $crntrestr) {

	        $updatephrestr = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_restrict` SET `user_id` = ?, `saved_by_dsplname` = ?, `groups` = ?, `users` = ? WHERE 
                                                            `phone_number` = ?');
	        if ($admupdatephonerestr = $updatephrestr->execute([$userId, $savedByDsplname, $groupsproc, $usersproc, $phoneNumber])) { 
                    $messagetosend = 'success';
                } else { 
                    $messagetosend = 'failure'; 
                }

	        $admupdatephonerestr->closeCursor();
            }
            return $messagetosend;
        }
     }


     private function updateusercredentials($userId, $usersarr, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey, $plivoapisecret, $plivosendernm, 
                                            $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret) {

        $msgtosend = 'success';

        foreach ($usersarr as $usrkey => $usrvalue) {

            $getusrset = $this->connection->prepare('SELECT `user_id` FROM `*PREFIX*sms_relent_settings` WHERE `user_id` = ?');
	    $getusrsetres = $getusrset->execute([$usrvalue]);
	    $getcrunmdata = $getusrsetres->fetch();
	    $getusrsetres->closeCursor();

            if ($getcrunmdata) {

                if ($provider == "tnx") {

                    $upusrset = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `telapi_key` = ?, `tel_pub_key` = ?, `messaging_profile_id` = ?,
                                                           `tel_sender_name` = ? WHERE `user_id` = ?');
                    if ($upusrsetres = $upusrset->execute([$telapiKey, $telpubKey, $telmsgprofid, $telsendername, $usrvalue])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();

                } elseif ($provider == "plv") {

                    $upusrset = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `nexapi_key` = ?, `nexapi_secret` = ?, `nex_sender_name` = ?
                                                            WHERE `user_id` = ?');
                    if ($upusrsetres = $upusrset->execute([$plivoapikey, $plivoapisecret, $plivosendernm, $usrvalue])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();

                } elseif ($provider == "twl") {

                    $upusrset = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `twilapi_key` = ?, `twilapi_secret` = ?, `twil_sender_name` = ?
                                                            WHERE `user_id` = ?');
                    if ($upusrsetres = $upusrset->execute([$twilapikey, $twilapisecret, $twilsendernm, $usrvalue])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();

                } elseif ($provider == "flr") {

                    $upusrset = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `flowapi_key` = ?, `flowapi_secret` = ? WHERE `user_id` = ?');
                    if ($upusrsetres = $upusrset->execute([$flowapikey, $flowapisecret, $usrvalue])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();
                }

            } else {

                $emptfld = "";

                if ($provider == "tnx") {

                    $upusrset = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_settings` (`user_id`, `telapi_key`, `tel_pub_key`, `telapi_url_rec`, `telapi_url`,
                                                           `messaging_profile_id`, `nexapi_key`, `nexapi_secret`, `nexapi_url_rec`, `nexapi_url`, `twilapi_key`, `twilapi_secret`,
                                                           `twilapi_url_rec`, `twilapi_url`, `flowapi_key`, `flowapi_secret`, `flowapi_url_rec`, `flowapi_url`, `tel_sender_name`) 
                                                            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
                    if ($upusrsetres = $upusrset->execute([$usrvalue, $telapiKey, $telpubKey, $emptfld, $emptfld, $telmsgprofid, $emptfld, $emptfld, $emptfld, $emptfld, $emptfld, 
                                                           $emptfld, $emptfld, $emptfld, $emptfld, $emptfld, $emptfld, $emptfld, $telsendername])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();

                } elseif ($provider == "plv") {

                    $upusrset = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_settings` (`user_id`, `telapi_key`, `tel_pub_key`, `telapi_url_rec`, `telapi_url`,
                                                           `messaging_profile_id`, `nexapi_key`, `nexapi_secret`, `nexapi_url_rec`, `nexapi_url`, `twilapi_key`, `twilapi_secret`,
                                                           `twilapi_url_rec`, `twilapi_url`, `flowapi_key`, `flowapi_secret`, `flowapi_url_rec`, `flowapi_url`, `nex_sender_name`)
                                                            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
                    if ($upusrsetres = $upusrset->execute([$usrvalue, $telapiKey, $telpubKey, $emptfld, $emptfld, $telmsgprofid, $plivoapikey, $plivoapisecret, $emptfld, $emptfld, 
                                                           $emptfld, $emptfld, $emptfld, $emptfld, $emptfld, $emptfld, $emptfld, $emptfld, $plivosendernm])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();

                } elseif ($provider == "twl") {

                    $upusrset = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_settings` (`user_id`, `telapi_key`, `tel_pub_key`, `telapi_url_rec`, `telapi_url`,
                                                           `messaging_profile_id`, `nexapi_key`, `nexapi_secret`, `nexapi_url_rec`, `nexapi_url`, `twilapi_key`, `twilapi_secret`,
                                                           `twilapi_url_rec`, `twilapi_url`, `flowapi_key`, `flowapi_secret`, `flowapi_url_rec`, `flowapi_url`, `twil_sender_name`)
                                                            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
                    if ($upusrsetres = $upusrset->execute([$usrvalue, $telapiKey, $telpubKey, $emptfld, $emptfld, $telmsgprofid, $plivoapikey, $plivoapisecret, $emptfld, $emptfld, 
                                                           $twilapikey, $twilapisecret, $emptfld, $emptfld, $emptfld, $emptfld, $emptfld, $emptfld, $twilsendernm])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();

                } elseif ($provider == "flr") {

                    $upusrset = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_settings` (`user_id`, `telapi_key`, `tel_pub_key`, `telapi_url_rec`, `telapi_url`,
                                                           `messaging_profile_id`, `nexapi_key`, `nexapi_secret`, `nexapi_url_rec`, `nexapi_url`, `twilapi_key`, `twilapi_secret`,
                                                           `twilapi_url_rec`, `twilapi_url`, `flowapi_key`, `flowapi_secret`, `flowapi_url_rec`, `flowapi_url`)
                                                            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
                    if ($upusrsetres = $upusrset->execute([$usrvalue, $telapiKey, $telpubKey, $emptfld, $emptfld, $telmsgprofid, $plivoapikey, $plivoapisecret, $emptfld, $emptfld, 
                                                           $twilapikey, $twilapisecret, $emptfld, $emptfld, $flowapikey, $flowapisecret, $emptfld, $emptfld])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();
                }

            }                 
        }

        return $msgtosend;
     }


     private function removeusercredentials($userId, $usersarr, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey, $plivoapisecret, $plivosendernm, 
                                            $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret) {

        $msgtosend = 'success';

        foreach ($usersarr as $usrkey => $usrvalue) {

                $emptyfld = "";

                if ($provider == "tnx") {

                    $upusrset = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `telapi_key` = ?, `tel_pub_key` = ?, `messaging_profile_id` = ?,
                                                           `tel_sender_name` = ? WHERE `user_id` = ?');
                    if ($upusrsetres = $upusrset->execute([$emptyfld, $emptyfld, $emptyfld, $emptyfld, $usrvalue])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();

                } elseif ($provider == "plv") {

                    $upusrset = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `nexapi_key` = ?, `nexapi_secret` = ?, `nex_sender_name` = ?
                                                            WHERE `user_id` = ?');
                    if ($upusrsetres = $upusrset->execute([$emptyfld, $emptyfld, $emptyfld, $usrvalue])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();

                } elseif ($provider == "twl") {

                    $upusrset = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `twilapi_key` = ?, `twilapi_secret` = ?, `twil_sender_name` = ?
                                                            WHERE `user_id` = ?');
                    if ($upusrsetres = $upusrset->execute([$emptyfld, $emptyfld, $emptyfld, $usrvalue])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();

                } elseif ($provider == "flr") {

                    $upusrset = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `flowapi_key` = ?, `flowapi_secret` = ? WHERE `user_id` = ?');
                    if ($upusrsetres = $upusrset->execute([$emptyfld, $emptyfld, $usrvalue])) {
                        $msgtosend = 'success';
                    } else { $msgtosend = 'failure'; }
                    $upusrsetres->closeCursor();
                }
        }

        return $msgtosend;
     }


     public function updatekeysallowedusers($userId, $groups, $users, $provider) {

       if ($this->groupManager->isAdmin($userId)) {

          $msgtosend = 'success';

          // Get the users that belong to the 'admin' group
          $getadmn = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
          $getadmnres = $getadmn->execute(['admin']);

          $usersadmin = [];
          while ($getadmnusrs = $getadmnres->fetch()) {
                 $usersadmin[] = $getadmnusrs['uid'];
          }
          $getadmnres->closeCursor();
          
          // Get the API keys and alphanumeric sender IDs for the current admin, from the 'sms_relent_settings' table
          $getadmset = $this->connection->prepare('SELECT `user_id`, `telapi_key`, `tel_pub_key`, `messaging_profile_id`, `tel_sender_name`, `nexapi_key`, `nexapi_secret`,
                                                  `nex_sender_name`, `twilapi_key`, `twilapi_secret`, `twil_sender_name`, `flowapi_key`, `flowapi_secret` 
                                                   FROM `*PREFIX*sms_relent_settings` WHERE `user_id` = ?');
	  $getadmsetres = $getadmset->execute([$userId]);
	  $getcradmdata = $getadmsetres->fetch();
          $telapiKey = $getcradmdata['telapi_key'];
          $telpubKey = $getcradmdata['tel_pub_key'];
          $telmsgprofid = $getcradmdata['messaging_profile_id'];
          $telsendername = $getcradmdata['tel_sender_name'];
          $plivoapikey = $getcradmdata['nexapi_key'];
          $plivoapisecret = $getcradmdata['nexapi_secret'];
          $plivosendernm = $getcradmdata['nex_sender_name'];
          $twilapikey = $getcradmdata['twilapi_key'];
          $twilapisecret = $getcradmdata['twilapi_secret'];
          $twilsendernm = $getcradmdata['twil_sender_name'];
          $flowapikey = $getcradmdata['flowapi_key'];
          $flowapisecret = $getcradmdata['flowapi_secret'];
	  $getadmsetres->closeCursor();

          if ($getcradmdata) {

            if ($provider == "tnx") {

                $getalwd = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed`, `tnx_users_allowed` FROM `*PREFIX*sms_relent_subac`');
                $getalwdres = $getalwd->execute();

                $upchck = 0;
                $seldataarr = [];
                $groupsPerProvider = '';
                $usersPerProvider = '';
                while ($crntrestr = $getalwdres->fetch()) {
                       if ($crntrestr['user_id'] != $userId) {
                           $seldataarr[] = ['userid' => $crntrestr['user_id'], 'groupsallowed' => $crntrestr['tnx_groups_allowed'], 'usersallowed' => $crntrestr['tnx_users_allowed']];
                       } else {
                           $upchck++;
                           $groupsPerProvider = $crntrestr['tnx_groups_allowed'];
                           $usersPerProvider = $crntrestr['tnx_users_allowed'];
                       }
                }
                $getalwdres->closeCursor();


            } elseif ($provider == "plv") {

                $getalwd = $this->connection->prepare('SELECT `user_id`, `plv_groups_allowed`, `plv_users_allowed` FROM `*PREFIX*sms_relent_subac`');
                $getalwdres = $getalwd->execute();

                $upchck = 0;
                $seldataarr = [];
                $groupsPerProvider = '';
                $usersPerProvider = '';
                while ($crntrestr = $getalwdres->fetch()) {
                       if ($crntrestr['user_id'] != $userId) {
                           $seldataarr[] = ['userid' => $crntrestr['user_id'], 'groupsallowed' => $crntrestr['plv_groups_allowed'], 'usersallowed' => $crntrestr['plv_users_allowed']];
                       } else {
                           $upchck++;
                           $groupsPerProvider = $crntrestr['plv_groups_allowed'];
                           $usersPerProvider = $crntrestr['plv_users_allowed'];
                       }
                }
                $getalwdres->closeCursor();

            } elseif ($provider == "twl") {

                $getalwd = $this->connection->prepare('SELECT `user_id`, `twl_groups_allowed`, `twl_users_allowed` FROM `*PREFIX*sms_relent_subac`');
                $getalwdres = $getalwd->execute();

                $upchck = 0;
                $seldataarr = [];
                $groupsPerProvider = '';
                $usersPerProvider = '';
                while ($crntrestr = $getalwdres->fetch()) {
                       if ($crntrestr['user_id'] != $userId) {
                           $seldataarr[] = ['userid' => $crntrestr['user_id'], 'groupsallowed' => $crntrestr['twl_groups_allowed'], 'usersallowed' => $crntrestr['twl_users_allowed']];
                       } else {
                           $upchck++;
                           $groupsPerProvider = $crntrestr['twl_groups_allowed'];
                           $usersPerProvider = $crntrestr['twl_users_allowed'];
                       }
                }
                $getalwdres->closeCursor();

            } elseif ($provider == "flr") {

                $getalwd = $this->connection->prepare('SELECT `user_id`, `flr_groups_allowed`, `flr_users_allowed` FROM `*PREFIX*sms_relent_subac`');
                $getalwdres = $getalwd->execute();

                $upchck = 0;
                $seldataarr = [];
                $groupsPerProvider = '';
                $usersPerProvider = '';
                while ($crntrestr = $getalwdres->fetch()) {
                       if ($crntrestr['user_id'] != $userId) {
                           $seldataarr[] = ['userid' => $crntrestr['user_id'], 'groupsallowed' => $crntrestr['flr_groups_allowed'], 'usersallowed' => $crntrestr['flr_users_allowed']];
                       } else {
                           $upchck++;
                           $groupsPerProvider = $crntrestr['flr_groups_allowed'];
                           $usersPerProvider = $crntrestr['flr_users_allowed'];
                       }
                }
                $getalwdres->closeCursor();

            }


            if ($seldataarr) {

                // Check if any of the current users are among the already saved ones (for the same provider)
                $usrchck = 0;
                $usrmsgarr = [];
                foreach ($users as $ukey => $uvalue) {
                         if ($uvalue != '') {
                             for ($j = 0; $j < count($seldataarr); $j++) {
                                  if (str_contains($seldataarr[$j]['usersallowed'], $uvalue)) {
                                      $usrchck++;
                                      $usrmsgarr[] = "The admin " . $seldataarr[$j]['userid'] . " has already allowed the user " . $uvalue . " to access his API keys for this provider.";
                                  }
                             }
                         }
                }

                // Check if any of the current groups are among the already saved ones (for the same provider)
                $grchck = 0;
                $grmsgarr = [];
                foreach ($groups as $gkey => $gvalue) {
                         if ($gvalue != '') {
                             for ($k = 0; $k < count($seldataarr); $k++) {
                                  if (str_contains($seldataarr[$k]['groupsallowed'], $gvalue)) {
                                      $grchck++;
                                      $grmsgarr[] = "The admin " . $seldataarr[$k]['userid'] . " has already allowed the group " . $gvalue . " to access his API keys for this provider.";
                                  }
                             }
                         }
                }

                if ($usrchck == 0 && $grchck == 0) {


                    // Remove the previously saved API keys for each user in the specified groups, for the current provider
                    if ($groupsPerProvider != '') {

                        $groupsPerProvarr = explode("|", $groupsPerProvider);
                        foreach ($groupsPerProvarr as $prgrkey => $prgrvalue) {

                                 if ($prgrvalue != "admin" && $prgrvalue != '') {

                                     // Get all the users that belong to the group
	                             $getusringrp = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
			             $getusringrpres = $getusringrp->execute([$prgrvalue]);

                                     $usersingroup = [];
			             while ($getusrnm = $getusringrpres->fetch()) {
                                            if ($getusrnm['uid'] != $userId) {

		                                // Ensure the current user is not an admin
                                                if (!in_array($getusrnm['uid'], $usersadmin)) {
                                                     $usersingroup[] = $getusrnm['uid'];
                                                }
                                            }
                                     }
			             $getusringrpres->closeCursor();

                                     if ($usersingroup) {
                                         $msgtosend = $this->removeusercredentials($userId, $usersingroup, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey, 
                                                                               $plivoapisecret, $plivosendernm, $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret);
                                     }
                                 }

                        }
                    }


                    // Remove the previously saved API keys for each user, for the current provider
                    if ($usersPerProvider != '') {

                        $usersPerProvarr = explode("|", $usersPerProvider);
                        if ($usersPerProvarr) {

                            $ctusernamearrpr = [];
                            foreach ($usersPerProvarr as $usrKeypr => $usrValuepr) {

		                 // Get the username for this Display Name
		                 $getacdataunmpr = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		                 $getacdataunmprres = $getacdataunmpr->execute(['displayname', $usrValuepr]);
		                 $acdatausrnamepr = $getacdataunmprres->fetch();
                                 if ($acdatausrnamepr['uid'] != $userId) {

		                     // Ensure the current user is not an admin
                                     if (!in_array($acdatausrnamepr['uid'], $usersadmin)) {
                                          $ctusernamearrpr[] = $acdatausrnamepr['uid'];
                                     }

                                 }
		                 $getacdataunmprres->closeCursor();
                            }

                            $msgtosend = $this->removeusercredentials($userId, $ctusernamearrpr, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey,
                                                                      $plivoapisecret, $plivosendernm, $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret);
                        }
                    }


                    // Insert the provider's API keys for the allowed users
                    if ($users) {

                        $ctusernamearruid = [];
                        $ctusernamearr = [];
                        foreach ($users as $usrKey => $usrValue) {
                             if ($usrValue != '') {
		                 // Get the username for this Display Name
		                 $getacdataunm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		                 $getacdataunmres = $getacdataunm->execute(['displayname', $usrValue]);
		                 $acdatausrname = $getacdataunmres->fetch();
                                 if ($acdatausrname['uid'] != $userId) {

		                     // Ensure the current user is not an admin
                                     if (!in_array($acdatausrname['uid'], $usersadmin)) {
                                         $ctusernamearruid[] = $acdatausrname['uid'];
                                         $ctusernamearr[] = $usrValue;
                                     }

                                 }
		                 $getacdataunmres->closeCursor();
                             }
                        }


                        // Insert/update the allowed users in the 'sms_relent_subac' table
                        $usersalwdrs = implode("|", $ctusernamearr);

                        if ($upchck == 0) {

		            if ($provider == "tnx") {

	                        $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `tnx_users_allowed`) VALUES (?, ?)');
	                        if ($datalwdres = $insertalwd->execute([$userId, $usersalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
                                $upchck++;

		            } elseif ($provider == "plv") {

	                        $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `plv_users_allowed`) VALUES (?, ?)');
	                        if ($datalwdres = $insertalwd->execute([$userId, $usersalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; } 
                                $upchck++;

		            } elseif ($provider == "twl") {

	                        $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `twl_users_allowed`) VALUES (?, ?)');
	                        if ($datalwdres = $insertalwd->execute([$userId, $usersalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; } 
                                $upchck++;

		            } elseif ($provider == "flr") {

	                        $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `flr_users_allowed`) VALUES (?, ?)');
	                        if ($datalwdres = $insertalwd->execute([$userId, $usersalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
                                $upchck++;
		            }

                        } else {

		            if ($provider == "tnx") {

	                        $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `tnx_users_allowed` = ? WHERE `user_id` = ?');
	                        if ($datalwdres = $updatealwd->execute([$usersalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

		            } elseif ($provider == "plv") {

	                        $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `plv_users_allowed` = ? WHERE `user_id` = ?');
	                        if ($datalwdres = $updatealwd->execute([$usersalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

		            } elseif ($provider == "twl") {

	                        $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `twl_users_allowed` = ? WHERE `user_id` = ?');
	                        if ($datalwdres = $updatealwd->execute([$usersalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

		            } elseif ($provider == "flr") {

	                        $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `flr_users_allowed` = ? WHERE `user_id` = ?');
	                        if ($datalwdres = $updatealwd->execute([$usersalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
		            }
                        }

                        $datalwdres->closeCursor();


                        // Insert/update the credentials in the 'sms_relent_settings' table, for each allowed user
                        $msgtosend = $this->updateusercredentials($userId, $ctusernamearruid, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey, 
                                                                  $plivoapisecret, $plivosendernm, $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret);
                    }

                    // Insert the provider's API keys for the allowed groups
                    if ($groups) {

                        $allwdgrps = [];
                        foreach ($groups as $groupkey => $groupvalue) {

                                 if ($groupvalue != "admin" && $groupvalue != '') {

                                     $allwdgrps[] = $groupvalue;

                                     // Get all the users that belong to the group
			             $getacdusr = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
			             $getacdusrres = $getacdusr->execute([$groupvalue]);

                                     $usersingrp = [];
			             while ($getacdusrnm = $getacdusrres->fetch()) {
                                            if ($getacdusrnm['uid'] != $userId) {

		                                // Ensure the current user is not an admin
                                                if (!in_array($getacdusrnm['uid'], $usersadmin)) {
                                                     $usersingrp[] = $getacdusrnm['uid'];
                                                }
                                            }
                                     }
			             $getacdusrres->closeCursor();

                                     // Insert the provider's API keys for each user of the allowed groups
                                     if ($usersingrp) {
                                         $msgtosend = $this->updateusercredentials($userId, $usersingrp, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey, 
                                                             $plivoapisecret, $plivosendernm, $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret);
                                     }
                                 }


		                // Insert/update the allowed groups in the 'sms_relent_subac' table
		                $groupsalwdrs = implode("|", $allwdgrps);

		                if ($upchck == 0) {

				    if ($provider == "tnx") {

			                $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `tnx_groups_allowed`) VALUES (?, ?)');
			                if ($datalwdres = $insertalwd->execute([$userId, $groupsalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
                                        $upchck++;

				    } elseif ($provider == "plv") {

			                $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `plv_groups_allowed`) VALUES (?, ?)');
			                if ($datalwdres = $insertalwd->execute([$userId, $groupsalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
                                        $upchck++;

				    } elseif ($provider == "twl") {

			                $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `twl_groups_allowed`) VALUES (?, ?)');
			                if ($datalwdres = $insertalwd->execute([$userId, $groupsalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
                                        $upchck++;

				    } elseif ($provider == "flr") {

			                $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `flr_groups_allowed`) VALUES (?, ?)');
			                if ($datalwdres = $insertalwd->execute([$userId, $groupsalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
                                        $upchck++;
				    }

		                } else {

				    if ($provider == "tnx") {

			                $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `tnx_groups_allowed` = ? WHERE `user_id` = ?');
			                if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

				    } elseif ($provider == "plv") {

			                $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `plv_groups_allowed` = ? WHERE `user_id` = ?');
			                if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

				    } elseif ($provider == "twl") {

			                $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `twl_groups_allowed` = ? WHERE `user_id` = ?');
			                if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

				    } elseif ($provider == "flr") {

			                $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `flr_groups_allowed` = ? WHERE `user_id` = ?');
			                if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
				    }
		                }

		                $datalwdres->closeCursor();
                        }

                    }

                } else {

                        if ($grmsgarr) {
                            $grppart = implode(" ", $grmsgarr) . " A group cannot be allowed access to 2 different sets of API keys for the same SMS provider.";
                        } else { $grppart = ''; }

                        if ($usrmsgarr) {
                            $usrpart = implode(" ", $usrmsgarr) . " A user cannot be allowed access to 2 different sets of API keys for the same SMS provider.";
                        } else { $usrpart = ''; }

                    $msgtosend = $grppart . $usrpart;
                }


            } else {

                if ($upchck == 0) {

                    // Insert the provider's API keys for the allowed users
                    if ($users) {

                        $ctusernamearruid = [];
                        $ctusernamearr = [];
                        foreach ($users as $usrKey => $usrValue) {
                             if ($usrValue != '') {
		                 // Get the username for this Display Name
		                 $getacdataunm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		                 $getacdataunmres = $getacdataunm->execute(['displayname', $usrValue]);
		                 $acdatausrname = $getacdataunmres->fetch();
                                 if ($acdatausrname['uid'] != $userId) {

		                     // Ensure the current user is not an admin
                                     if (!in_array($acdatausrname['uid'], $usersadmin)) {
                                         $ctusernamearruid[] = $acdatausrname['uid'];
                                         $ctusernamearr[] = $usrValue;
                                     }

                                 }
		                 $getacdataunmres->closeCursor();
                             }
                        }


                        // Insert the allowed users into the 'sms_relent_subac' table
                        $usersalwdrs = implode("|", $ctusernamearr);

		        if ($provider == "tnx") {

	                    $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `tnx_users_allowed`) VALUES (?, ?)');
	                    if ($datalwdres = $insertalwd->execute([$userId, $usersalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; } 
                            $upchck++;

		        } elseif ($provider == "plv") {

	                    $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `plv_users_allowed`) VALUES (?, ?)');
	                    if ($datalwdres = $insertalwd->execute([$userId, $usersalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
                            $upchck++;

		        } elseif ($provider == "twl") {

	                    $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `twl_users_allowed`) VALUES (?, ?)');
	                    if ($datalwdres = $insertalwd->execute([$userId, $usersalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
                            $upchck++;

		        } elseif ($provider == "flr") {

	                    $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `flr_users_allowed`) VALUES (?, ?)');
	                    if ($datalwdres = $insertalwd->execute([$userId, $usersalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
                            $upchck++;
		        }

                        $datalwdres->closeCursor();


                        // Insert/update the credentials in the 'sms_relent_settings' table, for each allowed user
                        $msgtosend = $this->updateusercredentials($userId, $ctusernamearruid, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey, 
                                                                  $plivoapisecret, $plivosendernm, $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret);
                    }

                    // Insert the provider's API keys for the allowed groups
                    if ($groups) {

                        $allwdgrps = [];
                        foreach ($groups as $groupkey => $groupvalue) {

                                 if ($groupvalue != "admin" && $groupvalue != '') {

                                     $allwdgrps[] = $groupvalue;

                                     // Get all the users that belong to the group
			             $getacdusr = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
			             $getacdusrres = $getacdusr->execute([$groupvalue]);

                                     $usersingrp = [];
			             while ($getacdusrnm = $getacdusrres->fetch()) {
                                            if ($getacdusrnm['uid'] != $userId) {

		                                // Ensure the current user is not an admin
                                                if (!in_array($getacdusrnm['uid'], $usersadmin)) {
                                                     $usersingrp[] = $getacdusrnm['uid'];
                                                }
                                            }
                                     }
			             $getacdusrres->closeCursor();

                                     // Insert the provider's API keys for each user of the allowed groups
                                     if ($usersingrp) {
                                         $msgtosend = $this->updateusercredentials($userId, $usersingrp, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey, 
                                                             $plivoapisecret, $plivosendernm, $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret);
                                     }
                                 }


		                // Insert the allowed groups into the 'sms_relent_subac' table
		                $groupsalwdrs = implode("|", $allwdgrps);

                                if ($upchck == 0) {

				    if ($provider == "tnx") {

			                $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `tnx_groups_allowed`) VALUES (?, ?)');
			                if ($datalwdres = $insertalwd->execute([$userId, $groupsalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; } 

				    } elseif ($provider == "plv") {

			                $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `plv_groups_allowed`) VALUES (?, ?)');
			                if ($datalwdres = $insertalwd->execute([$userId, $groupsalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; } 

				    } elseif ($provider == "twl") {

			                $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `twl_groups_allowed`) VALUES (?, ?)');
			                if ($datalwdres = $insertalwd->execute([$userId, $groupsalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; } 

				    } elseif ($provider == "flr") {

			                $insertalwd = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_subac` (`user_id`, `flr_groups_allowed`) VALUES (?, ?)');
			                if ($datalwdres = $insertalwd->execute([$userId, $groupsalwdrs])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; } 
				    }

                                } else {

				    if ($provider == "tnx") {

			                $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `tnx_groups_allowed` = ? WHERE `user_id` = ?');
			                if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

				    } elseif ($provider == "plv") {

			                $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `plv_groups_allowed` = ? WHERE `user_id` = ?');
			                if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

				    } elseif ($provider == "twl") {

			                $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `twl_groups_allowed` = ? WHERE `user_id` = ?');
			                if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

				    } elseif ($provider == "flr") {

			                $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `flr_groups_allowed` = ? WHERE `user_id` = ?');
			                if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
				    }

                                }

		                $datalwdres->closeCursor();
                        }

                    }

                } else {

                    // Remove the previously saved API keys for each user in the specified groups, for the current provider
                    if ($groupsPerProvider != '') {

                        $groupsPerProvarr = explode("|", $groupsPerProvider);
                        foreach ($groupsPerProvarr as $prgrkey => $prgrvalue) {

                                 if ($prgrvalue != "admin" && $prgrvalue != '') {

                                     // Get all the users that belong to the group
	                             $getusringrp = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
			             $getusringrpres = $getusringrp->execute([$prgrvalue]);

                                     $usersingroup = [];
			             while ($getusrnm = $getusringrpres->fetch()) {
                                            if ($getusrnm['uid'] != $userId) {

		                                // Ensure the current user is not an admin
                                                if (!in_array($getusrnm['uid'], $usersadmin)) {
                                                     $usersingroup[] = $getusrnm['uid'];
                                                }
                                            }
                                     }
			             $getusringrpres->closeCursor();

                                     if ($usersingroup) {
                                         $msgtosend = $this->removeusercredentials($userId, $usersingroup, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey, 
                                                             $plivoapisecret, $plivosendernm, $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret);
                                     }
                                 }

                        }
                    }


                    // Remove the previously saved API keys for each user, for the current provider
                    if ($usersPerProvider != '') {

                        $usersPerProvarr = explode("|", $usersPerProvider);
                        if ($usersPerProvarr) {

                            $ctusernamearrpr = [];
                            foreach ($usersPerProvarr as $usrKeypr => $usrValuepr) {

		                 // Get the username for this Display Name
		                 $getacdataunmpr = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		                 $getacdataunmprres = $getacdataunmpr->execute(['displayname', $usrValuepr]);
		                 $acdatausrnamepr = $getacdataunmprres->fetch();
                                 if ($acdatausrnamepr['uid'] != $userId) {

		                     // Ensure the current user is not an admin
                                     if (!in_array($acdatausrnamepr['uid'], $usersadmin)) {
                                          $ctusernamearrpr[] = $acdatausrnamepr['uid'];
                                     }

                                 }
		                 $getacdataunmprres->closeCursor();
                            }

                            $msgtosend = $this->removeusercredentials($userId, $ctusernamearrpr, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey,
                                                                      $plivoapisecret, $plivosendernm, $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret);
                        }
                    }



                    // Insert the provider's API keys for the allowed users
                    if ($users) {

                        $ctusernamearruid = [];
                        $ctusernamearr = [];
                        foreach ($users as $usrKey => $usrValue) {
                             if ($usrValue != '') {
		                 // Get the username for this Display Name
		                 $getacdataunm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		                 $getacdataunmres = $getacdataunm->execute(['displayname', $usrValue]);
		                 $acdatausrname = $getacdataunmres->fetch();
                                 if ($acdatausrname['uid'] != $userId) {

		                     // Ensure the current user is not an admin
                                     if (!in_array($acdatausrname['uid'], $usersadmin)) {
                                         $ctusernamearruid[] = $acdatausrname['uid'];
                                         $ctusernamearr[] = $usrValue;

                                     }

                                 }
		                 $getacdataunmres->closeCursor();
                             }
                        }


                        // Update the allowed users in the 'sms_relent_subac' table
                        $usersalwdrs = implode("|", $ctusernamearr);

		        if ($provider == "tnx") {

	                    $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `tnx_users_allowed` = ? WHERE `user_id` = ?');
	                    if ($datalwdres = $updatealwd->execute([$usersalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

		        } elseif ($provider == "plv") {

	                    $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `plv_users_allowed` = ? WHERE `user_id` = ?');
	                    if ($datalwdres = $updatealwd->execute([$usersalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

		        } elseif ($provider == "twl") {

	                    $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `twl_users_allowed` = ? WHERE `user_id` = ?');
	                    if ($datalwdres = $updatealwd->execute([$usersalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

		        } elseif ($provider == "flr") {

	                    $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `flr_users_allowed` = ? WHERE `user_id` = ?');
	                    if ($datalwdres = $updatealwd->execute([$usersalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
		        }

                        $datalwdres->closeCursor();


                        // Insert/update the credentials in the 'sms_relent_settings' table, for each allowed user
                        $msgtosend = $this->updateusercredentials($userId, $ctusernamearruid, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey, 
                                                                  $plivoapisecret, $plivosendernm, $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret);
                    }

                    // Insert the provider's API keys for the allowed groups
                    if ($groups) {

                        $allwdgrps = [];
                        foreach ($groups as $groupkey => $groupvalue) {

                                 if ($groupvalue != "admin" && $groupvalue != '') {

                                     $allwdgrps[] = $groupvalue;

                                     // Get all the users that belong to the group
			             $getacdusr = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
			             $getacdusrres = $getacdusr->execute([$groupvalue]);

                                     $usersingrp = [];
			             while ($getacdusrnm = $getacdusrres->fetch()) {
                                            if ($getacdusrnm['uid'] != $userId) {

		                                // Ensure the current user is not an admin
                                                if (!in_array($getacdusrnm['uid'], $usersadmin)) {
                                                     $usersingrp[] = $getacdusrnm['uid'];
                                                }
                                            }
                                     }
			             $getacdusrres->closeCursor();

                                     // Insert the provider's API keys for each user of the allowed groups
                                     if ($usersingrp) {
                                         $msgtosend = $this->updateusercredentials($userId, $usersingrp, $provider, $telapiKey, $telpubKey, $telmsgprofid, $telsendername, $plivoapikey, 
                                                             $plivoapisecret, $plivosendernm, $twilapikey, $twilapisecret, $twilsendernm, $flowapikey, $flowapisecret);
                                     }
                                 }


		                 // Update the allowed groups in the 'sms_relent_subac' table
		                 $groupsalwdrs = implode("|", $allwdgrps);

				 if ($provider == "tnx") {

			             $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `tnx_groups_allowed` = ? WHERE `user_id` = ?');
			             if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

				 } elseif ($provider == "plv") {

			             $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `plv_groups_allowed` = ? WHERE `user_id` = ?');
			             if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

				 } elseif ($provider == "twl") {

			             $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `twl_groups_allowed` = ? WHERE `user_id` = ?');
			             if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }

				 } elseif ($provider == "flr") {

			             $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `flr_groups_allowed` = ? WHERE `user_id` = ?');
			             if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $userId])) { $msgtosend = 'success'; } else { $msgtosend = 'failure'; }
				 }

		                 $datalwdres->closeCursor();
                        }

                    }

                }

            }

          } else { $msgtosend = "You have to save your credentials first, by clicking the 'Save' button at the bottom of this page, and then share your API keys with other users."; }

          return $msgtosend;
       }
     }


     public function removenumberrestrictions($userId, $phoneNumber) {

        if ($this->groupManager->isAdmin($userId)) {

                // Remove the restrictions for the given phone number
		$delrstr = $this->connection->prepare('
		       DELETE FROM `*PREFIX*sms_relent_restrict`
		       WHERE `phone_number` = ?');
                if ($delrstrres = $delrstr->execute([$phoneNumber])) { $delresult = "success"; } else { $delresult = "failure"; }
		$delrstrres->closeCursor();

	        $updateind = $this->connection->prepare('
                       SET @resetrec = 0;
		       UPDATE `*PREFIX*sms_relent_restrict`
		       SET `id` = @resetrec := @resetrec + 1;
                       ALTER TABLE `*PREFIX*sms_relent_restrict` auto_increment=1;');
	        $updateindres = $updateind->execute();
	        $updateindres->closeCursor();

                return $delresult;
        }
     }


    /**
     * @NoAdminRequired
     */
    public function updateautoreplies($userId, $savedByDsplname, $phoneNumber, $daysOfWeek, $dailyStart, $dailyEnd, $vacationStart, $vacationEnd, $messageText) {

        // Get the auto-reply for the current number from the 'sms_relent_autorply' table
        $getarpl = $this->connection->prepare('SELECT `user_id`, `saved_by_dsplname`, `phone_number`, `days_of_week`, `daily_start`, `daily_end`, `vacation_start`,
                                              `vacation_end`, `message_text` FROM `*PREFIX*sms_relent_autorply` WHERE `phone_number` = ?');
        $getarplresult = $getarpl->execute([$phoneNumber]);
        $crntarpl = $getarplresult->fetch();
        $getarplresult->closeCursor();

        if ($getarplresult && !$crntarpl) {

	    $insertpharpl = $this->connection->prepare('INSERT INTO `*PREFIX*sms_relent_autorply` (`user_id`, `saved_by_dsplname`, `phone_number`, `days_of_week`, 
                                                       `daily_start`, `daily_end`, `vacation_start`, `vacation_end`, `message_text`) VALUES
                                                        (?, ?, ?, ?, ?, ?, ?, ?, ?)');
	    if ($insertpharpl->execute([$userId, $savedByDsplname, $phoneNumber, $daysOfWeek, $dailyStart, $dailyEnd, $vacationStart, $vacationEnd, $messageText])) { 
                $messagetosend = 'success'; 
            } else { 
                $messagetosend = 'failure'; 
            }
         
        } elseif ($getarplresult && $crntarpl) {

            if ($this->groupManager->isAdmin($userId)) {

                $updatepharpl = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_autorply` SET `user_id` = ?, `saved_by_dsplname` = ?, `days_of_week` = ?, `daily_start` = ?,
                                                           `daily_end` = ?, `vacation_start` = ?, `vacation_end` = ?, `message_text` = ?  WHERE `phone_number` = ?');
	        if ($updatephnmbrarpl = $updatepharpl->execute([$userId, $savedByDsplname, $daysOfWeek, $dailyStart, $dailyEnd, $vacationStart, $vacationEnd, $messageText,
                                                                $phoneNumber])) { 
                    $messagetosend = 'success';
                } else { 
                    $messagetosend = 'failure'; 
                }
	        $updatephnmbrarpl->closeCursor();

            } else {

                // Check if the current user is the author of the existing version of the auto-reply
                if ($userId == $crntarpl['user_id']) {

                    $updatepharpl = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_autorply` SET `user_id` = ?, `saved_by_dsplname` = ?, `days_of_week` = ?, `daily_start` = ?,
                                                               `daily_end` = ?, `vacation_start` = ?, `vacation_end` = ?, `message_text` = ?  WHERE `phone_number` = ?');
	            if ($updatephnmbrarpl = $updatepharpl->execute([$userId, $savedByDsplname, $daysOfWeek, $dailyStart, $dailyEnd, $vacationStart, $vacationEnd, $messageText,
                                                                    $phoneNumber])) { 
                        $messagetosend = 'success';
                    } else { 
                        $messagetosend = 'failure'; 
                    }
	            $updatephnmbrarpl->closeCursor();

                } else { $messagetosend = 'not allowed'; }
            }
        }

        return $messagetosend;
    }


    /**
     * @NoAdminRequired
     */
    public function removeautoreplies($userId, $phoneNumber) {

        if ($this->groupManager->isAdmin($userId)) {

                // Remove the auto-reply for the given phone number
		$delarpl = $this->connection->prepare('
		       DELETE FROM `*PREFIX*sms_relent_autorply`
		       WHERE `phone_number` = ?');
                if ($delarplres = $delarpl->execute([$phoneNumber])) { $delarplresult = "success"; } else { $delarplresult = "failure"; }
		$delarplres->closeCursor();

	        $updateindarpl = $this->connection->prepare('
                       SET @resetarpl = 0;
		       UPDATE `*PREFIX*sms_relent_autorply`
		       SET `id` = @resetarpl := @resetarpl + 1;
                       ALTER TABLE `*PREFIX*sms_relent_autorply` auto_increment=1;');
	        $updateindarplres = $updateindarpl->execute();
	        $updateindarplres->closeCursor();

                return $delarplresult;

        } else {
                // Get the author of the auto-reply for the given phone number
		$getarplusr = $this->connection->prepare('SELECT `user_id`, `phone_number` FROM `*PREFIX*sms_relent_autorply` WHERE `phone_number` = ?');
		$getarplusrres = $getarplusr->execute([$phoneNumber]);
		$crntarpldata = $getarplusrres->fetch();
                $crntarpluser = $crntarpldata['user_id'];
		$getarplusrres->closeCursor();

                // If the author of the auto-reply is the current user, allow the removal
                if ($crntarpluser == $userId) {

                    // Remove the auto-reply for the given phone number
		    $delarpl = $this->connection->prepare('
		           DELETE FROM `*PREFIX*sms_relent_autorply`
		           WHERE `phone_number` = ?');
                    if ($delarplres = $delarpl->execute([$phoneNumber])) { $delarplresult = "success"; } else { $delarplresult = "failure"; }
		    $delarplres->closeCursor();

	            $updateindarpl = $this->connection->prepare('
                           SET @resetarpl = 0;
		           UPDATE `*PREFIX*sms_relent_autorply`
		           SET `id` = @resetarpl := @resetarpl + 1;
                           ALTER TABLE `*PREFIX*sms_relent_autorply` auto_increment=1;');
	            $updateindarplres = $updateindarpl->execute();
	            $updateindarplres->closeCursor();

                    return $delarplresult;

                } else { 
                    return $delarplresult = 'not allowed';
                }
        }
    }


    public function getadminsettings($userId) {

        if ($this->groupManager->isAdmin($userId)) {


	    $getsettings = $this->connection->prepare('
                            SELECT `id`, `user_id`, `telapi_key`, `tel_pub_key`, `telapi_url_rec`, `telapi_url`, `messaging_profile_id`, `nexapi_key`, `nexapi_secret`, `nexapi_url_rec`,
                                   `nexapi_url`, `twilapi_key`, `twilapi_secret`, `twilapi_url_rec`, `twilapi_url`, `flowapi_key`, `flowapi_secret`, `flowapi_url_rec`, `flowapi_url`, 
                                   `tel_sender_name`, `nex_sender_name`, `twil_sender_name`, `flow_sender_name`, `messagesperpage`, `get_notify`, `notification_email`, `getsmsinemail`, 
                                   `show_all_messages`
			    FROM  `*PREFIX*sms_relent_settings`
			    WHERE `user_id` = ?');

	    $resultsettings = $getsettings->execute([$userId]);

            $settingsadm = $resultsettings->fetch();

	    $resultsettings->closeCursor();

	    if ($settingsadm) {

		    if ($settingsadm['telapi_key'] != '') {

		        // Send a placeholder to the browser, instead of the real API key
		        $settingsadm['telapi_key'] = "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20";
		    }
		    if ($settingsadm['tel_pub_key'] != '') {
		        $settingsadm['tel_pub_key'] = "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20";
		    }
		    if ($settingsadm['messaging_profile_id'] != '') {
		        $settingsadm['messaging_profile_id'] = "%20%20%20%20%20%20%20%20%20%20%20%20";
		    }
		    if ($settingsadm['nexapi_key'] != '') {
		        $settingsadm['nexapi_key'] = "%20%20%20%20%20%20%20%20%20";
		    }
		    if ($settingsadm['nexapi_secret'] != '') {
		        $settingsadm['nexapi_secret'] = "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20";
		    }
		    if ($settingsadm['twilapi_key'] != '') {
		        $settingsadm['twilapi_key'] = "%20%20%20%20%20%20%20%20%20";
		    }
		    if ($settingsadm['twilapi_secret'] != '') {
		        $settingsadm['twilapi_secret'] = "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20";
		    }
		    if ($settingsadm['flowapi_key'] != '') {
		        $settingsadm['flowapi_key'] = "%20%20%20%20%20%20%20%20%20";
		    }
		    if ($settingsadm['flowapi_secret'] != '') {
		        $settingsadm['flowapi_secret'] = "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20";
		    }


		    // Get the Display Name of the current admin
		    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
		    $getacdatadnres = $getacdatadn->execute([$userId, 'displayname']);
		    $acdatausrdnadm = $getacdatadnres->fetch();
		    $cruserdname = $acdatausrdnadm['value'];
		    $getacdatadnres->closeCursor();

		    // Get all the restrictions on phone numbers
		    $getrestr = $this->connection->prepare('SELECT `saved_by_dsplname`, `phone_number`, `groups`, `users` FROM `*PREFIX*sms_relent_restrict`');
		    $getrestres = $getrestr->execute();

		    $restrictedArr = [];
		    while ($restrfetched = $getrestres->fetch()) {
		           $restrictedArr[] = $restrfetched;
		    }
		    $getrestres->closeCursor();

		    if ($restrictedArr) { $restrictedUsers = $restrictedArr; } else { $restrictedUsers = ''; }


		    // Get the name of all the groups
		    $getgroups = $this->connection->prepare('SELECT `gid`, `displayname` FROM `*PREFIX*groups`');
		    $getgroupsres = $getgroups->execute();

		    $groupsArr = [];
                    $allgroupswadmarr = [];
		    while ($groupsfetched = $getgroupsres->fetch()) {

		           $groupsArr[] = $groupsfetched['gid'];
                           if ($groupsfetched['gid'] != 'admin') { $allgroupswadmarr[] = $groupsfetched['gid']; }
		    }
		    $getgroupsres->closeCursor();

		    if ($groupsArr) { $allgroups = $groupsArr; } else { $allgroups = ''; }
                    if ($allgroupswadmarr) { $allgroupswadm = $allgroupswadmarr; } else { $allgroupswadm = ''; }

		    // Get the users that belong to the 'admin' group
		    $getadmnsc = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
		    $getadmnscres = $getadmnsc->execute(['admin']);

		    $usersadminsc = [];
		    while ($getadmnusrsc = $getadmnscres->fetch()) {
		           $usersadminsc[] = $getadmnusrsc['uid'];
		    }
		    $getadmnscres->closeCursor();


		    // Get the display name of all the users
		    $getusers = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ?');
		    $getusersres = $getusers->execute(['displayname']);

		    $usersArr = [];
                    $alluserswadmarr = [];
		    while ($usersfetched = $getusersres->fetch()) {

		           $usersArr[] = $usersfetched['value'];
                           if (!in_array($usersfetched['uid'], $usersadminsc)) { $alluserswadmarr[] = $usersfetched['value']; }
		    }
		    $getusersres->closeCursor();

		    if ($usersArr) { $allusers = $usersArr; } else { $allusers = ''; }
                    if ($alluserswadmarr) { $alluserswadm = $alluserswadmarr; } else { $alluserswadm = ''; }

                    // Get the groups and users that are allowed to use the API Keys, for each provider
                    $getalwdall = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed`, `tnx_users_allowed`, `plv_groups_allowed`, `plv_users_allowed`,
                                                             `twl_groups_allowed`, `twl_users_allowed`, `flr_groups_allowed`, `flr_users_allowed` FROM `*PREFIX*sms_relent_subac`
                                                              WHERE `user_id` = ?');
                    $getalwdallres = $getalwdall->execute([$userId]);
                    $crtdtrow = $getalwdallres->fetch();
                    if ($crtdtrow) {
                        $allowedgrps = ['tnx_groups_allowed' => $crtdtrow['tnx_groups_allowed'], 'tnx_users_allowed' => $crtdtrow['tnx_users_allowed'], 
                                        'plv_groups_allowed' => $crtdtrow['plv_groups_allowed'], 'plv_users_allowed' => $crtdtrow['plv_users_allowed'],
                                        'twl_groups_allowed' => $crtdtrow['twl_groups_allowed'], 'twl_users_allowed' => $crtdtrow['twl_users_allowed'],
                                        'flr_groups_allowed' => $crtdtrow['flr_groups_allowed'], 'flr_users_allowed' => $crtdtrow['flr_users_allowed']];
                        $getalwdallres->closeCursor();
                    } else { $allowedgrps = []; }


                    $settingsadm['admdisplayname'] = $cruserdname;
                    $settingsadm['restrictions'] = $restrictedUsers;
                    $settingsadm['allgroups'] = $allgroups;
                    $settingsadm['allusers'] = $allusers;
                    $settingsadm['allgroupswadm'] = $allgroupswadm;
                    $settingsadm['alluserswadm'] = $alluserswadm;  
                    $settingsadm['allowedkeysuse'] = $allowedgrps;

		    return $settingsadm;
	    }
        }
     }


     /**
      * @NoAdminRequired
      *
      */
     public function updatesettings($userId, $telapiUrlRec, $telapiUrl, $nexapiUrlRec, $nexapiUrl, $twilapiUrlRec, $twilapiUrl, $flowapiUrlRec, $flowapiUrl, $messagesperpage, 
                                    $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval) {
        $upsettings = $this->connection->prepare('
                        SELECT `id`, `user_id`, `telapi_key`, `tel_pub_key`, `telapi_url_rec`, `telapi_url`, `messaging_profile_id`, `nexapi_key`, `nexapi_secret`, `nexapi_url_rec`,
                           `nexapi_url`, `twilapi_key`, `twilapi_secret`, `twilapi_url_rec`, `twilapi_url`, `flowapi_key`, `flowapi_secret`, `flowapi_url_rec`, `flowapi_url`, 
                           `tel_sender_name`, `nex_sender_name`, `twil_sender_name`, `flow_sender_name`, `messagesperpage`, `get_notify`, `notification_email`, `getsmsinemail`, 
                           `show_all_messages`, `show_display_names`, `add_display_names`, `available_numbers`, `msg_check_interval`, `new_message_rcd`
		        FROM  `*PREFIX*sms_relent_settings`
		        WHERE `user_id` = ?');

        $resultstng = $upsettings->execute([$userId]);

        $rowup = $resultstng->fetch();

        $resultstng->closeCursor();

        if ($resultstng && !$rowup) {

	    $sql = $this->connection->prepare('
				INSERT INTO `*PREFIX*sms_relent_settings`
					(`user_id`, `telapi_url_rec`, `telapi_url`, `nexapi_url_rec`, `nexapi_url`, `twilapi_url_rec`, `twilapi_url`, `flowapi_url_rec`, `flowapi_url`, 
                                         `messagesperpage`, `get_notify`, `notification_email`, `getsmsinemail`, `show_display_names`, `add_display_names`, `msg_check_interval`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
			');
	    $sql->execute([$userId, $telapiUrlRec, $telapiUrl, $nexapiUrlRec, $nexapiUrl, $twilapiUrlRec, $twilapiUrl, $flowapiUrlRec, $flowapiUrl, $messagesperpage, $getNotify, 
                           $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval]);

        } elseif ($resultstng && $rowup) {

	    $sqlupdatedb = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_settings`
			SET `telapi_url_rec` = ?, `telapi_url` = ?, `nexapi_url_rec` = ?, `nexapi_url` = ?, `twilapi_url_rec` = ?, `twilapi_url` = ?, `flowapi_url_rec` = ?, 
                            `flowapi_url` = ?, `messagesperpage` = ?, `get_notify` = ?, `notification_email` = ?, `getsmsinemail` = ?, `show_display_names` = ?, `add_display_names` = ?,
                            `msg_check_interval` = ?
	                WHERE `user_id` = ?');
	    $updateRes = $sqlupdatedb->execute([$telapiUrlRec, $telapiUrl, $nexapiUrlRec, $nexapiUrl, $twilapiUrlRec, $twilapiUrl, $flowapiUrlRec, $flowapiUrl, $messagesperpage, 
                                                $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval, $userId]);
	    $updateRes->closeCursor();

	}
     }


     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) {

        if ($this->groupManager->isAdmin($userId)) {

            $upsettings = $this->connection->prepare('
                        SELECT `id`, `user_id`, `telapi_key`, `tel_pub_key`, `telapi_url_rec`, `telapi_url`, `messaging_profile_id`, `nexapi_key`, `nexapi_secret`, `nexapi_url_rec`,
                           `nexapi_url`, `twilapi_key`, `twilapi_secret`, `twilapi_url_rec`, `twilapi_url`, `flowapi_key`, `flowapi_secret`, `flowapi_url_rec`, `flowapi_url`, 
                           `tel_sender_name`, `nex_sender_name`, `twil_sender_name`, `flow_sender_name`, `messagesperpage`, `get_notify`, `notification_email`, `getsmsinemail`, 
                           `show_all_messages`, `show_display_names`, `add_display_names`
		        FROM  `*PREFIX*sms_relent_settings`
		        WHERE `user_id` = ?');

            $resultstng = $upsettings->execute([$userId]);

            $rowup = $resultstng->fetch();

            $resultstng->closeCursor();

            if ($resultstng && !$rowup) {

	        if ($telapiKey != '') {
	            $telapikeystrenc = $this->crypto->encrypt($telapiKey);             
	        } else { $telapikeystrenc = ''; }

	        if ($telPubKey != '') {
	            $telpubkeystrenc =  $this->crypto->encrypt($telPubKey);             
	        } else { $telpubkeystrenc = ''; }

	        if ($messagingProfileId != '') {
	            $messagingprofenc = $this->crypto->encrypt($messagingProfileId);             
	        } else { $messagingprofenc = ''; }

	        if ($nexapiKey != '') {
	            $nexapikeystrenc = $this->crypto->encrypt($nexapiKey);             
	        } else { $nexapikeystrenc = ''; }

	        if ($nexapiSecret != '') {
	            $nexapisecretstrenc = $this->crypto->encrypt($nexapiSecret);             
	        } else { $nexapisecretstrenc = ''; }

	        if ($twilapiKey != '') {
	            $twilapikeystrenc = $this->crypto->encrypt($twilapiKey);             
	        } else { $twilapikeystrenc = ''; }

	        if ($twilapiSecret != '') {
	            $twilapisecretstrenc = $this->crypto->encrypt($twilapiSecret);             
	        } else { $twilapisecretstrenc = ''; }

	        if ($flowapiKey != '') {
	            $flowapikeystrenc = $this->crypto->encrypt($flowapiKey);             
	        } else { $flowapikeystrenc = ''; }

	        if ($flowapiSecret != '') {
	            $flowapisecretstrenc = $this->crypto->encrypt($flowapiSecret);             
	        } else { $flowapisecretstrenc = ''; }


	        $sql = $this->connection->prepare('
				INSERT INTO `*PREFIX*sms_relent_settings`
					(`user_id`, `telapi_key`, `tel_pub_key`, `telapi_url_rec`, `telapi_url`, `messaging_profile_id`, `nexapi_key`, `nexapi_secret`, `nexapi_url_rec`, 
	                                 `nexapi_url`, `tel_sender_name`, `nex_sender_name`, `twilapi_key`, `twilapi_secret`, `twilapi_url_rec`, `twilapi_url`, `twil_sender_name`, 
                                         `flowapi_key`, `flowapi_secret`, `flowapi_url_rec`, `flowapi_url`, `show_all_messages`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
			');
	        $sql->execute([$userId, $telapikeystrenc, $telpubkeystrenc, $telapiUrlRec, $telapiUrl, $messagingprofenc, $nexapikeystrenc, $nexapisecretstrenc, $nexapiUrlRec, 
                               $nexapiUrl, $telSenderName, $nexSenderName, $twilapikeystrenc, $twilapisecretstrenc, $twilapiUrlRec, $twilapiUrl, $twilSenderName, $flowapikeystrenc, 
                               $flowapisecretstrenc, $flowapiUrlRec, $flowapiUrl, $showAllMessages]);

            } elseif ($resultstng && $rowup) {

	        // Check if the value of the field is the placeholder or an empty string
	        if ($telapiKey != '' && $telapiKey != "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $telapikeystrenc = $this->crypto->encrypt($telapiKey);                
	        } elseif ($telapiKey == "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $telapikeystrenc = $rowup['telapi_key'];
	        } elseif ($telapiKey == '') {
	            $telapikeystrenc = '';
	        }

	        if ($telPubKey != '' && $telPubKey != "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $telpubkeystrenc = $this->crypto->encrypt($telPubKey);                
	        } elseif ($telPubKey == "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $telpubkeystrenc = $rowup['tel_pub_key'];
	        } elseif ($telPubKey == '') {
	            $telpubkeystrenc = '';
	        }

	        if ($messagingProfileId != '' && $messagingProfileId != "%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $messagingprofenc = $this->crypto->encrypt($messagingProfileId);                
	        } elseif ($messagingProfileId == "%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $messagingprofenc = $rowup['messaging_profile_id'];
	        } elseif ($messagingProfileId == '') {
	            $messagingprofenc = '';
	        }

	        if ($nexapiKey != '' && $nexapiKey != "%20%20%20%20%20%20%20%20%20") {
	            $nexapikeystrenc = $this->crypto->encrypt($nexapiKey);                
	        } elseif ($nexapiKey == "%20%20%20%20%20%20%20%20%20") {
	            $nexapikeystrenc = $rowup['nexapi_key'];
	        } elseif ($nexapiKey == '') {
	            $nexapikeystrenc = '';
	        }

	        if ($twilapiKey != '' && $twilapiKey != "%20%20%20%20%20%20%20%20%20") {
	            $twilapikeystrenc = $this->crypto->encrypt($twilapiKey);                
	        } elseif ($twilapiKey == "%20%20%20%20%20%20%20%20%20") {
	            $twilapikeystrenc = $rowup['twilapi_key'];
	        } elseif ($twilapiKey == '') {
	            $twilapikeystrenc = '';
	        }

	        if ($flowapiKey != '' && $flowapiKey != "%20%20%20%20%20%20%20%20%20") {
	            $flowapikeystrenc = $this->crypto->encrypt($flowapiKey);                
	        } elseif ($flowapiKey == "%20%20%20%20%20%20%20%20%20") {
	            $flowapikeystrenc = $rowup['flowapi_key'];
	        } elseif ($flowapiKey == '') {
	            $flowapikeystrenc = '';
	        }

	        if ($nexapiSecret != '' && $nexapiSecret != "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $nexapisecretstrenc = $this->crypto->encrypt($nexapiSecret);                
	        } elseif ($nexapiSecret == "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $nexapisecretstrenc = $rowup['nexapi_secret'];
	        } elseif ($nexapiSecret == '') {
	            $nexapisecretstrenc = '';
	        }

	        if ($twilapiSecret != '' && $twilapiSecret != "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $twilapisecretstrenc = $this->crypto->encrypt($twilapiSecret);                
	        } elseif ($twilapiSecret == "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $twilapisecretstrenc = $rowup['twilapi_secret'];
	        } elseif ($twilapiSecret == '') {
	            $twilapisecretstrenc = '';
	        }

	        if ($flowapiSecret != '' && $flowapiSecret != "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $flowapisecretstrenc = $this->crypto->encrypt($flowapiSecret);                
	        } elseif ($flowapiSecret == "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
	            $flowapisecretstrenc = $rowup['flowapi_secret'];
	        } elseif ($flowapiSecret == '') {
	            $flowapisecretstrenc = '';
	        }

	        $sqlupdatedb = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_settings`
			SET `telapi_key` = ?, `tel_pub_key` = ?, `telapi_url_rec` = ?, `telapi_url` = ?, `messaging_profile_id` = ?, `nexapi_key` = ?, `nexapi_secret` = ?,
	                    `nexapi_url_rec` = ?, `nexapi_url` = ?, `tel_sender_name` = ?, `nex_sender_name` = ?, `twilapi_key` = ?, `twilapi_secret` = ?, `twilapi_url_rec` = ?, `twilapi_url` = ?, `twil_sender_name` = ?, `flowapi_key` = ?, 
	                    `flowapi_secret` = ?, `flowapi_url_rec` = ?, `flowapi_url` = ?, `show_all_messages` = ?
	                WHERE `user_id` = ?');
	        $updateRes = $sqlupdatedb->execute([$telapikeystrenc, $telpubkeystrenc, $telapiUrlRec, $telapiUrl, $messagingprofenc, $nexapikeystrenc, $nexapisecretstrenc, 
                                                    $nexapiUrlRec, $nexapiUrl, $telSenderName, $nexSenderName, $twilapikeystrenc, $twilapisecretstrenc, $twilapiUrlRec, $twilapiUrl, 
                                                    $twilSenderName, $flowapikeystrenc, $flowapisecretstrenc, $flowapiUrlRec, $flowapiUrl, $showAllMessages, $userId]);
	        $updateRes->closeCursor();

	    }
        }
     }


     public function updatepersadmnsettings($userId, $messagesperpage, $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval) {

        if ($this->groupManager->isAdmin($userId)) {

            $upsettings = $this->connection->prepare('
                        SELECT `id`, `user_id`, `telapi_key`, `tel_pub_key`, `telapi_url_rec`, `telapi_url`, `messaging_profile_id`, `nexapi_key`, `nexapi_secret`, `nexapi_url_rec`,
                           `nexapi_url`, `twilapi_key`, `twilapi_secret`, `twilapi_url_rec`, `twilapi_url`, `flowapi_key`, `flowapi_secret`, `flowapi_url_rec`, `flowapi_url`, 
                           `tel_sender_name`, `nex_sender_name`, `twil_sender_name`, `flow_sender_name`, `messagesperpage`, `get_notify`, `notification_email`, `getsmsinemail`, 
                           `show_all_messages`, `show_display_names`, `add_display_names`, `available_numbers`, `msg_check_interval`, `new_message_rcd`
		        FROM  `*PREFIX*sms_relent_settings`
		        WHERE `user_id` = ?');

            $resultstng = $upsettings->execute([$userId]);

            $rowup = $resultstng->fetch();

            $resultstng->closeCursor();

            if ($resultstng && !$rowup) {

	        $sql = $this->connection->prepare('
				INSERT INTO `*PREFIX*sms_relent_settings` (`user_id`, `messagesperpage`, `get_notify`, `notification_email`, `getsmsinemail`, `show_display_names`,
                                `add_display_names`, `msg_check_interval`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
	        $sql->execute([$userId, $messagesperpage, $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval]);

            } elseif ($resultstng && $rowup) {

	        $sqlupdatedb = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_settings`
			SET `messagesperpage` = ?, `get_notify` = ?, `notification_email` = ?, `getsmsinemail` = ?, `show_display_names` = ?, `add_display_names` = ?, 
                            `msg_check_interval` = ?
	                WHERE `user_id` = ?');
	        $updateRes = $sqlupdatedb->execute([$messagesperpage, $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval, $userId]);
	        $updateRes->closeCursor();
            }
        }
     }


     /**
      * @NoAdminRequired
      */
     public function getapicredentials($userId) {

        $sqlcr = $this->connection->prepare('
              SELECT `id`, `user_id`, `telapi_key`, `tel_pub_key`, `telapi_url_rec`, `telapi_url`, `messaging_profile_id`, `nexapi_key`, `nexapi_secret`, `nexapi_url_rec`, `nexapi_url`,
                     `tel_sender_name`, `nex_sender_name`, `messagesperpage`, `get_notify`, `notification_email`, `getsmsinemail`, `twilapi_key`, `twilapi_secret`, `twilapi_url_rec`, 
                     `twilapi_url`, `twil_sender_name`, `flowapi_key`, `flowapi_secret`, `flowapi_url_rec`, `flowapi_url`, `add_display_names` FROM `*PREFIX*sms_relent_settings`
	      WHERE `user_id` = ?');
	$resultcr = $sqlcr->execute([$userId]);
        $settingsfrdb = $resultcr->fetch();
        $resultcr->closeCursor();

        if (($settingsfrdb['telapi_key'] != '') && ($settingsfrdb['telapi_key'] != 'undefined') && ($settingsfrdb['telapi_key'] != null)) { 
             $telapikeystrdec = $this->crypto->decrypt($settingsfrdb['telapi_key']); 
        } else { $telapikeystrdec = ''; }

        if (($settingsfrdb['tel_pub_key'] != '') && ($settingsfrdb['tel_pub_key'] != 'undefined') && ($settingsfrdb['tel_pub_key'] != null)) {
             $telpubkeystrdec = $this->crypto->decrypt($settingsfrdb['tel_pub_key']); 
        } else { $telpubkeystrdec = ''; }

        $telapiurlrec = $settingsfrdb['telapi_url_rec'];
        $telapiurlstr = $settingsfrdb['telapi_url'];

        if (($settingsfrdb['messaging_profile_id'] != '') && ($settingsfrdb['messaging_profile_id'] != 'undefined') && ($settingsfrdb['messaging_profile_id'] != null)) {
             $messagingprofid = $this->crypto->decrypt($settingsfrdb['messaging_profile_id']); 
        } else { $messagingprofid = ''; }

        if (($settingsfrdb['nexapi_key'] != '') && ($settingsfrdb['nexapi_key'] != 'undefined') && ($settingsfrdb['nexapi_key'] != null)) { 
             $nexapikeystr = $this->crypto->decrypt($settingsfrdb['nexapi_key']); 
        } else { $nexapikeystr = ''; }

        if (($settingsfrdb['nexapi_secret'] != '') && ($settingsfrdb['nexapi_secret'] != 'undefined') && ($settingsfrdb['nexapi_secret'] != null)) { 
             $nexapisecretstr = $this->crypto->decrypt($settingsfrdb['nexapi_secret']); 
        } else { $nexapisecretstr = ''; }

        if (($settingsfrdb['twilapi_key'] != '') && ($settingsfrdb['twilapi_key'] != 'undefined') && ($settingsfrdb['twilapi_key'] != null)) { 
             $twilapikeystr = $this->crypto->decrypt($settingsfrdb['twilapi_key']); 
        } else { $twilapikeystr = ''; }

        if (($settingsfrdb['twilapi_secret'] != '') && ($settingsfrdb['twilapi_secret'] != 'undefined') && ($settingsfrdb['twilapi_secret'] != null)) { 
             $twilapisecretstr = $this->crypto->decrypt($settingsfrdb['twilapi_secret']); 
        } else { $twilapisecretstr = ''; }

        if (($settingsfrdb['flowapi_key'] != '') && ($settingsfrdb['flowapi_key'] != 'undefined') && ($settingsfrdb['flowapi_key'] != null)) { 
             $flowapikeystr = $this->crypto->decrypt($settingsfrdb['flowapi_key']); 
        } else { $flowapikeystr = ''; }

        if (($settingsfrdb['flowapi_secret'] != '') && ($settingsfrdb['flowapi_secret'] != 'undefined') && ($settingsfrdb['flowapi_secret'] != null)) { 
             $flowapisecretstr = $this->crypto->decrypt($settingsfrdb['flowapi_secret']); 
        } else { $flowapisecretstr = ''; }

        $nexapiurlrecsms = $settingsfrdb['nexapi_url_rec'];
        $nexapiurldelrcpt = $settingsfrdb['nexapi_url'];
        $twilapiurlrecsms = $settingsfrdb['twilapi_url_rec'];
        $twilapiurldelrcpt = $settingsfrdb['twilapi_url'];
        $flowapiurlrecsms = $settingsfrdb['flowapi_url_rec'];
        $flowapiurldelrcpt = $settingsfrdb['flowapi_url'];
        $gettelsendername = $settingsfrdb['tel_sender_name'];
        $getnexsendername = $settingsfrdb['nex_sender_name'];
        $gettwilsendername = $settingsfrdb['twil_sender_name'];
        $getmessagesperpage = $settingsfrdb['messagesperpage'];
        $getnotification = $settingsfrdb['get_notify'];
        $notifyemail = $settingsfrdb['notification_email'];
        $includesmsinemail = $settingsfrdb['getsmsinemail'];
        $includeDisplNames = $settingsfrdb['add_display_names'];

        return [$telapikeystrdec, $telpubkeystrdec, $telapiurlrec, $telapiurlstr, $messagingprofid, $nexapikeystr, $nexapisecretstr, $nexapiurlrecsms, $nexapiurldelrcpt,
                $gettelsendername, $getnexsendername, $getmessagesperpage, $getnotification, $notifyemail, $includesmsinemail, $twilapikeystr, $twilapisecretstr, $twilapiurlrecsms, 
                $twilapiurldelrcpt, $gettwilsendername, $flowapikeystr, $flowapisecretstr, $flowapiurlrecsms, $flowapiurldelrcpt, $includeDisplNames];
     }

     /**
      * @NoAdminRequired
      */
     public function getuserbytelrecwhurl($recsmswebhookurl) {

        $sqlrec = $this->connection->prepare('SELECT `user_id`, `telapi_url_rec` FROM `*PREFIX*sms_relent_settings` WHERE `telapi_url_rec` = ?');
	$result = $sqlrec->execute([$recsmswebhookurl]);
        $datafromdb = $result->fetch();
        $result->closeCursor();
        $ncusertelrec = $datafromdb['user_id'];

        return $ncusertelrec;
     }

     /**
      * @NoAdminRequired
      */
     public function getuserbyteldelrwhurl($delsmswebhookurl) {

        $sqldel = $this->connection->prepare('SELECT `user_id`, `telapi_url` FROM `*PREFIX*sms_relent_settings` WHERE `telapi_url` = ?');
	$ressqldel = $sqldel->execute([$delsmswebhookurl]);
        $datafromdbdel = $ressqldel->fetch();
        $ressqldel->closeCursor();
        $ncuserteldel = $datafromdbdel['user_id'];

        return $ncuserteldel;
     }

     /**
      * @NoAdminRequired
      */
     public function getuserbyplivorecwhurl($plivorecurl) {

        $sqlrecpl = $this->connection->prepare('SELECT `user_id`, `nexapi_url_rec` FROM `*PREFIX*sms_relent_settings` WHERE `nexapi_url_rec` = ?');
	$plresrecsql = $sqlrecpl->execute([$plivorecurl]);
        $pldatafromdb = $plresrecsql->fetch();
        $plresrecsql->closeCursor();
        $ncuserplrec = $pldatafromdb['user_id'];

        return $ncuserplrec;
     }

     /**
      * @NoAdminRequired
      */
     public function getuserbyplivodelrwhurl($plivodrurl) {

        $sqldrpl = $this->connection->prepare('SELECT `user_id`, `nexapi_url` FROM `*PREFIX*sms_relent_settings` WHERE `nexapi_url` = ?');
	$ressqldelrec = $sqldrpl->execute([$plivodrurl]);
        $datafromdbdr = $ressqldelrec->fetch();
        $ressqldelrec->closeCursor();
        $ncuserplivodel = $datafromdbdr['user_id'];

        return $ncuserplivodel;
     }

     /**
      * @NoAdminRequired
      */
     public function getuserbytwilrecwhurl($twilrecurl) {

        $sqlrectw = $this->connection->prepare('SELECT `user_id`, `twilapi_url_rec` FROM `*PREFIX*sms_relent_settings` WHERE `twilapi_url_rec` = ?');
	$twresrecsql = $sqlrectw->execute([$twilrecurl]);
        $twdatafromdb = $twresrecsql->fetch();
        $twresrecsql->closeCursor();
        $ncusertwrec = $twdatafromdb['user_id'];

        return $ncusertwrec;
     }

     /**
      * @NoAdminRequired
      */
     public function getuserbytwildelrwhurl($twildrurl) {

        $sqldrtw = $this->connection->prepare('SELECT `user_id`, `twilapi_url` FROM `*PREFIX*sms_relent_settings` WHERE `twilapi_url` = ?');
	$ressqldelrectw = $sqldrtw->execute([$twildrurl]);
        $datafromdbdrtw = $ressqldelrectw->fetch();
        $ressqldelrectw->closeCursor();
        $ncusertwildel = $datafromdbdrtw['user_id'];

        return $ncusertwildel;
     }

     /**
      * @NoAdminRequired
      */
     public function getuserbyflowrecwhurl($flowrecurl) {

        $sqlrecfl = $this->connection->prepare('SELECT `user_id`, `flowapi_url_rec` FROM `*PREFIX*sms_relent_settings` WHERE `flowapi_url_rec` = ?');
	$flresrecsql = $sqlrecfl->execute([$flowrecurl]);
        $fldatafromdb = $flresrecsql->fetch();
        $flresrecsql->closeCursor();
        $ncuserflrec = $fldatafromdb['user_id'];

        return $ncuserflrec;
     }

     /**
      * @NoAdminRequired
      */
     public function getuserbyflowdelrwhurl($flowdrurl) {

        $sqldrfl = $this->connection->prepare('SELECT `user_id`, `flowapi_url` FROM `*PREFIX*sms_relent_settings` WHERE `flowapi_url` = ?');
	$ressqldelrecfl = $sqldrfl->execute([$flowdrurl]);
        $datafromdbdrfl = $ressqldelrecfl->fetch();
        $ressqldelrecfl->closeCursor();
        $ncuserflowdel = $datafromdbdrfl['user_id'];

        return $ncuserflowdel;
     }


    /**
     * @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 getallowedusers($userId) {

        // Collect the users with whom the current admin is sharing his API keys and whose messages he will be able to see
        if ($this->groupManager->isAdmin($userId)) {

            // Get the groups and users that were allowed access to the API keys
            $getgrps = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed`, `tnx_users_allowed`, `plv_groups_allowed`, `plv_users_allowed`,
                                                  `twl_groups_allowed`, `twl_users_allowed`, `flr_groups_allowed`, `flr_users_allowed` FROM `*PREFIX*sms_relent_subac`
                                                   WHERE `user_id` = ?');
            $getgrpsres = $getgrps->execute([$userId]);
            $getgrpsusr = $getgrpsres->fetch();
            $getgrpsres->closeCursor();

            if ($getgrpsusr) {

                if ($getgrpsusr['tnx_users_allowed']) { $tnxusers = explode("|", $getgrpsusr['tnx_users_allowed']); } else { $tnxusers = []; }
                if ($getgrpsusr['plv_users_allowed']) { $plvusers = explode("|", $getgrpsusr['plv_users_allowed']); } else { $plvusers = []; }
                if ($getgrpsusr['twl_users_allowed']) { $twlusers = explode("|", $getgrpsusr['twl_users_allowed']); } else { $twlusers = []; }
                if ($getgrpsusr['flr_users_allowed']) { $flrusers = explode("|", $getgrpsusr['flr_users_allowed']); } else { $flrusers = []; }

                $allwdusersarr = array_merge($tnxusers, $plvusers, $twlusers, $flrusers);
                $allwdusersunq = array_filter(array_unique($allwdusersarr));

                if ($getgrpsusr['tnx_groups_allowed']) { $tnxgroups = explode("|", $getgrpsusr['tnx_groups_allowed']); } else { $tnxgroups = []; }
                if ($getgrpsusr['plv_groups_allowed']) { $plvgroups = explode("|", $getgrpsusr['plv_groups_allowed']); } else { $plvgroups = []; }
                if ($getgrpsusr['twl_groups_allowed']) { $twlgroups = explode("|", $getgrpsusr['twl_groups_allowed']); } else { $twlgroups = []; }
                if ($getgrpsusr['flr_groups_allowed']) { $flrgroups = explode("|", $getgrpsusr['flr_groups_allowed']); } else { $flrgroups = []; }

                $allwdgroupsarr = array_merge($tnxgroups, $plvgroups, $twlgroups, $flrgroups);
                $allwdgroupsunq = array_filter(array_unique($allwdgroupsarr));

            } else {
                $allwdusersunq = [];
                $allwdgroupsunq = [];
            }

            // Get the username for each Display Name of the allowed users
            $allwdusersfnl = [];
            foreach ($allwdusersunq as $alwdusrkey => $alwdusrvalue) {

                         $getacdatausrnm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		         $getacdatausrnmres = $getacdatausrnm->execute(['displayname', $alwdusrvalue]);
		         $acdatausrname = $getacdatausrnmres->fetch();
                         if ($acdatausrname) {
                             $allwdusersfnl[] = $acdatausrname['uid'];
                         }
                         $getacdatausrnmres->closeCursor();
            }

            // Get the users from all the allowed groups
            $allwdusersgrpmlt = [];
            foreach ($allwdgroupsunq as $prgrpkey => $prgrpvalue) {

                     // Get all the users that belong to the current group, if the current group is different from 'admin'
                     if ($prgrpvalue != 'admin') {
                         $getusringroup = $this->connection->prepare('SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `gid` = ?');
		         $getusringroupres = $getusringroup->execute([$prgrpvalue]);

		         while ($getusrname = $getusringroupres->fetch()) {

                                $allwdusersgrpmlt[] = $getusrname['uid'];
                         }
		         $getusringroupres->closeCursor();
                     }
            }
            $allwdusersgrpfnl = array_unique($allwdusersgrpmlt);
            
            $allusr = array_merge($allwdusersfnl, $allwdusersgrpfnl);
            $allusruniquest = array_unique($allusr);

            if ($allusruniquest) {
                array_unshift($allusruniquest, $userId);
                $allusruniquerc = $allusruniquest;
            } else { $allusruniquerc = [$userId]; }

            return $allusruniquerc;

        } else { return [$userId]; }
    }


    /**
     * @NoAdminRequired
     */
    public function getsmsnumbers($userId) {

        // Check if there are any saved phone numbers for the current user
        $getnumbers = $this->connection->prepare('SELECT `user_id`, `available_numbers` FROM `*PREFIX*sms_relent_settings` WHERE `user_id` = ?');
	$getcrtusrno = $getnumbers->execute([$userId]);
        $getusrnmbrs = $getcrtusrno->fetch();
        $getcrtusrno->closeCursor();

        if ($getusrnmbrs['available_numbers']) {

            $retrievednmbrs = $getusrnmbrs['available_numbers'];
            $getnmbrsarr = explode("|", $retrievednmbrs);
            $numbersforuser = array_filter($getnmbrsarr);
            return $numbersforuser;

        // Get the available phone numbers for the current user from the SMS providers
        } else {

            $smsapicred = $this->getapicredentials($userId);

            $telnyxkey = $smsapicred[0];

            $nexapikey = $smsapicred[5];
            $nexapisecret = $smsapicred[6];

            $twilapikey = $smsapicred[15];
            $twilapisecret = $smsapicred[16];

            $flowapikey = $smsapicred[20];
            $flowapisecret = $smsapicred[21];

            $telsendernameinit = $smsapicred[9];
            $nexsendernameinit = $smsapicred[10];
            $twilsendernameinit = $smsapicred[19];

            if ($telsendernameinit) {
                $telsendername = "Tx: " . $telsendernameinit;
                $telsenderarr = [0 => $telsendername];
            } else { $telsenderarr = []; }

            if ($nexsendernameinit) {
                $nexsendername = "Pl: " . $nexsendernameinit;
                $nexsenderarr = [0 => $nexsendername];
            } else { $nexsenderarr = []; }

            if ($twilsendernameinit) {
                $twilsendername = "Tw: " . $twilsendernameinit;
                $twilsenderarr = [0 => $twilsendername];
            } else { $twilsenderarr = []; }

            // Get Telnyx phone numbers
            if ($telnyxkey != '') {

               \Telnyx\Telnyx::setApiKey($telnyxkey);
               $telnumbers = \Telnyx\MessagingPhoneNumber::All();

               $telnumbersarr = $this->object_to_array($telnumbers);
               $telnmbrs = [];

               foreach ($telnumbersarr['_originalValues'] as $nmbkey => $nmbvalue) {
                   if (is_int($nmbkey)) {
                       foreach ($nmbvalue as $nkey => $nvalue) {
                           if ($nkey == 'phone_number' && $nvalue) {
                               $telnmbrs[] = "Tx: " . $nvalue;
                           }
                       }
                   }
               }

            } else { $telnmbrs = []; }

            // Get Plivo phone numbers
            if ($nexapikey != '' && $nexapisecret != '') {

               $getacdata = "https://".$nexapikey.":".$nexapisecret."@api.plivo.com/v1/Account/".$nexapikey."/Number/";
               $acdata = file_get_contents($getacdata);
               $datainit = json_decode($acdata, true);

               $findata = $this->object_to_array($datainit);

               $nexcurrentnmbrs = [];

               foreach ($findata['objects'] as $smskey => $smsvalue) {
                       if (is_array($smsvalue)) {
                             foreach ($smsvalue as $smskey2 => $smsvalue2) {
                                   if ($smskey2 == 'number' && $smsvalue2) {
                                       $nexcurrentnmbrs[] = "Pl: +" . $smsvalue2;
                                   }
                             }
                       }
               }

            } else { $nexcurrentnmbrs = []; }

            // Get Twilio phone numbers
            if ($twilapikey != '' && $twilapisecret != '') {

                $twilnumbers = json_decode(file_get_contents("https://".$twilapikey.":".$twilapisecret."@api.twilio.com/2010-04-01/Accounts/".$twilapikey."/IncomingPhoneNumbers.json"), true);
                $twilactivenmbrs = $twilnumbers['incoming_phone_numbers'];

                $twilcurrentnmbrs = [];
                foreach ($twilactivenmbrs as $twnbkey => $twnbvalue) {
                     if (is_array($twnbvalue)) {
                         foreach ($twnbvalue as $twfkey => $twfvalue) {
                              if ($twfkey == 'phone_number' && $twfvalue) {
                                  $twilcurrentnmbrs[] = "Tw: " . $twfvalue;
                              }
                         }
                     }
                }

            } else { $twilcurrentnmbrs = []; }

            // Get Flowroute phone numbers
            if ($flowapikey != '' && $flowapisecret != '') {

                $flnbrsresult = json_decode(file_get_contents("https://".$flowapikey.":".$flowapisecret."@api.flowroute.com/v2/numbers"));
                $flnbrsarr = $flnbrsresult->data;
                $flowcurrentnmbrs = [];
                foreach ($flnbrsarr as $flkey => $flitem) {
                         if ($flitem->id) {
                             $flowcurrentnmbrs[] = "Fl: +" . $flitem->id;
                         }
                }

            } else { $flowcurrentnmbrs = []; }

            $currentnmbrs = array_merge($telnmbrs, $nexcurrentnmbrs, $twilcurrentnmbrs, $flowcurrentnmbrs, $telsenderarr, $nexsenderarr, $twilsenderarr);

            if ($this->groupManager->isAdmin($userId)) {

                // Save the available phone numbers for the current user
                $availablenmbrs = implode("|", $currentnmbrs);
                $savephno = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `available_numbers` = ? WHERE `user_id` = ?');
                $upusrphnmbrs = $savephno->execute([$availablenmbrs, $userId]);
	        $upusrphnmbrs->closeCursor();

                return $currentnmbrs;

            } else {

                // Get the restrictions from the 'sms_relent_restrict' table
                $getrestr = $this->connection->prepare('
		            SELECT `phone_number`, `groups`, `users` FROM `*PREFIX*sms_relent_restrict`');
                $getrestrres = $getrestr->execute();

                $restrdata = [];
                while ($restrfetched = $getrestrres->fetch()) {
                       $restrdata[] = $restrfetched;
                }
                $getrestrres->closeCursor();

                if ($restrdata) {

                    // Get the groups to which the current user belongs
                    $getusrgrp = $this->connection->prepare('
		                 SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `uid` = ?');
                    $getusrgrpres = $getusrgrp->execute([$userId]);

                    $usergrps = [];
                    while ($fetchedgrps = $getusrgrpres->fetch()) {
                           $usergrps[] = $fetchedgrps['gid'];
                    }
                    $getusrgrpres->closeCursor();
                    $ctusergroups = implode("|", $usergrps);

		    // Get the Display Name of the current user
		    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
		    $getacdatadnres = $getacdatadn->execute([$userId, 'displayname']);
		    $acdatausrdnadm = $getacdatadnres->fetch();
		    $cruserdname = $acdatausrdnadm['value'];
		    $getacdatadnres->closeCursor();

                    // Get the phone numbers that are not allowed for the current user
                    $restrPhoneNb = [];
                    foreach ($restrdata as $rskey => $rsvalue) {

                        $chck = 0;
                        if ($rsvalue['groups']) {
                            $restrgrparr = explode("|", $rsvalue['groups']);

                            foreach ($restrgrparr as $grkey => $grvalue) {
                                     if (str_contains($ctusergroups, $grvalue)) { $chck++; }
                            }
                        }

                        if ($rsvalue['users']) {
                            $usrnmstr = $rsvalue['users'];
                            if (str_contains($usrnmstr, $cruserdname)) { $chck++; }
                        }

                        if ($chck == 0) { $restrPhoneNb[] = $rsvalue['phone_number']; }
                    }

                    $restrPhoneNmbrs = array_unique($restrPhoneNb);

                    // Assemble the array of phone numbers that the current user is allowed to use
                    for ($k = 0; $k < count($currentnmbrs); $k++) {

                        if (in_array($currentnmbrs[$k], $restrPhoneNmbrs)) {
                            unset($currentnmbrs[$k]);
                        }
                    }

                    $currentnmbrsrstr = array_values($currentnmbrs);

                    // Save the available phone numbers for the current user
                    $availablenmbrs = implode("|", $currentnmbrsrstr);
                    $savephno = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `available_numbers` = ? WHERE `user_id` = ?');
                    $upusrphnmbrs = $savephno->execute([$availablenmbrs, $userId]);
	            $upusrphnmbrs->closeCursor();

                    return $currentnmbrsrstr;

                } else {

                    // Save the available phone numbers for the current user
                    $availablenmbrs = implode("|", $currentnmbrs);
                    $savephno = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `available_numbers` = ? WHERE `user_id` = ?');
                    $upusrphnmbrs = $savephno->execute([$availablenmbrs, $userId]);
	            $upusrphnmbrs->closeCursor();

                    return $currentnmbrs; 
                }
            }
        }
    }


    /**
     * @NoAdminRequired
     */
    public function refreshavailablenumbers($userId) {

        $smsapicred = $this->getapicredentials($userId);

        $telnyxkey = $smsapicred[0];

        $nexapikey = $smsapicred[5];
        $nexapisecret = $smsapicred[6];

        $twilapikey = $smsapicred[15];
        $twilapisecret = $smsapicred[16];

        $flowapikey = $smsapicred[20];
        $flowapisecret = $smsapicred[21];

        $telsendernameinit = $smsapicred[9];
        $nexsendernameinit = $smsapicred[10];
        $twilsendernameinit = $smsapicred[19];

        if ($telsendernameinit) {
            $telsendername = "Tx: " . $telsendernameinit;
            $telsenderarr = [0 => $telsendername];
        } else { $telsenderarr = []; }

        if ($nexsendernameinit) {
            $nexsendername = "Pl: " . $nexsendernameinit;
            $nexsenderarr = [0 => $nexsendername];
        } else { $nexsenderarr = []; }

        if ($twilsendernameinit) {
            $twilsendername = "Tw: " . $twilsendernameinit;
            $twilsenderarr = [0 => $twilsendername];
        } else { $twilsenderarr = []; }

        // Get Telnyx phone numbers
        if ($telnyxkey != '') {

           \Telnyx\Telnyx::setApiKey($telnyxkey);
           $telnumbers = \Telnyx\MessagingPhoneNumber::All();

           $telnumbersarr = $this->object_to_array($telnumbers);
           $telnmbrs = [];

           foreach ($telnumbersarr['_originalValues'] as $nmbkey => $nmbvalue) {
              if (is_int($nmbkey)) {
                 foreach ($nmbvalue as $nkey => $nvalue) {
                    if ($nkey == 'phone_number' && $nvalue) {
                       $telnmbrs[] = "Tx: " . $nvalue;
                    }
                 }
              }
           }

        } else { $telnmbrs = []; }

        // Get Plivo phone numbers
        if ($nexapikey != '' && $nexapisecret != '') {

           $getacdata = "https://".$nexapikey.":".$nexapisecret."@api.plivo.com/v1/Account/".$nexapikey."/Number/";
           $acdata = file_get_contents($getacdata);
           $datainit = json_decode($acdata, true);

           $findata = $this->object_to_array($datainit);

           $nexcurrentnmbrs = [];

           foreach ($findata['objects'] as $smskey => $smsvalue) {
                   if (is_array($smsvalue)) {
                         foreach ($smsvalue as $smskey2 => $smsvalue2) {
                               if ($smskey2 == 'number' && $smsvalue2) {
                                   $nexcurrentnmbrs[] = "Pl: +" . $smsvalue2;
                               }
                         }
                   }
           }

        } else { $nexcurrentnmbrs = []; }

        // Get Twilio phone numbers
        if ($twilapikey != '' && $twilapisecret != '') {

            $twilnumbers = json_decode(file_get_contents("https://".$twilapikey.":".$twilapisecret."@api.twilio.com/2010-04-01/Accounts/".$twilapikey."/IncomingPhoneNumbers.json"), true);
            $twilactivenmbrs = $twilnumbers['incoming_phone_numbers'];

            $twilcurrentnmbrs = [];
            foreach ($twilactivenmbrs as $twnbkey => $twnbvalue) {
                 if (is_array($twnbvalue)) {
                     foreach ($twnbvalue as $twfkey => $twfvalue) {
                          if ($twfkey == 'phone_number' && $twfvalue) {
                              $twilcurrentnmbrs[] = "Tw: " . $twfvalue;
                          }
                     }
                 }
            }

        } else { $twilcurrentnmbrs = []; }

        // Get Flowroute phone numbers
        if ($flowapikey != '' && $flowapisecret != '') {

            $flnbrsresult = json_decode(file_get_contents("https://".$flowapikey.":".$flowapisecret."@api.flowroute.com/v2/numbers"));
            $flnbrsarr = $flnbrsresult->data;
            $flowcurrentnmbrs = [];
            foreach ($flnbrsarr as $flkey => $flitem) {
                     if ($flitem->id) {
                         $flowcurrentnmbrs[] = "Fl: +" . $flitem->id;
                     }
            }

        } else { $flowcurrentnmbrs = []; }

        $currentnmbrs = array_merge($telnmbrs, $nexcurrentnmbrs, $twilcurrentnmbrs, $flowcurrentnmbrs, $telsenderarr, $nexsenderarr, $twilsenderarr);


        if ($this->groupManager->isAdmin($userId)) {

            // Save the available phone numbers for the current user
            $availablenmbrs = implode("|", $currentnmbrs);
            $savephno = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `available_numbers` = ? WHERE `user_id` = ?');
            $upusrphnmbrs = $savephno->execute([$availablenmbrs, $userId]);
	    $upusrphnmbrs->closeCursor();

            return $currentnmbrs;

        } else {

            // Get the restrictions from the 'sms_relent_restrict' table
            $getrestr = $this->connection->prepare('
		       SELECT `phone_number`, `groups`, `users` FROM `*PREFIX*sms_relent_restrict`');
            $getrestrres = $getrestr->execute();

            $restrdata = [];
            while ($restrfetched = $getrestrres->fetch()) {
                   $restrdata[] = $restrfetched;
            }
            $getrestrres->closeCursor();

            if ($restrdata) {

                // Get the groups to which the current user belongs
                $getusrgrp = $this->connection->prepare('
		       SELECT `gid`, `uid` FROM `*PREFIX*group_user` WHERE `uid` = ?');
                $getusrgrpres = $getusrgrp->execute([$userId]);

                $usergrps = [];
                while ($fetchedgrps = $getusrgrpres->fetch()) {
                       $usergrps[] = $fetchedgrps['gid'];
                }
                $getusrgrpres->closeCursor();
                $ctusergroups = implode("|", $usergrps);

		// Get the Display Name of the current user
		$getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
		$getacdatadnres = $getacdatadn->execute([$userId, 'displayname']);
		$acdatausrdnadm = $getacdatadnres->fetch();
		$cruserdname = $acdatausrdnadm['value'];
		$getacdatadnres->closeCursor();

                // Get the phone numbers that are not allowed for the current user
                $restrPhoneNb = [];
                foreach ($restrdata as $rskey => $rsvalue) {

                        $chck = 0;
                        if ($rsvalue['groups']) {
                            $restrgrparr = explode("|", $rsvalue['groups']);

                            foreach ($restrgrparr as $grkey => $grvalue) {
                                     if (str_contains($ctusergroups, $grvalue)) { $chck++; }
                            }
                        }

                        if ($rsvalue['users']) {
                            $usrnmstr = $rsvalue['users'];
                            if (str_contains($usrnmstr, $cruserdname)) { $chck++; }
                        }

                        if ($chck == 0) { $restrPhoneNb[] = $rsvalue['phone_number']; }
                }

                $restrPhoneNmbrs = array_unique($restrPhoneNb);

                // Assemble the array of phone numbers that the current user is allowed to use
                for ($k = 0; $k < count($currentnmbrs); $k++) {

                    if (in_array($currentnmbrs[$k], $restrPhoneNmbrs)) {
                        unset($currentnmbrs[$k]);
                    }
                }

                $currentnmbrsrstr = array_values($currentnmbrs);

                // Save the available phone numbers for the current user
                $availablenmbrs = implode("|", $currentnmbrsrstr);
                $savephno = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `available_numbers` = ? WHERE `user_id` = ?');
                $upusrphnmbrs = $savephno->execute([$availablenmbrs, $userId]);
	        $upusrphnmbrs->closeCursor();

                return $currentnmbrsrstr;

            } else {

                // Save the available phone numbers for the current user
                $availablenmbrs = implode("|", $currentnmbrs);
                $savephno = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_settings` SET `available_numbers` = ? WHERE `user_id` = ?');
                $upusrphnmbrs = $savephno->execute([$availablenmbrs, $userId]);
	        $upusrphnmbrs->closeCursor();

                return $currentnmbrs; 
            }
        }
    }
}
