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: 2025-02-15

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([

    /**
     * after current request was get
     */
    'mvc.request.in.after' => [
        /*
         * logging requests
         */
        function(\MVC\DataType\DTRequestIn $oDTRequestIn, \MVC\DataType\DTEventContext $oDTEventContext) {

            if (false === \MVC\Config::get_MVC_LOG_REQUEST())
            {
                return false;
            }

            \MVC\Log::write(php_sapi_name () . ' ' . $oDTRequestIn->get_requestMethod() . ' ' . $oDTRequestIn->get_full(), \MVC\Config::get_MVC_LOG_FILE_REQUEST());
        },
    ],
]);

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('\Foo\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
app.controller.__destruct \App\Controller::__destruct
app.controller.cron.__destruct \App\Controller\Cron::__destruct
app.controller.cron.run.maintenance \App\Controller\Cron::run
app.controller.cron.run.warning modules/{module}/etc/event/cron.php \App\Controller\Cron::run string $sWarningText
app.controller.cron.run.after modules/{module}/etc/event/cron.php \App\Controller\Cron::run string pid: $iPid, $sRoute
app.controller.queue.worker modules/{module}/etc/event/queue.php \App\Controller\Queue::workerAutoRouteResolve string pid: $iPid, id: $iIdQueue \t $sWorkerClassConcreteJob
app.controller.queue.__destruct \App\Controller\Queue::__destruct
app.model.menu.build.after \App\Model\Menu::build
app.model.menu.build.before \App\Model\Menu::build
app.table.queue.push.before modules/Foo/etc/event/queue.php \App\Table\Queue::push
app.table.queue.push.after modules/Foo/etc/event/queue.php \App\Table\Queue::push
app.table.queue.pop.before modules/Foo/etc/event/queue.php \App\Table\Queue::pop
app.table.queue.pop.after modules/Foo/etc/event/queue.php \App\Table\Queue::pop
app.table.queue.popall.before modules/Foo/etc/event/queue.php \App\Table\Queue::popAll
app.table.queue.popall.after modules/Foo/etc/event/queue.php \App\Table\Queue::popAll
app.table.queue.expire.before modules/Foo/etc/event/queue.php \App\Table\Queue::expire
app.table.queue.expire.after modules/Foo/etc/event/queue.php \App\Table\Queue::expire
mvc.application.construct.after \MVC\Application::__construct
mvc.application.destruct.before \MVC\Application::__destruct \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.application.maintenance modules/Foo/etc/event/default.php \MVC\Application::getMaintenanceTimeStamp int $iFilectime
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.controller.init.before \MVC\Request::in \MVC\Controller::init
mvc.controller.init.after \MVC\Controller::init boolean $bSuccess
mvc.controller.runTargetClassPreconstruct.after \MVC\Controller::runTargetClassPreconstruct \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.controller.destruct.before \MVC\Controller::__destruct \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.debug.stop.after modules/{module}/etc/event/default.php \MVC\Debug::stop \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.event.init.after \MVC\Event::init
mvc.lock.create \MVC\Lock::create \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.policy.init.after \MVC\Policy::init
mvc.policy.init.before \MVC\Policy::init
mvc.policy.set.after \MVC\Policy::set array $aPolicy all declared policies
mvc.policy.set.before \MVC\Policy::set array $aPolicy all declared policies
mvc.policy.unset.after \MVC\Policy::unset array $aPolicy all declared policies
mvc.policy.unset.before \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.process.callRoute.after modules/Foo/etc/event/process.php \MVC\Process::callRoute
mvc.process.callRoute.before modules/Foo/etc/event/process.php \MVC\Process::callRoute
mvc.process.deleteZombieFiles.after modules/Foo/etc/event/process.php \MVC\Process::deleteZombieFiles string $sPidFile
mvc.process.destruct.after modules/Foo/etc/event/process.php \MVC\Process::destruct int $iPid
mvc.reflex.reflect.before \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.reflect.targetObject.before 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.request.in.after modules/Foo/etc/event/request.php \MVC\Request::in \MVC\DataType\DTRequestIn $oDTRequestIn
mvc.request.out.before \MVC\Request::out
mvc.request.out.after \MVC\Request::out
mvc.request.redirect \MVC\Request::redirect \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.route.init.after \MVC\Route::init
mvc.route.init.before \MVC\Route::init
mvc.route.handleFallback.after \MVC\Route::handleFallback \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.routeintervall.run.before \MVC\RouteIntervall::run \MVC\DataType\DTCronTask $oDTCronTask
mvc.routeintervall.intervall.after modules/{module}/etc/event/routeintervall.php \MVC\RouteIntervall::intervall \MVC\DataType\DTCronTask $oDTCronTask
mvc.routeintervall.intervall.before 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.routeintervall.intervall.skip modules/{module}/etc/event/routeintervall.php \MVC\RouteIntervall::intervall \MVC\DataType\DTCronTask $oDTCronTask
mvc.view.echoOut.off \MVC\View::__construct
mvc.view.echoOut.on \MVC\View::__construct
mvc.view.render.after \MVC\View::render \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.view.render.off \MVC\View::__construct
mvc.view.render.on \MVC\View::__construct
mvc.view.render.before \MVC\InfoTool::__construct \MVC\View::render \MVC\DataType\DTArrayObject $oDTArrayObject
mvc.view.renderString.before \MVC\View::renderString string $sTemplateString
mvc.view.renderString.after \MVC\View::renderString string $sRendered
mvc.worker.after \MVC\Worker::run string Infotext
policy.index.requestMethodHasToMatchRouteMethod.after modules/{module}/etc/event/policy.php \{module}\Policy\Index::requestMethodHasToMatchRouteMethod \MVC\DataType\DTArrayObject $oDTArrayObject
$sControllerClassName :: $sMethod \MVC\Reflex::reflect

Database Events

Event Name Event::bind perforemd in Event::run located in value passed
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.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.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.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.deleteTupel.before \MVC\DB\Model\Db::deleteTupel \MVC\DB\DataType\DB\TableDataType $oTableDataType
mvc.db.model.db.dropIndices.after \MVC\DB\Model\Db::dropIndices
mvc.db.model.db.insert.sql modules/{module}/etc/event/db.php \MVC\DB\Model\Db::synchronizeFields string $sSql
mvc.db.model.db.retrieve.after \MVC\DB\Model\Db::retrieve \MVC\DataType\DTValue $oDTValue
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.retrieveTupel.before \MVC\DB\Model\Db::retrieveTupel \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.before \MVC\DB\Model\Db::updateTupel \MVC\DB\DataType\DB\TableDataType $oTableDataType
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.{tableName}.update.before modules/{module}/etc/event/db.php \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.{tableName}.update.sql modules/{module}/etc/event/db.php \MVC\DB\Model\Db::update string $sSql
mvc.db.model.db.{tableName}.update.success \MVC\DB\Model\Db::update \MVC\DataType\DTValue $oDTValue
mvc.db.model.db.setForeignKey.before \MVC\DB\Model\Db::setForeignKey
mvc.db.model.db.setForeignKey.after \MVC\DB\Model\Db::setForeignKey
mvc.db.model.db.synchronizeFields.after \MVC\DB\Model\Db::synchronizeFields
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.dbcollection.construct.after \MVC\DB\Model\DbCollection::__construct Registry::get(Db::$sRegistryKeyDbPDO)

Examples

Chained Events

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

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

    'mvc.db.model.dbcollection.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.dbcollection.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);
                    },
                ],
            ]);
        }
    ],
]);