We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 4172
    • 5,888 Posts
    Trying to understand xPDO

    after reading in the forum, the docs to xpdo, the examples and the code of revolution -
    reading ’all’ the posts in the forum again - reading the docs again ............. and so on.
    playing a little bit with that great thing, what is xPDO. (sorry for my bad englisch!)

    Created my first experiment with xPDO and trying to understand.
    It counts each call to a Document, where the snippet is placed, and saves the count in a TV.

    <?php
    
    $host=$modx->dbConfig['host'];
    $dbname=str_replace("`", "", $modx->dbConfig['dbase']);
    $dbusername=$modx->dbConfig['user'];
    $dbpassword=$modx->dbConfig['pass'];
    $dbprefix=$modx->dbConfig['table_prefix'];
    	
    define('XPDO_MODE', 2);
    include_once ( $modx->config['base_path'] . 'core/xpdo/xpdo.class.php');
    
    $xpdo= new xPDO('mysql:host='.$host.';dbname='.$dbname, $dbusername, $dbpassword, $dbprefix);
    $xpdo->setPackage('modx095',XPDO_CORE_PATH .'../model/');
    $xpdo->setDebug(false);
    $xpdo->loadClass('modElement');
    //
    //  get the docid of your choice, here its the actuell doc
    //
    $id=$modx->documentIdentifier;
    $criteria= $xpdo->newQuery('modResource', $id);
    $criteria->limit(1);
    $docm= $xpdo->getObject('modResource', $criteria);
    
    if ($docm) { 
    $output.= "DOC OK <br/>";
    $content= $docm->get('content');
    $pagetitle= $docm->get('pagetitle');
    $longtitle= $docm->get('longtitle');
    $output.= '<br/>Content   : '.$content;
    $output.= '<br/>PageTitle : '.$pagetitle.'<br/>';
    
    $tvname= $xpdo->getObject('modTemplateVar', array ('name' => 'test'));
    $tv_criteria=array ('tmplvarid' =>$tvname->get('id'), 'contentid'=> $docm->get('id'));
    
    //print_r($param);
    if ($tvname) { $output.= "TVname OK <br/>";
    
    //$docm->getMany('modTemplateVarDocument');
    $tvs= $xpdo->getObject('modTemplateVarDocument', $tv_criteria);
    //print_r($docm);
    if ($tvs) { 
      $value=$tvs->get('value');
      $value++;
      $tvs->set('value', $value);
      $tvs->save(); 
      $output.= 'TV edited to '.$value.' <br/>';
    } else {
    	$tvs=$xpdo->newObject('modTemplateVarDocument');
      if ($tvs) { 
      $tvs->set('value', '0');
      $tvs->fromArray($tv_criteria); 
      $tvs->save();
      $output.= "new TV created <br/>";
    } else {$output.= "TV could not be created <br/>";}	
    }
    } 
      else {$output.= "TVname NOT OK <br/>";}
       
    } else {$output.= "DOC NOT found";}   
    
    ?>


    Ok, works fine. But now some questions.

    • Is there a way in xPDO to get all or just some TVs together with the Document with getObjectGraph or so as one object, using the relations from the schema?
    • make some changes to the TVs in that document (create new if not saved before) with $docm->set.......
    • make changes to the document
    • then save the document-object together with all the changes on document and TVs with $docm->save?

    Is it possible? And when yes, how can I do that magic thing?

    Bruno
      -------------------------------

      you can buy me a beer, if you like MIGX

      http://webcmsolutions.de/migx.html

      Thanks!
    • Quote from: Bruno17 at Sep 03, 2008, 10:29 AM

      Created my first experiment with xPDO and trying to understand.
      It counts each call to a Document, where the snippet is placed, and saves the count in a TV.

      <?php
      
      $host=$modx->dbConfig['host'];
      $dbname=str_replace("`", "", $modx->dbConfig['dbase']);
      $dbusername=$modx->dbConfig['user'];
      $dbpassword=$modx->dbConfig['pass'];
      $dbprefix=$modx->dbConfig['table_prefix'];
      	
      define('XPDO_MODE', 2);
      include_once ( $modx->config['base_path'] . 'core/xpdo/xpdo.class.php');
      
      $xpdo= new xPDO('mysql:host='.$host.';dbname='.$dbname, $dbusername, $dbpassword, $dbprefix);
      $xpdo->setPackage('modx095',XPDO_CORE_PATH .'../model/');
      $xpdo->setDebug(false);
      $xpdo->loadClass('modElement');
      //
      //  get the docid of your choice, here its the actuell doc
      //
      $id=$modx->documentIdentifier;
      $criteria= $xpdo->newQuery('modResource', $id);
      $criteria->limit(1);
      $docm= $xpdo->getObject('modResource', $criteria);
      
      if ($docm) { 
      $output.= "DOC OK <br/>";
      $content= $docm->get('content');
      $pagetitle= $docm->get('pagetitle');
      $longtitle= $docm->get('longtitle');
      $output.= '<br/>Content   : '.$content;
      $output.= '<br/>PageTitle : '.$pagetitle.'<br/>';
      
      $tvname= $xpdo->getObject('modTemplateVar', array ('name' => 'test'));
      $tv_criteria=array ('tmplvarid' =>$tvname->get('id'), 'contentid'=> $docm->get('id'));
      
      //print_r($param);
      if ($tvname) { $output.= "TVname OK <br/>";
      
      //$docm->getMany('modTemplateVarDocument');
      $tvs= $xpdo->getObject('modTemplateVarDocument', $tv_criteria);
      //print_r($docm);
      if ($tvs) { 
        $value=$tvs->get('value');
        $value++;
        $tvs->set('value', $value);
        $tvs->save(); 
        $output.= 'TV edited to '.$value.' <br/>';
      } else {
      	$tvs=$xpdo->newObject('modTemplateVarDocument');
        if ($tvs) { 
        $tvs->set('value', '0');
        $tvs->fromArray($tv_criteria); 
        $tvs->save();
        $output.= "new TV created <br/>";
      } else {$output.= "TV could not be created <br/>";}	
      }
      } 
        else {$output.= "TVname NOT OK <br/>";}
         
      } else {$output.= "DOC NOT found";}   
      
      ?>


      Ok, works fine. But now some questions.

      • Is there a way in xPDO to get all or just some TVs together with the Document with getObjectGraph or so as one object, using the relations from the schema?
      • make some changes to the TVs in that document (create new if not saved before) with $docm->set.......
      • make changes to the document
      • then save the document-object together with all the changes on document and TVs with $docm->save?

      Is it possible? And when yes, how can I do that magic thing?

      Bruno

      First of all it looks like you are using the new classes with 0.9.6, which will not work, as there is a lot of code in the new Revolution code that would not apply in the legacy offering. Or are you just creating a model based on the same class structure? modElement is very specifically one of those classes making me think you are headed for trouble.

      Also, template variables are probably the most complex part of the Revolution code, because, well, it’s simply a complex situation, but, you can indeed get child objects populated with getObjectGraph() or getCollectionGraph(). You could make changes to the document or TVs and simply add a new object using xPDOObject->addOne() or ->addMany() or update an existing ones you already pulled in with your graph query, then just save()’ing the parent will take care of child changes (a.k.a. cascading save()’s).

      This is not a good subject for an example however, because of the complexity of the relationship between template variables and documents, via templates. Otherwise, I’d provide you a full example. I’ll see if I can’t come up with a reasonable example in the next few days as part of some efforts to better document xPDO in general.
        • 4172
        • 5,888 Posts
        OpenGeek, thanks for your reply and your great work! smiley

        Quote from: OpenGeek at Sep 03, 2008, 04:19 PM

        First of all it looks like you are using the new classes with 0.9.6, which will not work, as there is a lot of code in the new Revolution code that would not apply in the legacy offering. Or are you just creating a model based on the same class structure? modElement is very specifically one of those classes making me think you are headed for trouble.

        I did copy the 0.9.6 schema from here: http://modxcms.com/forums/index.php/topic,25021.msg153655.html#msg153655
        then I created the classes with the code from here: http://modxcms.com/forums/index.php/topic,12895.msg85352.html#msg85352
        and got the codesnippet for my experiments from here: http://modxcms.com/forums/index.php/topic,20639.msg127681.html#msg127681

        first it didn’t work, but after some little modifications and loading the modElement-class with
        $xpdo->loadClass('modElement');

        it does the job well.

        Also, template variables are probably the most complex part of the Revolution code, because, well, it’s simply a complex situation, but, you can indeed get child objects populated with getObjectGraph() or getCollectionGraph(). You could make changes to the document or TVs and simply add a new object using xPDOObject->addOne() or ->addMany() or update an existing ones you already pulled in with your graph query, then just save()’ing the parent will take care of child changes (a.k.a. cascading save()’s).

        I know, its complex, but I think its a good example for experimenting with.
        Ok since I could not find well documented examples huh (I know, first comes coding, then documentation) for getObjectGraph() or getCollectionGraph() xPDOObject->addOne() or ->addMany() I will play a little bit arround with it and try what I can get. After that I will report here what I could find out and sure have some more questions about it.

        Thank you,
        Bruno


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

          you can buy me a beer, if you like MIGX

          http://webcmsolutions.de/migx.html

          Thanks!
          • 4172
          • 5,888 Posts
          my next step
          Now I know a little bit more about addOne addMany getOne getMany getObjectGraph.............
          The shema for 0.9.6 from above link did not generate the relations, because there are no alias for aggregate and composite.
          So I made my own 0.9.6-shema. I will upload it with this post.

          Made a new code with same result as above, which uses the relations from the schema (the generated classes) for getting and saving objects with related subobjects. I don’t know if it is the right way, but it works. I’m wondering if there are better ways to do that.

          <?php
          
          $host = $modx->dbConfig['host'];
          $dbname = str_replace("`", "", $modx->dbConfig['dbase']);
          $dbusername = $modx->dbConfig['user'];
          $dbpassword = $modx->dbConfig['pass'];
          $dbprefix = $modx->dbConfig['table_prefix'];
          
          define('XPDO_MODE', 2);
          include_once ($modx->config['base_path'].'core/xpdo/xpdo.class.php');
          
          $xpdo = new xPDO('mysql:host='.$host.';dbname='.$dbname, $dbusername, $dbpassword, $dbprefix);
          $xpdo->setPackage('modx095', XPDO_CORE_PATH.'../model/');
          $xpdo->setDebug(false);
          
          //  get the docid of your choice, here its the actuell doc
          $id = $modx->documentIdentifier;
          $tvname = 'test2';
          
          //get the tmplvarid of the TV with given name
          $tvobj = $xpdo->getObject('modTemplateVar', array ('name'=>$tvname));
          if ($tvobj)
          {
              $tmplvarid = $tvobj->get('id');
          
              //get the document
              $docm = $xpdo->getObject('modResource', $id);
          
              //get the TVs related to the document
              $tvs2 = $docm->getMany('modTemplateVarResource');
          
              //make an array of all TVs related to the document for access with given tmplvarid
              //key -> tmplvarid, value -> id
              $tvarr = array ();
              foreach ($tvs2 as $key=>$tv)
              {
                  $tvarr[$tv->get('tmplvarid')] = $tv->get('id');
              }
          
              //check if tv exists, if not create a new one
              if ( isset ($tvarr[$tmplvarid]))
              {
                  //get the id for given TV from the array
                  $tvid = $tvarr[$tmplvarid];
                  $value = $tvs2[$tvid]->get('value');
                  $value++;
                  $tvs2[$tvid]->set('value', $value);
                  $output .= 'TV edited to '.$value.' <br/>';
              }
              else
              {
                  echo 'TV not found - must create new one';
                  $newtv = $xpdo->newObject('modTemplateVarResource');
                  $newtv->set('value', '1');
                  $newtv->set('tmplvarid', $tmplvarid);
                  $docm->addmany($newtv);
          
              }
              //echo 'class:'.get_parent_class($tvs2[$tvid]).'<br/>';
              //echo $tvs2[$tvid]->get('tvarid').':'.$tvs2[$tvid]->get('value').'<br/>';
          }
          else
          {
              $output .= "TVname NOT OK <br/>";
          }
          
          //save the doc and related TVs
          $docm->save();
          
          ?>
          


          Would be happy about more examples. Could you have a look for your xPDO-calender-Code, OpenGeek?
          Thanks for that all,

          Bruno

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

            you can buy me a beer, if you like MIGX

            http://webcmsolutions.de/migx.html

            Thanks!
          • Bruno17:

            Attached is the sample xPDO project I created and have used for several event calendars in 0.9.x sites. There is no visual calendar component, but the sample snippets and chunks do show how to present event listings in the hCalendar microformat as well as interact with the model.

            Let me know if this helps, or you have more questions...

              • 4172
              • 5,888 Posts
              thank you very much, OpenGeek!

              That is exactly what I was looking for. I want to try what I can do with it and will report about my success.

              Thanks again
              Bruno
                -------------------------------

                you can buy me a beer, if you like MIGX

                http://webcmsolutions.de/migx.html

                Thanks!