This website uses Cookies to provide you with the best possible service. Please see our Privacy Policy for more information. Click the check box below to accept cookies. Then confirm with a click on "Save".  
Status: 2024-10-06

Events


Registering Event Listeners

Location where to write Event Listeners

module/{module}/etc/event/

Listeners written here are executed right after all Configurations have been loaded. No essential classes of Emvicy have been loaded or processed at this point yet.

So this is the perfect place to influence the behavior of the starting application.

Example: log current request object to debug.log when on develop environment

<?php

\MVC\Event::processBindConfigStack([

    'mvc.request.getCurrentRequest.after' => [ // Event

        function (\MVC\DataType\DTArrayObject $oDTArrayObject) { // Closure

            // get request object
            $oDTRequestCurrent = $oDTArrayObject->getDTKeyValueByKey('oDTRequestCurrent')->get_sValue();

            if ('develop' === \MVC\Config::get_MVC_ENV())
            {
                \MVC\Log::write($oDTRequestCurrent, 'debug.log');
            }
        },
    ],
]);

You can write your own event bondings into an already existing file.

And you may add as many events as your application requires.

You can also create your own php file in that folder and note your event bondings, no problem.
⚠ but consider the loading order of the files, which is a-z.


\MVC\Event::run()

with run you initialize an event; bonded Closures to the event name get executed in order.

Syntax

\MVC\Event::run('eventName', {mixed} );

Example: Run a simple Event

\MVC\Event::run('foo');

Example: pass a value to the event

\MVC\Event::run('foo', 123);

Example: pass an DTArrayObject Object with Infos

\MVC\Event::run('foo', DTArrayObject::create()
    ->add_aKeyValue(
        DTKeyValue::create()->set_sKey('foo')->set_sValue('bar')
    )
);

\MVC\Event::bind()

with bind you create a Listener to an expected event; you bind a closure to the expected event.

Syntax

\MVC\Event::bind('event', {closure} );

bind to an Event Name

regular - listens to event whose event name is 'fooName'

\MVC\Event::bind('fooName', function() { ... });

bind to an Event Name with placeholder

you can listen for many similar events by using wildcard symbol * (asterisk).

Examples: with placeholder * - listens to all events whose event names match

// listen for events that begin with `foo`
\MVC\Event::bind('foo*', function() { ... });

// listen for events ending with `Name`
\MVC\Event::bind('*Name', function() { ... });

// listens for events that begin with "f" and have an "N" somewhere in between
\MVC\Event::bind('f*N*', function() { ... });

// listen for events that begin with `mvc.db.model.` and end with `.sql`
\MVC\Event::bind('mvc.db.model.*.sql', function() { ... }); 

bind to a Controller::method

Example: bind a closure to a concrete Controller::method

\MVC\Event::bind('\{module}\Controller\Index::foo', function (\MVC\DataType\DTArrayObject $oDTArrayObject, \MVC\DataType\DTEventContext $oDTEventContext) {
    info($oDTArrayObject);
    display($oDTEventContext);
});
  • 🛈 The first parameter will always be of type \MVC\DataType\DTArrayObject $oDTArrayObject
  • 🛈 You can bind to Controller classes only which have \MVC\MVCInterface\Controller implemented
  • 🛈 Make sure to write the event name as the method was a static one, even it is not.

Additional Context Infos passed as second parameter to a bonded closure

As you may have noticed, the object \MVC\DataType\DTEventContext $oDTEventContext) is always being passed as the second parameter to a bonded closure. It provides Infos about the context of the event.

This is helpful if your app listens to events with placeholder * - let's say foo* (with placeholder asterisk). You can get the origin Event which matched to foo*:

// returns 'fooName'
$oDTEventContext->get_sEventOrigin();

example content of \MVC\DataType\DTEventContext $oDTEventContext)

// type: object
\MVC\DataType\DTEventContext::__set_state(array(
      'sEvent' => 'foo*',
      'sEventOrigin' => 'fooName',
      'mRunPackage' => true,
      'aBonded' =>    array (
        's:53:"/modules/{module}/etc/event/default.php, 7 (65759f7544778)";' =>        \Closure::__set_state(array(
        )),
    ),
      'sBondedBy' => 's:53:"/modules/{module}/etc/event/default.php, 7 (65759f7544778)";',
      'sCalledIn' => '/modules/Foo/Controller/Index.php, 58',
      'oCallback' =>    \Closure::__set_state(array(
    )),
      'sCallbackDumped' => 'function (oDTEventContext $oDTEventContext){
                        info($oDTEventContext);
                        display($oDTEventContext->get_sEventOrigin());
                },
',
      'sMessage' => 'RUN+ (foo* [fooName]) --> called in: /modules/Foo/Controller/Index.php, 58 --> bonded by `/modules/{module}/etc/event/default.php, 7 (65759f7544778), try to run its Closure: function ($mPackage, \\MVC\\DataType\\DTEventContext $oDTEventContext) { info($oDTEventContext); display($oDTEventContext->get_sEventOrigin()); }',
))

Bind to Events via config Stack with \MVC\Event::processBindConfigStack()

Instead of writing one bind command expressure after the other you can make use of array notation and use Event::processBindConfigStack.

Syntax

\MVC\Event::processBindConfigStack([ '{EventName}' => [ {Closure}, ], ]);

This way you can note bondings to multiple Events at once and you can even note multiple closures for each event.

This reduces complexity and improves readability.

Example: using config Stack to bind closures to Events

<?php
\MVC\Event::processBindConfigStack([ // Bondings to 2 Events

    '\Foo\Controller\Index::foo' => [ // 2 Closures bonded to this Event

        function (\MVC\DataType\DTArrayObject $oDTArrayObject, \MVC\DataType\DTEventContext $oDTEventContext) {      
            info($oDTArrayObject);
        },
        function (\MVC\DataType\DTArrayObject $oDTArrayObject, \MVC\DataType\DTEventContext $oDTEventContext) {      
            \MVC\Log:write($oDTArrayObject, 'debug.log');
        }
    ],
    '\Foo\Controller\Index::bar' => [ // 1 Closure bonded to this Event

        function (\MVC\DataType\DTArrayObject $oDTArrayObject, \MVC\DataType\DTEventContext $oDTEventContext) {      
            \MVC\Log:write($oDTArrayObject, 'debug.log');
        }
    ],    
]);

\MVC\Event::delete()

delete one or all events.

⚠ If this parameter not is set, all events are going to be deleted.

Example: delete the certain Event named foo.bar

\MVC\Event::delete('foo.bar');

Example: delete all Events

\MVC\Event::delete();

Emvicy Standard Events

Event Name Event::bind perforemd in Event::run located in value passed
app.controller.__construct.before \App\Controller::__construct \MVC\DataType\DTRequestCurrent $oDTRequestCurrent
mvc.event.init.after \MVC\Event::init
policy.index.requestMethodHasToMatchRouteMethod.after modules/{module}/etc/event/policy.php \{module}\Policy\Index::requestMethodHasToMatchRouteMethod \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.application.construct.after \MVC\Application::__construct
mvc.application.setSession.before modules/{module}/etc/event/default.php \MVC\Application::initSession
mvc.application.setSession.after \MVC\Application::initSession \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.application.destruct.before \MVC\Application::__destruct \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.controller.init.before \MVC\Request::getCurrentRequest \MVC\Controller::init
mvc.controller.init.after \MVC\Controller::init $bSuccess
mvc.controller.runTargetClassPreconstruct.after \MVC\Controller::runTargetClassPreconstruct \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.controller.destruct.before \MVC\Controller::__destruct \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.error \MVC\Error::init
modules/{module}/etc/event/default.php
\MVC\Controller::runTargetClassPreconstruct
\MVC\Request::getUriProtocol
\MVC\Policy::apply
\MVC\DataType\DTArrayObject $oDTArrayObject
mvc.policy.init.before \MVC\Policy::init
mvc.policy.init.after \MVC\Policy::init
mvc.policy.set.before \MVC\Policy::set array $aPolicy all declared policies
mvc.policy.set.after \MVC\Policy::set array $aPolicy all declared policies
mvc.policy.unset.before \MVC\Policy::unset array $aPolicy all declared policies
mvc.policy.unset.after \MVC\Policy::unset array $aPolicy all declared policies
mvc.policy.apply.before \MVC\Policy::apply array $aPolicy matching policy rules on the current request
mvc.policy.apply.execute \MVC\Policy::apply \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.reflex.reflect.before \MVC\Reflex::reflect \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.reflex.reflect.targetObject.before modules/{module}/etc/event/default.php \MVC\Reflex::reflect \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.reflex.reflect.targetObject.after modules/{module}/etc/event/default.php \MVC\Reflex::reflect \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.reflex.destruct.before \MVC\Reflex::__destruct \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.route.init.before \MVC\Route::init
mvc.route.init.after \MVC\Route::init
$sControllerClassName :: $sMethod \MVC\Reflex::reflect
mvc.request.getCurrentRequest.after \MVC\Request::getCurrentRequest \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.request.redirect \MVC\Request::redirect \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.routeintervall.intervall.before modules/{module}/etc/event/routeintervall.php \MVC\RouteIntervall::intervall \MVC\DataType\DTCronTask $oDTCronTask
mvc.routeintervall.intervall.after modules/{module}/etc/event/routeintervall.php \MVC\RouteIntervall::intervall \MVC\DataType\DTCronTask $oDTCronTask
mvc.routeintervall.intervall.skip modules/{module}/etc/event/routeintervall.php \MVC\RouteIntervall::intervall \MVC\DataType\DTCronTask $oDTCronTask
mvc.routeintervall.intervall.end modules/{module}/etc/event/routeintervall.php \MVC\RouteIntervall::intervall \MVC\DataType\DTCronTask $oDTCronTask
mvc.view.render.before \MVC\InfoTool::__construct \MVC\View::render \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.view.renderString.before \MVC\View::renderString $sTemplateString
mvc.view.renderString.after \MVC\View::renderString $sRendered
mvc.view.render.after \MVC\View::render \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.debug.stop.after modules/{module}/etc/event/default.php \MVC\Debug::stop \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.lock.create \MVC\Lock::create \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.view.echoOut.off \MVC\View::__construct
mvc.view.echoOut.on \MVC\View::__construct
mvc.view.render.off \MVC\View::__construct
mvc.view.render.on \MVC\View::__construct

Database Events

Event Name Event::bind perforemd in Event::run located in value passed
mvc.db.model.dbinit.construct.after
mvc.db.model.dbpdo.fetchRow.sql modules/{module}/etc/event/db.php \MVC\DB\Model\DbPDO::fetchRow string $sSql
mvc.db.model.dbpdo.fetchAll.sql modules/{module}/etc/event/db.php \MVC\DB\Model\DbPDO::fetchAll string $sSql
mvc.db.model.dbpdo.query.sql modules/{module}/etc/event/db.php \MVC\DB\Model\DbPDO::query string $sSql
mvc.db.model.db.construct.before \MVC\DB\Model\Db::__construct \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.construct.saveCache modules/{module}/etc/event/db.php \MVC\DB\Model\Db::__construct
mvc.db.model.db.create.before modules/{module}/etc/event/db.php \MVC\DB\Model\Db::create \MVC\DB\DataType\DB\TableDataType $oTableDataType
mvc.db.model.db.create.sql modules/{module}/etc/event/db.php \MVC\DB\Model\Db::create string $sSql
mvc.db.model.db.create.after \MVC\DB\Model\Db::create \MVC\DB\DataType\DB\TableDataType $oTableDataType
mvc.db.model.db.createTable.before \MVC\DB\Model\Db::createTable \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.createTable.after \MVC\DB\Model\Db::createTable \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.createTable.sql modules/{module}/etc/event/db.php \MVC\DB\Model\Db::createTable string $sSql
mvc.db.model.db.insert.sql modules/{module}/etc/event/db.php \MVC\DB\Model\Db::synchronizeFields string $sSql
mvc.db.model.db.retrieveTupel.before \MVC\DB\Model\Db::retrieveTupel \MVC\DB\DataType\DB\TableDataType $oTableDataType
mvc.db.model.db.retrieve.before \MVC\DB\Model\Db::retrieve \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.retrieve.sql modules/{module}/etc/event/db.php \MVC\DB\Model\Db::retrieve string $sSql
mvc.db.model.db.retrieve.after \MVC\DB\Model\Db::retrieve \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.count.before \MVC\DB\Model\Db::count \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.count.sql \MVC\DB\Model\Db::count string $sSql
mvc.db.model.db.updateTupel.before \MVC\DB\Model\Db::updateTupel \MVC\DB\DataType\DB\TableDataType $oTableDataType
mvc.db.model.db.updateTupel.after \MVC\DB\Model\Db::updateTupel \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.updateTupel.fail \MVC\DB\Model\Db::updateTupel \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.updateTupel.success \MVC\DB\Model\Db::updateTupel \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.update.before modules/{module}/etc/event/db.php \MVC\DB\Model\Db::update \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.{tableName}.update.before modules/{module}/etc/event/db.php \MVC\DB\Model\Db::update \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.update.sql modules/{module}/etc/event/db.php \MVC\DB\Model\Db::update string $sSql
mvc.db.model.db.{tableName}.update.sql modules/{module}/etc/event/db.php \MVC\DB\Model\Db::update string $sSql
mvc.db.model.db.update.fail \MVC\DB\Model\Db::update \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.{tableName}.update.fail \MVC\DB\Model\Db::update \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.update.success \MVC\DB\Model\Db::update \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.{tableName}.update.success \MVC\DB\Model\Db::update \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.deleteTupel.before \MVC\DB\Model\Db::deleteTupel \MVC\DB\DataType\DB\TableDataType $oTableDataType
mvc.db.model.db.delete.before \MVC\DB\Model\Db::delete \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.delete.sql modules/{module}/etc/event/db.php \MVC\DB\Model\Db::delete string $sSql
mvc.db.model.db.synchronizeFields.after \MVC\DB\Model\Db::synchronizeFields
mvc.db.model.db.dropIndices.after \MVC\DB\Model\Db::dropIndices

striked events are deprecated


Examples

Chained Events

wait for database coming up before binding to one (or more) certain events

// bind to those events
\MVC\Event::processBindConfigStack([

    // WHEN Database has been built...
    'mvc.db.model.dbinit.construct.after' => [

        function () {
            // ...bind to those events
            \MVC\Event::processBindConfigStack([

                // event
                'foo.model.index.action' => [
                    function () {
                        // concrete doing
                    },
                ],
            ]);
        }
    ],
]);

wait for database coming up before binding to a certain event, run a further event when job has been done

// bind to those events
\MVC\Event::processBindConfigStack([

    // event
    'job.done' => [
        function () {
            // concrete doing
        },
    ],

    // WHEN Database has been built...
    'mvc.db.model.dbinit.construct.after' => [

        function () {
            // ...bind to those events
            \MVC\Event::processBindConfigStack([

                // event
                'foo.model.index.action' => [
                    function () {

                        // concrete doing...

                        // run a "Job done" event
                        \MVC\Event::run('job.done', $mData);
                    },
                ],
            ]);
        }
    ],
]);