We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 25663 MODX Staff
    • 12,272 Posts
    That sounds like an amazingly useful addition and I’d LOVE to see the code working ASAP. laugh Go for it!
      Ryan Thrash, MODX Co-Founder
      Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
      • 1511
      • 144 Posts
      Here’s the code of a snippet I’ve just written to get document IDs to perform the search on.
      It behaves as described above.

      <?php
      $parentId = isset($parentId) ? $parentId : '0';
      $level = isset($level) ? $level : '100';
      $includeParent = isset($includeParent) ? $includeParent : '0';
      $includeDocId = isset($includeDocId) ? $includeDocId : '';
      $excludeDocId = isset($excludeDocId) ? $excludeDocId : '';
      $excludeParentId = isset($excludeParentId) ? $excludeParentId : '';
      $lastChildOnly = isset($lastChildOnly) ? $lastChildOnly : '0';
      
      
      // result array
      $docs = array();
      
      // all parents
      $parents = array();
      
      // all ids to be excluded
      $remove = array();
      
      
      // get all children
        foreach (explode(',', $parentId) as $pId) {
          $childs = $modx->getChildIds($pId, $level);
          $docs = array_merge($docs, $childs);
          if ($pId != 0) {
            $parents[] = $pId;
          }
        }
      
      /////////////////////// include
      
      // add parents
        if ( (boolean) $includeParent == true) {
          $docs = array_merge($docs, $parents);
        }
      
      // add includeDocId
        if ($includeDocId != '') {
          $docs = array_merge($docs, explode(',', $includeDocId));
        }
        
      /////////////////////// get last children
      
        if ( (boolean) $lastChildOnly == true) {
           $tblContent = $modx->getFullTableName('site_content');
      
      
      // if a document has an isfolder flag, this query will not select it, even if it has no childs
      //     $sql = "SELECT id FROM $tblContent WHERE isfolder=0 ";
      //   
      // here isfolder flag doesn't matter, we count only the documents with no childs   
      // ignore isfolder flag for SQL 4.1+
      //     $sql = "SELECT id FROM $tblContent WHERE id NOT IN (SELECT parent FROM $tblContent) "; 
      //  
      // ignore isfolder flag for SQL <4.1  
           $sql = "SELECT a.id FROM $tblContent AS a LEFT JOIN $tblContent AS b ON a.id = b.parent WHERE b.parent IS NULL"; 
        
           $res = $modx->dbQuery($sql);
           $childs = array();
           
           while ($row = $modx->db->getRow($res)) {
             $childs[] = $row[id];
           }
           
           $docs = array_intersect($docs, $childs);
        } 
      
      /////////////////////// remove
      
      // remove excludeDocId
        if ($excludeDocId != '') {
          $remove = explode(',', $excludeDocId);
        }
      
      // remove excludeParentId
        foreach (explode(',', $excludeParentId) as $pId) {
          $childs = $modx->getChildIds($pId, $level);
          $remove = array_merge($remove, $childs);
          
          // remove parents listed in exludeParentId
          if ( (boolean) $includeParent == true) {
            $remove[] = $pId;
          }  
        }
      
        // remove
        $docs = array_diff($docs, $remove);
        $docs = array_unique($docs);
      
       return implode(', ', $docs);
      ?>
      


      Now this list has to be included in the SQL statements, somewhere along the
       SELECT ...... WHERE (sc.id IN ( myList )) AND  ..... 

      My guess (and a bit of testing smiley ) is to add the id list in line 146 and 179 of the AjaxSearch.inc.php (right after the" WHERE"; ).



      ATTENTION
      There are three different SQL queries for documents that have no children (for lastChildOnly parameter). Select the apropriate one or make it a preference. wink
      The differences are described in the code.
        • 1511
        • 144 Posts
        I’ve packed the above code in a class, since I guess it would be useful also in other snippets.
        Shall I add it to the repository? Being document selection/filtering utility...

        It would be easy to add filtering for flags as ’published’, ’deleted’, or any other field.
        Actually, I’m already coding it.

        My version of AjaxSearch has it already integrated.


        PS: is there any way to code this any better? To get an array directly from a complete query dataset?
        $sql = " SELECT id FROM modx_site_content ";
        $res = $modx->dbQuery($sql);
        $childs = array();
        				 
        while ($row = $modx->db->getRow($res)) {
           $childs[] = $row[id];
        }
        


        Uploaded new code, check below.
          • 1511
          • 144 Posts
          ////////////////////////////////////////////////////////////////////////////////////////////////
          // GetDocIds
          ////////////////////////////////////////////////////////////////////////////////////////////////
          //
          // version: 1.1
          //
          // created by Andraz Kozelj (andrazk) - andraz dot kozelj at amis dot net
          // 21.3.2007 - first release
          //
          // this class prepares a list of documents from the document tree regarding the criteria
          //
          ////////////////////////////////////////////////////////////////////////////////////////////////
          //
          // Usage:
          // $idList = array();
          // $getIdList = new GetDocIds();
          // $idList = $getIdList->getIds(’’, ’’, ’’, ’’, ’’, ’’, ’’, ’’);
          //
          // Parameters:
          // GetDocIds.getIds( $parentId, // csv - list of parent documents -> search their children
          // $depth, // int - set depth of search
          // $includeParent, // boolean / int - add parents to searching
          // $includeDocId, // csv - include individual documents
          // $excludeDocId, // csv - exclude individual documents
          // $ecludeParentId, // csv - exclude whole tree-branch of documents
          // $lastChildOnly, // boolean / int - search only in documents that have no children (last leafs in the tree)
          // $filters // csv - add filters in form "fieldname:value"
          // );
          //
          // Returns:
          // array of document IDs
          //
          ////////////////////////////////////////////////////////////////////////////////////////////////
          //
          // Examples:
          //
          // // return ALL documents
          // getIds(’’, ’’, ’’, ’’, ’’, ’’, ’’, ’’);
          //
          // // return only documents that have no children
          // getIds(’’, ’’, ’’, ’’, ’’, ’’, ’1’, ’’);
          //
          // // return childs of documents (26) and (76), but only two levels deep
          // getIds(’26,76’, ’2’, ’’, ’’, ’’, ’’, ’’, ’’);
          //
          // // return childs of document (26), but only two levels deep, and the document (26) itself
          // getIds(’26’, ’2’, ’1’, ’’, ’’, ’’, ’’, ’’);
          //
          // // return childs of a specified document (26), and if the list includes document (34) or (35), remove them from the list
          // getIds(’26’, ’’, ’’, ’’, ’34,35’, ’’, ’’, ’’);
          //
          // // return all documents except childs of document (45)
          // getIds(’’, ’’, ’’, ’’, ’’, ’45’, ’’, ’’);
          //
          // // return all documents except childs of document (45) and the document (45) itself
          // getIds(’’, ’’, ’1’, ’’, ’’, ’45’, ’’, ’’);
          //
          // // return childs of document (17), include document 17 itself, add documents (23) and (42), exclude document (66)
          // getIds(’17,’, ’’, ’1’, ’23,42’, ’66’, ’’, ’’, ’’);
          //
          // // get all documents that are published
          // getIds(’’, ’’, ’’, ’’, ’’, ’’, ’’, ’published:1’);
          //
          // // get childs of document (26) that are published and searchable
          // getIds(’26’, ’’, ’’, ’’, ’’, ’’, ’’, ’published:1,searchable:1’);
          //
          // // get all documents that are published and searchable and folders, ecxept for document (17)
          // getIds(’’, ’’, ’’, ’’, ’17’, ’’, ’’, ’published:1,searchable:1,isfolder:1’);
          //
          ////////////////////////////////////////////////////////////////////////////////////////////////
            • 14050
            • 788 Posts
            Silly me. Thanks Kyle, that fixed it.
              Jesse R.
              Consider trying something new and extraordinary.
              Illinois Wine

              Have you considered donating to MODx lately?
              Donate now. Every contribution helps.
              • 24495
              • 407 Posts
              I’m very interested in a solution excluding a document tree from search. The posts above are interesting but I don’t understand what to do. Can anyone explain how to integrate and use this solution? What AjaxSearch version is required: 1.0 or 1.5/6?

              I think this would be very helpful for others. My problem is that we build a bi-lingual web site where the german tree is ready but the english tree is mostly empty because of less translations. Therefore we set the weblink to the english tree unpublished. But searching finds documents in the english area. Setting all documents unpublished is NOT a solution because of pub_dates manually set for news. The english tree is invisible but searchable.

              What can I do? Thx for help.
                • 28465
                • 29 Posts
                Hi,

                I’ve got a small problem with version 1.5 (or 1.6, not sure from the label/comments inside the snippet) and a general localisation question:

                Translating the labels to German &mdash or rather, switching the variable order &mdash; results in meaningless output.


                $resultsFoundTextSingle = ’Die Suche nach "%s" ergab %d Ergebnis.’;
                $resultsFoundTextMultiple = ’Die Suche nach "%s" ergab %d Ergebnisse.’;

                results in

                Die Suche nach "2" ergab 0 Ergebnisse.

                It appears that the search script expects the variables in a certain order: first %d, then %s (which then works like a charm). Can this be worked around or fixed? I wouldn’t want to build my sentences around that variable order.

                I’ve created a German lang file for AjaxSearch, but how do I activate it? I’ve looked through the snippet, couldn’t find a parameter. Deleting/modifying the file name of the english lang file results in a MODx system error.

                Keep up the good work smiley
                  • 24495
                  • 407 Posts
                  Ok, have seen that the "including/excluding solution" is only for AjaxSearch from version 1.5. Until that works at my site I use the DocManager to exclude document trees from search. I think it’s the simplest solution this time.

                  Btw: AS 1.5/1.6 doesn’t work at my site on the landing page when I use two calls (first for a visible search form at left column, second for displaying results). Maybe the problem is phx. Tried many call variants (cached/uncached snippet call, cached/uncached page): nothing works. It shows only one of both calls, wether the search form or the search results.
                    • 14050
                    • 788 Posts
                    @rasc

                    I have the same problem, two calls and only one shows. I have one call embedded in the template for the search field, and then another call on the landing page. The results show, but then the call in the template seems to get ignored or overridden.
                      Jesse R.
                      Consider trying something new and extraordinary.
                      Illinois Wine

                      Have you considered donating to MODx lately?
                      Donate now. Every contribution helps.
                      • 18250
                      • 37 Posts
                      Hello...

                      I’ve been trying to figure this for a while now, and i just don’t get it.. The thing i want to do is, that the search results would display apart from the searchbox. Ajax or not, whatever.. I have a header (here is searchbox), and content of the page (where results should be). Now, the results show right under the search input. I found this in the snippet:
                      // $resultsPage [int]
                         // The default behavior is to show the results on
                         // the current page, but you may define the results
                         // page any way you like. The priority is:
                         //
                         // 1- snippet variable - set in page template like this:
                         //    [[AjaxSearch? AS_landing=int]]
                         //    where int is the page id number of the page you want
                         //    your results on
                         // 2- querystring variable AS_form
                         // 3- variable set here
                         // 4- use current page
                         //
                         // This is VERY handy when you want to put the search form in
                         // a discrete and/or small place on your page- like a side
                         // column, but don't want all your results to show up there!
                         // Set to results page or leave 0 as default
                         $resultsPage = 1;


                      This is defenetly the part for me, but whatever i choose (1,2,3,4), I cant get the results i need..
                      I use AjaxSearch 1.1. No one seemed to have similar problems, so i guess, you all know the answer wink

                      Please help me out..
                      Thanks guys (and girls wink )

                      This discussion is closed to further replies. Keep calm and carry on.