| Current Path : /var/www/html/components/com_jchat/Model/ |
| Current File : /var/www/html/components/com_jchat/Model/ConferenceModel.php |
<?php
namespace JExtstore\Component\JChat\Site\Model;
/**
* @package JCHAT::WEBRTC::components::com_jchat
* @subpackage models
* @author Joomla! Extensions Store
* @copyright (C) 2024 - Joomla! Extensions Store
* @license GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html
*/
defined( '_JEXEC' ) or die( 'Restricted access' );
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Factory;
use Joomla\CMS\Filter\InputFilter;
use JExtstore\Component\JChat\Administrator\Framework\Model as JChatModel;
use JExtstore\Component\JChat\Administrator\Framework\Exception as JChatException;
use JExtstore\Component\JChat\Administrator\Framework\Helpers\Users as JChatHelpersUsers;
/**
* Group users chat model
*
* @package JCHAT::WEBRTC::components::com_jchat
* @subpackage models
* @since 2.5
*/
class ConferenceModel extends JChatModel {
/**
* This peer1 session ID
* @access private
* @var int
*/
private $peer1;
/**
* Client response
* @access private
* @var array
*/
private $response;
/**
* Stream model instance
* @access public
* @var object
*/
public $streamModel;
/**
* User instance
* @access public
* @var object
*/
public $myUser;
/**
* User field name
* @access public
* @var string
*/
public $userFieldName;
/**
*
* Store contact user ID for current owner
*
* @param string $otherPeer
* @param string $sdp
* @param string $iceCandidate
* @param int $videoCam
* @param int $isCaller
* @params string $otherPeers Used to chain calls with other participants
*
* @access public
* @return boolean
*/
public function storeEntity($otherPeer = null, $sdp = null, $iceCandidate = null, $videoCam = null, $isCaller = 0, $otherPeers = null) {
// Check if correct informations are feed to this server model
if(!$otherPeer) {
$this->response['storing'] = array('status'=>false, 'exception_message'=>Text::_('COM_JCHAT_NOPEER_SPECIFIED'));
return $this->response;
}
// Missing informations sent by client, we can't go on
if(!$sdp && !$iceCandidate) {
$this->response['storing'] = array('status'=>false, 'exception_message'=>Text::_('COM_JCHAT_NODATA_SPECIFIED'));
return $this->response;
}
// Check if callee has permissions to use videochat
$aclParamValue = $this->componentParams->get('allow_videochat', array(0));
// Ensure that the ACL parameter has no 'All groups' option selected
if(is_array($aclParamValue) && !in_array(0, $aclParamValue, false)) {
// Fetch current user id using session id of the remote callee peer
$query = "SELECT " .
$this->dbInstance->quoteName('userid') .
"\n FROM " .
$this->dbInstance->quoteName('#__session') .
"\n WHERE " .
$this->dbInstance->quoteName('session_id') . " = " . $this->dbInstance->quote($otherPeer);
$otherPeerUserID = $this->dbInstance->setQuery($query)->loadResult();
$otherPeerUser = Factory::getContainer()->get(\Joomla\CMS\User\UserFactoryInterface::class)->loadUserById($otherPeerUserID);
// If we are calling a super user skip the ACL permissions check, always allowed
if(!$otherPeerUser->authorise('core.admin')) {
$totalParamGroups = $aclParamValue;
// Cycle on all the group selected and retrieve the child groups
foreach ($aclParamValue as $aclParamGroup) {
$totalParamGroups = array_merge($totalParamGroups, JChatHelpersUsers::getChildGroups($this->dbInstance, $aclParamGroup));
}
// Remove duplicates
$totalParamGroups = array_unique($totalParamGroups);
// Fetch current user groups, but firstly user id using session id of the remote callee peer
$userGroups = $otherPeerUser->getAuthorisedGroups();
// Finally intersect to check ACL permission allowed
if(!array_intersect($totalParamGroups, $userGroups)) {
$this->response['storing'] = array('status'=>false, 'exception_message'=>Text::_('COM_JCHAT_OTHERPEER_NOTALLOWED'), 'usermessage'=>true);
return $this->response;
}
}
}
// Avoid collision call based on concurrency model
if(!$isCaller) {
// Check if the current caller is not already a callee from other peer, respect concurrency model
$queryNotCallee = "SELECT" .
$this->dbInstance->quoteName('peer1') .
"\n FROM #__jchat_webrtc_conference" .
"\n WHERE " .
$this->dbInstance->quoteName('peer2') . " = " .
$this->dbInstance->quote($this->peer1);
$imIACallee = $this->dbInstance->setQuery($queryNotCallee)->loadResult();
// This peer is no more a callee from other peer for example the caller hanged up, don't go on starting a collision call!
if(!$imIACallee) {
$this->response['storing'] = array('status'=>false, 'exception_message'=>Text::_('COM_JCHAT_NOMORE_A_CALLEE'));
return $this->response;
}
}
// Exchange field and value
$field = $sdp ? 'sdp' : 'icecandidate';
$message = $sdp ? $sdp : $iceCandidate;
// Now execute insert/update query with feed data, the result will be a call start/accept
$query = "INSERT INTO #__jchat_webrtc_conference" .
"\n (" . $this->dbInstance->quoteName('peer1') . "," .
$this->dbInstance->quoteName('peer2') . "," .
$this->dbInstance->quoteName($field) . "," .
$this->dbInstance->quoteName('videocam') . "," .
$this->dbInstance->quoteName('other_peers') . ")" .
"\n VALUES (" .
$this->dbInstance->quote($this->peer1) . "," .
$this->dbInstance->quote($otherPeer) . "," .
$this->dbInstance->quote($message) . "," .
$this->dbInstance->quote($videoCam) . "," .
$this->dbInstance->quote($otherPeers) . ")" .
"\n ON DUPLICATE KEY UPDATE" .
$this->dbInstance->quoteName($field) . "=" .
$this->dbInstance->quote($message);
try {
$this->dbInstance->setQuery($query);
$this->dbInstance->execute ();
} catch (JChatException $e) {
$this->response['storing'] = array('status'=>false, 'exception_message'=>$e->getMessage());
return $this->response;
} catch (\Exception $e) {
$jchatException = new JChatException($e->getMessage(), 'error');
$this->response['storing'] = array('status'=>false, 'exception_message'=>$jchatException->getMessage());
return $this->response;
}
// All went well
$this->response['storing'] = array('status'=>true);
return $this->response;
}
/**
* Completely deletes a conversation call, this means that caller or callee
* will delete both records and reset status of both peers
*
* @param int $ids
* @access public
* @return array
*/
public function deleteEntity($ids): array {
// End a peers conversation call
$query = "DELETE FROM #__jchat_webrtc_conference" .
"\n WHERE (" .
$this->dbInstance->quoteName('peer1') . " = " .
$this->dbInstance->quote($this->peer1) .
"\n AND " .
$this->dbInstance->quoteName('peer2') . " = " .
$this->dbInstance->quote($ids) . ")" .
"\n OR (" .
$this->dbInstance->quoteName('peer1') . " = " .
$this->dbInstance->quote($ids) .
"\n AND " .
$this->dbInstance->quoteName('peer2') . " = " .
$this->dbInstance->quote($this->peer1) . ")";
try {
$this->dbInstance->setQuery($query);
$this->dbInstance->execute ();
} catch (JChatException $e) {
$this->response['storing'] = array('status'=>false, 'exception_message'=>$e->getMessage());
return $this->response;
} catch (\Exception $e) {
$jchatException = new JChatException($e->getMessage(), 'error');
$this->response['storing'] = array('status'=>false, 'exception_message'=>$jchatException->getMessage());
return $this->response;
}
// All went well
$this->response['storing'] = array('status'=>true);
// Remove my own deleted call from the session to avoid false double
if(isset($this->sessionName['jchat_conference_webrtc_caller_sessions'][$ids])) {
unset($this->sessionName['jchat_conference_webrtc_caller_sessions'][$ids]);
}
return $this->response;
}
/**
*
* Store contact user ID for current owner
*
* @param int $videoCam
* @access public
* @return boolean
*/
public function updateEntity($videoCam) {
// End a peers conversation call
$query = "UPDATE #__jchat_webrtc_conference" .
"\n SET " .
$this->dbInstance->quoteName('videocam') . " = " . (int)$videoCam .
"\n WHERE" .
$this->dbInstance->quoteName('peer1') . " = " .
$this->dbInstance->quote($this->peer1);
try {
$this->dbInstance->setQuery($query);
$this->dbInstance->execute ();
} catch (JChatException $e) {
$this->response['storing'] = array('status'=>false, 'exception_message'=>$e->getMessage());
return $this->response;
} catch (\Exception $e) {
$jchatException = new JChatException($e->getMessage(), 'error');
$this->response['storing'] = array('status'=>false, 'exception_message'=>$jchatException->getMessage());
return $this->response;
}
// All went well
$this->response['storing'] = array('status'=>true);
return $this->response;
}
/**
* Class constructor
* @access public
* @param array $config
* @param object $factory
*/
public function __construct($config = array(), ?MVCFactoryInterface $factory = null) {
// Parent model construct
parent::__construct( $config, $factory );
// Store ssessionID peer1 caller
$this->peer1 = $config['sessiontable']->session_id;
$this->response = array();
// Get component params
$this->getComponentParams();
// Reference to the stream model
if(isset($config['streamModel'])) {
$this->streamModel = $config['streamModel'];
}
// Store the owned user object instance
$this->myUser = $this->app->getIdentity();
$filter = InputFilter::getInstance();
$this->userFieldName = $filter->clean($this->componentParams->get('usefullname', 'username'), 'word');
}
}