We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 3232
    • 380 Posts
    I'm looking to create a simple snippet that given an id and depth it will look in the tree, use the id given and transverse the tree to the depth indicated.

    I really don't know the first thing about XPDO and am a little lost. I have figured out how to do basic queries with it but I am not quite sure how I would go about getting the children and their children.

    I could use wayfinder (and have tried without success) because I am trying to use this in a TV input field. I was successfully able to product the desired string (in the frontend) with wayfinder but it won't work in the TV so I figured it might be easier, better to create a custom snippet.

    Does anyone have any information on how to accomplish this? I have done both google and forum search with little success. I have also search through the wayfinder code and my head just spins looking at it.

    Thanks
    Brian

      • 3232
      • 380 Posts
      So far I have the following which retrieves the entire tree.

      <?php
      $sortby = 'pagetitle';
       
      $c = $modx->newQuery('modResource');
      $c->where(array('published'=>1,'deleted:!=' =>'1'));
      $c->sortby($sortby);
      $collection = $modx->getCollection('modResource',$c);
       
      $output='select a page==';
      foreach ($collection as $o){
      $output .= '||'.$o->get('pagetitle').'('.$o->get('id').')=='.$o->get('id');
      }
      return $output;
      


      Would one have to set a specific parent (say 0) get the id of all items with that parent and then loop through each of those children and so on? I can think of a really convoluted way of doing that. [ed. note: betoranaldi last edited this post 14 years, 4 months ago.]
        • 3232
        • 380 Posts
        I am finding the APIs documentation very confusion (I'm sure it will click once I totally understand what is going on) but I found $modx->getChildIds()

        I can use that to get all children's ids, where i am lost is how can I use that array to query the database and get the pagetitle of each item?
          • 4172
          • 5,888 Posts
          try this:
          <?php
          $childs = $modx->getChildIds($parent,$depth);
          $sortby = 'pagetitle';
            
          $c = $modx->newQuery('modResource');
          $c->where(array('published'=>1,'deleted:!=' =>'1'));
          $c->where(array('id:IN'=>$childs));
          $c->sortby($sortby);
          $collection = $modx->getCollection('modResource',$c);
            
          $output='select a page==';
          foreach ($collection as $o){
          $output .= '||'.$o->get('pagetitle').'('.$o->get('id').')=='.$o->get('id');
          }
          return $output;
            -------------------------------

            you can buy me a beer, if you like MIGX

            http://webcmsolutions.de/migx.html

            Thanks!
            • 3232
            • 380 Posts
            Thanks Bruno, appreciate your help. I wan't aware you could stack where elements.

            I tried this out but it isn't outputing anything. I took a look at the logs and got the following:

            [2012-06-14 08:17:06] (ERROR @ /manager/index.php) Encountered empty IN condition with key id
            [2012-06-14 08:32:10] (ERROR @ /manager/index.php) parent:0 depth:5 children: 


            It appears that $childs is empty. I also added a line to output the values to the error log which doesnt seem to be working.

            My whole code is:

            <?php
            $parent = isset($parent) ? $parent : $modx->resource->get('id');
            $depth= isset($depth) ? $depth : '10';
            $sortby = isset($sortby) ? $sortby : 'pagetitle';
             
            $childs = $modx->getChildIds($parent,$depth);
            
            $modx->log(modX::LOG_LEVEL_ERROR, 'parent:'.$parent.' depth:'.$depth.' children:' . implode(',',$childs));
            
            $c = $modx->newQuery('modResource');
            $c->where(array('published'=>1,'deleted:!=' =>'1'));
            $c->where(array('id:IN'=>$childs));
            $c->sortby($sortby);
            $collection = $modx->getCollection('modResource',$c);
               
            $output='-==';
            foreach ($collection as $o){
            $output .= '||'.$o->get('pagetitle').'('.$o->get('id').')=='.$o->get('id');
            }
            return $output;
              • 3232
              • 380 Posts
              Figured it out, since this is being used in the manager, the context needs to be set:

              $childs = $modx->getChildIds($parent,$depth,array('context' => 'web'));


              Once that is set, it now returns results.

              Bruno, I can't thank you enough. Do you know of any resources that list/explain the xpdo getCollection and what can and can't be done while collecting resources? I would like to get a betting understanding of this.

              Thanks
              Brian

              P.S. to everyone, I am going to clean this up and post this snippet so everyone can have quill - like functionality in Revo. (just not as robust.) [ed. note: betoranaldi last edited this post 14 years, 4 months ago.]
                • 14147
                • 26 Posts
                Hi Brian.

                I've just tried your code out, however, my script is simply timing out, despite the fact that it should only be returning one child resource. I've tried one on Bob Guides, but that again simply times out (he uses getMany). However, if I use "getOne", it returns a dump of a database table of sorts.

                I'm running the latest version of ModX 2.2.4.

                Any ideas?
                  • 3232
                  • 380 Posts
                  Sorry for the delay, I didn't get notification of a post. This was in 2.2.2 but let me upgrade to the latest and get back to you.
                    • 3232
                    • 380 Posts
                    jigr69, the code is working in 2.2.4 without a problem. Here is my exact code and how I am using it. Give it a try and let me know how you make out.

                    I created a snippet called "getResourceList" with the following code:

                    <?php
                    $parent = isset($parent) ? $parent : $modx->resource->get('id');
                    $depth= isset($depth) ? $depth : '10';
                    $sortby = isset($sortby) ? $sortby : 'pagetitle';
                     
                    $childs = $modx->getChildIds($parent,$depth,array('context' => 'web'));
                    
                    $c = $modx->newQuery('modResource');
                    $c->where(array('published'=>1,'deleted:!=' =>'1'));
                    $c->where(array('id:IN'=>$childs));
                    $c->sortby($sortby);
                    $collection = $modx->getCollection('modResource',$c);
                       
                    $output='-==';
                    foreach ($collection as $o){
                    $output .= '||'.$o->get('pagetitle').'('.$o->get('id').')=='.$o->get('id');
                    }
                    return $output;


                    Then in my TV I used the following code as Input Option Values on the input tab:

                    @EVAL return $modx->runSnippet("getResourceList", array('id'='3','depth'=>'2'));


                    If you wanted to pull children in of the current item then you would leave off the id value in the array:

                    @EVAL return $modx->runSnippet("getResourceList", array('depth'=>'2'));


                    I have been having great results using this with the Listbox Input Type and enabling Enable "Type-Ahead".