We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 40541
    • 85 Posts
    Hi,

    I use the following snippet (dbconnect) to access an external DB and load the package for it:

    if (!isset($modx->myDB)) {
     
    $host = 'IPAddress';
    $username = 'Username';
    $password = 'Password';
    $dbname = 'DBName';
    $port = 3306;
    $charset = 'utf-8';
        
    $dsn = "mysql:host=$host;dbname=$dbname;port=$port;charset=$charset";
    $modx->myDB = new xPDO($dsn, $username, $password);
        
    echo $o = ($modx->myDB->connect()) ? 'Connected </br>' : 'Not Connected';
    
      $path = MODX_CORE_PATH . 'components/nhs/';
    	if (!$modx->myDB->addPackage('packageName', $path . 'model/','')) {
    	  print 'There was a problem adding your package.';
    	};
    
    }
    


    What I want to be able to do is load this dbconnect once and then use queries against it when I want, in other snippets like the following:

    $results = $modx->myDB->getCollection('LogData',array('diallednumber' => $search));
    


    But the error I am getting is the following:


    Notice: Undefined property: modX::$myDB in /home/sites/domain.co.uk/public_html/nhs/core/cache/includes/elements/modsnippet/20.include.cache.php on line 11 Fatal error: Call to a member function getCollection() on a non-object in /home/sites/domain.co.uk/public_html/nhs/core/cache/includes/elements/modsnippet/20.include.cache.php on line 11

    I think the problem is that the Instantiation (if I have my terminology right?) of the dbconnect is not being made available to the getCollection snippet. Maybe I need to store $modx->myDB in a session or cookie? If so I not quite sure either how to do that if anyone can point me in the right direction.

    Many thanks.
      • 4172
      • 5,888 Posts
      How to you call your snippets? cached/uncached? In which order?

      $modx->myDB should be avail in your second snippet
        -------------------------------

        you can buy me a beer, if you like MIGX

        http://webcmsolutions.de/migx.html

        Thanks!
        • 40541
        • 85 Posts
        Thanks for answering.

        I'm calling the dbconnect cached and the get collection uncached (if i'm correct as per below). In the code of my template I have the following:

        [[dbconnect]]
        [[!dbform]]
        


        where the dbform snippet is as follows

        <?php
        if (isset($_POST['search'])) {
        
            $search = $_POST['search'];
         
            $results = $modx->myDB->getCollection('LogData',array('diallednumber' => $search));
        
            if ($results) {
        	   $output ='';
             foreach($results as $result) {
              $fields = $result->toArray();
               $output .= $modx->getChunk('ShowData', $fields);
             }
            }else {
             return 'No items found.';
            }
        }
        return $output;
        
        • I'm not seeing any red flags on why that shouldn't work, it sounds like it's not keeping your class assigned to the $modx object.

          Personally I would take a slightly different approach than what you're showing, and maybe it's worth giving that a try. I'd do something like this using a wrapper class..

          class MyClass {
            /* @var xPDO $myDB */
            public $myDB = null;
            /* @var modX $modx */
            public $modx = null;
          
            public function __construct(&$modx, $options) {
              $this->modx = &$modx;
              $this->getConnection();
            }
            public function  getConnection() {
              $host = 'IPAddress';
              $username = 'Username';
              $password = 'Password';
              $dbname = 'DBName';
              $port = 3306;
              $charset = 'utf-8';
          
              $dsn = "mysql:host=$host;dbname=$dbname;port=$port;charset=$charset";
              $this->myDB = new xPDO($dsn, $username, $password);
          
              $this->modx->log(modX::LOG_LEVEL_ERROR, ($modx->myDB->connect()) ? 'Connected </br>' : 'Not Connected' );
          
              $path = MODX_CORE_PATH . 'components/nhs/';
              if (!$this->myDB->addPackage('packageName', $path . 'model/')) {
                $this->modx->log(modX::LOG_LEVEL_ERROR, 'There was a problem adding your package.');
              };
            }
          }


          and using $modx->getService in your snippet:

          $modx->getService('myclass','MyClass', MODX_CORE_PATH . '/components/myclass/model/myclass.class.php');
          $modx->myclass->myDB->getCollection();


          The getService call will make sure it's only initiated once, and you just place that getService call at the top of every snippet to make sure it's loaded.
            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.
            • 4172
            • 5,888 Posts
            I think cached snippets aren't executed as soon as the page is cached.

            But you can call both snippets cached:
            [[dbconnect]]
            [[dbform]]


            As soon, as you need your xpdo-instance in an uncached snippet, you should call your dbconnect-snippet also uncached, I think:

            [[!dbconnect]]
            [[!dbform]]


              -------------------------------

              you can buy me a beer, if you like MIGX

              http://webcmsolutions.de/migx.html

              Thanks!
              • 40541
              • 85 Posts
              Bruno17 - can't believe it was that simple but your recommendation worked, thanks!

              Mark - I like the idea of using this wrapper class and calling that instead. Please excuse any newbie error but I have created the myclass.class.php file in my /components/packagename/model/packagenaame/myclass.class.php and am calling it with my new dbform snippet as follows:

              <?php
              if (isset($_POST['search'])) {
               
                  $search = $_POST['search'];
                
                  $modx->getService('myclass','MyClass', MODX_CORE_PATH . '/components/packagename/model/packagename/myclass.class.php');
                  $results = $modx->myclass->myDB->getCollection('LogData',array('diallednumber' => $search));
               
                  if ($results) {
                     $output ='';
                   foreach($results as $result) {
                    $fields = $result->toArray();
                     $output .= $modx->getChunk('ShowData', $fields);
                   }
                  }else {
                   return 'No items found.';
                  }
              }
              return $output;
              


              but am getting the following error:


              Notice: Undefined property: modX::$myclass in /home/sites/domain.co.uk/public_html/nhs/core/cache/includes/elements/modsnippet/20.include.cache.php on line 13 Notice: Trying to get property of non-object in /home/sites/domainl.co.uk/public_html/nhs/core/cache/includes/elements/modsnippet/20.include.cache.php on line 13 Fatal error: Call to a member function getCollection() on a non-object in /home/sites/paradoxal.co.uk/public_html/nhs/core/cache/includes/elements/modsnippet/20.include.cache.php on line 13

              Thanks
              • I think you'd have to create a new namespace (System -> Namespaces) for MODx to know what you're talking about when you say "myclass".
                  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
                  • 40541
                  • 85 Posts
                  Thanks Sottwell.

                  I move the myclass.class.php to components/myclass/model/

                  Create a new Namespace as follows: myclass {core_path}components/myclass/

                  I change the getService back to this:

                  	$modx->getService('myclass','MyClass', MODX_CORE_PATH . '/components/myclass/model/myclass.class.php');
                  


                  and am still getting the same error.


                  • That third parameter should be the path to the directory the class is in. If you add your package before calling getService, you should not need to specify this at all however.
                      • 40541
                      • 85 Posts
                      Opengeek - thanks for the info, although I'm thinking I can not use that in this case as the purpose of the class is to get the connection to add the package. So I couldn't therefore add the package, to get the myclass that then makes to connection (blimey, think I've confused myself smiley

                      Here is what I have done, written exactly as it is:

                      Namespace created as follows:

                      Name: myclass
                      Path: {core_path}components/nhs/model/nhs/

                      File created as below:

                      File: myclass.class.php
                      Path: core/components/nhs/model/nhs/myclass.class.php

                      Error log shows the following:

                      [2013-01-08 12:26:29] (ERROR @ /nhs/index.php) Could not load class: MyClass from myclass.
                      [2013-01-08 12:26:29] (ERROR @ /nhs/index.php) Problem getting service myclass, instance of class MyClass, from path /home/sites/domain.co.uk/public_html/nhs/core/components/nhs/model/nhs/myclass.class.php

                      And the getService call

                      $modx->getService('myclass','MyClass', MODX_CORE_PATH . 'components/nhs/model/nhs/myclass.class.php');


                      Which I can not make sense of the error asvthe path is correct and the class file is there?