Jump to content

Hook before WireHttp::send


Zeka
 Share

Recommended Posts

Hi.

Just dumb question.

How to prevent sending of a request from hook if some condition is met? 

$this->wire()->addHookBefore('WireHttp::send', $this, 'checkIfHostExist');

public function modifyPayloadData($event) {
	... do some check and prevent sending request
		exit(); /// ???
}

Thanks. 

Link to comment
Share on other sites

Hi you might call it dumb, but this is actually interesting, I was thinking is there any mechanism to /condition to stop a Hook from being called, so pardon this jargon, so I took the time to see if such exists

public function runHooks($method, $arguments, $type = 'method') {
		$result = array(
			'return' => null, 
			'numHooksRun' => 0, 
			'methodExists' => false,
			'replace' => false,
			);
		$realMethod = "___$method";
		if($type == 'method') $result['methodExists'] = method_exists($this, $realMethod);
		if(!$result['methodExists'] && !self::isHooked($method . ($type == 'method' ? '()' : ''))) {
			return $result; //  The condition for not running is when not hooked or method doesn't exist
		}
		$hooks = $this->getHooks($method);
		foreach(array('before', 'after') as $when) {
			if($type === 'method' && $when === 'after' && $result['replace'] !== true) {
				if($result['methodExists']) {
					$result['return'] = call_user_func_array(array($this, $realMethod), $arguments);
				} else {
					$result['return'] = null;
				}
			}
			foreach($hooks as $priority => $hook) {
				if(!$hook['options'][$when]) continue;
				if(!empty($hook['options']['objMatch'])) {
					$objMatch = $hook['options']['objMatch'];
					// object match comparison to determine at runtime whether to execute the hook
					if(is_object($objMatch)) {
						if(!$objMatch->matches($this)) continue;
					} else {
						if(((string) $this) != $objMatch) continue;
					}
				}
				
				if($type == 'method' && !empty($hook['options']['argMatch'])) {
					// argument comparison to determine at runtime whether to execute the hook
					$argMatches = $hook['options']['argMatch'];
					$matches = true;
					foreach($argMatches as $argKey => $argMatch) {
						$argVal = isset($arguments[$argKey]) ? $arguments[$argKey] : null;
						if(is_object($argMatch)) {
							// Selectors object
							if(is_object($argVal)) {
								$matches = $argMatch->matches($argVal);
							} else {
								// we don't work with non-object here
								$matches = false;
							}
						} else {
							if(is_array($argVal)) {
								// match any array element
								$matches = in_array($argMatch, $argVal);
							} else {
								// exact string match
								$matches = $argMatch == $argVal;
							}
						}
						if(!$matches) break;
					}
					if(!$matches) continue; // don't run hook
				}
				$event = new HookEvent(); 
				$event->object = $this;
				$event->method = $method;
				$event->arguments = $arguments;  
				$event->when = $when; 
				$event->return = $result['return']; 
				$event->id = $hook['id']; 
				$event->options = $hook['options']; 
				$toObject = $hook['toObject'];		
				$toMethod = $hook['toMethod']; 
				if(is_null($toObject)) $toMethod($event); 
					else $toObject->$toMethod($event); 
				$result['numHooksRun']++;
				if($when == 'before') {
					$arguments = $event->arguments; 
					$result['replace'] = $event->replace === true || $result['replace'] === true; 
					if($result['replace']) $result['return'] = $event->return;
				}
				if($when == 'after') $result['return'] = $event->return; 
			}	
		}
		return $result;
	}

As you can see there isn't any logic to stop hooks from running other than if the arguments are wrong and method doesn't exist or the method itself in question is not hookable. However using an exit should work since the exit method stop the execution of the current script. I think the concept of Hooks is you attaching to them and not stopping them.

But another alternative would be to remove the check from the hook and and have the check determining whether to call the WireHttp::send

Let me know if that suffices 

 

  • Like 1
Link to comment
Share on other sites

Can't you just return?

$this->wire()->addHookBefore('WireHttp::send', $this, 'functionName'); 

public function functionName($event) { 
	if ($something === true) {
		return;
	} 

	// continue
}

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...