Version 4.0.13.1

This commit is contained in:
Neo committed 2025-12-19 04:57:54 -08:00
1 parent f9e857d255
commit c6a86f0d9b
7517 files changed
+597400 -668041

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
<?php
/**
* @brief Chat Application Class
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2014 Invision Power Services, Inc.
* @package IPS Social Suite
* @subpackage Chat
* @since 03 Jan 2014
* @version
*/
namespace IPS\chat;
/**
* Chat Application Class
*/
class _Application extends \IPS\Application
{
/**
* Install 'other' items.
*
* @return void
*/
public function installOther()
{
/* Set non guests to be able to access */
foreach( \IPS\Member\Group::groups( TRUE, FALSE ) as $group )
{
$group->chat_access = TRUE;
$group->save();
}
}
/**
* [Node] Get Icon for tree
*
* @note Return the class for the icon (e.g. 'globe')
* @return string|null
*/
protected function get__icon()
{
return 'comment';
}
}
+16
View File
@@ -0,0 +1,16 @@
{
"chat": {
"logs": {
"tab": "community",
"controller": "logs",
"do": "",
"restriction": "logs_manage"
},
"settings": {
"tab": "community",
"controller": "settings",
"do": "",
"restriction": "settings_manage"
}
}
}
@@ -0,0 +1,10 @@
{
"chat": {
"settings": {
"settings_manage": "settings_manage"
},
"logs": {
"logs_manage": "logs_manage"
}
}
}
+1
View File
@@ -0,0 +1 @@
[]
+8
View File
@@ -0,0 +1,8 @@
{
"application_title": "Chat",
"app_author": "Invision Power Services, Inc.",
"app_directory": "chat",
"app_protected": 0,
"app_website": null,
"app_update_check": null
}
+2
View File
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<emails/>
+32
View File
@@ -0,0 +1,32 @@
/**
* Friendly URL Structure @todo check 3.x URLs and add alias for any that need redirecting to new 4.x equivalents. See blog entry record for example.
*
* For each value in the $furl array:
* The key should be the "SEO Template" - an identifier which you'll use when displaying a URL.
* The value should be an associative array with two or three elements: 'friendly' and 'real', and optionally 'verify':
* 'friendly'
* The friendly URL to use - encase variables in {curly braces} containing a symbol, followed by the name of the parameter that matches in the "real" URL
* The symbol should be # for numbers or @ for strings
* For example, if the "real" URL contains id=XXX, where XXX is a number, you should include {#id} somewhere in the friendly URL.
* You can also use the tag {?} for the "SEO Title" (that is, any variables that shouldn't be part of the real URL, such as the name of the topipc being viewed).
* If you want to support more than one SEO Title, you can give them zero-indexed keys like so: {?0} {?1} {?2}
* 'real'
* This should be the base of the real URL. You should not include parameters which will be parsed out from the friendly URL.
* 'verify'
* This should be the name of a class that contains a loadFromUrl() and an url() method. The dynamic URL (i.e. app=core&...) will be passed to loadFromUrl(), and the url()
* method will subsequently be called to retrieve the correct URL, ideal with ActiveRecord pattern classes.
*
* IMPORTANT: Ensure values are listed with the most specific ones first. This is to ensure that non-FURL redirects are done correctly. For example, if you have these FURLs:
* /index.php?app=myapp&module=mymodule&controller=mycontroller&do=myaction -> /myfolder/myaction
* /index.php?app=myapp&module=mymodule&controller=mycontroller -> /myfolder
* They must be provided in that order, otherwise the former will redirec to /myfolder/?do=myaction rather than /myfolder/myaction
*/
{
"topLevel": "chat",
"pages": {
"chat": {
"friendly": "",
"real": "app=chat&module=chat&controller=view"
}
}
}
+14
View File
@@ -0,0 +1,14 @@
{
"tabCountLoad": {
"type": "C",
"class": "\\IPS\\Data\\Store\\Database"
},
"tabNewWindow": {
"type": "C",
"class": "\\IPS\\Dispatcher\\Front"
},
"tabCount": {
"type": "C",
"class": "\\IPS\\Dispatcher\\Front"
}
}
View File
Whitespace-only changes.
File diff suppressed because it is too large. Load diff
+113
View File
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<language>
<app key="chat" version="100045">
<word key="__app_chat" js="0">Chat</word>
<word key="frontnavigation_chat" js="0">Chat</word>
<word key="chat_title" js="0">Chat</word>
<word key="module__chat_chat" js="0">Chat</word>
<word key="menu__chat_chat" js="0">Chat</word>
<word key="time_pm" js="0">PM</word>
<word key="time_am" js="0">AM</word>
<word key="chat_insert_emoticon" js="0">Insert Emoticon</word>
<word key="no_users_chatting" js="0">0 users chatting</word>
<word key="menu__chat_chat_settings" js="0">Settings</word>
<word key="menu__chat_chat_logs" js="0">Logs</word>
<word key="r__logs" js="0">Logs</word>
<word key="r__logs_manage" js="0">Can view chat logs?</word>
<word key="chat_banned" js="0">Can access chat?</word>
<word key="chat_access" js="0">Can access chat?</word>
<word key="chat_moderate" js="0">Can moderate chats?</word>
<word key="chat_private" js="0">Can send private chats?</word>
<word key="group__chat_ChatAccess" js="0">Chat</word>
<word key="member__chat_ChatBanned" js="0">Chat</word>
<word key="ipchat_24hour" js="0">Time format</word>
<word key="chat_12hour" js="0">Show times with AM/PM</word>
<word key="chat_24hour" js="0">Show times with 24 hour format</word>
<word key="ipchat_hide_usermessage" js="0">Show room join messages</word>
<word key="ipchat_hide_usermessage_desc" js="0">Shows a message in the chat window when users enter and leave the room</word>
<word key="ipchat_inactive_minutes" js="0">Inactivity period</word>
<word key="ipchat_inactive_minutes_desc" js="0">When the user has been inactive for this amount of time, they will be automatically kicked from the room</word>
<word key="ipchat_max_messages" js="0">Maximum number of displayed chats</word>
<word key="ipchat_new_window" js="0">Open in a new window</word>
<word key="ipchat_no_buffer" js="0">Show chat history upon joining a room</word>
<word key="ipschat_enable_rules" js="0">Show chat rules</word>
<word key="ipschat_enable_rules_desc" js="0">The user will be prompted to agree to the rules before being allowed to join the room</word>
<word key="ipschat_rules_text" js="0">Chat rules</word>
<word key="chat_timeplaceholder" js="0">HH:MM</word>
<word key="acplogs__chat_settings" js="0">Updated chat settings</word>
<word key="ipschat_online" js="0">Online times</word>
<word key="ipschat_online_desc" js="0">Optionally specify a time period that chat will be available</word>
<word key="ipschat_no_license" js="0">The chat room is not presently available</word>
<word key="ipschat_no_license_admin" js="0">You must supply a license key in order to enable the chat room</word>
<word key="ipschat_no_license_access" js="0">Your license does not include access to the chat room</word>
<word key="ipschat_no_group_access" js="0">Your group does not have permission to access the chat room</word>
<word key="ipschat_no_access" js="0">You do not have permission to access the chat room</word>
<word key="ipschat_no_ignore" js="0">This user cannot be ignored</word>
<word key="ipschat_no_ban" js="0">You do not have permission to ban users in chat</word>
<word key="ipschat_log_archive" js="0">Chat Logs</word>
<word key="acplog__chatlog_settings" js="0">Edited chat log prune settings</word>
<word key="ipchat_log_prune" js="0">Prune chat logs</word>
<word key="chatlog_log_time" js="0">Date</word>
<word key="chatlog_log_user" js="0">User</word>
<word key="chatlog_log_message" js="0">Message</word>
<word key="chatlog__hasentered" js="0">%s entered the room</word>
<word key="chatlog__hasleft" js="0">%s left the room</word>
<word key="chatlog__kicked" js="0">Kicked: %s</word>
<word key="chatlog__private" js="0">Private chat with %s: %s</word>
<word key="chat_toggle_sound" js="0">Toggle sound notifications</word>
<word key="chat_leave_room" js="0">Leave Chatroom</word>
<word key="ipschat_confirm" js="0">I agree to the terms</word>
<word key="generic_chatconnect_error" js="0">There was an error joining the chat room. Please try again or contact us.</word>
<word key="chat_currently_offline" js="0">The chat room is currently offline but will be back at %s.</word>
<word key="chat_offline_admin" js="0"><![CDATA[The chat room is currently offline based upon the ACP configuration available at Community -> Chat -> Settings]]></word>
<word key="leave_chat_room" js="0">You have left the chat room</word>
<word key="ipchat_private_chat" js="0">Start private chat</word>
<word key="ipchat_ignore_chats" js="0">Ignore private chats</word>
<word key="ipchat_unignore_chats" js="0">Stop ignoring private chats</word>
<word key="ipchat_kick" js="0">Kick user from room</word>
<word key="ipchat_ban" js="0">Ban user from room</word>
<word key="ipchat_profile" js="0">View user profile</word>
<word key="connect_error_1" js="0">The license key used was invalid, or is not correctly associated with a chat account.</word>
<word key="connect_error_2" js="0">No username was supplied to connect to the chat room. Please contact technical support for assistance.</word>
<word key="connect_error_3" js="0">No room number was supplied to connect to the chat room. Please contact technical support for assistance.</word>
<word key="connect_error_5" js="0">The room id supplied is invalid. Please contact technical support for assistance.</word>
<word key="connect_error_6" js="0">The license key used was invalid, or is not correctly associated with a chat account. Please contact technical support for assistance.</word>
<word key="connect_error_8" js="0">The server the chat room was hosted on is no longer online. Please wait a few moments and try again or contact technical support for assistance.</word>
<word key="connect_error_10" js="0">The chat server is offline. Please contact technical support for assistance.</word>
<word key="chat_room_full" js="0">The chat room limit has been reached. You will not be able to join the chat room until some users first leave.</word>
<word key="license_no_chat" js="0">Your license does not include Chat or has expired. Please contact customer services for assistance.</word>
<word key="connect_gw_error_0" js="0">Your server was unable to communicate with our chat servers. Please contact technical support for assistance.</word>
<word key="connect_gw_error_1" js="0">The license key used was invalid, or is not correctly associated with a chat account. Please contact technical support for assistance.</word>
<word key="connect_gw_error_2" js="0">No username was supplied to connect to the chat room. Please contact technical support for assistance.</word>
<word key="connect_gw_error_4" js="0">The room ID supplied was invalid. Please wait a few moments and try again or contact technical support for assistance.</word>
<word key="connect_gw_error_5" js="0">The chat room key has expired. Please wait a few moments and try again or contact technical support for assistance.</word>
<word key="connect_gw_error_6" js="0">The license key did not match the key for the chat room. Please wait a few moments and try again or contact technical support for assistance.</word>
<word key="block_chatwhoschatting" js="0">Who's Chatting</word>
<word key="block_chatwhoschatting_desc" js="0">Show the users currently in the chat room</word>
<word key="chatters_list_empty" js="0">There are no users currently in the chat room</word>
<word key="accept_rules" js="0">Accept and enter chatroom</word>
<word key="chatroom_rules" js="0">Chatroom Rules</word>
<word key="modcp_members_chatBanned" js="0">Chat Banned</word>
<word key="leftRoom" js="1">{{username}} left the room</word>
<word key="enteredRoom" js="1">{{username}} entered the room</word>
<word key="privateChatWith" js="1">Private chat with {{user}}</word>
<word key="privateChat" js="1">Private Chat</word>
<word key="soundEnabled" js="1">Notification sounds have been enabled</word>
<word key="soundDisabled" js="1">Notification sounds have been disabled</word>
<word key="usersChatting" js="1">{# [1:user][?:users]} chatting</word>
<word key="cantChatWithSelf" js="1">You can't start a private chat with yourself!</word>
<word key="cantIgnoreUser" js="1">{{user}} can't be ignored</word>
<word key="closeThisTab" js="1">Close this chat</word>
<word key="insertEmoticon" js="1">Insert Emoticon</word>
<word key="sendChat" js="1">Send</word>
<word key="noUsersChatting" js="1">No users chatting</word>
<word key="chatroom" js="1">Chat</word>
<word key="chatroomTooltip" js="1">Public Chat</word>
<word key="system" js="1">System</word>
<word key="kickedFromServer" js="1">You have been kicked from the chatroom.</word>
<word key="time_am" js="1">AM</word>
<word key="time_pm" js="1">PM</word>
<word key="hideImage" js="1">Toggle image</word>
<word key="imageHidden" js="1">Image hidden</word>
</app>
</language>
+14
View File
@@ -0,0 +1,14 @@
{
"admin": {
"chat": {
"default_controller": "",
"protected": false
}
},
"front": {
"chat": {
"default_controller": "view",
"protected": 0
}
}
}
+129
View File
@@ -0,0 +1,129 @@
{
"chat_log_archive": {
"name": "chat_log_archive",
"columns": {
"log_id": {
"allow_null": false,
"auto_increment": true,
"binary": false,
"comment": "",
"decimals": null,
"default": null,
"length": 11,
"name": "log_id",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"log_room_id": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 11,
"name": "log_room_id",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"log_time": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 11,
"name": "log_time",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"log_code": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 6,
"name": "log_code",
"type": "SMALLINT",
"unsigned": false,
"values": [],
"zerofill": false
},
"log_user": {
"allow_null": true,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": null,
"length": 255,
"name": "log_user",
"type": "VARCHAR",
"unsigned": false,
"values": [],
"zerofill": false
},
"log_message": {
"allow_null": true,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": null,
"length": 0,
"name": "log_message",
"type": "TEXT",
"unsigned": false,
"values": [],
"zerofill": false
},
"log_extra": {
"allow_null": true,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": null,
"length": 255,
"name": "log_extra",
"type": "VARCHAR",
"unsigned": false,
"values": [],
"zerofill": false
}
},
"indexes": {
"PRIMARY": {
"type": "primary",
"name": "PRIMARY",
"length": [
null
],
"columns": [
"log_id"
]
},
"log_time": {
"type": "key",
"name": "log_time",
"columns": [
"log_time"
],
"length": [
null
]
}
},
"collation": "latin1_swedish_ci",
"engine": "MyISAM"
}
}
+38
View File
@@ -0,0 +1,38 @@
[
{
"key": "ipchat_24hour",
"default": "12"
},
{
"key": "ipchat_hide_usermessage",
"default": "0"
},
{
"key": "ipchat_inactive_minutes",
"default": "360"
},
{
"key": "ipchat_log_prune",
"default": "30"
},
{
"key": "ipchat_new_window",
"default": "0"
},
{
"key": "ipchat_no_buffer",
"default": "0"
},
{
"key": "ipschat_enable_rules",
"default": "0"
},
{
"key": "ipschat_online",
"default": ""
},
{
"key": "ipschat_rules",
"default": ""
}
]
+1
View File
@@ -0,0 +1 @@
{"chatlogprune":"P0Y0M1DT0H0M0S","chatlogrefresh":"P0Y0M0DT0H30M0S"}
+467
View File
@@ -0,0 +1,467 @@
<?xml version="1.0" encoding="UTF-8"?>
<theme name="Default" author_name="Invision Power Services, Inc" author_url="http://www.invisionpower.com">
<template template_group="global" template_name="tabCount" template_data="$count" template_location="front" template_app="chat"><![CDATA[{{if $count}}
<script type='text/javascript'>
$('.elNavigation_app_chat_Chat').append( $('<span/>').addClass('ipsNotificationCount').text('{$count}') );
</script>
{{endif}}]]></template>
<template template_group="global" template_name="tabNewWindow" template_data="" template_location="front" template_app="chat"><![CDATA[<script type='text/javascript'>
$('.elNavigation_app_chat_Chat').click( function( e ){
e.preventDefault();
var joinWith = '?';
if ( $( e.currentTarget ).attr('href').indexOf('?') != -1 )
{
joinWith = '&';
}
window.open( $( e.currentTarget ).attr('href') + joinWith + '_popup=1', '_blank', "height=480,width=1200,location=0,menubar=0,toolbar=0" );
return false;
});
</script>]]></template>
<template template_group="settings" template_name="chatOnline" template_data="$value" template_location="admin" template_app="chat"><![CDATA[<div>
<input type='time' class='ipsField_short' placeholder='{lang="chat_timeplaceholder"}' value="{$value[0]}" name="ipschat_online[0]">
{lang="to"}
<input type='time' class='ipsField_short' placeholder='{lang="chat_timeplaceholder"}' value="{$value[1]}" name="ipschat_online[1]">
</div>]]></template>
<template template_group="view" template_name="acceptRules" template_data="$form" template_location="front" template_app="chat"><![CDATA[
<div class='ipsAreaBackground_light ipsPad'>
<h1 class='ipsType_pageTitle'>{lang="chatroom_rules"}</h1>
<div class='ipsType_normal ipsType_richText ipsContained ipsType_break ipsSpacer_both'>
{lang="ipschat_rules"}
</div>
{$form|raw}
</div>]]></template>
<template template_group="view" template_name="chat" template_data="$chatters" template_location="front" template_app="chat"><![CDATA[
{{if !\IPS\Settings::i()->ipchat_new_window}}
<div class="ipsPageHeader ipsClearfix ipsSpacer_bottom">
<h1 class="ipsType_pageTitle">{lang="chat_title"}</h1>
<p id='chatDebug'></p>
</div>
{{endif}}
<div data-controller='chat.front.chatcompat.main'>
<div id='elChatWrapper'>
<div class="ipsTabs ipsClearfix" id='elChatTabs'>
<ul class='ipsPos_right ipsList_inline ipsList_noSpacing ipsResponsive_hidePhone'>
<li>
<a href='#' class='ipsPos_right ipsButton ipsButton_verySmall ipsButton_overlaid' data-action='toggleSound' data-ipsTooltip title='{lang="chat_toggle_sound"}'><i class='fa fa-volume-up'></i></a>
</li>
<li>
{{$leave = \IPS\Request::i()->_popup ? '&_popup=' . \IPS\Request::i()->_popup : '';}}
<a href='{url="app=chat&module=chat&controller=view&do=leave{$leave}" seoTemplate="chat" csrf="true"}' class='ipsPos_right ipsButton ipsButton_verySmall ipsButton_overlaid' data-action='leaveChat' data-ipsTooltip title='{lang="chat_leave_room"}'>{lang="chat_leave_room"}</a>
</li>
</ul>
<a href="#elChatTabs" data-action="expandTabs"><i class="fa fa-caret-down"></i></a>
<ul role="tablist" class="ipsList_reset" id='elChatTabBar'>
</ul>
</div>
<section id='elChatTabsContent'>
</section>
</div>
<div id='elChatIFrame'></div>
<ul id='elInitialUserList' class='ipsHide'>
{{foreach $chatters as $chatter}}
{template="userRow" group="view" app="chat" params="$chatter"}
{{endforeach}}
</ul>
<div class='ipsAreaBackground_light ipsPad ipsResponsive_showPhone ipsResponsive_block ipsSpacer_top ipsType_center'>
<ul class='ipsList_inline ipsList_noSpacing'>
<li>
<a href='#' class='ipsPos_right ipsButton ipsButton_verySmall ipsButton_light' data-action='toggleSound' data-ipsTooltip title='{lang="chat_toggle_sound"}'><i class='fa fa-volume-up'></i></a>
</li>
<li>
{{$leave = \IPS\Request::i()->_popup ? '&_popup=' . \IPS\Request::i()->_popup : '';}}
<a href='{url="app=chat&module=chat&controller=view&do=leave{$leave}" seoTemplate="chat" csrf="true"}' class='ipsPos_right ipsButton ipsButton_verySmall ipsButton_light' data-action='leaveChat' data-ipsTooltip title='{lang="chat_leave_room"}'>{lang="chat_leave_room"}</a>
</li>
</ul>
</div>
</div>]]></template>
<template template_group="view" template_name="chatvars" template_data="$options, $forumIdMap, $groups, $badwords, $ignored, $emoticons" template_location="front" template_app="chat"><![CDATA[
<script type='text/javascript'>
// System vars
ips.setSetting( 'roomID', {$options['roomId']} );
ips.setSetting( 'userID', {$options['userId']} );
ips.setSetting( 'forumUserID', {expression="intval( \IPS\Member::loggedIn()->member_id )"} );
ips.setSetting( 'username', '{{if \IPS\Member::loggedIn()->member_id}}{expression="\IPS\Member::loggedIn()->name"}{{else}}{expression="\IPS\Member::loggedIn()->language()->get('guest')"}_{$options['userId']}{{endif}}' );
ips.setSetting( 'accessKey', '{$options['accessKey']}' );
ips.setSetting( 'serverHost', '{$options['serverHost']}' );
ips.setSetting( 'serverPath', '{$options['serverPath']}' );
ips.setSetting( 'ourURL', "{expression="urlencode(\IPS\Settings::i()->base_url)"}" );
ips.setSetting( 'chatEmoticons',
{expression="json_encode( $emoticons )" raw="true"}
);
ips.setSetting( 'ignoredChats',
{expression="json_encode( $ignored )" raw="true"}
);
ips.setSetting( 'forumIDMap',
{expression="json_encode( $forumIdMap )" raw="true"}
);
ips.setSetting( 'groups',
{expression="json_encode( $groups )" raw="true"}
);
ips.setSetting( 'badwords',
{expression="json_encode( $badwords )" raw="true"}
);
// Sounds in MP3 format
ips.setSetting( 'sounds', {
'enter': 'enter',
'leave': 'leave',
'message': 'message'
});
// Settings
ips.setSetting( 'condenseTime', true );
ips.setSetting( 'maxMessages', 100 );
ips.setSetting( 'moderator', {{if \IPS\Member::loggedIn()->group['chat_moderate']}}true{{else}}false{{endif}} );
ips.setSetting( 'private', {{if \IPS\Member::loggedIn()->group['chat_private']}}true{{else}}false{{endif}} );
ips.setSetting( 'hideEnterExit', '{expression="(bool) \IPS\Settings::i()->ipchat_hide_usermessage"}' );
ips.setSetting( 'noBuffer', '{expression="(bool) \IPS\Settings::i()->ipchat_no_buffer"}' );
ips.setSetting( 'inactiveKick', parseInt( {expression="\IPS\Settings::i()->ipchat_inactive_minutes"} * 60 ) );
ips.setSetting( 'user24hour', {{if \IPS\Settings::i()->ipchat_24hour == '24'}}true{{else}}false{{endif}} );
ips.setSetting( 'soundEnabled', ips.utils.db.get( 'chat', 'sounds' ) );
</script>]]></template>
<template template_group="view" template_name="userInfo" template_data="$member" template_location="front" template_app="chat"><![CDATA[{{$group = \IPS\Member\Group::load( $member->member_group_id );}}
<div class='ipsType_center ipsSpacer_top'>
<h3 class='ipsType_sectionHead ipsSpacer_bottom'>
{$group->formatName( $member->name )|raw}
</h3>
<br>
{template="userPhoto" group="global" app="core" params="$member, 'medium'"}
</div>]]></template>
<template template_group="view" template_name="userRow" template_data="$data" template_location="front" template_app="chat"><![CDATA[
<li id='elChatUserRow_{$data['user_id']}'>
{{if $data['forumUserID'] or \IPS\Member::loggedIn()->member_id !== $data['forumUserID']}}
<a href='#' class='ipsPhotoPanel ipsPhotoPanel_tiny ipsFaded_withHover cChatUserRow ipsType_blendLinks ipsPad_half' id='elChatUser_{$data['user_id']}' data-userID='{$data['user_id']}' data-forumUserID='{$data['forumUserID']}' data-username="{$data['username']}" data-ipsMenu data-ipsMenu-activeClass='cChatUserRow_hover' data-ipsMenu-appendTo='#elChatUserRow_{$data['user_id']}' >
<img src='{$data['photo']}' alt='' class='ipsUserPhoto ipsUserPhoto_tiny'>
<div class='cChatUsername'>
{$data['formattedUsername']|raw} <i class='fa fa-caret-down ipsFaded ipsFaded_more'></i>
</div>
</a>
<ul id='elChatUser_{$data['user_id']}_menu' class='ipsHide ipsMenu ipsMenu_auto cChatUserMenu' data-userID='{$data['user_id']}' data-forumUserID='{$data['forumUserID']}'>
{{if \IPS\Member::loggedIn()->member_id !== $data['forumUserID']}}
<li class='ipsMenu_item' data-ipsMenuValue='private'>
<a href='#'>{lang="ipchat_private_chat"}</a>
</li>
<li class='ipsMenu_sep' data-role='privateSep'><hr></li>
<li class='ipsMenu_item' data-ipsMenuValue='ignore'>
<a href='#'>{lang="ipchat_ignore_chats"}</a>
</li>
<li class='ipsMenu_item' data-ipsMenuValue='unignore'>
<a href='#'>{lang="ipchat_unignore_chats"}</a>
</li>
{{if \IPS\Member::loggedIn()->group['chat_moderate']}} <!-- if moderator... -->
<li class='ipsMenu_sep' data-role='modSep'><hr></li>
<li class='ipsMenu_item' data-ipsMenuValue='kick'>
<a href='#'>{lang="ipchat_kick"}</a>
</li>
<li class='ipsMenu_item' data-ipsMenuValue='ban'>
<a href='#'>{lang="ipchat_ban"}</a>
</li>
{{endif}}
<li class='ipsMenu_sep'><hr></li>
{{endif}}
{{if $data['forumUserID']}}
<li class='ipsMenu_item'>
<a href='{$data['profileUrl']}' target='_blank'>{lang="ipchat_profile"}</a>
</li>
{{endif}}
</ul>
{{else}}
<span class='ipsPhotoPanel ipsPhotoPanel_tiny ipsFaded_withHover cChatUserRow ipsType_blendLinks ipsPad_half' id='elChatUser_{$data['user_id']}' data-userID='{$data['user_id']}' data-forumUserID='{$data['forumUserID']}' data-username="{$data['username']}">
<img src='{$data['photo']}' alt='' class='ipsUserPhoto ipsUserPhoto_tiny'>
<div class='cChatUsername'>
{$data['formattedUsername']|raw}
</div>
</span>
{{endif}}
</li>]]></template>
<template template_group="widgets" template_name="chatwhoschatting" template_data="$chatters, $orientation='vertical'" template_location="front" template_app="chat"><![CDATA[<h3 class='ipsType_reset ipsWidget_title'>
{lang="block_chatwhoschatting"}
</h3>
<div class='ipsWidget_inner {{if $orientation == 'vertical'}}ipsPad{{endif}}'>
{{if count( $chatters )}}
<ul class='ipsList_inline ipsList_csv ipsList_noSpacing'>
{{foreach $chatters as $row}}
<li>{template="userLinkFromData" group="global" app="core" params="$row['forumUserID'], $row['username'], $row['seo_name'], $row['groupID']"}</li>
{{endforeach}}
</ul>
{{else}}
<p class='ipsType_reset ipsType_medium ipsType_light'>{lang="chatters_list_empty"}</p>
{{endif}}
</div>]]></template>
<css css_location="front" css_app="chat" css_attributes="" css_path="." css_name="chat_responsive.css"><![CDATA[/* PHONES */
@media screen and (max-width: 767px) {
.cChatContainer {
height: 315px;
}
#elChatTabBar {
margin-right: 0;
}
#elChatTabsContent > .ipsTabs_panel {
height: auto;
}
#elChatTabBar .ipsTabs_item [data-action="closeTab"] {
margin-left: 10px;
}
.cEmoticonsButton, .cSendButton {
margin-bottom: 0 !important;
}
.cEmoticonsButton {
width: 25% !important;
float: left;
}
.cSendButton {
width: 71% !important;
float: left;
margin-left: 4% !important;
}
/* Row stuff */
.cChatRow {
display: block;
}
.cChatRow_date {
display: none !important;
}
.cChatRow_responsiveDate {
float: right;
font-size: 11px;
}
.cChatRow_notice {
text-align: center;
}
.cChatRow .cChatRow_user {
text-align: left;
background: #f5f5f5;
width: 100%;
border-bottom: 0;
min-width: 0;
max-width: 100%;
font-size: 13px;
padding: 7px 10px;
}
.cChatRow_own .cChatRow_user {
background: #d0dbe7;
}
.cChatRow .cChatRow_user:empty {
display: none;
}
.cChatRow .cChatRow_user, .cChatRow .cChatRow_content, .cChatRow .cChatRow_date {
display: block;
}
}]]></css>
<css css_location="front" css_app="chat" css_attributes="" css_path="." css_name="chat.css"><![CDATA[#elChatTabs {
background: #262e33;
}
/*#elChatTabs .ipsTabs_item {
font-weight: normal;
}*/
#elChatWrapper {
border: 1px solid rgba(0,0,0,0.1);
}
#elChatTabsContent > .ipsTabs_panel {
height: 430px;
}
#elChatTabBar {
margin-right: 190px;
}
#elChatTabBar > li > a:not( .ipsTabs_activeItem ) {
background: rgba(225,225,225,0.3);
}
@media screen and (min-width: 767px) {
#elChatTabBar > li > a:not( .ipsTabs_activeItem ) {
color: rgba(255,255,255,0.5);
}
}
#elUserList {
max-height: 395px;
overflow: auto;
}
.cChatCompose {
}
.ipsApp .cMessageTextarea {
width: 100%;
height: 44px;
resize: none;
}
.cChatTab {
position: relative;
height: 430px;
border-right: 1px solid rgba(0,0,0,0.1);
}
.cChatCompose {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
.cChatCompose .ipsColumn_veryNarrow {
width: 58px;
}
.cChatCompose .ipsColumn_veryNarrow .ipsButton {
font-size: 18px;
}
.cChatUserRow {
display: block;
}
.cChatUserRow:hover, .cChatUserRow_hover {
background: #fafafa;
}
.cChatUsername {
font-size: 14px;
line-height: 28px;
}
#elUserList .ipsUserPhoto_tiny img,
#elUserList img.ipsUserPhoto_tiny,
#elUserList .ipsUserPhoto_tiny:after {
width: 28px;
height: 28px;
}
.cChatUserInfo {
min-height: 150px;
}
#elChatTabs [data-action='toggleSound'] {
font-size: 15px;
}
/* Message styles */
.cChatContainer {
width: 100%;
height: 355px;
overflow: auto;
}
.cChatRow {
font-size: 14px;
overflow: auto;
display: table-row;
width: 100%;
}
.cChatRow .cChatRow_user,
.cChatRow .cChatRow_content,
.cChatRow .cChatRow_date {
display: table-cell;
padding: 10px;
border-bottom: 1px solid #efefef;
vertical-align: top;
}
.cChatRow .cChatRow_user {
text-align: right;
color: #898989;
min-width: 130px;
max-width: 150px;
text-overflow: ellipsis;
overflow: hidden;
}
.cChatRow_date {
padding: 0 10px;
font-size: 12px;
color: #939393;
min-width: 75px; /* Wide enough for AM/PM */
width: 75px;
}
/*.cChatRow.cChatRow_date {
font-size: 12px;
font-weight: bold;
color: #222;
}
.cChatRow.cChatRow_date .cChatRow_user,
.cChatRow.cChatRow_date .cChatRow_content {
padding: 5px 10px 0;
border-bottom: 0px;
}*/
.cChatRow.cChatRow_notice {
color: #939393;
}
.cChatRow.cChatRow_me {
color: #898989;
}
.cChatRow .cChatRow_content {
width: 100%;
}
.cChatRow_system {
background: #f9e4e1;
}
.cChatRow_own {
background: #e1eaf5;
}
.cChatRow_own .cChatRow_user,
.cChatRow_own .cChatRow_content,
.cChatRow_own .cChatRow_date {
border-color: #cdd8e6;
}
.cChatParsedImage img {
max-width: 100px;
max-height: 100px;
}
.cChatParsedImage a {
display: inline-block;
}
.cChatParsedImage a:last-child {
vertical-align: top;
}
.cChatParsedImage .ipsButton {
line-height: 14px;
padding: 0 5px;
}]]></css>
</theme>
@@ -0,0 +1 @@
{}
+89
View File
@@ -0,0 +1,89 @@
{
"11004": "1.1.0 Alpha 5",
"11005": "1.1.0 Beta 1",
"11008": "1.1.0",
"13000": "1.3.0 Beta 1",
"40000": "4.0.0",
"100000": "4.0.0 Beta 0",
"100001": "4.0.0 Beta 1",
"100002": "4.0.0 Beta 2",
"100003": "4.0.0 Beta 3",
"100004": "4.0.0 Beta 3a",
"100005": "4.0.0 Beta 4",
"100006": "4.0.0 Beta 4a",
"100007": "4.0.0 Beta 4b",
"100008": "4.0.0 Beta 5",
"100009": "4.0.0 Beta 5a",
"100010": "4.0.0 Beta 6",
"100011": "4.0.0 Beta 7",
"100012": "4.0.0 Beta 7a",
"100013": "4.0.0 Beta 8",
"100014": "4.0.0 RC1",
"100015": "4.0.0 RC2",
"100016": "4.0.0 RC3",
"100017": "4.0.0 RC4",
"100018": "4.0.0 RC5",
"100019": "4.0.0 RC5a",
"100020": "4.0.0 RC6",
"10000": "1.0.0 Alpha 1",
"10001": "1.0.0 Alpha 2",
"10002": "1.0.0 Alpha 3",
"10003": "1.0.0 Alpha 4",
"10004": "1.0.0 Alpha 5",
"10005": "1.0.0 Alpha 6",
"10006": "1.0.0 Alpha 7",
"10007": "1.0.0 Alpha 8",
"10008": "1.0.0 Beta 1",
"10009": "1.0.0 Beta 2",
"10010": "1.0.0 Beta 3",
"10011": "1.0.0 Beta 4",
"10012": "1.0.0 RC 1",
"10013": "1.0.0 RC 2",
"10014": "1.0.0",
"11000": "1.1.0 Alpha 1",
"11001": "1.1.0 Alpha 2",
"11002": "1.1.0 Alpha 3",
"11003": "1.1.0 Alpha 4",
"11006": "1.1.0 Beta 2",
"11007": "1.1.0 Beta 3",
"11009": "1.1.1",
"11010": "1.1.2",
"12000": "1.2.0 Beta 1",
"12001": "1.2.0 RC 1",
"12002": "1.2.0",
"13001": "1.3.0 Beta 2",
"13002": "1.3.0",
"13003": "1.3.1",
"14000": "1.4.0 Beta 1",
"14001": "1.4.0 Beta 2",
"14002": "1.4.0",
"14003": "1.4.1",
"14004": "1.4.2",
"14005": "1.4.3",
"14006": "1.4.4",
"100021": "4.0.0 RC7",
"100022": "4.0.0 RC7a",
"100023": "4.0.0",
"100024": "4.0.1",
"100025": "4.0.2",
"100026": "4.0.3",
"100027": "4.0.4",
"100028": "4.0.5",
"100029": "4.0.5.1",
"100030": "4.0.6",
"100031": "4.0.6.1",
"100032": "4.0.7",
"100033": "4.0.8",
"100034": "4.0.8.1",
"100035": "4.0.9",
"100036": "4.0.9.1",
"100037": "4.0.9.2",
"100038": "4.0.10",
"100039": "4.0.10.1",
"100040": "4.0.10.2",
"100041": "4.0.11",
"100042": "4.0.12",
"100043": "4.0.12.1",
"100044": "4.0.13",
"100045": "4.0.13.1"
}
+1
View File
@@ -0,0 +1 @@
{"chatwhoschatting":{"class":"\\IPS\\Widget\\StaticCache","restrict":["sidebar","cms"],"default_area":"","allow_reuse":false,"menu_style":"menu","embeddable":true}}
@@ -0,0 +1,76 @@
<?php
/**
* @brief Front Navigation Extension: Chat
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Chat
* @since 8 Jan 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Chat
*/
class _Chat
{
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return !\IPS\Application::load('chat')->hide_tab and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'chat', 'chat' ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('frontnavigation_chat');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=chat&module=chat&controller=view", 'front', 'chat' );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'chat';
}
/**
* Children
*
* @return array
*/
public function children()
{
return array();
}
}
Whitespace-only changes.
@@ -0,0 +1,54 @@
<?php
/**
* @brief Admin CP Group Form
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Chat
* @since 15 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\extensions\core\GroupForm;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Admin CP Group Form
*/
class _ChatAccess
{
/**
* Process Form
*
* @param \IPS\Form\Tabbed $form The form
* @param \IPS\Member\Group $group Existing Group
* @return void
*/
public function process( &$form, $group )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'chat_access', $group->chat_access ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'chat_moderate', $group->chat_moderate ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'chat_private', $group->chat_private ) );
}
/**
* Save
*
* @param array $values Values from form
* @param \IPS\Member\Group $group The group
* @return void
*/
public function save( $values, &$group )
{
$group->chat_access = $values['chat_access'];
$group->chat_moderate = $values['chat_moderate'];
$group->chat_private = $values['chat_private'];
}
}
Whitespace-only changes.
@@ -0,0 +1,50 @@
<?php
/**
* @brief Admin CP Member Form
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Chat
* @since 15 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\extensions\core\MemberForm;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Admin CP Member Form
*/
class _ChatBanned
{
/**
* Process Form
*
* @param \IPS\Form\Tabbed $form The form
* @param \IPS\Member $member Existing Member
* @return void
*/
public function process( &$form, $member )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'chat_banned', !$member->chat_banned ) );
}
/**
* Save
*
* @param array $values Values from form
* @param \IPS\Member $member The member
* @return void
*/
public function save( $values, &$member )
{
$member->chat_banned = !$values['chat_banned'];
}
}
Whitespace-only changes.
@@ -0,0 +1,104 @@
<?php
/**
* @brief Moderator Control Panel Member Management Extension: ChatBanned
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Chat
* @since 15 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\extensions\core\ModCpMemberManagement;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Moderator Control Panel Member Management Extension: ChatBanned
*/
class _ChatBanned
{
/**
* Returns the tab key for the navigation bar
*
* @return string
*/
public function getTab()
{
return 'chatBanned';
}
/**
* Get content to display
*
* @return string
*/
public function manage()
{
/* Create the table */
$table = new \IPS\Helpers\Table\Db( 'core_members', \IPS\Http\Url::internal( 'app=core&module=modcp&tab=members&area=chat_banned' ), 'chat_banned=1' );
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'modcp', 'core', 'front' ), 'memberManagementRow' );
$table->langPrefix = 'members_';
/* Columns we need */
$table->include = array( 'member_id', 'name', 'email', 'joined', 'member_group_id', 'photo' );
$table->mainColumn = 'name';
/* Custom parsers */
$table->parsers = array(
'joined' => function( $val, $row )
{
return \IPS\DateTime::ts( $val )->localeDate();
},
'member_group_id' => function( $val, $row )
{
return \IPS\Member\Group::load( $val )->formattedName;
},
'photo' => function( $val, $row )
{
return \IPS\Theme::i()->getTemplate( 'global', 'core' )->userPhoto( \IPS\Member::constructFromData( $row ), 'mini' );
},
);
/* Individual member actions */
$table->rowButtons = function( $row )
{
$member = \IPS\Member::constructFromData( $row );
$return = array();
$return['edit'] = array(
'icon' => 'pencil',
'title' => 'edit',
'link' => \IPS\Http\Url::internal( 'app=core&module=members&controller=profile&do=edit&id=' . $member->member_id, 'front', 'edit_profile', $member->members_seo_name )
);
$return['warn'] = array(
'icon' => '',
'title' => 'modcp_view_warnings',
'link' => \IPS\Http\Url::internal( 'app=core&module=system&controller=warnings&id=' . $member->member_id, 'front', 'warn_list', $member->members_seo_name )
);
$return['contact'] = array(
'icon' => 'envelope',
'title' => 'message',
'link' => \IPS\Http\Url::internal( 'app=core&module=messaging&controller=messenger&do=compose&to=' . $member->member_id, 'front', 'messenger_compose', $member->members_seo_name )
);
return $return;
};
/* Default sort options */
$table->sortBy = $table->sortBy ?: 'joined';
$table->sortDirection = $table->sortDirection ?: 'desc';
return (string) $table;
}
}
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
View File
Whitespace-only changes.
+56
View File
@@ -0,0 +1,56 @@
//<?php
class chat_hook_tabCount extends _HOOK_CLASS_
{
/**
* Output the basic javascript files every page needs
*
* @return void
*/
protected static function baseJs()
{
parent::baseJs();
if ( !isset( \IPS\Data\Store::i()->chatters ) )
{
\IPS\Data\Store::i()->chatters = array();
}
$chatters = \IPS\Data\Store::i()->chatters;
$seen = array();
$count = 0;
if( is_array( $chatters ) AND count( $chatters ) )
{
foreach( $chatters as $uid => $chatter )
{
/* Have we already seen this? Remove duplicates */
if( in_array( $chatter['forumUserID'], $seen ) )
{
unset( $chatters[ $uid ] );
}
/* If the last update was longer than 120 seconds ago, they're gone */
if( $chatter['last_update'] < time() - 120 )
{
unset( $chatters[ $uid ] );
}
$seen[ $chatter['forumUserID'] ] = $chatter['forumUserID'];
}
$count = count( $chatters );
}
if( !$count )
{
return;
}
\IPS\Output::i()->endBodyCode .= <<<HTML
<script type='text/javascript'>
$('.elNavigation_app_chat_Chat').append( $('<span/>').addClass('ipsNotificationCount').text('{$count}') );
</script>
HTML;
}
}
+17
View File
@@ -0,0 +1,17 @@
//<?php
class chat_hook_tabCountLoad extends _HOOK_CLASS_
{
/**
* Constructor
* Gets stores which are always needed to save individual queries
*
* @return void
*/
public function __construct()
{
parent::__construct();
$this->initLoad[] = 'chatters';
}
}
+53
View File
@@ -0,0 +1,53 @@
//<?php
class chat_hook_tabNewWindow extends _HOOK_CLASS_
{
/**
* Output the basic javascript files every page needs
*
* @return void
*/
protected static function baseJs()
{
parent::baseJs();
if( !\IPS\Settings::i()->ipchat_new_window )
{
return;
}
\IPS\Output::i()->endBodyCode .= <<<HTML
<script type='text/javascript'>
$('.elNavigation_app_chat_Chat').click( function( e ){
e.preventDefault();
var joinWith = '?';
if ( $( e.currentTarget ).attr('href').indexOf('?') != -1 )
{
joinWith = '&';
}
window.open( $( e.currentTarget ).attr('href') + joinWith + '_popup=1', '_blank', "height=480,width=1200,location=0,menubar=0,toolbar=0" );
return false;
});
</script>
HTML;
}
/**
* Finish
*
* @return void
*/
public function finish()
{
/* Is this a popup? */
if ( \IPS\Request::i()->_popup == 1 AND \IPS\Dispatcher::i()->application->directory == 'chat' )
{
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Output::i()->output ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
}
parent::finish();
}
}
View File
Whitespace-only changes.
+11
View File
@@ -0,0 +1,11 @@
// ----------------------------------------------------------------------------
// Buzz, a Javascript HTML5 Audio library
// v1.1.8 - Built 2015-01-12 11:08
// Licensed under the MIT license.
// http://buzz.jaysalvat.com/
// ----------------------------------------------------------------------------
// Copyright (C) 2010-2015 Jay Salvat
// http://jaysalvat.com/
// ----------------------------------------------------------------------------
(function(t,e){"use strict";"undefined"!=typeof module&&module.exports?module.exports=e():"function"==typeof define&&define.amd?define([],e):t.buzz=e()})(this,function(){"use strict";var t=window.AudioContext||window.webkitAudioContext,e={audioCtx:window.AudioContext?new t:null,defaults:{autoplay:!1,duration:5e3,formats:[],loop:!1,placeholder:"--",preload:"metadata",volume:80,webAudioApi:!1,document:window.document},types:{mp3:"audio/mpeg",ogg:"audio/ogg",wav:"audio/wav",aac:"audio/aac",m4a:"audio/x-m4a"},sounds:[],el:document.createElement("audio"),sound:function(t,n){function i(t){for(var e=[],n=t.length-1,i=0;n>=i;i++)e.push({start:t.start(i),end:t.end(i)});return e}function u(t){return t.split(".").pop()}n=n||{};var s=n.document||e.defaults.document,r=0,o=[],a={},h=e.isSupported();if(this.load=function(){return h?(this.sound.load(),this):this},this.play=function(){return h?(this.sound.play(),this):this},this.togglePlay=function(){return h?(this.sound.paused?this.sound.play():this.sound.pause(),this):this},this.pause=function(){return h?(this.sound.pause(),this):this},this.isPaused=function(){return h?this.sound.paused:null},this.stop=function(){return h?(this.setTime(0),this.sound.pause(),this):this},this.isEnded=function(){return h?this.sound.ended:null},this.loop=function(){return h?(this.sound.loop="loop",this.bind("ended.buzzloop",function(){this.currentTime=0,this.play()}),this):this},this.unloop=function(){return h?(this.sound.removeAttribute("loop"),this.unbind("ended.buzzloop"),this):this},this.mute=function(){return h?(this.sound.muted=!0,this):this},this.unmute=function(){return h?(this.sound.muted=!1,this):this},this.toggleMute=function(){return h?(this.sound.muted=!this.sound.muted,this):this},this.isMuted=function(){return h?this.sound.muted:null},this.setVolume=function(t){return h?(0>t&&(t=0),t>100&&(t=100),this.volume=t,this.sound.volume=t/100,this):this},this.getVolume=function(){return h?this.volume:this},this.increaseVolume=function(t){return this.setVolume(this.volume+(t||1))},this.decreaseVolume=function(t){return this.setVolume(this.volume-(t||1))},this.setTime=function(t){if(!h)return this;var e=!0;return this.whenReady(function(){e===!0&&(e=!1,this.sound.currentTime=t)}),this},this.getTime=function(){if(!h)return null;var t=Math.round(100*this.sound.currentTime)/100;return isNaN(t)?e.defaults.placeholder:t},this.setPercent=function(t){return h?this.setTime(e.fromPercent(t,this.sound.duration)):this},this.getPercent=function(){if(!h)return null;var t=Math.round(e.toPercent(this.sound.currentTime,this.sound.duration));return isNaN(t)?e.defaults.placeholder:t},this.setSpeed=function(t){return h?(this.sound.playbackRate=t,this):this},this.getSpeed=function(){return h?this.sound.playbackRate:null},this.getDuration=function(){if(!h)return null;var t=Math.round(100*this.sound.duration)/100;return isNaN(t)?e.defaults.placeholder:t},this.getPlayed=function(){return h?i(this.sound.played):null},this.getBuffered=function(){return h?i(this.sound.buffered):null},this.getSeekable=function(){return h?i(this.sound.seekable):null},this.getErrorCode=function(){return h&&this.sound.error?this.sound.error.code:0},this.getErrorMessage=function(){if(!h)return null;switch(this.getErrorCode()){case 1:return"MEDIA_ERR_ABORTED";case 2:return"MEDIA_ERR_NETWORK";case 3:return"MEDIA_ERR_DECODE";case 4:return"MEDIA_ERR_SRC_NOT_SUPPORTED";default:return null}},this.getStateCode=function(){return h?this.sound.readyState:null},this.getStateMessage=function(){if(!h)return null;switch(this.getStateCode()){case 0:return"HAVE_NOTHING";case 1:return"HAVE_METADATA";case 2:return"HAVE_CURRENT_DATA";case 3:return"HAVE_FUTURE_DATA";case 4:return"HAVE_ENOUGH_DATA";default:return null}},this.getNetworkStateCode=function(){return h?this.sound.networkState:null},this.getNetworkStateMessage=function(){if(!h)return null;switch(this.getNetworkStateCode()){case 0:return"NETWORK_EMPTY";case 1:return"NETWORK_IDLE";case 2:return"NETWORK_LOADING";case 3:return"NETWORK_NO_SOURCE";default:return null}},this.set=function(t,e){return h?(this.sound[t]=e,this):this},this.get=function(t){return h?t?this.sound[t]:this.sound:null},this.bind=function(t,e){if(!h)return this;t=t.split(" ");for(var n=this,i=function(t){e.call(n,t)},u=0;t.length>u;u++){var s=t[u],r=s;s=r.split(".")[0],o.push({idx:r,func:i}),this.sound.addEventListener(s,i,!0)}return this},this.unbind=function(t){if(!h)return this;t=t.split(" ");for(var e=0;t.length>e;e++)for(var n=t[e],i=n.split(".")[0],u=0;o.length>u;u++){var s=o[u].idx.split(".");(o[u].idx===n||s[1]&&s[1]===n.replace(".",""))&&(this.sound.removeEventListener(i,o[u].func,!0),o.splice(u,1))}return this},this.bindOnce=function(t,e){if(!h)return this;var n=this;return a[r++]=!1,this.bind(t+"."+r,function(){a[r]||(a[r]=!0,e.call(n)),n.unbind(t+"."+r)}),this},this.trigger=function(t,e){if(!h)return this;t=t.split(" ");for(var n=0;t.length>n;n++)for(var i=t[n],u=0;o.length>u;u++){var r=o[u].idx.split(".");if(o[u].idxLine truncated
Whitespace-only changes.
@@ -0,0 +1,72 @@
/*! https://mths.be/esrever v0.2.0 by @mathias */
;(function(root) {
// Detect free variables `exports`
var freeExports = typeof exports == 'object' && exports;
// Detect free variable `module`
var freeModule = typeof module == 'object' && module &&
module.exports == freeExports && module;
// Detect free variable `global`, from Node.js or Browserified code,
// and use it as `root`
var freeGlobal = typeof global == 'object' && global;
if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
root = freeGlobal;
}
/*--------------------------------------------------------------------------*/
var regexSymbolWithCombiningMarks = /([\0-\u02FF\u0370-\u1AAF\u1B00-\u1DBF\u1E00-\u20CF\u2100-\uD7FF\uE000-\uFE1F\uFE30-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])([\u0300-\u036F\u1AB0-\u1AFF\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]+)/g;
var regexSurrogatePair = /([\uD800-\uDBFF])([\uDC00-\uDFFF])/g;
var reverse = function(string) {
// Step 1: deal with combining marks and astral symbols (surrogate pairs)
string = string
// Swap symbols with their combining marks so the combining marks go first
.replace(regexSymbolWithCombiningMarks, function($0, $1, $2) {
// Reverse the combining marks so they will end up in the same order
// later on (after another round of reversing)
return reverse($2) + $1;
})
// Swap high and low surrogates so the low surrogates go first
.replace(regexSurrogatePair, '$2$1');
// Step 2: reverse the code units in the string
var result = '';
var index = string.length;
while (index--) {
result += string.charAt(index);
}
return result;
};
/*--------------------------------------------------------------------------*/
var esrever = {
'version': '0.2.0',
'reverse': reverse
};
// Some AMD build optimizers, like r.js, check for specific condition patterns
// like the following:
if (
typeof define == 'function' &&
typeof define.amd == 'object' &&
define.amd
) {
define(function() {
return esrever;
});
} else if (freeExports && !freeExports.nodeType) {
if (freeModule) { // in Node.js, io.js, or RingoJS v0.8.0+
freeModule.exports = esrever;
} else { // in Narwhal or RingoJS v0.7.0-
for (var key in esrever) {
esrever.hasOwnProperty(key) && (freeExports[key] = esrever[key]);
}
}
} else { // in Rhino or a web browser
root.esrever = esrever;
}
}(this));
Whitespace-only changes.
Whitespace-only changes.
Binary file not shown.
Whitespace-only changes.
Binary file not shown.
Binary file not shown.
Whitespace-only changes.
@@ -0,0 +1,170 @@
<?php
/**
* @brief logs
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Chat
* @since 15 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\modules\admin\chat;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* logs
*/
class _logs extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'logs_manage' );
parent::execute();
}
/**
* Show logs
*
* @return void
*/
protected function manage()
{
/* Create the table */
$table = new \IPS\Helpers\Table\Db( 'chat_log_archive', \IPS\Http\Url::internal( 'app=chat&module=chat&controller=logs' ) );
$table->langPrefix = 'chatlog_';
/* Column stuff */
$table->include = array( 'log_time', 'log_user', 'log_message' );
$table->mainColumn = 'log_message';
$table->widths = array( 'log_time' => '20', 'log_user' => '20', 'log_message' => '60' );
/* Sort stuff */
$table->sortBy = $table->sortBy ?: 'log_time';
$table->sortDirection = $table->sortDirection ?: 'desc';
/* Search */
$table->quickSearch = 'log_message';
$table->advancedSearch = array(
'log_user' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
'log_time' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
);
/* Formatters */
$self = $this;
$table->parsers = array(
'log_time' => function( $val, $row )
{
$date = \IPS\DateTime::ts( $val );
return $date->localeDate() . ' ' . $date->localeTime( FALSE );
},
'log_user' => function( $val, $row ) use ( $self )
{
return $self->cleanMessage( $val );
},
'log_message' => function( $val, $row ) use ( $self )
{
$val = $self->cleanMessage( $val );
if( $row['log_code'] == 2 )
{
$_extra = explode( '_', $row['log_extra'] );
if( $_extra[0] == 1 )
{
$val = \IPS\Member::loggedIn()->language()->addToStack('chatlog__hasentered', FALSE, array( 'sprintf' => $row['log_user'] ) );
}
else
{
$val = \IPS\Member::loggedIn()->language()->addToStack('chatlog__hasleft', FALSE, array( 'sprintf' => $row['log_user'] ) );
}
}
else if( $row['log_code'] == 5 )
{
$val = \IPS\Member::loggedIn()->language()->addToStack('chatlog__kicked', FALSE, array( 'sprintf' => $val ) );
}
if( mb_strpos( $val, '/me' ) === 0 )
{
$val = mb_substr( $val, 4 );
}
if( mb_strpos( $row['log_extra'], 'private=' ) === 0 )
{
$_user = mb_substr( $row['log_extra'], mb_strrpos( $row['log_extra'], '=' ) + 1 );
$_uid = $_user;
$_user = \IPS\Member::load( $_user );
$val = \IPS\Member::loggedIn()->language()->addToStack('chatlog__private', FALSE, array( 'sprintf' => array( $_user->name, $val ) ) );
}
return $val;
}
);
/* Root buttons */
\IPS\Output::i()->sidebar['actions']['settings'] = array(
'title' => 'prunesettings',
'icon' => 'cog',
'link' => \IPS\Http\Url::internal( 'app=chat&module=chat&controller=logs&do=settings' ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('prunesettings') )
);
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('ipschat_log_archive');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( 'title', (string) $table );
}
/**
* Clean "special" characters
*
* @param string String to clean
* @return string Cleaned string
*/
public function cleanMessage( $string )
{
$string = str_replace( "__N__" , "\n", $string );
$string = str_replace( "__C__" , ",", $string );
$string = str_replace( "__E__" , "=", $string );
$string = str_replace( "__PS__" , "+", $string );
$string = str_replace( "__A__" , "&", $string );
$string = str_replace( "__P__" , "%", $string );
return $string;
}
/**
* Settings
*
* @return void
*/
public function settings()
{
$form = new \IPS\Helpers\Form;
$form->add( new \IPS\Helpers\Form\Number( 'ipchat_log_prune', \IPS\Settings::i()->ipchat_log_prune, FALSE, array( 'unlimited' => 0, 'unlimitedLang' => 'never' ), NULL, \IPS\Member::loggedIn()->language()->addToStack('after'), \IPS\Member::loggedIn()->language()->addToStack('days') ) );
if ( $form->values() )
{
$form->saveAsSettings();
\IPS\Session::i()->log( 'acplog__chatlog_settings' );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=chat&module=chat&controller=logs' ), 'saved' );
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( 'settings', $form, FALSE );
}
}
@@ -0,0 +1,106 @@
<?php
/**
* @brief settings
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Chat
* @since 15 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\modules\admin\chat;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* settings
*/
class _settings extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'settings_manage' );
parent::execute();
}
/**
* Show the settings form
*
* @return void
*/
protected function manage()
{
$form = new \IPS\Helpers\Form;
$form->add( new \IPS\Helpers\Form\YesNo( 'ipchat_new_window', \IPS\Settings::i()->ipchat_new_window, TRUE ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'ipschat_enable_rules', \IPS\Settings::i()->ipschat_enable_rules, TRUE, array( 'togglesOn' => array( 'ipschat_rules_id' ) ) ) );
$form->add( new \IPS\Helpers\Form\Translatable( 'ipschat_rules_text', NULL, FALSE, array( 'app' => 'core', 'key' => 'ipschat_rules', 'editor' => array( 'app' => 'core', 'key' => 'Admin', 'autoSaveKey' => 'ipschat_rules', 'attachIds' => array( NULL, NULL, 'ipschat_rules' ) ) ), NULL, NULL, NULL, 'ipschat_rules_id' ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'ipchat_hide_usermessage', !\IPS\Settings::i()->ipchat_hide_usermessage, TRUE ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'ipchat_no_buffer', \IPS\Settings::i()->ipchat_no_buffer, TRUE ) );
$form->add( new \IPS\Helpers\Form\Number( 'ipchat_inactive_minutes', \IPS\Settings::i()->ipchat_inactive_minutes, TRUE, array(), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('minutes') ) );
$form->add( new \IPS\Helpers\Form\Select( 'ipchat_24hour', \IPS\Settings::i()->ipchat_24hour, TRUE, array( 'options' => array( '12' => 'chat_12hour', '24' => 'chat_24hour' ) ) ) );
if( \IPS\Settings::i()->ipschat_online )
{
$times = explode( ',', \IPS\Settings::i()->ipschat_online );
/* Do we need to adjust the time zone? */
if( isset( $times[2] ) AND $times[2] != \IPS\Member::loggedIn()->timezone )
{
$start = new \IPS\DateTime( '2015-01-01 ' . $times[0], new \DateTimeZone( $times[2] ) );
$start->setTimezone( new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) );
$times[0] = $start->format( 'H:i' );
$end = new \IPS\DateTime( '2015-01-01 ' . $times[1], new \DateTimeZone( $times[2] ) );
$end->setTimezone( new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) );
$times[1] = $end->format( 'H:i' );
}
}
else
{
$times = array( 0 => '', 1 => '' );
}
$form->add( new \IPS\Helpers\Form\Custom( 'ipschat_online', $times, FALSE, array(
'getHtml' => function( $element )
{
return \IPS\Theme::i()->getTemplate( 'settings' )->chatOnline( $element->value );
},
'formatValue' => function( $element )
{
$element->value[2] = \IPS\Member::loggedIn()->timezone;
return $element->value;
}
), NULL, NULL, NULL, 'ipschat_online' ) );
if ( $values = $form->values( TRUE ) )
{
\IPS\Lang::saveCustom( 'chat', "ipschat_rules", $values['ipschat_rules_text'] );
unset( $values['ipschat_rules_text'] );
$values['ipchat_hide_usermessage'] = !$values['ipchat_hide_usermessage'];
$form->saveAsSettings( $values );
/* Clear guest page caches */
\IPS\Data\Cache::i()->clearAll();
\IPS\Session::i()->log( 'acplogs__chat_settings' );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__chat_chat_settings');
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( 'menu__chat_chat_settings', $form );
}
}
Whitespace-only changes.
@@ -0,0 +1,246 @@
<?php
/**
* @brief Action Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Chat
* @since 23 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\modules\front\chat;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Action Controller
*/
class _action extends \IPS\Content\Controller
{
/**
* Init
*
* @return void
*/
public function execute()
{
parent::execute();
}
/**
* Add a user to the chat room
*
* @return void
* @note Forum (local) user ID is in \IPS\Request::i()->id and Chat user ID is in \IPS\Request::i()->user
*/
protected function addUser()
{
$member = \IPS\Member::load( intval( \IPS\Request::i()->id ) );
$map = array(
'user_id' => intval( \IPS\Request::i()->user ),
'forumUserID' => intval( \IPS\Request::i()->id ),
'prefix' => $member->group['prefix'],
'suffix' => $member->group['suffix'],
'photo' => $member->photo,
'username' => $member->member_id ? $member->name : $member->loggedIn()->language()->get('guest'),
'formattedUsername' => \IPS\Member\Group::load( $member->member_group_id )->formatName( $member->name ),
'canBeIgnored' => $member->member_id ? !$member->group['gbw_cannot_be_ignored'] : 1,
'canBypassBadwords' => $member->group['g_bypass_badwords'],
'groupID' => $member->member_group_id,
'profileUrl' => $member->url(),
'canModerate' => $member->group['chat_moderate'],
'seo_name' => $member->members_seo_name,
'last_update' => time(),
);
/* Update the chatters list */
$chatters = ( isset( \IPS\Data\Store::i()->chatters ) ) ? \IPS\Data\Store::i()->chatters : array();
$chatters[ $map['user_id'] ] = $map;
\IPS\Data\Store::i()->chatters = $chatters;
/* Output */
\IPS\Output::i()->json( array(
'html' => \IPS\Theme::i()->getTemplate( 'view' )->userRow( $map ),
'user' => $map
) );
}
/**
* Load user info
*
* @return void
* @note Forum (local) user ID is in \IPS\Request::i()->id
*/
protected function loadUserInfo()
{
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'view', 'chat' )->userInfo( \IPS\Member::load( intval( \IPS\Request::i()->id ) ) ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
}
/**
* Ignore and unignore chats
*
* @return void
* @note Forum (local) user ID is in \IPS\Request::i()->id
*/
protected function blockUser()
{
/* Make sure there is an ID */
if( !\IPS\Request::i()->id )
{
\IPS\Output::i()->json( 'OK' );
}
/* Make sure we can ignore this user */
$user = \IPS\Member::load( \IPS\Request::i()->id );
if( $user->group['gbw_cannot_be_ignored'] )
{
\IPS\Output::i()->error( 'ipschat_no_ignore', '3H269/K', 403, '' );
}
/* Update or insert the ignore */
try
{
$existing = \IPS\Db::i()->select( '*', 'core_ignored_users', array( 'ignore_owner_id=? AND ignore_ignore_id=?', \IPS\Member::loggedIn()->member_id, \IPS\Request::i()->id ) )->first();
\IPS\Db::i()->update( 'core_ignored_users', array( 'ignore_chats' => $existing['ignore_chats'] ? 0 : 1 ), array( 'ignore_id=?', $existing['ignore_id'] ) );
}
catch( \UnderflowException $e )
{
\IPS\Db::i()->insert( 'core_ignored_users', array(
'ignore_owner_id' => \IPS\Member::loggedIn()->member_id,
'ignore_ignore_id' => intval( \IPS\Request::i()->id ),
'ignore_chats' => 1
) );
}
\IPS\Output::i()->json( 'OK' );
}
/**
* Ban user
*
* @return void
* @note Forum (local) user ID is in \IPS\Request::i()->id
*/
protected function banUser()
{
/* Make sure there is an ID */
if( !\IPS\Request::i()->id )
{
\IPS\Output::i()->json( 'OK' );
}
/* Make sure we can moderate */
if( !\IPS\Member::loggedIn()->group['chat_moderate'] )
{
\IPS\Output::i()->error( 'ipschat_no_ban', '3H269/L', 403, '' );
}
/* Ban the user */
$user = \IPS\Member::load( \IPS\Request::i()->id );
$user->chat_banned = 1;
$user->save();
/* Remove us from chatters list */
$chatters = ( isset( \IPS\Data\Store::i()->chatters ) ) ? \IPS\Data\Store::i()->chatters : array();
foreach( $chatters as $uid => $chatter )
{
if( $chatter['forumUserID'] == $user->member_id )
{
unset( $chatters[ $uid ] );
}
}
\IPS\Data\Store::i()->chatters = $chatters;
\IPS\Output::i()->json( 'OK' );
}
/**
* Ping to keep us in chatters list
*
* @return void
* @note Forum (local) user ID is in \IPS\Request::i()->id
*/
protected function ping()
{
/* Make sure there is an ID */
if( !\IPS\Request::i()->id )
{
\IPS\Output::i()->json( 'OK' );
}
/* If the data store doesn't exist it was wiped, so recreate it */
if( !isset( \IPS\Data\Store::i()->chatters ) )
{
$chatters = array();
$options = $_SESSION['chatOptions'];
$result = \IPS\Http\Url::external( "http://{$options['serverHost']}{$options['serverPath']}/list.php?room={$options['roomId']}&user={$options['userId']}&access_key={$options['accessKey']}" )->request()->get();
if( $result )
{
$results = explode( "~~||~~", $result );
$status = array_shift( $results );
if( $status == 1 )
{
foreach( $results as $k => $v )
{
$_thisRecord = explode( ',', $v );
if( !$_thisRecord[0] )
{
continue;
}
$member = \IPS\Member::load( intval( $_thisRecord[2] ) );
$username = str_replace( '~~#~~', ',', $_thisRecord[1] );
$chatters[ $_thisRecord[0] ] = array(
'user_id' => $_thisRecord[0],
'username' => htmlspecialchars( $username, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
'forumUserID' => $member->member_id,
'canBeIgnored' => $member->member_id ? !$member->group['gbw_cannot_be_ignored'] : 1,
'canBypassBadwords' => $member->group['g_bypass_badwords'],
'groupID' => $member->member_group_id,
'prefix' => str_replace( '"', '__DBQ__', $member->group['prefix'] ),
'suffix' => str_replace( '"', '__DBQ__', $member->group['suffix'] ),
'photo' => $member->photo,
'profileUrl' => $member->url(),
'canModerate' => $member->group['chat_moderate'],
'seo_name' => $member->members_seo_name,
'last_update' => time(),
);
}
}
}
}
else
{
$chatters = \IPS\Data\Store::i()->chatters;
}
/* Update us in chatters list - session will be auto-handled */
if( isset( $chatters[ \IPS\Request::i()->id ] ) )
{
$chatters[ \IPS\Request::i()->id ]['last_update'] = time();
\IPS\Data\Store::i()->chatters = $chatters;
}
/* Return a response */
\IPS\Output::i()->json( 'OK' );
}
}
Whitespace-only changes.
@@ -0,0 +1,481 @@
<?php
/**
* @brief View File Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Chat
* @since 10 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\modules\front\chat;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* View File Controller
*/
class _view extends \IPS\Content\Controller
{
/**
* @brief Master chat server URL
*/
const MASTERSERVER = "http://chatservice.ipsdns.com/";
/**
* Init
*
* @return void
*/
public function execute()
{
/* Check that the license allows access, etc. */
$licenseData = \IPS\IPS::licenseKey();
if( !$licenseData )
{
\IPS\Output::i()->error( 'ipschat_no_license', '4H268/1', 500, 'ipschat_no_license_admin' );
}
if( !isset( $licenseData['chat_limit'] ) OR $licenseData['chat_limit'] < 1 )
{
\IPS\Output::i()->error( 'ipschat_no_license', '4H269/1', 500, 'ipschat_no_license_access' );
}
/* Group access check */
if( !\IPS\Member::loggedIn()->group['chat_access'] )
{
\IPS\Output::i()->error( 'ipschat_no_group_access', '2H269/2', 403, '' );
}
/* Is this a guest that was blocked? */
if( !\IPS\Member::loggedIn()->member_id AND isset( \IPS\Request::i()->cookie['chat_blocked'] ) AND \IPS\Request::i()->cookie['chat_blocked'] )
{
\IPS\Output::i()->error( 'ipschat_no_access', '2H269/3', 403, '' );
}
/* Or a member? */
if( \IPS\Member::loggedIn()->chat_banned )
{
\IPS\Output::i()->error( 'ipschat_no_access', '2H269/5', 403, '' );
}
/* Spiders also do not have access */
if( \IPS\Session\Front::i()->userAgent->spider )
{
\IPS\Output::i()->error( 'ipschat_no_access', '2H269/4', 403, '' );
}
/* Figure out if chat is online due to time restrictions */
if( \IPS\Settings::i()->ipschat_online )
{
$times = explode( ',', \IPS\Settings::i()->ipschat_online );
if( count( $times ) AND $times[0] )
{
/* Do we need to adjust the time zone? */
if( isset( $times[2] ) AND $times[2] != \IPS\Member::loggedIn()->timezone )
{
$start = new \IPS\DateTime( '2015-01-01 ' . $times[0], new \DateTimeZone( $times[2] ) );
$start->setTimezone( new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) );
$times[0] = $start->format( 'H:i' );
$end = new \IPS\DateTime( '2015-01-01 ' . $times[1], new \DateTimeZone( $times[2] ) );
$end->setTimezone( new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) );
$times[1] = $end->format( 'H:i' );
}
$currentTime = new \IPS\DateTime( NULL, new \DateTimeZone( ( isset( $times[2] ) ) ? $times[2] : \IPS\Member::loggedIn()->timezone ) );
$currentTime->setTimezone( new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) );
$currentTime = $currentTime->format( 'H:i' );
/* Convert times to floats, as that is simple to compare */
$start = str_replace( ':', '.', $times[0] );
$end = str_replace( ':', '.', $times[1] );
$currentTime = str_replace( ':', '.', $currentTime );
if( $end > $start )
{
if( !( $currentTime >= $start ) OR !( $currentTime < $end ) )
{
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'chat_currently_offline', FALSE, array( 'sprintf' => $start ) ), '1H269/I', 403, 'chat_offline_admin' );
}
}
else
{
if( !( $currentTime >= $start ) AND $currentTime >= $end )
{
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'chat_currently_offline', FALSE, array( 'sprintf' => $start ) ), '1H269/J', 403, 'chat_offline_admin' );
}
}
}
}
parent::execute();
}
/**
* View Chat
*
* @return void
*/
protected function manage()
{
/* Initiate output */
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'jquery/jquery.rangyinputs.js', 'core', 'interface' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'buzz/buzz.min.js', 'chat', 'interface' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'esrever/esrever.js', 'chat', 'interface' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_chat.js', 'chat', 'front' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'chat.css', 'chat', 'front' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'chat_responsive.css', 'chat', 'front' ) );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'chat_title' );
/* Check rules */
if( \IPS\Settings::i()->ipschat_enable_rules )
{
$proceed = FALSE;
$form = new \IPS\Helpers\Form( 'chat_rules', 'accept_rules' );
$form->class = 'ipsForm_vertical';
$form->hiddenValues['proceed'] = TRUE;
if( $values = $form->values() )
{
if( $values['proceed'] )
{
$proceed = TRUE;
}
}
/* If we haven't agreed yet, show the form */
if( !$proceed )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->acceptRules( $form );
return;
}
}
/* Initiate our options */
$options = array(
'roomId' => 0,
'userId' => 0,
'userName' => $this->cleanUsername( \IPS\Member::loggedIn()->member_id ? \IPS\Member::loggedIn()->name : \IPS\Member::loggedIn()->language()->get('guest') ),
'accessKey' => '',
'serverHost' => '',
'serverPath' => '',
);
/* Call master to retrieve info */
try
{
$result = \IPS\Http\Url::external( self::MASTERSERVER . "gateway31.php?api_key=" . \IPS\Settings::i()->ipb_reg_number . "&user={$options['userName']}&level=" . \IPS\Member::loggedIn()->group['chat_moderate'] )->request()->get();
}
catch ( \IPS\Http\Request\Exception $e )
{
\IPS\Output::i()->error( 'generic_chatconnect_error', '4H268/2', 500, 'connect_gw_error_0' );
}
$results = explode( ',', $result );
/* Error? */
if( $results[0] == 0 )
{
switch( $results[1] )
{
// No license key
case 1:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H269/7', 500, 'connect_gw_error_1' );
break;
// No username
case 2:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H269/8', 500, 'connect_gw_error_2' );
break;
// MySQL error
case 3:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H268/3', 500, 'connect_gw_error_3' );
break;
// Invalid room ID
case 5:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H269/A', 500, 'connect_gw_error_5' );
break;
// Chat room full
case 6:
$key = \IPS\IPS::licenseKey();
\IPS\Output::i()->error( 'chat_room_full', ( $key['chat_limit'] ? '1' : '4' ) . 'H269/B', 403, $key['chat_limit'] ? 'license_no_chat' : NULL );
break;
// Chat room full
case 7:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H269/A', 500, 'connect_gw_error_5' );
break;
// The chat room is on a server which is no longer online
case 8:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H268/4', 500, 'connect_gw_error_8' );
break;
// No online chat servers could be found
case 10:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H268/5', 500, 'connect_gw_error_10' );
break;
// Other
default:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H269/6', 500 );
break;
}
}
/* Set the options we just got from the master chat server */
$options['roomId'] = intval($results[3]);
$options['serverHost'] = $results[1];
$options['serverPath'] = $results[2];
/* If this is a guest, adjust the URL to send an identifier */
$guestFlag = ( !\IPS\Member::loggedIn()->member_id and isset( \IPS\Request::i()->cookie['chat_user_id'] ) ) ? "&userid=" . intval( \IPS\Request::i()->cookie['chat_user_id'] ) : '';
/* Now join the actual chat room */
try
{
$result = \IPS\Http\Url::external( "http://{$options['serverHost']}{$options['serverPath']}/join31.php?api_key=" . \IPS\Settings::i()->ipb_reg_number . "&user={$options['userName']}&level=" . \IPS\Member::loggedIn()->group['chat_moderate'] . "&room={$options['roomId']}&forumid=" . \IPS\Member::loggedIn()->member_id . "{$guestFlag}&forumgroup=" . \IPS\Member::loggedIn()->member_group_id )->request()->get();
}
catch ( \IPS\Http\Request\Exception $e )
{
\IPS\Output::i()->error( 'generic_chatconnect_error', '4H268/2', 500, 'connect_gw_error_0' );
}
$results = explode( ',', $result );
/* Error? */
if( $results[0] == 0 )
{
switch( $results[1] )
{
// No license key
case 1:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H269/C', 500, 'connect_gw_error_1' );
break;
// No username
case 2:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H269/D', 500, 'connect_gw_error_2' );
break;
// No room ID
case 3:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H269/E', 500, 'connect_gw_error_3' );
break;
// MySQL error
case 4:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H269/E', 500, 'connect_gw_error_4' );
break;
// Could not create room
case 5:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H269/F', 500, 'connect_gw_error_5' );
break;
// License key mismatch
case 6:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H269/G', 500, 'connect_gw_error_6' );
break;
// Chat room full
case 7:
$key = \IPS\IPS::licenseKey();
\IPS\Output::i()->error( 'chat_room_full', ( $key['chat_limit'] ? '1' : '4' ) . 'H269/H', 500, $key['chat_limit'] ? 'license_no_chat' : NULL );
break;
// Other
default:
\IPS\Output::i()->error( 'generic_chatconnect_error', '5H268/6', 500, 'connect_gw_error_0' );
break;
}
}
/* Remember the important parts of this response */
$options['userId'] = $results[1];
$options['accessKey'] = $results[2];
/* If this is a guest, set the chat user ID cookie */
if( !\IPS\Member::loggedIn()->member_id )
{
\IPS\Request::i()->setCookie( 'chat_user_id', $options['userId'], NULL, FALSE );
}
/* Fetch the online users list and build the map */
$chatters = array();
$result = \IPS\Http\Url::external( "http://{$options['serverHost']}{$options['serverPath']}/list.php?room={$options['roomId']}&user={$options['userId']}&access_key={$options['accessKey']}" )->request()->get();
if( $result )
{
$results = explode( "~~||~~", $result );
$status = array_shift( $results );
if( $status == 1 )
{
foreach( $results as $k => $v )
{
$_thisRecord = explode( ',', $v );
if( !$_thisRecord[0] )
{
continue;
}
$member = \IPS\Member::load( intval( $_thisRecord[2] ) );
$username = str_replace( '~~#~~', ',', $_thisRecord[1] );
$chatters[ $username ] = array(
'user_id' => $_thisRecord[0],
'username' => htmlspecialchars( $username, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
'formattedUsername' => \IPS\Member\Group::load( $member->member_group_id )->formatName( $member->name ),
'forumUserID' => $member->member_id,
'canBeIgnored' => $member->member_id ? !$member->group['gbw_cannot_be_ignored'] : 1,
'canBypassBadwords' => $member->group['g_bypass_badwords'],
'groupID' => $member->member_group_id,
'prefix' => str_replace( '"', '__DBQ__', $member->group['prefix'] ),
'suffix' => str_replace( '"', '__DBQ__', $member->group['suffix'] ),
'photo' => $member->photo,
'profileUrl' => $member->url(),
'canModerate' => $member->group['chat_moderate'],
'seo_name' => $member->members_seo_name,
'last_update' => time(),
);
}
}
}
ksort($chatters);
$forumIdMap = array();
foreach( $chatters as $chatter )
{
$forumIdMap[ $chatter['user_id'] ] = $chatter;
}
/* Update the chatters list */
if( count( $chatters ) )
{
\IPS\Data\Store::i()->chatters = $forumIdMap;
}
/* Get badwords list */
$badwords = iterator_to_array( \IPS\Db::i()->select( 'm_exact, swop, type', 'core_profanity_filters' )->setKeyField( 'type' ) );
/* Get groups */
$groups = array();
foreach( \IPS\Member\Group::groups() as $group )
{
$groups[ $group->g_id ] = array( 'prefix' => $group->prefix, 'suffix' => $group->suffix, 'bypassBadwords' => $group->g_bypass_badwords );
}
/* Are we ignoring any chats? */
if( \IPS\Member::loggedIn()->member_id )
{
$ignored = iterator_to_array( \IPS\Db::i()->select( 'ignore_ignore_id, ignore_id', 'core_ignored_users', array( 'ignore_owner_id=? and ignore_chats=1', \IPS\Member::loggedIn()->member_id ) )->setKeyField( 'ignore_ignore_id' )->setValueField( 'ignore_id' ) );
}
else
{
$ignored = array();
}
/* Emoticons */
$emoticons = array();
foreach ( \IPS\Db::i()->select( '*', 'core_emoticons', NULL, 'emo_set,emo_position' ) as $row )
{
$emoticons[ $row['typed'] ] = (string) \IPS\File::get( 'core_Emoticons', $row['image'] )->url;
}
/* We store the chat options in our session in case we choose to leave the room */
$_SESSION['chatOptions'] = $options;
/* Display */
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->chat( $forumIdMap );
\IPS\Output::i()->endBodyCode .= \IPS\Theme::i()->getTemplate( 'view' )->chatvars( $options, $forumIdMap, $groups, $badwords, $ignored, $emoticons );
}
/**
* Leave Chat
*
* @return void
*/
protected function leave()
{
/* Check secure key */
\IPS\Session::i()->csrfCheck();
/* Call server */
if( isset( $_SESSION['chatOptions'] ) )
{
$options = $_SESSION['chatOptions'];
\IPS\Http\Url::external( "http://{$options['serverHost']}{$options['serverPath']}/leave.php?room={$options['roomId']}&user={$options['userId']}&access_key={$options['accessKey']}" )->request()->get();
unset( $_SESSION['chatOptions'] );
}
/* Remove us from chatters list */
$chatters = ( isset( \IPS\Data\Store::i()->chatters ) ) ? \IPS\Data\Store::i()->chatters : array();
foreach( $chatters as $uid => $chatter )
{
if( $chatter['forumUserID'] == \IPS\Member::loggedIn()->member_id )
{
unset( $chatters[ $uid ] );
}
}
\IPS\Data\Store::i()->chatters = $chatters;
// If this is a popup, close it, otherwise send us back to the suite index
if( \IPS\Request::i()->_popup == 1 )
{
\IPS\Output::i()->output = "<script type='text/javascript'>window.close();</script>";
}
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "_leaveChat=1" ), 'leave_chat_room' );
}
}
/**
* Clean username for chat
*
* @param string Username
* @return string
*/
protected function cleanUsername( $username )
{
$username = str_replace( "\r", '', $username );
$username = str_replace( "\n", '__N__', $username );
$username = str_replace( ",", '__C__', $username );
$username = str_replace( "=", '__E__', $username );
$username = str_replace( "+", '__PS__', $username );
$username = str_replace( "&", '__A__', $username );
$username = str_replace( "%", '__P__', $username );
$username = urlencode($username);
return $username;
}
}
Whitespace-only changes.
Whitespace-only changes.
View File
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,62 @@
{
"1": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "chat_access",
"type": "TINYINT",
"length": 10,
"null": false,
"default": 0,
"comment": "Can access chat?",
"unsigned": true
}
]
},
"2": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "chat_moderate",
"type": "TINYINT",
"length": 10,
"null": false,
"default": 0,
"comment": "Can moderate chat?",
"unsigned": true
}
]
},
"3": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "chat_private",
"type": "TINYINT",
"length": 10,
"null": false,
"default": 0,
"comment": "Can send private chats?",
"unsigned": true
}
]
},
"4": {
"method": "addColumn",
"params": [
"core_members",
{
"name": "chat_banned",
"type": "TINYINT",
"length": 1,
"null": false,
"default": 0,
"comment": "",
"unsigned": true
}
]
}
}
Whitespace-only changes.
@@ -0,0 +1,63 @@
{
"1": {
"method": "addIndex",
"params": [
"chat_log_archive",
{
"type": "key",
"name": "log_time",
"columns": [
"log_time"
],
"length": [
null
]
}
]
},
"2": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "chat_access",
"type": "TINYINT",
"length": 10,
"null": false,
"default": 0,
"comment": "Can access chat?",
"unsigned": true
}
]
},
"3": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "chat_moderate",
"type": "TINYINT",
"length": 10,
"null": false,
"default": 0,
"comment": "Can moderate chat?",
"unsigned": true
}
]
},
"4": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "chat_private",
"type": "TINYINT",
"length": 10,
"null": false,
"default": 0,
"comment": "Can send private chats?",
"unsigned": true
}
]
}
}
@@ -0,0 +1,81 @@
<?php
/**
* @brief 4.0.0 Upgrade Code
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 15 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\setup\upg_100021;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.0.0 RC 5 Upgrade Code
*/
class _Upgrade
{
/**
* Step 1
* Rebuild reputation received
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
/* Set access permission */
if( \IPS\Settings::i()->ipschat_group_access )
{
\IPS\Db::i()->update( 'core_groups', array( 'chat_access' => 1 ), 'g_id IN(' . \IPS\Settings::i()->ipschat_group_access . ')' );
}
else
{
\IPS\Db::i()->update( 'core_groups', array( 'chat_access' => 1 ) );
}
if( \IPS\Settings::i()->ipschat_mods )
{
\IPS\Db::i()->update( 'core_groups', array( 'chat_moderate' => 1 ), 'g_id IN(' . \IPS\Settings::i()->ipschat_mods . ')' );
}
if( \IPS\Settings::i()->ipschat_private )
{
\IPS\Db::i()->update( 'core_groups', array( 'chat_private' => 1 ), 'g_id IN(' . \IPS\Settings::i()->ipschat_private . ')' );
}
/* Add rules text */
\IPS\Lang::saveCustom( 'core', "ipschat_rules", html_entity_decode( \IPS\Settings::i()->ipschat_rules, ENT_QUOTES, 'UTF-8' ) );
/* Add online/offline start value */
\IPS\Db::i()->replace( 'core_sys_conf_settings', array(
'conf_key' => 'ipschat_online',
'conf_default' => '',
'conf_value' => implode( ',', array( 0 => \IPS\Settings::i()->ipschat_online_start, 1 => \IPS\Settings::i()->ipschat_online_end ) ),
'conf_app' => 'chat',
) );
/* Remove old settings */
\IPS\Db::i()->delete( 'core_sys_conf_settings', "conf_key IN ('ipschat_group_access', 'ipschat_mods', 'ipschat_private', 'ipschat_online',
'ipschat_account_key', 'ipchat_htc_zero', 'ipchat_max_messages', 'ipschat_offline_msg', 'ipschat_offline_groups', 'ipschat_hide_chatting',
'ipschat_whos_chatting', 'ipchat_htc_view', 'ipschat_format_names', 'ipschat_online_start', 'ipschat_online_end', 'ipschat_rules')" );
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return "Converting and cleaning up settings";
}
}
Whitespace-only changes.
@@ -0,0 +1,13 @@
<?php
$SQL = array();
$SQL[] = "CREATE TABLE chat_log_archive (
log_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
log_room_id INT NOT NULL DEFAULT '0',
log_time INT NOT NULL DEFAULT '0',
log_code SMALLINT NOT NULL DEFAULT '0',
log_user VARCHAR( 255 ) NULL DEFAULT NULL ,
log_message TEXT NULL DEFAULT NULL ,
log_extra VARCHAR( 255 ) NULL DEFAULT NULL
) ENGINE = MYISAM;";
@@ -0,0 +1,38 @@
<?php
/**
* @brief 4.0.0 Upgrade Code
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Chat
* @since 15 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\setup\upg_11005;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.0.0 Upgrade Code
*/
class _Upgrade
{
/**
* Conversion from 3.0
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
\IPS\core\Setup\Upgrade::runLegacySql( 'chat', 11005 );
return TRUE;
}
}
Whitespace-only changes.
@@ -0,0 +1,38 @@
<?php
/**
* @brief 4.0.0 Upgrade Code
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Chat
* @since 15 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\setup\upg_13000;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.0.0 Upgrade Code
*/
class _Upgrade
{
/**
* Conversion from 3.0
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
// Ignored users conversion
return TRUE;
}
}
Whitespace-only changes.
@@ -0,0 +1 @@
[]
Whitespace-only changes.
+61
View File
@@ -0,0 +1,61 @@
<?php
/**
* @brief chatlogprune Task
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage chat
* @since 15 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\tasks;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* chatlogprune Task
*/
class _chatlogprune extends \IPS\Task
{
/**
* Execute
*
* If ran successfully, should return anything worth logging. Only log something
* worth mentioning (don't log "task ran successfully"). Return NULL (actual NULL, not '' or 0) to not log (which will be most cases).
* If an error occurs which means the task could not finish running, throw an \IPS\Task\Exception - do not log an error as a normal log.
* Tasks should execute within the time of a normal HTTP request.
*
* @return mixed Message to log or NULL
* @throws \IPS\Task\Exception
*/
public function execute()
{
if( \IPS\Settings::i()->ipchat_log_prune )
{
\IPS\DB::i()->delete( 'chat_log_archive', array( 'log_time < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->ipchat_log_prune . 'D' ) )->getTimestamp() ) );
}
return NULL;
}
/**
* Cleanup
*
* If your task takes longer than 15 minutes to run, this method
* will be called before execute(). Use it to clean up anything which
* may not have been done
*
* @return void
*/
public function cleanup()
{
}
}
+103
View File
@@ -0,0 +1,103 @@
<?php
/**
* @brief chatlogrefresh Task
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage chat
* @since 15 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\tasks;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* chatlogrefresh Task
*/
class _chatlogrefresh extends \IPS\Task
{
/**
* Execute
*
* If ran successfully, should return anything worth logging. Only log something
* worth mentioning (don't log "task ran successfully"). Return NULL (actual NULL, not '' or 0) to not log (which will be most cases).
* If an error occurs which means the task could not finish running, throw an \IPS\Task\Exception - do not log an error as a normal log.
* Tasks should execute within the time of a normal HTTP request.
*
* @return mixed Message to log or NULL
* @throws \IPS\Task\Exception
*/
public function execute()
{
if ( !\IPS\Settings::i()->ipb_reg_number )
{
throw new \IPS\Task\Exception( $this, 'ipschat_no_license_admin' );
}
/* Get last log time */
$max = \IPS\Db::i()->select( 'MAX(log_time)', 'chat_log_archive' )->first();
/* Fetch logs */
try
{
$result = \IPS\Http\Url::external( \IPS\chat\modules\front\chat\view::MASTERSERVER . "get_logs.php?api_key=" . \IPS\Settings::i()->ipb_reg_number . "&timestamp=" . $max )->request()->get();
}
catch( \IPS\Http\Request\Exception $e )
{
throw new \IPS\Task\Exception( $this, $e->getMessage() );
}
$results = explode( ',', $result );
$status = array_shift( $results );
if( $status == 0 )
{
throw new \IPS\Task\Exception( $this, 'connect_gw_error_' . $results[0] );
}
foreach( $results as $k => $v )
{
$_thisResult = explode( "~~||~~", $v );
if( !isset( $_thisResult[1] ) OR !$_thisResult[1] )
{
continue;
}
$_insert = array(
'log_room_id' => $_thisResult[1],
'log_time' => $_thisResult[2],
'log_code' => $_thisResult[3],
'log_user' => $_thisResult[4],
'log_message' => $_thisResult[5],
'log_extra' => $_thisResult[6],
);
\IPS\Db::i()->insert( "chat_log_archive", $_insert );
}
return NULL;
}
/**
* Cleanup
*
* If your task takes longer than 15 minutes to run, this method
* will be called before execute(). Use it to clean up anything which
* may not have been done
*
* @return void
*/
public function cleanup()
{
}
}
View File
Whitespace-only changes.
@@ -0,0 +1,78 @@
<?php
/**
* @brief chatwhoschatting Widget
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage chat
* @since 15 Mar 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\chat\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* chatwhoschatting Widget
*/
class _chatwhoschatting extends \IPS\Widget\StaticCache
{
/**
* @brief Widget Key
*/
public $key = 'chatwhoschatting';
/**
* @brief App
*/
public $app = 'chat';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Render a widget
*
* @return string
*/
public function render()
{
if( !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'chat', 'chat' ) ) )
{
return '';
}
$chatters = ( isset( \IPS\Data\Store::i()->chatters ) ) ? \IPS\Data\Store::i()->chatters : array();
/* It's possible to get duplicates from the chat server if a user rejoins the room, so weed them out */
$seen = array();
foreach( $chatters as $uid => $chatter )
{
/* Have we already seen this? Remove duplicates */
if( in_array( $chatter['forumUserID'], $seen ) )
{
unset( $chatters[ $uid ] );
}
/* If the last update was longer than 120 seconds ago, they're gone */
if( $chatter['last_update'] < time() - 120 )
{
unset( $chatters[ $uid ] );
}
$seen[ $chatter['forumUserID'] ] = $chatter['forumUserID'];
}
return $this->output( $chatters );
}
}
Whitespace-only changes.