How to detect specific TV change inside a plugin?

I’d like to perform actions only if a specific TV value changed. I can get the TV value on OnDocFormRender and OnDocFormSave events but I cannot compare the values because all attemps to store the OnDocFormRender fails.

I have also tried to set a cookie but the problem still same.

$eventName = $modx->event->name;
switch($eventName) {
    case 'OnDocFormRender':
        if ($resource->get('template') == 17) {
           $edi_cron_fc_onload = $resource->getTVValue('edi_cron_fc');
        }
      
    break;
    case 'OnDocFormSave':
        if ($resource->get('template') == 17) {         
            $edi_cron_fc = $resource->getTVValue('edi_cron_fc');
//try to get $edi_cron_fc_onload
          $modx->log(modX::LOG_LEVEL_ERROR, 'Plugin: createNotifCron (48) OnDocFormSave > old TV value: ' . $edi_cron_fc_onload);// NEVER AVAILABLE

	break;
            }

Maybe you can use the event “OnBeforeDocFormSave” instead.

The value from the database should still be the original value and the new value you can probably get from $_POST. I think the parameter name is tv plus the TV ID (e.g. tv12).

You definitely want to get the TV value directly from the database rather than the resource before it’s gone. It should be there in OnBeforeDocFormSave, as halftrainedharry suggests. This should work for that:

$resourceId = $resource->get('id');
 /* You'll need to set the next one to the TV ID */
$tvId = 12;
$val = '';  /* Initialize $val to an empty string */

/* Set the selection criteria */
$c = array(
    'contentid' => $resourceId,
    'tmplvarid' => $tvId,
}

/* Get the TVR */
$tvr = $modx->getObject('modTemplateVarResource', $c);

/* Make sure we got the TVR and get the value */

if ($tvr) {
    $val = $tvr->get('value');
} else {
    /*  No TVR. We have to get the default value of the TV */
    $tv = $modx->getObject('modTemplateVar', $tvId);

    /* Make sure we got the TV object */
    if ($tv) {
        $val = $tv->get('default_text');
    }
}
if (!empty($val)) { /* This assumes that none of them will be empty */
   $_SESSION['db_tv_value'] = $val;
} else {
    /* Error message to log ? */
}

Now, you can get the $_SESSION variable value in OnDocFormSave and compare the values. The New TV Value should be available in the $resource object somewhere. You might be able get it with $resource->getTVValue($tvId). I think that will be the new value, but I’m not positive.

If not, the new value is in the $resource object somewhere, I think they’re identified as tv1, tv2, tv3, etc.

You can see it with this (in OnDocFormSave):

$modx->log(modX::LOG_LEVEL_ERROR, print_r($resource, true);

It’s a monster so it may swamp the log (in fact it’s recursive, too so unless MODX or PHP truncates it, it will be endless.). If you have a debugger, You can write a small script to load one of your resources and examine it. I once did this for your exact situation, but I can’t find the results.

PS: Don’t forget to do this at the end of the code that reads the session variable, or you’ll have a real mess on your hands.

unset($_SESSION['db_tv_value']);

Thank you very much for your help, it works like a charm !

[2023-03-31 09:17:50] (ERROR @ /var/www/***/***/***/***/***/cache/***/includes/elements/modplugin/48.include.cache.php : 117) Plugin: createNotifCron (48) OnDocFormSave > TV edi_cron_fc (old TV value): 1 * * * *
[2023-03-31 09:17:50] (ERROR @ /var/www/***/***/***/***/***/cache/***/includes/elements/modplugin/48.include.cache.php : 138) Plugin: createNotifCron (48) OnDocFormSave > TV edi_cron_fc (new value) a une valeur: * * * * *
    case 'OnBeforeDocFormSave':
        
        if ($resource->get('template') == 17) {
            
            $resourceId = $resource->get('id');
             /* You'll need to set the next one to the TV ID */
            $tvId = 518;
            $val = '';  /* Initialize $val to an empty string */
            
            /* Set the selection criteria */
            $c = array(
                'contentid' => $resourceId,
                'tmplvarid' => $tvId,
            );
        
            /* Get the TVR */
            $tvr = $modx->getObject('modTemplateVarResource', $c);
            
            /* Make sure we got the TVR and get the value */
            
            if ($tvr) {
                $val = $tvr->get('value');
            } else {
                /*  No TVR. We have to get the default value of the TV */
                $tv = $modx->getObject('modTemplateVar', $tvId);
            
                /* Make sure we got the TV object */
                if ($tv) {
                    $val = $tv->get('default_text');
                }
            }
            if (!empty($val)) { /* This assumes that none of them will be empty */
               $_SESSION['db_tv_value'] = $val;
            } else {
                /* Error message to log ? */
            }
            
                    
        }
         
        break;
    
    case 'OnDocFormSave':

        if ($resource->get('template') == 17) {

            $db_tv_value = $_SESSION['db_tv_value'];
            
            if($debug==true){ $modx->log(modX::LOG_LEVEL_ERROR, 'Plugin: createNotifCron (48) OnDocFormSave > TV edi_cron_fc (old TV value): ' . $db_tv_value ); }

            unset($_SESSION['db_tv_value']);

            if($edi_cron_fc){
                if($debug==true){ $modx->log(modX::LOG_LEVEL_ERROR, 'Plugin: createNotifCron (48) OnDocFormSave > TV edi_cron_fc (new value) a une valeur: ' . $edi_cron_fc); }
            } else {
                if($debug==true){ $modx->log(modX::LOG_LEVEL_ERROR, 'Plugin: createNotifCron (48) OnDocFormSave > TV edi_cron_fc (new value)  n\'pas de valeur: ' . $edi_cron_fc); }
            }
		}
    break;

Glad I could help. Thanks for reporting back. :slight_smile:

This topic was automatically closed 2 days after discussion ended and a solution was marked. New replies are no longer allowed. You can open a new topic by clicking the link icon below the original post or solution and selecting “+ New Topic”.