mirror of
				https://github.com/Mibew/i18n.git
				synced 2025-11-01 01:36:57 +03:00 
			
		
		
		
	Update plugins message system.
Now arbitrary data can be attached to any message.
This commit is contained in:
		
							parent
							
								
									aa38622b8d
								
							
						
					
					
						commit
						fb6517dc9f
					
				| @ -202,6 +202,7 @@ class ThreadTest extends PHPUnit_Framework_TestCase { | ||||
| 
 | ||||
| 			'lrevision' => 189, | ||||
| 			'istate' => Thread::STATE_QUEUE, | ||||
| 			'invitationstate' => Thread::INVITATION_NOT_INVITED, | ||||
| 			'ltoken' => 19908, | ||||
| 
 | ||||
| 			'nextagent' => 0, | ||||
| @ -574,15 +575,19 @@ class ThreadTest extends PHPUnit_Framework_TestCase { | ||||
| 			'agentId' => 12, | ||||
| 			'tmessage' => 'New message text', | ||||
| 			'dtmcreated' => time(), | ||||
| 			'tname' => 'Sender name' | ||||
| 			'tname' => 'Sender name', | ||||
| 			'plugin' => '', | ||||
| 			'data' => array() | ||||
| 		); | ||||
| 
 | ||||
| 		$message['messageid'] = $thread->postMessage( | ||||
| 			$message['ikind'], | ||||
| 			$message['tmessage'], | ||||
| 			$message['tname'], | ||||
| 			$message['agentId'], | ||||
| 			$message['dtmcreated'] | ||||
| 			array( | ||||
| 				'name' => $message['tname'], | ||||
| 				'operator_id' => $message['agentId'], | ||||
| 				'created' => $message['dtmcreated'] | ||||
| 			) | ||||
| 		); | ||||
| 		// Load message info from database
 | ||||
| 		$msg_info = $db->query( | ||||
| @ -590,6 +595,8 @@ class ThreadTest extends PHPUnit_Framework_TestCase { | ||||
| 			array($message['messageid']), | ||||
| 			array('return_rows' => Database::RETURN_ONE_ROW) | ||||
| 		); | ||||
| 		$msg_info['data'] = unserialize($msg_info['data']); | ||||
| 
 | ||||
| 		// Check values
 | ||||
| 		$this->assertEquals($message, $msg_info); | ||||
| 
 | ||||
| @ -613,21 +620,27 @@ class ThreadTest extends PHPUnit_Framework_TestCase { | ||||
| 			'kind' => Thread::KIND_USER, | ||||
| 			'message' => 'The first message', | ||||
| 			'created' => time(), | ||||
| 			'name' => 'System message only for agent' | ||||
| 			'name' => 'System message only for agent', | ||||
| 			'plugin' => 'f_test_plg', | ||||
| 			'data' => array('msg_num' => 1) | ||||
| 		); | ||||
| 		// The second
 | ||||
| 		$second_message = array( | ||||
| 			'kind' => Thread::KIND_AGENT, | ||||
| 			'message' => 'The second message', | ||||
| 			'created' => time(), | ||||
| 			'name' => 'User' | ||||
| 			'name' => 'User', | ||||
| 			'plugin' => 'f_test_plg', | ||||
| 			'data' => array('msg_num' => 1) | ||||
| 		); | ||||
| 		// The third
 | ||||
| 		$third_message = array( | ||||
| 			'kind' => Thread::KIND_FOR_AGENT, | ||||
| 			'message' => 'The third message', | ||||
| 			'created' => time(), | ||||
| 			'name' => 'Agent' | ||||
| 			'name' => 'Agent', | ||||
| 			'plugin' => 'f_test_plg', | ||||
| 			'data' => array('msg_num' => 1) | ||||
| 		); | ||||
| 
 | ||||
| 		// Send messages
 | ||||
| @ -635,25 +648,37 @@ class ThreadTest extends PHPUnit_Framework_TestCase { | ||||
| 		$first_message['id'] = $thread->postMessage( | ||||
| 			$first_message['kind'], | ||||
| 			$first_message['message'], | ||||
| 			$first_message['name'], | ||||
| 			12, | ||||
| 			$first_message['created'] | ||||
| 			array( | ||||
| 				'name' => $first_message['name'], | ||||
| 				'operator_id' => 12, | ||||
| 				'created' => $first_message['created'], | ||||
| 				'plugin' => $second_message['plugin'], | ||||
| 				'data' => $second_message['data'] | ||||
| 			) | ||||
| 		); | ||||
| 		// The second
 | ||||
| 		$second_message['id'] = $thread->postMessage( | ||||
| 			$second_message['kind'], | ||||
| 			$second_message['message'], | ||||
| 			$second_message['name'], | ||||
| 			14, | ||||
| 			$second_message['created'] | ||||
| 			array( | ||||
| 				'name' => $second_message['name'], | ||||
| 				'operator_id' => 14, | ||||
| 				'created' => $second_message['created'], | ||||
| 				'plugin' => $second_message['plugin'], | ||||
| 				'data' => $second_message['data'] | ||||
| 			) | ||||
| 		); | ||||
| 		// The third
 | ||||
| 		$third_message['id'] = $thread->postMessage( | ||||
| 			$third_message['kind'], | ||||
| 			$third_message['message'], | ||||
| 			$third_message['name'], | ||||
| 			16, | ||||
| 			$third_message['created'] | ||||
| 			array( | ||||
| 				'name' => $third_message['name'], | ||||
| 				'operator_id' => 16, | ||||
| 				'created' => $third_message['created'], | ||||
| 				'plugin' => $second_message['plugin'], | ||||
| 				'data' => $second_message['data'] | ||||
| 			) | ||||
| 		); | ||||
| 
 | ||||
| 		// Check messages for agent with ids starts from $msg_id
 | ||||
|  | ||||
| @ -127,6 +127,11 @@ $dbtables = array( | ||||
| 		"agentId" => "int NOT NULL DEFAULT 0", | ||||
| 		// Message text body.
 | ||||
| 		"tmessage" => "text NOT NULL", | ||||
| 		// Name of the plugin which sent the message. If message was not sent by
 | ||||
| 		// a plugin this field equals to an empty string.
 | ||||
| 		"plugin" => "varchar(256) NOT NULL DEFAULT ''", | ||||
| 		// Arbitrary serialized data related with message.
 | ||||
| 		"data" => "text", | ||||
| 		// Unix timestamp when message was created.
 | ||||
| 		"dtmcreated" => "int NOT NULL DEFAULT 0", | ||||
| 		// Name of the message sender.
 | ||||
| @ -266,7 +271,7 @@ $dbtables_can_update = array( | ||||
| 	"${mysqlprefix}chatthread" => array("agentId", "userTyping", "agentTyping", "messageCount", "nextagent", "shownmessageid", "userid", "userAgent", "groupid", "dtmchatstarted", "invitationstate"), | ||||
| 	"${mysqlprefix}chatthreadstatistics" => array("missedthreads", "sentinvitations", "acceptedinvitations", "rejectedinvitations", "ignoredinvitations"), | ||||
| 	"${mysqlprefix}requestbuffer" => array("requestid", "requestkey", "request"), | ||||
| 	"${mysqlprefix}chatmessage" => array("agentId"), | ||||
| 	"${mysqlprefix}chatmessage" => array("agentId", "plugin", "data"), | ||||
| 	"${mysqlprefix}chatoperator" => array("vcavatar", "vcjabbername", "iperm", "istatus", "idisabled", "vcemail", "dtmrestore", "vcrestoretoken", "code"), | ||||
| 	"${mysqlprefix}chatoperatorstatistics" => array("sentinvitations", "acceptedinvitations", "rejectedinvitations", "ignoredinvitations"), | ||||
| 	"${mysqlprefix}chatban" => array(), | ||||
|  | ||||
| @ -91,6 +91,14 @@ if ($act == "silentcreateall") { | ||||
| 			runsql("update ${mysqlprefix}chatmessage, ${mysqlprefix}chatoperator set agentId = operatorid where agentId = 0 AND ikind = 2 AND (vclocalename = tname OR vccommonname = tname)", $link); | ||||
| 		} | ||||
| 
 | ||||
| 		if (in_array("${mysqlprefix}chatmessage.plugin", $absent_columns)) { | ||||
| 			runsql("ALTER TABLE ${mysqlprefix}chatmessage ADD plugin varchar(256) NOT NULL DEFAULT '' AFTER tmessage", $link); | ||||
| 		} | ||||
| 
 | ||||
| 		if (in_array("${mysqlprefix}chatmessage.data", $absent_columns)) { | ||||
| 			runsql("ALTER TABLE ${mysqlprefix}chatmessage ADD data text AFTER plugin", $link); | ||||
| 		} | ||||
| 
 | ||||
| 		if (in_array("${mysqlprefix}chatthread.agentId", $absent_columns)) { | ||||
| 			runsql("ALTER TABLE ${mysqlprefix}chatthread ADD agentId int NOT NULL DEFAULT 0 AFTER agentName", $link); | ||||
| 			runsql("update ${mysqlprefix}chatthread, ${mysqlprefix}chatoperator set agentId = operatorid where agentId = 0 AND (vclocalename = agentName OR vccommonname = agentName)", $link); | ||||
|  | ||||
| @ -6,5 +6,5 @@ | ||||
|      http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| */ | ||||
| (function(b,d,j){b.Collections.Messages=d.Collection.extend({model:b.Models.Message,initialize:function(){this.periodicallyCalled=[];this.periodicallyCalled.push(b.Objects.server.callFunctionsPeriodically(j.bind(this.updateMessagesFunctionBuilder,this),j.bind(this.updateMessages,this)))},finalize:function(){for(var a=0;a<this.periodicallyCalled.length;a++)b.Objects.server.stopCallFunctionsPeriodically(this.periodicallyCalled[a])},updateMessages:function(a){a.lastId&&b.Objects.Models.thread.set({lastId:a.lastId}); | ||||
| for(var k=b.Models.Message.prototype.KIND_PLUGIN,g=[],c,f,e,h=0,d=a.messages.length;h<d;h++)c=a.messages[h],c.kind!=k?g.push(new b.Models.Message(c)):"object"!=typeof c.message||null===c.message||(f=c.message.plugin||!1,f="process:"+(!1!==f?f+":":"")+"plugin:message",e={messageData:c,model:!1},this.trigger(f,e),e.model&&(e.model.get("id")||e.model.set({id:c.id}),g.push(e.model)));0<g.length&&this.add(g)},updateMessagesFunctionBuilder:function(){var a=b.Objects.Models.thread,d=b.Objects.Models.user; | ||||
| return[{"function":"updateMessages",arguments:{"return":{messages:"messages",lastId:"lastId"},references:{},threadId:a.get("id"),token:a.get("token"),lastId:a.get("lastId"),user:!d.get("isAgent")}}]},add:function(){var a=Array.prototype.slice.apply(arguments),a=d.Collection.prototype.add.apply(this,a);this.trigger("multiple:add");return a}})})(Mibew,Backbone,_); | ||||
| for(var k=b.Models.Message.prototype.KIND_PLUGIN,g=[],c,f,e,h=0,d=a.messages.length;h<d;h++)c=a.messages[h],c.kind!=k?g.push(new b.Models.Message(c)):"object"!=typeof c.data||null===c.data||(f=c.plugin||!1,f="process:"+(!1!==f?f+":":"")+"plugin:message",e={messageData:c,model:!1},this.trigger(f,e),e.model&&(e.model.get("id")||e.model.set({id:c.id}),g.push(e.model)));0<g.length&&this.add(g)},updateMessagesFunctionBuilder:function(){var a=b.Objects.Models.thread,d=b.Objects.Models.user;return[{"function":"updateMessages", | ||||
| arguments:{"return":{messages:"messages",lastId:"lastId"},references:{},threadId:a.get("id"),token:a.get("token"),lastId:a.get("lastId"),user:!d.get("isAgent")}}]},add:function(){var a=Array.prototype.slice.apply(arguments),a=d.Collection.prototype.add.apply(this,a);this.trigger("multiple:add");return a}})})(Mibew,Backbone,_); | ||||
|  | ||||
| @ -157,8 +157,8 @@ groupId:a.get("groupId"),name:a.get("name"),info:a.get("info"),email:a.get("emai | ||||
|      http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| */ | ||||
| (function(b,d,j){b.Collections.Messages=d.Collection.extend({model:b.Models.Message,initialize:function(){this.periodicallyCalled=[];this.periodicallyCalled.push(b.Objects.server.callFunctionsPeriodically(j.bind(this.updateMessagesFunctionBuilder,this),j.bind(this.updateMessages,this)))},finalize:function(){for(var a=0;a<this.periodicallyCalled.length;a++)b.Objects.server.stopCallFunctionsPeriodically(this.periodicallyCalled[a])},updateMessages:function(a){a.lastId&&b.Objects.Models.thread.set({lastId:a.lastId}); | ||||
| for(var k=b.Models.Message.prototype.KIND_PLUGIN,g=[],c,f,e,h=0,d=a.messages.length;h<d;h++)c=a.messages[h],c.kind!=k?g.push(new b.Models.Message(c)):"object"!=typeof c.message||null===c.message||(f=c.message.plugin||!1,f="process:"+(!1!==f?f+":":"")+"plugin:message",e={messageData:c,model:!1},this.trigger(f,e),e.model&&(e.model.get("id")||e.model.set({id:c.id}),g.push(e.model)));0<g.length&&this.add(g)},updateMessagesFunctionBuilder:function(){var a=b.Objects.Models.thread,d=b.Objects.Models.user; | ||||
| return[{"function":"updateMessages",arguments:{"return":{messages:"messages",lastId:"lastId"},references:{},threadId:a.get("id"),token:a.get("token"),lastId:a.get("lastId"),user:!d.get("isAgent")}}]},add:function(){var a=Array.prototype.slice.apply(arguments),a=d.Collection.prototype.add.apply(this,a);this.trigger("multiple:add");return a}})})(Mibew,Backbone,_); | ||||
| for(var k=b.Models.Message.prototype.KIND_PLUGIN,g=[],c,f,e,h=0,d=a.messages.length;h<d;h++)c=a.messages[h],c.kind!=k?g.push(new b.Models.Message(c)):"object"!=typeof c.data||null===c.data||(f=c.plugin||!1,f="process:"+(!1!==f?f+":":"")+"plugin:message",e={messageData:c,model:!1},this.trigger(f,e),e.model&&(e.model.get("id")||e.model.set({id:c.id}),g.push(e.model)));0<g.length&&this.add(g)},updateMessagesFunctionBuilder:function(){var a=b.Objects.Models.thread,d=b.Objects.Models.user;return[{"function":"updateMessages", | ||||
| arguments:{"return":{messages:"messages",lastId:"lastId"},references:{},threadId:a.get("id"),token:a.get("token"),lastId:a.get("lastId"),user:!d.get("isAgent")}}]},add:function(){var a=Array.prototype.slice.apply(arguments),a=d.Collection.prototype.add.apply(this,a);this.trigger("multiple:add");return a}})})(Mibew,Backbone,_); | ||||
| /* | ||||
|  Copyright 2005-2013 the original author or authors. | ||||
|  Licensed under the Apache License, Version 2.0 (the "License"). | ||||
|  | ||||
| @ -5,4 +5,4 @@ | ||||
|  You may obtain a copy of the License at | ||||
|      http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| */ | ||||
| (function(a){a.Models.Message=a.Models.Base.extend({defaults:{kind:null,created:0,name:"",message:""},KIND_USER:1,KIND_AGENT:2,KIND_FOR_AGENT:3,KIND_INFO:4,KIND_CONN:5,KIND_EVENTS:6,KIND_PLUGIN:7})})(Mibew); | ||||
| (function(a){a.Models.Message=a.Models.Base.extend({defaults:{kind:null,created:0,name:"",message:"",plugin:"",data:{}},KIND_USER:1,KIND_AGENT:2,KIND_FOR_AGENT:3,KIND_INFO:4,KIND_CONN:5,KIND_EVENTS:6,KIND_PLUGIN:7})})(Mibew); | ||||
|  | ||||
| @ -73,7 +73,7 @@ b.Utils.playSound=function(a){c("body").append('<audio autoplay style="display: | ||||
|  You may obtain a copy of the License at | ||||
|      http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| */ | ||||
| (function(a){a.Models.Message=a.Models.Base.extend({defaults:{kind:null,created:0,name:"",message:""},KIND_USER:1,KIND_AGENT:2,KIND_FOR_AGENT:3,KIND_INFO:4,KIND_CONN:5,KIND_EVENTS:6,KIND_PLUGIN:7})})(Mibew); | ||||
| (function(a){a.Models.Message=a.Models.Base.extend({defaults:{kind:null,created:0,name:"",message:"",plugin:"",data:{}},KIND_USER:1,KIND_AGENT:2,KIND_FOR_AGENT:3,KIND_INFO:4,KIND_CONN:5,KIND_EVENTS:6,KIND_PLUGIN:7})})(Mibew); | ||||
| /* | ||||
|  Copyright 2005-2013 the original author or authors. | ||||
|  Licensed under the Apache License, Version 2.0 (the "License"). | ||||
|  | ||||
| @ -5,4 +5,4 @@ | ||||
|  You may obtain a copy of the License at | ||||
|      http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| */ | ||||
| (function(b,c){var a=new c.Marionette.Application;a.addRegions({messagesRegion:"#messages-region"});a.addInitializer(function(c){a.messagesRegion.show(new b.Views.MessagesCollection({collection:new b.Collections.Messages(c.messages)}))});b.Application=a})(Mibew,Backbone); | ||||
| (function(a,c){var b=new c.Marionette.Application;b.addRegions({messagesRegion:"#messages-region"});b.addInitializer(function(c){var d=new a.Collections.Messages;a.Objects.Collections.messages=d;d.updateMessages(c.messages);b.messagesRegion.show(new a.Views.MessagesCollection({collection:d}))});a.Application=b})(Mibew,Backbone); | ||||
|  | ||||
| @ -5,4 +5,4 @@ | ||||
|  You may obtain a copy of the License at | ||||
|      http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| */ | ||||
| (function(a,b){a.Collections.Messages=b.Collection.extend({model:a.Models.Message})})(Mibew,Backbone,_); | ||||
| (function(d,e){d.Collections.Messages=e.Collection.extend({model:d.Models.Message,updateMessages:function(b){for(var c=[],a=0;a<b.length;a++)b[a].message&&c.push(b[a]);0<c.length&&this.add(c)}})})(Mibew,Backbone,_); | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
|  You may obtain a copy of the License at | ||||
|      http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| */ | ||||
| (function(a,b){a.Collections.Messages=b.Collection.extend({model:a.Models.Message})})(Mibew,Backbone,_); | ||||
| (function(d,e){d.Collections.Messages=e.Collection.extend({model:d.Models.Message,updateMessages:function(b){for(var c=[],a=0;a<b.length;a++)b[a].message&&c.push(b[a]);0<c.length&&this.add(c)}})})(Mibew,Backbone,_); | ||||
| /* | ||||
|  Copyright 2005-2013 the original author or authors. | ||||
|  Licensed under the Apache License, Version 2.0 (the "License"). | ||||
| @ -18,4 +18,4 @@ | ||||
|  You may obtain a copy of the License at | ||||
|      http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| */ | ||||
| (function(b,c){var a=new c.Marionette.Application;a.addRegions({messagesRegion:"#messages-region"});a.addInitializer(function(c){a.messagesRegion.show(new b.Views.MessagesCollection({collection:new b.Collections.Messages(c.messages)}))});b.Application=a})(Mibew,Backbone); | ||||
| (function(a,c){var b=new c.Marionette.Application;b.addRegions({messagesRegion:"#messages-region"});b.addInitializer(function(c){var d=new a.Collections.Messages;a.Objects.Collections.messages=d;d.updateMessages(c.messages);b.messagesRegion.show(new a.Views.MessagesCollection({collection:d}))});a.Application=b})(Mibew,Backbone); | ||||
|  | ||||
| @ -81,15 +81,10 @@ | ||||
| 
 | ||||
|                     // Message have KIND_PLUGIN kind and need to be processed
 | ||||
|                     // by plugins to know how to display it.
 | ||||
|                     //
 | ||||
|                     // Message treat as data object with following fields:
 | ||||
|                     //  - 'plugin': string, name of the plugin which sent the
 | ||||
|                     //    message;
 | ||||
|                     //  - 'data': object, some data sent by the plugin.
 | ||||
| 
 | ||||
|                     // Check if message is an real Object
 | ||||
|                     if ((typeof messageData.message != 'object') | ||||
|                         || (messageData.message === null)) { | ||||
|                     if ((typeof messageData.data != 'object') | ||||
|                         || (messageData.data === null)) { | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
| @ -98,7 +93,7 @@ | ||||
|                     // If plugin name was specified it will be
 | ||||
|                     // 'process:<plugin_name>:plugin:message' and
 | ||||
|                     // 'process:plugin:message' otherwise.
 | ||||
|                     pluginName = messageData.message.plugin || false; | ||||
|                     pluginName = messageData.plugin || false; | ||||
|                     eventName = 'process:' | ||||
|                         + ((pluginName !== false) ? pluginName + ':' : '') | ||||
|                         + 'plugin:message'; | ||||
|  | ||||
| @ -40,7 +40,20 @@ | ||||
|                  * Text of the message | ||||
|                  * @type String | ||||
|                  */ | ||||
|                 message: '' | ||||
|                 message: '', | ||||
| 
 | ||||
|                 /** | ||||
|                  * Name of the plugin which sent the message. If message was not | ||||
|                  * sent by a plugin it equals to an empty string. | ||||
|                  * @type String | ||||
|                  */ | ||||
|                 plugin: '', | ||||
| 
 | ||||
|                 /** | ||||
|                  * Set of arbitrary data attached to the message. | ||||
|                  * @type Object | ||||
|                  */ | ||||
|                 data: {} | ||||
|             }, | ||||
| 
 | ||||
|             /** Message kind constants */ | ||||
|  | ||||
| @ -18,8 +18,16 @@ | ||||
| 
 | ||||
|     // Initialize application
 | ||||
|     App.addInitializer(function(options){ | ||||
|         // Create new empty messages collection and store it
 | ||||
|         var messages = new Mibew.Collections.Messages(); | ||||
|         Mibew.Objects.Collections.messages = messages; | ||||
| 
 | ||||
|         // Update messages in the collection
 | ||||
|         messages.updateMessages(options.messages); | ||||
| 
 | ||||
|         // Dispaly collection
 | ||||
|         App.messagesRegion.show(new Mibew.Views.MessagesCollection({ | ||||
|             collection: new Mibew.Collections.Messages(options.messages) | ||||
|             collection: messages | ||||
|         })); | ||||
|     }); | ||||
| 
 | ||||
|  | ||||
| @ -18,7 +18,29 @@ | ||||
|              * Default contructor for model | ||||
|              * @type Function | ||||
|              */ | ||||
|             model: Mibew.Models.Message | ||||
|             model: Mibew.Models.Message, | ||||
| 
 | ||||
|             /** | ||||
|              * Update messages in collection. | ||||
|              * | ||||
|              * Skip messages with empty text body. | ||||
|              * @param rawMessages {Array} Array of row message models data. | ||||
|              */ | ||||
|             updateMessages: function(rawMessages) { | ||||
|                 // Reject all messages with empty text body
 | ||||
|                 var newMessages = []; | ||||
|                 for(var i = 0; i < rawMessages.length; i++) { | ||||
|                     if (! rawMessages[i].message) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     newMessages.push(rawMessages[i]); | ||||
|                 } | ||||
| 
 | ||||
|                 // Add new messages to the collection
 | ||||
|                 if (newMessages.length > 0) { | ||||
|                     this.add(newMessages); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     ); | ||||
| 
 | ||||
|  | ||||
| @ -563,9 +563,10 @@ Class Thread { | ||||
| 					$this->postMessage( | ||||
| 						self::KIND_CONN, | ||||
| 						$message_to_post, | ||||
| 						null, | ||||
| 						null, | ||||
| 						$last_ping_other_side + self::CONNECTION_TIMEOUT | ||||
| 						array( | ||||
| 							'created' => $last_ping_other_side | ||||
| 								+ self::CONNECTION_TIMEOUT | ||||
| 						) | ||||
| 					); | ||||
| 
 | ||||
| 					// And update thread
 | ||||
| @ -582,9 +583,10 @@ Class Thread { | ||||
| 				$this->postMessage( | ||||
| 					self::KIND_FOR_AGENT, | ||||
| 					$message_to_post, | ||||
| 					null, | ||||
| 					null, | ||||
| 					$last_ping_other_side + self::CONNECTION_TIMEOUT | ||||
| 					array( | ||||
| 						'created' => $last_ping_other_side | ||||
| 							+ self::CONNECTION_TIMEOUT | ||||
| 					) | ||||
| 				); | ||||
| 			} | ||||
| 		} | ||||
| @ -690,8 +692,10 @@ Class Thread { | ||||
| 	 *  - 'kind': int, message kind, see Thread::KIND_* for details; | ||||
| 	 *  - 'created': int, unix timestamp when message was created; | ||||
| 	 *  - 'name': string, name of sender; | ||||
| 	 *  - 'message': associative array with message data if kind equals to | ||||
| 	 *    Thread::KIND_PLUGIN and message text string otherwise. | ||||
| 	 *  - 'message': string, message text; | ||||
| 	 *  - 'plugin': string, name of the plugin which sent the message or an | ||||
| 	 *    empty string if message was not sent by a plugin. | ||||
| 	 *  - 'data' array, arbitrary data attached to the message | ||||
| 	 * @see Thread::postMessage() | ||||
| 	 */ | ||||
| 	public function getMessages($is_user, &$last_id) { | ||||
| @ -702,7 +706,7 @@ Class Thread { | ||||
| 		// Load messages
 | ||||
| 		$messages = $db->query( | ||||
| 			"select messageid as id, ikind as kind, dtmcreated as created, " . | ||||
| 			" tname as name, tmessage as message " . | ||||
| 			" tname as name, tmessage as message, plugin, data " . | ||||
| 			"from {chatmessage} " . | ||||
| 			"where threadid = :threadid and messageid > :lastid " . | ||||
| 			($is_user ? "and ikind <> " . self::KIND_FOR_AGENT : "") . | ||||
| @ -722,21 +726,22 @@ Class Thread { | ||||
| 				$msg['name'] | ||||
| 			); | ||||
| 
 | ||||
| 			// Process message body
 | ||||
| 			if ($messages[$key]['kind'] == self::KIND_PLUGIN) { | ||||
| 				// Treat plugin message body as an associative array
 | ||||
| 				$messages[$key]['message'] = unserialize( | ||||
| 					$messages[$key]['message'] | ||||
| 			// Process data attached to the message
 | ||||
| 			if (! empty($messages[$key]['data'])) { | ||||
| 				$messages[$key]['data'] = unserialize( | ||||
| 					$messages[$key]['data'] | ||||
| 				); | ||||
| 			} else { | ||||
| 				// Change message body encoding for core messages kinds
 | ||||
| 				$messages[$key]['message'] = myiconv( | ||||
| 					$webim_encoding, | ||||
| 					"utf-8", | ||||
| 					$msg['message'] | ||||
| 				); | ||||
| 				$messages[$key]['data'] = array(); | ||||
| 			} | ||||
| 
 | ||||
| 			// Change message body encoding
 | ||||
| 			$messages[$key]['message'] = myiconv( | ||||
| 				$webim_encoding, | ||||
| 				"utf-8", | ||||
| 				$msg['message'] | ||||
| 			); | ||||
| 
 | ||||
| 			// Get last message ID
 | ||||
| 			if ($msg['id'] > $last_id) { | ||||
| 				$last_id = $msg['id']; | ||||
| @ -749,20 +754,30 @@ Class Thread { | ||||
| 	/** | ||||
| 	 * Send the messsage | ||||
| 	 * | ||||
| 	 * Use to send message with one of the core kinds(not Thread::KIND_PLUGIN). | ||||
| 	 * Trigger error with 'E_USER_WARNING' level if $kind equals to | ||||
| 	 * Thread::KIND_PLUGIN. | ||||
| 	 * One can attach arbitrary data to the message by setting 'data' item | ||||
| 	 * in the $options array. DO NOT serialize data manually - it will be | ||||
| 	 * automatically coverted to array and serialized before save in database | ||||
| 	 * and unserialized after retreive form database. | ||||
| 	 * | ||||
| 	 * To send plugin message use Thread::postPluginMessage instead. | ||||
| 	 * One can also set plugin item of the $options array to indicate that | ||||
| 	 * message was sent by a plugin. | ||||
| 	 * | ||||
| 	 * @param int $kind Message kind. One of the Thread::KIND_* but not | ||||
| 	 * Thread::KIND_PLUGIN | ||||
| 	 * @param int $kind Message kind. One of the Thread::KIND_* | ||||
| 	 * @param string $message Message body | ||||
| 	 * @param string|null $from Sender name | ||||
| 	 * @param int|null $opid operator id. Use NULL for system messages | ||||
| 	 * @param int|null $time unix timestamp of the send time. Use NULL for | ||||
| 	 * current time. | ||||
| 	 * @return int|boolean Message ID or boolean false on failure. | ||||
| 	 * @param array $options List of additional options. It may contain | ||||
| 	 * following items: | ||||
| 	 *  - 'name': string, name of the message sender. | ||||
| 	 *  - 'operator_id': int, ID of the operator who sent the message. For | ||||
| 	 *    system messages do not set this field. | ||||
| 	 *  - 'created': int, unix timestamp of the send time. If you want to set | ||||
| 	 *    current time do not set this field. | ||||
| 	 *  - 'plugin': string, name of the plugin which sent the message. If | ||||
| 	 *    message was not sent by a plugin do not set this field. | ||||
| 	 *  - 'data': array with arbitrary data related with message. This value | ||||
| 	 *    will be converted to array and serialized before save. If there is no | ||||
| 	 *    such data do not set this field. | ||||
| 	 * | ||||
| 	 * @return int Message ID | ||||
| 	 * | ||||
| 	 * @see Thread::KIND_USER | ||||
| 	 * @see Thread::KIND_AGENT | ||||
| @ -774,39 +789,11 @@ Class Thread { | ||||
| 	 * @see Thread::getMessages() | ||||
| 	 * @see Thread::postPluginMessage() | ||||
| 	 */ | ||||
| 	public function postMessage($kind, $message, $from = null, $opid = null, $time = null) { | ||||
| 		// Check message kind. It can not be equal to Thread::KIND_PLUGIN
 | ||||
| 		if ($kind == self::KIND_PLUGIN) { | ||||
| 			trigger_error( | ||||
| 				'Use Thread::postPluginMessage to send plugins messages', | ||||
| 				E_USER_WARNING | ||||
| 			); | ||||
| 			return false; | ||||
| 		} | ||||
| 	public function postMessage($kind, $message, $options = array()) { | ||||
| 		$options = is_array($options) ? $options : array(); | ||||
| 
 | ||||
| 		// Send message
 | ||||
| 		return $this->saveMessage($kind, $message, $from, $opid, $time); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Send plugin messsage | ||||
| 	 * | ||||
| 	 * @param string $plugin Plugin name. Use to determine which plugin sent | ||||
| 	 * the message. | ||||
| 	 * @param array $data Message data. Can contain arbitrary structure. | ||||
| 	 * @param int|null $time unix timestamp of the send time. Use NULL for | ||||
| 	 * current time. | ||||
| 	 * @return int Message ID | ||||
| 	 * | ||||
| 	 * @see Thread::getMessages() | ||||
| 	 */ | ||||
| 	public function postPluginMessage($plugin, $data, $time = null) { | ||||
| 		$message = serialize(array( | ||||
| 			'plugin' => $plugin, | ||||
| 			'data' => $data | ||||
| 		)); | ||||
| 
 | ||||
| 		return $this->saveMessage(self::KIND_PLUGIN, $message, null, null, $time); | ||||
| 		return $this->saveMessage($kind, $message, $options); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| @ -814,10 +801,19 @@ Class Thread { | ||||
| 	 * | ||||
| 	 * @param int $kind Message kind. One of the Thread::KIND_* | ||||
| 	 * @param string $message Message body | ||||
| 	 * @param string|null $from Sender name | ||||
| 	 * @param int|null $opid operator id. Use NULL for system messages | ||||
| 	 * @param int|null $time unix timestamp of the send time. Use NULL for | ||||
| 	 * current time. | ||||
| 	 * @param array $options List of additional options. It may contain | ||||
| 	 * following items: | ||||
| 	 *  - 'name': string, name of the message sender. | ||||
| 	 *  - 'operator_id': int, ID of the operator who sent the message. For | ||||
| 	 *    system messages do not set this field. | ||||
| 	 *  - 'created': int, unix timestamp of the send time. If you want to set | ||||
| 	 *    current time do not set this field. | ||||
| 	 *  - 'plugin': string, name of the plugin which sent the message. If | ||||
| 	 *    message was not sent by a plugin do not set this field. | ||||
| 	 *  - 'data': array with arbitrary data related with message. This value | ||||
| 	 *    will be converted to array and serialized before save. If there is no | ||||
| 	 *    such data do not set this field. | ||||
| 	 * | ||||
| 	 * @return int Message ID | ||||
| 	 * | ||||
| 	 * @see Thread::KIND_USER | ||||
| @ -829,22 +825,42 @@ Class Thread { | ||||
| 	 * @see Thread::KIND_PLUGIN | ||||
| 	 * @see Thread::getMessages() | ||||
| 	 */ | ||||
| 	protected function saveMessage($kind, $message, $from = null, $opid = null, $time = null) { | ||||
| 	protected function saveMessage($kind, $message, $options = array()) { | ||||
| 		$db = Database::getInstance(); | ||||
| 
 | ||||
| 		$query = "INSERT INTO {chatmessage} " . | ||||
| 			"(threadid,ikind,tmessage,tname,agentId,dtmcreated) " . | ||||
| 			"VALUES (:threadid,:kind,:message,:name,:agentid,:created)"; | ||||
| 		// Add default values to options
 | ||||
| 		$options += array( | ||||
| 			'name' => null, | ||||
| 			'operator_id' => 0, | ||||
| 			'created' => time(), | ||||
| 			'plugin' => '', | ||||
| 			'data' => array() | ||||
| 		); | ||||
| 
 | ||||
| 		// Prepare message data
 | ||||
| 		$options['data'] = serialize((array)$options['data']); | ||||
| 
 | ||||
| 		// Prepare query
 | ||||
| 		$query = "INSERT INTO {chatmessage} (" . | ||||
| 				"threadid, ikind, tmessage, tname, agentId, " . | ||||
| 				"dtmcreated, plugin, data" . | ||||
| 			") VALUES (" . | ||||
| 				":threadid, :kind, :message, :name, :agentid, " . | ||||
| 				":created, :plugin, :data" . | ||||
| 			")"; | ||||
| 
 | ||||
| 		$values = array( | ||||
| 			':threadid' => $this->id, | ||||
| 			':kind' => $kind, | ||||
| 			':message' => $message, | ||||
| 			':name' => ($from ? $from : NULL), | ||||
| 			':agentid' => ($opid ? $opid : 0), | ||||
| 			':created' => ($time ? $time : time()) | ||||
| 			':name' => $options['name'], | ||||
| 			':agentid' => $options['operator_id'], | ||||
| 			':created' => $options['created'], | ||||
| 			':plugin' => $options['plugin'], | ||||
| 			':data' => $options['data'] | ||||
| 		); | ||||
| 
 | ||||
| 		// Execute query
 | ||||
| 		$db->query($query, $values); | ||||
| 		return $db->insertedId(); | ||||
| 	} | ||||
|  | ||||
| @ -326,11 +326,17 @@ class ThreadProcessor extends ClientSideProcessor { | ||||
| 
 | ||||
| 		// Set fields
 | ||||
| 		$kind = $args['user'] ? Thread::KIND_USER : Thread::KIND_AGENT; | ||||
| 		$from = $args['user'] ? $thread->userName : $thread->agentName; | ||||
| 		$opid = $args['user'] ? null : $operator['operatorid']; | ||||
| 		if ($args['user']) { | ||||
| 			$msg_options = array('name' => $thread->userName); | ||||
| 		} else { | ||||
| 			$msg_options = array( | ||||
| 				'name' => $thread->agentName, | ||||
| 				'operator_id' => $operator['operatorid'] | ||||
| 			); | ||||
| 		} | ||||
| 
 | ||||
| 		// Post message
 | ||||
| 		$posted_id = $thread->postMessage($kind, $args['message'], $from, $opid); | ||||
| 		$posted_id = $thread->postMessage($kind, $args['message'], $msg_options); | ||||
| 
 | ||||
| 		// Update shownMessageId
 | ||||
| 		if($args['user'] && $thread->shownMessageId == 0) { | ||||
| @ -498,7 +504,7 @@ class ThreadProcessor extends ClientSideProcessor { | ||||
| 			$posted_id = $thread->postMessage( | ||||
| 				Thread::KIND_USER, | ||||
| 				$first_message, | ||||
| 				$visitor['name'] | ||||
| 				array('name' => $visitor['name']) | ||||
| 			); | ||||
| 			$thread->shownMessageId = $posted_id; | ||||
| 			$thread->save(); | ||||
| @ -621,7 +627,7 @@ class ThreadProcessor extends ClientSideProcessor { | ||||
| 				getstring2('chat.visitor.info', array($info)) | ||||
| 			); | ||||
| 		} | ||||
| 		$thread->postMessage(Thread::KIND_USER, $message, $name); | ||||
| 		$thread->postMessage(Thread::KIND_USER, $message, array('name'=>$name)); | ||||
| 
 | ||||
| 		// Get email for message
 | ||||
| 		$inbox_mail = get_group_email($group_id); | ||||
|  | ||||
| @ -122,8 +122,10 @@ function invitation_invite($visitor_id, $operator) { | ||||
| 	$thread->postMessage( | ||||
| 		Thread::KIND_AGENT, | ||||
| 		getlocal("invitation.message"), | ||||
| 		$operator_name, | ||||
| 		$operator['operatorid'] | ||||
| 		array( | ||||
| 			'name' => $operator_name, | ||||
| 			'operator_id' => $operator['operatorid'] | ||||
| 		) | ||||
| 	); | ||||
| 
 | ||||
| 	return $thread; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user