JSON Search API for Drupal
<?php
/**
* implements hook_menu
*/
function json_search_menu (){
$items['json/search/%'] = array(
'page callback' => '_json_search',
'access arguments' => array('access content'),
'page arguments' => array(2),
'type' => MENU_CALLBACK,
);
return $items;
}
// @important this should be only used when you want to disable drupal default search page
/**
* implements hook_init()
*/
function json_search_init(){
}
/**
* custom function to perform and output search results in json
*/
function _json_search( $search_keyword = NULL ){
$nid_list = array();
$writerResults = array();
$storyResults = array();
$search_keyword = check_plain( $search_keyword ); // Sanitise input
$server = search_api_server_load('search_server');
$index = search_api_index_load('writers_index');
$query = new SearchApiQuery($index);
$query->keys( $search_keyword )
->fields( array('title', 'body:value') );
$srv = new SearchApiDbService($server);
$result = $srv->search($query);
foreach ($result['results'] as $result_node) {
array_push($nid_list, $result_node['id']);
}
// Unpublished nodes should be out of the index already
$nodes = node_load_multiple($nid_list);
foreach ($nodes as $node) {
if($node->type === 'writer_story') {
//Story result
$entity_reference = _get_entity_field('node', $node, 'field_story_ref_writer');
$newStoryFound = array(
'id' => $node->nid,
'title' => $node->title,
'writerId' => $entity_reference['#options']['entity']->nid,
'writerType' => $entity_reference['#options']['entity']->type,
'writerName' => $entity_reference['#title'],
'body' => _get_entity_field('node', $node, 'body')['#markup'],
# 'image' => null, Add this later...
);
// Fetch field collection of first image
$image_collection = _get_entity_field('node', $node, 'field_images_meta', 0)['entity']['field_collection_item'];
// If image exists
if (!empty( $image_collection )) {
$field_collection = field_collection_item_load( key( $image_collection ) );
$image = _get_entity_field( 'field_collection_item', $field_collection, 'field_writer_story_img', 0);
// Create URL
$newStoryFound['image'] = file_create_url( $image['#item']['uri'] );
// For formatted style uncomment next line.
# $newStoryFound['image'] = image_style_url('thumbnail', $image['#item']['uri']);
}
$newStoryFound['body'] = strip_tags($newStoryFound['body']); // Clean HTML
$reg_matches = array();
// $reg_pattern = '/(?:^|\.)\K.*?(?=' . $search_keyword . ')[^\.]*\./i'; Old regex
$reg_pattern = '/[^|\.]*(?='. $search_keyword .')[^\.]*\.(.*?)\./i';
preg_match($reg_pattern, $newStoryFound['body'], $reg_matches); // Strip sentences containing keyword.
$newStoryFound['body'] = preg_replace('/(' .$search_keyword. ')/i', "<dfn>$1</dfn>", $reg_matches[0]); // Add DFN tags keeping original case.
array_push($storyResults, $newStoryFound);
}
else if($node->type === 'writer') {
//Writer result
$newWriterFound = array(
'id' => $node->nid,
'title' => $node->title,
'type' => $node->type,
'quote' => _get_entity_field('node', $node, 'field_writer_quote')['#markup'],
'firstname' => _get_entity_field('node', $node, 'field_writer_first_name')['#markup'],
'surname' => _get_entity_field('node', $node, 'field_writer_surname')['#markup'],
# 'backgroundImage' => field_get_default_value('node', $node, 'field_writer_background_image'),
);
$image = _get_entity_field('node', $node, 'field_writer_background_image');
if ( !empty($image['#item']['uri']) && isset($image['#item']['uri']) ) {
$newWriterFound['backgroundImage'] = file_create_url( $image['#item']['uri'] );
}
else {
$default_image = file_load( field_info_field('field_writer_background_image')['settings']['default_image'] );
$newWriterFound['backgroundImage'] = file_create_url( $default_image->uri );
}
// Manually filter writers
if ( strpos(strtolower($newWriterFound['title']), strtolower($search_keyword)) !== false ) {
array_push($writerResults, $newWriterFound);
}
}
}
$cleanedResult = array(
'writers' => $writerResults,
'stories' => $storyResults,
);
drupal_json_output($cleanedResult);
exit();
}
/**
* Uses Field API to view and get fields inside nodes with the correct access.
* @return array|bool Field array if present, false if not.
*/
function _get_entity_field( $entity_type = 'node', &$entity_object, $field_name = NULL, $delta = 0 ) {
if (!!$field_name) {
$this_field = field_get_items($entity_type, $entity_object, $field_name);
return field_view_value($entity_type, $entity_object, $field_name, $this_field[$delta]);
}
else {
return false;
}
}