We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 44866
    • 50 Posts
    Hi Everyone,
    I'm working on some modifications to my web page. I didn't create it but I'm stuck with supporting it.

    So I'm trying to learn all the bits and pieces that go together to make MODX work.

    My ultimate goal to solve my current problem is to look up a file name in a table then remove that file from the file system.
    Towards that goal I have created a Snippet that I can run from the CronManager. (Based on an existing example)
    This Snippet can execute a PHP file. ( Also based on an existing example)


    I have a fairly complex SQL query that I want to run against a table in the database but I can't figure out how to do it.
    I have some examples where the existing code query's the database but it is so convoluted I can't figure out what it is doing.

    I'd be happy to start with a "Select * from tablename" and get that working. Output can go to the cron manager log.
    After that I should be able to continue teaching my self.

    I did do a search through the rtfm doco but couldn't find any examples.
    Any pointers in the right direction would be appreciated.

    My Modx version 2.2.6 (I know I'm working on upgrading it)

    Thanks
    David
      • 44866
      • 50 Posts
      I can see this example within my existing web page code but the sql only seems half complete (where is the "FROM") and I can't really understand the syntax.

      $query_obj->select('`modResource`.`id`, `TemplateVarResources`.`value`');
      		$query_obj->innerJoin('modTemplateVarResource', 'TemplateVarResources');
      		$query_obj->innerJoin('modTemplateVar', 'TemplateVar','`TemplateVar`.`id` = `TemplateVarResources`.`tmplvarid` AND `TemplateVar`.`name` = "PropertyID"');			
      		$query_obj->where(array(
      			'TemplateVarResources.value' => $property_id,
      			'modResource.template' => $this->template,
      			'modResource.parent' => $this->parent,
      		 ));
      		$query_obj->limit(1);
        • 18373 ☆ A M B ☆
        • 3,141 Posts
        What you're seeing is the xPDO data base layer. There are (should be) no actual "SELECT * FROM table" queries within the MODX core, and it's not recommended in extras either.

        The $query_obj you're seeing is an xPDOQuery object. You can read more about that here: http://rtfm.modx.com/xpdo/2.x/class-reference/xpdoquery

        The xPDOQuery replaces manually writing SQL, making sure it uses prepared PDO statements and that it's mostly database-agnostic.. the same code can normally run on MySQL and SqlServer for example. At the end of that block of code, there is probably a $modx->getObject, $modx->getCollection or $modx->getIterator statement passing the $query_obj as second parameter. Those methods build the actual SQL statement and fire it off to the database, returning an array of xPDOObject instances. In your example code, that instance happens to be a modResource.

        It's also possible to use $modx->query('SELECT * FROM table'), which will return a PDOStatement object. I wouldn't recommend that as it bypasses the security measures and a bunch of other xPDO features.
          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.
          • 44866
          • 50 Posts
          Hi Mark,
          That is exactly what I needed to know. You explained it clearly as well.
          It also explains why when ever I look at a PHP example I always see them passing passwords around. I figured that MODX was picking up the password from somewhere but couldn't see how.

          I'll make my simple Hello World example and then try to upscale it to my more complex query.

          Thanks!
          David
            • 28042 ☆ A M B ☆
            • 24,524 Posts
            As you have surmised, MODX opens a connection to the database automatically on every page request. So any code, be it snippet, plugin, or TV @EVAL binding, has access to that database connection. The same with the session; you do not need to ever start a session when working in MODX-based code.

            These default connections and sessions are why it's always best to use a MODX resource as the vehicle for handling AJAX processors or any other "external" code that isn't used to generate a page in itself. You can use a snippet in a resource with a (blank) template for returning AJAX request, or for generating dynamic code for cron to use - anywhere where you will need a simple returned value.

            All of the .php files that you can see in the MODX core, including the cached snippet and plugin files in core/cache/ as well as .php files for add-ons in core/components/, are included into the index.php file using include, include_once, require and require_once directives.

            Likewise, the Manager does the same thing with the /manager/index.php file. That is the actual file called when any requests are made to the Manager.
              Studying MODX in the desert - http://sottwell.com
              Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
              Join the Slack Community - http://modx.org
              • 3749
              • 24,544 Posts
              You might find this useful: http://bobsguides.com/revolution-objects.html.

              Is the table you want to query a MODX table, or a custom table of your own?
                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
                • 44866
                • 50 Posts
                As far as "Hello World" goes this did the trick.
                I tried to understand the XPDOQuery stuff but it is just to obscure for me.
                I kept getting confused.
                Next I'll try and convert this to use my more complex query.

                Thanks again for your help guys.

                David

                $output = '';
                $sql = "SELECT * FROM myDBName.myTableName";
                foreach ($modx->query($sql) as $row) 
                {
                	$output = $row['Col1Name']."\t".$row['Col2Name'];
                	if ($this->debug){ $this->logMessage('Debug: function run() Output=', $output);}
                }
                
                function logMessage($item, $message) 
                {
                	$this->messages[] = array( 
                	'item' => $item,
                	'message' => $message
                	);
                }
                
                  • 44866
                  • 50 Posts
                  I don't believe it. I started with the above script working then slowly added stuff to make my more complex SQL Query. It didn't work so I started removing things again to get back to the exact script above and it still doesn't work.

                  Part of my problem is I can't debug things apart from outputting variables to the cron log.
                  I'm executing my code as a cron job as this is how it will be executed once complete.
                  If I make any syntax errors nothing at all happens, no errors that I can find.

                  If I comment out the foreach loop above my code executes so the problem is with this line.
                  foreach ($modx->query($sql) as $row) 


                  Any idea's what I'm doing wrong or how I can capture any actual error messages?

                  Thanks
                  David
                    • 3749
                    • 24,544 Posts
                    Since you have $modx instantiated, you can do this at any point to write to the MODX error log:

                    $msg = 'Debugging Message';
                    $modx->log(modX::LOG_LEVEL_ERROR, $msg);


                    You might find this useful: http://bobsguides.com/blog.html/2014/11/19/using-my-sql-in-modx/

                      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
                      • 4172
                      • 5,888 Posts
                      not sure, if pollardd has really instantiated modx.
                      maybe, it is not, is the reason, why his code stops execution at this line

                      foreach ($modx->query($sql) as $row)


                      seems to be the only line, where a modx-method is called.
                        -------------------------------

                        you can buy me a beer, if you like MIGX

                        http://webcmsolutions.de/migx.html

                        Thanks!