diff --git a/src/messenger/webim/js/164/mibewapi.js b/src/messenger/webim/js/164/mibewapi.js index e1bf7f7e..f1ca4f6d 100644 --- a/src/messenger/webim/js/164/mibewapi.js +++ b/src/messenger/webim/js/164/mibewapi.js @@ -6,14 +6,16 @@ License: http://mibew.org/license.php */ function MibewAPI(a){this.protocolVersion="1.0";if("object"!=typeof a||!(a instanceof MibewAPIInteraction))throw Error("Wrong interaction type");this.interaction=a} -MibewAPI.prototype.checkFunction=function(a,b){if("undefined"==typeof a["function"]||""==a["function"])throw Error("Cannot call for function with no name");if(b)for(var c=0;c<this.interaction.reservedFunctionNames.length;c++)if(a["function"]==this.interaction.reservedFunctionNames[c])throw Error("'"+a["function"]+"' is reserved function name");if("object"!=typeof a.arguments)throw Error("There are no arguments in '"+a["function"]+"' function");var d=0,e;a:for(e in a.arguments)for(c=0;c<this.interaction.obligatoryArguments.length;c++)if(e== -this.interaction.obligatoryArguments[c]){d++;continue a}if(d!=this.interaction.obligatoryArguments.length)throw Error("Not all obligatory arguments are set in '"+a["function"]+"' function");}; +MibewAPI.prototype.checkFunction=function(a,b){if("undefined"==typeof a["function"]||""==a["function"])throw Error("Cannot call for function with no name");if(b)for(var c=0;c<this.interaction.reservedFunctionNames.length;c++)if(a["function"]==this.interaction.reservedFunctionNames[c])throw Error("'"+a["function"]+"' is reserved function name");if("object"!=typeof a.arguments)throw Error("There are no arguments in '"+a["function"]+"' function");var d=0,f=this.interaction.getObligatoryArguments(a["function"]), +e;a:for(e in a.arguments)for(c=0;c<f.length;c++)if(e==f[c]){d++;continue a}if(d!=f.length)throw Error("Not all obligatory arguments are set in '"+a["function"]+"' function");}; MibewAPI.prototype.checkRequest=function(a){if("string"!=typeof a.token){if("undefined"==typeof a.token)throw Error("Empty token");throw Error("Wrong token type");}if(""==a.token)throw Error("Empty token");if("object"!=typeof a.functions||!(a.functions instanceof Array)||0==a.functions.length)throw Error("Empty functions set");for(var b=0;b<a.functions.length;b++)this.checkFunction(a.functions[b])}; MibewAPI.prototype.checkPackage=function(a){if("undefined"==typeof a.signature)throw Error("Missed package signature");if("undefined"==typeof a.proto)throw Error("Missed protocol version");if(a.proto!=this.protocolVersion)throw Error("Wrong protocol version");if("undefined"==typeof a.async)throw Error("'async' flag is missed");if("boolean"!=typeof a.async)throw Error("Wrong 'async' flag value");if("object"!=typeof a.requests||!(a.requests instanceof Array)||0==a.requests.length)throw Error("Empty requests set"); for(var b=0;b<a.requests.length;b++)this.checkRequest(a.requests[b])};MibewAPI.prototype.getResultFunction=function(a,b){"undefined"==typeof b&&(b=null);var c=null,d;for(d in a)if(a.hasOwnProperty(d)&&"result"==a[d]["function"]){if(null!==c)throw Error("Function 'result' already exists in functions list");c=a[d]}if(!0===b&&null===c)throw Error("There is no 'result' function in functions list");if(!1===b&&null!==c)throw Error("There is 'result' function in functions list");return c}; -MibewAPI.prototype.buildResult=function(a,b){var c=this.interaction.getDefaultObligatoryArguments(),d;for(d in c)c.hasOwnProperty(d)&&(a[d]=c[d]);return{token:b,functions:[{"function":"result",arguments:a}]}};MibewAPI.prototype.encodePackage=function(a){var b={signature:""};b.proto=this.protocolVersion;b.async=!0;b.requests=a;return encodeURIComponent(JSON.stringify(b)).replace(/\%20/gi,"+")}; -MibewAPI.prototype.decodePackage=function(a){a=JSON.parse(decodeURIComponent(a.replace(/\+/gi," ")));this.checkPackage(a);return a};function MibewAPIInteraction(){this.reservedFunctionNames=[];this.obligatoryArguments=[];this.getDefaultObligatoryArguments=function(){return{}}}function MibewAPIWindowToCoreInteraction(){this.reservedFunctionNames=["result"];this.obligatoryArguments=["return","references"];this.getDefaultObligatoryArguments=function(){return{"return":{},references:{}}}} -MibewAPIWindowToCoreInteraction.prototype=new MibewAPIInteraction;function MibewAPIExecutionContext(){this.returnValues={};this.functionsResults=[]} -MibewAPIExecutionContext.prototype.getArgumentsList=function(a){var b=a.arguments,c=a.arguments.references,d,e,f;for(f in c)if(c.hasOwnProperty(f)){e=c[f];if("undefined"==typeof this.functionsResults[e-1])throw Error("Wrong reference in '"+a["function"]+"' function. Function #"+e+" does not call yet.");if("undefined"==typeof b[f]||""==b[f])throw Error("Wrong reference in '"+a["function"]+"' function. Empty '"+f+"' argument.");d=b[f];if("undefined"==typeof this.functionsResults[e-1][d])throw Error("Wrong reference in '"+ -a["function"]+"' function. There is no '"+d+"' argument in #"+e+" function results");b[f]=this.functionsResults[e-1][d]}return b};MibewAPIExecutionContext.prototype.getResults=function(){return this.returnValues}; +MibewAPI.prototype.buildResult=function(a,b){var c=this.interaction.getDefaultObligatoryArguments("result"),d;for(d in c)c.hasOwnProperty(d)&&(a[d]=c[d]);return{token:b,functions:[{"function":"result",arguments:a}]}};MibewAPI.prototype.encodePackage=function(a){var b={signature:""};b.proto=this.protocolVersion;b.async=!0;b.requests=a;return encodeURIComponent(JSON.stringify(b)).replace(/\%20/gi,"+")}; +MibewAPI.prototype.decodePackage=function(a){a=JSON.parse(decodeURIComponent(a.replace(/\+/gi," ")));this.checkPackage(a);return a};function MibewAPIInteraction(){this.obligatoryArguments={};this.reservedFunctionNames=[]} +MibewAPIInteraction.prototype.getObligatoryArguments=function(a){var b=[];if("object"==typeof this.obligatoryArguments["*"]&&this.obligatoryArguments["*"]instanceof Array)for(var c in this.obligatoryArguments["*"])this.obligatoryArguments["*"].hasOwnProperty(c)&&b.push(c);if("object"==typeof this.obligatoryArguments[a]&&this.obligatoryArguments[a]instanceof Array)for(c in this.obligatoryArguments[a])this.obligatoryArguments[a].hasOwnProperty(c)&&b.push(c);return b}; +MibewAPIInteraction.prototype.getDefaultObligatoryArguments=function(a){var b=[];if("object"==typeof this.obligatoryArguments["*"]&&this.obligatoryArguments["*"]instanceof Array)for(var c in this.obligatoryArguments["*"])this.obligatoryArguments["*"].hasOwnProperty(c)&&(b[c]=this.obligatoryArguments["*"][c]);if("object"==typeof this.obligatoryArguments[a]&&this.obligatoryArguments[a]instanceof Array)for(c in this.obligatoryArguments[a])this.obligatoryArguments[a].hasOwnProperty(c)&&(b[c]=this.obligatoryArguments[a][c]); +return b};function MibewAPIWindowToCoreInteraction(){this.obligatoryArguments={"*":{"return":{},references:{}}};this.reservedFunctionNames=["result"]}MibewAPIWindowToCoreInteraction.prototype=new MibewAPIInteraction;function MibewAPIExecutionContext(){this.returnValues={};this.functionsResults=[]} +MibewAPIExecutionContext.prototype.getArgumentsList=function(a){var b=a.arguments,c=a.arguments.references,d,f,e;for(e in c)if(c.hasOwnProperty(e)){f=c[e];if("undefined"==typeof this.functionsResults[f-1])throw Error("Wrong reference in '"+a["function"]+"' function. Function #"+f+" does not call yet.");if("undefined"==typeof b[e]||""==b[e])throw Error("Wrong reference in '"+a["function"]+"' function. Empty '"+e+"' argument.");d=b[e];if("undefined"==typeof this.functionsResults[f-1][d])throw Error("Wrong reference in '"+ +a["function"]+"' function. There is no '"+d+"' argument in #"+f+" function results");b[e]=this.functionsResults[f-1][d]}return b};MibewAPIExecutionContext.prototype.getResults=function(){return this.returnValues}; MibewAPIExecutionContext.prototype.storeFunctionResults=function(a,b){var c,d;for(d in a.arguments["return"])if(a.arguments["return"].hasOwnProperty(d)){c=a.arguments["return"][d];if("undefined"==typeof b[d])throw Error("Variable with name '"+d+"' is undefined in the results of the '"+a["function"]+"' function");this.returnValues[c]=b[d]}this.functionsResults.push(b)}; \ No newline at end of file diff --git a/src/messenger/webim/js/source/mibewapi.js b/src/messenger/webim/js/source/mibewapi.js index 1a0ab0fb..47dce027 100644 --- a/src/messenger/webim/js/source/mibewapi.js +++ b/src/messenger/webim/js/source/mibewapi.js @@ -12,7 +12,6 @@ * @constructor * @param {MibewAPIInteraction} interaction An object that represents * interaction type - * @todo Think about error code */ function MibewAPI(interaction) { @@ -73,17 +72,19 @@ MibewAPI.prototype.checkFunction = function(functionObject, filterReservedFuncti ); } var obligatoryArgumentsCount = 0; + var obligatoryArgumentsList = this.interaction.getObligatoryArguments( + functionObject['function'] + ); argumentsLoop: for (var argName in functionObject.arguments){ - for (var i = 0; i < this.interaction.obligatoryArguments.length; i++) { - if (argName == this.interaction.obligatoryArguments[i]) { + for (var i = 0; i < obligatoryArgumentsList.length; i++) { + if (argName == obligatoryArgumentsList[i]) { obligatoryArgumentsCount++; continue argumentsLoop; } } } - if (obligatoryArgumentsCount != - this.interaction.obligatoryArguments.length) { + if (obligatoryArgumentsCount != obligatoryArgumentsList.length) { throw new Error( "Not all obligatory arguments are set in '" + functionObject["function"] + "' function" @@ -222,7 +223,7 @@ MibewAPI.prototype.getResultFunction = function(functionsList, existance){ */ MibewAPI.prototype.buildResult = function(resultArguments, token) { var mergedArguments = resultArguments; - var defaultArguments = this.interaction.getDefaultObligatoryArguments(); + var defaultArguments = this.interaction.getDefaultObligatoryArguments('result'); for (var argName in defaultArguments) { if (! defaultArguments.hasOwnProperty(argName)) { continue; @@ -282,24 +283,104 @@ MibewAPI.prototype.decodePackage = function(encodedPackage){ */ function MibewAPIInteraction(){ /** - * Abligatory arguments in called functions + * Defines obligatory arguments and default values for them + * + * Keys of the array are function names ('*' for all functions). Values are + * arrays of obligatory arguments with key for name of an argument and value + * for default value. + * + * For example: + * <code> + * this.obligatoryArguments = { + * '*': { + * 'return': {}, + * 'references': {} + * }, + * 'result': { + * 'errorCode': 0 + * } + * } + * </code> + * @type Object + * @private + */ + this.obligatoryArguments = {}; + + /** + * Reserved function's names + * + * Defines reserved(system) function's names described in the Mibew API. + * @type Array */ this.reservedFunctionNames = []; - /** - * Reserved function names - */ - this.obligatoryArguments = []; - /** - * Returns default values of obligatory arguments - * - * @returns {Object} An object fields names are obligatory arguments and - * values are default values of them - */ - this.getDefaultObligatoryArguments = function(){ - return {} - } } +/** + * Returns obligatory arguments for the functionName function + * + * @param {String} functionName Function name + * @returns {Array} An array of obligatory arguments + */ +MibewAPIInteraction.prototype.getObligatoryArguments = function(functionName) { + var obligatoryArguments = []; + // Add obligatory for all functions arguments + if (typeof this.obligatoryArguments['*'] == 'object' && + this.obligatoryArguments['*'] instanceof Array) { + for (var arg in this.obligatoryArguments['*']) { + if (! this.obligatoryArguments['*'].hasOwnProperty(arg)) { + continue; + } + obligatoryArguments.push(arg); + } + } + // Add obligatory arguments for given function + if (typeof this.obligatoryArguments[functionName] == 'object' && + this.obligatoryArguments[functionName] instanceof Array) { + for (var arg in this.obligatoryArguments[functionName]) { + if (! this.obligatoryArguments[functionName].hasOwnProperty(arg)) { + continue; + } + obligatoryArguments.push(arg); + } + } + return obligatoryArguments; +} + +/** + * Returns default values of obligatory arguments for the functionName function + * + * @param {String} functionName Function name + * @returns {Object} An object fields names are obligatory arguments and + * values are default values of them + */ +MibewAPIInteraction.prototype.getDefaultObligatoryArguments = function(functionName) { + var obligatoryArguments = []; + // Add obligatory for all functions arguments + if (typeof this.obligatoryArguments['*'] == 'object' && + this.obligatoryArguments['*'] instanceof Array) { + for (var arg in this.obligatoryArguments['*']) { + if (! this.obligatoryArguments['*'].hasOwnProperty(arg)) { + continue; + } + obligatoryArguments[arg] = this.obligatoryArguments['*'][arg]; + } + } + // Add obligatory arguments for given function + if (typeof this.obligatoryArguments[functionName] == 'object' && + this.obligatoryArguments[functionName] instanceof Array) { + for (var arg in this.obligatoryArguments[functionName]) { + if (! this.obligatoryArguments[functionName].hasOwnProperty(arg)) { + continue; + } + obligatoryArguments[arg] = this.obligatoryArguments[functionName][arg]; + } + } + return obligatoryArguments; +} +/** + * End of MibewAPIInteraction class + */ + /** * Represents Window to core interaction type * @@ -307,21 +388,16 @@ function MibewAPIInteraction(){ * @todo Think about real values! */ function MibewAPIWindowToCoreInteraction() { + this.obligatoryArguments = { + '*': { + 'return': {}, + 'references': {} + } + }; + this.reservedFunctionNames = [ 'result' ]; - - this.obligatoryArguments = [ - 'return', - 'references' - ]; - - this.getDefaultObligatoryArguments = function(){ - return { - "return" : {}, - "references" : {} - } - } } MibewAPIWindowToCoreInteraction.prototype = new MibewAPIInteraction(); diff --git a/src/messenger/webim/libs/mibew_api.php b/src/messenger/webim/libs/mibew_api.php index b6acc47e..e283bd9c 100644 --- a/src/messenger/webim/libs/mibew_api.php +++ b/src/messenger/webim/libs/mibew_api.php @@ -201,7 +201,7 @@ Class MibewAPI { ); } $unset_arguments = array_diff( - $this->interaction->obligatoryArguments, + $this->interaction->getObligatoryArguments($function['function']), array_keys($function['arguments']) ); if (! empty($unset_arguments)) { @@ -273,7 +273,7 @@ Class MibewAPI { * @return array Result package */ public function buildResult($token, $result_arguments) { - $arguments = $result_arguments + $this->interaction->getDefaultObligatoryArguments(); + $arguments = $result_arguments + $this->interaction->getDefaultObligatoryArguments('result'); $package = array( 'token' => $token, 'functions' => array( @@ -438,44 +438,130 @@ Class MibewAPIExecutionContext { */ abstract class MibewAPIInteraction { /** - * Abligatory arguments in called functions - * @var array + * Defines obligatory arguments and default values for them + * + * @var array Keys of the array are function names ('*' for all functions). Values are arrays of obligatory + * arguments with key for name of an argument and value for default value. + * + * For example: + * <code> + * protected $obligatoryArguments = array( + * '*' => array( // Obligatory arguments for all functions are + * 'return' => array(), // 'return' with array() by default and + * 'references' => array() // 'references' with array() by default + * ), + * 'result' => array( // There is an additional argument for the result function + * 'errorCode' => 0 // This is 'error_code' with 0 by default + * ) + * ); + * </code> */ - public $obligatoryArguments; - /** - * Reserved function names - * @var array - */ - public $reservedFunctionNames; + protected $obligatoryArguments = array(); /** - * Returns default values of obligatory arguments + * Reserved function's names * + * Defines reserved(system) function's names described in the Mibew API. + * @var array + */ + public $reservedFunctionNames = array(); + + /** + * Returns obligatory arguments for the $function_name function + * + * @param string $function_name Function name + * @return array An array of obligatory arguments + */ + public function getObligatoryArguments($function_name) { + $obligatory_arguments = array(); + // Add obligatory for all functions arguments + if (! empty($this->obligatoryArguments['*'])) { + $obligatory_arguments = array_merge( + $obligatory_arguments, + array_keys($this->obligatoryArguments['*']) + ); + } + // Add obligatory arguments for given function + if (! empty($this->obligatoryArguments[$function_name])) { + $obligatory_arguments = array_merge( + $obligatory_arguments, + array_keys($this->obligatoryArguments[$function_name]) + ); + } + return array_unique($obligatory_arguments); + } + + /** + * Returns default values of obligatory arguments for the $function_name function + * + * @param string $function_name Function name * @return array Associative array with keys are obligatory arguments and values are default * values of them */ - abstract public function getDefaultObligatoryArguments(); + public function getDefaultObligatoryArguments($function_name) { + $obligatory_arguments = array(); + // Add obligatory for all functions arguments + if (! empty($this->obligatoryArguments['*'])) { + $obligatory_arguments = array_merge($obligatory_arguments, $this->obligatoryArguments['*']); + } + // Add obligatory arguments for given function + if (! empty($this->obligatoryArguments[$function_name])) { + $obligatory_arguments = array_merge($obligatory_arguments, $this->obligatoryArguments[$function_name]); + } + return $obligatory_arguments; + } } /** * Implements Base Mibew Interaction */ class MibewAPIBaseInteraction extends MibewAPIInteraction { - public $obligatoryArguments = array( - 'references', - 'return' + /** + * Defines obligatory arguments and default values for them + * @var array + * @see MibewAPIInteraction::$obligatoryArgumnents + */ + protected $obligatoryArguments = array( + '*' => array( + 'references' => array(), + 'return' => array() + ) ); + /** + * Reserved function's names + * @var array + * @see MibewAPIInteraction::$reservedFunctionNames + */ public $reservedFunctionNames = array( 'result' ); +} - public function getDefaultObligatoryArguments() { - return array( +/** + * Implements Mibew Core - Mibew Chat Window interaction + */ +class MibewAPIWindowInteraction extends MibewAPIInteraction { + /** + * Defines obligatory arguments and default values for them + * @var array + * @see MibewAPIInteraction::$obligatoryArgumnents + */ + protected $obligatoryArguments = array( + '*' => array( 'references' => array(), 'return' => array() - ); - } + ) + ); + + /** + * Reserved function's names + * @var array + * @see MibewAPIInteraction::$reservedFunctionNames + */ + public $reservedFunctionNames = array( + 'result' + ); } /**