1. Go to this page and download the library: Download cmatosbc/clotho library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
cmatosbc / clotho example snippets
use Clotho\Attribute\EventBefore;
use Clotho\Attribute\EventAfter;
class UserService
{
#[EventBefore('user.create')]
#[EventAfter('user.create')]
public function createUser(string $name, string $email): array
{
return [
'id' => 1,
'name' => $name,
'email' => $email,
];
}
}
// Set up the event system
$dispatcher = new EventDispatcher();
$handler = new EventAttributeHandler($dispatcher);
// Add event listeners
$dispatcher->addEventListener('user.create', function (array $payload) {
echo "User creation started with email: " . $payload['arguments'][1];
});
// Wrap and use the method
$service = new UserService();
$createUser = $handler->wrapMethod($service, 'createUser');
$result = $createUser('John Doe', '[email protected]');
use Clotho\Event\BeforeMethodEvent;
use Clotho\Event\AfterMethodEvent;
class OrderService
{
#[EventBefore]
public function submitOrder(array $items): array
{
return ['order_id' => 123, 'items' => $items];
}
}
// Higher priority listeners execute first
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
// Validate stock levels
if (!$this->checkStock($event->getArguments()[0])) {
$event->stopPropagation();
}
}, 20);
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
// Check user credit
}, 10);
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
// Log order attempt
}, 0);
// After events with priority
$dispatcher->addEventListener(AfterMethodEvent::class, function (AfterMethodEvent $event) {
// High priority post-processing
$result = $event->getResult();
// Process order result
}, 20);
// Listen to all user events
$dispatcher->addEventListener('user.*', function ($payload) {
echo "User operation detected: " . $payload['event'];
});
// Listen to all create operations
$dispatcher->addEventListener('*.create', function ($payload) {
echo "Create operation detected in module: " . $payload['module'];
});
class UserService
{
#[EventBefore('user.profile.update')]
#[EventBefore('user.settings.update')]
public function updateUserData(string $section, array $data): array
{
return ['section' => $section, 'data' => $data];
}
}
class GroupService
{
#[EventBefore('admin.group:create')]
#[EventBefore('user.group:update')]
public function manageGroup(string $operation, array $data): array
{
return ['operation' => $operation, 'data' => $data];
}
}
// Listen to all group creation events
$dispatcher->addEventListener('*.group:create', function ($payload) {
echo "Group creation in progress...";
});
use Clotho\Event\BeforeMethodEvent;
class UserService
{
#[EventBefore]
public function deleteUser(int $userId): bool
{
// Delete user logic
return true;
}
}
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
if (!$this->hasPermission('delete_users')) {
echo "Permission denied";
$event->stopPropagation();
return;
}
}, 20);
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
// This won't execute if the previous listener stops propagation
echo "Deleting user...";
}, 10);
use Clotho\Event\BeforeMethodEvent;
use Clotho\Event\AfterMethodEvent;
use Clotho\Attribute\EventBefore;
use Clotho\Attribute\EventAfter;
class UserService
{
#[EventBefore('user.create')]
#[EventAfter('user.create')]
public function createUser(string $name, string $email): array
{
return [
'id' => 1,
'name' => $name,
'email' => $email,
];
}
}
// Listen for event objects (useful for priority-based handling)
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
$arguments = $event->getArguments();
echo "Creating user: " . $arguments[0];
}, 20);
// Listen for named events (useful for domain-specific handling)
$dispatcher->addEventListener('user.create', function (array $payload) {
$event = $payload['event']; // BeforeMethodEvent or AfterMethodEvent
$arguments = $payload['arguments'];
echo "User creation event: " . $arguments[0];
});
use Clotho\Event\BeforeMethodEvent;
use Clotho\Event\AfterMethodEvent;
use Clotho\Event\BeforeFunctionEvent;
use Clotho\Event\AfterFunctionEvent;
// Listen for method events
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
$methodName = $event->getMethodName();
$arguments = $event->getArguments();
if (!$this->isValid($arguments)) {
$event->stopPropagation();
}
}, 10);
// Listen for after events with results
$dispatcher->addEventListener(AfterMethodEvent::class, function (AfterMethodEvent $event) {
if ($event->hasException()) {
$this->handleError($event->getException());
return;
}
$result = $event->getResult();
$this->processResult($result);
});
use Clotho\Event\BeforeMethodEvent;
// High priority validation
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
// Runs first (priority 20)
if (!$this->hasPermission()) {
$event->stopPropagation();
}
}, 20);
// Normal priority logging
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
// Runs second (priority 10)
$this->logAccess($event->getMethodName());
}, 10);
// Low priority operations
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
// Runs last (priority 0)
$this->notify($event->getMethodName());
}, 0);
use Clotho\Event\BeforeMethodEvent;
class UserService
{
#[EventBefore]
public function deleteUser(int $userId): void
{
// Delete user logic
}
}
// High priority security check
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
if (!$this->hasPermission('delete_users')) {
$event->stopPropagation(); // Prevents further listeners from executing
throw new SecurityException('Permission denied');
}
}, 20);
// This won't execute if permission check fails
$dispatcher->addEventListener(BeforeMethodEvent::class, function (BeforeMethodEvent $event) {
$this->logDeletion($event->getArguments()[0]);
}, 10);
use Clotho\Exception\EventDispatchException;
use Clotho\Exception\EventListenerException;
use Clotho\Exception\EventPropagationException;
// Invalid event name
try {
$dispatcher->dispatch(''); // Empty event name
} catch (EventDispatchException $e) {
// Handles dispatch-related errors:
// - Empty or invalid event names
// - Errors thrown by event listeners
}
// Invalid listener priority
try {
// Priority must be between -100 and 100
$dispatcher->addEventListener('user.create', $listener, 150);
} catch (EventListenerException $e) {
// Handles listener-related errors:
// - Invalid priority values
// - Invalid listener types
}
// 1. Events with no listeners - perfectly valid
$dispatcher->dispatch('user.created', ['id' => 123]);
// 2. Stopping event propagation - normal control flow
$dispatcher->addEventListener('user.delete', function (BeforeMethodEvent $event) {
if (!$this->hasPermission()) {
$event->stopPropagation(); // Stops further listeners, no exception
return;
}
// Process the event
}, 20);
// 3. Wildcard events with no matches - also valid
$dispatcher->dispatch('custom.event');
[
'event' => BeforeMethodEvent, // The actual event object
'object' => object, // The object instance the method belongs to
'method' => string, // Name of the method being called
'arguments' => array, // Array of arguments passed to the method
]
[
'event' => AfterMethodEvent, // The actual event object
'object' => object, // The object instance the method belongs to
'method' => string, // Name of the method being called
'arguments' => array, // Array of arguments passed to the method
'result' => mixed, // The return value from the method (if successful)
'exception' => Throwable|null // Exception object if method threw an exception
]
[
'event' => BeforeFunctionEvent, // The actual event object
'function' => string, // Name of the function being called
'arguments' => array, // Array of arguments passed to the function
]
[
'event' => AfterFunctionEvent, // The actual event object
'function' => string, // Name of the function being called
'arguments' => array, // Array of arguments passed to the function
'result' => mixed, // The return value from the function (if successful)
'exception' => Throwable|null // Exception object if function threw an exception
]
use Clotho\Attribute\EventBefore;
use Clotho\Attribute\EventAfter;
class UserService
{
#[EventBefore('user.create')]
#[EventAfter('user.create')]
public function createUser(string $name, string $email): array
{
return [
'id' => 1,
'name' => $name,
'email' => $email,
];
}
}
// Access payload in before event
$dispatcher->addEventListener('user.create', function (array $payload) {
$event = $payload['event']; // BeforeMethodEvent instance
$object = $payload['object']; // UserService instance
$method = $payload['method']; // "createUser"
$arguments = $payload['arguments']; // [$name, $email]
echo "Creating user {$arguments[0]} with email {$arguments[1]}";
});
// Access payload in after event
$dispatcher->addEventListener('user.create', function (array $payload) {
if (isset($payload['exception'])) {
echo "Error creating user: " . $payload['exception']->getMessage();
return;
}
$result = $payload['result']; // The returned user array
echo "Created user with ID: {$result['id']}";
});
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.