Skip to content

Commit e2fa0ad

Browse files
author
Wazabii
committed
Added EventHandler
1 parent 249e69f commit e2fa0ad

File tree

3 files changed

+167
-8
lines changed

3 files changed

+167
-8
lines changed

EventHandler.php

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MaplePHP\Container;
6+
7+
use MaplePHP\Container\Interfaces\EventInterface;
8+
use MaplePHP\Container\Reflection;
9+
use BadMethodCallException;
10+
11+
/**
12+
* Create an event handler that will listent to a certain method in class
13+
*/
14+
class EventHandler
15+
{
16+
private $handler;
17+
private $event;
18+
private $bindable = [];
19+
private $stopPropagate = false;
20+
21+
/**
22+
* Add a class handler that you want to listen to
23+
* @param object|string $handler
24+
* @return void
25+
*/
26+
public function addHandler(object|string $handler, string|array $method = null): void
27+
{
28+
if (!is_array($method)) {
29+
$method = [$method];
30+
}
31+
32+
if (is_object($handler)) {
33+
$this->handler[] = [$handler, $method];
34+
} else {
35+
$reflect = new Reflection($handler);
36+
$this->handler[] = [$reflect->get(), $method];
37+
}
38+
}
39+
40+
/**
41+
* Attach an event to a method that exist in handler
42+
* @param string $method
43+
* @param callable $event
44+
* @return void
45+
*/
46+
public function addEvent(callable|object|string $event, ?string $bind = null): void
47+
{
48+
if(is_string($event)) {
49+
$reflect = new Reflection($event);
50+
$event = $reflect->get();
51+
}
52+
53+
if(is_object($event) && !($event instanceof EventInterface)) {
54+
throw new \Exception("Event object/class needs to be instance of \"EventInterface\"!", 1);
55+
}
56+
57+
if (is_null($bind)) {
58+
$this->event[] = $event;
59+
} else {
60+
$this->event[] = [$bind => $event];
61+
}
62+
}
63+
64+
/**
65+
* Make sure event only is executed once!
66+
* @param bool $stopPropagate
67+
* @return void
68+
*/
69+
public function stopPropagation(bool $stopPropagate): void
70+
{
71+
$this->stopPropagate = $stopPropagate;
72+
}
73+
74+
75+
/**
76+
* Release the listener
77+
* @param string $method
78+
* @param array $args
79+
* @return mixed
80+
*/
81+
public function __call(string $method, array $args): mixed
82+
{
83+
$data = null;
84+
foreach ($this->handler as $handler) {
85+
/*
86+
if (!method_exists($handler[0], $method)) {
87+
throw new BadMethodCallException("The method \"".$method."\" does not exist in the class (" . $handler[0]::class . ")", 1);
88+
}
89+
*/
90+
if (is_null($handler[1][0]) || in_array($method, $handler[1])) {
91+
$this->bindable[$method] = $method;
92+
}
93+
$data = call_user_func_array([$handler[0], $method], $args);
94+
}
95+
96+
if (isset($this->bindable[$method])) {
97+
$this->triggerEvents();
98+
}
99+
return $data;
100+
}
101+
102+
/**
103+
* Trigger event
104+
* @return void
105+
*/
106+
final protected function triggerEvents(): void
107+
{
108+
if (is_null($this->event)) {
109+
throw new \Exception("Event has not been initiated", 1);
110+
}
111+
112+
113+
foreach ($this->event as $key => $event) {
114+
if (is_array($event)) {
115+
$select = key($event);
116+
if (isset($this->bindable[$select])) {
117+
$this->getEvent($event[$select]);
118+
}
119+
} else {
120+
$this->getEvent($event);
121+
}
122+
// Execute event once!
123+
if ($this->stopPropagate) {
124+
unset($this->event[$key]);
125+
}
126+
}
127+
}
128+
129+
/**
130+
* Resolve event
131+
* @param callable|object $data
132+
* @return void
133+
*/
134+
final protected function getEvent(callable|object $data): void
135+
{
136+
if(is_object($data)) {
137+
$data->resolve();
138+
} else {
139+
$data();
140+
}
141+
}
142+
}

Interfaces/EventInterface.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MaplePHP\Container\Interfaces;
6+
7+
/**
8+
* Used to pass a service to the event handler
9+
*/
10+
interface EventInterface
11+
{
12+
13+
public function resolve(): void;
14+
}

Reflection.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,18 @@ public function allowInterfaces(bool $bool): void
6868
*/
6969
public function dependencyInjector(): object
7070
{
71-
$params = $this->reflect->getConstructor()->getParameters();
72-
$this->injectRecursion($params, $this->reflect->getName());
73-
7471
$args = array();
75-
foreach ($params as $param) {
76-
if ($param->getType() && !$param->getType()->isBuiltin()) {
77-
$classKey = $param->getType()->getName();
78-
if (isset(self::$class[$classKey])) {
79-
$args[] = self::$class[$classKey];
72+
$constructor = $this->reflect->getConstructor();
73+
if(!is_null($constructor)) {
74+
$params = $constructor->getParameters();
75+
$this->injectRecursion($params, $this->reflect->getName());
76+
77+
foreach ($params as $param) {
78+
if ($param->getType() && !$param->getType()->isBuiltin()) {
79+
$classKey = $param->getType()->getName();
80+
if (isset(self::$class[$classKey])) {
81+
$args[] = self::$class[$classKey];
82+
}
8083
}
8184
}
8285
}

0 commit comments

Comments
 (0)