Server IP : 15.235.198.142 / Your IP : 216.73.216.91 Web Server : Apache/2.4.58 (Ubuntu) System : Linux ballsack 6.8.0-45-generic #45-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 30 12:02:04 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/rhodeworks/wp-content/plugins/really-simple-ssl/settings/src/utils/ |
Upload File : |
/** * Class for evaluating React conditions on a field. * If the current field has no react_conditions key, it is considered enabled by * default. */ export class ReactConditions { /** * Creates an instance of ReactConditions. * * @param {object} currentField - The field being evaluated. * @param {Array<object>} allFields - All field objects available for * evaluation. */ constructor(currentField, allFields) { this.currentField = currentField; this.allFields = allFields; this.disabledReason = this._getDefaultDisabledReason(); this.fieldConditionKeyBlocklist = ['disabledTooltipText']; } /** * Evaluates the react_conditions for the current field. * * @returns {boolean} Returns true if the conditions pass or if no * react_conditions are present; otherwise, false. */ isEnabled() { if (!this.currentField.react_conditions) return true; return this._evaluateGroup(this.currentField.react_conditions); } /** * Get the reason why the field is conditionally disabled. This reason is * stored in the field condition like so: [ send_notifications_email' => 1, 'disabledTooltipText' => 'foobar', ] */ getDisabledTooltipText() { return this.disabledReason; } /** * Get the default disabled reason for the field from the config. * @returns {string|*|string} * @private */ _getDefaultDisabledReason() { return (( this.currentField.hasOwnProperty('disabled') && this.currentField.hasOwnProperty('disabledTooltipText') && this.currentField.disabled ) ? this.currentField.disabledTooltipText : ''); } /** * Recursively evaluates a group of conditions. * * @param {object} group - A conditions group with an optional 'relation' * property (AND/OR) and subconditions. * @returns {boolean} True if the group evaluates to true. */ _evaluateGroup(group) { const relation = group.relation ? group.relation.toUpperCase() : 'AND'; // Evaluate each subcondition (ignoring the 'relation' key). const subResults = Object.keys(group) .filter(key => key !== 'relation') .map(key => { const subCondition = group[key]; if (typeof subCondition === 'object' && subCondition.hasOwnProperty('relation')) { return this._evaluateGroup(subCondition); } if (typeof subCondition === 'object') { return this._evaluateFieldConditions(subCondition); } return false; }); return relation === 'AND' ? subResults.every(result => result) : subResults.some(result => result); } /** * Evaluates a set of field conditions. * * @param {object} conditionObject - An object mapping field keys to * expected values. * @returns {boolean} True if every field condition passes. */ _evaluateFieldConditions(conditionObject) { // Skip the keys in the fieldConditionKeyBlocklist let allowedKeysOfGroup = Object.keys(conditionObject).filter(key => (!this.fieldConditionKeyBlocklist.includes(key))); let fieldEnabledBasedOnGroupedCondition = allowedKeysOfGroup.every(rawFieldKey => this._checkFieldCondition(rawFieldKey, conditionObject[rawFieldKey]) ); // If the field will be disabled due to this group of conditions, set // the disabled reason. No reason given? Then set an empty string to // override the default disabledTooltipText from the field config. // Example: field.id = '404_blocking_threshold' in path: // settings/config/fields/firewall.php if (fieldEnabledBasedOnGroupedCondition === false) { this.disabledReason = (conditionObject.hasOwnProperty('disabledTooltipText') ? conditionObject.disabledTooltipText : ''); } return fieldEnabledBasedOnGroupedCondition; } /** * Evaluates an individual field condition. * * @param {string} rawFieldKey - The field key, possibly prefixed with "!" * to indicate inversion. * @param {*} expectedValue - The expected value for the condition. * @returns {boolean} True if the field condition is met. */ _checkFieldCondition(rawFieldKey, expectedValue) { const isInverted = rawFieldKey.startsWith('!'); const fieldKey = isInverted ? rawFieldKey.substring(1) : rawFieldKey; const field = this.allFields.find(field => field.id === fieldKey); if (!field) return false; const conditionResult = this._evaluateField(field, expectedValue); return isInverted ? !conditionResult : conditionResult; } /** * Evaluates the condition for a specific field based on its type. * * @param {object} field - The field object. * @param {*} expectedValue - The expected value. * @returns {boolean} True if the field's actual value meets the expected * condition. */ _evaluateField(field, expectedValue) { const actualValue = field.value; switch (field.type) { case 'text_checkbox': return actualValue && actualValue.show === expectedValue; case 'checkbox': return actualValue == expectedValue; case 'multicheckbox': { const expectedArray = Array.isArray(expectedValue) ? expectedValue : [expectedValue]; return Array.isArray(actualValue) && actualValue.some(val => expectedArray.includes(val)); } case 'radio': return Array.isArray(expectedValue) ? expectedValue.includes(actualValue) : expectedValue === actualValue; default: if (expectedValue === true) { return actualValue === 1 || actualValue === '1' || actualValue === true; } if (expectedValue === false) { return actualValue === 0 || actualValue === '0' || actualValue === false; } if (typeof expectedValue === 'string' && expectedValue.includes('EMPTY')) { return Array.isArray(actualValue) ? actualValue.length === 0 : !actualValue; } return String(actualValue).toLowerCase() === String(expectedValue).toLowerCase(); } } }