We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 36760
    • 136 Posts
    I'm using Modx Revolution 2.5.5-pl. I feel like I'm missing something obvious with this, but I'm trying to write a plugin that will populate a TV with a value based on an MIGX TV if it exists, or with the publishedon date if the MIGX TV doesn't exist. I've never written anything like this, so I decided to start simple.

    I came across this thread as a starting point: https://forums.modx.com/thread/?thread=71048. This gave me the plugin below which is set to run "OnDocFormSave." This plugin causes Modx to hang on "Saving..." on any resource.
    <?php
    $tvId = 104;
    $tv1 = $modx->getObject('modTemplateVarResource',array ('tmplvarid'=>$tvId,'contentid' => $id));
    $val = $tv1->getValue();
    
    $modx->log(modX::LOG_LEVEL_ERROR,'Testing Output: ' . $val);

    If I only use the following, a message is added to the Error Log on save as expected.
    <?php
    $modx->log(modX::LOG_LEVEL_ERROR,'Testing Output: ');

    I've also tried using getTVValue and setTVValue in a similar fashion, but Modx still hangs on "Saving..."
    <?php
    $modx->log(modX::LOG_LEVEL_ERROR,'Testing Output: ' . $modx->resource->getTVValue('guideParentID'));

    I'm not quite sure where I'm going wrong, even the Plugin entry in the wiki shows similar methods. The TV ID 104 is just a plain text TV with a number as the value, so there's nothing going on with MIGX (yet).

    I appreciate any help!

    This question has been answered by BobRay. See the first response.

      • 42562
      • 1,145 Posts
      When it hangs, what is the browser error?

      I guess it hang because the value is not sanitized or escaped properly.

      Where is the code that sets the value of TV?

        TinymceWrapper: Complete back/frontend content solution.
        Harden your MODX site by passwording your three main folders: core, manager, connectors and renaming your assets (thank me later!)
        5 ways to sniff / hack your own sites; even with renamed/hidden folders, burst them all up, to see how secure you are not.
        • 36760
        • 136 Posts
        Chrome had changed its Console filtering, so I wasn't seeing the errors before! This is what comes up. I might be able to do some more digging on my own now.
        Failed to load resource: the server responded with a status of 500 () (index.php)
        
        Uncaught Object
        message: "JsonReader.read: Json object not found" (ext-all.js:21)


        There is no code that sets the TV currently, it's entered manually. I figured I'd start simple.

        **EDIT**
        There are no additional errors in the Modx Error Log either, and nothing in the server error logs that I can find, for what it's worth.
        • discuss.answer
          • 3749
          • 24,544 Posts
          Try this:

          $contentId = $modx->resource->get('id');
          $tvr = $modx->getObject('modTemplateVarResource',array ('tmplvarid'=>$tvId,'contentid' => $contentId));
          if ($tvr) {
              $val = $tv1->get('value');
          }


          If for any reason MODX can't get the TVR object, the getValue() call will throw a fatal PHP error. Also, you need to be aware that for TVs set to their default value, there is no modTemplateVarResource record, and as donshakespeare suggests, for certain kinds of TVs, the raw value won't be what you want. AFAIK, MIGX TVs store their values as JSON strings, so that's what you'll get back.

          You're getting the modTemplateVarResource value, not the TV. And I'm pretty sure that object doesn't have a getValue() method, so you need to simply grab the 'value' field.

          Another approach:
          It will be slower, but you might be better off getting the TV object itself and calling getValue() or renderOutput() on it. That would look like this:

          $tvId = 104;
          $contentId = $modx->resource->get('id');
          $tv = $modx->getObject('modTemplateVar', $tvId);
          
          
          if ($tv) {
              $val = $tv->getValue($contentId); // gets the raw value of the TV
              // or
              // $val = $tv->renderOutput($contentId); // gets the processed value of the TV (e.g., for image TVs, dates, and maybe MIGX TVs)
          }
          

          That will convert any JSON values to PHP arrays and it will handle TV's set to their default values. You still need the if statement because for some pages, the TV may not be connected to the page template.


            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 36760
            • 136 Posts
            Thanks for the help Bob! I think my server is actually causing some of the trouble, it seems to 500 error when I switch too quickly between saving a plugin and saving a resource to see if it works. I have the first part working below, with a few questions below that.

            <?php
            $contentId = $modx->resource->get('id');
            
            $tv_guideParentID_ID = 48;
            $tv_guideParentID = $modx->getObject('modTemplateVar', $tv_guideParentID_ID);
            
            if ($tv_guideParentID) {
              $tv_guideParentID_val = $tv_guideParentID->getValue($contentId);
              $modx->log(modX::LOG_LEVEL_ERROR,'tv_guideParentID: ' . $tv_guideParentID_val);
              
              $tv_guideChangeLog_ID = 37;
              $tv_guideChangeLog = $modx->getObject('modTemplateVar', $tv_guideChangeLog_ID);
              if ($tv_guideChangeLog) {
                  $changeDate = $modx->runSnippet('getImageList',array(
                      'docid' => $contentId,
                      'tvname' => 'guideChangeLog',
                      'tpl' => 'guideChangeLogDateNoFormatTpl',
                      'reverse' => '1',
                      'limit' => '1'
                  ));
                  $modx->log(modX::LOG_LEVEL_ERROR,'changeDate: ' . $changeDate);
              }
            }


            Is "if ($tv_guideParentID)" supposed to check if the TV is assigned to the current resource's template? Currently it's triggering whether the TV is assigned to the resource or not. My next step is adding an "else" statement if the TV doesn't exist or is empty that pulls the publishedon date instead.

            I'm guessing there's a better way to get the value I need over $modx->runSnippet? I haven't tried $tv->renderOutput yet. I was just excited it was working in some capacity!
              • 3749
              • 24,544 Posts
              "if ($tv_guideParentID)" is a fairly generic sanity check. It's checking to see if the TV object was retrieved successfully (getObject() returns null on failure). It's there because if you don't have the TV, getValue() or any other call to a method of the TV will throw a fatal PHP error.

              There are lots of reasons why you might not have gotten the TV (not attached to resource's template, permissions violation, incorrect name or ID, TV doesn't exist, etc.). The if() statement will catch all of them.

              I'm not sure what getImageList actually does, so it's difficult to suggest a better method. Presumably, getImageList replaces the placeholders in the Tpl chunk, so rolling your own shortcut would probably mean copying code out of the getImageList snippet. It would be faster, but maybe not enough to make it worth the work involved.



                Did I help you? Buy me a beer
                Get my Book: MODX:The Official Guide
                MODX info for everyone: http://bobsguides.com/modx.html
                My MODX Extras
                Bob's Guides is now hosted at A2 MODX Hosting
                • 36760
                • 136 Posts
                Thanks for the explanations! I'll keep fiddling with it, I'm making progress now.

                I have one other question, is there something besides the plugin code that would be causing "Saving..." to hang? I can be using the same exact plugin code that was working on one save, but it'll hang another time. It's always the same console errors as I posted above, and it happens in both Chrome and FireFox. Saving doesn't hang when the plugin is disabled, so it seems like it's related to the plugin but also not at the same time.

                I've tried clearing core/cache, and my browser cache. I upgraded to 2.5.8 today as well. Sometimes disabling the plugin, saving the resource, enabling the plugin, and saving again works, but not always. Most of the time I just need to wait awhile.
                  • 3749
                  • 24,544 Posts
                  It sure sounds like the plugin is causing the problem, but if there was anything wrong with the code, the problem wouldn't be intermittent.

                  My best guess would be that it's a problem with getImageList. Maybe it's timing out.

                  It could also be mod_security if the output from getImageList might look suspicious.
                    Did I help you? Buy me a beer
                    Get my Book: MODX:The Official Guide
                    MODX info for everyone: http://bobsguides.com/modx.html
                    My MODX Extras
                    Bob's Guides is now hosted at A2 MODX Hosting
                    • 36760
                    • 136 Posts
                    I forgot to mention in my last message, getImageList is just the MIGX snippet, nothing that I wrote myself. I'll look into mod_security a little bit. I still can't nail down why it works sometimes and not other times.

                    Thanks again for all the help!

                    **EDIT**
                    I don't want to jinx it, but I changed the OnDocFormSave Priority from 0 to 1, and it seems to be working consistently now. I'll give it until tomorrow then set the thread as answered if it's still working. [ed. note: firebot6 last edited this post 6 years, 7 months ago.]
                    • To properly debug the 500 error, look at your server's error log (PHP/apache/nginx) for anything around the time of the error. If there's nothing in your logs, open the browser developer tools before saving the resources and look on the network tab. That should list the outgoing AJAX request that returns the 500 error. Click on it to see the details, including the response, which will likely contain the PHP error.
                        Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

                        Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.