Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
711 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
language: php | ||
|
||
php: | ||
- 7.0 | ||
- 7.1 | ||
|
||
before_script: | ||
- composer self-update | ||
- composer install --prefer-source --no-interaction --dev | ||
|
||
script: phpunit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,68 @@ | ||
# laravel-transactional-events | ||
Enabling transactional events in Laravel | ||
# Transactional Events on Laravel <a href="https://travis-ci.org/fntneves/laravel-transactional-events"><img src="https://travis-ci.org/fntneves/laravel-transactional-events.svg?branch=master" alt="TravisCI Status"></a> | ||
|
||
This package brings transactional events to your Laravel application, allowing to achieve consistency between dispatched events and active database transactions. | ||
<br> | ||
Without changing a line of code your application will be able to take advantage from transactional events, out of the box. | ||
|
||
## Why transactional events? | ||
When your application hits a size that requires some effort to organize things, you may want to dispatch events on models to represent changes on their state. Let's say, for instance, that a ordering tickets is a complex process that calls an external payment service and triggers a notification that will be sent by e-mail, SMS, ... | ||
|
||
```php | ||
|
||
// OrdersController.php | ||
DB::transaction(function() { | ||
$user = User::find(...); | ||
$concert = Concert::find(...); | ||
$tickets = $concert->orderTickets($user, 3); | ||
PaymentService::createOrder($tickets); | ||
}); | ||
|
||
// Concert.php | ||
public function orderTickets($user, $amount) | ||
{ | ||
... | ||
event(UserDisabledAccount::class); | ||
} | ||
``` | ||
|
||
In case the transaction of the example fails due to an error on external payment service or due to other reason in the database-level, such as deadlocks, will rollback all your database changes. **However, the event was actually dispatched and it will be executed, even the whole transaction failed**. | ||
|
||
Here is the purpose of this package: if an event is dispatched within a transaction, it will be executed if and only if the transaction succeeds. If the transaction fails, they will never execute. | ||
|
||
However, if have parts on your code that do not leverage transactions, **events will be dispatched using the default Laravel Event Dispatcher**. | ||
|
||
## Installation | ||
**Note:** This package is only available for Laravel 5.5 LTS. | ||
|
||
The installation of this package leverages the Package Auto-Discovery feature enabled in Laravel 5.5. Therefore, you just need to add this package to `composer.json` file. | ||
|
||
```php | ||
composer require "fntneves/laravel-transactional-events" | ||
``` | ||
|
||
The configuration file can be customized, just publish the provided one `transactional-events.php` to your config folder. | ||
|
||
```php | ||
php artisan vendor:publish --provider="Neves\Events\EventServiceProvider" | ||
``` | ||
|
||
|
||
## Usage | ||
|
||
Once the package is installed, it is ready to use out-of-the-box. By default, it will start to handle all events of `App\Events` namespace as transactional events. | ||
|
||
The `Event::dispatch(...)` facade or the `event(new UserRegistered::class)` helper method can still be used to dispatch events. If you use queues, they will still work smoothly, since this package only adds a transactional layer over the event dispatcher. | ||
|
||
**Note:** This package only applies the transactional behavior to events dispatched within a database transaction. Otherwise, it will perform the same as the default Laravel Event Dispatcher. | ||
|
||
|
||
## Configuration | ||
|
||
**enabled**: The transactional behavior of events can be enable or disable by setting up the `enable` property in configuration file. | ||
|
||
**events**: By default, the transactional behavior will be applied to events on `App\Events` namespace. This is configurable to patterns and full namespaces. | ||
|
||
**exclude**: Apart of the transactional events, you can choose specific events to be handled with the default Laravel Event Dispatcher, i.e., without the transactional behavior. | ||
|
||
## License | ||
This package is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "fntneves/laravel-transactional-events", | ||
"description": "Transactional layer for Laravel Event Dispatcher", | ||
"type": "library", | ||
"require": { | ||
"illuminate/events": "5.5.*", | ||
"illuminate/support": "5.5.*", | ||
"illuminate/database": "5.5.*" | ||
}, | ||
"require-dev": { | ||
"phpunit/phpunit": "^6.3", | ||
"mockery/mockery": "^0.9.9" | ||
}, | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "Francisco Neves", | ||
"email": "contact@francisconeves.com" | ||
} | ||
], | ||
"autoload": { | ||
"psr-0": { | ||
"Neves\\Events\\": "src/" | ||
} | ||
}, | ||
"extra": { | ||
"laravel": { | ||
"providers": [ | ||
"Neves\\Events\\EventServiceProvider" | ||
] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<phpunit backupGlobals="false" | ||
backupStaticAttributes="false" | ||
bootstrap="vendor/autoload.php" | ||
colors="true" | ||
convertErrorsToExceptions="true" | ||
convertNoticesToExceptions="true" | ||
convertWarningsToExceptions="true" | ||
processIsolation="false" | ||
stopOnFailure="false" | ||
syntaxCheck="false" | ||
> | ||
<testsuites> | ||
<testsuite name="Package Test Suite"> | ||
<directory suffix=".php">./tests/</directory> | ||
</testsuite> | ||
</testsuites> | ||
</phpunit> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?php | ||
|
||
namespace Neves\Events; | ||
|
||
use Illuminate\Support\ServiceProvider; | ||
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher; | ||
|
||
class EventServiceProvider extends ServiceProvider | ||
{ | ||
/** | ||
* Register the service provider. | ||
* | ||
* @return void | ||
*/ | ||
public function register() | ||
{ | ||
if (config('transactional-events.enable', true)) { | ||
$this->app->extend('events', function () { | ||
$dispatcher = new TransactionalDispatcher( | ||
$this->app->make('db'), | ||
$this->app->make(EventDispatcher::class) | ||
); | ||
|
||
$dispatcher->setTransactionalEvents(config('transactional-events.events', [])); | ||
$dispatcher->setExcludedEvents(config('transactional-events.exclude', [])); | ||
|
||
return $dispatcher; | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* Bootstrap the application events. | ||
* | ||
* @return void | ||
*/ | ||
public function boot() | ||
{ | ||
$this->publishes([ | ||
__DIR__.'/../../config/transactional-events.php' => config_path('transactional-events.php'), | ||
]); | ||
|
||
$this->mergeConfigFrom( | ||
__DIR__.'/../../config/transactional-events.php', 'transactional-events' | ||
); | ||
} | ||
} |
Oops, something went wrong.