Make Plugins Execute Based on TV Values

Enable or disable plugins based on the values of specific TVs


In the previous article, we looked at how to enable or disable Manager plugins based on specific resource fields of the resource being edited or updated. In this one, we'll look at restrictions based on TV values of the resource.


MODX logo

Using Template Variable Values to Enable or Disable Plugins

This is relatively simple. Using $resource in the Manage and $modx->resource in the front end, you can do one of the following:

/* Manager */
$value = $resource->getTVValue('TvName' or ID);

/* Front End */
$value = $modx->resource->getTVValue('TvName' or ID);

Using the ID will be slightly faster, but remember not to put quotes around the ID. Remember also that this will get you the *rendered* value of the TV. For image TVs, for example, you'll get a full image tag, not just the path to the image. If you want the raw value of the TV, you can do this:

$tvId = 12; // ID of the TV

/* Manager */
$docId = $resource->get('id');

/* Front End */
$docId = $modx->resource->get('id');

$tvObject = $modx->getObject('modTemplateVar', $tvId);

$value = $tvObject->getValue();

Controlling the Plugin

This works just like the code in the previous articles. The following code assumes that the $value variable has been set using one of the methods above.

The code will look like one of the following options, placed at the top of the plugin (below the point where the $value variable is set):

/* Disable the plugin if the value is 12 */
if ( (int) $value === 12) {
    return;
}

/* Disable the plugin if the value is not 12 */
if ( (int) $value !== 12) {
   return;
}

Note that in the code just above, we've used a cast to convert $value to an integer, so that no matter what type the TV contains, as long as it can be converted to an integer, we can use the strict === equality test.

As we discussed in a previous article, if you use a strict operator like === or !==, pay attention to the type of value that might be returned by the TV. This is especially true when there might be a 0 or 1 in the value being tested and you're using a boolean (true/false) test, or could contain string that starts with a numeric value and you're doing a numeric comparison.

/* Multiple values */

$allowedValues = array(12,34,52);
if (! in_array($allowedValues, (int) $value)) {
    return;
}

$disAllowedValues = array(11,23,32);
if (in_array($disAllowedValues, (int) $value)) {
    return;
}

Using in_array() in strict mode

Note that in_array() takes an optional third argument called "strict." It can be true or false. If it's true, in_array() will use a strict comparison (===). So the values must be of the same type for in_array() to find a match.

Using a strict comparison is important if there might be matches you don't want to make that result from type coercions that could occur.

Consider this example where the array represents a single car where 0 and 1 are used to tell whether the car has certain features, and strings are used to describe other features. You want to add cars to the results if they have an automatic transmission:

$vehicle = array(
    'make' => 'ford',
    'model' => 'mustang',
    'convertible' => 1,
    'heated_seats' => 1,
    'backup_camera' => 0,
    'transmission' => 'manual',
);

if (in_array('automatic', $vehicle) !== FALSE) {
   addToResults($vehicle);
}

You might think that this car won't get added to the results because it doesn't have an automatic transmission, especially since you are using the strict inequality operator, !==.

That's not what will happen, however. In fact almost all cars will be added to the results.

The in_array() function checks each member of the $vehicle array for a match. When it hits any array member with a numeric value, it will coerce the first argument ('automatic') to an integer in order to compare it with the integer value of the array member. Because 'automatic' is not a numeric value, it's converted to the integer 0, which matches the value for 'backup_camera'.

Having found a match, in_array() returns true. As long as the car is missing one of the listed features it will be included in the results, regardless of its transmission type.

The cleanest solution is to just add true as the third argument to in_array():

if (in_array('automatic', $vehicle, true) !== FALSE)

Now, in_array() will use a strict comparison and no type coercions will occur. The test string, 'automatic' will not match any of the array values unless the car actually has an automatic transmission.


Coming Up

In the next article, we'll see how to get the paths of a Media Source.



Looking for high-quality, MODX-friendly hosting? As of May 2016, Bob's Guides is hosted at A2 hosting. (More information in the box below.)



Comments (0)


Please login to comment.

  (Login)