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

    I'm relatively new to modx and I've come across something that I can't seem to get my head around. Any help would be appreciated.

    I have created a resource which runs a snippet. This resource is called via ajax on a form submit.

    In the snippet, I am adding my package and then running a query to retrieve some results from the db.

    This works fine if there is nothing in my class, however, I would like to add my query into my class as a method so that I can reuse it.

    Once I add a construct to my class it breaks and I get the following error.

    Fatal error: Call to a member function getOption() on a non-object in pathtosite/core/xpdo/om/xpdoobject.class.php on line 703

    This is just by adding the following to my class:

    function __construct(modX &$modx,array $config = array()){
    $this->modx =& $modx;
    }

    Am I doing something obviously wrong here?

    Thanks in advance

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

      • 3749
      • 24,544 Posts
      That error suggests that the $modx variable is not really an instance of modX. Are you sure you're passing a valid instance of $modx as the first argument to the constructor?

      Are you calling the constructor with $modx->newObject() rather than just new (assuming that your class is set up for xPDO)?
        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
        • 50077
        • 8 Posts
        Hi BobRay

        Thanks for your reply.

        At the moment I'm not even calling the constructor, it breaks simply by adding a constructor to the class with nothing in it.

        However, when I did try calling the constructor and the method, I was doing this:

        $service = new Service($modx);

        return $service->searchServices($searchTerm);

        Is this not correct?

        Thanks
          • 50077
          • 8 Posts
          By adding the constructor and method back into the class and calling them like:

          $service = $modx->newObject('Service');

          return $service->searchServices($searchTerm);

          It manages to get to the query and prints it out but seems to fail at: $suggestions = $this->modx->getCollection('Service', $query); with the same error as above.

            • 4172
            • 5,888 Posts
            Would you like to show the whole code of the class and how/where you call that class?
              -------------------------------

              you can buy me a beer, if you like MIGX

              http://webcmsolutions.de/migx.html

              Thanks!
              • 50077
              • 8 Posts
              Hi Bruno17

              This is my class:

              class Service extends xPDOSimpleObject{
                  public $modx;
                  public $config = array();
              
                  function __construct(modX &$modx,array $config = array()){
                      $this->modx =& $modx;
              
                      $basePath = $this->modx->getOption('search_bar.core_path','',$this->modx->getOption('core_path').'components/search_bar/');
                      $assetsUrl = $this->modx->getOption('search_bar.assets_url','',$this->modx->getOption('assets_url').'components/search_bar/');
              		
                      $this->config = array_merge(array(
                          'basePath' => $basePath,
                          'corePath' => $basePath,
                          'modelPath' => $basePath.'model/',
                          'processorsPath' => $basePath.'processors/', 
                          'templatesPath' => $basePath.'templates/',           
                          'chunksPath' => $basePath.'elements/chunks/',
                          'jsUrl' => $assetsUrl.'js/',
                          'cssUrl' => $assetsUrl.'css/',
                          'assetsUrl' => $assetsUrl,
                          'connectorUrl' => $assetsUrl . 'connector.php',
                      ),$config);
                  }
              
                  public function searchServices($searchTerm  = ''){
                      
                      if($searchTerm != ""){
              	        $query = $this->modx->newQuery('Service');
              		$query->select($this->modx->getSelectColumns('Service','Service','',array('id', 'subject', 'link', 'target')));
              		$query->leftJoin('ServiceTag', 'ServiceTag', 'Service.id = ServiceTag.service_id');
              		$query->leftJoin('Tag', 'Tag', 'ServiceTag.tag_id = Tag.id');
              		$query->where(array(
              		'Service.subject:LIKE' => '%'.$searchTerm.'%',
              		'OR:Tag.tag:LIKE' => '%'.$searchTerm.'%'
              		));
              		$query->sortby('Service.subject','ASC');
              		$query->limit(10);
              	
              		$query->prepare();
              		print $query->toSQL();
              		
              		$suggestions = $this->modx->getCollection('Service', $query);
              		
              		if(count($suggestions) > 0){
              
              			foreach($suggestions as $suggestion) {
              		
              				$listItems[] = array(
              				        "label"=>$suggestion->get('subject'),
              					"link"=>$suggestion->get('link'),
              					"target"=>$suggestion->get('target')
              				);
              			}
              	
              		}else{
              			$listItems[] = array(
              			        "label"=>"no results found",
              				"link"=>"/services",
              				"target"=>""
              			);
              			
              		}
              		return json_encode($listItems);
                      }
                  }
              }
              


              And in my snippet I have:

              
              $modelPath = MODX_CORE_PATH . 'components/search_bar/model/';
              
              //add package
              if(!$modx->addPackage('search_bar', $modelPath,'res_search')){
              	$modx->log(modX::LOG_LEVEL_ERROR, 'Error loading Service class in snippet.service.php');
              	return 'Error adding search_bar package in snippet.service.php';
              }
              
              $action = (isset($_POST['action'])) ? $_POST['action'] : '';
              $searchTerm = (isset($_POST['search_term'])) ? $_POST['search_term'] : '';
              
              if($searchTerm != "" && $action == "service-search"){
              	
              	$service = $modx->newObject('Service');
              	
              	//search for services
              	return $service->searchServices($searchTerm);
              }
              


              The snippet is being called via a resource via ajax.

              Thanks
                • 4172
                • 5,888 Posts
                1. 'Service' isn't a very good name for a custom - class, use something, what you are sure, this is unique.
                2. You shouldn't extend a xpdo-object-class this way with a constructor like that
                3. Create instead another class, which doesn't extend a xpdo-object and put your searchServices - method there.
                  -------------------------------

                  you can buy me a beer, if you like MIGX

                  http://webcmsolutions.de/migx.html

                  Thanks!
                  • 50077
                  • 8 Posts
                  Thanks for the help.

                  I've changed the name of my class to something more appropriate and unique and taken out the construct and method.
                  I have basically gone back to how I had it in the beginning and it works fine. I followed this: http://bobsguides.com/custom-db-tables.html
                  to get to this point which created classes that extend xPDOSimpleObject.

                  So if I want to now put my snippet code (basically a search query, which I could reuse elsewhere) in my class, how would I go about doing that?
                  Are you saying I would need a separate class for that?

                  The construct that I had in my class came about from trying create a CMP. I assumed that I would use the same classes for the front end and the back end.

                  Could you point me in the right direction for setting up a CMP for my custom DB tables?
                  • discuss.answer
                    • 4172
                    • 5,888 Posts
                    If you ask me, I would do it with help of MIGXdb

                    For listings migxLoopCollection does work for many scenarios
                      -------------------------------

                      you can buy me a beer, if you like MIGX

                      http://webcmsolutions.de/migx.html

                      Thanks!
                      • 50077
                      • 8 Posts
                      Thanks so much for your help. MIGXdb is really helpful.