Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
chromed
/
wp-content
/
plugins
/
advanced-access-manager
/
application
/
Framework
/
Policy
:
Condition.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php /** * ====================================================================== * LICENSE: This file is subject to the terms and conditions defined in * * file 'license.txt', which is part of this source code package. * * ====================================================================== */ /** * AAM access policy condition evaluator * * @package AAM * @version 7.0.0 */ class AAM_Framework_Policy_Condition { /** * Map between condition type and method that evaluates the * group of conditions * * @var array * @access protected * * @version 7.0.0 */ protected $map = array( 'between' => 'evaluate_between', 'equals' => 'evaluate_equals', 'notequals' => 'evaluate_not_equals', 'greater' => 'evaluate_greater', 'less' => 'evaluate_less', 'greaterorequals' => 'evaluate_greater_or_equals', 'lessorequals' => 'evaluate_less_or_equals', 'in' => 'evaluate_in', 'notin' => 'evaluate_not_in', 'like' => 'evaluate_like', 'notlike' => 'evaluate_not_like', 'regex' => 'evaluate_regex' ); /** * Single instance of itself * * @var AAM_Framework_Policy_Condition * @access private * * @version 7.0.0 */ private static $_instance = null; /** * Constructor * * @access protected * * @version 7.0.0 */ protected function __construct() { } /** * Evaluate the group of conditions based on type * * @param array $conditions List of conditions * @param array $args Since 5.9 - Inline args for evaluation * * @return boolean * @access public * * @version 7.0.3 */ public function execute($conditions, $args = []) { // Determine if we have a logical operator defined if (isset($conditions['Operator'])) { $operator = strtoupper($conditions['Operator']); } else { $operator = 'AND'; } $res = ($operator === 'OR' ? null : true); // Making sure that OR is handled foreach ($conditions as $type => $group) { $type = strtolower($type); if ($type === 'operator') { continue; } elseif (isset($this->map[$type])) { $callback = array($this, $this->map[$type]); $group = $this->_prepare_condition_group($group); $group_operator = isset($group['Operator']) ? $group['Operator'] : 'OR'; $res = $this->_compute( $res, call_user_func($callback, $group, $args, $group_operator), $operator ); } else { $res = apply_filters( 'aam_policy_condition_result_filter', false, $type, $this->_prepare_conditions( $this->_prepare_condition_group($group), $args ), $args ); } } return $res; } /** * Evaluate group of BETWEEN conditions * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_between($conditions, $args, $operator) { $result = null; foreach ($this->_prepare_conditions($conditions, $args) as $condition) { if (isset($condition['right'][0]) && is_array($condition['right'][0])) { $right = $condition['right']; } else { $right = array($condition['right']); } foreach ($right as $subset) { if (is_a($subset, 'Closure')) { $result = $this->_compute( $result, $subset($condition['left']), $operator ); } else { list($min, $max) = $subset; $result = $this->_compute( $result, ($condition['left'] >= $min && $condition['left'] <= $max), $operator ); } } } return $result; } /** * Evaluate group of EQUALS conditions * * The values have to be identical * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_equals($conditions, $args, $operator) { $result = null; foreach ($this->_prepare_conditions($conditions, $args) as $condition) { foreach ($this->_prepare_right_operand($condition['right']) as $right) { $result = $this->_compute( $result, ($condition['left'] === $right), $operator ); } } return $result; } /** * Evaluate group of NOT EQUALs conditions * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_not_equals($conditions, $args, $operator) { $result = null; foreach ($this->_prepare_conditions($conditions, $args) as $condition) { foreach ($this->_prepare_right_operand($condition['right']) as $right) { $result = $this->_compute( $result, ($condition['left'] !== $right), $operator ); } } return $result; } /** * Evaluate group of GREATER THEN conditions * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_greater($conditions, $args, $operator) { $result = null; foreach ($this->_prepare_conditions($conditions, $args) as $condition) { foreach ($this->_prepare_right_operand($condition['right']) as $right) { $result = $this->_compute( $result, ($condition['left'] > $right), $operator ); } } return $result; } /** * Evaluate group of LESS THEN conditions * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_less($conditions, $args, $operator) { $result = null; foreach ($this->_prepare_conditions($conditions, $args) as $condition) { foreach ($this->_prepare_right_operand($condition['right']) as $right) { $result = $this->_compute( $result, ($condition['left'] < $right), $operator ); } } return $result; } /** * Evaluate group of GREATER OR EQUALS THEN conditions * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_greater_or_equals($conditions, $args, $operator) { $result = null; foreach ($this->_prepare_conditions($conditions, $args) as $condition) { foreach ($this->_prepare_right_operand($condition['right']) as $right) { $result = $this->_compute( $result, ($condition['left'] >= $right), $operator ); } } return $result; } /** * Evaluate group of LESS OR EQUALS THEN conditions * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_less_or_equals($conditions, $args, $operator) { $result = null; foreach ($this->_prepare_conditions($conditions, $args) as $condition) { foreach ($this->_prepare_right_operand($condition['right']) as $right) { $result = $this->_compute( $result, ($condition['left'] <= $right), $operator ); } } return $result; } /** * Evaluate group of IN conditions * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_in($conditions, $args, $operator) { $result = null; foreach ($this->_prepare_conditions($conditions, $args) as $condition) { // Transform the left and right operands, if necessary if (is_a($condition['left'], 'Closure')) { $left = $condition['left'](); // Left operand does not require any values to cb } else { $left = $condition['left']; } if (isset($condition['right'][0]) && is_array($condition['right'][0])) { $normalized_right = $condition['right']; } else { $normalized_right = array($condition['right']); } foreach ($normalized_right as $right) { if (is_a($right, 'Closure')) { $right = $right($left); // Right operand accepts left operand } // If both operands are arrays, then this condition verifies that the // left set of values is present in the right set of values if (is_array($left) && is_array($right)) { $ci = count(array_intersect($left, $right)); $result = $this->_compute( $result, count($left) === $ci, $operator ); } elseif (is_scalar($left) && is_array($right)) { $set_result = null; foreach($right as $value) { if (is_scalar($value)) { $set_result = $set_result || ($left === $value); } elseif (is_a($value, 'Closure')) { $set_result = $set_result || $value($left); } } $result = $this->_compute($result, $set_result, $operator); } } } return $result; } /** * Evaluate group of NOT IN conditions * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_not_in($conditions, $args, $operator) { return !$this->evaluate_in($conditions, $args, $operator); } /** * Evaluate group of LIKE conditions * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_like($conditions, $args, $operator) { $result = null; foreach ($this->_prepare_conditions($conditions, $args) as $condition) { foreach ($this->_prepare_right_operand($condition['right']) as $right) { $sub = str_replace( array('\*', '@'), array('.*', '\\@'), preg_quote($right) ); $result = $this->_compute( $result, preg_match('@^' . $sub . '$@', $condition['left']), $operator ); } } return $result; } /** * Evaluate group of NOT LIKE conditions * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_not_like($conditions, $args, $operator) { return !$this->evaluate_like($conditions, $args, $operator); } /** * Evaluate group of REGEX conditions * * @param array $conditions * @param array $args * @param string $operator * * @return boolean * @access protected * * @version 7.0.0 */ protected function evaluate_regex($conditions, $args, $operator) { $result = null; foreach ($this->_prepare_conditions($conditions, $args) as $condition) { foreach ($this->_prepare_right_operand($condition['right']) as $right) { $result = $this->_compute( $result, preg_match($right, $condition['left']), $operator ); } } return $result; } /** * Prepare conditions by replacing all defined tokens * * @param array $conditions * @param array $args * * @return array * @access private * * @version 7.0.0 */ private function _prepare_conditions($conditions, $args) { $result = []; if (is_array($conditions)) { foreach ($conditions as $left => $right) { if ($left !== 'Operator') { $result[] = array( 'left' => $this->_parse_expression($left, $args), 'right' => $this->_parse_expression($right, $args) ); } } } return $result; } /** * Parse condition and try to replace all defined tokens * * @param mixed $exp Part of the condition (either left or right) * @param array $args Inline arguments * * @return mixed Prepared part of the condition or false on failure * @access private * * @version 7.0.0 */ private function _parse_expression($exp, $args) { if (is_scalar($exp)) { $exp = AAM_Framework_Policy_Marker::execute($exp, $args); } elseif (is_array($exp) || is_object($exp)) { foreach ($exp as &$value) { $value = $this->_parse_expression($value, $args); } } elseif (is_null($exp) === false) { $exp = false; } return $exp; } /** * Compute the logical expression * * @param boolean $left * @param boolean $right * @param string $operator * * @return boolean|null * @access private * * @version 7.0.0 */ private function _compute($left, $right, $operator) { $upper = strtoupper($operator); $result = null; // The first condition that checks for null is super important to ensure that // we cover the first condition in chain if ($left === null) { $result = $right; } elseif ($upper === 'AND') { $result = $left && $right; } elseif ($upper === 'OR') { $result = $left || $right; } return $result; } /** * Prepare the right operand * * @param mixed $right * * @return array * @access private * * @version 7.0.0 */ private function _prepare_right_operand($right) { if (is_array($right)) { // Naming collision? $response = $right; } else { $response = array($right); } return $response; } /** * Prepare condition group * * @param array $group * * @return array * @access private * * @version 7.0.0 */ private function _prepare_condition_group($group) { $response = []; // Taking into consideration legacy format like // { // "Equals": [ // { "${USER.email}": "a" }, // { "${USER.email}": "b" } // ] // } if (isset($group[0]) && is_array($group[0])) { // Array of arrays? foreach($group as $subset) { foreach($subset as $key => $value) { if (isset($response[$key])) { if (is_scalar($response[$key])) { $response[$key] = array($response[$key]); } array_push($response[$key], $value); } else { $response[$key] = $value; } } } } else { // Otherwise assume a normal conditional group $response = $group; } return $response; } /** * Bootstrap the object * * @return AAM_Framework_Policy_Condition * @access public * * @version 7.0.0 */ public static function bootstrap() { if (is_null(self::$_instance)) { self::$_instance = new self; } return self::$_instance; } /** * Get single instance of itself * * @return AAM_Framework_Policy_Condition * @access public * * @version 7.0.0 */ public static function get_instance() { return self::bootstrap(); } }