2015-02-24 21:58:33 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Radar\Connect;
|
|
|
|
|
|
|
|
use Guzzle\Http\ClientInterface;
|
|
|
|
use Guzzle\Http\Message\RequestInterface;
|
|
|
|
use Guzzle\Http\Message\Response;
|
|
|
|
use Radar\Connect\Entity\Entity;
|
|
|
|
|
|
|
|
class Connect {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var ClientInterface Guzzle HTTP Client
|
|
|
|
*/
|
|
|
|
protected $client;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Cache Doctrine cache for entities.
|
|
|
|
*/
|
|
|
|
protected $cache;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string URL of API endpoint.
|
|
|
|
*/
|
|
|
|
public $apiUrl;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var bool Debug switch true for verbose.
|
|
|
|
*/
|
|
|
|
public $debug;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
*
|
|
|
|
* @param ClientInterface $client
|
|
|
|
* Guzzle HTTP Client.
|
|
|
|
* @param array $configuration
|
|
|
|
*/
|
|
|
|
public function __construct(ClientInterface $client, $configuration = array()) {
|
|
|
|
$this->client = $client;
|
|
|
|
$this->client->setDefaultOption('headers', array('Accept' => 'application/json'));
|
|
|
|
|
|
|
|
if (!empty($configuration['api_url'])) {
|
|
|
|
$this->apiUrl = $configuration['api_url'];
|
|
|
|
}
|
|
|
|
else {
|
2015-03-28 11:44:43 +01:00
|
|
|
$this->apiUrl = 'https://radar.squat.net/api/1.0/';
|
2015-02-24 21:58:33 +01:00
|
|
|
}
|
|
|
|
$this->debug = !empty($configuration['debug']);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For now also just allow direct access to guzzle itself.
|
|
|
|
*/
|
|
|
|
public function __call($name, $arguments) {
|
|
|
|
return call_user_func_array(array($this->client, $name), $arguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set a cache to store entities.
|
|
|
|
*
|
|
|
|
* @param \Radar\Connect\Cache $cache
|
|
|
|
*/
|
|
|
|
public function setCache(Cache $cache) {
|
|
|
|
$this->cache = $cache;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve all fields for single entity.
|
|
|
|
*
|
|
|
|
* Entities can be partly loaded. Especially when just a reference on
|
|
|
|
* an event or group. Use this to retrieve the full entity.
|
|
|
|
* If there is a cache set, and the entity is still validly cached
|
|
|
|
* this will be returned rather than making a new query.
|
|
|
|
*
|
|
|
|
* @param Entity $entity
|
|
|
|
* The partly loaded entity.
|
|
|
|
*
|
|
|
|
* @return Entity
|
|
|
|
* The loaded entity.
|
|
|
|
*/
|
|
|
|
public function retrieveEntity(Entity $entity) {
|
|
|
|
if (!empty($this->cache) && $this->cache->contains($entity)) {
|
|
|
|
return $this->cache->fetch($entity);
|
|
|
|
}
|
|
|
|
$request = $this->client->get($entity->apiUri());
|
|
|
|
$entity = $this->parseResponse($response);
|
|
|
|
if (!empty($this->cache)) {
|
|
|
|
$this->cache->save($entity);
|
|
|
|
}
|
|
|
|
return $entity;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve all fields for multiple entities.
|
|
|
|
*
|
|
|
|
* As retrieveEntity(), but making multiple concurrent requests.
|
|
|
|
*
|
|
|
|
* @param Entity[] $entities
|
|
|
|
* Array of partly loaded entities.
|
|
|
|
*
|
|
|
|
* @return Entity[]
|
|
|
|
* Array of loaded entities.
|
|
|
|
*/
|
|
|
|
public function retrieveEntityMultiple(&$entities) {
|
|
|
|
$cached = array();
|
|
|
|
if (!empty($this->cache)) {
|
|
|
|
foreach($entities as $key => $entity) {
|
|
|
|
if ($this->cache->contains($entity)) {
|
|
|
|
$cached[] = $this->cache->fetch($entity);
|
|
|
|
unset($entities[$key]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$requests = array();
|
|
|
|
foreach ($entities as $entity) {
|
|
|
|
$requests[] = $this->client->get($entity->apiUri());
|
|
|
|
}
|
|
|
|
$retrieved = $this->retrieveMultiple($requests);
|
|
|
|
|
|
|
|
if (!empty($this->cache)) {
|
|
|
|
foreach ($retrieved as $entity) {
|
|
|
|
$this->cache->save($entity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$entities = array_merge($cached, $retrieved);
|
|
|
|
return $entities;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* TODO Insert or update an existing Entity.
|
|
|
|
*/
|
|
|
|
public function putEntity(Entity $entity) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prepare a request to retrieve events.
|
|
|
|
*
|
|
|
|
* @see self::retrieve()
|
|
|
|
*
|
|
|
|
* @param Filter $filter
|
|
|
|
* @param array $fields
|
|
|
|
* A list of fields to load. Optional, default is most available fields.
|
|
|
|
* @param int $limit
|
|
|
|
* How many events to return.
|
|
|
|
*
|
|
|
|
* @return \Guzzle\Http\Message\Request
|
|
|
|
* Request object to retrieve.
|
|
|
|
*/
|
|
|
|
public function prepareEventsRequest(Filter $filter, $fields = array(), $limit = 500) {
|
|
|
|
$request = $this->client->get($this->apiUrl . 'search/events.json');
|
|
|
|
$query = $request->getQuery();
|
|
|
|
$query->set('facets', $filter->getQuery());
|
|
|
|
if (! empty($fields)) {
|
|
|
|
// Always retrieve type.
|
|
|
|
$fields = array_merge($fields, array('type'));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$fields = array(
|
|
|
|
'title',
|
|
|
|
'type',
|
|
|
|
'uuid',
|
|
|
|
'og_group_ref',
|
|
|
|
'date_time',
|
|
|
|
'offline',
|
|
|
|
'category',
|
|
|
|
'topic',
|
|
|
|
'price',
|
|
|
|
'link',
|
|
|
|
'phone',
|
|
|
|
'body',
|
|
|
|
'image',
|
|
|
|
'language',
|
|
|
|
'created',
|
|
|
|
'updated',
|
|
|
|
'view_url',
|
|
|
|
);
|
|
|
|
}
|
|
|
|
$query->set('fields', $fields);
|
|
|
|
$query->set('limit', $limit);
|
|
|
|
return $request;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prepare a request to retrieve groups.
|
|
|
|
*
|
|
|
|
* @see self::retrieve()
|
|
|
|
*
|
|
|
|
* @param Filter $filter
|
|
|
|
* @param array $fields
|
|
|
|
* A list of fields to load. Optional, default is most available fields.
|
|
|
|
* @param int $limit
|
|
|
|
* How many groups to return.
|
|
|
|
*
|
|
|
|
* @return \Guzzle\Http\Message\Request
|
|
|
|
* Request object to retrieve.
|
|
|
|
*/
|
|
|
|
public function prepareGroupsRequest(Filter $filter, $fields = array(), $limit = 500) {
|
|
|
|
$request = $this->client->get($this->apiUrl . 'search/groups.json');
|
|
|
|
$query = $request->getQuery();
|
|
|
|
$query->set('facets', $filter->getQuery());
|
|
|
|
if (! empty($fields)) {
|
|
|
|
$fields += array('type');
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$fields = array(
|
|
|
|
'title',
|
|
|
|
'type',
|
|
|
|
'category',
|
|
|
|
'offline',
|
|
|
|
'topic',
|
|
|
|
'body',
|
|
|
|
'email',
|
|
|
|
'weblink',
|
|
|
|
'offline',
|
|
|
|
'opening_times',
|
|
|
|
'phone',
|
|
|
|
'view_url',
|
|
|
|
);
|
|
|
|
}
|
|
|
|
$query->set('fields', $fields);
|
|
|
|
$query->set('limit', $limit);
|
|
|
|
return $request;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve entities from a prepared request.
|
|
|
|
*
|
|
|
|
* @param \Guzzle\Http\Message\RequestInterface $request
|
|
|
|
*
|
|
|
|
* @return Entity[]
|
|
|
|
*/
|
|
|
|
public function retrieve(RequestInterface $request) {
|
|
|
|
$response = $this->client->send($request);
|
|
|
|
if ($this->debug) {
|
|
|
|
var_export($response->getHeaders());
|
|
|
|
var_export($response->getBody());
|
|
|
|
}
|
|
|
|
return $this->parseResponse($response);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve entities from multiple prepared requests.
|
|
|
|
*
|
|
|
|
* Results are merged into one entity array.
|
|
|
|
*
|
|
|
|
* @param \Guzzle\Http\Message\RequestInterface[] $requests
|
|
|
|
*
|
|
|
|
* @return Entity[]
|
|
|
|
*/
|
|
|
|
public function retrieveMultiple($requests) {
|
|
|
|
try {
|
|
|
|
$responses = $this->client->send($requests);
|
|
|
|
}
|
|
|
|
catch (MultiTransferException $e) {
|
|
|
|
foreach ($e->getFailedRequests() as $request) {
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($e->getSuccessfulRequests() as $request) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$items = array();
|
|
|
|
foreach ($responses as $response) {
|
|
|
|
$items = array_merge($items, $this->parseResponse($response));
|
|
|
|
}
|
|
|
|
return $items;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse a response from the client.
|
|
|
|
*
|
|
|
|
* TODO this doesn't need to be in here.
|
|
|
|
*/
|
|
|
|
protected function parseResponse(Response $response) {
|
|
|
|
$items = array();
|
|
|
|
|
|
|
|
$content = $response->json();
|
|
|
|
if (isset($content['type'])) {
|
|
|
|
$class = __NAMESPACE__ . '\\Entity\\' . Entity::className($content['type']);
|
|
|
|
$content['apiBase'] = $this->apiUrl;
|
|
|
|
$items[] = new $class($content);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
foreach ($content as $key => $item) {
|
|
|
|
$class = __NAMESPACE__ . '\\Entity\\' . Entity::className($item['type']);
|
|
|
|
$item['apiBase'] = $this->apiUrl;
|
|
|
|
$items[] = new $class($item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $items;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|