Making A Plugin Searchable

From e107 Wiki
Jump to: navigation, search

e107 Wiki: English | Русский | Deutsch | Français | Magyar | Português | Български | Česky | Nederlands | Ελληνικά | Italiano | Norske | Polska | Slovenščina | Español | Svenska | Translate: Wiki | Page

logo_wiki.png

Current Release 1.0.4 | e107.org | Download | Changelog | Forum | Plugins | Themes | RSS Feed of Latest Changes | Atom Feed of Latest Changes


How to write a plugin
Main page > I : First Aid > II : Development > III : Administration > IV : How To's > V : Plugin Writing > VI : Theming & Shortcodes


Contents

Making A Plugin Searchable

This guide describes how to add your plugin to the core e107 search functionality.

It also shows you how you can add a search text box to your plugins page(s).

e_search.php

Create a file called e_search.php in your plugin folder. It must be called this as it is a well known file name that is looked for in each plugin folder.

Code: Example e_search.php
<?php
$search_info[] = array(
   'sfile'     => e_PLUGIN.'mypluginfolder/search.php',
   'qtype'     => 'MyPlugin',
   'refpage'   => 'myplugin.php',
   'id'        => 'myplugin',
   'advanced'  => e_PLUGIN.'mypluginfolder/advanced_search.php',
);
?>
  • sfile is the file containing the search code to be run that returns results
  • qtype is the name of your plugin or similar - this is the text that will apear in the Search page drop down list.
  • refpage is where you go to if a user clicks on a search match for your plugin
  • id a unique id for your plugin, use the plugin folder name
  • advanced is the file containing the advanced search code to be run that returns results, optional

search.php

Create a file called search.php (or whatever you called the file in the 'sfile' array element in your e_search.php file). The following example is adapted from the Election plugin.

Note: you must define all these variables, even if they are blank, to prevent contamination of bad values from other plugins' search modules.

Code: Example search.php
<?php
$advanced_where = "";

// The fields that will be returned by the SQL
$return_fields = "election_id, election_name, election_description, election_owner,
   election_candidate_id, election_candidate_election_ids, election_candidate_name,
   election_candidate_title, election_candidate_description, election_candidate_link_url,
   election_candidate_link_description
";

// The fields that can be search for matches
$search_fields = array("election_name", 
                       "election_description", 
                       "election_candidate_name", 
                       "election_candidate_title", 
                       "election_candidate_description");

// A weighting for the importance of finding a match in each of the search fields
$weights = array("1.2", "0.8", "1.2", "1.0", "0.8");

// Message to be displayed when no matches found
$no_results = LAN_198;

// The SQL WHERE clause, if any
$where = "1 and".$advanced_where;

// The SQL ORDER BY columns as a keyed array
$order = array('election_candidate_id' => DESC);

// The table(s) to be searched
$table = ELECC_CANDIDATES_TABLE." 
   left join #".ELECC_ELECTIONS_TABLE." on election_candidate_election_ids=election_id";

// Perform the search
$ps = $sch->parsesearch($table, $return_fields, $search_fields, $weights, 
                        'search_election', $no_results, $where, $order);

// Assign the results to specific variables
$text .= $ps['text'];
$results = $ps['results'];

// A callback function (name is passed to the parsesearch() function above)
// It is passed a single row from the DB result set
function search_election($row) {
   global $pref;
   global $con;

   // Populate as many of the $res array keys as is sensible for the plugin
   $res['link'] = e_PLUGIN."election/election.php?".ELECC_CANDIDATE_PAGE.".".$row["election_candidate_id"];
   $res['pre_title'] = "";
   $res['title'] = $row["election_candidate_name"]." : ".$row["election_candidate_title"];
   $res['pre_summary'] = "<div class='smalltext' style='padding: 2px 0px'>";
   $res['pre_summary'] .= "<a href='".e_PLUGIN."election/election.php'>".ELEC_LAN_ELECTION."</a>";
   $res['pre_summary'] .= $pref["election_separator"];
   $res['pre_summary'] .= "<a href='".e_PLUGIN."election/election.php?".ELECC_CANDIDATES_PAGE.".".$row["election_id"]."'>".$row['election_name']."</a>";
   $res['pre_summary'] .= "</div>";
   $res['summary'] = $row["election_candidate_description"];
   $res['detail'] = "<a href='".$row['election_candidate_link_url']."'>".$row['election_candidate_link_description']."</a>";
   return $res;
}
?> 

search.php (old style)

This is an older way of defining a search results file. However, it is still valid code and can be used in preference to the newer method (above).

Create a file called search.php (or whatever you called the file in the 'sfile' array element in your e_search.php file). The following example is adapted from the Userjournals plugin.

Code: Example search.php
<?php
$text .= ujSearch();

function ujSearch() {
   global $search_info, $key, $pref, $query;
   $sql = new db();
   $gen2 = new convert();
   $nothingfound = true;
   $result = "";
   
   $linkprefix = "<img src=\"".THEME_ABS."images/bullet2.gif\" alt=\"bullet\" /> ";
   $linkprefix .= "<b><a href=\"".e_PLUGIN_ABS."userjournals_menu/userjournals.php?";
   
   $search_info[$key]['qtype'] = $pref["userjournals_page_title"];

   if ($sql->db_Select("userjournals", "*", 
      "userjournals_entry REGEXP('".$query."') ORDER BY userjournals_timestamp DESC"))
   {
      $nothingfound = false;
      while($row = $sql -> db_Fetch()){
         extract($row);
         $short = parsesearch($userjournals_username, $query);
         $short .= " (".$gen2->convert_date($userjournals_timestamp, "short").")";
         $long = parsesearch($userjournals_entry, $query);
         $result .= $linkprefix;
         $result .= "blogger.$userjournals_userid.$userjournals_username\">";
         $result .= $que</a></b><br />";
         $result .= <span class=\"smalltext\">Match found in Journal</span>";
         $result .= <br />$ans<br /><br />";
      }
   }
 
   if ($nothingfound) {
      $result .= "No matches found";
   }
 
   return $text;
}
?> 

Here's a rundown of what's happening in this file.

  • First, we call a function that returns our search results. Not strictly neccessary but helps prevent corrupting global variables. The search results text must be appended to the variable $text.
  • $nothingfound is just a flag so you can put out a nice message if nothing found. Not really needed here but useful if you have mulitple SQL queries for which you want to return search results for (e.g. search in name, decription and category).
  • $linkprefix is just to save typing it in a lot of places (potentially). It's set to the HTML that represents the first part of the anchor that will be used to link the search result(s) back to your plugins page.
  • $search_info[$key]['qtype'] is the title for your section of the search results page. You must assign it to this array element.
  • In the SQL query the value of $query is the text the user is looking for. Use REGEXP to search for this value in your columns.
  • $short and $long - the two parts to the search result, the first is the title/link that can be clicked to go to the appropriate page, the 2nd is the longer textual description with the search term highlighted.
  • $result is appended with the result of each match, note the formatting (i.e. breaks). Also note that $linkprefix is appended with the specific URL parameters so that the appropriate page is displayed if the link is selected.

Note that the English text should really be localized and put in a language file.

advanced_search.php

Not sure of all the options for this file yet. This is just the Content Manager plugin advanced search file for now.

Code: advanced_search.php
if (!defined('e107_INIT')) { exit; }

$advanced['cat']['type'] = 'dropdown';
$advanced['cat']['text'] = LAN_SEARCH_63.':';
$advanced['cat']['list'][] = array('id' => 'all', 'title' => LAN_SEARCH_51);

$advanced_caption['id'] = 'cat';
$advanced_caption['title']['all'] = CONT_SCH_LAN_2;

if ($sql -> db_Select("pcontent", "content_id, content_heading", "LEFT(content_parent,1)='0'")) {
   while ($row = $sql -> db_Fetch()) {
      $advanced['cat']['list'][] = array('id' => $row['content_id'], 'title' => $row['content_heading']);
      $advanced_caption['title'][$row['content_id']] = $row['content_heading'];
   }
}

$advanced['date']['type'] = 'date';
$advanced['date']['text'] = LAN_SEARCH_68.':';

$advanced['match']['type'] = 'dropdown';
$advanced['match']['text'] = LAN_SEARCH_52.':';
$advanced['match']['list'][] = array('id' => 0, 'title' => LAN_SEARCH_53);
$advanced['match']['list'][] = array('id' => 1, 'title' => LAN_SEARCH_54);

Adding A Search Text Box

You can add a search text box - so users can search directly from your plugins page(s) by adding some simple HTML (but see notes after sample code).

Code: Sample Search Text Box HTML
<form method='get' action='".e_HTTP."search.php'>
Search myplugin: 
<input class='tbox search' type='text' name='q' size='20' value='' maxlength='50' />
<input type='hidden' name='r' value='0' />
<input type='hidden' name='t' value='12' />
</form> 

This will give you a text box where the user can type in their search term and press Enter/Return to start the search.

Note: In practice this does not work too well. This is because the hidden field t actually represents the plugin as a number, and this will vary from site to site depending on what plugins are installed. An alternate approach here is to use the plugin folder name.

Also, as mentioned, the English text should really come from a language file.

Note: You must create a plugin.php file and install your plugin through the e107 Plugin Manager. This allows e107 to register your plugin in the e107_core/search_prefs table so that e107_search will include it in it's searchable modules.

Searching Comments in your Plugin

Many third party plugins allow comments to be posted on records in the plugin. To be able to search these comments you need to create a file called search_comments.php. Following the e107 convention of putting all search related scripts into a sub directory called search this example assumes that file path is used.The search_comments.php file should be found on plugin installation or with a tools-database-scan plugin directories.

Code: Searching Comments
// check called correctly
if (!defined('e107_INIT')) { exit; }
// get the language file for your plugin
include_lan(e_PLUGIN . "reviewer/languages/" . e_LANGUAGE . ".php");
// THe title of the plugin to be displayed in the main admin search page
$comments_title = 'Reviewer';
// the id that is used to identify comments for this plugin in the e107_comments table
$comments_type_id = 'reviewer';
// fields to be returned from the search for this plugin
$comments_return['reviewer'] = "p.reviewer_reviewer_id, p.reviewer_reviewer_review,p.reviewer_reviewer_itemid";
// a join from the comments table to your table in order that the search query can identify and return
// both the comment and the record in your plugin to which it refers
$comments_table['reviewer'] = "LEFT JOIN #reviewer_reviewer AS p ON c.comment_type='reviewer' 
AND p.reviewer_reviewer_id = c.comment_item_id";
// function to handle the results which are then displayed 
//- see the name has com_search_ prefixing the plugin dname
function com_search_reviewer($row) {
	global $con;
	// convert the comments datestamp
	$datestamp = $con -> convert_date($row['comment_datestamp'], "long");
	// link to the plugins record that has the comment made on it
	$res['link'] = e_PLUGIN."reviewer/reviewer.php?0.view.".$row['reviewer_reviewer_id'];
	// pre title for example "comment found in -"
	$res['pre_title'] = REVIEWER_S03.': ';
	// the title or name of the plugin record
	$res['title'] = $row['reviewer_reviewer_review'];
	// the contents of the comment
	$res['summary'] = $row['comment_comment'];
	// get the user name for the commentator
	preg_match("/([0-9]+)\.(.*)/", $row['comment_author'], $user);
	// detailed information to be passedback, in this case a link to membership details of the commentator
	$res['detail'] = LAN_SEARCH_7."<a href='user.php?id.".$user[1]."'>".$user[2]."</a>".LAN_SEARCH_8.$datestamp;
	return $res;
}