Event Listeners and Direct Manipulation of Event Propagation

Asked

Viewed 139 times

0

My recent forays into PHP development were with respect to Event Handling and Event Listening.

Through a Mediator it was possible to create a concise and elegant platform to elevate extensibility to another level.

As in Javascript, all Event Listener receives at least one Event to be manipulated into their own scopes:

$eventHandler -> addListener(

    'success', new Listener( function( Event $event, View $view, $message ) {

        $view -> success = $message;
    })
);

$eventHandler -> addListener(

    'error', new Listener( function( Event $event, View $view, $message ) {

        $event -> stopPropagation();

        $view -> error = $message;
    })
);

These are two real examples implemented as part of the Listeners standard of a base class for developing Plugins

They are very simple because they only provide information to the Application where the Plugins will be used, thus avoiding dozens of nested Ifs just to mount a simple View.

Well, as in Javascript, the Events can be manipulated from within the Listeners may have their propagation interrupted. And such a resource has also been implemented by making it Listeners above were used as follows:

$application = new Application; # Fake
$view = new View; # Fake

$plugin = new Plugin( $application );

$plugin -> getEventHandler() -> handle( 'error', $view, 'message' );
$plugin -> getEventHandler() -> handle( 'warning', $view, 'message' );

Only the Listener error would be executed. because the trigger process would be aborted if the Event had its propagation interrupted.

Well, it happened that during the rewriting of the Plugins, both to use the Plugins base class (which was previously an interface) as well as the Event Listeners, I had an epiphany (ours that deep).

In recent conversation in chat with @Omni I had as confirmation that, in a hypothetical scenario, with a 1:N relationship between two subjects, where each Plugin would be one of many relatable (N), if the Plugin had its main task successfully executed, the Controller that ran the Plugin is who should change one fag in the database that characterizes that such step, of such Plugin, was completed.

But what if, although the Plugin has been run successfully, this update flag for some reason failed?

In the same way as a Listener successful, a Listener warning could be fired in sequence but, if for some reason the propagation of the Event had been prevented in Listener successful, the Listener sequential would be ignored.

And that’s where my epiphany comes in:

It would be minimally plausible to operate manually, in global scope, the Event now manipulated in the local scope of a Listener so that when a next one was fired it would not be restricted by the interrupted propagation in the Listener previous?

My idea, currently implemented and fully functional was something like this, although quite abridged and abstracted (but logically equivalent):

class Controller {

    private $application;
    private $view;

    // ...

    public function action() {

        $plugin = new Plugin( $this -> application );

        try {

            // Executes pre-execution routines

            $plugin -> onBeforeRun();

            // Main routine

            $plugin -> run();

            /*
             * Executes post-execution routines
             * Here is where the success Listener is
             * triggered and the Event Propagation stopped
             */
            $plugin -> onAfterRun();

            // Updates Plugin status

            try {

                // ...

                $repository -> update();

            } catch( SomeTableException $e ) {

                // Manuall restarting the Event Propagation

                $plugin -> getEventHandler() -> getEvent() -> startPropagation();

                $plugin -> getEventHandler() -> handle(

                    'warning', $this -> view, $e -> getMessage()
                );
            }

        } catch( SomePLuginException $e ) {

            // Plugin execution error. Handled differently
        }

        // ...
    }
}

That is, assuming that the Plugin has been successfully executed but that for some reason, perfectly falsifiable by way of debugging, the entity of the repository could not be updated, other Listener would be executed only to warn that almost all went well, but for this, the spread of the Event interrupted by the previous Listener should be reversed.

But, so far, I found nothing respect, not even in Javascript to know if there would be this possibility and/ or if it would make sense the enterprise.

  • Enlighten me one thing: your event propagates by where? By function stack? Because in the case of JS propagation is by DOM, but in PHP I didn’t understand where it would be.

  • Something automatic in DOM style would be quite complicated with PHP, so it’s pseudo-automatic. In the example I gave, the successful Listener is fired in Plugin::onAfterRun() which is invoked after the Plugin has been successfully executed, since if there is an error, the stream is directed to the outermost catch block.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.