1
0
Fork 0
forked from lino/radar-wp

Upgrading to 1.0.0-beta1 version of the API PHP implementation.

This commit is contained in:
ekes 2017-06-09 13:30:20 +01:00
parent 4424f09f06
commit 4ed51243b5
56 changed files with 1330 additions and 824 deletions

View file

@ -20,15 +20,15 @@ class Cache {
$this->cache = $cache;
}
public function contains(Entity $entity) {
return $this->cache->contains($entity->apiUri());
public function contains($uri) {
return $this->cache->contains($uri);
}
public function fetch(Entity $entity) {
return $this->cache->fetch($entity->apiUri());
public function fetch($uri) {
return $this->cache->fetch($uri);
}
public function save(Entity $entity) {
public function save($uri, Entity $entity) {
// TODO Make configurable.
$ttl = array(
'group' => 60 * 60,
@ -36,11 +36,12 @@ class Cache {
'event' => 60 * 5,
'location' => 60 * 60 * 24,
'taxonomy_term' => 60 * 60 * 24 * 30,
'file' => 60 * 60,
);
return $this->cache->save($entity->apiUri(), $entity, $ttl[$entity->type]);
return $this->cache->save($uri, $entity, $ttl[$entity->type]);
}
public function delete(Entity $entity) {
return $this->cache->delete($entity->apiUri());
public function delete($uri) {
return $this->cache->delete($uri);
}
}

View file

@ -29,6 +29,11 @@ class Connect {
*/
public $debug;
/**
* @var string ISO 639-1 code.
*/
public $language;
/**
* Constructor.
*
@ -44,7 +49,7 @@ class Connect {
$this->apiUrl = $configuration['api_url'];
}
else {
$this->apiUrl = 'https://radar.squat.net/api/1.0/';
$this->apiUrl = 'https://radar.squat.net/api/1.1/';
}
$this->debug = !empty($configuration['debug']);
}
@ -65,6 +70,36 @@ class Connect {
$this->cache = $cache;
}
/**
* Set, default, language for queries.
*/
public function setLanguage($langcode) {
$this->language = $langcode;
}
/**
* Retrieve language code.
*/
public function getLanguage() {
if (!empty($this->language)) {
return $this->language;
}
else {
return 'und';
}
}
/**
* Compute url for cache storage.
*
* Language is for the language requested, not necessarily the language of
* the entity, as different language requests can return different
* langage entities (not necessarity corresponding) based on fallback.
*/
public function cacheUri($entity) {
return $entity->apiUri() . '?language=' . $this->getLanguage();
}
/**
* Retrieve all fields for single entity.
*
@ -80,13 +115,18 @@ class Connect {
* The loaded entity.
*/
public function retrieveEntity(Entity $entity) {
if (!empty($this->cache) && $this->cache->contains($entity)) {
return $this->cache->fetch($entity);
$cacheUri = $this->cacheUri($entity);
if (!empty($this->cache) && $this->cache->contains($cacheUri)) {
return $this->cache->fetch($cacheUri);
}
$request = $this->client->get($entity->apiUri());
$entity = $this->parseResponse($response);
if ($this->getLanguage() != 'und') {
$query = $request->getQuery();
$query->set('language', $this->getLanguage());
}
$entity = $this->retrieve($request);
if (!empty($this->cache)) {
$this->cache->save($entity);
$this->cache->save($cacheUri, $entity);
}
return $entity;
}
@ -106,8 +146,8 @@ class Connect {
$cached = array();
if (!empty($this->cache)) {
foreach($entities as $key => $entity) {
if ($this->cache->contains($entity)) {
$cached[] = $this->cache->fetch($entity);
if ($this->cache->contains($this->cacheUri($entity))) {
$cached[] = $this->cache->fetch($this->cacheUri($entity));
unset($entities[$key]);
}
}
@ -115,13 +155,18 @@ class Connect {
$requests = array();
foreach ($entities as $entity) {
$requests[] = $this->client->get($entity->apiUri());
$request = $this->client->get($entity->apiUri());
if ($this->getLanguage() != 'und') {
$query = $request->getQuery();
$query->set('language', $this->getLanguage());
}
$requests[] = $request;
}
$retrieved = $this->retrieveMultiple($requests);
if (!empty($this->cache)) {
foreach ($retrieved as $entity) {
$this->cache->save($entity);
$this->cache->save($this->cacheUri($entity), $entity);
}
}
@ -136,8 +181,6 @@ class Connect {
}
/**
* Prepare a request to retrieve events.
*
@ -148,14 +191,27 @@ class Connect {
* A list of fields to load. Optional, default is most available fields.
* @param int $limit
* How many events to return.
* @param array $sort
* Optional array ['field_name' => 'order'], where order is ASC or DESC.
* @param array $keys
* Values for full text search ['search', 'words'] for OR ['search words'] for AND.
*
* @return \Guzzle\Http\Message\Request
* Request object to retrieve.
*/
public function prepareEventsRequest(Filter $filter, $fields = array(), $limit = 500) {
public function prepareEventsRequest(Filter $filter, $fields = array(), $limit = 500, $sort = array(), $keys = array()) {
$request = $this->client->get($this->apiUrl . 'search/events.json');
$query = $request->getQuery();
$query->set('facets', $filter->getQuery());
if ($this->getLanguage() != 'und') {
$query->set('language', $this->getLanguage());
}
if (!empty($sort)) {
$query->set('sort', $sort);
}
if (!empty($keys)) {
$query->set('keys', $keys);
}
if (! empty($fields)) {
// Always retrieve type.
$fields = array_merge($fields, array('type'));
@ -165,11 +221,13 @@ class Connect {
'title',
'type',
'uuid',
'nid',
'og_group_ref',
'date_time',
'offline',
'category',
'topic',
'price_category',
'price',
'link',
'phone',
@ -196,27 +254,42 @@ class Connect {
* A list of fields to load. Optional, default is most available fields.
* @param int $limit
* How many groups to return.
* @param array $sort
* Optional array ['field_name' => 'order'], where order is ASC or DESC.
* @param array $keys
* Values for full text search ['search', 'words'] for OR ['search words'] for AND.
*
* @return \Guzzle\Http\Message\Request
* Request object to retrieve.
*/
public function prepareGroupsRequest(Filter $filter, $fields = array(), $limit = 500) {
public function prepareGroupsRequest(Filter $filter, $fields = array(), $limit = 500, $sort = array(), $keys = array()) {
$request = $this->client->get($this->apiUrl . 'search/groups.json');
$query = $request->getQuery();
if ($this->getLanguage() != 'und') {
$query->set('language', $this->getLanguage());
}
$query->set('facets', $filter->getQuery());
if (!empty($sort)) {
$query->set('sort', $sort);
}
if (!empty($keys)) {
$query->set('keys', $keys);
}
if (! empty($fields)) {
$fields += array('type');
}
else {
$fields = array(
'uuid',
'title',
'type',
'nid',
'category',
'offline',
'topic',
'body',
'email',
'weblink',
'link',
'offline',
'opening_times',
'phone',
@ -228,6 +301,22 @@ class Connect {
return $request;
}
/**
* Retrieve API response from a prepared request.
*
* @param \Guzzle\Http\Message\RequestInterface $request
*
* @return \Guzzle\Http\Message\Response
*/
public function retrieveResponse(RequestInterface $request) {
$response = $this->client->send($request);
if ($this->debug) {
var_export($response->getHeaders());
var_export($response->getBody());
}
return $response;
}
/**
* Retrieve entities from a prepared request.
*
@ -241,7 +330,9 @@ class Connect {
var_export($response->getHeaders());
var_export($response->getBody());
}
return $this->parseResponse($response);
$items = $this->parseResponse($response);
$entity = reset($items);
return $entity;
}
/**
@ -277,24 +368,52 @@ class Connect {
*
* TODO this doesn't need to be in here.
*/
protected function parseResponse(Response $response) {
public function parseResponse(Response $response) {
$items = array();
$content = $response->json();
if (isset($content['type'])) {
// Single item response.
$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);
$result = empty($content['result']) ? array() : $content['result'];
$first_content_item = current($result);
if (!empty($first_content_item)) {
// List response, that is non-empty.
foreach ($result as $key => $item) {
$class = __NAMESPACE__ . '\\Entity\\' . Entity::className($item['type']);
$item['apiBase'] = $this->apiUrl;
$items[] = new $class($item);
}
}
else {
// Empty response.
$items = array();
}
}
return $items;
}
/**
* Parse response metadata.
*/
public function parseResponseMeta(Response $response) {
$output = [];
$content = $response->json();
if (isset($content['count'])) {
$output['count'] = $content['count'];
}
if (isset($content['facets'])) {
$output['facets'] = $content['facets'];
}
return $output;
}
}

View file

@ -27,6 +27,7 @@ abstract class Entity {
'category' => 'TaxonomyTerm',
'topic' => 'TaxonomyTerm',
'price' => 'TaxonomyTerm',
'file' => 'RadarFile',
);
return $classes[$type];
}

View file

@ -87,11 +87,21 @@ class Event extends Node {
/**
* Return image field data.
*
* TODO API isn't putting the data into the output.
*/
public function getImageRaw() {
return $this->image;
return $this->image['file'];
}
/**
* Return image file object.
*
* @return RadarFile|NULL
*/
public function getImage() {
if (!empty($this->image['file'])) {
return new RadarFile($this->image['file']);
}
return NULL;
}
public function getPriceCategoryRaw() {

View file

@ -17,17 +17,42 @@ class Group extends Node {
}
/**
* TODO not appearing in the API output.
* Logo raw data.
*/
public function getGroupLogoRaw() {
return $this->group_logo;
}
/**
* TODO not appearing in the API output.
* Logo file object.
*
* @return File|NULL
*/
public function getGroupLogo() {
if (!empty($this->group_logo)) {
return new RadarFile($this->group_logo);
}
return NULL;
}
/**
* Raw image entity array.
*/
public function getImageRaw() {
return $this->image->file;
return $this->image;
}
/**
* Return image entity object.
*
* @return RadarFile|NULL
*/
public function getImage() {
if (!empty($this->image->file)) {
return new RadarFile($this->image);
}
return NULL;
}
/**

View file

@ -65,7 +65,11 @@ class Node extends Entity {
}
public function getCategoriesRaw() {
return $this->category;
$categories = array();
foreach ($this->category as $category) {
$categories[$category['id']] = $category;
}
return $category;
}
/**
@ -77,14 +81,18 @@ class Node extends Entity {
$categories = array();
if (is_array($this->category)) {
foreach ($this->category as $category) {
$categories[] = new TaxonomyTerm($category);
$categories[$category['id']] = new TaxonomyTerm($category);
}
}
return $categories;
}
public function getTopicsRaw() {
return $this->topics;
$topics = array();
foreach ($this->topic as $topic) {
$topics[$topic['id']] = $topic;
}
return $topics;
}
/**
@ -96,7 +104,7 @@ class Node extends Entity {
$topics = array();
if (is_array($this->topic)) {
foreach ($this->topic as $topic) {
$topics[] = new TaxonomyTerm($topic);
$topics[$topic['id']] = new TaxonomyTerm($topic);
}
}
return $topics;

View file

@ -0,0 +1,67 @@
<?php
namespace Radar\Connect\Entity;
class RadarFile extends Entity {
public $title;
public $mime;
public $size;
public $url;
function __construct($data = array()) {
$this->set($data);
$this->type = 'file';
}
public function set($data) {
$data = (array) $data;
parent::set($data);
if (isset($data['fid'])) {
$this->drupalId = $data['fid'];
}
}
public function apiUri() {
if (isset($this->apiUri)) {
return $this->apiUri;
}
elseif (isset($this->uuid)) {
return $this->apiBase . 'file/' . $this->uuid;
}
throw new Exception();
}
/**
* Title is usually filename.
*/
public function getTitle() {
return $this->title;
}
/**
* Mimetype, eg image/jpeg
*/
public function getImageRaw() {
return $this->mime;
}
/**
* URL to the file itself.
*
* @return string
*/
public function getUrl() {
return $this->url;
}
/**
* Size, in bytes.
*
* @return int
*/
public function getSize() {
return $this->size;
}
}

View file

@ -9,6 +9,18 @@ class Filter {
*/
private $query;
/**
* Add arbitary filter, knowing key.
*
* If you add something that doesn't work it usually just returns no results.
*
* @param string key
* @param string value
*/
public function add($key, $value) {
$this->query[$key][] = $value;
}
/**
* Filter by group.
*
@ -43,7 +55,7 @@ class Filter {
/**
* Filter by year.
*
* @param string $year.
* @param string $year
* Optional: year in YYYY format. Default current year.
*/
public function addYear($year = 'now') {
@ -128,4 +140,5 @@ class Filter {
public function getQuery() {
return $this->query;
}
}