Transaction-aware Event Dispatcher for Laravel

Overview

Transaction-aware Event Dispatcher for Laravel

Latest Stable Version TravisCI Status Scrutinizer Code Quality Total Downloads

This Laravel package introduces Transaction-aware Event Dispatcher.
It ensures the events dispatched within a database transaction are dispatched only if the outer transaction successfully commits. Otherwise, the events are discarded and never dispatched.

Note: Laravel 8.17 introduced a new method DB::afterCommit that allows one to achieve the same of this package. Yet, it lacks transaction-aware behavior support for Eloquent events.

Table of Contents

Motivation

Consider the following example of ordering tickets that involves changes to the database.
The orderTickets dispatches the custom OrderCreated event. In turn, its listener sends an email to the user with the order details.

DB::transaction(function() {
    ...
    $order = $concert->orderTickets($user, 3); // internally dispatches 'OrderCreated' event
    PaymentService::registerOrder($order);
});

In the case of transaction failure, due to an exception in the orderTickets method or even a deadlock, the database changes are completely discarded.

Unfortunately, this is not true for the already dispatched OrderCreated event. This results in sending the order confirmation email to the user, even after the order failure.

The purpose of this package is thus to hold events dispatched within a database transaction until it successfully commits. In the above example the OrderCreated event would never be dispatched in the case of transaction failure.

Installation

Laravel Package
5.8.x-7.x 1.8.x
8.x 2.x

Laravel

  • Install this package via composer:
composer require fntneves/laravel-transactional-events
  • Publish the provided transactional-events.php configuration file:
php artisan vendor:publish --provider="Neves\Events\EventServiceProvider"

Lumen

  • Install this package via composer:
composer require fntneves/laravel-transactional-events
  • Manually copy the provided transactional-events.php configuration file to the config folder:
cp vendor/fntneves/laravel-transactional-events/src/config/transactional-events.php config/transactional-events.php
  • Register the configuration file and the service provider in bootstrap/app.php:
// Ensure the original EventServiceProvider is registered first, otherwise your event listeners are overriden.
$app->register(App\Providers\EventServiceProvider::class);

$app->configure('transactional-events');
$app->register(Neves\Events\EventServiceProvider::class);

Usage

The transaction-aware layer is enabled out of the box for the events under the App\Events namespace.

This package offers three distinct ways to dispatch transaction-aware events:

  • Implement the Neves\Events\Contracts\TransactionalEvent contract;
  • Use the generic TransactionalClosureEvent event;
  • Use the Neves\Events\transactional helper;
  • Change the configuration file.

Use the contract, Luke:

The simplest way to mark events as transaction-aware events is implementing the Neves\Events\Contracts\TransactionalEvent contract:

namespace App\Events;

use Illuminate\Queue\SerializesModels;
use Illuminate\Foundation\Events\Dispatchable;
...
use Neves\Events\Contracts\TransactionalEvent;

class TicketsOrdered implements TransactionalEvent
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    ...
}

And that's it. There are no further changes required.

What about Jobs?

This package provides a generic TransactionalClosureEvent event for bringing the transaction-aware behavior to custom behavior without requiring specific events.

One relevant use case is to ensure that Jobs are dispatched only after the transaction successfully commits:

DB::transaction(function () {
    ...
    Event::dispatch(new TransactionalClosureEvent(function () {
        // Job will be dispatched only if the transaction commits.
        ProcessOrderShippingJob::dispatch($order);
    });
    ...
});

And that's it. There are no further changes required.

Configuration

The configuration file includes the following parameters:

Enable or disable the transaction-aware behavior:

'enable' => true

By default, the transaction-aware behavior will be applied to all events under the App\Events namespace.
Feel free to use patterns and namespaces.

'transactional' => [
    'App\Events'
]

Choose the events that should always bypass the transaction-aware layer, i.e., should be handled by the original event dispatcher. By default, all *ed Eloquent events are excluded. The main reason for this default value is to avoid interference with your already existing event listeners for Eloquent events.

'excluded' => [
    // 'eloquent.*',
    'eloquent.booted',
    'eloquent.retrieved',
    'eloquent.saved',
    'eloquent.updated',
    'eloquent.created',
    'eloquent.deleted',
    'eloquent.restored',
],

Frequently Asked Questions

Can I use it for Jobs?

Yes. As mentioned in Usage, you can use the generic TransactionalClosureEvent(Closure $callable) event to trigger jobs only after the transaction commits.

License

This package is open-sourced software licensed under the MIT license.

Comments
  •  Call to a member function getParent() on null

    Call to a member function getParent() on null

    Call to a member function getParent() on null {"userId":3,"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Call to a member function getParent() on null at /var/www/app/vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php:229)
    
                Bus::pipeThrough([UseDatabaseTransactions::class]);
    //            dispatch_now($Job->chain([$Job2, $Job3, $Job4, $Job5]) );
                dispatch_now($Job);
                dispatch_now($Job2);
                dispatch_now($Job3);
                dispatch_now($Job4);
                dispatch_now($Job5);
                Bus::pipeThrough([]);
    
    

    Failed on line dispatch_now($Job2);

    class UseDatabaseTransactions {
    
        public function handle($command, $next) {
            return DB::transaction(function() use ($command, $next) {
                return $next($command);
            });
        }
    
    }
    
    #0 /var/www/app/vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php(161): Neves\\Events\\TransactionalDispatcher->finishTransaction()
    #1 /var/www/app/vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php(299): Neves\\Events\\TransactionalDispatcher->onTransactionCommit()
    #2 /var/www/app/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(347): Neves\\Events\\TransactionalDispatcher->Neves\\Events\\{closure}(Object(Illuminate\\Database\\Events\\TransactionCommitted))
    #3 /var/www/app/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(196): Illuminate\\Events\\Dispatcher->Illuminate\\Events\\{closure}('Illuminate\\\\Data...', Array)
    #4 /var/www/app/vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php(114): Illuminate\\Events\\Dispatcher->dispatch('Illuminate\\\\Data...', Array, false)
    #5 /var/www/app/vendor/laravel/framework/src/Illuminate/Database/Connection.php(813): Neves\\Events\\TransactionalDispatcher->dispatch(Object(Illuminate\\Database\\Events\\TransactionCommitted))
    #6 /var/www/app/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php(162): Illuminate\\Database\\Connection->fireConnectionEvent('committed')
    #7 /var/www/app/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php(30): Illuminate\\Database\\Connection->commit()
    #8 /var/www/app/vendor/laravel/framework/src/Illuminate/Support/helpers.php(1124): Illuminate\\Database\\Connection->Illuminate\\Database\\Concerns\\{closure}(NULL)
    #9 /var/www/app/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php(31): tap(NULL, Object(Closure))
    #10 /var/www/app/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(349): Illuminate\\Database\\Connection->transaction(Object(Closure))
    #11 /var/www/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(237): Illuminate\\Database\\DatabaseManager->__call('transaction', Array)
    #12 /var/www/app/app/Jobs/Pipes/UseDatabaseTransactions.php(12): Illuminate\\Support\\Facades\\Facade::__callStatic('transaction', Array)
    #13 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): App\\Jobs\\Pipes\\UseDatabaseTransactions->handle(Object(App\\Jobs\\Sender), Object(Closure))
    #14 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(App\\Jobs\\Sender))
    #15 /var/www/app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
    #16 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php(413): Illuminate\\Bus\\Dispatcher->dispatchNow(Object(App\\Jobs\\Sender), false)
    #17 /var/www/app/app/Nova/Actions/Signer.php(85): dispatch_now(Object(App\\Jobs\\Sender))
    
    bug 
    opened by 4n70w4 24
  • Nested multiple connections problems.

    Nested multiple connections problems.

    Hi! I have many databases in one app. But there's something wrong with laravel-transactional-events when nested multiple connections. I report these cases.

    OK (Single connection)

    \DB::connection('logdb')->transaction(function() {
        event(new \App\Events\EventA);
        event(new \App\Events\EventB);
    });
    

    Of course it is no problems. I got both events.

    NG (Exception when nested multiple connections)

    \DB::connection('logdb')->transaction(function() {
        \DB::transaction(function() {
            event(new \App\Events\EventA);
        });
        event(new \App\Events\EventB);
    });
    

    I got exception below.

    ErrorException: count(): Parameter must be an array or an object that implements Countable in /vagrant/server/vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php:152
    Stack trace:
    #0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'count(): Parame...', '/vagrant/server...', 152, Array)
    #1 /vagrant/server/vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php(152): count(NULL)
    

    NG (Inner event not fired when nested multiple connections)

    \DB::connection('logdb')->transaction(function() {
        event(new \App\Events\EventB);
        \DB::transaction(function() {
            event(new \App\Events\EventA);
        });
    });
    

    I got EventB only. EventA is not fired.

    My Environment

    • laravel 5.8.10
    • laravel-transactional-events 1.8.0
    • CentOS 7
    • MySQL 8.0
    bug 
    opened by ktanakaj 19
  • How does it work in nested (emulated with savepoints) transactions?

    How does it work in nested (emulated with savepoints) transactions?

    DB::transaction(function () {
        DB::transaction(function () {
           event(new TransactionalEvent());
        });
        // A: dispatched here?
    });
    // B: or here?
    
    question 
    opened by mpyw 10
  • Problem with DatabaseTransactions

    Problem with DatabaseTransactions

    Hello,

    In my tests I am using DatabaseTransactions trait. Because of that I still have a problem that you resolved with Neves\RefreshDatabase trait. All events are fired after the outer transaction which happens after the end of the test.

    Could you create a fix for DatabaseTransactions trait as well?

    opened by V-Srv 8
  • Route fire method through TransactionalDispatcher

    Route fire method through TransactionalDispatcher

    The fire method is an alias to the dispatch method in Illuminate\Event\Dispatcher and should be routed through the TransactionalDispatcher too to. Events created through models are now too transaction-aware.

    opened by erikgaal 8
  • Add DatabaseTransactions trait for transactional events

    Add DatabaseTransactions trait for transactional events

    In my test suite I'm not using RefreshDatabase but DatabaseTransactions.

    The reason is that I've a custom system in place which primes the database once before all tests are run and not for every tests. Because I can't use sqlite but the actual DB driver, this is much more faster.

    With this trait I can replace the vanilla one and transactional events and their effect can be tested like anything else.

    Mildly related question

    I've a question regarding https://github.com/fntneves/laravel-transactional-events#known-issues though: I re-read the paragraph multiple times but TBH, it's not clear whether this packages RefreshDatabase is basically required to be used or not.

    I saw that you landed https://github.com/laravel/framework/pull/23832 some time ago but this package actually does not use any of this:

    • the trait has a slightly differently logic then the one in this package (I can't test this, not using it)
    • the introduced unsetEventDispatcher is also not used anywhere

    Can you clarify: if it recommended/required to use this package RefreshDatabase trait?

    If so, I think the README could be clarified and also if this PR gets accepted, this should be added too (willing to do in this PR once this is cleared up for me).

    If not so, then I don't understand why it exists :-)

    I certainly needed this modified DatabaseTransactions otherwise the actual transactional events where never dispatched in tests.

    opened by mfn 7
  • Keep the payload context in dispatched events

    Keep the payload context in dispatched events

    If it isn't, then an audit monitor listening on the updated event won't see any differences, since the model attributes will already have been merged back in original.

    opened by woodspire 7
  • Would you consider approaching Laravel to include this in core?

    Would you consider approaching Laravel to include this in core?

    I'm aware the history of the project originated in trying to have this in Laravel.

    Personally the approach used feels very clean and it definitely is production ready.

    Also by using the explicit interface to mark events, the addition to Laravel core could be done in almost backwards compatible way (i.e. it could start without the white/blacklist thing), i.e. changing at least no runtime behaviour (as long as users didn't replace it with their own event bus, etc.).

    What's your take on this thought?

    opened by mfn 5
  • [1.8.x] Add namespaced transactional helper

    [1.8.x] Add namespaced transactional helper

    This PR recovers the old transactional helper.

    Similarly to what is happening in Laravel 8, with the introduction of namespaced functions (i.e., queueable), this PR aims at easing the usage of this library by introducing a new helper.

    opened by fntneves 4
  • Wrong parameter to TransactionalDispatcher constructor

    Wrong parameter to TransactionalDispatcher constructor

    Sometimes I'm getting this error:

    [27-Mar-2019 00:36:04 UTC] PHP Fatal error: Uncaught TypeError: Argument 2 passed to Neves\Events\TransactionalDispatcher::__construct() must be an instance of Illuminate\Events\Dispatcher, instance of Neves\Events\TransactionalDispatcher given, called in /app/vendor/fntneves/laravel-transactional-events/src/Neves/Events/EventServiceProvider.php on line 29 and defined in /app/vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php:69

    If I remove the EventDispatcher type on constructor, it works, so I print a log to test:

    /**
     * Create a new transactional event dispatcher instance.
     *
     * @param  \Illuminate\Database\ConnectionResolverInterface $connectionResolver
     * @param  \Illuminate\Contracts\Events\Dispatcher          $eventDispatcher
     */
    public function __construct(ConnectionResolverInterface $connectionResolver, $eventDispatcher)
    {
        Log::debug(get_class($eventDispatcher));
    
        $this->connectionResolver = $connectionResolver;
        $this->dispatcher = $eventDispatcher;
        $this->setUpListeners();
    }
    

    And got this:

    [2019-03-27 11:33:03] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:08] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:33] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:33] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:40] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:40] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:40] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:40] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:40] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:40] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:40] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:40] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:40] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:42] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:42] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:33:44] local.DEBUG: Neves\Events\TransactionalDispatcher  
    [2019-03-27 11:33:44] local.DEBUG: Neves\Events\TransactionalDispatcher  
    [2019-03-27 11:33:44] local.DEBUG: Neves\Events\TransactionalDispatcher  
    [2019-03-27 11:33:44] local.DEBUG: Neves\Events\TransactionalDispatcher  
    [2019-03-27 11:33:44] local.DEBUG: Neves\Events\TransactionalDispatcher  
    [2019-03-27 11:33:44] local.DEBUG: Neves\Events\TransactionalDispatcher  
    [2019-03-27 11:33:44] local.DEBUG: Neves\Events\TransactionalDispatcher  
    [2019-03-27 11:33:44] local.DEBUG: Neves\Events\TransactionalDispatcher  
    [2019-03-27 11:33:44] local.DEBUG: Neves\Events\TransactionalDispatcher  
    [2019-03-27 11:34:00] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:34:00] local.DEBUG: Illuminate\Events\Dispatcher  
    [2019-03-27 11:34:00] local.DEBUG: Illuminate\Events\Dispatcher  
    

    Can we do something about this? The most quickly solution is remove the EventDispatcher type from constructor, but I don't know if is the best solution.

    opened by ibrunotome 4
  • Serialization of 'Closure' is not allowed

    Serialization of 'Closure' is not allowed

    I don't have time to get more information right now, had to remove the package. Will want it back in soon so will be back to debug and give more information.

    Will also get better stack tracers with just the relevant information later.

    Laravel 5.7.

    Exception Serialization of 'Closure' is not allowed 
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:138 serialize
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:138 Illuminate\Queue\Queue::createObjectPayload
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:110 Illuminate\Queue\Queue::createPayloadArray
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Queue/RedisQueue.php:150 Illuminate\Queue\RedisQueue::createPayloadArray
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:88 Illuminate\Queue\Queue::createPayload
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Queue/RedisQueue.php:91 Illuminate\Queue\RedisQueue::push
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/horizon/src/RedisQueue.php:46 Laravel\Horizon\RedisQueue::push
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:44 Illuminate\Queue\Queue::pushOn
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Broadcasting/BroadcastManager.php:128 Illuminate\Broadcasting\BroadcastManager::queue
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:280 Illuminate\Events\Dispatcher::broadcastEvent
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:203 Illuminate\Events\Dispatcher::dispatch
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php:171 Neves\Events\TransactionalDispatcher::dispatchPendingEvents
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php:114 Neves\Events\TransactionalDispatcher::commit
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php:409 Neves\Events\TransactionalDispatcher::Neves\Events\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:360 Illuminate\Events\Dispatcher::Illuminate\Events\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:209 Illuminate\Events\Dispatcher::dispatch
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/fntneves/laravel-transactional-events/src/Neves/Events/TransactionalDispatcher.php:92 Neves\Events\TransactionalDispatcher::dispatch
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Database/Connection.php:813 Illuminate\Database\Connection::fireConnectionEvent
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:162 Illuminate\Database\Connection::commit
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:30 Illuminate\Database\Connection::Illuminate\Database\Concerns\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Support/helpers.php:1027 tap
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:31 Illuminate\Database\Connection::transaction
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php:327 Illuminate\Database\DatabaseManager::__call
        helpers.php:105 db_transaction
        Http/Controllers/ContentArticleRevision/ApprovedController.php:43 App\Http\Controllers\ContentArticleRevision\ApprovedController::store
        [internal] call_user_func_array
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54 Illuminate\Routing\Controller::callAction
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:45 Illuminate\Routing\ControllerDispatcher::dispatch
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Route.php:219 Illuminate\Routing\Route::runController
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Route.php:176 Illuminate\Routing\Route::run
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php:682 Illuminate\Routing\Router::Illuminate\Routing\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:30 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        Http/Middleware/Visitor.php:50 App\Http\Middleware\Visitor::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:163 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        Http/Middleware/Authenticate.php:80 App\Http\Middleware\Authenticate::handleMetaData
        Http/Middleware/Authenticate.php:45 App\Http\Middleware\Authenticate::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:163 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/barryvdh/laravel-cors/src/HandleCors.php:36 Barryvdh\Cors\HandleCors::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:163 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php:41 Illuminate\Routing\Middleware\SubstituteBindings::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:163 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:104 Illuminate\Pipeline\Pipeline::then
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php:684 Illuminate\Routing\Router::runRouteWithinStack
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php:659 Illuminate\Routing\Router::runRoute
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php:625 Illuminate\Routing\Router::dispatchToRoute
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php:614 Illuminate\Routing\Router::dispatch
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:176 Illuminate\Foundation\Http\Kernel::Illuminate\Foundation\Http\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:30 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/nova/src/Http/Middleware/ServeNova.php:26 Laravel\Nova\Http\Middleware\ServeNova::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:163 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/fideloper/proxy/src/TrustProxies.php:57 Fideloper\Proxy\TrustProxies::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:163 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        Http/Middleware/LogRequest.php:61 App\Http\Middleware\LogRequest::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:163 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:31 Illuminate\Foundation\Http\Middleware\TransformsRequest::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:163 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php:27 Illuminate\Foundation\Http\Middleware\ValidatePostSize::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:163 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php:62 Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:163 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/barryvdh/laravel-cors/src/HandlePreflight.php:29 Barryvdh\Cors\HandlePreflight::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:163 Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:53 Illuminate\Routing\Pipeline::Illuminate\Routing\{closure}
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:104 Illuminate\Pipeline\Pipeline::then
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:151 Illuminate\Foundation\Http\Kernel::sendRequestThroughRouter
        /var/www/partner.postedin.com/releases/20190228205803/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:116 Illuminate\Foundation\Http\Kernel::handle
        /var/www/partner.postedin.com/releases/20190228205803/api/public/index.php:55 [main]
    
    opened by robclancy 4
Releases(2.1.0)
  • 2.1.0(Jan 14, 2022)

  • 2.0.1(Oct 13, 2020)

  • 1.8.11(Oct 13, 2020)

  • 2.0.0(Sep 8, 2020)

  • 1.8.10(Sep 8, 2020)

  • 1.8.9(Apr 15, 2020)

    • Removed the transactional helper. See #39

    Alternatively, use TransactionalClosureEvent directly.

    Event::dispatch(new TransactionalClosureEvent(function () {
        // Job will be dispatched only if the transaction commits. 
        ProcessOrderShippingJob::dispatch($order);
    });
    
    Source code(tar.gz)
    Source code(zip)
  • 1.8.8(Apr 15, 2020)

    What's new?

    This version includes the transactional helper to bring transactional behavior to custom instructions.

    It is particularly useful for dispatching jobs:

    transactional(function () {
        ProcessPodcast::dispatch($podcast);
    });
    
    Source code(tar.gz)
    Source code(zip)
  • 1.8.7(Mar 31, 2020)

  • 1.8.6(Mar 3, 2020)

  • 1.8.5(Jan 6, 2020)

  • 1.8.4(Sep 7, 2019)

  • 1.8.3(Sep 4, 2019)

  • 1.8.2(Aug 19, 2019)

  • 1.8.1(Jun 2, 2019)

  • 1.8.0(Feb 26, 2019)

  • 1.4.6(Sep 5, 2018)

  • 1.4.5(Jun 1, 2018)

  • 1.4.4(Aug 20, 2018)

  • 1.4.3(Apr 21, 2018)

  • 1.4.2(Apr 14, 2018)

    This release introduces a new trait useful only for versions before Laravel 5.6.16 (see #23832).

    The custom RefreshDatabase trait disables the dispatch of the events related to transactions used to reset your database. This is motivated by the fact that they interfere with the behavior of your application during tests.

    In order to take advantage of this trait, replace the original Illuminate\Foundation\Testing\RefreshDatabase with Neves\Testing\RefreshDatabase in your test classes.

    Source code(tar.gz)
    Source code(zip)
  • 1.4.1(Mar 31, 2018)

    This releases introduces a change for the issue described below:

    Contextualization:

    When you are testing your application, perhaps you refresh your database either rollbacking and migrating your database migrations (fast for in-memory databases such as SQLite) or using database transactions that are created before each test and rollbacked at the end of it.

    Problem:

    If you are using an non-in-memory database, such as PostgreSQL or MySQL, you will figure out that your transactional events are never dispatched. Why? Since this package dispatches events only after the outer transaction commits, your events are never dispatched since your test is running within a transaction that you do not control.

    Solution:

    This release now allows this package to manage the transactional level internally according to the events that it actually receives. It allows this package to work properly when events are not triggered but the transaction level in Laravel is greater than 0.

    ⚠️⚠️⚠️However... It does not solve the fact that the RefreshDatabase trait dispatches events. I have introduced an issue in Laravel internals repository to discuss this. For now, if you are using PostgreSQL and MySQL databases, you must disable the TransactionBeginning event while the outer transaction (the one that cover each test method) starts. To do so, you can use this Github gist: https://gist.github.com/fntneves/7f0b99767fce369919211148942eb297

    Source code(tar.gz)
    Source code(zip)
  • 1.4.0(Mar 31, 2018)

    This release introduces Lumen compatibility.

    Thanks to @Szasza, the composer.json dependencies were replaced with the minimal required packages, so this package can be installed in Lumen also:

    • "illuminate/database": "5.5.* || 5.6.*"
    • "illuminate/events": "5.5.* || 5.6.*"
    • "illuminate/support": "5.5.* || 5.6.*"
    Source code(tar.gz)
    Source code(zip)
  • 1.3.2(Feb 12, 2018)

    Ensure composer.json includes the following requirements:

    • PHP ^7.0
    • Laravel 5.5.* || 5.6.*

    Otherwise it could be installed on previous versions and they are not compatible.

    Source code(tar.gz)
    Source code(zip)
  • 1.3.1(Feb 3, 2018)

    This release adds the contract Neves\Events\Contracts\TransactionalEvent.

    When events implement this contract, they will become transactional. Please note that this contract overrides the configuration, i.e., the events that implement this contract will behave as transactional events even when present in the excluded array.

    Here's in an example:

    namespace App\Events;
    
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Foundation\Events\Dispatchable;
    ...
    use Neves\Events\Contracts\TransactionalEvent;
    
    class TicketsOrdered implements TransactionalEvent
    {
        use Dispatchable, InteractsWithSockets, SerializesModels;
    
        ...
    }
    
    Source code(tar.gz)
    Source code(zip)
  • 1.3.0(Jan 21, 2018)

    This release contains the following changes:

    • Events with $halt set to true now bypass the transactional layer, since caller is waiting for the result and it is often used in *ing (like booting and updating) events.
    • Eloquent events are now supported but disabled by default in the excluded config key:
    'excluded' => [
        // 'eloquent.*',
        'eloquent.booted',
        'eloquent.retrieved',
        'eloquent.created',
        'eloquent.saved',
        'eloquent.updated',
        'eloquent.created',
        'eloquent.deleted',
        'eloquent.restored',
    ],
    
    • Config file is now merged with the published config file.

    Bug fixes:

    • On a nested transaction rollback, the events dispatched on previous successful transactions within the same transaction level were discarded.
    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Jan 15, 2018)

    The following Model events are now considered transactional events:

    eloquent.booting
    eloquent.booted
    eloquent.retrieved
    eloquent.saved
    eloquent.updated
    eloquent.created
    eloquent.deleted
    eloquent.restored
    
    Source code(tar.gz)
    Source code(zip)
Owner
Francisco Neves
Mix of engineer and human being. Team & Product Manager @ Nutrium. Invited Assistant Professor at University of Minho. Ph.D. Candidate at University of Minho.
Francisco Neves
laravel zibal - transaction request package for zibal

laravel zibal transaction request package for zibal Getting Started To get a local copy up and running follow these simple steps. Installation You can

Abbas mkhzomi 4 Jan 10, 2022
Add eloquent model events fired after a transaction is committed or rolled back

Laravel Transactional Model Events Add transactional events to your eloquent models. Will automatically detect changes in your models within a transac

Mark van Duijker 62 Dec 22, 2022
An HTTP Interop compatible middleware dispatcher in Equip

An HTTP Interop compatible middleware dispatcher in Equip. Attempts to be PSR-1, PSR-2, PSR-4, PSR-7, and PSR-15 compliant.

Equip 24 Aug 10, 2022
Nachricht is an message dispatcher which focuses on distributing workloads

Nachricht Nachricht is a message dispatcher which focuses on distributing workloads. Features Directly dispatch messages Dispatch messages via AMQP au

JTL Software 1 Jan 18, 2022
A simple Laravel event log package for easy model based logging.

Karacraft Logman A simple Model Event Logging Package Usage Installation composer require karacraft/logman Migrate php artisan migrate Publish php a

Karacraft 0 Dec 28, 2021
Attendize is an open-source ticketing and event management application built using the Laravel PHP framework

Attendize is an open-source ticketing and event management application built using the Laravel PHP framework. Attendize allows event organisers to sel

Attendize 3.6k Dec 27, 2022
A minimalistic event calendar Tool for Laravel's Nova 4

Event calendar for Laravel Nova 4 An event calendar that displays Nova resources or other time-related data in your Nova 4 project on a monthly calend

wdelfuego 44 Jan 1, 2023
Laravel Event Visualizer

Laravel package to visualize events with their handlers, including jobs to chain them together.

Jonas Pardon 4 Dec 30, 2022
PlayZ is an esport event organization and management website allowing the creation of tournaments on the most popular video games of the esport scene.

PlayZ the playz to play Table of Contents Description "What is Playz?" In one sentence PlayZ is "an esport event organization and management website a

Antoine Saunier 2 Dec 7, 2021
A lightweight domain event pattern implementation for Doctrine2.

Knp Rad Domain Event A lightweight domain event pattern implementation for Doctrine2. Official maintainers: @Einenlum Installation With composer : $ c

KNP Labs 5 Sep 23, 2022
An event stream library based on tail

TailEventStream An event stream library based on tail. Note: I don't think you should use this library in a real project, but it's great for education

Matthias Noback 4 Feb 19, 2022
List of 77 languages for Laravel Framework 4, 5, 6, 7 and 8, Laravel Jetstream , Laravel Fortify, Laravel Breeze, Laravel Cashier, Laravel Nova and Laravel Spark.

Laravel Lang In this repository, you can find the lang files for the Laravel Framework 4/5/6/7/8, Laravel Jetstream , Laravel Fortify, Laravel Cashier

Laravel Lang 6.9k Jan 2, 2023
⚡ Laravel Charts — Build charts using laravel. The laravel adapter for Chartisan.

What is laravel charts? Charts is a Laravel library used to create Charts using Chartisan. Chartisan does already have a PHP adapter. However, this li

Erik C. Forés 31 Dec 18, 2022
Laravel Kickstart is a Laravel starter configuration that helps you build Laravel websites faster.

Laravel Kickstart What is Laravel Kickstart? Laravel Kickstart is a Laravel starter configuration that helps you build Laravel websites faster. It com

Sam Rapaport 46 Oct 1, 2022
Laravel User Activity Log - a package for Laravel 8.x that provides easy to use features to log the activities of the users of your Laravel app

Laravel User Activity Log - a package for Laravel 8.x that provides easy to use features to log the activities of the users of your Laravel app

null 9 Dec 14, 2022
Laravel Segment is an opinionated, approach to integrating Segment into your Laravel application.

Laravel Segment Laravel Segment is an opinionated, approach to integrating Segment into your Laravel application. Installation You can install the pac

Octohook 13 May 16, 2022
Laravel Sanctum support for Laravel Lighthouse

Lighthouse Sanctum Add Laravel Sanctum support to Lighthouse Requirements Installation Usage Login Logout Register Email Verification Forgot Password

Daniël de Wit 43 Dec 21, 2022
Bring Laravel 8's cursor pagination to Laravel 6, 7

Laravel Cursor Paginate for laravel 6,7 Installation You can install the package via composer: composer require vanthao03596/laravel-cursor-paginate U

Pham Thao 9 Nov 10, 2022
A package that uses blade templates to control how markdown is converted to HTML inside Laravel, as well as providing support for markdown files to Laravel views.

Install Install via composer. $ composer require olliecodes/laravel-etched-blade Once installed you'll want to publish the config. $ php artisan vendo

Ollie Codes 19 Jul 5, 2021