<?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; }
            }

            // Search for the conversation ID in the 'sms_relent_conv' table
            $convExists = 0;
            $archivedConv = 0;
            $tophnumberarr = explode(": ", $recmessagearr[3]);
            $tophnumber = $tophnumberarr[1];
            $getconvid = $this->connection->prepare('SELECT `conversation_id`, `archived`, `last_msg_from`, `last_msg_to` FROM `*PREFIX*sms_relent_conv` WHERE 
                                                   (`last_msg_from` = ? AND `last_msg_to` = ?) OR (`last_msg_from` = ? AND `last_msg_to` = ?)');
            $getconvres = $getconvid->execute([$recmessagearr[2], $tophnumber, $tophnumber, $recmessagearr[2]]);
            $convfetched = $getconvres->fetch();
            $getconvres->closeCursor();

            if ($convfetched) {
                $conversationId = $convfetched['conversation_id'];
                $convExists = 1;
                $archivedConv = $convfetched['archived'];
            } else {
                // Create a conversation ID
	        $keypassin = substr(sha1((string) mt_rand()), 0, 32);
	        $keysaltin = openssl_random_pseudo_bytes(24);
	        $keyLengthin = 64;
	        $iterationin = 50;
	        $generated_keyin = openssl_pbkdf2($keypassin, $keysaltin, $keyLengthin, $iterationin, 'sha256');
	        $conversationId = bin2hex($generated_keyin);
            }


            // 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`, `conversation_id`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
			  ');
	    $sql->execute([$userId, $recmessagearr[0], $recmessagearr[1], $recmessagearr[2], $recmessagearr[3], $escapedmessage, $authorDisplayNm, $internalSender, $conversationId]);


            // Update or insert data in the 'sms_relent_conv' table
            $archivedornot = 0;
            $lastUnarchived = date("Y-m-d H:i:s");
            $lastMsgDate = $lastUnarchived;
            $lastMsgFrom = $recmessagearr[2];
            $lastMsgToArr = explode(": ", $recmessagearr[3]);
            $lastMsgTo = $lastMsgToArr[1];

            if ($convExists == 1) {

                if ($archivedConv == 1) {

	            $sqlupdatecv = $this->connection->prepare('
			        UPDATE `*PREFIX*sms_relent_conv`
			        SET `archived` = ?, `last_unarchived` = ?, `unarchived_by` = ?, `last_msg_date` = ?, `last_msg_from` = ?, `last_msg_to` = ?, `last_message` = ?, 
                                `lastmsgdisplayname` = ?, `lastmsgprovid` = ?
	                        WHERE `conversation_id` = ?');
	            $updatecvRes = $sqlupdatecv->execute([$archivedornot, $lastUnarchived, $authorDisplayNm, $lastMsgDate, $lastMsgFrom, $lastMsgTo, $escapedmessage, $authorDisplayNm, 
                                                          $recmessagearr[0], $conversationId]);
	            $updatecvRes->closeCursor();

                } else {

	            $sqlupdatecv = $this->connection->prepare('
			        UPDATE `*PREFIX*sms_relent_conv`
			        SET `archived` = ?, `last_msg_date` = ?, `last_msg_from` = ?, `last_msg_to` = ?, `last_message` = ?, `lastmsgdisplayname` = ?, `lastmsgprovid` = ?
	                        WHERE `conversation_id` = ?');
	            $updatecvRes = $sqlupdatecv->execute([$archivedornot, $lastMsgDate, $lastMsgFrom, $lastMsgTo, $escapedmessage, $authorDisplayNm, $recmessagearr[0], $conversationId]);
	            $updatecvRes->closeCursor();
                }

            } else {

                    $sqlinscv = $this->connection->prepare('
				INSERT INTO `*PREFIX*sms_relent_conv`
					(`conversation_id`, `archived`, `last_msg_date`, `last_msg_from`, `last_msg_to`, `last_message`, `lastmsgdisplayname`, `lastmsgprovid`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?)
			        ');
	            $sqlinscv->execute([$conversationId, $archivedornot, $lastMsgDate, $lastMsgFrom, $lastMsgTo, $escapedmessage, $authorDisplayNm, $recmessagearr[0]]);
            }

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

            // Search for the conversation ID in the 'sms_relent_conv' table
            $convExistssc = 0;
            $archivedConvsc = 0;
            $fromphnumberarr = explode(": ", $sentmessagearr[2]);
            $fromphnumber = $fromphnumberarr[1];
            $getconvidsc = $this->connection->prepare('SELECT `conversation_id`, `archived`, `last_msg_from`, `last_msg_to` FROM `*PREFIX*sms_relent_conv` WHERE 
                                                     (`last_msg_from` = ? AND `last_msg_to` = ?) OR (`last_msg_from` = ? AND `last_msg_to` = ?)');
            $getconvressc = $getconvidsc->execute([$fromphnumber, $sentmessagearr[3], $sentmessagearr[3], $fromphnumber]);
            $convfetchedsc = $getconvressc->fetch();
            $getconvressc->closeCursor();

            if ($convfetchedsc) {
                $conversationIdsc = $convfetchedsc['conversation_id'];
                $convExistssc = 1;
                $archivedConvsc = $convfetchedsc['archived'];
            } else {
                // Create a conversation ID
	        $keypassinsc = substr(sha1((string) mt_rand()), 0, 32);
	        $keysaltinsc = openssl_random_pseudo_bytes(24);
	        $keyLengthinsc = 64;
	        $iterationinsc = 50;
	        $generated_keyinsc = openssl_pbkdf2($keypassinsc, $keysaltinsc, $keyLengthinsc, $iterationinsc, 'sha256');
	        $conversationIdsc = bin2hex($generated_keyinsc);
            }

            // Insert the sent message in the 'sms_relent_sent' table
            $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`, `conversation_id`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
			  ');
	    $sql->execute([$userId, $sentmessagearr[0], $sentmessagearr[1], $sentmessagearr[2], $sentmessagearr[3], $sentmessagearr[4], $sentmessagearr[5], $sentmessagearr[6], 
                           $sentmessagearr[7], $textwithnl, $displayname, $conversationIdsc]);


            // Update or insert data in the 'sms_relent_conv' table
            $archivedornotsc = 0;
            $lastUnarchivedsc = date("Y-m-d H:i:s");
            $lastMsgDatesc = $lastUnarchivedsc;
            $lastMsgFromArrsc = explode(": ", $sentmessagearr[2]);
            $lastMsgFromsc = $lastMsgFromArrsc[1];
            $lastMsgTosc = $sentmessagearr[3];

            if ($convExistssc == 1) {

                if ($archivedConvsc == 1) {

	            $sqlupdatecvsc = $this->connection->prepare('
			        UPDATE `*PREFIX*sms_relent_conv`
			        SET `archived` = ?, `last_unarchived` = ?, `unarchived_by` = ?, `last_msg_date` = ?, `last_msg_from` = ?, `last_msg_to` = ?, `last_message` = ?, 
                                `lastmsgdisplayname` = ?, `lastmsgprovid` = ?
	                        WHERE `conversation_id` = ?');
	            $updatecvRessc = $sqlupdatecvsc->execute([$archivedornotsc, $lastUnarchivedsc, $displayname, $lastMsgDatesc, $lastMsgFromsc, $lastMsgTosc, $textwithnl, 
                                                              $displayname, $sentmessagearr[0], $conversationIdsc]);
	            $updatecvRessc->closeCursor();

                } else {

	            $sqlupdatecvsc = $this->connection->prepare('
			        UPDATE `*PREFIX*sms_relent_conv`
			        SET `archived` = ?, `last_msg_date` = ?, `last_msg_from` = ?, `last_msg_to` = ?, `last_message` = ?, `lastmsgdisplayname` = ?, `lastmsgprovid` = ?
	                        WHERE `conversation_id` = ?');
	            $updatecvRessc = $sqlupdatecvsc->execute([$archivedornotsc, $lastMsgDatesc, $lastMsgFromsc, $lastMsgTosc, $textwithnl, $displayname, $sentmessagearr[0], 
                                                              $conversationIdsc]);
	            $updatecvRessc->closeCursor();
                }

            } else {

                    $sqlinscvsc = $this->connection->prepare('
				INSERT INTO `*PREFIX*sms_relent_conv`
					(`conversation_id`, `archived`, `last_msg_date`, `last_msg_from`, `last_msg_to`, `last_message`, `lastmsgdisplayname`, `lastmsgprovid`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?)
			        ');
	            $sqlinscvsc->execute([$conversationIdsc, $archivedornotsc, $lastMsgDatesc, $lastMsgFromsc, $lastMsgTosc, $textwithnl, $displayname, $sentmessagearr[0]]);
            }
     }


     /**
      * @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) {

                         $displName = 'displayname';
                         $getacdatausrnm = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
		         $getacdatausrnmres = $getacdatausrnm->execute([$displName, $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
            $dsplyname = 'displayname';
	    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
	    $getacdatadnres = $getacdatadn->execute([$userId, $dsplyname]);
	    $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
            $restrPhoneNmbrs = [];
            $allowedPhoneNmbrs = [];
            if ($restrdata) {
                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()) {
               $rowfetchedsc = htmlspecialchars($rowfetched["message"], ENT_QUOTES);
               $fetchedcont = str_replace(['&lt;br /&gt;', '&lt;br&gt;', '&lt;/b&gt;'], ['<br />', '<br>', '</b>'], $rowfetchedsc);
               $rowfetched["message"] = $fetchedcont;
               $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 removeMsgFromConv($msgProvId) {

             // Check if the message that will be deleted is the last message in a conversation
             $chcklstmsg = $this->connection->prepare('SELECT `conversation_id`, `last_msg_date`, `last_msg_from`, `last_msg_to`, `last_message`, `lastmsgdisplayname`, 
                                                      `lastmsgprovid` FROM `*PREFIX*sms_relent_conv` WHERE `lastmsgprovid` = ?');
             $checklstmsgres = $chcklstmsg->execute([$msgProvId]);
             $convlmsgfetched = $checklstmsgres->fetch();
             $checklstmsgres->closeCursor();

             if ($convlmsgfetched) {

                 $conversationID = $convlmsgfetched['conversation_id'];
                 $lastmsgFrom = $convlmsgfetched['last_msg_from'];
                 $lastmsgFromLike = "%" . $convlmsgfetched['last_msg_from'];
                 $lastmsgTo = $convlmsgfetched['last_msg_to'];
                 $lastmsgToLike = "%" . $convlmsgfetched['last_msg_to'];

                 // Check if the conversation contains other messages (in the 'sms_relent_received' table), apart from the last message that will be deleted
	         $getcnvqr = $this->connection->prepare('SELECT `message_id`, `date`, `from`, `to`, `message`, `author_displayname` FROM `*PREFIX*sms_relent_received` WHERE 
	                                               (`from` = ? AND `to` LIKE ?) OR (`from` = ? AND `to` LIKE ?)');
	         $getcnvres = $getcnvqr->execute([$lastmsgFrom, $lastmsgToLike, $lastmsgTo, $lastmsgFromLike]);

	         $msgexchrec = [];
	         while ($rwsfetched = $getcnvres->fetch()) {
	                $msgexchrec[] = $rwsfetched;
	         }
	         $getcnvres->closeCursor();

                 // Check if the conversation contains other messages (in the 'sms_relent_sent' table), apart from the last message that will be deleted
	         $getcnvqrst = $this->connection->prepare('SELECT `message_id`, `date`, `from`, `to`, `message`, `author_displayname` FROM `*PREFIX*sms_relent_sent` WHERE 
	                                                 (`from` LIKE ? AND `to` = ?) OR (`from` LIKE ? AND `to` = ?)');
	         $getcnvstres = $getcnvqrst->execute([$lastmsgFromLike, $lastmsgTo, $lastmsgToLike, $lastmsgFrom]);

	         $msgexchsent = [];
	         while ($rwsfetchedst = $getcnvstres->fetch()) {
	                $msgexchsent[] = $rwsfetchedst;
	         }
	         $getcnvstres->closeCursor();

                 $mergedrecsent = array_merge($msgexchrec, $msgexchsent);

                 // Check if there are at least 2 messages exchanged between the two numbers
                 if (count($mergedrecsent) > 1) {

                     // Order all the messages exchanged between the two numbers
                     usort($mergedrecsent, function($a, $b) { return strtotime($a["date"]) - strtotime($b["date"]); });

                     // Get the last but one message
                     $msgdatares = array_slice($mergedrecsent, -2, 1);
                     $lastbutone = $msgdatares[0];

                     // Replace the message that will be deleted with the last but one message in the same conversation
                     if (str_contains($lastbutone['to'], ": ")) {
                         $lastMsgToarr = explode(": ", $lastbutone['to']);
                         $lastMsgTo = $lastMsgToarr[1];
                     } else { $lastMsgTo = $lastbutone['to']; }

                     if (str_contains($lastbutone['from'], ": ")) {
                         $lastMsgFromarr = explode(": ", $lastbutone['from']);
                         $lastMsgFrom = $lastMsgFromarr[1];
                     } else { $lastMsgFrom = $lastbutone['from']; }

                     $updatecnv = $this->connection->prepare('
		             UPDATE `*PREFIX*sms_relent_conv`
		             SET `last_msg_date` = ?, `last_msg_from` = ?, `last_msg_to` = ?, `last_message` = ?, `lastmsgdisplayname` = ?, `lastmsgprovid` = ?
                             WHERE `conversation_id` = ?');
                     $updatecnvres = $updatecnv->execute([$lastbutone['date'], $lastMsgFrom, $lastMsgTo, $lastbutone['message'], $lastbutone['author_displayname'], 
                                                          $lastbutone['message_id'], $conversationID]);
                     $updatecnvres->closeCursor();

                 } else {

                     // Since the last message in the conversation is the only message of the conversation and will be deleted, delete the conversation row from the conversations table
		     $convmsgdel = $this->connection->prepare('
				   DELETE FROM `*PREFIX*sms_relent_conv`
				   WHERE `conversation_id` = ?');
		     $convmsgdelres = $convmsgdel->execute([$conversationID]);
		     $convmsgdelres->closeCursor();

		     // Reindex the conversations table
		     $sqlupdateconv = $this->connection->prepare('
			           SET @resetconv = 0;
				   UPDATE `*PREFIX*sms_relent_conv`
				   SET `id` = @resetconv := @resetconv + 1;
			           ALTER TABLE `*PREFIX*sms_relent_conv` auto_increment=1;');
		     $updateconvRes = $sqlupdateconv->execute();
		     $updateconvRes->closeCursor();
                 }
             }
     }


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

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

            /* The user who deletes the messages is an admin */

            foreach ($recmessagedbIDs as $key => $rowtodelrw) {

                     $rowtodelarr = explode("|", $rowtodelrw);
                     $msgDbId = $rowtodelarr[0];
                     $msgProvId = $rowtodelarr[1];

                     // Delete the message
                     if ($msgProvId != "" && $msgProvId != "n/a") {

                         // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                         $this->removeMsgFromConv($msgProvId);

		         $rdlquery = $this->connection->prepare('
		                     DELETE FROM `*PREFIX*sms_relent_received`
		                     WHERE `message_id` = ?');
		         $delRes = $rdlquery->execute([$msgProvId]);
		         $delRes->closeCursor();
                     } else {
		         $rdlquery = $this->connection->prepare('
		                     DELETE FROM `*PREFIX*sms_relent_received`
		                     WHERE `id` = ?');
		         $delRes = $rdlquery->execute([$msgDbId]);
		         $delRes->closeCursor();
                     }
            }

            // Reindex the table of received messages
	    $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();

            return "success";

        } else {

            /* The user who deletes the messages is not an admin */

            $permcheck = false;
            $delcheck = 0;
            foreach ($recmessagedbIDs as $key => $rowtodelrw) {

                $rowtodelarr = explode("|", $rowtodelrw);
                $msgDbId = $rowtodelarr[0];
                $msgProvId = $rowtodelarr[1];

                // Get the phone number on which the message was received, and the number's provider 
                $getphprv = $this->connection->prepare('SELECT `id`, `to` FROM `*PREFIX*sms_relent_received` WHERE `id` = ?');
		$getphprvres = $getphprv->execute([$msgDbId]);
		$phnmbrprov = $getphprvres->fetch();
                $getphprvres->closeCursor();

                if ($phnmbrprov) {
                    $retrphprovraw = $phnmbrprov['to'];
                    $retrphprovarr = explode(": ", $retrphprovraw);
                    $retrprovider = $retrphprovarr[0];
                    $retrphnumber = "%" . $retrphprovarr[1] . "%";

                    // Get the username of the admin who shared the retrieved phone number with the non-admin user
                    $getadm = $this->connection->prepare('SELECT `user_id`, `available_numbers` FROM `*PREFIX*sms_relent_settings` WHERE `available_numbers` LIKE ?');
		    $getadmres = $getadm->execute([$retrphnumber]);
                    $admunameretr = [];
		    while ($getadmuname = $getadmres->fetch()) {
                           $admunameretr[] = $getadmuname['user_id'];
                    }
                    $getadmres->closeCursor();

                    if ($admunameretr) {
                        foreach ($admunameretr as $admkey => $admuname) {

                                 // Check if the retrieved admin allowed the user to delete messages
                                 $userDspNameder = "%" . $userDelDspName . "%";
                                 $usrsgrpsdel = 1;

                                 if ($retrprovider == "Telnyx") {

                                     $checkperm = $this->connection->prepare('SELECT `user_id`, `tnx_users_allowed`, `tnx_users_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `tnx_users_allowed` LIKE ? AND `tnx_users_del` = ?');
		                     $checkpermres = $checkperm->execute([$admuname, $userDspNameder, $usrsgrpsdel]);
                                     $admallwddel = $checkpermres->fetch();
                                     $checkpermres->closeCursor();

                                     // If the user has been allowed to delete messages by Display Name, delete the current message
                                     if ($admallwddel) {

                                         if ($msgProvId != "" && $msgProvId != "n/a") {

                                             // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                             $this->removeMsgFromConv($msgProvId);

				             $delquery = $this->connection->prepare('
					          DELETE FROM `*PREFIX*sms_relent_received`
					          WHERE `message_id` = ?');
				             $qrdelResult = $delquery->execute([$msgProvId]);
				             $qrdelResult->closeCursor();
                                             $permcheck = true;
                                             $delcheck++;
                                         } else {
				             $delquery = $this->connection->prepare('
					          DELETE FROM `*PREFIX*sms_relent_received`
					          WHERE `id` = ?');
				             $qrdelResult = $delquery->execute([$msgDbId]);
				             $qrdelResult->closeCursor();
                                             $permcheck = true;
                                             $delcheck++;
                                         }

                                     } else {
                                         // Check if the user has been allowed to delete messages by group
                                         $checkpermgrp = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed`, `tnx_groups_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `tnx_groups_del` = ?');
		                         $checkpermgrpres = $checkpermgrp->execute([$admuname, $usrsgrpsdel]);
                                         $admallwddelgrp = $checkpermgrpres->fetch();
                                         $checkpermgrpres->closeCursor();
                              
                                         if ($admallwddelgrp) {
					     // 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();

                                             $groupsallowed = explode("|", $admallwddelgrp['tnx_groups_allowed']);

                                             if ($usergrps && $groupsallowed) {
                                                 $countGrps = array_intersect($usergrps, $groupsallowed);

                                                 // If the user has been allowed to delete messages by group, delete the current message
                                                 if (count($countGrps) > 0) {

		                                     if ($msgProvId != "" && $msgProvId != "n/a") {

                                                         // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                                         $this->removeMsgFromConv($msgProvId);

						         $delquery = $this->connection->prepare('
							      DELETE FROM `*PREFIX*sms_relent_received`
							      WHERE `message_id` = ?');
						         $qrdelResult = $delquery->execute([$msgProvId]);
						         $qrdelResult->closeCursor();
                                                         $permcheck = true;
		                                         $delcheck++;
		                                     } else {
						         $delquery = $this->connection->prepare('
							      DELETE FROM `*PREFIX*sms_relent_received`
							      WHERE `id` = ?');
						         $qrdelResult = $delquery->execute([$msgDbId]);
						         $qrdelResult->closeCursor();
                                                         $permcheck = true;
		                                         $delcheck++;
		                                     }

                                                 }
                                             }
                                         }
                                     }

                                 } elseif ($retrprovider == "Plivo") {

                                     $checkperm = $this->connection->prepare('SELECT `user_id`, `plv_users_allowed`, `plv_users_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `plv_users_allowed` LIKE ? AND `plv_users_del` = ?');
		                     $checkpermres = $checkperm->execute([$admuname, $userDspNameder, $usrsgrpsdel]);
                                     $admallwddel = $checkpermres->fetch();
                                     $checkpermres->closeCursor();

                                     // If the user has been allowed to delete messages by Display Name, delete the current message
                                     if ($admallwddel) {

                                         if ($msgProvId != "" && $msgProvId != "n/a") {

                                             // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                             $this->removeMsgFromConv($msgProvId);

				             $delquery = $this->connection->prepare('
					          DELETE FROM `*PREFIX*sms_relent_received`
					          WHERE `message_id` = ?');
				             $qrdelResult = $delquery->execute([$msgProvId]);
				             $qrdelResult->closeCursor();
                                             $permcheck = true;
                                             $delcheck++;
                                         } else {
				             $delquery = $this->connection->prepare('
					          DELETE FROM `*PREFIX*sms_relent_received`
					          WHERE `id` = ?');
				             $qrdelResult = $delquery->execute([$msgDbId]);
				             $qrdelResult->closeCursor();
                                             $permcheck = true;
                                             $delcheck++;
                                         }
                                      
                                     } else {
                                         // Check if the user has been allowed to delete messages by group
                                         $checkpermgrp = $this->connection->prepare('SELECT `user_id`, `plv_groups_allowed`, `plv_groups_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `plv_groups_del` = ?');
		                         $checkpermgrpres = $checkpermgrp->execute([$admuname, $usrsgrpsdel]);
                                         $admallwddelgrp = $checkpermgrpres->fetch();
                                         $checkpermgrpres->closeCursor();
                              
                                         if ($admallwddelgrp) {
					     // 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();

                                             $groupsallowed = explode("|", $admallwddelgrp['plv_groups_allowed']);

                                             if ($usergrps && $groupsallowed) {
                                                 $countGrps = array_intersect($usergrps, $groupsallowed);

                                                 // If the user has been allowed to delete messages by group, delete the current message
                                                 if (count($countGrps) > 0) {

				                     if ($msgProvId != "" && $msgProvId != "n/a") {

                                                         // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                                         $this->removeMsgFromConv($msgProvId);

							 $delquery = $this->connection->prepare('
							      DELETE FROM `*PREFIX*sms_relent_received`
						              WHERE `message_id` = ?');
							 $qrdelResult = $delquery->execute([$msgProvId]);
							 $qrdelResult->closeCursor();
                                                         $permcheck = true;
				                         $delcheck++;
				                     } else {
							 $delquery = $this->connection->prepare('
						              DELETE FROM `*PREFIX*sms_relent_received`
							      WHERE `id` = ?');
							 $qrdelResult = $delquery->execute([$msgDbId]);
							 $qrdelResult->closeCursor();
                                                         $permcheck = true;
				                         $delcheck++;
				                     }
                                                 }
                                             }
                                         }
                                     }

                                 } elseif ($retrprovider == "Twilio") {

                                     $checkperm = $this->connection->prepare('SELECT `user_id`, `twl_users_allowed`, `twl_users_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `twl_users_allowed` LIKE ? AND `twl_users_del` = ?');
		                     $checkpermres = $checkperm->execute([$admuname, $userDspNameder, $usrsgrpsdel]);
                                     $admallwddel = $checkpermres->fetch();
                                     $checkpermres->closeCursor();

                                     // If the user has been allowed to delete messages by Display Name, delete the current message
                                     if ($admallwddel) {

                                         if ($msgProvId != "" && $msgProvId != "n/a") {

                                             // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                             $this->removeMsgFromConv($msgProvId);

				             $delquery = $this->connection->prepare('
					          DELETE FROM `*PREFIX*sms_relent_received`
					          WHERE `message_id` = ?');
				             $qrdelResult = $delquery->execute([$msgProvId]);
				             $qrdelResult->closeCursor();
                                             $permcheck = true;
                                             $delcheck++;
                                         } else {
				             $delquery = $this->connection->prepare('
					          DELETE FROM `*PREFIX*sms_relent_received`
					          WHERE `id` = ?');
				             $qrdelResult = $delquery->execute([$msgDbId]);
				             $qrdelResult->closeCursor();
                                             $permcheck = true;
                                             $delcheck++;
                                         }

                                     } else {
                                         // Check if the user has been allowed to delete messages by group
                                         $checkpermgrp = $this->connection->prepare('SELECT `user_id`, `twl_groups_allowed`, `twl_groups_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `twl_groups_del` = ?');
		                         $checkpermgrpres = $checkpermgrp->execute([$admuname, $usrsgrpsdel]);
                                         $admallwddelgrp = $checkpermgrpres->fetch();
                                         $checkpermgrpres->closeCursor();
                              
                                         if ($admallwddelgrp) {
					     // 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();

                                             $groupsallowed = explode("|", $admallwddelgrp['twl_groups_allowed']);

                                             if ($usergrps && $groupsallowed) {
                                                 $countGrps = array_intersect($usergrps, $groupsallowed);

                                                 // If the user has been allowed to delete messages by group, delete the current message
                                                 if (count($countGrps) > 0) {

				                     if ($msgProvId != "" && $msgProvId != "n/a") {

                                                         // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                                         $this->removeMsgFromConv($msgProvId);

							 $delquery = $this->connection->prepare('
							      DELETE FROM `*PREFIX*sms_relent_received`
							      WHERE `message_id` = ?');
							 $qrdelResult = $delquery->execute([$msgProvId]);
							 $qrdelResult->closeCursor();
                                                         $permcheck = true;
				                         $delcheck++;
				                     } else {
							 $delquery = $this->connection->prepare('
							      DELETE FROM `*PREFIX*sms_relent_received`
							      WHERE `id` = ?');
							 $qrdelResult = $delquery->execute([$msgDbId]);
							 $qrdelResult->closeCursor();
                                                         $permcheck = true;
				                         $delcheck++;
				                     }

                                                 }
                                             }
                                         }
                                     }

                                 } elseif ($retrprovider == "Flowroute") {

                                     $checkperm = $this->connection->prepare('SELECT `user_id`, `flr_users_allowed`, `flr_users_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `flr_users_allowed` LIKE ? AND `flr_users_del` = ?');
		                     $checkpermres = $checkperm->execute([$admuname, $userDspNameder, $usrsgrpsdel]);
                                     $admallwddel = $checkpermres->fetch();
                                     $checkpermres->closeCursor();

                                     // If the user has been allowed to delete messages by Display Name, delete the current message
                                     if ($admallwddel) {

                                         if ($msgProvId != "" && $msgProvId != "n/a") {

                                             // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                             $this->removeMsgFromConv($msgProvId);

				             $delquery = $this->connection->prepare('
					          DELETE FROM `*PREFIX*sms_relent_received`
					          WHERE `message_id` = ?');
				             $qrdelResult = $delquery->execute([$msgProvId]);
				             $qrdelResult->closeCursor();
                                             $permcheck = true;
                                             $delcheck++;
                                         } else {
				             $delquery = $this->connection->prepare('
					          DELETE FROM `*PREFIX*sms_relent_received`
					          WHERE `id` = ?');
				             $qrdelResult = $delquery->execute([$msgDbId]);
				             $qrdelResult->closeCursor();
                                             $permcheck = true;
                                             $delcheck++;
                                         }
                                  
                                     } else {
                                         // Check if the user has been allowed to delete messages by group
                                         $checkpermgrp = $this->connection->prepare('SELECT `user_id`, `flr_groups_allowed`, `flr_groups_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `flr_groups_del` = ?');
		                         $checkpermgrpres = $checkpermgrp->execute([$admuname, $usrsgrpsdel]);
                                         $admallwddelgrp = $checkpermgrpres->fetch();
                                         $checkpermgrpres->closeCursor();
                              
                                         if ($admallwddelgrp) {
					     // 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();

                                             $groupsallowed = explode("|", $admallwddelgrp['flr_groups_allowed']);

                                             if ($usergrps && $groupsallowed) {
                                                 $countGrps = array_intersect($usergrps, $groupsallowed);

                                                 // If the user has been allowed to delete messages by group, delete the current message
                                                 if (count($countGrps) > 0) {

				                     if ($msgProvId != "" && $msgProvId != "n/a") {

                                                         // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                                         $this->removeMsgFromConv($msgProvId);

							 $delquery = $this->connection->prepare('
							      DELETE FROM `*PREFIX*sms_relent_received`
							      WHERE `message_id` = ?');
							 $qrdelResult = $delquery->execute([$msgProvId]);
							 $qrdelResult->closeCursor();
                                                         $permcheck = true;
				                         $delcheck++;
				                     } else {
							 $delquery = $this->connection->prepare('
							      DELETE FROM `*PREFIX*sms_relent_received`
							      WHERE `id` = ?');
							 $qrdelResult = $delquery->execute([$msgDbId]);
							 $qrdelResult->closeCursor();
                                                         $permcheck = true;
				                         $delcheck++;
				                     }

                                                 }
                                             }
                                         }
                                     }
                                 }

                        }
                    }
                }
            }

            if ($delcheck > 0) {
                // Reindex the table of received messages
	        $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();
            }

            if ($permcheck) { return "success"; } else { return "not allowed"; }
        }
     }


     /**
      * @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
            $dsplnme = 'displayname';
	    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
	    $getacdatadnres = $getacdatadn->execute([$userId, $dsplnme]);
	    $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
            $restrPhoneNmbrs = [];
            $allowedPhoneNmbrs = [];
            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()) {
               $rowfetchedsc = htmlspecialchars($rowfetched["message"], ENT_QUOTES);
               $fetchedcont = str_replace(['&lt;br /&gt;', '&lt;br&gt;', '&lt;/b&gt;'], ['<br />', '<br>', '</b>'], $rowfetchedsc);
               $rowfetched["message"] = $fetchedcont;
               $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, $userstDelDspName, $sentmessagedbIDs) {

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

            /* The user who deletes the messages is an admin */

            foreach ($sentmessagedbIDs as $key => $sentrowtodel) {

                     $rowtodelarr = explode("|", $sentrowtodel);
                     $msgDbId = $rowtodelarr[0];
                     $msgProvId = $rowtodelarr[1];

                     // Delete the message
                     if ($msgProvId != "" && $msgProvId != "n/a") {

                         // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                         $this->removeMsgFromConv($msgProvId);

		         $smdlquery = $this->connection->prepare('
		               DELETE FROM `*PREFIX*sms_relent_sent`
		               WHERE `message_id` = ?');
		         $delsmsgRes = $smdlquery->execute([$msgProvId]);
		         $delsmsgRes->closeCursor();

                     } else {
		         $smdlquery = $this->connection->prepare('
		               DELETE FROM `*PREFIX*sms_relent_sent`
		               WHERE `id` = ?');
		         $delsmsgRes = $smdlquery->execute([$msgDbId]);
		         $delsmsgRes->closeCursor();
                     }
            }

            // Reindex the table of sent messages
	    $sqlupdatest = $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;');
	    $updatestRes = $sqlupdatest->execute();
	    $updatestRes->closeCursor();

            return "success";

        } else {

            /* The user who deletes the messages is not an admin */

            $permcheckst = false;
            $delstcheck = 0;
            foreach ($sentmessagedbIDs as $key => $sentrowtodel) {

                $rowtodelarr = explode("|", $sentrowtodel);
                $msgDbId = $rowtodelarr[0];
                $msgProvId = $rowtodelarr[1];

                // Get the phone number from which the message was sent, and the number's provider 
                $getphprv = $this->connection->prepare('SELECT `id`, `user_id`, `from` FROM `*PREFIX*sms_relent_sent` WHERE `id` = ?');
		$getphprvres = $getphprv->execute([$msgDbId]);
		$phnmbrprov = $getphprvres->fetch();
                $getphprvres->closeCursor();

                if ($phnmbrprov) {

                    $retrphprovraw = $phnmbrprov['from'];
                    $retrphprovarr = explode(": ", $retrphprovraw);
                    $retrprovider = $retrphprovarr[0];
                    $retrphnumber = "%" . $retrphprovarr[1] . "%";

                    // Get the username of the admin who shared the retrieved phone number with the non-admin user
                    $getadm = $this->connection->prepare('SELECT `user_id`, `available_numbers` FROM `*PREFIX*sms_relent_settings` WHERE `available_numbers` LIKE ?');
		    $getadmres = $getadm->execute([$retrphnumber]);
                    $admunameretr = [];
		    while ($getadmuname = $getadmres->fetch()) {
                           $admunameretr[] = $getadmuname['user_id'];
                    }
                    $getadmres->closeCursor();

                    if ($admunameretr) {

                            foreach ($admunameretr as $admkey => $admuname) {

                                 // Check if the retrieved admin allowed the user to delete messages
                                 $userDspNameder = "%" . $userstDelDspName . "%";
                                 $usrsgrpsdel = 1;

                                 if ($retrprovider == "Telnyx") {

                                     $checkperm = $this->connection->prepare('SELECT `user_id`, `tnx_users_allowed`, `tnx_users_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `tnx_users_allowed` LIKE ? AND `tnx_users_del` = ?');
		                     $checkpermres = $checkperm->execute([$admuname, $userDspNameder, $usrsgrpsdel]);
                                     $admallwddel = $checkpermres->fetch();
                                     $checkpermres->closeCursor();

                                     // If the user has been allowed to delete messages by Display Name, delete the current message
                                     if ($admallwddel) {

				         if ($msgProvId != "" && $msgProvId != "n/a") {

                                             // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                             $this->removeMsgFromConv($msgProvId);

					     $smdlquery = $this->connection->prepare('
					           DELETE FROM `*PREFIX*sms_relent_sent`
					           WHERE `message_id` = ?');
					     $delsmsgRes = $smdlquery->execute([$msgProvId]);
					     $delsmsgRes->closeCursor();
                                             $permcheckst = true;
				             $delstcheck++;
				         } else {
					     $smdlquery = $this->connection->prepare('
					           DELETE FROM `*PREFIX*sms_relent_sent`
					           WHERE `id` = ?');
					     $delsmsgRes = $smdlquery->execute([$msgDbId]);
					     $delsmsgRes->closeCursor();
                                             $permcheckst = true;
				             $delstcheck++;
				         }
                                      
                                     } else {
                                         // Check if the user has been allowed to delete messages by group
                                         $checkpermgrp = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed`, `tnx_groups_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `tnx_groups_del` = ?');
		                         $checkpermgrpres = $checkpermgrp->execute([$admuname, $usrsgrpsdel]);
                                         $admallwddelgrp = $checkpermgrpres->fetch();
                                         $checkpermgrpres->closeCursor();
                              
                                         if ($admallwddelgrp) {
					     // 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();

                                             $groupsallowed = explode("|", $admallwddelgrp['tnx_groups_allowed']);

                                             if ($usergrps && $groupsallowed) {
                                                 $countGrps = array_intersect($usergrps, $groupsallowed);

                                                 // If the user has been allowed to delete messages by group, delete the current message
                                                 if (count($countGrps) > 0) {

					             if ($msgProvId != "" && $msgProvId != "n/a") {

                                                         // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                                         $this->removeMsgFromConv($msgProvId);

							 $smdlquery = $this->connection->prepare('
							       DELETE FROM `*PREFIX*sms_relent_sent`
							       WHERE `message_id` = ?');
							 $delsmsgRes = $smdlquery->execute([$msgProvId]);
							 $delsmsgRes->closeCursor();
                                                         $permcheckst = true;
							 $delstcheck++;
					             } else {
							 $smdlquery = $this->connection->prepare('
							       DELETE FROM `*PREFIX*sms_relent_sent`
							       WHERE `id` = ?');
							 $delsmsgRes = $smdlquery->execute([$msgDbId]);
							 $delsmsgRes->closeCursor();
                                                         $permcheckst = true;
							 $delstcheck++;
					             }
                                                 }
                                             }
                                         }
                                     }

                                 } elseif ($retrprovider == "Plivo") {

                                     $checkperm = $this->connection->prepare('SELECT `user_id`, `plv_users_allowed`, `plv_users_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `plv_users_allowed` LIKE ? AND `plv_users_del` = ?');
		                     $checkpermres = $checkperm->execute([$admuname, $userDspNameder, $usrsgrpsdel]);
                                     $admallwddel = $checkpermres->fetch();
                                     $checkpermres->closeCursor();

                                     // If the user has been allowed to delete messages by Display Name, delete the current message
                                     if ($admallwddel) {

				         if ($msgProvId != "" && $msgProvId != "n/a") {

                                             // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                             $this->removeMsgFromConv($msgProvId);

					     $smdlquery = $this->connection->prepare('
					           DELETE FROM `*PREFIX*sms_relent_sent`
					           WHERE `message_id` = ?');
					     $delsmsgRes = $smdlquery->execute([$msgProvId]);
					     $delsmsgRes->closeCursor();
                                             $permcheckst = true;
				             $delstcheck++;
				         } else {
					     $smdlquery = $this->connection->prepare('
					           DELETE FROM `*PREFIX*sms_relent_sent`
					           WHERE `id` = ?');
					     $delsmsgRes = $smdlquery->execute([$msgDbId]);
					     $delsmsgRes->closeCursor();
                                             $permcheckst = true;
				             $delstcheck++;
				         }
                                    
                                     } else {
                                         // Check if the user has been allowed to delete messages by group
                                         $checkpermgrp = $this->connection->prepare('SELECT `user_id`, `plv_groups_allowed`, `plv_groups_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `plv_groups_del` = ?');
		                         $checkpermgrpres = $checkpermgrp->execute([$admuname, $usrsgrpsdel]);
                                         $admallwddelgrp = $checkpermgrpres->fetch();
                                         $checkpermgrpres->closeCursor();
                              
                                         if ($admallwddelgrp) {
					     // 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();

                                             $groupsallowed = explode("|", $admallwddelgrp['plv_groups_allowed']);

                                             if ($usergrps && $groupsallowed) {
                                                 $countGrps = array_intersect($usergrps, $groupsallowed);

                                                 // If the user has been allowed to delete messages by group, delete the current message
                                                 if (count($countGrps) > 0) {

					             if ($msgProvId != "" && $msgProvId != "n/a") {

                                                         // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                                         $this->removeMsgFromConv($msgProvId);

							 $smdlquery = $this->connection->prepare('
							       DELETE FROM `*PREFIX*sms_relent_sent`
							       WHERE `message_id` = ?');
							 $delsmsgRes = $smdlquery->execute([$msgProvId]);
							 $delsmsgRes->closeCursor();
                                                         $permcheckst = true;
							 $delstcheck++;
					             } else {
							 $smdlquery = $this->connection->prepare('
							       DELETE FROM `*PREFIX*sms_relent_sent`
							       WHERE `id` = ?');
							 $delsmsgRes = $smdlquery->execute([$msgDbId]);
							 $delsmsgRes->closeCursor();
                                                         $permcheckst = true;
							 $delstcheck++;
					             }

                                                 }
                                             }
                                         }
                                     }

                                 } elseif ($retrprovider == "Twilio") {

                                     $checkperm = $this->connection->prepare('SELECT `user_id`, `twl_users_allowed`, `twl_users_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `twl_users_allowed` LIKE ? AND `twl_users_del` = ?');
		                     $checkpermres = $checkperm->execute([$admuname, $userDspNameder, $usrsgrpsdel]);
                                     $admallwddel = $checkpermres->fetch();
                                     $checkpermres->closeCursor();

                                     // If the user has been allowed to delete messages by Display Name, delete the current message
                                     if ($admallwddel) {

				         if ($msgProvId != "" && $msgProvId != "n/a") {

                                             // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                             $this->removeMsgFromConv($msgProvId);

					     $smdlquery = $this->connection->prepare('
					           DELETE FROM `*PREFIX*sms_relent_sent`
					           WHERE `message_id` = ?');
					     $delsmsgRes = $smdlquery->execute([$msgProvId]);
					     $delsmsgRes->closeCursor();
                                             $permcheckst = true;
				             $delstcheck++;
				         } else {
					     $smdlquery = $this->connection->prepare('
					           DELETE FROM `*PREFIX*sms_relent_sent`
					           WHERE `id` = ?');
					     $delsmsgRes = $smdlquery->execute([$msgDbId]);
					     $delsmsgRes->closeCursor();
                                             $permcheckst = true;
				             $delstcheck++;
				         }
                                       
                                     } else {
                                         // Check if the user has been allowed to delete messages by group
                                         $checkpermgrp = $this->connection->prepare('SELECT `user_id`, `twl_groups_allowed`, `twl_groups_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `twl_groups_del` = ?');
		                         $checkpermgrpres = $checkpermgrp->execute([$admuname, $usrsgrpsdel]);
                                         $admallwddelgrp = $checkpermgrpres->fetch();
                                         $checkpermgrpres->closeCursor();
                              
                                         if ($admallwddelgrp) {
					     // 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();

                                             $groupsallowed = explode("|", $admallwddelgrp['twl_groups_allowed']);

                                             if ($usergrps && $groupsallowed) {
                                                 $countGrps = array_intersect($usergrps, $groupsallowed);

                                                 // If the user has been allowed to delete messages by group, delete the current message
                                                 if (count($countGrps) > 0) {

					             if ($msgProvId != "" && $msgProvId != "n/a") {

                                                         // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                                         $this->removeMsgFromConv($msgProvId);

							 $smdlquery = $this->connection->prepare('
							       DELETE FROM `*PREFIX*sms_relent_sent`
							       WHERE `message_id` = ?');
							 $delsmsgRes = $smdlquery->execute([$msgProvId]);
							 $delsmsgRes->closeCursor();
                                                         $permcheckst = true;
							 $delstcheck++;
					             } else {
							 $smdlquery = $this->connection->prepare('
							       DELETE FROM `*PREFIX*sms_relent_sent`
							       WHERE `id` = ?');
							 $delsmsgRes = $smdlquery->execute([$msgDbId]);
							 $delsmsgRes->closeCursor();
                                                         $permcheckst = true;
							 $delstcheck++;
					             }
                                                 }
                                             }
                                         }
                                     }

                                 } elseif ($retrprovider == "Flowroute") {

                                     $checkperm = $this->connection->prepare('SELECT `user_id`, `flr_users_allowed`, `flr_users_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `flr_users_allowed` LIKE ? AND `flr_users_del` = ?');
		                     $checkpermres = $checkperm->execute([$admuname, $userDspNameder, $usrsgrpsdel]);
                                     $admallwddel = $checkpermres->fetch();
                                     $checkpermres->closeCursor();

                                     // If the user has been allowed to delete messages by Display Name, delete the current message
                                     if ($admallwddel) {

				         if ($msgProvId != "" && $msgProvId != "n/a") {

                                             // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                             $this->removeMsgFromConv($msgProvId);

					     $smdlquery = $this->connection->prepare('
					           DELETE FROM `*PREFIX*sms_relent_sent`
					           WHERE `message_id` = ?');
					     $delsmsgRes = $smdlquery->execute([$msgProvId]);
					     $delsmsgRes->closeCursor();
                                             $permcheckst = true;
				             $delstcheck++;
				         } else {
					     $smdlquery = $this->connection->prepare('
					           DELETE FROM `*PREFIX*sms_relent_sent`
					           WHERE `id` = ?');
					     $delsmsgRes = $smdlquery->execute([$msgDbId]);
					     $delsmsgRes->closeCursor();
                                             $permcheckst = true;
				             $delstcheck++;
				         }
                                       
                                     } else {
                                         // Check if the user has been allowed to delete messages by group
                                         $checkpermgrp = $this->connection->prepare('SELECT `user_id`, `flr_groups_allowed`, `flr_groups_del` FROM `*PREFIX*sms_relent_subac` WHERE `user_id` = ? AND `flr_groups_del` = ?');
		                         $checkpermgrpres = $checkpermgrp->execute([$admuname, $usrsgrpsdel]);
                                         $admallwddelgrp = $checkpermgrpres->fetch();
                                         $checkpermgrpres->closeCursor();
                              
                                         if ($admallwddelgrp) {
					     // 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();

                                             $groupsallowed = explode("|", $admallwddelgrp['flr_groups_allowed']);

                                             if ($usergrps && $groupsallowed) {
                                                 $countGrps = array_intersect($usergrps, $groupsallowed);

                                                 // If the user has been allowed to delete messages by group, delete the current message
                                                 if (count($countGrps) > 0) {

					             if ($msgProvId != "" && $msgProvId != "n/a") {

                                                         // If it's the case, replace the message that will be deleted, in the conversations table, or remove the conversation's row from the conversations table
                                                         $this->removeMsgFromConv($msgProvId);

							 $smdlquery = $this->connection->prepare('
							       DELETE FROM `*PREFIX*sms_relent_sent`
							       WHERE `message_id` = ?');
							 $delsmsgRes = $smdlquery->execute([$msgProvId]);
							 $delsmsgRes->closeCursor();
                                                         $permcheckst = true;
							 $delstcheck++;
					             } else {
							 $smdlquery = $this->connection->prepare('
							       DELETE FROM `*PREFIX*sms_relent_sent`
							       WHERE `id` = ?');
							 $delsmsgRes = $smdlquery->execute([$msgDbId]);
							 $delsmsgRes->closeCursor();
                                                         $permcheckst = true;
							 $delstcheck++;
					             }

                                                 }
                                             }
                                         }
                                     }
                                 }
                            }

                    }
                }
            }

            if ($delstcheck > 0) {

                // Reindex the table of sent messages
	        $sqlupdatest = $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;');
	        $updatestRes = $sqlupdatest->execute();
	        $updatestRes->closeCursor();
            }

            if ($permcheckst) { return "success"; } else { return "not allowed"; }
        }
     }


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

        // Get the phone numbers that the current user has access to
        $getnumberscv = $this->connection->prepare('SELECT `user_id`, `available_numbers` FROM `*PREFIX*sms_relent_settings` WHERE `user_id` = ?');
	$getcrtusrnocv = $getnumberscv->execute([$userId]);
        $getusrnmbrscv = $getcrtusrnocv->fetch();
        $getcrtusrnocv->closeCursor();

        if ($getusrnmbrscv['available_numbers']) {

            $retrievednmbrArr = explode("|", $getusrnmbrscv['available_numbers']);
            $retrievednmbrpr = array_filter($retrievednmbrArr);
            $retrievednmbrsfin = [];

            foreach ($retrievednmbrpr as $convKey => $convValue) {
                     $retrnmbrex = explode(": ", $convValue);
                     $retrievednmbrsfin[] = $retrnmbrex[1]; 
            }
            $retrievednmbrsimp = "'" . implode("','", $retrievednmbrsfin) . "'";

            // Get the conversation data from the 'sms_relent_conv' table
            $getconvdata = $this->connection->executeQuery("SELECT `conversation_id`, `archived`, `last_archived`, `last_unarchived`, `archived_by`, `unarchived_by`, `last_msg_date`, 
                                                           `last_msg_from`, `last_msg_to`, `last_message`, `lastmsgdisplayname`, `flagged`, `flagunflagby`, `flagunflagdate`, `tag`,
                                                           `taguntagby`, `taguntagdate`, `description`, `descriptionby`, `descriptiondate` FROM `*PREFIX*sms_relent_conv` WHERE 
                                                           `last_msg_from` IN (" . $retrievednmbrsimp . ") OR `last_msg_to` IN (" . $retrievednmbrsimp . ")");

            $convdatafdb = [];
            while ($convdatafetched = $getconvdata->fetch()) {
                   $rowfetchedsc = htmlspecialchars($convdatafetched["last_message"], ENT_QUOTES);
                   $fetchedcont = str_replace(['&lt;br /&gt;', '&lt;br&gt;', '&lt;/b&gt;'], ['<br />', '<br>', '</b>'], $rowfetchedsc);
                   $convdatafetched["last_message"] = $fetchedcont;
                   $convdatafdb[] = $convdatafetched;
            }   
            $getconvdata->closeCursor();

        } else { $convdatafdb = []; }

        return $convdatafdb;
     }


     /**
      * @NoAdminRequired
      */
     public function archiveconv($userId, $userDspNameArch, $conversationId) {

        $archivedyn = 1;
        $dateArchived = date("Y-m-d H:i:s");
        $sqlarchive = $this->connection->prepare('
		        UPDATE `*PREFIX*sms_relent_conv`
		        SET `archived` = ?, `last_archived` = ?, `archived_by` = ?
                        WHERE `conversation_id` = ?');
        $archiveRes = $sqlarchive->execute([$archivedyn, $dateArchived, $userDspNameArch, $conversationId]);
        $archiveRes->closeCursor();
        if ($archiveRes) { return "success"; } else { return "error"; }
     }


     /**
      * @NoAdminRequired
      */
     public function unarchiveconv($userId, $userDspNameUnarch, $conversationIdUn) {

        $archivedynun = 0;
        $dateUnarchived = date("Y-m-d H:i:s");
        $sqlarchiveun = $this->connection->prepare('
		        UPDATE `*PREFIX*sms_relent_conv`
		        SET `archived` = ?, `last_unarchived` = ?, `unarchived_by` = ?
                        WHERE `conversation_id` = ?');
        $archiveResun = $sqlarchiveun->execute([$archivedynun, $dateUnarchived, $userDspNameUnarch, $conversationIdUn]);
        $archiveResun->closeCursor();
        if ($archiveResun) { return "success"; } else { return "error"; }
     }


     /**
      * @NoAdminRequired
      */
     public function saveconvdescription($userId, $userDspNameDesc, $convDescription, $convId) {

            $dateDescSaved = date("Y-m-d H:i:s");
	    $updatedesc = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_conv`
			SET `description` = ?, `descriptionby` = ?, `descriptiondate` = ?
                        WHERE `conversation_id` = ?');
	    $updatedescres = $updatedesc->execute([$convDescription, $userDspNameDesc, $dateDescSaved, $convId]);

            if ($updatedescres) {
                return $respupdesc = "The conversation description has been saved successfully.";
            } else {
                return $respupdesc = "Error while trying to save the conversation description to the database.";
            }
	    $updatedescres->closeCursor();
     }


     /**
      * @NoAdminRequired
      */
     public function saveconvtag($userId, $userDspNameTag, $convTag, $convId) {

            $dateTagSaved = date("Y-m-d H:i:s");
	    $updatetag = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_conv`
			SET `tag` = ?, `taguntagby` = ?, `taguntagdate` = ?
                        WHERE `conversation_id` = ?');
	    $updatetagres = $updatetag->execute([$convTag, $userDspNameTag, $dateTagSaved, $convId]);

            if ($updatetagres) {
                return $respuptag = "The conversation tag has been saved successfully.";
            } else {
                return $respuptag = "Error while trying to save the conversation tag to the database.";
            }
	    $updatetagres->closeCursor();
     }


     /**
      * @NoAdminRequired
      */
     public function saveconvflag($userId, $userDspNameFlag, $convFlag, $convId) {

            $dateFlagSaved = date("Y-m-d H:i:s");
	    $updateflag = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_conv`
			SET `flagged` = ?, `flagunflagby` = ?, `flagunflagdate` = ?
                        WHERE `conversation_id` = ?');
	    $updateflagres = $updateflag->execute([$convFlag, $userDspNameFlag, $dateFlagSaved, $convId]);

            if ($updateflagres) {
                return $respupflag = "success";
            } else {
                return $respupflag = "failure";
            }
	    $updateflagres->closeCursor();
     }


     /**
      * @NoAdminRequired
      */
     public function removeconvmsgs($userId, $conversationId) {

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

            // Delete all the messages included in the conversation with the given conversation ID, from the 'sms_relent_received' table
            $convmsgdelrec = $this->connection->prepare('
		           DELETE FROM `*PREFIX*sms_relent_received`
		           WHERE `conversation_id` = ?');
            $convmsgdelrecres = $convmsgdelrec->execute([$conversationId]);
	    $convmsgdelrecres->closeCursor();

	    $sqlupdaterec = $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;');
	    $updaterecRes = $sqlupdaterec->execute();
	    $updaterecRes->closeCursor();

            // Delete all the messages included in the conversation with the given conversation ID, from the 'sms_relent_sent' table
            $convmsgdelsent = $this->connection->prepare('
		           DELETE FROM `*PREFIX*sms_relent_sent`
		           WHERE `conversation_id` = ?');
            $convmsgdelsentres = $convmsgdelsent->execute([$conversationId]);
	    $convmsgdelsentres->closeCursor();

	    $sqlupdatesent = $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;');
	    $updatesentRes = $sqlupdatesent->execute();
	    $updatesentRes->closeCursor();

            // Delete the row with the given conversation ID from the 'sms_relent_conv' table
            $convmsgdel = $this->connection->prepare('
		           DELETE FROM `*PREFIX*sms_relent_conv`
		           WHERE `conversation_id` = ?');
            $convmsgdelres = $convmsgdel->execute([$conversationId]);
	    $convmsgdelres->closeCursor();

            // Reindex the conversations table
	    $sqlupdateconv = $this->connection->prepare('
                           SET @resetconv = 0;
		           UPDATE `*PREFIX*sms_relent_conv`
		           SET `id` = @resetconv := @resetconv + 1;
                           ALTER TABLE `*PREFIX*sms_relent_conv` auto_increment=1;');
	    $updateconvRes = $sqlupdateconv->execute();
	    $updateconvRes->closeCursor();

            return "success";

        } else { return "not allowed"; }
     }


     /**
      * @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
            $displnme = 'displayname';
	    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
	    $getacdatadnres = $getacdatadn->execute([$userId, $displnme]);
	    $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
            $restrPhoneNmbrs = [];
            $allowedPhoneNmbrs = [];
            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';
	       $rowfetchedscrc = htmlspecialchars($rcrowsfetch['message'], ENT_QUOTES);
	       $fetchedconrc = str_replace(["&lt;br /&gt;", "&lt;br&gt;", "&lt;/b&gt;"], ["<br />", "<br>", "</b>"], $rowfetchedscrc);
	       $rcrowsfetch['message'] = $fetchedconrc;
	       $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';
               $rowfetchedscs = htmlspecialchars($rowfetchedsmsg["message"], ENT_QUOTES);
               $fetchedcons = str_replace(['&lt;br /&gt;', '&lt;br&gt;', '&lt;/b&gt;'], ['<br />', '<br>', '</b>'], $rowfetchedscs);
               $rowfetchedsmsg["message"] = $fetchedcons;
               $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 getactivitytable($userId, $displayname, $interval) {

        // If the user is an admin
        if ($this->groupManager->isAdmin($userId)) {

            // Get the number of messages sent by the admin in the last specified time interval
            if ($interval == "day") {
                $getsentact = $this->connection->prepare('
		       SELECT `user_id`, `date`, `from`, `to`, `message`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 DAY) and now());');
            } elseif ($interval == "week") {
                $getsentact = $this->connection->prepare('
		       SELECT `user_id`, `date`, `from`, `to`, `message`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 WEEK) and now());');
            } elseif ($interval == "month") {
                $getsentact = $this->connection->prepare('
		       SELECT `user_id`, `date`, `from`, `to`, `message`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 MONTH) and now());');
            }

            $getsentmsgsact = $getsentact->execute([$userId]);

            $fromto = [];
            $totalmsg = 0;
            $crwordnb = [];
            $crcharnb = [];
            $finfromtoadm = [];
            while ($rowfetchedsmsg = $getsentmsgsact->fetch()) {
                   $totalmsg++;
                   $crwordnb[] = count(preg_split('/\s+/', $rowfetchedsmsg["message"]));
                   $crcharnb[] = mb_strlen($rowfetchedsmsg["message"]);

                   if (array_key_exists($rowfetchedsmsg['to'], $fromto)) {
                           @$fromto[$rowfetchedsmsg['to']][$rowfetchedsmsg['from']] = intval($fromto[$rowfetchedsmsg['to']][$rowfetchedsmsg['from']]) + 1;
                   } else {
                           @$fromto[$rowfetchedsmsg['to']][$rowfetchedsmsg['from']] = 1;
                   }
            }
            $getsentmsgsact->closeCursor();
            $totwordnb = array_sum($crwordnb);
            $totcharnb = array_sum($crcharnb);
            $finfromtoadm[0] = ["displayname" => $displayname, "nbdata" => ["msgpernmbr" => $fromto, "totalmessage" => $totalmsg, "totalwordnb" => $totwordnb, "totalcharnb" => $totcharnb]];

            // Get the number of messages sent by all the users with whom the admin is sharing 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 = [];
            }

            // Collect the username and Display Name of the users allowed to use the API keys by specifying their names
            $usrnamedispname = [];
            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) {
                             $usrnamedispname[$acdatausrname['uid']] = $alwdusrvalue;
                         }
                         $getacdatausrnmres->closeCursor();
            }

            // Get the usernames of all the users from 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);
            

	    // Get the Display Name of each user in all allowed groups
            $cruserdname = [];
            foreach ($allwdusersgrpfnl as $alwdkey => $alwdusr) {
		     $displnme = 'displayname';
		     $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
		     $getacdatadnres = $getacdatadn->execute([$alwdusr, $displnme]);
		     $acdatausrdnadm = $getacdatadnres->fetch();
		     $cruserdname[$alwdusr] = $acdatausrdnadm['value'];
		     $getacdatadnres->closeCursor();
            }

            // The usernames and the corresponding Display Names of all the users with whom the admin is sharing his API keys
            $allusrdispnm = array_merge($usrnamedispname, $cruserdname);
            $allusrdispnmunq = array_unique($allusrdispnm);

            $finfromtoreg = [];
            if ($allusrdispnmunq) {

                  $finfromtoreg = [];
                  foreach ($allusrdispnmunq as $allusrkey => $allusrvalue) {

		         if ($interval == "day") {
			     $getsntrgusrsc = $this->connection->prepare('
			          SELECT `user_id`, `date`, `from`, `to`, `message`
			          FROM  `*PREFIX*sms_relent_sent`
			          WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 DAY) and now());');
		         } elseif ($interval == "week") {
			     $getsntrgusrsc = $this->connection->prepare('
			          SELECT `user_id`, `date`, `from`, `to`, `message`
			          FROM  `*PREFIX*sms_relent_sent`
			          WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 WEEK) and now());');
		         } elseif ($interval == "month") {
			     $getsntrgusrsc = $this->connection->prepare('
			          SELECT `user_id`, `date`, `from`, `to`, `message`
			          FROM  `*PREFIX*sms_relent_sent`
			          WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 MONTH) and now());');
		         }

                         $getsntrgusresc = $getsntrgusrsc->execute([$allusrkey]);

		         $fromtosc = [];
		         $totalmsgsc = 0;
		         $crwordnbsc = [];
		         $crcharnbsc = [];
                         $finfromtosc = [];

		         while ($getstrgusrft = $getsntrgusresc->fetch()) {
		                $totalmsgsc++;
		                $crwordnbsc[] = count(preg_split('/\s+/', $getstrgusrft["message"]));
		                $crcharnbsc[] = mb_strlen($getstrgusrft["message"]);

		                if (array_key_exists($getstrgusrft['to'], $fromtosc)) {
	                            @$fromtosc[$getstrgusrft['to']][$getstrgusrft['from']] = intval($fromtosc[$getstrgusrft['to']][$getstrgusrft['from']]) + 1;
		                } else {
		                    @$fromtosc[$getstrgusrft['to']][$getstrgusrft['from']] = 1;
		                }
		         }
		         $getsntrgusresc->closeCursor();
		         $totwordnbsc = array_sum($crwordnbsc);
		         $totcharnbsc = array_sum($crcharnbsc);

                         $finfromtoreg[] = ["displayname" => $allusrvalue, "nbdata" => ["msgpernmbr" => $fromtosc, "totalmessage" => $totalmsgsc, "totalwordnb" => $totwordnbsc, "totalcharnb" => $totcharnbsc]];
                }
            }

	    $finfromto = array_merge($finfromtoadm, $finfromtoreg);
            usort($finfromto, function($a, $b) { return strcmp($a["displayname"], $b["displayname"]); });
            return $finfromto;

        // If the user is not an admin
        } else {

            if ($interval == "day") {
                $getsentactrg = $this->connection->prepare('
		       SELECT `user_id`, `date`, `from`, `to`, `message`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 DAY) and now());');
            } elseif ($interval == "week") {
                $getsentactrg = $this->connection->prepare('
		       SELECT `user_id`, `date`, `from`, `to`, `message`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 WEEK) and now());');
            } elseif ($interval == "month") {
                $getsentactrg = $this->connection->prepare('
		       SELECT `user_id`, `date`, `from`, `to`, `message`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 MONTH) and now());');
            }
            $getsentmsgsactrg = $getsentactrg->execute([$userId]);

            $fromtorg = [];
            $totalmsgrg = 0;
            $crwordnbrg = [];
            $crcharnbrg = [];
            $finfromto = [];
            while ($rowfetchedsmsgrg = $getsentmsgsactrg->fetch()) {
                   $totalmsgrg++;
                   $crwordnbrg[] = count(preg_split('/\s+/', $rowfetchedsmsgrg["message"]));
                   $crcharnbrg[] = mb_strlen($rowfetchedsmsgrg["message"]);

                   if (array_key_exists($rowfetchedsmsgrg['to'], $fromtorg)) {
                           @$fromtorg[$rowfetchedsmsgrg['to']][$rowfetchedsmsgrg['from']] = intval($fromtorg[$rowfetchedsmsgrg['to']][$rowfetchedsmsgrg['from']]) + 1;
                   } else {
                           @$fromtorg[$rowfetchedsmsgrg['to']][$rowfetchedsmsgrg['from']] = 1;
                   }
            }
            $getsentmsgsactrg->closeCursor();
            $totwordnbrg = array_sum($crwordnbrg);
            $totcharnbrg = array_sum($crcharnbrg);
            $finfromto[0] = ["displayname" => $displayname, "nbdata" => ["msgpernmbr" => $fromtorg, "totalmessage" => $totalmsgrg, "totalwordnb" => $totwordnbrg, "totalcharnb" => $totcharnbrg]];

            return $finfromto;
        }
     }


     /**
      * @NoAdminRequired
      */
     public function getindactivity($userId, $displayname, $interval, $indusrdspnm) {

        if ($this->groupManager->isAdmin($userId) || $displayname == $indusrdspnm) {

            // Get the username of the individual user whose Display Name is received
            $getacdataind = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `name` = ? AND `value` = ?');
            $getacdataindres = $getacdataind->execute(['displayname', $indusrdspnm]);
            $acdataind = $getacdataindres->fetch();
            $crntuserid = $acdataind["uid"];
            $getacdataindres->closeCursor();

            if ($interval == "day") {
                $getsentactrg = $this->connection->prepare('
		       SELECT `user_id`, `date`, `from`, `to`, `message`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 DAY) and now());');
            } elseif ($interval == "week") {
                $getsentactrg = $this->connection->prepare('
		       SELECT `user_id`, `date`, `from`, `to`, `message`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 WEEK) and now());');
            } elseif ($interval == "month") {
                $getsentactrg = $this->connection->prepare('
		       SELECT `user_id`, `date`, `from`, `to`, `message`
		       FROM  `*PREFIX*sms_relent_sent`
		       WHERE `user_id` = ? AND (date between date_sub(now(), INTERVAL 1 MONTH) and now());');
            }
            $getsentmsgsactind = $getsentactrg->execute([$crntuserid]);

            $fromtoind = [];
            $totalmsgind = 0;
            $crwordnbind = [];
            $crcharnbind = [];
            $finfromtoind = [];
            while ($rowfetchedind = $getsentmsgsactind->fetch()) {
                   $totalmsgind++;
                   $crwordnbind[] = count(preg_split('/\s+/', $rowfetchedind["message"]));
                   $crcharnbind[] = mb_strlen($rowfetchedind["message"]);

                   if (array_key_exists($rowfetchedind['to'], $fromtoind)) {
                           @$fromtoind[$rowfetchedind['to']][$rowfetchedind['from']] = intval($fromtoind[$rowfetchedind['to']][$rowfetchedind['from']]) + 1;
                   } else {
                           @$fromtoind[$rowfetchedind['to']][$rowfetchedind['from']] = 1;
                   }
            }
            $getsentmsgsactind->closeCursor();
            $totwordnbind = array_sum($crwordnbind);
            $totcharnbind = array_sum($crcharnbind);
            $finfromtoind[0] = ["nbdata" => ["msgpernmbr" => $fromtoind, "totalmessage" => $totalmsgind, "totalwordnb" => $totwordnbind, "totalcharnb" => $totcharnbind]];

            return $finfromtoind;
        }
     }


     /**
      * @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
            $dispname = 'displayname';
	    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
	    $getacdatadnres = $getacdatadn->execute([$userId, $dispname]);
	    $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
            $restrPhoneNmbrs = [];
            $allowedPhoneNmbrs = [];
            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';
               $rowfetchedsc = htmlspecialchars($rcrowsfetch["message"], ENT_QUOTES);
               $fetchedcont = str_replace(['&lt;br /&gt;', '&lt;br&gt;', '&lt;/b&gt;'], ['<br />', '<br>', '</b>'], $rowfetchedsc);
               $rcrowsfetch["message"] = $fetchedcont;
               $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';
               $rowfetchedsc = htmlspecialchars($rowfetchedsmsg["message"], ENT_QUOTES);
               $fetchedcont = str_replace(['&lt;br /&gt;', '&lt;br&gt;', '&lt;/b&gt;'], ['<br />', '<br>', '</b>'], $rowfetchedsc);
               $rowfetchedsmsg["message"] = $fetchedcont;
               $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
            $dispname = 'displayname';
	    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
	    $getacdatadnres = $getacdatadn->execute([$userId, $dispname]);
	    $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
            $restrPhoneNmbrs = [];
            $allowedPhoneNmbrs = [];
            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';
               $rowfetchedscrpl = htmlspecialchars($rcrowsfetch["message"], ENT_QUOTES);
               $fetchedcontrpl = str_replace(['&lt;br /&gt;', '&lt;br&gt;', '&lt;/b&gt;'], ['<br />', '<br>', '</b>'], $rowfetchedscrpl);
               $rcrowsfetch["message"] = $fetchedcontrpl;
               $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';
               $rowfetchedscst = htmlspecialchars($rowfetchedsmsg["message"], ENT_QUOTES);
               $fetchedconrst = str_replace(['&lt;br /&gt;', '&lt;br&gt;', '&lt;/b&gt;'], ['<br />', '<br>', '</b>'], $rowfetchedscst);
               $rowfetchedsmsg["message"] = $fetchedconrst;
               $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]);

	    $updatedispnmcv = $this->connection->prepare('
			UPDATE `*PREFIX*sms_relent_conv`
			SET `lastmsgdisplayname` = ?
                        WHERE `last_msg_from` = ?');
	    $updatedispnmrescv = $updatedispnmcv->execute([$authorDisplayname, $from]);

            if ($updatedispnmres && $updatedispnmrescv) {
                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 getmsgsperpgnewmsgarchnb($userId) {

        $sqlmpp = $this->connection->prepare('
	       SELECT `user_id`, `messagesperpage`, `msg_check_interval`, `archived_conv_nmbr`
               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'], 'archconvnb' => $mesppdata['archived_conv_nmbr'] ];
            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 getadminornot($userId) {

            if ($this->groupManager->isAdmin($userId)) { $admreguser = 'admin'; } else { $admreguser = 'reguser'; }
            return $admreguser;
     }


     /**
      * @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`, `archived_conv_nmbr`                           
		    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;
            $settingsfromdb['notification_email'] = htmlspecialchars($settingsfromdb['notification_email'], ENT_QUOTES);

            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;
        }
     }


     public function updatekeysallowedusers($userId, $groups, $users, $groupsdel, $usersdel, $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 ($seldataarr[$j]['usersallowed']) {
                                      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 ($seldataarr[$k]['groupsallowed']) {
                                      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) {

                    // Insert/Update the allowed users in the 'sms_relent_subac' table
                    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();
                             }
                        }

                        $usersalwdrs = implode("|", $ctusernamearr);

                        if ($upchck == 0) {

		            if ($provider == "tnx") {

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

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

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

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

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

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

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

                        } else {

		            if ($provider == "tnx") {

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

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

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

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

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

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

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

                        $datalwdres->closeCursor();
                    }

                    // Insert/Update the allowed groups in the 'sms_relent_subac' table
                    if ($groups) {

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

                                $allwdgrps[] = $groupvalue;

		                $groupsalwdrs = implode("|", $allwdgrps);

		                if ($upchck == 0) {

				    if ($provider == "tnx") {

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

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

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

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

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

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

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

		                } else {

				    if ($provider == "tnx") {

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

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

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

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

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

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

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

		                $datalwdres->closeCursor();
                        }

                    }

                } else {

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

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

                    $msgtosend = $grppart . $usrpart;
                }


            } else {

                if ($upchck == 0) {

                    // Insert/Update the allowed users in the 'sms_relent_subac' table
                    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();
                             }
                        }

                        $usersalwdrs = implode("|", $ctusernamearr);

		        if ($provider == "tnx") {

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

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

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

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

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

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

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

                        $datalwdres->closeCursor();
                    }

                    // Insert/Update the allowed groups in the 'sms_relent_subac' table
                    if ($groups) {

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

                                $allwdgrps[] = $groupvalue;

		                $groupsalwdrs = implode("|", $allwdgrps);

                                if ($upchck == 0) {

				    if ($provider == "tnx") {

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

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

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

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

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

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

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

                                } else {

				    if ($provider == "tnx") {

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

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

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

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

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

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

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

                                }

		                $datalwdres->closeCursor();
                        }

                    }

                } else {

		    // Update the allowed users in the 'sms_relent_subac' table
                    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();
                             }
                        }


                        $usersalwdrs = implode("|", $ctusernamearr);

		        if ($provider == "tnx") {

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

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

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

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

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

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

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

                        $datalwdres->closeCursor();
                    }

		    // Update the allowed groups in the 'sms_relent_subac' table
                    if ($groups) {

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

                                 $allwdgrps[] = $groupvalue;

		                 $groupsalwdrs = implode("|", $allwdgrps);

				 if ($provider == "tnx") {

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

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

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

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

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

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

			             $updatealwd = $this->connection->prepare('UPDATE `*PREFIX*sms_relent_subac` SET `flr_groups_allowed` = ?, `flr_groups_del` = ? WHERE `user_id` = ?');
			             if ($datalwdres = $updatealwd->execute([$groupsalwdrs, $groupsdel, $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";
		    }

                    $settingsadm['telapi_url'] = ($settingsadm['telapi_url'])? htmlspecialchars($settingsadm['telapi_url'], ENT_QUOTES) : "";
                    $settingsadm['telapi_url_rec'] = ($settingsadm['telapi_url_rec'])? htmlspecialchars($settingsadm['telapi_url_rec'], ENT_QUOTES) : "";
                    $settingsadm['nexapi_url'] = ($settingsadm['nexapi_url'])? htmlspecialchars($settingsadm['nexapi_url'], ENT_QUOTES) : "";
                    $settingsadm['nexapi_url_rec'] = ($settingsadm['nexapi_url_rec'])? htmlspecialchars($settingsadm['nexapi_url_rec'], ENT_QUOTES) : "";
                    $settingsadm['twilapi_url'] = ($settingsadm['twilapi_url'])? htmlspecialchars($settingsadm['twilapi_url'], ENT_QUOTES) : "";
                    $settingsadm['twilapi_url_rec'] = ($settingsadm['twilapi_url_rec'])? htmlspecialchars($settingsadm['twilapi_url_rec'], ENT_QUOTES) : "";
                    $settingsadm['flowapi_url'] = ($settingsadm['flowapi_url'])? htmlspecialchars($settingsadm['flowapi_url'], ENT_QUOTES) : "";
                    $settingsadm['flowapi_url_rec'] = ($settingsadm['flowapi_url_rec'])? htmlspecialchars($settingsadm['flowapi_url_rec'], ENT_QUOTES) : "";

		    // 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;
		           $restrfetched['groups'] = htmlspecialchars($restrfetched['groups'], ENT_QUOTES);
		           $restrfetched['users'] = htmlspecialchars($restrfetched['users'], ENT_QUOTES);
		           $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`, `tnx_groups_del`, `tnx_users_del`,
                                                             `plv_groups_del`, `plv_users_del`, `twl_groups_del`, `twl_users_del`, `flr_groups_del`, `flr_users_del` 
                                                              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'])? htmlspecialchars($crtdtrow['tnx_groups_allowed'], ENT_QUOTES) : "",
                                        'tnx_users_allowed' => ($crtdtrow['tnx_users_allowed'])? htmlspecialchars($crtdtrow['tnx_users_allowed'], ENT_QUOTES) : "",
                                        'plv_groups_allowed' => ($crtdtrow['plv_groups_allowed'])? htmlspecialchars($crtdtrow['plv_groups_allowed'], ENT_QUOTES) : "", 
                                        'plv_users_allowed' => ($crtdtrow['plv_users_allowed'])? htmlspecialchars($crtdtrow['plv_users_allowed'], ENT_QUOTES) : "",
                                        'twl_groups_allowed' => ($crtdtrow['twl_groups_allowed'])? htmlspecialchars($crtdtrow['twl_groups_allowed'], ENT_QUOTES) : "", 
                                        'twl_users_allowed' => ($crtdtrow['twl_users_allowed'])? htmlspecialchars($crtdtrow['twl_users_allowed'], ENT_QUOTES) : "",
                                        'flr_groups_allowed' => ($crtdtrow['flr_groups_allowed'])? htmlspecialchars($crtdtrow['flr_groups_allowed'], ENT_QUOTES) : "",
                                        'flr_users_allowed' => ($crtdtrow['flr_users_allowed'])? htmlspecialchars($crtdtrow['flr_users_allowed'], ENT_QUOTES) : "",
                                        'tnx_groups_del' => $crtdtrow['tnx_groups_del'], 'tnx_users_del' => $crtdtrow['tnx_users_del'],
                                        'plv_groups_del' => $crtdtrow['plv_groups_del'], 'plv_users_del' => $crtdtrow['plv_users_del'],
                                        'twl_groups_del' => $crtdtrow['twl_groups_del'], 'twl_users_del' => $crtdtrow['twl_users_del'],
                                        'flr_groups_del' => $crtdtrow['flr_groups_del'], 'flr_users_del' => $crtdtrow['flr_users_del']];
                        $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, $archivedConvNmbr) {
        $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`, `archived_conv_nmbr`
		        FROM  `*PREFIX*sms_relent_settings`
		        WHERE `user_id` = ?');

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

        $rowup = $resultstng->fetch();

        $resultstng->closeCursor();

        if (($notificationEmail == "") || ($notificationEmail != "" && filter_var($notificationEmail, FILTER_VALIDATE_EMAIL))) {

            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`, 
                                         `archived_conv_nmbr`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
			    ');
	        $runqr = $sql->execute([$userId, $telapiUrlRec, $telapiUrl, $nexapiUrlRec, $nexapiUrl, $twilapiUrlRec, $twilapiUrl, $flowapiUrlRec, $flowapiUrl, $messagesperpage, $getNotify, 
                                        $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval, $archivedConvNmbr]);
                if ($runqr) { $msgtsnd = "success"; } else { $msgtsnd = "failure"; }

            } 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` = ?, `archived_conv_nmbr` = ?
	                    WHERE `user_id` = ?');
	        $updateRes = $sqlupdatedb->execute([$telapiUrlRec, $telapiUrl, $nexapiUrlRec, $nexapiUrl, $twilapiUrlRec, $twilapiUrl, $flowapiUrlRec, $flowapiUrl, $messagesperpage, 
                                                    $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval, $archivedConvNmbr, $userId]);
                if ($updateRes) { $msgtsnd = "success"; } else { $msgtsnd = "failure"; }
	        $updateRes->closeCursor();
	    }

            $infotosend = $msgtsnd;

        } else { $infotosend = "failure"; }

        return $infotosend;
     }


     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 = ''; }

                $telSenderName = preg_replace( "[^A-Za-z0-9 ]", "", $telSenderName);
                $nexSenderName = preg_replace( "[^A-Za-z0-9 ]", "", $nexSenderName);
                $twilSenderName = preg_replace( "[^A-Za-z0-9 ]", "", $twilSenderName);

	        $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, 
                                            $archivedConvNmbr) {

        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`, `archived_conv_nmbr`
		        FROM  `*PREFIX*sms_relent_settings`
		        WHERE `user_id` = ?');

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

            $rowup = $resultstng->fetch();

            $resultstng->closeCursor();

            if (($notificationEmail == "") || ($notificationEmail != "" && filter_var($notificationEmail, FILTER_VALIDATE_EMAIL))) {

                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`, `archived_conv_nmbr`)
				    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)');
	            $runqradm = $sql->execute([$userId, $messagesperpage, $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval, $archivedConvNmbr]);
                    if ($runqradm) { $msgadmsnd = "success"; } else { $msgadmsnd = "failure"; }

                } 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` = ?, `archived_conv_nmbr` = ?
	                    WHERE `user_id` = ?');
	            $updateRes = $sqlupdatedb->execute([$messagesperpage, $getNotify, $notificationEmail, $getsmsinemail, $showDisplayNames, $addDisplayNames, $msgCheckInterval, $archivedConvNmbr, $userId]);
                    if ($updateRes) { $msgadmsnd = "success"; } else { $msgadmsnd = "failure"; }
	            $updateRes->closeCursor();
                }

                $infoprsadm = $msgadmsnd; 

            } else { $infoprsadm = "failure"; }

        } else { $infoprsadm = "failure"; }

        return $infoprsadm;
     }


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

        if ($this->groupManager->isAdmin($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();

        } else {

            // If the user is not an admin, get the API keys in a different way, since a non-admin has to use the API keys shared with him by an admin

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

            // 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]);

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

            if ($provider == 'telnyx') {

		    // Search the 'sms_relent_subac' table to find the admin who shared his credentials with the current user
		    $getgrps = $this->connection->prepare('SELECT `user_id`, `tnx_users_allowed` FROM `*PREFIX*sms_relent_subac` WHERE `tnx_users_allowed` LIKE ?');
		    $getgrpsres = $getgrps->execute([$usersAllwdLike]);
                    $getadmusr = $getgrpsres->fetch();
		    $getgrpsres->closeCursor();

                    if ($getadmusr) {
                        $admalwdusr = $getadmusr['user_id'];
		    } else {
		        // Search by group
		        if ($crtusergrps) {
		            $usersbgrp = [];
		            foreach ($crtusergrps as $grkey => $grvalue) {

		                     $grvalueLike = "%" . $grvalue . "%";
				     $getgrpsec = $this->connection->prepare('SELECT `user_id`, `tnx_groups_allowed` FROM `*PREFIX*sms_relent_subac` WHERE `tnx_groups_allowed` LIKE ?');
				     $getgrpsecres = $getgrpsec->execute([$grvalueLike]);
                                     $getadmusrgr = $getgrpsecres->fetch();
				     $getgrpsecres->closeCursor();

                                     if ($getadmusrgr) {
                                         $usersbgrp[] = $getadmusrgr['user_id'];
		                     }                                 
		            }

		            if ($usersbgrp) {
		                $admalwdusr = $usersbgrp[0];
		            } else {
		                $admalwdusr = '';
		            }
		        }
		    }

		    if ($admalwdusr) {
			$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([$admalwdusr]);
			$settingsfrdb = $resultcr->fetch();
			$resultcr->closeCursor();

                        // Get the delivery receipt URL of the non-admin user
			$sqldr = $this->connection->prepare('
			      SELECT `user_id`, `telapi_url` FROM `*PREFIX*sms_relent_settings`
			      WHERE `user_id` = ?');
			$sqldrres = $sqldr->execute([$userId]);
			$delrcpt = $sqldrres->fetch();
			$sqldrres->closeCursor();
                        $delrcpturl = $delrcpt['telapi_url'];

                        // Replace the delivery receipt URL of the admin with that of the non-admin
                        $settingsfrdb['telapi_url'] = $delrcpturl;

		    } else { return; }

            } elseif ($provider == 'plivo') {

		    // Search the 'sms_relent_subac' table to find the admin who shared his credentials with the current user
		    $getgrps = $this->connection->prepare('SELECT `user_id`, `plv_users_allowed` FROM `*PREFIX*sms_relent_subac` WHERE `plv_users_allowed` LIKE ?');
		    $getgrpsres = $getgrps->execute([$usersAllwdLike]);
                    $getadmusr = $getgrpsres->fetch();
		    $getgrpsres->closeCursor();

                    if ($getadmusr) {
                        $admalwdusr = $getadmusr['user_id'];
		    } else {
		        // Search by group
		        if ($crtusergrps) {
		            $usersbgrp = [];
		            foreach ($crtusergrps as $grkey => $grvalue) {

		                     $grvalueLike = "%" . $grvalue . "%";
				     $getgrpsec = $this->connection->prepare('SELECT `user_id`, `plv_groups_allowed` FROM `*PREFIX*sms_relent_subac` WHERE `plv_groups_allowed` LIKE ?');
				     $getgrpsecres = $getgrpsec->execute([$grvalueLike]);
                                     $getadmusrgr = $getgrpsecres->fetch();
				     $getgrpsecres->closeCursor();

                                     if ($getadmusrgr) {
                                         $usersbgrp[] = $getadmusrgr['user_id'];
		                     }                                 
		            }

		            if ($usersbgrp) {
		                $admalwdusr = $usersbgrp[0];
		            } else {
		                $admalwdusr = '';
		            }
		        }
		    }

		    if ($admalwdusr) {
			$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([$admalwdusr]);
			$settingsfrdb = $resultcr->fetch();
			$resultcr->closeCursor();

                        // Get the delivery receipt URL of the non-admin user
			$sqldr = $this->connection->prepare('
			      SELECT `user_id`, `nexapi_url` FROM `*PREFIX*sms_relent_settings`
			      WHERE `user_id` = ?');
			$sqldrres = $sqldr->execute([$userId]);
			$delrcpt = $sqldrres->fetch();
			$sqldrres->closeCursor();
                        $delrcpturl = $delrcpt['nexapi_url'];

                        // Replace the delivery receipt URL of the admin with that of the non-admin
                        $settingsfrdb['nexapi_url'] = $delrcpturl;

		    } else { return; }

            } elseif ($provider == 'twilio') {

		    // Search the 'sms_relent_subac' table to find the admin who shared his credentials with the current user
		    $getgrps = $this->connection->prepare('SELECT `user_id`, `twl_users_allowed` FROM `*PREFIX*sms_relent_subac` WHERE `twl_users_allowed` LIKE ?');
		    $getgrpsres = $getgrps->execute([$usersAllwdLike]);
                    $getadmusr = $getgrpsres->fetch();
		    $getgrpsres->closeCursor();

                    if ($getadmusr) {
                        $admalwdusr = $getadmusr['user_id'];
		    } else {
		        // Search by group
		        if ($crtusergrps) {
		            $usersbgrp = [];
		            foreach ($crtusergrps as $grkey => $grvalue) {

		                     $grvalueLike = "%" . $grvalue . "%";
				     $getgrpsec = $this->connection->prepare('SELECT `user_id`, `twl_groups_allowed` FROM `*PREFIX*sms_relent_subac` WHERE `twl_groups_allowed` LIKE ?');
				     $getgrpsecres = $getgrpsec->execute([$grvalueLike]);
                                     $getadmusrgr = $getgrpsecres->fetch();
				     $getgrpsecres->closeCursor();

                                     if ($getadmusrgr) {
                                         $usersbgrp[] = $getadmusrgr['user_id'];
		                     }                                 
		            }

		            if ($usersbgrp) {
		                $admalwdusr = $usersbgrp[0];
		            } else {
		                $admalwdusr = '';
		            }
		        }
		    }

		    if ($admalwdusr) {
			$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([$admalwdusr]);
			$settingsfrdb = $resultcr->fetch();
			$resultcr->closeCursor();

                        // Get the delivery receipt URL of the non-admin user
			$sqldr = $this->connection->prepare('
			      SELECT `user_id`, `twilapi_url` FROM `*PREFIX*sms_relent_settings`
			      WHERE `user_id` = ?');
			$sqldrres = $sqldr->execute([$userId]);
			$delrcpt = $sqldrres->fetch();
			$sqldrres->closeCursor();
                        $delrcpturl = $delrcpt['twilapi_url'];

                        // Replace the delivery receipt URL of the admin with that of the non-admin
                        $settingsfrdb['twilapi_url'] = $delrcpturl;

		    } else { return; }

            } elseif ($provider == 'flowroute') {

		    // Search the 'sms_relent_subac' table to find the admin who shared his credentials with the current user
		    $getgrps = $this->connection->prepare('SELECT `user_id`, `flr_users_allowed` FROM `*PREFIX*sms_relent_subac` WHERE `flr_users_allowed` LIKE ?');
		    $getgrpsres = $getgrps->execute([$usersAllwdLike]);
                    $getadmusr = $getgrpsres->fetch();
		    $getgrpsres->closeCursor();

                    if ($getadmusr) {
                        $admalwdusr = $getadmusr['user_id'];
		    } else {
		        // Search by group
		        if ($crtusergrps) {
		            $usersbgrp = [];
		            foreach ($crtusergrps as $grkey => $grvalue) {

		                     $grvalueLike = "%" . $grvalue . "%";
				     $getgrpsec = $this->connection->prepare('SELECT `user_id`, `flr_groups_allowed` FROM `*PREFIX*sms_relent_subac` WHERE `flr_groups_allowed` LIKE ?');
				     $getgrpsecres = $getgrpsec->execute([$grvalueLike]);
                                     $getadmusrgr = $getgrpsecres->fetch();
				     $getgrpsecres->closeCursor();

                                     if ($getadmusrgr) {
		                         $usersbgrp[] = $getadmusrgr['user_id'];
		                     }                                 
		            }

		            if ($usersbgrp) {
		                $admalwdusr = $usersbgrp[0];
		            } else {
		                $admalwdusr = '';
		            }
		        }
		    }

		    if ($admalwdusr) {
			$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([$admalwdusr]);
			$settingsfrdb = $resultcr->fetch();
			$resultcr->closeCursor();

                        // Get the delivery receipt URL of the non-admin user
			$sqldr = $this->connection->prepare('
			      SELECT `user_id`, `flowapi_url` FROM `*PREFIX*sms_relent_settings`
			      WHERE `user_id` = ?');
			$sqldrres = $sqldr->execute([$userId]);
			$delrcpt = $sqldrres->fetch();
			$sqldrres->closeCursor();
                        $delrcpturl = $delrcpt['flowapi_url'];

                        // Replace the delivery receipt URL of the admin with that of the non-admin
                        $settingsfrdb['flowapi_url'] = $delrcpturl;

		    } else { return; }

            }
        }


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

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

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

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

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

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

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

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

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

        $telapiurlrec = $settingsfrdb['telapi_url_rec'];
        $telapiurlstr = $settingsfrdb['telapi_url'];
        $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();
        if (!$datafromdb || empty($datafromdb['user_id'])) { return ''; }
        return (string) $datafromdb['user_id'];
     }

     /**
      * @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();
        if (!$datafromdbdel || empty($datafromdbdel['user_id'])) { return ''; }
        return (string) $datafromdbdel['user_id'];
     }

     /**
      * @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();
        if (!$pldatafromdb || empty($pldatafromdb['user_id'])) { return ''; }
        return (string) $pldatafromdb['user_id'];
     }

     /**
      * @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();
        if (!$datafromdbdr || empty($datafromdbdr['user_id'])) { return ''; }
        return (string) $datafromdbdr['user_id'];
     }

     /**
      * @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();
        if (!$twdatafromdb || empty($twdatafromdb['user_id'])) { return ''; }
        return (string) $twdatafromdb['user_id'];
     }

     /**
      * @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();
        if (!$datafromdbdrtw || empty($datafromdbdrtw['user_id'])) { return ''; }
        return (string) $datafromdbdrtw['user_id'];
     }

     /**
      * @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();
        if (!$fldatafromdb || empty($fldatafromdb['user_id'])) { return ''; }
        return (string) $fldatafromdb['user_id'];
     }

     /**
      * @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();
        if (!$datafromdbdrfl || empty($datafromdbdrfl['user_id'])) { return ''; }
        return (string) $datafromdbdrfl['user_id'];
     }


    /**
     * @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 {

            // Get Telnyx phone numbers
            $smsapicredtx = $this->getapicredentials($userId, 'telnyx');

            if ($smsapicredtx) {

                $telnyxkey = $smsapicredtx[0];
                $telsendernameinit = $smsapicredtx[9];

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

                if ($telnyxkey != '') {

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

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

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

                } else { $telcurrentnmbrs = []; }

            } else { $telcurrentnmbrs = []; $telsenderarr = []; }

            // Get Plivo phone numbers
            $smsapicredpl = $this->getapicredentials($userId, 'plivo');

            if ($smsapicredpl) {

                $nexapikey = $smsapicredpl[5];
                $nexapisecret = $smsapicredpl[6];
                $nexsendernameinit = $smsapicredpl[10];

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

                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 = []; }

            } else { $nexcurrentnmbrs = []; $nexsenderarr = []; }


            // Get Twilio phone numbers
            $smsapicredtw = $this->getapicredentials($userId, 'twilio');

            if ($smsapicredtw) {

                $twilapikey = $smsapicredtw[15];
                $twilapisecret = $smsapicredtw[16];
                $twilsendernameinit = $smsapicredtw[19];

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

                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 = []; }

            } else { $twilcurrentnmbrs = []; $twilsenderarr = []; }

            // Get Flowroute phone numbers
            $smsapicredfl = $this->getapicredentials($userId, 'flowroute');

            if ($smsapicredfl) {

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

                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 = []; }

            } else { $flowcurrentnmbrs = []; }

            $currentnmbrs = array_merge($telcurrentnmbrs, $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
                    $dsplnm = 'displayname';
		    $getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
		    $getacdatadnres = $getacdatadn->execute([$userId, $dsplnm]);
		    $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) {

        // Get Telnyx phone numbers
        $smsapicredtx = $this->getapicredentials($userId, 'telnyx');

        if ($smsapicredtx) {

            $telnyxkey = $smsapicredtx[0];
            $telsendernameinit = $smsapicredtx[9];

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

            if ($telnyxkey != '') {

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

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

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

            } else { $telcurrentnmbrs = []; }

        } else { $telcurrentnmbrs = []; $telsenderarr = []; }

        // Get Plivo phone numbers
        $smsapicredpl = $this->getapicredentials($userId, 'plivo');

        if ($smsapicredpl) {

            $nexapikey = $smsapicredpl[5];
            $nexapisecret = $smsapicredpl[6];
            $nexsendernameinit = $smsapicredpl[10];

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

            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 = []; }

        } else { $nexcurrentnmbrs = []; $nexsenderarr = []; }

        // Get Twilio phone numbers
        $smsapicredtw = $this->getapicredentials($userId, 'twilio');

        if ($smsapicredtw) {

            $twilapikey = $smsapicredtw[15];
            $twilapisecret = $smsapicredtw[16];
            $twilsendernameinit = $smsapicredtw[19];

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

            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 = []; }

        } else { $twilcurrentnmbrs = []; $twilsenderarr = []; }

        // Get Flowroute phone numbers
        $smsapicredfl = $this->getapicredentials($userId, 'flowroute');

        if ($smsapicredfl) {

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

            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 = []; }

        } else { $flowcurrentnmbrs = []; }

        $currentnmbrs = array_merge($telcurrentnmbrs, $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
                $dispname = 'displayname';
		$getacdatadn = $this->connection->prepare('SELECT `uid`, `name`, `value` FROM `*PREFIX*accounts_data` WHERE `uid` = ? AND `name` = ?');
		$getacdatadnres = $getacdatadn->execute([$userId, $dispname]);
		$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; 
            }
        }
    }
}
