UNPKG

phpjs

Version:

php.js offers community built php functions in javascript

1,730 lines (1,551 loc) 416 kB
// This file is generated by `make build`. // Do NOT edit by hand. // // Make function changes in ./functions and // generator changes in ./lib/phpjsutil.js exports.array = function () { try { this.php_js = this.php_js || {}; } catch (e) { this.php_js = {}; } var arrInst, e, __, that = this, PHPJS_Array = function PHPJS_Array() {}; mainArgs = arguments, p = this.php_js, _indexOf = function(value, from, strict) { var i = from || 0, nonstrict = !strict, length = this.length; while (i < length) { if (this[i] === value || (nonstrict && this[i] == value)) { return i; } i++; } return -1; }; // BEGIN REDUNDANT if (!p.Relator) { p.Relator = (function() {// Used this functional class for giving privacy to the class we are creating // Code adapted from http://www.devpro.it/code/192.html // Relator explained at http://webreflection.blogspot.com/2008/07/javascript-relator-object-aka.html // Its use as privacy technique described at http://webreflection.blogspot.com/2008/10/new-relator-object-plus-unshared.html // 1) At top of closure, put: var __ = Relator.$(); // 2) In constructor, put: var _ = __.constructor(this); // 3) At top of each prototype method, put: var _ = __.method(this); // 4) Use like: _.privateVar = 5; function _indexOf(value) { var i = 0, length = this.length; while (i < length) { if (this[i] === value) { return i; } i++; } return -1; } function Relator() { var Stack = [], Array = []; if (!Stack.indexOf) { Stack.indexOf = _indexOf; } return { // create a new relator $: function() { return Relator(); }, constructor: function(that) { var i = Stack.indexOf(that); ~i ? Array[i] : Array[Stack.push(that) - 1] = {}; this.method(that).that = that; return this.method(that); }, method: function(that) { return Array[Stack.indexOf(that)]; } }; } return Relator(); }()); } // END REDUNDANT if (p && p.ini && p.ini['phpjs.return_phpjs_arrays'].local_value.toLowerCase() === 'on') { if (!p.PHPJS_Array) { // We keep this Relator outside the class in case adding prototype methods below // Prototype methods added elsewhere can also use this ArrayRelator to share these "pseudo-global mostly-private" variables __ = p.ArrayRelator = p.ArrayRelator || p.Relator.$(); // We could instead allow arguments of {key:XX, value:YY} but even more cumbersome to write p.PHPJS_Array = function PHPJS_Array() { var _ = __.constructor(this), args = arguments, i = 0, argl, p; args = (args.length === 1 && args[0] && typeof args[0] === 'object' && args[0].length && !args[0].propertyIsEnumerable('length')) ? args[0] : args; // If first and only arg is an array, use that (Don't depend on this) if (!_.objectChain) { _.objectChain = args; _.object = {}; _.keys = []; _.values = []; } for (argl = args.length; i < argl; i++) { for (p in args[i]) { // Allow for access by key; use of private members to store sequence allows these to be iterated via for...in (but for read-only use, with hasOwnProperty or function filtering to avoid prototype methods, and per ES, potentially out of order) this[p] = _.object[p] = args[i][p]; // Allow for easier access by prototype methods _.keys[_.keys.length] = p; _.values[_.values.length] = args[i][p]; break; } } }; e = p.PHPJS_Array.prototype; e.change_key_case = function(cs) { var _ = __.method(this), oldkey, newkey, i = 0, kl = _.keys.length, case_fn = (!cs || cs === 'CASE_LOWER') ? 'toLowerCase' : 'toUpperCase'; while (i < kl) { oldkey = _.keys[i]; newkey = _.keys[i] = _.keys[i][case_fn](); if (oldkey !== newkey) { this[oldkey] = _.object[oldkey] = _.objectChain[i][oldkey] = null; // Break reference before deleting delete this[oldkey]; delete _.object[oldkey]; delete _.objectChain[i][oldkey]; this[newkey] = _.object[newkey] = _.objectChain[i][newkey] = _.values[i]; // Fix: should we make a deep copy? } i++; } return this; }; e.flip = function() { var _ = __.method(this), i = 0, kl = _.keys.length; while (i < kl) { oldkey = _.keys[i]; newkey = _.values[i]; if (oldkey !== newkey) { this[oldkey] = _.object[oldkey] = _.objectChain[i][oldkey] = null; // Break reference before deleting delete this[oldkey]; delete _.object[oldkey]; delete _.objectChain[i][oldkey]; this[newkey] = _.object[newkey] = _.objectChain[i][newkey] = oldkey; _.keys[i] = newkey; } i++; } return this; }; e.walk = function(funcname, userdata) { var _ = __.method(this), obj, func, ini, i = 0, kl = 0; try { if (typeof funcname === 'function') { for (i = 0, kl = _.keys.length; i < kl; i++) { if (arguments.length > 1) { funcname(_.values[i], _.keys[i], userdata); } else { funcname(_.values[i], _.keys[i]); } } } else if (typeof funcname === 'string') { this.php_js = this.php_js || {}; this.php_js.ini = this.php_js.ini || {}; ini = this.php_js.ini['phpjs.no-eval']; if (ini && ( parseInt(ini.local_value, 10) !== 0 && (!ini.local_value.toLowerCase || ini.local_value.toLowerCase() !== 'off') )) { if (arguments.length > 1) { for (i = 0, kl = _.keys.length; i < kl; i++) { this.window[funcname](_.values[i], _.keys[i], userdata); } } else { for (i = 0, kl = _.keys.length; i < kl; i++) { this.window[funcname](_.values[i], _.keys[i]); } } } else { if (arguments.length > 1) { for (i = 0, kl = _.keys.length; i < kl; i++) { eval(funcname + '(_.values[i], _.keys[i], userdata)'); } } else { for (i = 0, kl = _.keys.length; i < kl; i++) { eval(funcname + '(_.values[i], _.keys[i])'); } } } } else if (funcname && typeof funcname === 'object' && funcname.length === 2) { obj = funcname[0]; func = funcname[1]; if (arguments.length > 1) { for (i = 0, kl = _.keys.length; i < kl; i++) { obj[func](_.values[i], _.keys[i], userdata); } } else { for (i = 0, kl = _.keys.length; i < kl; i++) { obj[func](_.values[i], _.keys[i]); } } } else { return false; } } catch (e) { return false; } return this; }; // Here we'll return actual arrays since most logical and practical for these functions to do this e.keys = function(search_value, argStrict) { var _ = __.method(this), pos, search = typeof search_value !== 'undefined', tmp_arr = [], strict = !!argStrict; if (!search) { return _.keys; } while ((pos = _indexOf(_.values, pos, strict)) !== -1) { tmp_arr[tmp_arr.length] = _.keys[pos]; } return tmp_arr; }; e.values = function() {var _ = __.method(this); return _.values; }; // Return non-object, non-array values, since most sensible e.search = function(needle, argStrict) { var _ = __.method(this), strict = !!argStrict, haystack = _.values, i, vl, val, flags; if (typeof needle === 'object' && needle.exec) { // Duck-type for RegExp if (!strict) { // Let's consider case sensitive searches as strict flags = 'i' + (needle.global ? 'g' : '') + (needle.multiline ? 'm' : '') + (needle.sticky ? 'y' : ''); // sticky is FF only needle = new RegExp(needle.source, flags); } for (i = 0, vl = haystack.length; i < vl; i++) { val = haystack[i]; if (needle.test(val)) { return _.keys[i]; } } return false; } for (i = 0, vl = haystack.length; i < vl; i++) { val = haystack[i]; if ((strict && val === needle) || (!strict && val == needle)) { return _.keys[i]; } } return false; }; e.sum = function() { var _ = __.method(this), sum = 0, i = 0, kl = _.keys.length; while (i < kl) { if (!isNaN(parseFloat(_.values[i]))) { sum += parseFloat(_.values[i]); } i++; } return sum; }; // Experimental functions e.foreach = function(handler) { var _ = __.method(this), i = 0, kl = _.keys.length; while (i < kl) { if (handler.length === 1) { handler(_.values[i]); // only pass the value } else { handler(_.keys[i], _.values[i]); } i++; } return this; }; e.list = function() { var key, _ = __.method(this), i = 0, argl = arguments.length; while (i < argl) { key = _.keys[i]; if (key && key.length === parseInt(key, 10).toString().length && // Key represents an int parseInt(key, 10) < argl) { // Key does not exceed arguments that.window[arguments[key]] = _.values[key]; } i++; } return this; }; // Parallel functionality and naming of built-in JavaScript array methods e.forEach = function(handler) { var _ = __.method(this), i = 0, kl = _.keys.length; while (i < kl) { handler(_.values[i], _.keys[i], this); i++; } return this; }; // Our own custom convenience functions e.$object = function() {var _ = __.method(this); return _.object; }; e.$objectChain = function() {var _ = __.method(this); return _.objectChain; }; } PHPJS_Array.prototype = p.PHPJS_Array.prototype; arrInst = new PHPJS_Array(); p.PHPJS_Array.apply(arrInst, mainArgs); return arrInst; } return Array.prototype.slice.call(mainArgs); }; exports.array_change_key_case = function (array, cs) { var case_fn, key, tmp_ar = {}; if (Object.prototype.toString.call(array) === '[object Array]') { return array; } if (array && typeof array === 'object' && array.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array return array.change_key_case(cs); } if (array && typeof array === 'object') { case_fn = (!cs || cs === 'CASE_LOWER') ? 'toLowerCase' : 'toUpperCase'; for (key in array) { tmp_ar[key[case_fn]()] = array[key]; } return tmp_ar; } return false; }; exports.array_chunk = function (input, size, preserve_keys) { var x, p = '', i = 0, c = -1, l = input.length || 0, n = []; if (size < 1) { return null; } if (Object.prototype.toString.call(input) === '[object Array]') { if (preserve_keys) { while (i < l) { (x = i % size) ? n[c][i] = input[i] : n[++c] = {}, n[c][i] = input[i]; i++; } } else { while (i < l) { (x = i % size) ? n[c][x] = input[i] : n[++c] = [input[i]]; i++; } } } else { if (preserve_keys) { for (p in input) { if (input.hasOwnProperty(p)) { (x = i % size) ? n[c][p] = input[p] : n[++c] = {}, n[c][p] = input[p]; i++; } } } else { for (p in input) { if (input.hasOwnProperty(p)) { (x = i % size) ? n[c][x] = input[p] : n[++c] = [input[p]]; i++; } } } } return n; }; exports.array_combine = function (keys, values) { var new_array = {}, keycount = keys && keys.length, i = 0; // input sanitation if (typeof keys !== 'object' || typeof values !== 'object' || // Only accept arrays or array-like objects typeof keycount !== 'number' || typeof values.length !== 'number' || !keycount) { // Require arrays to have a count return false; } // number of elements does not match if (keycount != values.length) { return false; } for (i = 0; i < keycount; i++) { new_array[keys[i]] = values[i]; } return new_array; }; exports.array_count_values = function (array) { var tmp_arr = {}, key = '', t = ''; var __getType = function(obj) { // Objects are php associative arrays. var t = typeof obj; t = t.toLowerCase(); if (t === 'object') { t = 'array'; } return t; }; var __countValue = function(value) { switch (typeof value) { case 'number': if (Math.floor(value) !== value) { return; } // Fall-through case 'string': if (value in this && this.hasOwnProperty(value)) { ++this[value]; } else { this[value] = 1; } } }; t = __getType(array); if (t === 'array') { for (key in array) { if (array.hasOwnProperty(key)) { __countValue.call(tmp_arr, array[key]); } } } return tmp_arr; }; exports.array_diff = function (arr1) { var retArr = {}, argl = arguments.length, k1 = '', i = 1, k = '', arr = {}; arr1keys: for (k1 in arr1) { for (i = 1; i < argl; i++) { arr = arguments[i]; for (k in arr) { if (arr[k] === arr1[k1]) { // If it reaches here, it was found in at least one array, so try next value continue arr1keys; } } retArr[k1] = arr1[k1]; } } return retArr; }; exports.array_diff_assoc = function (arr1) { var retArr = {}, argl = arguments.length, k1 = '', i = 1, k = '', arr = {}; arr1keys: for (k1 in arr1) { for (i = 1; i < argl; i++) { arr = arguments[i]; for (k in arr) { if (arr[k] === arr1[k1] && k === k1) { // If it reaches here, it was found in at least one array, so try next value continue arr1keys; } } retArr[k1] = arr1[k1]; } } return retArr; }; exports.array_diff_key = function (arr1) { var argl = arguments.length, retArr = {}, k1 = '', i = 1, k = '', arr = {}; arr1keys: for (k1 in arr1) { for (i = 1; i < argl; i++) { arr = arguments[i]; for (k in arr) { if (k === k1) { // If it reaches here, it was found in at least one array, so try next value continue arr1keys; } } retArr[k1] = arr1[k1]; } } return retArr; }; exports.array_diff_uassoc = function (arr1) { var retArr = {}, arglm1 = arguments.length - 1, cb = arguments[arglm1], arr = {}, i = 1, k1 = '', k = ''; cb = (typeof cb === 'string') ? this.window[cb] : (Object.prototype.toString.call(cb) === '[object Array]') ? this.window[cb[0]][cb[1]] : cb; arr1keys: for (k1 in arr1) { for (i = 1; i < arglm1; i++) { arr = arguments[i]; for (k in arr) { if (arr[k] === arr1[k1] && cb(k, k1) === 0) { // If it reaches here, it was found in at least one array, so try next value continue arr1keys; } } retArr[k1] = arr1[k1]; } } return retArr; }; exports.array_diff_ukey = function (arr1) { var retArr = {}, arglm1 = arguments.length - 1, cb = arguments[arglm1], arr = {}, i = 1, k1 = '', k = ''; cb = (typeof cb === 'string') ? this.window[cb] : (Object.prototype.toString.call(cb) === '[object Array]') ? this.window[cb[0]][cb[1]] : cb; arr1keys: for (k1 in arr1) { for (i = 1; i < arglm1; i++) { arr = arguments[i]; for (k in arr) { if (cb(k, k1) === 0) { // If it reaches here, it was found in at least one array, so try next value continue arr1keys; } } retArr[k1] = arr1[k1]; } } return retArr; }; exports.array_fill = function (start_index, num, mixed_val) { var key, tmp_arr = {}; if (!isNaN(start_index) && !isNaN(num)) { for (key = 0; key < num; key++) { tmp_arr[(key + start_index)] = mixed_val; } } return tmp_arr; }; exports.array_fill_keys = function (keys, value) { var retObj = {}, key = ''; for (key in keys) { retObj[keys[key]] = value; } return retObj; }; exports.array_filter = function (arr, func) { var retObj = {}, k; func = func || function(v) { return v; }; // Fix: Issue #73 if (Object.prototype.toString.call(arr) === '[object Array]') { retObj = []; } for (k in arr) { if (func(arr[k])) { retObj[k] = arr[k]; } } return retObj; }; exports.array_intersect = function (arr1) { var retArr = {}, argl = arguments.length, arglm1 = argl - 1, k1 = '', arr = {}, i = 0, k = ''; arr1keys: for (k1 in arr1) { arrs: for (i = 1; i < argl; i++) { arr = arguments[i]; for (k in arr) { if (arr[k] === arr1[k1]) { if (i === arglm1) { retArr[k1] = arr1[k1]; } // If the innermost loop always leads at least once to an equal value, continue the loop until done continue arrs; } } // If it reaches here, it wasn't found in at least one array, so try next value continue arr1keys; } } return retArr; }; exports.array_intersect_assoc = function (arr1) { var retArr = {}, argl = arguments.length, arglm1 = argl - 1, k1 = '', arr = {}, i = 0, k = ''; arr1keys: for (k1 in arr1) { arrs: for (i = 1; i < argl; i++) { arr = arguments[i]; for (k in arr) { if (arr[k] === arr1[k1] && k === k1) { if (i === arglm1) { retArr[k1] = arr1[k1]; } // If the innermost loop always leads at least once to an equal value, continue the loop until done continue arrs; } } // If it reaches here, it wasn't found in at least one array, so try next value continue arr1keys; } } return retArr; }; exports.array_intersect_key = function (arr1) { var retArr = {}, argl = arguments.length, arglm1 = argl - 1, k1 = '', arr = {}, i = 0, k = ''; arr1keys: for (k1 in arr1) { arrs: for (i = 1; i < argl; i++) { arr = arguments[i]; for (k in arr) { if (k === k1) { if (i === arglm1) { retArr[k1] = arr1[k1]; } // If the innermost loop always leads at least once to an equal value, continue the loop until done continue arrs; } } // If it reaches here, it wasn't found in at least one array, so try next value continue arr1keys; } } return retArr; }; exports.array_intersect_uassoc = function (arr1) { var retArr = {}, arglm1 = arguments.length - 1, arglm2 = arglm1 - 1, cb = arguments[arglm1], k1 = '', i = 1, arr = {}, k = ''; cb = (typeof cb === 'string') ? this.window[cb] : (Object.prototype.toString.call(cb) === '[object Array]') ? this.window[cb[0]][cb[1]] : cb; arr1keys: for (k1 in arr1) { arrs: for (i = 1; i < arglm1; i++) { arr = arguments[i]; for (k in arr) { if (arr[k] === arr1[k1] && cb(k, k1) === 0) { if (i === arglm2) { retArr[k1] = arr1[k1]; } // If the innermost loop always leads at least once to an equal value, continue the loop until done continue arrs; } } // If it reaches here, it wasn't found in at least one array, so try next value continue arr1keys; } } return retArr; }; exports.array_intersect_ukey = function (arr1) { var retArr = {}, arglm1 = arguments.length - 1, arglm2 = arglm1 - 1, cb = arguments[arglm1], k1 = '', i = 1, arr = {}, k = ''; cb = (typeof cb === 'string') ? this.window[cb] : (Object.prototype.toString.call(cb) === '[object Array]') ? this.window[cb[0]][cb[1]] : cb; arr1keys: for (k1 in arr1) { arrs: for (i = 1; i < arglm1; i++) { arr = arguments[i]; for (k in arr) { if (cb(k, k1) === 0) { if (i === arglm2) { retArr[k1] = arr1[k1]; } // If the innermost loop always leads at least once to an equal value, continue the loop until done continue arrs; } } // If it reaches here, it wasn't found in at least one array, so try next value continue arr1keys; } } return retArr; }; exports.array_key_exists = function (key, search) { if (!search || (search.constructor !== Array && search.constructor !== Object)) { return false; } return key in search; }; exports.array_keys = function (input, search_value, argStrict) { var search = typeof search_value !== 'undefined', tmp_arr = [], strict = !!argStrict, include = true, key = ''; if (input && typeof input === 'object' && input.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array return input.keys(search_value, argStrict); } for (key in input) { if (input.hasOwnProperty(key)) { include = true; if (search) { if (strict && input[key] !== search_value) { include = false; } else if (input[key] != search_value) { include = false; } } if (include) { tmp_arr[tmp_arr.length] = key; } } } return tmp_arr; }; exports.array_map = function (callback) { var argc = arguments.length, argv = arguments, glbl = this.window, obj = null, cb = callback, j = argv[1].length, i = 0, k = 1, m = 0, tmp = [], tmp_ar = []; while (i < j) { while (k < argc) { tmp[m++] = argv[k++][i]; } m = 0; k = 1; if (callback) { if (typeof callback === 'string') { cb = glbl[callback]; } else if (typeof callback === 'object' && callback.length) { obj = typeof callback[0] === 'string' ? glbl[callback[0]] : callback[0]; if (typeof obj === 'undefined') { throw 'Object not found: ' + callback[0]; } cb = typeof callback[1] === 'string' ? obj[callback[1]] : callback[1]; } tmp_ar[i++] = cb.apply(obj, tmp); } else { tmp_ar[i++] = tmp; } tmp = []; } return tmp_ar; }; exports.array_merge = function () { var args = Array.prototype.slice.call(arguments), argl = args.length, arg, retObj = {}, k = '', argil = 0, j = 0, i = 0, ct = 0, toStr = Object.prototype.toString, retArr = true; for (i = 0; i < argl; i++) { if (toStr.call(args[i]) !== '[object Array]') { retArr = false; break; } } if (retArr) { retArr = []; for (i = 0; i < argl; i++) { retArr = retArr.concat(args[i]); } return retArr; } for (i = 0, ct = 0; i < argl; i++) { arg = args[i]; if (toStr.call(arg) === '[object Array]') { for (j = 0, argil = arg.length; j < argil; j++) { retObj[ct++] = arg[j]; } } else { for (k in arg) { if (arg.hasOwnProperty(k)) { if (parseInt(k, 10) + '' === k) { retObj[ct++] = arg[k]; } else { retObj[k] = arg[k]; } } } } } return retObj; }; exports.array_multisort = function (arr) { var argl = arguments.length, sal = 0, flags = { 'SORT_REGULAR': 16, 'SORT_NUMERIC': 17, 'SORT_STRING': 18, 'SORT_ASC': 32, 'SORT_DESC': 40 }, sortArrs = [ [] ], sortFlag = [0], sortKeys = [ [] ], g = 0, i = 0, j = 0, k = '', l = 0, thingsToSort = [], vkey = 0, zlast = null, args = arguments, nLastSort = [], lastSort = [], lastSorts = [], tmpArray = [], elIndex = 0, sortDuplicator = function(a, b) { return nLastSort.shift(); }; sortFunctions = [ [function(a, b) { lastSort.push(a > b ? 1 : (a < b ? -1 : 0)); return a > b ? 1 : (a < b ? -1 : 0); }, function(a, b) { lastSort.push(b > a ? 1 : (b < a ? -1 : 0)); return b > a ? 1 : (b < a ? -1 : 0); }], [function(a, b) { lastSort.push(a - b); return a - b; }, function(a, b) { lastSort.push(b - a); return b - a; }], [function(a, b) { lastSort.push((a + '') > (b + '') ? 1 : ((a + '') < (b + '') ? -1 : 0)); return (a + '') > (b + '') ? 1 : ((a + '') < (b + '') ? -1 : 0); }, function(a, b) { lastSort.push((b + '') > (a + '') ? 1 : ((b + '') < (a + '') ? -1 : 0)); return (b + '') > (a + '') ? 1 : ((b + '') < (a + '') ? -1 : 0); }] ]; // Store first argument into sortArrs and sortKeys if an Object. // First Argument should be either a Javascript Array or an Object, otherwise function would return FALSE like in PHP if (Object.prototype.toString.call(arr) === '[object Array]') { sortArrs[0] = arr; } else if (arr && typeof arr === 'object') { for (i in arr) { if (arr.hasOwnProperty(i)) { sortKeys[0].push(i); sortArrs[0].push(arr[i]); } } } else { return false; } // arrMainLength: Holds the length of the first array. All other arrays must be of equal length, otherwise function would return FALSE like in PHP // // sortComponents: Holds 2 indexes per every section of the array that can be sorted. As this is the start, the whole array can be sorted. var arrMainLength = sortArrs[0].length, sortComponents = [0, arrMainLength]; // Loop through all other arguments, checking lengths and sort flags of arrays and adding them to the above variables. for (j = 1; j < argl; j++) { if (Object.prototype.toString.call(arguments[j]) === '[object Array]') { sortArrs[j] = arguments[j]; sortFlag[j] = 0; if (arguments[j].length !== arrMainLength) { return false; } } else if (arguments[j] && typeof arguments[j] === 'object') { sortKeys[j] = []; sortArrs[j] = []; sortFlag[j] = 0; for (i in arguments[j]) { if (arguments[j].hasOwnProperty(i)) { sortKeys[j].push(i); sortArrs[j].push(arguments[j][i]); } } if (sortArrs[j].length !== arrMainLength) { return false; } } else if (typeof arguments[j] === 'string') { var lFlag = sortFlag.pop(); if (typeof flags[arguments[j]] === 'undefined' || ((((flags[arguments[j]]) >>> 4) & (lFlag >>> 4)) > 0)) { // Keep extra parentheses around latter flags check to avoid minimization leading to CDATA closer return false; } sortFlag.push(lFlag + flags[arguments[j]]); } else { return false; } } for (i = 0; i !== arrMainLength; i++) { thingsToSort.push(true); } // Sort all the arrays.... for (i in sortArrs) { if (sortArrs.hasOwnProperty(i)) { lastSorts = []; tmpArray = []; elIndex = 0; nLastSort = []; lastSort = []; // If ther are no sortComponents, then no more sorting is neeeded. Copy the array back to the argument. if (sortComponents.length === 0) { if (Object.prototype.toString.call(arguments[i]) === '[object Array]') { args[i] = sortArrs[i]; } else { for (k in arguments[i]) { if (arguments[i].hasOwnProperty(k)) { delete arguments[i][k]; } } sal = sortArrs[i].length; for (j = 0, vkey = 0; j < sal; j++) { vkey = sortKeys[i][j]; args[i][vkey] = sortArrs[i][j]; } } delete sortArrs[i]; delete sortKeys[i]; continue; } // Sort function for sorting. Either sorts asc or desc, regular/string or numeric. var sFunction = sortFunctions[(sortFlag[i] & 3)][((sortFlag[i] & 8) > 0) ? 1 : 0]; // Sort current array. for (l = 0; l !== sortComponents.length; l += 2) { tmpArray = sortArrs[i].slice(sortComponents[l], sortComponents[l + 1] + 1); tmpArray.sort(sFunction); lastSorts[l] = [].concat(lastSort); // Is there a better way to copy an array in Javascript? elIndex = sortComponents[l]; for (g in tmpArray) { if (tmpArray.hasOwnProperty(g)) { sortArrs[i][elIndex] = tmpArray[g]; elIndex++; } } } // Duplicate the sorting of the current array on future arrays. sFunction = sortDuplicator; for (j in sortArrs) { if (sortArrs.hasOwnProperty(j)) { if (sortArrs[j] === sortArrs[i]) { continue; } for (l = 0; l !== sortComponents.length; l += 2) { tmpArray = sortArrs[j].slice(sortComponents[l], sortComponents[l + 1] + 1); nLastSort = [].concat(lastSorts[l]); // alert(l + ':' + nLastSort); tmpArray.sort(sFunction); elIndex = sortComponents[l]; for (g in tmpArray) { if (tmpArray.hasOwnProperty(g)) { sortArrs[j][elIndex] = tmpArray[g]; elIndex++; } } } } } // Duplicate the sorting of the current array on array keys for (j in sortKeys) { if (sortKeys.hasOwnProperty(j)) { for (l = 0; l !== sortComponents.length; l += 2) { tmpArray = sortKeys[j].slice(sortComponents[l], sortComponents[l + 1] + 1); nLastSort = [].concat(lastSorts[l]); tmpArray.sort(sFunction); elIndex = sortComponents[l]; for (g in tmpArray) { if (tmpArray.hasOwnProperty(g)) { sortKeys[j][elIndex] = tmpArray[g]; elIndex++; } } } } } // Generate the next sortComponents zlast = null; sortComponents = []; for (j in sortArrs[i]) { if (sortArrs[i].hasOwnProperty(j)) { if (!thingsToSort[j]) { if ((sortComponents.length & 1)) { sortComponents.push(j - 1); } zlast = null; continue; } if (!(sortComponents.length & 1)) { if (zlast !== null) { if (sortArrs[i][j] === zlast) { sortComponents.push(j - 1); } else { thingsToSort[j] = false; } } zlast = sortArrs[i][j]; } else { if (sortArrs[i][j] !== zlast) { sortComponents.push(j - 1); zlast = sortArrs[i][j]; } } } } if (sortComponents.length & 1) { sortComponents.push(j); } if (Object.prototype.toString.call(arguments[i]) === '[object Array]') { args[i] = sortArrs[i]; } else { for (j in arguments[i]) { if (arguments[i].hasOwnProperty(j)) { delete arguments[i][j]; } } sal = sortArrs[i].length; for (j = 0, vkey = 0; j < sal; j++) { vkey = sortKeys[i][j]; args[i][vkey] = sortArrs[i][j]; } } delete sortArrs[i]; delete sortKeys[i]; } } return true; }; exports.array_pad = function (input, pad_size, pad_value) { var pad = [], newArray = [], newLength, diff = 0, i = 0; if (Object.prototype.toString.call(input) === '[object Array]' && !isNaN(pad_size)) { newLength = ((pad_size < 0) ? (pad_size * -1) : pad_size); diff = newLength - input.length; if (diff > 0) { for (i = 0; i < diff; i++) { newArray[i] = pad_value; } pad = ((pad_size < 0) ? newArray.concat(input) : input.concat(newArray)); } else { pad = input; } } return pad; }; exports.array_pop = function (inputArr) { var key = '', lastKey = ''; if (inputArr.hasOwnProperty('length')) { // Indexed if (!inputArr.length) { // Done popping, are we? return null; } return inputArr.pop(); } else { // Associative for (key in inputArr) { if (inputArr.hasOwnProperty(key)) { lastKey = key; } } if (lastKey) { var tmp = inputArr[lastKey]; delete(inputArr[lastKey]); return tmp; } else { return null; } } }; exports.array_product = function (input) { var idx = 0, product = 1, il = 0; if (Object.prototype.toString.call(input) !== '[object Array]') { return null; } il = input.length; while (idx < il) { product *= (!isNaN(input[idx]) ? input[idx] : 0); idx++; } return product; }; exports.array_push = function (inputArr) { var i = 0, pr = '', argv = arguments, argc = argv.length, allDigits = /^\d$/, size = 0, highestIdx = 0, len = 0; if (inputArr.hasOwnProperty('length')) { for (i = 1; i < argc; i++) { inputArr[inputArr.length] = argv[i]; } return inputArr.length; } // Associative (object) for (pr in inputArr) { if (inputArr.hasOwnProperty(pr)) { ++len; if (pr.search(allDigits) !== -1) { size = parseInt(pr, 10); highestIdx = size > highestIdx ? size : highestIdx; } } } for (i = 1; i < argc; i++) { inputArr[++highestIdx] = argv[i]; } return len + i - 1; }; exports.array_rand = function (input, num_req) { var indexes = []; var ticks = num_req || 1; var checkDuplicate = function(input, value) { var exist = false, index = 0, il = input.length; while (index < il) { if (input[index] === value) { exist = true; break; } index++; } return exist; }; if (Object.prototype.toString.call(input) === '[object Array]' && ticks <= input.length) { while (true) { var rand = Math.floor((Math.random() * input.length)); if (indexes.length === ticks) { break; } if (!checkDuplicate(indexes, rand)) { indexes.push(rand); } } } else { indexes = null; } return ((ticks == 1) ? indexes.join() : indexes); }; exports.array_reduce = function (a_input, callback) { var lon = a_input.length; var res = 0, i = 0; var tmp = []; for (i = 0; i < lon; i += 2) { tmp[0] = a_input[i]; if (a_input[(i + 1)]) { tmp[1] = a_input[(i + 1)]; } else { tmp[1] = 0; } res += callback.apply(null, tmp); tmp = []; } return res; }; exports.array_replace = function (arr) { var retObj = {}, i = 0, p = '', argl = arguments.length; if (argl < 2) { throw new Error('There should be at least 2 arguments passed to array_replace()'); } // Although docs state that the arguments are passed in by reference, it seems they are not altered, but rather the copy that is returned (just guessing), so we make a copy here, instead of acting on arr itself for (p in arr) { retObj[p] = arr[p]; } for (i = 1; i < argl; i++) { for (p in arguments[i]) { retObj[p] = arguments[i][p]; } } return retObj; }; exports.array_replace_recursive = function (arr) { var retObj = {}, i = 0, p = '', argl = arguments.length; if (argl < 2) { throw new Error('There should be at least 2 arguments passed to array_replace_recursive()'); } // Although docs state that the arguments are passed in by reference, it seems they are not altered, but rather the copy that is returned (just guessing), so we make a copy here, instead of acting on arr itself for (p in arr) { retObj[p] = arr[p]; } for (i = 1; i < argl; i++) { for (p in arguments[i]) { if (retObj[p] && typeof retObj[p] === 'object') { retObj[p] = this.array_replace_recursive(retObj[p], arguments[i][p]); } else { retObj[p] = arguments[i][p]; } } } return retObj; }; exports.array_reverse = function (array, preserve_keys) { var isArray = Object.prototype.toString.call(array) === '[object Array]', tmp_arr = preserve_keys ? {} : [], key; if (isArray && !preserve_keys) { return array.slice(0).reverse(); } if (preserve_keys) { var keys = []; for (key in array) { // if (array.hasOwnProperty(key)) { keys.push(key); // } } var i = keys.length; while (i--) { key = keys[i]; // FIXME: don't rely on browsers keeping keys in insertion order // it's implementation specific // eg. the result will differ from expected in Google Chrome tmp_arr[key] = array[key]; } } else { for (key in array) { // if (array.hasOwnProperty(key)) { tmp_arr.unshift(array[key]); // } } } return tmp_arr; }; exports.array_shift = function (inputArr) { var props = false, shift = undefined, pr = '', allDigits = /^\d$/, int_ct = -1, _checkToUpIndices = function(arr, ct, key) { // Deal with situation, e.g., if encounter index 4 and try to set it to 0, but 0 exists later in loop (need to // increment all subsequent (skipping current key, since we need its value below) until find unused) if (arr[ct] !== undefined) { var tmp = ct; ct += 1; if (ct === key) { ct += 1; } ct = _checkToUpIndices(arr, ct, key); arr[ct] = arr[tmp]; delete arr[tmp]; } return ct; }; if (inputArr.length === 0) { return null; } if (inputArr.length > 0) { return inputArr.shift(); } /* UNFINISHED FOR HANDLING OBJECTS for (pr in inputArr) { if (inputArr.hasOwnProperty(pr)) { props = true; shift = inputArr[pr]; delete inputArr[pr]; break; } } for (pr in inputArr) { if (inputArr.hasOwnProperty(pr)) { if (pr.search(allDigits) !== -1) { int_ct += 1; if (parseInt(pr, 10) === int_ct) { // Key is already numbered ok, so don't need to change key for value continue; } _checkToUpIndices(inputArr, int_ct, pr); arr[int_ct] = arr[pr]; delete arr[pr]; } } } if (!props) { return null; } return shift; */ }; exports.array_sum = function (array) { var key, sum = 0; if (array && typeof array === 'object' && array.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array return array.sum.apply(array, Array.prototype.slice.call(arguments, 0)); } // input sanitation if (typeof array !== 'object') { return null; } for (key in array) { if (!isNaN(parseFloat(array[key]))) { sum += parseFloat(array[key]); } } return sum; }; exports.array_udiff = function (arr1) { var retArr = {}, arglm1 = arguments.length - 1, cb = arguments[arglm1], arr = '', i = 1, k1 = '', k = ''; cb = (typeof cb === 'string') ? this.window[cb] : (Object.prototype.toString.call(cb) === '[object Array]') ? this.window[cb[0]][cb[1]] : cb; arr1keys: for (k1 in arr1) { for (i = 1; i < arglm1; i++) { arr = arguments[i]; for (k in arr) { if (cb(arr[k], arr1[k1]) === 0) { // If it reaches here, it was found in at least one array, so try next value continue arr1keys; } } retArr[k1] = arr1[k1]; } } return retArr; }; exports.array_udiff_assoc = function (arr1) { var retArr = {}, arglm1 = arguments.length - 1, cb = arguments[arglm1], arr = {}, i = 1, k1 = '', k = ''; cb = (typeof cb === 'string') ? this.window[cb] : (Object.prototype.toString.call(cb) === '[object Array]') ? this.window[cb[0]][cb[1]] : cb; arr1keys: for (k1 in arr1) { for (i = 1; i < arglm1; i++) { arr = arguments[i]; for (k in arr) { if (cb(arr[k], arr1[k1]) === 0 && k === k1) { // If it reaches here, it was found in at least one array, so try next value continue arr1keys; } } retArr[k1] = arr1[k1]; } } return retArr; }; exports.array_udiff_uassoc = function (arr1) { var retArr = {}, arglm1 = arguments.length - 1, arglm2 = arglm1 - 1, cb = arguments[arglm1], cb0 = arguments[arglm2], k1 = '', i = 1, k = '', arr = {}; cb = (typeof cb === 'string') ? this.window[cb] : (Object.prototype.toString.call(cb) === '[object Array]') ? this.window[cb[0]][cb[1]] : cb; cb0 = (typeof cb0 === 'string') ? this.window[cb0] : (Object.prototype.toString.call(cb0) === '[object Array]') ? this.window[cb0[0]][cb0[1]] : cb0; arr1keys: for (k1 in arr1) { for (i = 1; i < arglm2; i++) { arr = arguments[i]; for (k in arr) { if (cb0(arr[k], arr1[k1]) === 0 && cb(k, k1) === 0) { // If it reaches here, it was found in at least one array, so try next value continue arr1keys; } } retArr[k1] = arr1[k1]; } } return retArr; }; exports.array_uintersect = function (arr1) { var retArr = {}, arglm1 = arguments.length - 1, arglm2 = arglm1 - 1, cb = arguments[arglm1], k1 = '', i = 1, arr = {}, k = ''; cb = (typeof cb === 'string') ? this.window[cb] : (Object.prototype.toString.call(cb) === '[object Array]') ? this.window[cb[0]][cb[1]] : cb; arr1keys: for (k1 in arr1) { arrs: for (i = 1; i < arglm1; i++) { arr = arguments[i]; for (k in arr) { if (cb(arr[k], arr1[k1]) === 0) { if (i === arglm2) { retArr[k1] = arr1[k1]; } // If the innermost loop always leads at least once to an equal value, continue the loop until done continue arrs; } } // If it reaches here, it wasn't found in at least one array, so try next value continue arr1keys; } } return retArr; }; exports.array_uintersect_assoc = function (arr1) { var retArr = {}, arglm1 = arguments.length - 1, arglm2 = arglm1 - 2, cb = arguments[arglm1], k1 = '', i = 1, arr = {}, k = ''; cb = (typeof cb === 'string') ? this.window[cb] : (Object.prototype.toString.call(cb) === '[object Array]') ? this.window[cb[0]][cb[1]] : cb; arr1keys: for (k1 in arr1) { arrs: for (i = 1; i < arglm1; i++) { arr = arguments[i]; for (k in arr) { if (k === k1 && cb(arr[k], arr1[k1]) === 0) { if (i === arglm2) { retArr[k1] = arr1[k1]; } // If the innermost loop always leads at least once to an equal value, continue the loop until done continue arrs; } } // If it reaches here, it wasn't found in at least one array, so try next value continue arr1keys; } } return retArr; }; exports.array_uintersect_uassoc = function (arr1) { var retArr = {}, arglm1 = arguments.length - 1, arglm2 = arglm1 - 1, cb = arguments[arglm1], cb0 = arguments[arglm2], k1 = '', i = 1, k = '', arr = {}; cb = (typeof cb === 'string') ? this.window[cb] : (Object.prototype.toString.call(cb) === '[object Array]') ? this.window[cb[0]][cb[1]] : cb; cb0 = (typeof cb0 === 'string') ? this.window[cb0] : (Object.prototype.toString.call(cb0) === '[object Array]') ? this.window[cb0[0]][cb0[1]] : cb0; arr1keys: for (k1 in arr1) { arrs: for (i = 1; i < arglm2; i++) { arr = arguments[i]; for (k in arr) { if (cb0(arr[k], arr1[k1]) === 0 && cb(k, k1) === 0) { if (i === arguments.length - 3) { retArr[k1] = arr1[k1]; } continue arrs; // If the innermost loop always leads at least once to an equal value, continue the loop until done } } continue arr1keys; // If it reaches here, it wasn't found in at least one array, so try next value } } return retArr; }; exports.array_unique = function (inputArr) { var key = '', tmp_arr2 = {}, val = ''; var __array_search = function(needle, haystack) { var fkey = ''; for (fkey in haystack) { if (haystack.hasOwnProperty(fkey)) { if ((haystack[fkey] + '') === (needle + '')) { return fkey; } } } return false; }; for (key in inputArr) { if (inputArr.hasOwnProperty(key)) { val = inputArr[key]; if (false === __array_search(val, tmp_arr2)) { tmp_arr2[key] = val; } } } return tmp_arr2; }; exports.array_unshift = function (array) { var i = arguments.length; while (--i !== 0) { arguments[0].unshift(arguments[i]); } return arguments[0].length; }; exports.array_values = function (input) { var tmp_arr = [], key = ''; if (input && typeof input === 'object' && input.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array return input.values(); } for (key in input) { tmp_arr[tmp_arr.length] = input[key]; } return tmp_arr; }; exports.array_walk_recursive = function (array, funcname, userdata) { var key; if (typeof array !== 'object') { return false; } for (key in array) { if (typeof array[key] === 'object') { return this.array_walk_recursive(array[key], funcname, userdata); } if (typeof userdata !== 'undefined') { eval(funcname + '( array [key] , key , userdata )'); } else { eval(funcname + '( userdata ) '); } } return true; }; exports.compact