We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9207 ☆ A M B ☆
    • 2,475 Posts
    I’m having trouble isolating this behavior... but I have an xPDO snippet that fails if I put it on the page twice. I’m unsetting my variables after running the Snippet, but still no dice. Snippets are uncached, page is uncached, I even turned off the system setting.

    Anyone have any ideas as to what might be going on?
      • 22303 MODX Staff
      • 10,725 Posts
      Something in the tag must be different or all instances of the tag on the page will get replaced with the same content. We have been discussing whether this is proper behavior or not, but in most cases, if multiple instances of a snippet need to return different content, then at least one property should be different. Add a fake property if necessary to resolve this for now.
        • 9207 ☆ A M B ☆
        • 2,475 Posts
        Haven’t see you in a while Jason... hope you’re doing all right.

        Odd... the 2 Snippet calls do have different arguments. But when I put them side by side on the page (e.g. into the content field), only the first one returns output. It doesn’t matter which one is on top, but the one on top returns the output. I should sleep on this, but it’s really not that complicated of a Snippet other than it instantiates a new xPDO object, but I was having trouble emulating this behavior in a simple proof-of-concept.
          • 9207 ☆ A M B ☆
          • 2,475 Posts
          Ok, this is weird... putting the Snippet on the page returns output... putting the same Snippet call on the page twice causes NO OUTPUT from either call.

          I log the intended output... and only the first instance logs output to the logs (not to the screen). WTF?
            • 22303 MODX Staff
            • 10,725 Posts
            Quote from: Everett at Aug 26, 2010, 02:25 PM

            Ok, this is weird... putting the Snippet on the page returns output... putting the same Snippet call on the page twice causes NO OUTPUT from either call.

            I log the intended output... and only the first instance logs output to the logs (not to the screen). WTF?
            IDK what it could be, but perhaps if you shared the Snippet code I might be able to assist in diagnosing the problem.
              • 9207 ☆ A M B ☆
              • 2,475 Posts
              Jason -- I just sent you a private message with the full details, but here’s the Snippet code. I’m hoping it’s something obvious. Note that I’m including a custom config file with some static variables containing the login info to my other database.

              <?php
              /*------------------------------------------------------------------------------
              INPUT:
              	type (str) -- for the type column in the database, e.g. job, job_centers
              	tpl (str) -- name of Chunk used for formatting the output of the Categories
              		Placeholders: category_id, parent_id, type, name, description, sort
              OUTPUT:
              	maybe something intended for inclusion in a <select> option in a form
              
                <option value="volvo">Volvo</option>
                <option value="saab">Saab</option>
                <option value="mercedes">Mercedes</option>
                <option value="audi">Audi</option>
              ------------------------------------------------------------------------------*/
              
              include_once(MODX_CORE_PATH.'config/edfconfig.inc.php');
              
              if (empty($tpl) || empty($type))
              {
              	$modx->log(modX::LOG_LEVEL_ERROR, "MISSING ARGS: getCategories Snippet requires &tpl and &type arguments.");
              	return '<!-- missing arguments -->';
              }
              
              $output = '';
              
              $my_xpdo= new xPDO('mysql:host='.EDF_DB::$host.';dbname='.EDF_DB::$dbname, EDF_DB::$dbuser, EDF_DB::$dbpasswd,'');
              $my_xpdo->addPackage(EDF_DB::$package_name,EDF_DB::$package_path);
              
              
              /* http://rtfm.modx.com//display/xPDO20/Retrieving+Objects */
              $query = $my_xpdo->newQuery('Categories');
              $query->where(array(  
                  'type' => $type,
              ));
              
              $query->sortby('sort','ASC');
              $resources = $my_xpdo->getCollection('Categories', $query );
              
              // Stack the formatted output
              foreach ($resources as $r) {  
                  $resourceArray = $r->toArray();  
                  $resourceArray['cls'] = $rowCls;  
                  $output .= $modx->getChunk($tpl,$resourceArray);  
              }
              
              unset($tpl);
              unset($type);
              unset($my_xpdo);
              $modx->log(modX::LOG_LEVEL_ERROR, "getCategories Snippet ran: $output");
              return $output;
              ?>
              
                • 22303 MODX Staff
                • 10,725 Posts
                The problem might be your include_once(). Try include() on the config.
                  • 9207 ☆ A M B ☆
                  • 2,475 Posts
                  Using include() results in fatal errors because my custom config file uses a class to contain static variables:
                  Fatal error: Cannot redeclare class


                  I should store the values locally on the $modx object then retrieve them if they are available on subsequent Snippet calls...
                    • 9207 ☆ A M B ☆
                    • 2,475 Posts
                    The solution was to store the instance of the object. I thought I was just being lazy, but for some reason, the code didn’t work if I redeclared the xPDO object each time the Snippet was called.

                    So I first check to see if an instance has been declared, and if it has, I use it, but if it hasn’t, I create a new instance and store it inside the $modx->placeholders array:


                    // Instantiate and store an instance of xPDO the first time the Snippet is called on a page
                    if ( !isset($modx->placeholders['edf_xpdo']) || !is_a( $modx->placeholders['edf_xpdo'], 'xPDO') )
                    {
                    	$modx->placeholders['my_xpdo']= new xPDO('mysql:host='.EDF_DB::$host.';dbname='.EDF_DB::$dbname, EDF_DB::$dbuser, EDF_DB::$dbpasswd,'');
                    	$modx->placeholders['my_xpdo']->addPackage(EDF_DB::$package_name,EDF_DB::$package_path);
                    }
                    
                      • 45778
                      • 75 Posts
                      This thread is quite old, but I'm glad it's here, because it solved my problem. Here's another example of the same idea, with code that's slightly more generic, in case it's useful to anyone else. This could be the full snippet, assuming it's calling an external class:

                      require_once 'path/to/MyClassName.class.php';
                      
                      // send the class instance to a modx placeholder if it hasn't been called already
                      if ( !isset($modx->placeholders['MyClassName']) )
                      {
                          $modx->placeholders['MyClassName']= new MyClassName;
                      }
                      // shorten the variable name, for convenience
                      $myClass = $modx->placeholders['MyClassName'];
                      
                      $output = $myClass->myMethodName($parameters);
                      $output .= $myClass->myOtherMethodName($parameters);
                      return $output;