| Current Path : /var/www/html/plugins/system/jchat/ |
| Current File : /var/www/html/plugins/system/jchat/jchat.php |
<?php
/**
* App runner
* @package JCHAT::plugins::system
* @author Joomla! Extensions Store
* @copyright (C) 2024 - Joomla! Extensions Store
* @license GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html
*/
// no direct access
defined ( '_JEXEC' ) or die ( 'Restricted access' );
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\SubscriberInterface;
use Joomla\Event\DispatcherInterface;
use Joomla\Event\Event;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Registry\Registry;
use Joomla\CMS\Factory;
use Joomla\CMS\Date\Date;
use Joomla\CMS\Router\Route;
use Joomla\Filter\OutputFilter;
use JExtstore\Component\JChat\Administrator\Framework\Helpers\Language as JChatHelpersLanguage;
class PlgSystemJChat extends CMSPlugin implements SubscriberInterface {
/**
* @access private
* @var boolean
*/
private $isPluginStopped;
/**
* App reference
*
* @access protected
* @var Object
*/
protected $appInstance;
/**
* DB reference
*
* @access protected
* @var Object
*/
protected $dbInstance;
/**
* Component configuration
*
* @access protected
* @var Object
*/
protected $componentConfig;
/**
* User object
*
* @access protected
* @var Object
*/
protected $myUser;
/**
* Holds the list of bots IP addresses
*
* @var array
*/
protected $botsIP = ['52.162.212.163'=>true,'13.78.216.56'=>true,'65.52.113.236'=>true,'52.229.122.240'=>true,'172.255.48.147'=>true,'172.255.48.146'=>true,'172.255.48.145'=>true,'172.255.48.144'=>true,'172.255.48.143'=>true,'172.255.48.142'=>true,'24.109.190.162'=>true,'172.255.48.141'=>true,'172.255.48.140'=>true,'172.255.48.139'=>true,'172.255.48.138'=>true,'172.255.48.137'=>true,'172.255.48.136'=>true,'172.255.48.135'=>true,'172.255.48.134'=>true,'172.255.48.133'=>true,'172.255.48.132'=>true,'172.255.48.131'=>true,'172.255.48.130'=>true,'104.214.48.247'=>true,'40.74.243.176'=>true,'40.74.243.13'=>true,'40.74.242.253'=>true,'13.85.82.26'=>true,'13.85.24.90'=>true,'13.85.24.83'=>true,'13.66.7.11'=>true,'104.214.72.101'=>true,'191.235.99.221'=>true,'191.235.98.164'=>true,'104.41.2.19'=>true,'104.211.165.53'=>true,'104.211.143.8'=>true,'172.255.61.40'=>true,'172.255.61.39'=>true,'172.255.61.38'=>true,'172.255.61.37'=>true,'172.255.61.36'=>true,'172.255.61.35'=>true,'172.255.61.34'=>true,'13.91.230.174'=>true,'20.52.146.77'=>true,'65.52.36.250'=>true,'70.37.83.240'=>true,'104.214.110.135'=>true,'157.55.189.189'=>true,'191.232.194.51'=>true,'52.175.57.81'=>true,'52.237.236.145'=>true,'52.237.250.73'=>true,'52.237.235.185'=>true,'40.83.89.214'=>true,'40.123.218.94'=>true,'102.133.169.66'=>true,'52.172.14.87'=>true,'52.231.199.170'=>true,'52.246.165.153'=>true,'13.76.97.224'=>true,'13.53.162.7'=>true,'20.52.36.49'=>true,'20.188.63.151'=>true,'51.144.102.233'=>true,'23.96.34.105'=>true];
/**
* JS App Inject
*
* @access private
* @param Object $cParams
* @return void
*/
private function injectApp ($cParams) {
// Ottenimento document
$doc = $this->appInstance->getDocument ();
$option = $this->appInstance->getInput()->get('option', null);
$viewName = $this->appInstance->getInput()->get('view', null);
// Output JS APP nel Document
if($doc->getType() !== 'html' || $this->appInstance->getInput()->getCmd ( 'tmpl' ) === 'component') {
return false;
}
$user = $this->appInstance->getIdentity();
if(!$user->id && !$cParams->get('guestenabled', false)) {
return;
}
// Special exclusion for Akeeba LoginGuard 2SV page and J4 Captive Login
if (($option == 'com_users' && $this->appInstance->getInput()->get ( 'view' ) == 'captive') || $option == 'com_loginguard') {
return false;
}
// Special exclusion for Kunena reply post
if ($option == 'com_kunena' && $this->appInstance->getInput()->get ( 'view' ) == 'topic' && in_array($this->appInstance->getInput()->get ( 'layout' ), ['create', 'reply', 'edit'])) {
return false;
}
// Check if bots should be excluded
if($cParams->get('exclude_bots', false)) {
$isBot = false;
// Exclude bots based on IP address
if(array_key_exists($_SERVER['REMOTE_ADDR'], $this->botsIP)) {
$isBot = true;
}
// Exclude bots based on user agent
if (isset ( $_SERVER ['HTTP_USER_AGENT'] )) {
$user_agent = $_SERVER ['HTTP_USER_AGENT'];
$botRegexPattern = "(Googlebot\/|Googlebot\-Mobile|Googlebot\-Image|Googlebot\-Video|Google favicon|JSitemapbot|Mediapartners\-Google|bingbot|Lighthouse|gtmetrix|slurp|java|wget|curl|Commons\-HttpClient|Python\-urllib|libwww|httpunit|nutch|phpcrawl|msnbot|jyxobot|FAST\-WebCrawler|FAST Enterprise Crawler|biglotron|teoma|convera|seekbot|gigablast|exabot|ngbot|ia_archiver|GingerCrawler|webmon |httrack|webcrawler|grub\.org|UsineNouvelleCrawler|antibot|netresearchserver|speedy|fluffy|bibnum\.bnf|findlink|msrbot|panscient|yacybot|AISearchBot|IOI|ips\-agent|tagoobot|MJ12bot|dotbot|woriobot|yanga|buzzbot|mlbot|yandexbot|purebot|Linguee Bot|Voyager|CyberPatrol|voilabot|baiduspider|citeseerxbot|spbot|twengabot|postrank|turnitinbot|scribdbot|page2rss|sitebot|linkdex|Adidxbot|blekkobot|ezooms|dotbot|Mail\.RU_Bot|discobot|heritrix|findthatfile|europarchive\.org|NerdByNature\.Bot|sistrix crawler|ahrefsbot)";
$isBot = $isBot || preg_match("/{$botRegexPattern}/i", $user_agent);
}
if($isBot) {
return false;
}
}
// Check access levels intersection to ensure that users has access usage permission for chat
// Get users access levels based on user groups belonging
$userAccessLevels = $user->getAuthorisedViewLevels();
// Get chat access level from configuration, if set AKA param != array(0) go on with intersection
$chatAccessLevels = $cParams->get('chat_accesslevels', array(0));
if(is_array($chatAccessLevels) && !in_array(0, $chatAccessLevels, false)) {
$intersectResult = array_intersect($userAccessLevels, $chatAccessLevels);
$hasChatAccess = (bool)(count($intersectResult));
// Return if user has no access
if(!$hasChatAccess) {
return;
}
}
// Check for menu exclusion
$menu = $this->appInstance->getMenu()->getActive();
if(is_object($menu)) {
$menuItemid = $menu->id;
$menuExcluded = $cParams->get('chat_exclusions');
if(is_array($menuExcluded) && !in_array(0, $menuExcluded, false) && in_array($menuItemid, $menuExcluded)) {
return;
}
$doc->getWebAssetManager()->addInlineScript("var jchat_itemid='$menuItemid';");
}
// Check for IP multiple ranges exclusions
if($cParams->get ( 'ipbanning', false)) {
$ipAddressRegex = '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/i';
$clientIP = $_SERVER ['REMOTE_ADDR'];
$clientIpDec = ( float ) sprintf ( "%u", ip2long ( $clientIP ) );
$ipRanges = $cParams->get ( 'iprange_multiple', null);
// Check if data are not null
if($ipRanges) {
// Try to load every range, one per row
$explodeRows = explode(PHP_EOL, $ipRanges);
if(!empty($explodeRows)) {
foreach ($explodeRows as $singleRange) {
// Try to detect single range
$explodeRange = explode('-', $singleRange);
if(!empty($explodeRange) && count($explodeRange) == 2) {
$ipStart = trim($explodeRange[0]);
$ipEnd = trim($explodeRange[1]);
$validIpRangeStart = preg_match ( $ipAddressRegex, $ipStart );
$validIpRangeEnd = preg_match ( $ipAddressRegex, $ipEnd );
if ($validIpRangeStart && $validIpRangeEnd) {
$lowerIpDec = ( float ) sprintf ( "%u", ip2long ( $ipStart ) );
$upperIpDec = ( float ) sprintf ( "%u", ip2long ( $ipEnd ) );
if (($clientIpDec >= $lowerIpDec) && ($clientIpDec <= $upperIpDec)) {
return false;
}
}
}
}
}
}
}
// Check for hours activation
$startHour = $cParams->get('start_at_hour', null);
$stopHour = $cParams->get('stop_at_hour', null);
if($startHour && $stopHour) {
$jTimeZone = $this->appInstance->getConfig ()->get ( 'offset' );
$dateObject = Factory::getDate();
$dateObject->setTimezone(new \DateTimeZone($jTimeZone));
$currentHour = $dateObject->format('G', true);
if($currentHour < $startHour || $currentHour >= $stopHour) {
return;
}
}
// Check for day of the week activation
$daysOfTheWeek = $cParams->get('days_of_the_week', null);
if(is_array($daysOfTheWeek) && count($daysOfTheWeek) && !in_array('', $daysOfTheWeek, true)) {
$jTimeZone = $this->appInstance->getConfig ()->get ( 'offset' );
$dateObject = Factory::getDate();
$dateObject->setTimezone(new \DateTimeZone($jTimeZone));
$currentDay = $dateObject->format('w', true);
if(!in_array($currentDay, $daysOfTheWeek)) {
return;
}
}
// Ensure that no 'commas' are used for the session_id
if($cParams->get ( 'clean_sessionid', false)) {
$session = $this->appInstance->getSession();
$sessionID = $session->getId();
if(strpos($sessionID, ',') !== false) {
$config = $this->appInstance->getConfig ();
if($config->get ( 'session_handler' ) == 'database') {
try {
// Load and temporary store the current session data
$selectQuery = method_exists ( $this->dbInstance, 'createQuery' ) ? $this->dbInstance->createQuery () : $this->dbInstance->getQuery ( true );
$selectQuery->select('*');
$selectQuery->from($this->dbInstance->quoteName('#__session'));
$selectQuery->where($this->dbInstance->quoteName('session_id') . ' = ' . $this->dbInstance->quote($sessionID));
$sessionObject = $this->dbInstance->setQuery($selectQuery)->loadObject();
// Fork now the session
$session->fork();
// Restore the previous session storage state
$newSessionID = $session->getId();
$insertQuery = method_exists ( $this->dbInstance, 'createQuery' ) ? $this->dbInstance->createQuery () : $this->dbInstance->getQuery ( true );
$insertQuery->insert($this->dbInstance->quoteName('#__session'))->columns($this->dbInstance->quoteName('session_id'))->values($this->dbInstance->quote($newSessionID));
$this->dbInstance->setQuery($insertQuery)->execute();
$updateQuery = method_exists ( $this->dbInstance, 'createQuery' ) ? $this->dbInstance->createQuery () : $this->dbInstance->getQuery ( true );
$updateQuery->update($this->dbInstance->quoteName('#__session'));
$updateQuery->set('client_id = ' . $this->dbInstance->quote($sessionObject->client_id));
$updateQuery->set('guest = ' . $this->dbInstance->quote($sessionObject->guest));
$updateQuery->set('time = ' . time());
$updateQuery->set('data = ' . $this->dbInstance->quote($sessionObject->data));
$updateQuery->set('userid = ' . $this->dbInstance->quote($sessionObject->userid));
$updateQuery->set('username = ' . $this->dbInstance->quote($sessionObject->username));
$updateQuery->where($this->dbInstance->quoteName('session_id') . ' = ' . $this->dbInstance->quote($newSessionID));
$this->dbInstance->setQuery($updateQuery)->execute();
// Delete query
$deleteQuery = method_exists ( $this->dbInstance, 'createQuery' ) ? $this->dbInstance->createQuery () : $this->dbInstance->getQuery ( true );
$deleteQuery->delete($this->dbInstance->quoteName('#__session'));
$deleteQuery->where($this->dbInstance->quoteName('session_id') . ' = ' . $this->dbInstance->quote($sessionID));
$this->dbInstance->setQuery($deleteQuery)->execute();
// Final redirect, if again character match start a loop ending when the session ID is cleaned
$this->appInstance->redirect(Uri::current());
} catch (\Exception $e) {
// No errors managed, leave the process go on anyway
}
}
}
}
//load the translation
require_once JPATH_BASE . '/administrator/components/com_jchat/Framework/Helpers/Language.php';
$base = Uri::base();
// Manage partial language translations
$jLang = $this->appInstance->getLanguage();
$jLang->load('com_jchat', JPATH_SITE . '/components/com_jchat', 'en-GB', true, true);
if($jLang->getTag() != 'en-GB') {
$jLang->load('com_jchat', JPATH_SITE, null, true, false);
$jLang->load('com_jchat', JPATH_SITE . '/components/com_jchat', null, true, false);
}
$chatLanguage = JChatHelpersLanguage::getInstance();
// Inject js translations
$translations = array( 'chat',
'privatechat',
'nousers',
'nousers_filter',
'gooffline',
'available',
'busy',
'statooffline',
'statodonotdisturb',
'reset_chatboxes',
'minimize_chatboxes',
'defaultstatus',
'sent_file',
'received_file',
'sent_file_waiting',
'sent_file_downloaded',
'sent_file_downloaded_realtime',
'sent_file_download',
'error_deleted_file',
'error_notfound_file',
'groupchat_filter',
'addfriend',
'optionsbutton',
'maximizebutton_maximized',
'maximizebutton_minimized',
'closesidebarbutton',
'loginbutton',
'logindesc',
'already_logged',
'spacer',
'scegliemoticons',
'wall_msgs',
'wall_msgs_refresh',
'manage_avatars',
'seconds',
'minutes',
'hours',
'days',
'years',
'groupchat_request_sent',
'groupchat_request_received',
'groupchat_request_accepted',
'groupchat_request_removed',
'groupchat_request_received',
'groupchat_request_accepted_owner',
'groupchat_nousers',
'groupchat_allusers',
'audio_onoff',
'public_audio_onoff',
'vibrate_onoff',
'notification_onoff',
'wall_notification',
'privatemsg_notification',
'sentfile_notification',
'trigger_emoticon',
'trigger_fileupload',
'trigger_export',
'trigger_delete',
'trigger_refresh',
'trigger_skypesave',
'trigger_skypedelete',
'trigger_infoguest',
'trigger_room',
'trigger_history',
'trigger_history_wall',
'trigger_webrtc',
'trigger_webrtc_ringing',
'trigger_send',
'trigger_geolocation',
'trigger_blackboard',
'search',
'invite',
'pending',
'remove',
'userprofile_link',
'you',
'me',
'seen',
'banning',
'banneduser',
'ban_moderator',
'startskypecall',
'startskypedownload',
'insert_skypeid',
'skypeidsaved',
'skypeid_deleted',
'roomname',
'roomcount',
'available_rooms',
'chatroom_users',
'chatroom_join',
'chatroom_joined',
'users_inchatroom',
'noavailable_rooms',
'chatroom',
'addnew_chatroom',
'chatroomform_name',
'chatroomform_description',
'chatroomform_accesslevel',
'chatroomform_submit',
'success_storing_chatroom',
'success_deleting_chatroom',
'insert_override_name',
'trigger_override_name',
'override_name_saved',
'override_name_deleted',
'select_period',
'nomessages_available',
'period_1d',
'period_1w',
'period_1m',
'period_3m',
'period_6m',
'period_1y',
'skype',
'newmessage_tab',
'start_call',
'accept_call',
'decline_call',
'end_call',
'call_starting',
'call_started',
'call_disconnected',
'incoming_started',
'connecting',
'missing_local_stream',
'closing_connection',
'connection_closed',
'connection_active',
'error_creating_connection',
'session_error',
'connection_close_error',
'connection_failed',
'webrtc_videochat',
'webcam',
'webcam_quality',
'webrtc_bandwidth',
'webrtc_recorder_local',
'webrtc_recorder_remote',
'webrtc_recorder_both',
'mediastream_error',
'requires_https',
'noanswer',
'webrtc_nosupport',
'chrome_webrtc_support',
'firefox_webrtc_support',
'opera_webrtc_support',
'ie_webrtc_support',
'safari_webrtc_support',
'webrtc_caniuse',
'nowebcam_detected',
'grant_cam_access',
'quality_cam',
'onoffswitch',
'endcall_before_close',
'endcall_totoggle_popups',
'hardware_unavailable',
'webrtc_notification_ringing',
'newvideocall_tab',
'fallback_suggestion',
'expired_msg',
'lamform_name',
'lamform_email',
'lamform_phonenumber',
'lamform_message',
'lamform_submit',
'lamform_required',
'success_send_lamessage',
'error_send_lamessage',
'sendus_aticket',
'select_user_receiver',
'trigger_messaging_emoticon',
'trigger_messaging_fileupload',
'trigger_messaging_export',
'trigger_messaging_delete',
'trigger_messaging_openbox',
'trigger_conference_fileupload',
'trigger_localvideo_toggle',
'remote_pin_video',
'open_privatemess',
'agentbox_defaultmessage',
'source_language',
'target_language',
'lang_switcher',
'translate_arrow',
'start_accept_call',
'end_decline_call',
'start_recording',
'stop_recording',
'pause_recording',
'view_recording',
'download_recording',
'upload_recording',
'send_recording',
'upload_complete',
'upload_error',
'start_sharing',
'end_sharing',
'accept_sharing',
'decline_sharing',
'blackboard',
'local_blackboard',
'remote_blackboard',
'blackboard_request',
'trigger_blackboard_ringing',
'blackboard_not_supported',
'webrtc_blackboard_nosupport',
'chrome_webrtc_blackboard_support',
'firefox_webrtc_blackboard_support',
'opera_webrtc_blackboard_support',
'session_started',
'session_starting',
'missing_local_blackboard_stream',
'blackboard_noanswer',
'blackboard_image_upload',
'blackboard_screen_share',
'blackboard_screen_end',
'toggle_sharing',
'chatroom_menuitems',
'privacy_policy_label',
'predefined_answers',
'recaptcha_label',
'delete_message_confirmation',
'delete_message_second_confirmation',
'delete_message_yes',
'delete_message_no',
'whatsapp_forward',
'copy_addon',
'copy_addon_success'
);
$chatLanguage->injectJsTranslations($translations, $doc);
// Output JS APP nel Document
$defaultWidth = '';
$baseTemplate = $cParams->get('chat_template', 'default.css');
switch ($baseTemplate) {
case 'custom.css':
$template = $this->appInstance->getTemplate(true);
$templateName = $template->template;
if(file_exists(JPATH_ROOT . '/media/templates/site/' . $templateName . '/css/com_jchat/css/templates/default.css')) {
$doc->getWebAssetManager()->registerAndUseStyle ( 'jchat.defaultcss', 'media/templates/site/' . $templateName . '/css/com_jchat/css/templates/default.css');
} elseif(file_exists(JPATH_ROOT . '/templates/' . $templateName . '/css/com_jchat/css/templates/default.css')) {
$doc->getWebAssetManager()->registerAndUseStyle ( 'jchat.defaultcss', 'templates/' . $templateName . '/css/com_jchat/css/templates/default.css');
}
break;
case 'livesupportchatbot.css':
$doc->getWebAssetManager()->registerAndUseStyle ( 'jchat.defaultcss', 'components/com_jchat/css/templates/default.css');
$myAvatarImage = $cParams->get('chatbot_avatar', null);
if($myAvatarImage) {
$myAvatarImage = Uri::root() . $myAvatarImage;
$doc->getWebAssetManager()->addInlineStyle("#jchat_userstab_popup div.jchat_userstabtitle:after{background-image: url('$myAvatarImage')}");
}
if($cParams->get('rendering_mode', 'auto') == 'auto') {
$defaultWidth = '340';
}
break;
case 'livesupport.css':
$doc->getWebAssetManager()->registerAndUseStyle ( 'jchat.defaultcss', 'components/com_jchat/css/templates/default.css');
if($cParams->get('rendering_mode', 'auto') == 'auto') {
$defaultWidth = '340';
}
break;
case 'mobile.css':
case 'animated.css':
$doc->getWebAssetManager()->registerAndUseStyle ( 'jchat.defaultcss', 'components/com_jchat/css/templates/default.css');
$doc->getWebAssetManager()->registerAndUseStyle ( 'jchat.font-awesome', 'components/com_jchat/css/font-awesome.min.css');
break;
case 'default.css':
default:
$doc->getWebAssetManager()->registerAndUseStyle ( 'jchat.defaultcss', 'components/com_jchat/css/templates/default.css');
break;
}
$directTemplates = array('default.css', 'custom.css');
if(!in_array($baseTemplate, $directTemplates)) {
$doc->getWebAssetManager()->registerAndUseStyle ( 'jchat.templatecss', 'components/com_jchat/css/templates/' . $baseTemplate, [], [], ['jchat.defaultcss']);
}
// Scripts loading
$defer = $cParams->get('scripts_loading', null) == 'defer' ? true : false;
$async = $cParams->get('scripts_loading', null) == 'async' ? true : false;
if($cParams->get('includejquery', 1)) {
$doc->getWebAssetManager()->useScript('jquery');
}
if($cParams->get('noconflict', 0)) {
$doc->getWebAssetManager()->useScript('jquery-noconflict');
}
$doc->getWebAssetManager()->addInlineScript("var jchat_livesite='$base';" .
"var jchat_excludeonmobile=" . $cParams->get('exclude_onmobile', 0) . ";" .
"var jchat_guestenabled='" . $cParams->get('guestenabled', 1) . "';" .
"var jchat_userid='" . $user->id . "';" .
"var jchat_usersessionid='" . session_id() . "';" .
"var jchat_notifications_time='" . $cParams->get('notifications_time', 10) . "';" .
"var jchat_notifications_public_time='" . $cParams->get('notifications_public_time', 5) . "';" .
"var jchat_wall_sendbutton=" . $cParams->get('show_send_button', 2) . ";" .
"var jchat_sidebar_default_width_override='" . $cParams->get('sidebar_default_width_override', $defaultWidth) . "';" .
"var jchat_privatemess_uri='" . @Route::_('index.php?option=com_jchat&view=messaging') . "';" .
"var jchat_privacy_policy=" . $cParams->get('privacy_policy', 0) . ";" .
"var jchat_privacy_policy_link='" . Text::_($cParams->get('privacy_policy_link', 'javascript:void(0)'), true) . "';" .
"var jchat_tickets_form_include_recaptcha=" . $cParams->get('tickets_form_include_recaptcha', 0) . ";" .
"var jchat_tickets_form_include_phonenumber=" . $cParams->get('tickets_form_include_phonenumber', 0) . ";" .
"var jchat_manage_unstable_network=" . $cParams->get('manage_unstable_network', 0) . ";" .
"var jchat_download_msgs_multitabs_mode=" . $cParams->get('download_msgs_multitabs_mode', 0) . ";" .
"var jchat_messenger_sounds_variation='" . $cParams->get('messenger_sounds_variation', 'variation1') . "';" .
"var jchat_messenger_typing_sound=" . $cParams->get('messenger_typing_sound', 1) . ";");
// Manage by plugin append the chat target element based on rendering mode and related overridden styles
$renderingMode = $cParams->get('rendering_mode', 'auto');
$targetElement = $renderingMode == 'auto' ? 'body' : '#jchat_target';
$offlineMessage = str_replace(array( "\n", "\r", "\t", PHP_EOL), ' ', Text::_($cParams->get('offline_message', Text::_('COM_JCHAT_DEFAULT_OFFLINE_MESSAGE')), true));
$doc->getWebAssetManager()->addInlineScript("var jchatTargetElement='$targetElement';" .
"var jchatOfflineMessage='$offlineMessage';" );
// Load and inject emoticons into the JS domain
$query = method_exists ( $this->dbInstance, 'createQuery' ) ? $this->dbInstance->createQuery () : $this->dbInstance->getQuery ( true );
$query->select($this->dbInstance->quoteName('linkurl') . ' AS ' . $this->dbInstance->quoteName('path') . ',' . $this->dbInstance->quoteName('keycode'));
$query->from($this->dbInstance->quoteName('#__jchat_emoticons'));
$query->where($this->dbInstance->quoteName('published') . '=1');
$query->order($this->dbInstance->quoteName('ordering') . 'ASC');
$emoticons = $this->dbInstance->setQuery($query)->loadObjectList();
$doc->getWebAssetManager()->addInlineScript("window.jchat_emoticons=" . json_encode($emoticons) . ";");
// Add styles for module displacement
if($renderingMode == 'module') {
$doc->getWebAssetManager()->addInlineStyle('
#jchat_base, #jchat_wall_popup, #jchat_userstab_popup {
position: relative;
}
#jchat_base, #jchat_wall_popup, #jchat_userstab_popup {
width: ' . ($cParams->get('sidebar_width', 250)) . 'px;
}
#jchat_userstab, #jchat_userstab.jchat_userstabclick {
width: ' . ($cParams->get('sidebar_width', 250) - 2) . 'px;
}
#jchat_target {
width: ' . $cParams->get('sidebar_width', 250) . 'px;
height: ' . $cParams->get('sidebar_height', 600) . 'px;
}
#jchat_users_search {
width: ' . $cParams->get('search_width', 100) . 'px;
}
#jchat_roomstooltip {
width: ' . $cParams->get('chatroom_width', 400) . 'px;
}
#jchat_roomsdragger {
width: ' . (int)($cParams->get('chatroom_width', 400) + 2) . 'px;
}
#jchat_users_search {
padding: 2px 6px 0 16px;
}
#jchat_wall_popup.jchat_wall_minimized {
top: 0;
}
');
}
if($fontsizeOverride = $cParams->get('fontsize_override', null)) {
$doc->getWebAssetManager()->addInlineStyle("div.jchat_chatboxmessage,
div.jchat_textarea{font-size:$fontsizeOverride}");
}
if($fontsizeTitlesOverride = $cParams->get('fontsize_titles_override', null)) {
$doc->getWebAssetManager()->addInlineStyle("span.jchat_publicchattitle,
span.jchat_privatechattitle,
#jchat_userstab:not(.jchat_tabclick) #jchat_userstab_text,
span.jchat_lamform_title{font-size:$fontsizeTitlesOverride}");
if((int)$fontsizeTitlesOverride >= 17 && $cParams->get('chat_template', 'default.css') != 'alternative.css') {
$doc->getWebAssetManager()->addInlineStyle("#jchat_userstab:not(.jchat_tabclick) #jchat_userstab_text{margin-top:0}");
}
$doc->getWebAssetManager()->addInlineStyle("div.jchat_userlist span.jchat_userscontentname{font-size:" . ((int)$fontsizeTitlesOverride - 1) . "px}");
}
if(!$cParams->get('show_users_count', 1)) {
$doc->getWebAssetManager()->addInlineStyle("span.jchat_userscount{display:none}");
}
if($cParams->get('messages_deletion', 0)) {
$doc->getWebAssetManager()->addInlineStyle("div.jchat_tabpopup div.jchat_chatboxmessage span.jchat_chatboxmessagecontent.selfmessage{max-width:65%}#jchat_private_messaging div.jchat_chatboxmessageinfo span.jchat_chatboxmessagecontent.selfmessage{max-width:85%}");
}
$renderRoundedBaloon = $cParams->get('render_rounded_baloon', 1);
if($renderRoundedBaloon || $baseTemplate == 'animated.css') {
$marginLeftRoundedBaloon = '';
$bottomRoundedOffset = "-80px";
switch ($baseTemplate) {
case 'mobile.css':
$marginLeftRoundedBaloon = '#jchat_userstab:not(.jchat_userstabclick) #jchat_userstab_icon{margin-left:12px}#jchat_userstab:not(.jchat_userstabclick) #jchat_userstab_text{margin-top:10px;margin-left:10px}';
$paddingRoundedBaloon = 'padding: 15px 0 !important';
break;
case 'animated.css':
$pathToCustomLiveSupportIcon = $cParams->get('chatbot_avatar', null);
$chatbotTopInnerIconImage = $cParams->get('chatbot_top_inner_icon_image', null);
$pathToLiveSupportIcon = $pathToCustomLiveSupportIcon ? Uri::root() . $pathToCustomLiveSupportIcon : Uri::root() . 'components/com_jchat/images/default/chatbot.svg';
if($cParams->get('chatbot_top_inner_icon', 1)) {
$pathToLiveSupportInnerIcon = $chatbotTopInnerIconImage ? Uri::root() . $chatbotTopInnerIconImage : Uri::root() . 'components/com_jchat/images/default/chatbot.png';
} else {
$pathToLiveSupportInnerIcon = Uri::root() . 'components/com_jchat/images/default/blank.gif';
}
$backgroundCustomSize = $pathToCustomLiveSupportIcon ? 'background-size: 100px 100px' : 'background-size: 50% 50%';
$marginLeftRoundedBaloon = '#jchat_userstab_popup .jchat_userstabtitle{background: #FFF url("' . $pathToLiveSupportInnerIcon . '") no-repeat !important;background-position: right 10px top 42px !important;background-size: auto 50% !important}#jchat_userstab.jchat_tab:not(.jchat_tabclick){background: url("' . $pathToLiveSupportIcon . '") no-repeat #fff;background-position: center center !important;' . $backgroundCustomSize . '}#jchat_userstab.jchat_tab:not(.jchat_tabclick) *{display:none}#jchat_userstab:not(.jchat_userstabclick) #jchat_userstab_icon{margin-left:12px}#jchat_userstab:not(.jchat_userstabclick) #jchat_userstab_text{margin-top:10px;margin-left:10px}';
$paddingRoundedBaloon = 'padding: 15px 0 !important';
$bottomRoundedOffset = "-60px";
break;
case 'alternative.css':
$marginLeftRoundedBaloon = '#jchat_userstab:not(.jchat_userstabclick) #jchat_userstab_icon{margin-left:4px;padding-right:2px}';
$paddingRoundedBaloon = 'padding: 35px 0 !important';
break;
case 'livesupportchatbot.css':
$pathToCustomLiveSupportIcon = $cParams->get('chatbot_avatar', null);
$pathToLiveSupportIcon = $pathToCustomLiveSupportIcon ? Uri::root() . $pathToCustomLiveSupportIcon : Uri::root() . 'components/com_jchat/images/default/livesupport_placeholder_white.png';
$backgroundCustomSize = $pathToCustomLiveSupportIcon ? 'background-size: 100px 100px' : '';
$marginLeftRoundedBaloon = '#jchat_userstab.jchat_tab:not(.jchat_tabclick){background: url("' . $pathToLiveSupportIcon . '") no-repeat #fff;background-position: center center !important;' . $backgroundCustomSize . '}#jchat_userstab.jchat_tab:not(.jchat_tabclick) *{display:none}';
$paddingRoundedBaloon = 'padding: 35px 0 !important';
break;
default:
$marginLeftRoundedBaloon = '#jchat_userstab:not(.jchat_userstabclick) #jchat_userstab_icon{margin-left:4px;padding-right:2px}';
$paddingRoundedBaloon = 'padding: 35px 0 !important';
break;
}
if($renderRoundedBaloon) {
$doc->getWebAssetManager()->addInlineStyle("#jchat_userstab:not(.jchat_userstabclick){box-sizing:border-box;width:100px !important;height:100px !important;border-radius:50px !important;margin-top:$bottomRoundedOffset !important;margin-right:20px;$paddingRoundedBaloon}$marginLeftRoundedBaloon");
} else {
$doc->getWebAssetManager()->addInlineStyle('#jchat_userstab_popup .jchat_userstabtitle{background: #FFF url("' . $pathToLiveSupportInnerIcon . '") no-repeat !important;background-position: right 10px top 42px !important;background-size: auto 50% !important}');
}
}
// Add override color styles
if($colorOverride = $cParams->get('chat_color_override', null)) {
$doc->getWebAssetManager()->addInlineStyle("#jchat_userstab.jchat_tab,
div.jchat_userstabtitle,
#jchat_roomsdragger.jchat_tab,
div#jchat_select_period,
div.jchat_tooltip_header,
div.jchat_roomstooltip div.jchat_roomright .jchat_roomjoin,
div.jchat_userstabsubtitle,
#jchat_confirm_delete,
#jchat_confirm_message_delete,
.jchat_chatboxmessage.selfmessage #jchat_confirm_message_delete,
div.jchat_infoguest_title{background:$colorOverride!important;background-color:$colorOverride}
div.jchat_single_period,
div.jchat_tabpopup div[class^=jchat_trigger_].toggle_on,
div.jchat_blackboardtooltip label.image_uploader,
div[class^=jchat_trigger].jchat_trigger_conference_fileupload.toggle_on,
#activation_form input.jchat_button,
input.jchat_button_exit_chat,
#jchat_private_messaging div[class^=jchat_trigger_].toggle_on{background-color:$colorOverride!important}
div.jchat_tabpopup span.jchat_tab{background:$colorOverride url('" . Uri::root() . "components/com_jchat/images/default/jchat.png') no-repeat top left;background-position: -20px}
div.jchat_tabpopup span.jchat_tab,
#jchat_roomstooltip,
#jchat_confirm_delete,
#jchat_select_period,
#chatroom_adder,
div.jchat_emoticonstooltip div.jchat_tooltip_content,
div.jchat_fileuploadtooltip iframe,
div.jchat_messaging_fileuploadtooltip iframe,
div.jchat_historytooltip,
div.jchat_webrtctooltip,
div.jchat_messaging_delete_conversation_tooltip,
div.jchat_userslist_ctrls div.jchat_userslist_reply,
div.jchat_tooltip_header,
div.jchat_infoguesttooltip,
div.jchat_geolocationtooltip,
#jchat_confirm_message_delete,
div.jchat_delete_message_tooltip,
div.jchat_emoticonstooltip,
div.jchat_blackboardtooltip,
div.jchat_chatroom_usersinfo_tooltip,
div.jchat_conference_fileuploadtooltip iframe,
div.jchat_messaging_emoticonstooltip{border-color:$colorOverride!important}");
if(in_array($baseTemplate, array('mobile.css','animated.css'))) {
$doc->getWebAssetManager()->addInlineStyle("#jchat_loginbutton{background:$colorOverride!important}
div.jchat_tabcontent.messagelist > div[class^=jchat_trigger],div.jchat_userslist_ctrls div[class^=jchat_trigger],div.jchat_closebox_bottom,div.jchat_closebox_bottom::before,div.jchat_tooltip_avatar_upload_header::before,.jchat_tooltip_chatroom_adder_header::before{border-color:$colorOverride!important;color:$colorOverride!important}
.jchat_chatboxmessage.selfmessage span.jchat_messagesdeletion g {fill: $colorOverride}
.jchat_chatboxmessage.selfmessage span.jchat_messagesdeletion {border-color: $colorOverride}
div.jchat_tabcontentinput::before,
#jchat_privatemessaging_textarea::before {
mask: url('" . Uri::root() . "components/com_jchat/images/default/chatsend.svg') no-repeat;
-webkit-mask: url('" . Uri::root() . "components/com_jchat/images/default/chatsend.svg') no-repeat;
background: $colorOverride !important;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}");
if($baseTemplate == 'animated.css' && $renderRoundedBaloon) {
$pathToCustomLiveSupportIcon = $cParams->get('chatbot_avatar', null);
$pathToLiveSupportIcon = $pathToCustomLiveSupportIcon ? Uri::root() . $pathToCustomLiveSupportIcon : Uri::root() . 'components/com_jchat/images/default/chatbot.svg';
$backgroundCustomSize = $pathToCustomLiveSupportIcon ? '100px 100px' : '50% 50%';
$doc->getWebAssetManager()->addInlineStyle("#jchat_userstab.jchat_tab:not(.jchat_tabclick){background: url('" . $pathToLiveSupportIcon . "') center center/" . $backgroundCustomSize . " no-repeat $colorOverride !important}");
}
}
}
// Submit button color override
if($submitButtonColorOverride = $cParams->get('submitlamform_color_override', null)) {
$pathImages = Uri::root(true) . '/components/com_jchat/images/default/icon_ticket.png';
$doc->getWebAssetManager()->addInlineStyle("div.jchat_submit_lam_form {border-color:$submitButtonColorOverride;background:$submitButtonColorOverride url($pathImages) no-repeat 6px 3px}
div.jchat_submit_chatroom_form {border-color:$submitButtonColorOverride;background:$submitButtonColorOverride}");
}
// Tooltip border color override
if($tooltipBorderColorOverride = $cParams->get('tooltip_bordercolor_override', null)) {
$doc->getWebAssetManager()->addInlineStyle("#jchat_default_suggestion_tooltip div.jchat_tooltip_content {border-color: $tooltipBorderColorOverride}" .
"#jchat_default_suggestion_tooltip:not(.jchat_arm)::before {background-color: $tooltipBorderColorOverride}");
}
// Tooltip custom background image
if($cParams->get('chat_template_tooltip', 'std') == 'custom' && $chatTemplateTooltipImage = $cParams->get('chat_template_tooltip_image', null)) {
$doc->getWebAssetManager()->addInlineStyle("#jchat_default_suggestion_tooltip::before {background: url('" . Uri::root() . $chatTemplateTooltipImage . "') no-repeat;content: '';border-radius: 10px;position: absolute;bottom: -31px;right: 20px;width: 150px;height: 200px;border: none;box-shadow: none;cursor: pointer;z-index: 1;}#jchat_default_suggestion_tooltip .jchat_tooltip_content {display:none}#jchat_tooltip_close{margin-right:0}");
}
// Tooltip background color override
if($tooltipBckcolorOverride = $cParams->get('tooltip_bckcolor_override', null)) {
$doc->getWebAssetManager()->addInlineStyle("#jchat_default_suggestion_tooltip div.jchat_tooltip_content {background-color: $tooltipBckcolorOverride !important}");
}
// Videochat custom background image
if($videochatBackgroundImageOverride = $cParams->get('videochat_background_image_override', null)) {
$doc->getWebAssetManager()->addInlineStyle("#jchat_localvideo_placeholder, #jchat_remotevideo_placeholder {background: url('" . Uri::root() . $videochatBackgroundImageOverride . "') center no-repeat;}");
}
// Add override height
if($cParams->get('public_chat_height_override', null)) {
$publicChatHeightOverride = (int)trim($cParams->get('public_chat_height_override'), '%');
$doc->getWebAssetManager()->addInlineStyle("#jchat_wall_popup{height:$publicChatHeightOverride%}");
}
if($cParams->get('private_chat_height_override', null)) {
$privateChatHeightOverride = (int)trim($cParams->get('private_chat_height_override'), '%');
$doc->getWebAssetManager()->addInlineStyle("#jchat_userstab_popup.jchat_tabopen{height:$privateChatHeightOverride%}" .
"#jchat_wall_popup.jchat_wall_minimized{bottom:$privateChatHeightOverride%}");
}
// Add override top margin for public chat
if($cParams->get('public_chat_top_override', null)) {
$publicChatTopOverride = trim($cParams->get('public_chat_top_override'));
if(stripos($publicChatTopOverride, 'px') === false && stripos($publicChatTopOverride, '%') === false) {
$publicChatTopOverride .= 'px';
}
$doc->getWebAssetManager()->addInlineStyle("#jchat_wall_popup:not(.maximized):not(.jchat_wall_minimized ){top:$publicChatTopOverride}");
}
// Disable emoticons if needed
if(!$cParams->get('emoticons_enabled', 1)) {
$doc->getWebAssetManager()->addInlineStyle("*.jchat_trigger_emoticon,*.jchat_trigger_messaging_emoticon{display:none;}");
}
// Override emoticons width
if($cParams->get('emoticons_original_size', 0)) {
$doc->getWebAssetManager()->addInlineStyle("div.jchat_tabcontenttext span.jchat_chatboxmessagecontent img.jchat_emoticons," .
" #jchat_usersmessages span.jchat_chatboxmessagecontent img.jchat_emoticons{max-width:inherit!important;max-height:inherit!important;}" .
" span.jchat_chatboxmessagecontent{min-width:26px;}");
}
// Custom videoconference chat overrides
if($option == 'com_jchat' && ($viewName == 'conference' || $viewName == 'livestreaming')) {
$videoconferenceLocalvideoMaxwidth = trim($cParams->get('videoconference_localvideo_maxwidth', '300px'));
if(stripos($videoconferenceLocalvideoMaxwidth, 'px') === false && stripos($videoconferenceLocalvideoMaxwidth, '%') === false) {
$videoconferenceLocalvideoMaxwidth .= 'px';
}
$videoconferencePinnedvideoMaxwidth = trim($cParams->get('videoconference_pinnedvideo_maxwidth', '260px'));
if(stripos($videoconferencePinnedvideoMaxwidth, 'px') === false && stripos($videoconferencePinnedvideoMaxwidth, '%') === false) {
$videoconferencePinnedvideoMaxwidth .= 'px';
}
$videoconferenceRemotevideoMaxwidth = trim($cParams->get('videoconference_remotevideo_maxwidth', '200px'));
if(stripos($videoconferenceRemotevideoMaxwidth, 'px') === false && stripos($videoconferenceRemotevideoMaxwidth, '%') === false) {
$videoconferenceRemotevideoMaxwidth .= 'px';
}
$doc->getWebAssetManager()->addInlineStyle("#jchat_wrapper_localvideo{max-width:$videoconferenceLocalvideoMaxwidth}div.jchat_wrapper_remotevideo.jchat_conference_pinnedvideo{max-width:$videoconferencePinnedvideoMaxwidth}div.jchat_wrapper_remotevideo:not(.jchat_conference_pinnedvideo){max-width:$videoconferenceRemotevideoMaxwidth}");
if($customConferencebackground = $this->appInstance->getParams('com_jchat')->get('conference_custom_color', '')) {
$doc->getWebAssetManager()->addInlineStyle("#jchat_conference_container,#jchat_left_userscolumn,#jchat_right_userscolumn,#jchat_conference_container #jchat_conference_userslist li:hover,div.jchat_conference_container_blacktheme #mic_vumeter{background-color:$customConferencebackground !important}");
}
}
// Add custom styles if any
if($customCssStyles = trim($cParams->get('custom_css_styles', ''))) {
$doc->getWebAssetManager()->addInlineStyle($customCssStyles);
}
$wa = $doc->getWebAssetManager();
$wa->registerAndUseScript ( 'jchat.utility', 'components/com_jchat/js/utility.js', [], ['defer'=>$defer, 'async'=>$async], ['jquery']);
$wa->registerAndUseScript ( 'jchat.jstorage', 'components/com_jchat/js/jstorage.min.js', [], ['defer'=>$defer, 'async'=>$async], ['jquery']);
$wa->registerAndUseScript ( 'jchat.soundmanager', 'components/com_jchat/sounds/soundmanager2.js', [], ['defer'=>$defer, 'async'=>$async]);
$wa->registerAndUseScript ( 'jchat.notifications', 'components/com_jchat/js/notifications.js', [], ['defer'=>$defer, 'async'=>$async], ['jquery', 'jchat.soundmanager']);
if($option == 'com_jchat' && $viewName == 'conference') {} else {
$wa->registerAndUseScript ( 'jchat.webrtc', 'components/com_jchat/js/webrtc.js', [], ['defer'=>$defer, 'async'=>$async], ['jquery']);
}
if($cParams->get('enable_recording', 0) && $viewName != 'livestreaming') {
$doc->getWebAssetManager()->addInlineScript("var jchat_recorder_max_videos_per_row=" . $cParams->get('recorder_max_videos_per_row', 4) . ";" .
"var jchat_recorder_video_width=" . $cParams->get('recorder_video_width', 640) . ";" .
"var jchat_recorder_video_height=" . $cParams->get('recorder_video_height', 480) . ";" .
"var jchat_recorder_video_miniature_width=" . $cParams->get('recorder_video_miniature_width', 160) . ";");
$wa->registerAndUseScript ( 'jchat.merger', 'components/com_jchat/js/merger.js', [], ['defer'=>$defer, 'async'=>$async], ['jquery']);
$wa->registerAndUseScript ( 'jchat.recorder', 'components/com_jchat/js/recorder.js', [], ['defer'=>$defer, 'async'=>$async], ['jquery']);
}
if($cParams->get('enable_blackboard', 0)) {
$wa->registerAndUseScript ( 'jchat.blackboard', 'components/com_jchat/js/blackboard.js', [], ['defer'=>$defer, 'async'=>$async], ['jquery']);
}
$wa->registerAndUseScript ( 'jchat.emoticons', 'components/com_jchat/js/emoticons.js', [], ['defer'=>$defer, 'async'=>$async], ['jquery']);
$wa->registerAndUseScript ( 'jchat.main', 'components/com_jchat/js/main.js', [], ['defer'=>$defer, 'async'=>$async], ['jquery', 'jchat.utility', 'jchat.jstorage', 'jchat.soundmanager', 'jchat.notifications', 'jchat.emoticons']);
// Check for Geolocation feature and related scripts
if($cParams->get('geolocation_enabled', 0)) {
$wa->addInlineScript("var initJChatMap=function(){return true};");
$wa->registerAndUseScript ( 'jchat.maps.google', 'https://maps.googleapis.com/maps/api/js?key=AIzaSyB1vhO4GX3yOqbVvv6S8e4PLRyGYI9Ldz0&callback=initJChatMap', [], ['defer'=>true]);
$wa->registerAndUseScript ( 'jchat.gmap', 'components/com_jchat/js/gmap.js', [], ['defer'=>true], ['jquery']);
}
// Kill CSP headers
$facebookLogin = $this->componentConfig->get('fblogin_active', 0);
$googleLogin = $this->componentConfig->get('gpluslogin_active', 0);
$twitterLogin = $this->componentConfig->get('twitterlogin_active', 0);
if($facebookLogin || $googleLogin || $twitterLogin) {
// Kill CSP headers
$httpHeadersPlugin = PluginHelper::getPlugin('system', 'httpheaders');
if(is_object($httpHeadersPlugin)) {
$httpHeadersPluginParams = new Registry($httpHeadersPlugin->params);
if($httpHeadersPluginParams->get('contentsecuritypolicy', 0) && $this->componentConfig->get('auto_manage_csp', 1)) {
$this->appInstance->setHeader('content-security-policy', null, true);
$this->appInstance->setHeader('content-security-policy-report-only', null, true);
}
}
}
// Remove expired sessions from the database.
if($cParams->get('force_joomla_session_cleanup', 0)) {
$config = $this->appInstance->getConfig ();
if($config->get ( 'session_handler' ) == 'database') {
try {
$time = time();
$session = $this->appInstance->getSession();
$sessionLifetime = $session->getExpire();
if ($time % 2) {
// The modulus introduces a little entropy, making the flushing less accurate but fires the query less than half the time.
$query = method_exists ( $this->dbInstance, 'createQuery' ) ? $this->dbInstance->createQuery () : $this->dbInstance->getQuery ( true );
$query->delete($this->dbInstance->quoteName('#__session'))
->where($this->dbInstance->quoteName('time') . ' < ' . $this->dbInstance->quote((int) ($time - $sessionLifetime)));
$this->dbInstance->setQuery($query);
$this->dbInstance->execute();
}
} catch (\Exception $e) {
// No errors managed, leave the process go on anyway
}
}
}
}
/**
* onBeforeCompileHead handler
*
* @param Event $event
* @access public
* @return null
*/
public function injectAppBeforeCompileHead(Event $event) {
$component = ComponentHelper::getComponent('com_jchat');
$cParams = $component->params;
if($this->appInstance->isClient ('site') && $cParams->get('jchat_include_event', 'afterdispatch') == 'beforecompilehead') {
$this->injectApp($cParams);
}
}
/**
* onAfterDispatch handler
*
* @param Event $event
* @access public
* @return null
*/
public function injectAppAfterDispatch(Event $event) {
// Redirect to the component configuration if the Joomla global configuration is requested instead
if($this->appInstance->isClient('administrator')) {
$dispatchedComponent = $this->appInstance->getInput()->get ( 'option' );
$dispatchedView = $this->appInstance->getInput()->get ( 'view' );
$componentConfig = $this->appInstance->getInput()->get ( 'component' );
if($dispatchedComponent == 'com_config' && $dispatchedView == 'component' && $componentConfig == 'com_jchat') {
$this->appInstance->redirect(Route::_('index.php?option=com_jchat&task=config.display', false));
return;
}
}
$component = ComponentHelper::getComponent('com_jchat');
$cParams = $component->params;
if($this->appInstance->isClient ('site') && $cParams->get('jchat_include_event', 'afterdispatch') == 'afterdispatch') {
$this->injectApp($cParams);
}
// Refresh always the session start time on Joomla 4
if($this->appInstance->isClient ('site')) {
$session = $this->appInstance->getSession();
$session->set('session.timer.start', time());
}
}
/** Manage the Joomla session metadata in all cases even if disabled by the global configuration
*
* @param Event $event
* @access public
* @return void
*/
public function manageSessionMetadata(Event $event) {
// Check if the plugin has not been stopped by the constructor
if($this->isPluginStopped) {
$dispatcher = $this->appInstance->getDispatcher();
$dispatcher->removeSubscriber($this);
return;
}
// Always force session metadata tracking
if(!$this->appInstance->getConfig ()->get ( 'session_metadata', 1 ) || !$this->appInstance->getConfig ()->get ( 'session_metadata_for_guest', 0 )) {
$container = Factory::getContainer();
$session = $this->appInstance->getSession();
$user = $this->appInstance->getIdentity();
if ($user) {
$container->get(\Joomla\CMS\Session\MetadataManager::class)->createOrUpdateRecord($session, $user);
}
}
}
/**
* Event to manipulate the menu item dashboard in backend
*
* @param Event $event
* @subparam array &$policy The privacy policy status data, passed by reference, with keys "published" and "editLink"
*
* @return void
*/
public function processMenuItemsDashboard(Event $event) {
// subparams: $context, $items
$arguments = $event->getArguments();
$context = isset($arguments[0]) ? $event->getArgument(0) : $event->getArgument('context');
$items = isset($arguments[1]) ? $event->getArgument(1) : $event->getArgument('subject');
if(!empty($items) && $context == 'administrator.module.mod_submenu') {
foreach ($items as $item) {
if($item->element == 'com_jchat') {
$item->img = Uri::base() . 'components/com_jchat/images/jchat-16x16.png';
$item->title = 'COM_JCHAT_DASHBOARD_TITLE';
}
}
}
// Kill com_joomlaupdate informations about extensions missing updater info, leave only main one
$document = $this->appInstance->getDocument();
if(!$this->appInstance->get('jextstore_joomlaupdate_script') && $this->appInstance->getInput()->get('option') == 'com_joomlaupdate' && !$this->appInstance->getInput()->get('view') && !$this->appInstance->getInput()->get('task')) {
$document->getWebAssetManager()->addInlineScript ("
window.addEventListener('DOMContentLoaded', function(e) {
if(document.querySelector('#preupdatecheck')) {
var jextensionsIntervalCount = 0;
var jextensionsIntervalTimer = setInterval(function() {
[].slice.call(document.querySelectorAll('#compatibilityTable1 tbody tr th.exname')).forEach(function(th) {
let txt = th.innerText;
if (txt && txt.toLowerCase().match(/jsitemap|gdpr|gptranslate|jpagebuilder|responsivizer|jchatsocial|jcomment|jshortcodes|jrealtime|jspeed|jredirects|vsutility|visualstyles|visual\sstyles|instant\sfacebook\slogin|instantpaypal|screen\sreader|jspeed|jamp/i)) {
th.parentElement.style.display = 'none';
th.parentElement.classList.remove('error');
th.parentElement.classList.add('jextcompatible');
}
});
[].slice.call(document.querySelectorAll('#compatibilityTable2 tbody tr th.exname')).forEach(function(th) {
let txt = th.innerText;
if (txt && txt.toLowerCase().match(/jsitemap|gdpr|gptranslate|jpagebuilder|responsivizer|jchatsocial|jcomment|jshortcodes|jrealtime|jspeed|jredirects|vsutility|visualstyles|visual\sstyles|instant\sfacebook\slogin|instantpaypal|screen\sreader|jspeed|jamp/i)) {
th.parentElement.classList.remove('error');
th.parentElement.classList.add('jextcompatible');
let smallDiv = th.querySelector(':scope div.small');
if(smallDiv) {
smallDiv.style.display = 'none';
}
}
});
if (document.querySelectorAll('#compatibilityTable0 tbody tr').length == 0 &&
document.querySelectorAll('#compatibilityTable1 tbody tr:not(.jextcompatible)').length == 0 &&
document.querySelectorAll('#compatibilityTable2 tbody tr:not(.jextcompatible)').length == 0) {
[].slice.call(document.querySelectorAll('#preupdatecheckbox, #preupdateCheckCompleteProblems')).forEach(function(element) {
element.style.display = 'none';
});
if(document.querySelector('#noncoreplugins')) {
document.querySelector('#noncoreplugins').checked = true;
}
if(document.querySelector('button.submitupdate')) {
document.querySelector('button.submitupdate').disabled = false;
document.querySelector('button.submitupdate').classList.remove('disabled');
}
if(document.querySelector('#joomlaupdate-precheck-extensions-tab span.fa')) {
let tabIcon = document.querySelector('#joomlaupdate-precheck-extensions-tab span.fa');
tabIcon.classList.remove('fa-times');
tabIcon.classList.remove('text-danger');
tabIcon.classList.remove('fa-exclamation-triangle');
tabIcon.classList.remove('text-warning');
tabIcon.classList.add('fa-check');
tabIcon.classList.add('text-success');
}
};
if (document.querySelectorAll('#compatibilityTable0 tbody tr').length == 0) {
if(document.querySelectorAll('#compatibilityTable1 tbody tr:not(.jextcompatible)').length == 0) {
let compatibilityTable1 = document.querySelector('#compatibilityTable1');
if(compatibilityTable1) {
compatibilityTable1.style.display = 'none';
}
}
clearInterval(jextensionsIntervalTimer);
}
jextensionsIntervalCount++;
}, 1000);
};
});");
$this->appInstance->set('jextstore_joomlaupdate_script', true);
}
}
/** Manage the Joomla updater based on the user license
*
* @param Event $event
* @subparam string The $url for the package update download
* @subparam array The headers array.
* @access public
* @return void
*/
public function jchatUpdateInstall(Event $event) {
// subparams: &$url, &$headers
$arguments = $event->getArguments();
$url = isset($arguments[0]) ? $event->getArgument(0) : $event->getArgument('url');
$headers = isset($arguments[1]) ? $event->getArgument(1) : $event->getArgument('headers');
$uri = Uri::getInstance($url);
$parts = explode('/', $uri->getPath());
if ($uri->getHost() == 'storejextensions.org' && in_array('com_jchat.zip', $parts)) {
// Init as false unless the license is valid
$validUpdate = false;
// Manage partial language translations
$jLang = $this->appInstance->getLanguage();
$jLang->load('com_jchat', JPATH_BASE . '/components/com_jchat', 'en-GB', true, true);
if($jLang->getTag() != 'en-GB') {
$jLang->load('com_jchat', JPATH_BASE, null, true, false);
$jLang->load('com_jchat', JPATH_BASE . '/components/com_jchat', null, true, false);
}
// Email license validation API call and &$url building construction override
$cParams = ComponentHelper::getParams('com_jchat');
$registrationEmail = $cParams->get('registration_email', null);
// License
if($registrationEmail) {
$prodCode = 'jchatent';
$cdFuncUsed = 'str_' . 'ro' . 't' . '13';
// Retrieve license informations from the remote REST API
$apiResponse = null;
$apiEndpoint = $cdFuncUsed('uggc' . '://' . 'fgberwrkgrafvbaf' . '.bet') . "/option,com_easycommerce/action,licenseCode/email,$registrationEmail/productcode,$prodCode";
if (function_exists('curl_init')){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiEndpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$apiResponse = curl_exec($ch);
}
$objectApiResponse = json_decode($apiResponse);
if(!is_object($objectApiResponse)) {
// Message user about error retrieving license informations
$this->appInstance->enqueueMessage(Text::_('COM_JCHAT_ERROR_RETRIEVING_LICENSE_INFO'));
} else {
if(!$objectApiResponse->success) {
switch ($objectApiResponse->reason) {
// Message user about the reason the license is not valid
case 'nomatchingcode':
$this->appInstance->enqueueMessage(Text::_('COM_JCHAT_LICENSE_NOMATCHING'));
break;
case 'expired':
// Message user about license expired on $objectApiResponse->expireon
$this->appInstance->enqueueMessage(Text::sprintf('COM_JCHAT_LICENSE_EXPIRED', $objectApiResponse->expireon));
break;
}
}
// Valid license found, builds the URL update link and message user about the license expiration validity
if($objectApiResponse->success) {
$url = $cdFuncUsed('uggc' . '://' . 'fgberwrkgrafvbaf' . '.bet' . '/XZY1405SSUOnifs3243564864kfunex35tdrntq5895q.ugzy');
// Joomla 5+ native BeforePackageDownloadEvent
if(method_exists($event, 'updateUrl')) {
$event->updateUrl($url);
} else {
// Fallback to generic Event up to Joomla 4
$event->setArgument(0, $url);
}
$validUpdate = true;
$this->appInstance->enqueueMessage(Text::sprintf('COM_JCHAT_EXTENSION_UPDATED_SUCCESS', $objectApiResponse->expireon));
}
}
} else {
// Message user about missing email license code
$this->appInstance->enqueueMessage(Text::sprintf('COM_JCHAT_MISSING_REGISTRATION_EMAIL_ADDRESS', OutputFilter::ampReplace('index.php?option=com_jchat&task=config.display#_licensepreferences')));
}
if(!$validUpdate) {
$this->appInstance->enqueueMessage(Text::_('COM_JCHAT_UPDATER_STANDARD_ADVISE'), 'notice');
}
}
}
/**
* Returns an array of events this subscriber will listen to.
*
* @return array
*
* @since 4.0.0
*/
public static function getSubscribedEvents(): array {
return [
'onAfterInitialise' => 'manageSessionMetadata',
'onAfterDispatch' => 'injectAppAfterDispatch',
'onBeforeCompileHead' => 'injectAppBeforeCompileHead',
'onPreprocessMenuItems' => 'processMenuItemsDashboard',
'onInstallerBeforePackageDownload' => 'jchatUpdateInstall'
];
}
/**
* Override registers Listeners to the Dispatcher
* It allows to legacy stop a plugin execution based on the return value of its constructor
*
* @override
* @return void
*/
public function registerListeners(?DispatcherInterface $dispatcher = null) {
// Check if the plugin has not been stopped by the constructor
if(!$this->isPluginStopped) {
parent::registerListeners($dispatcher);
}
}
/**
* Constructor
*
* @param
* object &$subject The object to observe
* @param array $config
* An optional associative array of configuration settings.
* Recognized key values include 'name', 'group', 'params', 'language'
* (this list is not meant to be comprehensive).
*
* @since 1.5
*/
public function __construct($subject, $config = []) {
parent::__construct ( $subject, $config );
// Init application
$this->appInstance = Factory::getApplication();
// Init database
$this->dbInstance = Factory::getContainer()->get('DatabaseDriver');
// Exclude always the api client
if ($this->appInstance->isClient ('api')) {
$this->isPluginStopped = true;
return;
}
$this->myUser = $this->appInstance->getIdentity ();
$this->componentConfig = ComponentHelper::getParams ( 'com_jchat' );
}
}