Repository navigation
Expand file tree
/
Copy path04_common_events.php
More file actions
139 lines (102 loc) · 5.54 KB
/
Copy path04_common_events.php
File metadata and controls
139 lines (102 loc) · 5.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?php
declare(strict_types=1);
/**
* Example 04 — CommonEvents Helpers
*
* CommonEvents provides ready-made callback pairs (data + closure) for
* common operations on objects — including those with protected properties.
*
* Each helper (getter, setter, adding, etc.) returns [Meta, callable].
* You pass them to EventExecutor::run() using the spread operator:
*
* EventExecutor::run($instance, 'event_name', ...CommonEvents::setter([...]))
* ^^^
* This unpacks [Meta, callable] into the $data and $hooks parameters.
*
* Helpers: getter, setter, adding, append, removing, cleanup
* Safe reflection: safeAttributeGet/Set/Has/Unset/Add/Append, safeCallMethod
*/
require __DIR__ . '/../vendor/autoload.php';
use Minfra\Chains\EventExecutor;
use Minfra\Chains\EventInterface;
use Minfra\Chains\CommonEvents;
use Minfra\Chains\Meta;
use Minfra\Chains\Result;
use Minfra\Chains\BasicResultInterface;
echo "=== 04: CommonEvents Helpers ===\n\n";
// A class with protected properties — no public setters!
$user = new class {
protected string $name = '';
protected string $email = '';
protected array $roles = [];
protected array $logs = [];
};
// ---- 4a. setter — set protected properties through events ----
// CommonEvents::setter(['name' => 'Alice']) returns [Meta, callable]
// The spread operator (...) maps them to $data and $hooks parameters
EventExecutor::run($user, 'set_name', ...CommonEvents::setter(['name' => 'Alice', 'email' => 'alice@example.com']));
echo "4a) setter -> name: " . CommonEvents::safeAttributeGet($user, 'name') . "\n";
echo " email: " . CommonEvents::safeAttributeGet($user, 'email') . "\n\n";
// ---- 4b. getter — read & validate a property ----
$result = EventExecutor::run($user, 'get_name', ...CommonEvents::getter('name', CommonEvents::safeAttributeGet($user, 'name')));
echo "4b) getter -> ok=" . ($result->ok() ? 'true' : 'false') . ", name={$result->data()->name}\n";
// getter with missing value
$empty = new class { protected ?string $token = null; };
$result = EventExecutor::run($empty, 'get_token', ...CommonEvents::getter('token', null));
echo " getter (null) -> ok=" . ($result->ok() ? 'true' : 'false') . ", status={$result->status()}\n\n";
// ---- 4c. adding — push items into an array property ----
EventExecutor::run($user, 'add_role', ...CommonEvents::adding('roles', ['admin']));
EventExecutor::run($user, 'add_role', ...CommonEvents::adding('roles', ['editor']));
$roles = CommonEvents::safeAttributeGet($user, 'roles');
echo "4c) adding -> roles: " . implode(', ', $roles) . "\n\n";
// ---- 4d. append — push into a nested array by index ----
EventExecutor::run($user, 'add_log', ...CommonEvents::append('logs', 'auth', ['login at 10:00']));
EventExecutor::run($user, 'add_log', ...CommonEvents::append('logs', 'auth', ['logout at 11:00']));
$logs = CommonEvents::safeAttributeGet($user, 'logs');
echo "4d) append -> logs['auth']: " . implode(', ', $logs['auth']) . "\n\n";
// ---- 4e. removing — unset properties ----
EventExecutor::run($user, 'remove_email', ...CommonEvents::removing(['email']));
echo "4e) removing -> email exists: " . (CommonEvents::safeAttributeHas($user, 'email') ? 'yes' : 'no') . "\n\n";
// ---- 4f. cleanup — reset a property to a given value ----
EventExecutor::run($user, 'clear_roles', ...CommonEvents::cleanup('roles', []));
$roles = CommonEvents::safeAttributeGet($user, 'roles');
echo "4f) cleanup -> roles: " . (empty($roles) ? '(empty)' : implode(', ', $roles)) . "\n\n";
// ---- 4g. setter on a container (nested object property) ----
// The "container" parameter tells setter to write into a child object's property.
// Note: the child must be a real class (not stdClass), because safeAttributeSet
// uses Closure::bindTo which requires a named class scope.
$app = new class {
protected object $config;
function __construct() {
$this->config = new class { protected bool $debug = false; protected string $version = '1.0'; };
}
};
EventExecutor::run($app, 'set_debug', ...CommonEvents::setter(['debug' => true], 'config'));
$debug = CommonEvents::safeAttributeGet(CommonEvents::safeAttributeGet($app, 'config'), 'debug');
echo "4g) setter (container) -> config.debug: " . ($debug ? 'true' : 'false') . "\n\n";
// ---- 4h. Combining CommonEvents with extra hooks ----
// When you need both CommonEvents helpers AND custom hooks, unpack
// the helper into $data and $callback, then build the hooks array.
$person = new class { protected int $age = 0; };
list($meta, $setter_cb) = CommonEvents::setter(['age' => -5]);
$result = EventExecutor::run($person, 'set_age', $meta, [
EventInterface::ON_BEFORE => function (Meta $d) {
if ($d->age < 0) {
return Result::false('age_must_be_positive', $d);
}
return null;
},
EventInterface::ON_MID => $setter_cb,
]);
echo "4h) setter + validation -> ok=" . ($result->ok() ? 'true' : 'false') . ", status={$result->status()}\n";
echo " age remains: " . CommonEvents::safeAttributeGet($person, 'age') . "\n";
// ---- 4i. Safe reflection utilities ----
$secret = new class {
private string $key = 'abc123';
private function getKey(): string { return $this->key; }
};
echo "\n4i) Safe reflection:\n";
echo " safeAttributeHas -> " . (CommonEvents::safeAttributeHas($secret, 'key') ? 'true' : 'false') . "\n";
echo " safeAttributeGet -> " . CommonEvents::safeAttributeGet($secret, 'key') . "\n";
echo " safeCallMethod -> " . CommonEvents::safeCallMethod([$secret, 'getKey']) . "\n";
echo "\n--- 04 done ---\n";