Handlers

The Handlers tab shows you a list of all the handlers that have been created in Backstage. Handlers are used to define the behavior of a change when it is deployed. This is useful for visualizing the objects that are tracked and the data sent with them.
Adding a Custom Handler
If you need to track additional items you can implement the GenericHandler in a plugin. Below is example code for a custom handler in MODX to track context settings.
<?php
use Backstage\v3\Callback\Handlers\GenericHandler;
use MODX\Revolution\modContextSetting;
use xPDO\Transport\xPDOTransport;
/** Plugin Name: Backstage.ContextSettings
* Event: BackstageCallbackInit
*/
$handlersMap = $scriptProperties['handlersMap'];
$handlersMap->addHandler(modContextSetting::class, GenericHandler::getInstance(
$modx,
function($data){
// return label/name for the changed grid
return $data['object']->context_key . ' - ' . $data['object']->key;
},
function($data){
// return primary key
return [
'context_key' => $data['object']->context_key,
'key' => $data['object']->key,
];
},
function () {
// return the object graph
return [
'graph' => [],
'attributes' => [
xPDOTransport::PRESERVE_KEYS => true,
xPDOTransport::UPDATE_OBJECT => true,
xPDOTransport::RELATED_OBJECTS => false,
]
];
}
));
<?php
/** Plugin Name: Backstage.ContextSettings
* Event: BackstageCallbackInit
*/
$bsCore = $modx->getOption('backstage.core_path', null, $modx->getOption('core_path', null, MODX_CORE_PATH) . 'components/backstage/');
/** @var Backstage $backstage */
$backstage = $modx->getService(
'backstage',
'Backstage',
$bsCore . 'model/backstage/',
[
'core_path' => $bsCore
]
);
$handlersMap = $scriptProperties['handlersMap'];
$handlersMap->addHandler(
'modContextSetting',
\Backstage\v2\Callback\Handlers\GenericHandler::getInstance(
$modx,
function($data){
// return label/name for the changed grid
return $data['object']->context_key . ' - ' . $data['object']->key;
},
function($data){
// return primary key
return [
'context_key' => $data['object']->context_key,
'key' => $data['object']->key,
];
},
function () {
// return the object graph
return [
'graph' => [],
'attributes' => [
xPDOTransport::PRESERVE_KEYS => true,
xPDOTransport::UPDATE_OBJECT => true,
xPDOTransport::RELATED_OBJECTS => false,
]
];
}
));
Extending an Existing Handler
Similar to custom handlers, you can create a plugin that extends or alters an existing handler class. The example below shows how to extend MODX to handle MIGX Template Variables on a Resource.
<?php
use \Backstage\v3\Callback\Handlers\Resource;
use \MODX\Revolution\modResource;
use \MODX\Revolution\modTemplateVar;
/** Plugin: Backstage.MIGX
* Event: BackstageCallbackInit
**/
if (!class_exists('MIGXResourceHandler')) {
class MIGXResourceHandler extends Resource
{
// overide the Find Template Variable assets functionality
public function findTVAssets($resource, array &$assets, $assetsTVs): void
{
parent::findTVAssets($resource, $assets, $assetsTVs);
$resourceArray = $resource->toArray();
// The IDs of the MIGX TVs
$migxTVs = [4, 76];
foreach ($migxTVs as $assetTV) {
if (!isset($resourceArray['tv' . $assetTV])) {
continue;
}
/** @var modTemplateVar $tv */
$tv = $this->modx->getObject(modTemplateVar::class, ['id' => $assetTV]);
if (!$tv) {
continue;
}
$src = json_decode($resourceArray['tv' . $assetTV], true);
foreach ($src as $value) {
// The field of the image to check within the MIGX TV
if (isset($value['Image'])) {
$this->addSrc($assets, $value['Image']);
}
}
}
}
}
}
$handlersMap =& $scriptProperties['handlersMap'];
$handlersMap->addHandler(
modResource::class,
new MIGXResourceHandler($modx),
true
);
<?php
/** Plugin: Backstage.MIGX
* Event: BackstageCallbackInit
**/
$bsCore = $modx->getOption('backstage.core_path', null, $modx->getOption('core_path', null, MODX_CORE_PATH) . 'components/backstage/');
/** @var Backstage $backstage */
$backstage = $modx->getService(
'backstage',
'Backstage',
$bsCore . 'model/backstage/',
[
'core_path' => $bsCore
]
);
if (!class_exists('MIGXResourceHandler')) {
class MIGXResourceHandler extends \Backstage\v2\Callback\Handlers\Resource
{
// overide the Find Template Variable assets functionality
public function findTVAssets($resource, array &$assets, $assetsTVs): void
{
parent::findTVAssets($resource, $assets, $assetsTVs);
$resourceArray = $resource->toArray();
// The IDs of the MIGX TVs
$migxTVs = [4, 76];
foreach ($migxTVs as $assetTV) {
if (!isset($resourceArray['tv' . $assetTV])) {
continue;
}
/** @var \modTemplateVar $tv */
$tv = $this->modx->getObject('modTemplateVar', ['id' => $assetTV]);
if (!$tv) {
continue;
}
$src = json_decode($resourceArray['tv' . $assetTV], true);
foreach ($src as $value) {
// The field of the image to check within the MIGX TV
if (isset($value['Image'])) {
$this->addSrc($assets, $value['Image']);
}
}
}
}
}
}
$handlersMap =& $scriptProperties['handlersMap'];
$handlersMap->addHandler(
'modResource',
new MIGXResourceHandler($modx),
true
);
Last modified: 04 February 2025