Check if resource contain specific TV

Summary

Hello everyone.
I’m building a plugin that needs to find for certain TV inside a resource to do what the snippets are build to do!.
It’s working fine, the problem is if the TV exist but it’s empty is not doing anything because obviously I’m getting the TV content not checking if it has been assigned to the resource.

Step to reproduce

$documents = $modx->getCollection('modResource',array(  
    'deleted' => 0,
    'published' => 1,
    'searchable' => 1,
    'context_key' => 'web'
));
foreach ($documents as $document) {
        $findtv = $document->getTVValue('TVnameHere);
        if ($findtv) {
                //OK let`s proceed!!!
        }
}

I need it to run if exist, empty or not!
Any help please?
Thank you very much!

Maybe check the template of the resource.
If the TV is assigned to the template (modTemplateVarTemplate), then it exists for the resource.

Well I think I solve it just using

empty();

$documents = $modx->getCollection('modResource',array(  
    'deleted' => 0,
    'published' => 1,
    'searchable' => 1,
    'context_key' => 'web'
));
foreach ($documents as $document) {
        //This is returning what I need!
        $findtv = empty($document->getTVValue('TVnameHere));
        if ($findtv) {
                //OK let`s proceed!!!
        }
}

Thank you very much!

Are you sure this works?

The function getTVValue returns null if the TV doesn’t exist and an empty string if the value of the TV is not set.

I don’t think empty() can discern between these two cases.

mate you are 100% right it doesn’t work, I just test it quick but at the end it’s not the way.

when I print the $document

print_r($document);

I can see the values I need, the problem is in that mess it’s hard to get them.

Right now an empty TV or not assigned TV are the same, so no way to know when to do something.

Can you please guide me on the process and how to use the modTemplateVarTemplate once I got the massive object and used the forEach to get the $document.

I just need to check if the tv existi in the resource, enpty or not ( I can get that one).

Thanks mate.

The easiest way in your case is probably just to check if the return value from getTVValue() is null.

$findtv = $document->getTVValue('TVnameHere');
if (!is_null($findtv)){
    //TV exists
} else {
    //TV doesn't exist
}

I already tried that, isset() , is_null() , empty() … no luck!
I think it’s because there is not difference between empty TV and no TV:
For example:

Resource ID:1 TV value is: 1TVTVTVTVTV1111111
Resource ID:3 TV value is:
(no value has been assigned= empty)
Resource ID:4 No TV has been assigned, different template.

The plugin code:

$documents = $modx->getCollection(‘modResource’,array(
‘deleted’ => 0,
‘context_key’ => ‘web’,
‘contentType’ => ‘text/html’
));
foreach ($documents as $document) {

    $id = $document->get('id');

    $findtv = $document->getTVValue('TVname');

    if (!is_null($findtv)){

        $modx->log(modX::LOG_LEVEL_ERROR, "$id NO NULL $findtv");
        $modx->log(modX::LOG_LEVEL_ERROR, var_dump($findtv));

    } else {

        $modx->log(modX::LOG_LEVEL_ERROR, "$id NULL $findtv");
        $modx->log(modX::LOG_LEVEL_ERROR, var_dump($findtv));

    }

The Output:

[2022-04-05 11:07:33] (ERROR @ blablabla.cache.php : 42) 1 NO NULL TVTVTVTVTV1111111
[2022-04-05 11:07:33] (ERROR @ blablabla.cache.php : 43)
[2022-04-05 11:07:33] (ERROR @ blablabla.cache.php: 42) 3 NO NULL
[2022-04-05 11:07:33] (ERROR @ blablabla.cache.php: 43)
[2022-04-05 11:07:33] (ERROR @ blablabla.cache.php: 42) 4 NO NULL
[2022-04-05 11:07:33] (ERROR @ blablabla.cache.php : 43) blablabla.cache.php : 1677) [OnWebPagePrerender]
string(17) “TVTVTVTVTV1111111”
string(0) “”
string(0) “”

As you see the var_dump() for ID’s 3 and 4 are string(0).
when ID 3 has the TV empty but ID 4 didn’t have the TV at all.

What a mystery! :sweat_smile:

Thanks @halftrainedharry

That is weird!
It seems to work when I test it.

What versions of MODX and PHP do you use?


Maybe you can try something like this:

//Query all template-ids with the TV (ID = 1) assigned to it.
$c = $modx->newQuery('modTemplateVarTemplate', array('tmplvarid' => 1)); //change '1' to the correct TV-ID
$c->select($modx->getSelectColumns('modTemplateVarTemplate', '', '', array('templateid')));
$c->prepare();
$c->stmt->execute();
$templates = $c->stmt->fetchAll(PDO::FETCH_COLUMN, 0);

//Use these template-ids in your call to getCollection
$documents = $modx->getCollection('modResource',array('template:IN' => $templates, ...));

Probably the best way is a direct query to the tables on a single sentence, yet I won’t necessarily show if a TV is used in a resource, for example, you could have a TV on a resources just using the default value, and it would show as not used, as well as a TV with assigned value, but not actually used anywhere, showing that it’s used.

At the end I’ve found 2 possible ways to this challenge, one, is to use a parser and before procesing modx tags, check if the TV is present on any of the resources elements, or the best one, which I went with, was to have a custom CMP where I can explicitly add a TV to a chunk or resource, and have the matching info on a custom table, I did this to overcome the shown of non used TVs on a resources to reduce the amount of “noise” my users were getting, like seeing 10 potential TVs, when only one was actually used at a given point

@halftrainedharry Mate you nail it. Excellent, thank you very much! :partying_face:
Now I’m getting only 2 resources, 1 with the tv value and one with an empty value.

[2022-04-05 19:16:01] (ERROR @ blablabla.cache.php : 58) 1 NO NULL TVTVTVTVTV1111111
[2022-04-05 19:16:01] (ERROR @ blablabla.cache.php : 59) 
[2022-04-05 19:16:01] (ERROR @ blablabla.cache.php : 58) 3 NO NULL 
[2022-04-05 19:16:01] (ERROR @ blablabla.cache.php : 59) 
[2022-04-05 19:16:01] (ERROR @ blablabla.class.php : 1677)
[OnWebPagePrerender]
string(17) "TVTVTVTVTV1111111"
string(0) ""

This is the right output! :+1:
I’m working local anyway: AMPPS V41 + ModX 2.8.3 + PHP 7.4

@camicase82 Thanks man for your help, I think the approach is very good, I like the idea of find TV’s in the code to hide fields in the manager, but is it not easier just create a template only with the necessary TV’s? Cheers mate! :+1:

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”.