Skip to content
This repository was archived by the owner on Jul 19, 2024. It is now read-only.

Commit 83a1082

Browse files
initial commit
0 parents  commit 83a1082

26 files changed

+1780
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.idea
2+
composer.lock
3+
vendor
4+
bin
5+
coverage
6+
coverage.xml

.travis.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
language: php
2+
3+
php:
4+
- 5.6
5+
- 7.0
6+
- 7.1
7+
- hhvm
8+
- nightly
9+
10+
before_script:
11+
- composer install

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2017 Superbalist.com a division of Takealot Online (Pty) Ltd
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
# php-event-pubsub
2+
3+
An event protocol and implementation over pub/sub
4+
5+
[![Author](http://img.shields.io/badge/author-@superbalist-blue.svg?style=flat-square)](https://twitter.com/superbalist)
6+
[![Build Status](https://img.shields.io/travis/Superbalist/php-event-pubsub/master.svg?style=flat-square)](https://travis-ci.org/Superbalist/php-event-pubsub)
7+
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
8+
[![Packagist Version](https://img.shields.io/packagist/v/superbalist/php-event-pubsub.svg?style=flat-square)](https://packagist.org/packages/superbalist/php-event-pubsub)
9+
[![Total Downloads](https://img.shields.io/packagist/dt/superbalist/php-event-pubsub.svg?style=flat-square)](https://packagist.org/packages/superbalist/php-event-pubsub)
10+
11+
This library builds on top of the [php-pubsub](https://github.com/Superbalist/php-pubsub) package and adds support for
12+
listening to and dispatching events over pub/sub channels.
13+
14+
15+
## Installation
16+
17+
```bash
18+
composer require superbalist/php-event-pubsub
19+
```
20+
21+
## Usage
22+
23+
### Simple Events
24+
25+
A `SimpleEvent` is an event which takes a name and optional attributes.
26+
27+
```php
28+
// create a new event manager
29+
$adapter = new \Superbalist\PubSub\Adapters\LocalPubSubAdapter();
30+
$translator = new \Superbalist\EventPubSub\Translators\SimpleEventMessageTranslator();
31+
$manager = new \Superbalist\EventPubSub\EventManager($adapter, $translator);
32+
33+
// publish an event
34+
$event = new \Superbalist\EventPubSub\Events\SimpleEvent(
35+
'user.created',
36+
[
37+
'user' => [
38+
'id' => 1456,
39+
'first_name' => 'Joe',
40+
'last_name' => 'Soap',
41+
'email' => 'joe.soap@example.org',
42+
],
43+
]
44+
);
45+
$manager->dispatch('events', $event);
46+
47+
// listen for an event
48+
$manager->listen('events', 'user.created', function (\Superbalist\EventPubSub\EventInterface $event) {
49+
var_dump($event->getName());
50+
var_dump($event->getAttribute('user'));
51+
});
52+
53+
// listen for all events on the channel
54+
$manager->listen('events', '*', function (\Superbalist\EventPubSub\EventInterface $event) {
55+
var_dump($event->getName());
56+
});
57+
```
58+
59+
### Topic Events
60+
61+
A `TopicEvent` is an event which takes a topic, name, version and optional attributes.
62+
63+
```php
64+
// create a new event manager
65+
$adapter = new \Superbalist\PubSub\Adapters\LocalPubSubAdapter();
66+
$translator = new \Superbalist\EventPubSub\Translators\TopicEventMessageTranslator();
67+
$manager = new \Superbalist\EventPubSub\EventManager($adapter, $translator);
68+
69+
// publish an event
70+
$event = new \Superbalist\EventPubSub\Events\TopicEvent(
71+
'user',
72+
'created',
73+
'1.0',
74+
[
75+
'user' => [
76+
'id' => 1456,
77+
'first_name' => 'Joe',
78+
'last_name' => 'Soap',
79+
'email' => 'joe.soap@example.org',
80+
],
81+
]
82+
);
83+
$manager->dispatch('events', $event);
84+
85+
// listen for an event on a topic
86+
$manager->listen('events', 'user/created', function (\Superbalist\EventPubSub\EventInterface $event) {
87+
// ...
88+
});
89+
90+
// listen for an event on a topic matching the given version
91+
$manager->listen('events', 'user/created/1.0', function (\Superbalist\EventPubSub\EventInterface $event) {
92+
// ...
93+
});
94+
95+
// listen for all events on a topic
96+
$manager->listen('events', 'user/*', function (\Superbalist\EventPubSub\EventInterface $event) {
97+
// ...
98+
});
99+
100+
// listen for all events on the channel
101+
$manager->listen('events', '*', function (\Superbalist\EventPubSub\EventInterface $event) {
102+
// ...
103+
});
104+
```
105+
106+
### Schema Events
107+
108+
A `SchemaEvent` is an extension of the `TopicEvent` and takes a schema and optional attributes. The topic, name and
109+
version are derived from the schema.
110+
111+
The schema must be in the format `(protocol)://(......)?/events/(topic)/(channel)/(version).json`
112+
113+
```php
114+
// create a new event manager
115+
$adapter = new \Superbalist\PubSub\Adapters\LocalPubSubAdapter();
116+
117+
$translator = new \Superbalist\EventPubSub\Translators\SchemaEventMessageTranslator();
118+
119+
$schemas = [
120+
'events/user/created/1.0.json' => json_encode([
121+
'$schema' => 'http://json-schema.org/draft-04/schema#',
122+
'title' => 'My Schema',
123+
'type' => 'object',
124+
'properties' => [
125+
'schema' => [
126+
'type' => 'string',
127+
],
128+
'user' => [
129+
'type' => 'object',
130+
],
131+
],
132+
'required' => [
133+
'schema',
134+
'user',
135+
],
136+
]),
137+
];
138+
$loader = new \League\JsonGuard\Loaders\ArrayLoader($schemas);
139+
140+
$dereferencer = new \League\JsonGuard\Dereferencer();
141+
$dereferencer->registerLoader($loader, 'array');
142+
143+
$validator = new \Superbalist\EventPubSub\Validators\JSONSchemaEventValidator($dereferencer);
144+
145+
$manager = new \Superbalist\EventPubSub\EventManager($adapter, $translator, $validator);
146+
147+
// publish an event
148+
$event = new \Superbalist\EventPubSub\Events\SchemaEvent(
149+
'http://schemas.my-website.org/events/user/created/1.0.json',
150+
[
151+
'user' => [
152+
'id' => 1456,
153+
'first_name' => 'Joe',
154+
'last_name' => 'Soap',
155+
'email' => 'joe.soap@example.org',
156+
],
157+
]
158+
);
159+
$manager->dispatch('events', $event);
160+
161+
// the listen expressions are the same as those used for TopicEvents.
162+
```
163+
164+
### Custom Events
165+
166+
You can easily use a custom event structure by writing a class which implements the `EventInterface` interface.
167+
You will then need to write a custom translator to translate incoming messages to your own event object.
168+
169+
Your event must implement the following methods.
170+
171+
```php
172+
/**
173+
* Return the event name.
174+
*
175+
* @return string
176+
*/
177+
public function getName();
178+
179+
/**
180+
* Return all event attributes.
181+
*
182+
* @return array
183+
*/
184+
public function getAttributes();
185+
186+
/**
187+
* Return an event attribute.
188+
*
189+
* @param string $name
190+
* @return mixed
191+
*/
192+
public function getAttribute($name);
193+
194+
/**
195+
* Check whether or not an event has an attribute.
196+
*
197+
* @param string $name
198+
* @return bool
199+
*/
200+
public function hasAttribute($name);
201+
202+
/**
203+
* Check whether or not the event matches the given expression.
204+
*
205+
* @param string $expr
206+
* @return bool
207+
*/
208+
public function matches($expr);
209+
210+
/**
211+
* Return the event in a message format ready for publishing.
212+
*
213+
* @return mixed
214+
*/
215+
public function toMessage();
216+
```
217+
218+
## Translators
219+
220+
A translator is used to translate an incoming message into an event.
221+
222+
The package comes bundled with a `SimpleEventMessageTranslator`, `TopicEventMessageTranslator` and a
223+
`SchemaEventMessageTranslator`.
224+
225+
### Custom Translators
226+
227+
You can easily write your own translator by implementing the `MessageTranslatorInterface` interface.
228+
229+
Your translator must implement the following methods.
230+
231+
```php
232+
/**
233+
* @param mixed $message
234+
* @return null|EventInterface
235+
*/
236+
public function translate($message);
237+
```
238+
239+
## Validators
240+
241+
A validator is an optional component used to validate an incoming event.
242+
243+
### JSONSchemaEventValidator
244+
245+
This package comes bundled with a `JSONSchemaEventValidator` which works with `SchemaEvent` type events.
246+
247+
This validator validates events against a [JSON Schema Spec](http://json-schema.org/) using the
248+
[JSON Guard](http://json-guard.thephpleague.com/dereferencing/overview/) PHP package.
249+
250+
Please see the "Schema Events" section above and the JSON Guard documentation for usage examples.
251+
252+
### Custom Validators
253+
254+
You can write your own validator by implementing the `EventValidatorInterface` interface.
255+
256+
Your validator must implement the following methods.
257+
258+
```php
259+
/**
260+
* @param EventInterface $event
261+
* @return bool
262+
*/
263+
public function validates(EventInterface $event);
264+
```

changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Changelog
2+
3+
## 1.0.0 - ?
4+
5+
* Initial release

composer.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "superbalist/php-event-pubsub",
3+
"description": "An event protocol and implementation over pub/sub",
4+
"license": "MIT",
5+
"authors": [
6+
{
7+
"name": "Superbalist.com a division of Takealot Online (Pty) Ltd",
8+
"email": "info@superbalist.com"
9+
}
10+
],
11+
"require": {
12+
"php": ">=5.6.0",
13+
"superbalist/php-pubsub": "^1.0",
14+
"composer/semver": "^1.4",
15+
"league/json-guard": "^0.5.1"
16+
},
17+
"autoload": {
18+
"psr-4": {
19+
"Superbalist\\EventPubSub\\": "src/",
20+
"Tests\\": "tests/"
21+
}
22+
},
23+
"extra": {
24+
"branch-alias": {
25+
"dev-master": "1.0-dev"
26+
}
27+
},
28+
"require-dev": {
29+
"phpunit/phpunit": "^5.5",
30+
"mockery/mockery": "^0.9.5"
31+
}
32+
}

phpunit.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
include __DIR__ . '/vendor/autoload.php';

phpunit.xml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="false"
3+
backupStaticAttributes="false"
4+
bootstrap="./phpunit.php"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false"
11+
syntaxCheck="true"
12+
verbose="true"
13+
>
14+
<testsuites>
15+
<testsuite name="php-event-pubsub/tests">
16+
<directory suffix=".php">./tests/</directory>
17+
</testsuite>
18+
</testsuites>
19+
<filter>
20+
<whitelist>
21+
<directory suffix=".php">./src/</directory>
22+
</whitelist>
23+
</filter>
24+
<logging>
25+
<log type="coverage-text" target="php://stdout" showUncoveredFiles="true"/>
26+
<log type="coverage-html" target="coverage" showUncoveredFiles="true"/>
27+
<log type="coverage-clover" target="coverage.xml" showUncoveredFiles="true"/>
28+
</logging>
29+
</phpunit>

0 commit comments

Comments
 (0)