-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gravityforms-minmax.js
executable file
·88 lines (71 loc) · 2.71 KB
/
gravityforms-minmax.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* Gravity Forms MIN/MAX Calculations
* Version 0.4.1
*
* Add MIN/MAX functions to Gravity Forms calculation
*
* Thanks to @michaeldozark for gravityforms-exponent plugin:
* https://github.com/michaeldozark/gravityforms-exponents
*
*/
gform.addFilter( 'gform_calculation_result', function( result, formulaField, formId, calcObj ) {
/**
* Only evaluate if the field has MIN/MAX present
*
* Technically we should be able to run any formulas through this without
* breaking them, but this way we save some small amount of processing
*
* @link https://www.w3schools.com/jsref/jsref_indexof.asp
* Description of `indexOf` method
*/
if ( formulaField.formula.indexOf( 'MIN' ) > -1 || formulaField.formula.indexOf( 'MAX' ) > -1 ) {
/**
* Replace field tags with their associated values
*
* @param int formId The ID of the form in use
* @param string formula The value of the "Formula" field entered in
* the form admin
* @param object formulaField The current calculation field object
* @var string fieldFormula
*/
let fieldFormula = calcObj.replaceFieldTags( formId, formulaField.formula, formulaField );
/**
* Sanitize the formula in case we have malicious user inputs. This
* prevents malicious code getting passed to our `eval` call later in the
* function
*
* We are stripping out anything that is not a number, decimal, space,
* parentheses, or simple arithmetical operator.
*
* @link https://www.w3schools.com/jsref/jsref_replace.asp
* Description of `replace` method
*/
const pattern = /\(?(MIN|MAX)\(([\d\s\W]+)\s*\)/gi;
// Remove leading & ending parentheses if present
while (fieldFormula[0] === '(' && fieldFormula.slice(-1) === ')') {
fieldFormula = fieldFormula.substr(1, fieldFormula.length - 2);
}
matches = fieldFormula.match(pattern);
let replaces = [];
for(let i in matches) {
let components = /\(?(MIN|MAX)\(([\d\s\W]+)\s*\)/gi.exec(matches[i]);
let values = components[2].split(',').map((value,index,array) => {
return parseFloat(eval(value.trim()));
});
if (components[1] == "MIN") replaces.push([matches[i], , Math.min(...values)]);
if (components[1] == "MAX") replaces.push([matches[i], , Math.max(...values)]);
}
for(let i in replaces) {
fieldFormula = fieldFormula.replace(replaces[i][0], replaces[i][2]);
}
fieldFormula = fieldFormula.replace( /[^0-9\s\n\r\+\-\*\/\^\(\)\.](MIN|MAX)/g, '' );
/**
* Set calculation result equal to evaluated string
*
* @link https://www.w3schools.com/jsref/jsref_eval.asp
* Description of `eval` function
*/
result = eval(fieldFormula);
}
return result;
});