We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 36994 ☆ A M B ☆
    • 10 Posts
    Hi,

    I'm trying to learn how to use xPDO (and more about OOP in general) so please show mercy if I do something totally dumb.
    I'm putting together a snippet/component with basic CRUD methods. I want to be able to use these methods through AJAX.

    I started by adding a single document in manager (ajax.html).
    Created a snippet with code:

    $base_path = $modx->getOption('assets_path').'components/crudTest/';
    
    $o = '';
    $f = $base_path.'crudTest.php';
    if (file_exists($f)) {
       $o = include $f;
    } else {
       $modx->setLogTarget('ECHO');
       $modx->log(modX::LOG_LEVEL_ERROR,'StoreFinder not found at: '.$f);
    }
    
    echo $o;


    Snippet call was placed (uncached) in my doc (ajax.html)

    Using Bob's guide I was able to generate table xml schema and necessary classes and when I follow his examples I'm able to insert, select and edit my data.
    I "post" my forms to ajax.html using jQuery and so far no problems.

    I want to go further and wrap my code into a class where each method will be a different action (ie: add, save, delete, select).

    I changed my snippet to:
    $path = $modx->getOption('assets_path').'components/crudTest/';
    $modx->addPackage('crudTest',$path . 'model/','prefix_');
    
    $output = '';
    $action = ($_POST['action']) ? filter_var($_POST['action'], FILTER_SANITIZE_STRING) : 'index';
    
    //get the class file 
    $f = $modx->getOption('assets_path').'components/crudTest/crudTest.class.php';
    
    if (file_exists($f)) {
    	
       include $f;
       $o = new CrudTest($modx); 
       
       if (method_exists($o,$action)) {
          $output = $o->{$action}();
          return $modx->toJSON($output);
       } 
    }
    
    $output = array('response' => NULL, 'error' => array('Method not found'));
    return $modx->toJSON($output);


    In my class I do:

    class CrudTest {
    
    	public $modx;
    
    	function __construct(&$modx) {
    		$this->modx = & $modx;
    	}
    
    	public function index() {
    		$data = array(
    			'response' => NULL,
    			'error' => array(),
    			'action' => 'index'
    		);
    		return $data;
    	}
    
    
            /* only one method to keep it short */
    	public function save() {
    
    		if ($_POST) {
    
    			$fields = array(
    				'user_id' => $this->modx->user->get('id'),
    				'addedon' => time()
    			);
    
    			$save = $this->modx->newObject('crudTest', $fields);
    			$save->save($save);
    		} else {
    			$return = 'empty';
    		}
    
    		// 		
    		$data = array(
    			'response' => $return,
    			'error' => array(),
    			'action' => 'save'
    		);
    
    		return $data;
    	}
    
    }


    Here is the place where I'm stuck.
    I'm not sure what I did wrong here but I'm not able to get any of xPDO methods to work in my class.
    My $this->modx object returns NULL or I'm getting errors like:

    <b>Fatal error</b>:  Nesting level too deep - recursive dependency?


    There is a problem with how I reference $modx object in my class for sure and especially how (or where) I register my package but I have no clue what I did wrong.

    I would appreciate if somebody help me understand how to do this properly.

    thanks.

      ----
      regards
      demagu
      • 3749
      • 24,544 Posts
      This looks a little suspect:

      $save = $this->modx->newObject('crudTest', $fields);
                  $save->save($save);

      ;)

      If your schema defines the class as extending an xPDO object (which it almost certainly does), it already has a save() method. IOW, you can just do this:

      $myObject = $this->modx->newObject('crudTest', $fields);
      $myObject->save();


      I understand that you're doing a learning exercise, but xPDO has all the necessary CRUD functions built in, so creating new ones on top of them will almost certainly land you in trouble and is probably not the best approach for what you want to do.

      I think you'd be better off learning the methods that already exist. Then, after you're comfortable with them, you can add your own to do what they won't do for you.

      There's some information here that might help: http://bobsguides.com/revolution-objects.html. Your class automatically has almost all the methods described there, including get(), set(), and save(). And you can access your object with getOne(), getMany(), getObject(), and getCollection().
        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
        • 2249
        • 60 Posts
        ashfinlayson Reply #3, 15 years ago
        I tried to implement this and got this error:

        <b>Fatal error</b>:  Call to a member function save() on a non-object in <b>/var/www/pfu/website/assets/site/classes/registration.class.php</b> on line <b>39</b><br />
        


        Heres the code i was using:

        $fields = array(
        			'title' => $industry,
        			'display' => 0
        		);
        				
        $qry = $this->modx->newObject('pfu_categories',$fields); // my db table and an array of stuff to insert
        $qry->save();


        I dont really understand the new method for dealing with databases at all. DBAPI was far easier
          • 3749
          • 24,544 Posts
          Do you have a $modx->addPackage() call to load your class (and are you testing the return value from that call (it returns true on success)?
            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