We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 54103
    • 2 Posts
    Heya,

    I am working on a website for a client, which contains a catalogue of items, which should be searchable. For searching, I am using AdvSearch as follows:

    [[!AdvSearch? &ids=`[[!GetIds? &ids=`c50`]]` &containerTpl=`myAdvSearchResults` &tpl=`myAdvSearchResult` &withTVs=`img_main, price, size_w, size_h, size_d, century` &thumbWidth=`400` &thumbHeight=`400` &bgColor=`f1ebd8` &queryHook=`qhFilter` &init=`all` &perPage=`50` &debug=`1`]]


    In order to display the attribute options (attributes are characteristics of an item), I am using Tagger. Tagger groups are attributes, whereas the tags themselves are options. For instance, an attribute could be itemColor, whereas an attribute option belonging to this attribute could be red. Each option/tag has an ID, and this is being used in the query.

    The displaying of the tags as checkboxes is done with a custom snippet, which works perfectly well. Price-range search works too, and so does keywords search, with the following query hook (qhFilter):

    <?php
    $andConditions = array();
    $andConditions['tv.price:>='] = 'minPrice:request:none';
    $andConditions['tv.price:<='] = 'maxPrice:request:none';
    
    if (!empty($andConditions)) {
        $qhDeclaration = array(
            'qhVersion' => '1.3',
            'andConditions' => $andConditions
        );
        $hook->setQueryHook($qhDeclaration);
    }
    return true;


    However, when I try to make AdvSearch search in the Tagger table, then I get no results. The qhFilter is then this:

    <?php
    $modx->setDebug(true);
    
    $main = array(
        'tablePrefix' => 'modx_',
        'package' => 'tagger',
        'packagePath' => '{core_path}components/tagger/model/',
        'class' => 'TaggerTagResource',
        'fields' => 'resource, tag',
        'withFields' => 'resource, tag', # TAGGER COLUMNS
    );
    
    # STILL KEEPING THE PRICE SEARCH
    $andConditions = array();
    $andConditions['tv.price:>='] = 'minPrice:request:none';
    $andConditions['tv.price:<='] = 'maxPrice:request:none';
    
    # Ignore for now, will be used when attribute option search is finally fixed
    $attributes = array();
    foreach($_REQUEST as $key => $value){
        $exp_key = explode('-', $key);
        if($exp_key[0] == 'attr'){
             $attributes[$key] = $value;
        }
    }
    # Just debugging the attributes expansion, ignore this
    $modx->log(modX::LOG_LEVEL_DEBUG, json_encode($attributes));
    
    # THIS TAG ID (OPTION) EXISTS, MANUAL QUERY FOR DEBUGGING PURPOSES
    $andConditions = array(
        'TaggerTagResource.tag:=' => '1'
    );
    
    
    if (!empty($andConditions)) {
        $qhDeclaration = array(
            'qhVersion' => '1.3',
            'main' => $main,
            'andConditions' => $andConditions
        );
        $hook->setQueryHook($qhDeclaration);
    }
    
    $modx->setDebug(false);
    
    return true;


    However, only a blank page is returned by AdvSearch, even though I know that the option/tag with ID 1 has items tagged with it, as I can see it in the SQL table! What am I doing wrong?

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

    [ed. note: agilburg last edited this post 6 years, 1 month ago.]
    • discuss.answer
      • 54103
      • 2 Posts
      It's all sorted! Here is the code which will allow the searching of Tagger tables:

      <?php
      # Main for MODX
      $main = array(
          'package' => 'modx',
          'packagePath' => '{core_path}model/',
          'class' => 'modResource',                         
          'fields' => 'id',                        
          'withFields' => 'id',                    
          'sortby' => 'TaggerTagResource.tag DESC',
          'tablePrefix' => 'modx_'
      );
      
      # Join with Tagger table
      $joined = array(
          array(
              'package' => 'tagger',        
              'packagePath' => '{core_path}components/tagger/model/', 
              'class' => 'TaggerTagResource',
              'withFields' => 'resource, tag',
              'fields' => 'resource, tag',
              # On the resource ID
              'joinCriteria' => 'modResource.id = TaggerTagResource.resource',
              'tablePrefix' => 'modx_'
          )
      );
      
      $andConditions = array(
          # One tag/option
          'TaggerTagResource.tag:=' => '2',
          # Another tag/option
          'TaggerTagResource.tag:=' => '4'
      );
      
      # set the query hook declaration
      $qhDeclaration = array(
          'qhVersion' => '1.3',
          'main' => $main,
          'joined' => $joined,
          'andConditions' => $andConditions
      ); 
      $hook->setQueryHook($qhDeclaration);
      
      return true;


      Now, I'll only have to re-include the price-check, and dynamically generate the andConditions from the supplied attribute options – but this should be trivial! I am planning on escaping the attributes obviously, as they are user-input from the GET request!
        • 17301
        • 932 Posts
        Thanks! This could be useful in future projects.
          ■ email: [email protected] | ■ website: https://alienbuild.uk

          The greatest compliment you can give back to us, is to spend a few seconds leaving a rating at our trustpilot: https://uk.trustpilot.com/review/alienbuild.uk about the service we provided. We always drop mention of services offered by businesses we've worked with in the past to those of interest.