acf
This commit is contained in:
		
							
								
								
									
										455
									
								
								plugins/system/nrframework/NRFramework/Conditions/Condition.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										455
									
								
								plugins/system/nrframework/NRFramework/Conditions/Condition.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,455 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @author          Tassos Marinos <info@tassos.gr> | ||||
|  * @link            https://www.tassos.gr | ||||
|  * @copyright       Copyright © 2024 Tassos All Rights Reserved | ||||
|  * @license         GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later | ||||
|  */ | ||||
|  | ||||
| namespace NRFramework\Conditions; | ||||
|  | ||||
| defined('_JEXEC') or die; | ||||
|  | ||||
| use Joomla\Registry\Registry; | ||||
| use Joomla\String\StringHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
|  | ||||
| /** | ||||
|  *  Assignment Class | ||||
|  */ | ||||
| class Condition | ||||
| { | ||||
| 	/** | ||||
| 	 *  Application Object | ||||
| 	 * | ||||
| 	 *  @var  object | ||||
| 	 */ | ||||
| 	protected $app; | ||||
|  | ||||
| 	/** | ||||
| 	 *  Document Object | ||||
| 	 * | ||||
| 	 *  @var  object | ||||
| 	 */ | ||||
| 	protected $doc; | ||||
|  | ||||
| 	/** | ||||
| 	 *  Date Object | ||||
| 	 * | ||||
| 	 *  @var  object | ||||
| 	 */ | ||||
| 	protected $date; | ||||
|  | ||||
| 	/** | ||||
| 	 *  Database Object | ||||
| 	 * | ||||
| 	 *  @var  object | ||||
| 	 */ | ||||
| 	protected $db; | ||||
|  | ||||
| 	/** | ||||
| 	 *  User Object | ||||
| 	 * | ||||
| 	 *  @var  object | ||||
| 	 */ | ||||
| 	protected $user; | ||||
|  | ||||
| 	/** | ||||
| 	 *  Assignment Selection | ||||
| 	 * | ||||
| 	 *  @var  mixed | ||||
| 	 */ | ||||
| 	protected $selection; | ||||
|  | ||||
| 	/** | ||||
| 	 *  Assignment Parameters | ||||
| 	 * | ||||
| 	 *  @var  mixed | ||||
| 	 */ | ||||
| 	protected $params; | ||||
|  | ||||
| 	/** | ||||
| 	 *  Assignment State (Include|Exclude) | ||||
| 	 * | ||||
| 	 *  @var  string | ||||
| 	 */ | ||||
|     public $assignment; | ||||
|      | ||||
|     /** | ||||
|      *  Options | ||||
| 	 *  | ||||
| 	 *  @var  object | ||||
|      */ | ||||
|     public $options; | ||||
|      | ||||
|     /** | ||||
|      *  Framework factory object | ||||
| 	 *  | ||||
| 	 *  @var  object | ||||
|      */ | ||||
|     public $factory; | ||||
|  | ||||
| 	/** | ||||
| 	 * The default operator that will be used to compare haystack with needle. | ||||
| 	 * | ||||
| 	 * @var string | ||||
| 	 */ | ||||
| 	protected $operator; | ||||
|  | ||||
| 	/** | ||||
| 	 * Class constructor | ||||
| 	 * | ||||
| 	 * @param	array  $options		The rule options. Expected properties: selection, value, params | ||||
| 	 * @param   object $factory		The framework's factory class. | ||||
| 	 */ | ||||
| 	public function __construct($options = null, $factory = null) | ||||
| 	{ | ||||
|         $this->factory = is_null($factory) ? new \NRFramework\Factory() : $factory; | ||||
|  | ||||
| 		// Set General Joomla Objects | ||||
| 		$this->db   = $this->factory->getDbo(); | ||||
| 		$this->app  = $this->factory->getApplication(); | ||||
| 		$this->doc  = $this->factory->getDocument(); | ||||
| 		$this->user = $this->factory->getUser(); | ||||
|  | ||||
| 		$this->options = new Registry($options); | ||||
|  | ||||
| 		$this->setParams($this->options->get('params')); | ||||
| 		$this->setOperator($this->options->get('operator', 'includesSome')); | ||||
|  | ||||
| 		// For performance reasons we might move this inside the pass() method | ||||
| 		$this->setSelection($this->options->get('selection', '')); | ||||
|     } | ||||
|  | ||||
| 	/** | ||||
| 	 * Set the rule's user selected value | ||||
| 	 * | ||||
| 	 * @param	mixed	$selection | ||||
| 	 * @return 	object | ||||
| 	 */ | ||||
| 	public function setSelection($selection) | ||||
| 	{ | ||||
| 		$this->selection = $selection; | ||||
|  | ||||
| 		if (method_exists($this, 'prepareSelection')) | ||||
| 		{ | ||||
| 			$this->selection = $this->prepareSelection(); | ||||
| 		} | ||||
|  | ||||
| 		return $this; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Undocumented function | ||||
| 	 * | ||||
| 	 * @return void | ||||
| 	 */ | ||||
| 	public function getSelection() | ||||
| 	{ | ||||
| 		return $this->selection; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Set the operator that will be used for the comparison | ||||
| 	 * | ||||
| 	 * @param	string $operator | ||||
| 	 * @return	object | ||||
| 	 */ | ||||
| 	public function setOperator($operator) | ||||
| 	{ | ||||
| 		$this->operator = $operator; | ||||
| 		return $this; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Set the rule's parameters | ||||
| 	 * | ||||
| 	 * @param  array $params | ||||
| 	 */ | ||||
| 	public function setParams($params) | ||||
| 	{ | ||||
| 		$this->params = new Registry($params); | ||||
| 	} | ||||
|  | ||||
| 	public function getParams() | ||||
| 	{ | ||||
| 		return $this->params; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Checks the validitity of two values based on the given operator. | ||||
| 	 *  | ||||
| 	 * Consider converting this method as a Trait. | ||||
| 	 *  | ||||
| 	 * @param   mixed   $value | ||||
| 	 * @param   mixed   $selection | ||||
| 	 * @param   string  $operator | ||||
| 	 * @param   array   $options 	ignoreCase: true,false | ||||
| 	 *  | ||||
| 	 * @return  bool | ||||
| 	 */ | ||||
| 	public function passByOperator($value = null, $selection = null, $operator = null, $options = null) | ||||
| 	{ | ||||
| 		$value = is_null($value) ? $this->value() : $value; | ||||
|  | ||||
| 		if (!is_null($selection)) | ||||
| 		{ | ||||
| 			$this->setSelection($selection); | ||||
| 		} | ||||
|  | ||||
| 		$selection = $this->getSelection(); | ||||
|  | ||||
| 		$options = new Registry($options); | ||||
| 		$ignoreCase = $options->get('ignoreCase', true); | ||||
|  | ||||
| 		if (is_object($value)) | ||||
| 		{ | ||||
| 			$value = (array) $value; | ||||
| 		} | ||||
|  | ||||
| 		if (is_object($selection)) | ||||
| 		{ | ||||
| 			$selection = (array) $selection; | ||||
| 		} | ||||
|  | ||||
| 		if ($ignoreCase) | ||||
| 		{ | ||||
| 			if (is_string($value)) | ||||
| 			{ | ||||
| 				$value = strtolower($value); | ||||
| 			} | ||||
|  | ||||
| 			if (is_string($selection)) | ||||
| 			{ | ||||
| 				$selection = strtolower($selection); | ||||
| 			} | ||||
|  | ||||
| 			if (is_array($value)) | ||||
| 			{ | ||||
| 				$value = array_map('strtolower', $value); | ||||
| 			} | ||||
|  | ||||
| 			if (is_array($selection)) | ||||
| 			{ | ||||
| 				$selection = array_map(function($str) | ||||
| 				{ | ||||
| 					return is_null($str) ? '' : strtolower($str); | ||||
| 				}, $selection); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		$operator = (is_null($operator) OR empty($operator)) ? $this->operator : $operator; | ||||
| 		$pass = false; | ||||
|  | ||||
|         switch ($operator) | ||||
|         { | ||||
| 			case 'exists': | ||||
| 				$pass = !is_null($value); | ||||
| 				break; | ||||
|  | ||||
| 			// Determines whether haystack is empty. Accepts: array, string | ||||
|             case 'empty': | ||||
| 				if (is_array($value)) | ||||
| 				{ | ||||
| 					$pass = empty($value); | ||||
| 				} | ||||
|  | ||||
| 				if (is_string($value)) | ||||
| 				{ | ||||
| 					$pass = $value == '' || trim($value) == ''; | ||||
| 				} | ||||
|  | ||||
| 				if (is_bool($value)) | ||||
| 				{ | ||||
| 					$pass = !$value; | ||||
| 				} | ||||
| 				break; | ||||
|  | ||||
| 			case 'equals': | ||||
| 				if (is_array($selection) || is_array($value)) | ||||
| 				{ | ||||
| 					$pass = $this->passByOperator($value, $selection, 'includesSome', $options); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					$pass = $value == $selection; | ||||
| 				} | ||||
| 				break; | ||||
|  | ||||
| 			case 'contains': | ||||
| 				if (is_string($value) && is_string($selection)) | ||||
| 				{ | ||||
| 					$pass = strlen($selection) > 0 && strpos($value, $selection) !== false; | ||||
| 				} | ||||
|  | ||||
| 				break; | ||||
| 			// Determine whether haystack is less than needle. | ||||
| 			case 'less_than': | ||||
| 			case 'lowerthan': | ||||
| 			case 'lt': | ||||
| 				$pass = $value < $selection; | ||||
| 				break; | ||||
|  | ||||
| 			// Determine whether haystack is less than or equal to needle. | ||||
| 			case 'less_than_or_equal_to': | ||||
| 			case 'lowerthanequal': | ||||
| 			case 'lte': | ||||
| 				$pass = $value <= $selection; | ||||
| 				break; | ||||
|  | ||||
| 			// Determine whether haystack is greater than needle. | ||||
| 			case 'greater_than': | ||||
| 			case 'greaterthan': | ||||
| 			case 'gt': | ||||
| 				$pass = $value > $selection; | ||||
| 				break; | ||||
|  | ||||
| 			// Determine whether haystack is greater than or equal to needle. | ||||
| 			case 'greater_than_or_equal_to': | ||||
| 			case 'greterthanequal': | ||||
| 			case 'gte': | ||||
| 				$pass = $value >= $selection; | ||||
| 				break; | ||||
|  | ||||
| 			// Determine whether haystack contains all elements in needle. | ||||
| 			case 'includesAll': | ||||
| 			case 'containsall': | ||||
| 				$pass = count(array_intersect((array) $selection, (array) $value)) == count((array) $selection); | ||||
| 				break; | ||||
|  | ||||
| 			// Determine whether haystack contains at least one element from needle. | ||||
| 			case 'includesSome': | ||||
| 			case 'containsany': | ||||
| 				$pass = !empty(array_intersect((array) $value, (array) $selection)); | ||||
| 				break; | ||||
|  | ||||
| 			// Determine whether haystack contains at least one element from needle. Accepts; string, array. | ||||
| 			case 'includes': | ||||
| 				if (is_string($value) && $value != '' && is_string($selection) && $selection != '') | ||||
| 				{ | ||||
| 					if (StringHelper::strpos($value, $selection) !== false) | ||||
| 					{ | ||||
| 						$pass = true; | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				if (is_array($value) || is_array($selection)) | ||||
| 				{ | ||||
| 					$pass = $this->passByOperator($value, $selection, 'includesSome', $options); | ||||
| 				} | ||||
|  | ||||
| 				break; | ||||
|  | ||||
| 			// Determine whether haystack starts with needle. Accepts: string | ||||
|             case 'starts_with': | ||||
|                 $pass = StringHelper::substr($value, 0, StringHelper::strlen($selection)) === $selection; | ||||
| 				break; | ||||
| 			 | ||||
| 			// Determine whether haystack ends with needle. Accepts: string | ||||
|             case 'ends_with': | ||||
|                 $pass = StringHelper::substr($value, -StringHelper::strlen($selection)) === $selection; | ||||
| 				break; | ||||
|  | ||||
| 			// Determine whether value is in given range | ||||
|             case 'range': | ||||
| 				$value1 = isset($selection['value1']) ? (float) $selection['value1'] : false; | ||||
| 				$value2 = isset($selection['value2']) ? (float) $selection['value2'] : false; | ||||
|  | ||||
|                 $pass = $value1 && $value2 ? (($value >= $value1) && ($value <= $value2)) : false; | ||||
| 				break; | ||||
| 			 | ||||
| 			// Determine whether haystack equals to needle. Accepts any object. | ||||
| 			default: | ||||
| 				$pass = $value == $selection; | ||||
|         } | ||||
|  | ||||
| 		return $pass; | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      *  Base assignment check | ||||
|      *  | ||||
|      *  @return bool | ||||
|      */ | ||||
| 	public function pass() | ||||
| 	{	 | ||||
| 		return $this->passByOperator(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 *  Returns all parent rows | ||||
| 	 *  | ||||
| 	 *  This method doesn't belong here. Move it to Functions.php. | ||||
| 	 * | ||||
| 	 *  @param   integer  $id      Row primary key | ||||
| 	 *  @param   string   $table   Table name | ||||
| 	 *  @param   string   $parent  Parent column name | ||||
| 	 *  @param   string   $child   Child column name | ||||
| 	 * | ||||
| 	 *  @return  array             Array with IDs | ||||
| 	 */ | ||||
| 	public function getParentIds($id = 0, $table = 'menu', $parent = 'parent_id', $child = 'id') | ||||
| 	{ | ||||
| 		if (!$id) | ||||
| 		{ | ||||
| 			return []; | ||||
| 		} | ||||
|  | ||||
| 		$cache = $this->factory->getCache();  | ||||
| 		$hash  = md5('getParentIds_' . $id . '_' . $table . '_' . $parent . '_' . $child); | ||||
|  | ||||
| 		if ($cache->has($hash)) | ||||
| 		{ | ||||
| 			return $cache->get($hash); | ||||
| 		} | ||||
|  | ||||
| 		$parent_ids = array(); | ||||
|  | ||||
| 		while ($id) | ||||
| 		{ | ||||
| 			$query = $this->db->getQuery(true) | ||||
| 				->select('t.' . $parent) | ||||
| 				->from('#__' . $table . ' as t') | ||||
| 				->where('t.' . $child . ' = ' . (int) $id); | ||||
| 			$this->db->setQuery($query); | ||||
| 			$id = $this->db->loadResult(); | ||||
|  | ||||
| 			// Break if no parent is found or parent already found before for some reason | ||||
| 			if (!$id || in_array($id, $parent_ids)) | ||||
| 			{ | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			$parent_ids[] = $id; | ||||
| 		} | ||||
|  | ||||
| 		return $cache->set($hash, $parent_ids); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * A one-line text that describes the current value detected by the rule. Eg: The current time is %s. | ||||
| 	 * | ||||
| 	 * @return string | ||||
| 	 */ | ||||
| 	public function getValueHint() | ||||
| 	{ | ||||
| 		$value = $this->value(); | ||||
|  | ||||
| 		// If the rule returns an array, use the 1st one. | ||||
| 		$value = is_array($value) ? $value[0] : $value; | ||||
|  | ||||
| 		return Text::sprintf('NR_DISPLAY_CONDITIONS_HINT_' . strtoupper($this->getName()), ucfirst(strtolower($value))); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Return the rule name | ||||
| 	 * | ||||
| 	 * @return string | ||||
| 	 */ | ||||
| 	protected function getName() | ||||
| 	{ | ||||
| 		$classParts = explode('\\', get_called_class()); | ||||
| 		return array_pop($classParts); | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user