/**
* Handle metadata search operation
*
* page => Page number. Defaults to 1
* limit => Limit to a number of images pr. page. Defaults to 20
* metadata => Whether or not to include metadata pr. image. Set to 1 to enable
* query => urlencoded json data to use in the query
* from => Unix timestamp to fetch from
* to => Unit timestamp to fetch to
*
* @param Imbo\EventListener\ListenerInterface $event The current event
* @param array $users Array with image identifiers
*/
protected function searchHandler(EventInterface $event, array $users)
{
$request = $event->getRequest();
$params = $request->query;
// Extract query
$metadataQuery = $request->getContent();
// If no metadata is provided, we'll let db.images.load take over
if (!$metadataQuery) {
$event->getManager()->trigger('db.images.load');
return;
}
// Check access token
$event->getManager()->trigger('auth.accesstoken');
// Check that the public key has access to the users
$this->validateAccess($event, $users);
// Build query params array
$queryParams = ['page' => $params->get('page', 1), 'limit' => $params->get('limit', 20), 'from' => $params->get('from'), 'to' => $params->get('to'), 'sort' => $this->getSortParams($event)];
if ($queryParams['page'] < 1) {
throw new RuntimeException('Invalid param. "page" must be a positive number.', 400);
}
if ($queryParams['limit'] < 1) {
throw new RuntimeException('Invalid param. "limit" must be a positive number.', 400);
}
// Parse the query JSON and transform it to an AST
$ast = DslParser::parse($metadataQuery);
// Query backend using the AST
$backendResponse = $this->backend->search($users, $ast, $queryParams);
// If we didn't get hits in the search backend, prepare a response
if (!$backendResponse->getImageIdentifiers()) {
// Create the model and set some pagination values
$model = new ImagesModel();
$model->setLimit($queryParams['limit'])->setPage($queryParams['page'])->setHits($backendResponse->getHits());
$response = $event->getResponse();
$response->setModel($model);
return;
}
$imageIdentifiers = $backendResponse->getImageIdentifiers();
// Set the ids to fetch from the Imbo backend
$params->set('ids', $imageIdentifiers);
// In order to paginate the already paginated resultset, we'll
// set the page param to 0 before triggering db.images.load
$params->set('page', 0);
// Unset date range parameters
$params->remove('to');
$params->remove('from');
// Trigger image loading from imbo DB
$event->getManager()->trigger('db.images.load');
$responseModel = $event->getResponse()->getModel();
// Set the actual page used for querying search backend on the response
$responseModel->setPage($queryParams['page']);
$responseModel->setHits($backendResponse->getHits());
// Sort the response image so they match the order of identifiers
// returned from search backend
$this->sortSearchResponse($responseModel, $imageIdentifiers);
}