Skip to content

Instantly share code, notes, and snippets.

@ksascomm
Last active June 26, 2018 20:56
Show Gist options
  • Save ksascomm/b479afa6c97793ba7631182515220824 to your computer and use it in GitHub Desktop.
Save ksascomm/b479afa6c97793ba7631182515220824 to your computer and use it in GitHub Desktop.
<?php
/**
* Get the page number from the query string
* In production, get this value from WordPress
* @return integer
*/
function getPage()
{
// deafult page number
$page = 1;
if (isset($_GET['page']) && $pageAsInt = (int) $_GET['page']) {
// valid number set in query string
return $pageAsInt;
}
return $page;
}
/**
* Get the user query from the query string
* In production, get this value from WordPress
* @return string
*/
function getQuery()
{
if (isset($_GET['q']) && !empty($_GET['q'])) {
return htmlentities($_GET['q']);
} else {
throw new Exception('Please provide a query via the "q" query string parameter');
}
}
/**
* Get the source from the query string
* @return string
*/
function getSource()
{
if (isset($_GET['source']) && in_array($_GET['source'], ['ksas'])) {
return $_GET['source'];
} else {
return null;
}
}
/**
* Generate the POST body
* @param string $query User query
* @param integer $page Requested page of results
* @param integer $count Number of results to return
* @return string JSON encoded string
*/
function getPostBody($query, $page = 1, $count = 10, $source = null)
{
// array of properties we want returned with each result (see below)
$properties = [
'title',
'content',
'Description',
'url',
'icon'
];
// start constructing the body
$body = [
'content_sample_length' => 300, // how many characters the snippet should be
'query' => ['unparsed' => $query], // user query
'count' => $count, // how many results to return
'max_page_count' => 10, // how many 'pages' worth of pagination information to return
'alternatives_query_spelling_max_estimated_count' => 5, // how many spelling suggestings to return
'properties' => getProperties($properties)
];
if ($source) {
$body['source_context']= [
'constraints' => addConstraint($source)
];
}
// add pagination data if we're on page 2+
if ($page > 1) {
if (!isset($_SESSION['search_qeng'][$query])) {
throw new Exception('Qeng variables not set. Cannot get page ' . $page . ' of results');
}
$body['result_pages'] = [
// qeng IDs from previous request
'qeng_ids' => $_SESSION['search_qeng'][$query],
// generate the "current page" data based on the requested page and count.
'pages' => [
[
'starts' => [($page - 1) * $count], // offset
'counts' => [$count], // how many results to return
'current_page' => true,
'page_number' => $page // requested page number
]
]
];
}
// uncomment this print statement to see the POST body
// print_r($body); die();
return json_encode($body);
}
/**
* Given a list of properties, transform them into
* the format expected by Mindbreeze
* @param array $properties Array of property names
* @return array Array of arrays
*/
function getProperties($properties)
{
return array_map(function ($property) {
return [
'name' => $property,
'formats' => ['HTML', 'VALUE']
];
}, $properties);
}
/**
* Limit which datasources are being queried
* @param string $constraint Constraint (ksas)
* @return array
*/
function addConstraint($constraint)
{
// list of all datasources on KSAS index
$datasources = [
'Web:ksas',
];
// list of the datasources that apply to certain constraints.
$constraints = [
'ksas' => ['Web:ksas']
];
// datasources that will be queried
$in = $constraints[$constraint];
// datasources that will NOT be queried
$out = array_diff($datasources, $in);
return [
'filter_base' => array_map(function ($datasource) {
return createFilter('fqcategory', $datasource);
}, array_values($in)),
'filtered' => array_map(function ($datasource) {
return createFilter('fqcategory', $datasource);
}, array_values($out))
];
}
/**
* Create boolean filter for datasource constraints
* @param string $label Filter label
* @param string $term Value of filter
* @return array Filter array
*/
function createFilter($label, $term, $type = 'and')
{
return [
$type => [
[
'label' => $label,
'quoted_term' => $term
]
]
];
}
/**
* Clean up the results from Mindbreeze. Instead of having the
* result properties numerically indexed, index the properties
* by the property title for easier retrieval. Upone return,
* cleaned up data can be found in $results->data
* @param array $results Array of results from Mindbreeze
* @return array Array of cleaned up results
*/
function cleanResults($results)
{
return array_map(function ($result) {
$result->data = new \StdClass();
foreach ($result->properties as $property) {
$name = str_replace([':', '/'], '_', strtolower($property->id));
$result->data->$name = $property->data[0];
}
unset($result->properties);
return $result;
}, $results);
}
function mindbreeze_query_vars_filter($vars) {
$vars[] = 'q';
$vars[] = 'page';
return $vars;
}
add_filter( 'query_vars', 'mindbreeze_query_vars_filter' );
// FIRE UP THE SESSION!
session_start();
// this require is here to show where the session_start(); is initiated
require __DIR__ . '/assets/mindbreeze/vendor/autoload.php';
$page = getPage();
$query = getQuery();
$count = 10;
$source = getSource(); // this will help illustrate how to get results from just one datasource
// create HTTP client
$guzzle = new \GuzzleHttp\Client([
'verify' => false,
]);
// send the POST request
$response = $guzzle->post('https://search.jh.edu:23440/api/v2/search', [
'body' => getPostBody($query, $page, $count, $source),
'headers' => ['Content-Type' => 'application/json']
]);
// handle the response
if ($response->getStatusCode() !== 200) {
// if not 200, display some kind of error message
throw new Exception('failed to get a response from Mindbreeze');
}
// get the body of the response
$body = json_decode((string) $response->getBody());
if (!isset($body->resultset->results)) {
$_SESSION['search_qeng'] = null;
throw new Exception('no results');
}
// there are results, let's display them.
$_SESSION['search_qeng'][$query] = $body->resultset->result_pages->qeng_ids;
// clean up the properties of each result
$results = cleanResults($body->resultset->results); ?>
<h1>Search Results: <?php echo $query; ?></h1>
<?php
// display each result
foreach($results as $result)
{
// print_r($result); die();
?>
<p>
<a href='<?php echo $result->data->url->value->str; ?>'><?php echo $result->data->title->html; ?></a>
<br />
<?php echo $result->data->description->value->str; ?>
<br />
<?php echo $result->data->url->value->str; ?>
</p>
<hr>
<?php
}
// I think I need to write the following as a php class to save
// this data as a static member. That way I can share the qeng_id
// across all sessions, instead of per session.
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$site_path = site_url('/search');
if ($body->resultset->prev_avail):
$newPage = $paged - 1;
// an associative array containing the query var and its value
$params = array(
'q' => $query,
'page' => $newPage
); ?>
<p><a href="<?php echo add_query_arg($params, $site_path); ?>">PREV</a></p>
<?php
elseif ($body->resultset->next_avail):
$newPage = $paged + 1;
$params = array(
'q' => $query,
'page' => $newPage
); ?>
<p><a href="<?php echo add_query_arg($params, $site_path); ?>">NEXT</a></p>
<?php
endif; ?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment