Adding a global search box

From Achievo/ATK Wiki

Jump to: navigation, search

ATK Howto: Adding a global search box

Complexity: Advanced
Author: Jorge Garifuna <info@GariDigital.com>

List of other Howto's

Contents

Summary

In this article you will learn to add a global search tool to your ATK applications so that each node becomes searchable from one single location.


Requirements

You will need to following to get this to work successfully:

  • PHP 4+
  • MySQL 4+
  • ATK 5.6+
  • Achievo for search module
  • Achievo Modern theme available on ATK nightly download after July 18

I think that covers it all. You can download the latest ATK and Achievo from: http://www.achievo.org/download/nightly

Nodes Preparation

To get the global search to work with your nodes you need to implement the following method within your node:

  function descriptor_def()
  {
    return "[your_descriptor_field_name_here]";
  }

Module Preparation

The Achievo installation comes with a search module that works out of the box on ATK. To use this module, simply

  • Go to the “modules” folder of your Achievo installation and copy the “search” module to the “modules” folder of your ATK installation.
  • Add the following line to your confic.modules.inc file:
module('search');


Search Box Preparation

To have the search displayed on the top right of your ATK application, you need to have the “achievo_modern” theme properly installed and follow these instructions:

  • Add the followin lines of code to the “top.php” file, before $top = $ui->renderBox....:
  $searchnode = &atkGetNode("search.search");
  $searchpiece = $searchnode->simpleSearchForm("", "main", SESSION_NEW);
  • Include the following line on the renderBox code:
  "searchpiece"=>$searchpiece,

Search Implementation On nodes

This is where the real fun begins. Now that we have done all the necessary preparation, it is time to implement the actual search, so that our nodes can use it. Follow these steps to have your nodes make use of the global search:

  • open the file “module.inc” from the module that you would like to use global search
  • add the following method to this file:
   
  /* start top search implementation */
  function search($expression)
  {
    $res = array();
    // replace “module_name” with the actula name of the module
    // replace “node_name” with the actual name of the node
    // replace  node_name_results with the title that will organize the results for the node
    $node_name_node = &atkGetNode("module_name.node_name");        
    $res["node_name_results"] = $this->recLinks($node_name_node->searchDb($expression), “module_name.node_name”);
 
    // example 2
    // $transaction_node = &atkGetNode($this->module.".budget_account_transaction");        
    //$res["transactions"] = $this->recLinks($transaction_node->searchDb($expression), $this->module.".budget_account_transaction");
          
    return $res;
  }// end function
  • Add the following method to this file as well:
  function recLinks($recordset, $nodetype)
  {
    //$node = &atkGetNode($nodetype);
          
    $res = array();
          
    $node = &atkGetNode($nodetype);
    if ($node->allowed("view"))
    {
      for($i=0, $_i=count($recordset); $i<$_i; $i++)
      {
        $item["title"] = $node->descriptor($recordset[$i]);
        $item["url"] = dispatch_url($nodetype, "view", array("atkselector"=>$node->primaryKey($recordset[$i])));
        $res[] = $item;
      }
    }
          
    return $res;
  } // end function
  /* end top search implementation */

That was easy, right? If you've followed these steps to the letter, you should be able to search all the nodes that you included the “search” method of the “module.inc” file.


Existing issues with Global Search

This might just be on my end, but for some reason, if you have a node that uses “atkCalculatorAttribute”, you might get an exception when you try to search, because the attribute name gets included as part of the SQL search, that gets passed to the MySQL engine.

To fix this this problem we may need to find a way, that will prevent those types of attributes from being passed to the MySQL engine at search time.

For TEXT type attributes in MySQL. The metadata type returned appears to be "blob" not "text", change the fetchMeta function in atktextattribute to use gentype instead of type. ie: $this->m_dbfieldtype = $metadata[$this->fieldName()]["gentype"];

Credits

I would like to thank Boy in particular for highlighting some of the procedures here to make this doc possible.

Personal tools
Navigation