Skip to content

Commit

Permalink
Issue RESTful-Drupal#297: Use the static cache controller.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mateu Aguiló Bosch committed Dec 5, 2014
1 parent 9ef275c commit e7702a6
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 29 deletions.
56 changes: 40 additions & 16 deletions plugins/restful/RestfulBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ abstract class RestfulBase extends \RestfulPluginBase implements \RestfulInterfa
*/
protected $valueMetadata = array();

/**
* Static cache controller.
*
* @var \RestfulStaticCacheController
*/
public $staticCache;

/**
* Get the cache id parameters based on the keys.
*
Expand Down Expand Up @@ -344,6 +351,7 @@ public function __construct(array $plugin, \RestfulAuthenticationManager $auth_m
if ($rate_limit = $this->getPluginKey('rate_limit')) {
$this->setRateLimitManager(new \RestfulRateLimitManager($this->getPluginKey('resource'), $rate_limit));
}
$this->staticCache = new \RestfulStaticCacheController();
}

/**
Expand Down Expand Up @@ -513,14 +521,15 @@ public function getResourceName() {
* definition.
*/
public function getVersion() {
$version = &drupal_static(__CLASS__ . '::' . __FUNCTION__);
$version = $this->staticCache->get(__CLASS__ . '::' . __FUNCTION__);
if (isset($version)) {
return $version;
}
$version = array(
'major' => $this->getPluginKey('major_version'),
'minor' => $this->getPluginKey('minor_version'),
);
$this->staticCache->set(__CLASS__ . '::' . __FUNCTION__, $version);
return $version;
}

Expand Down Expand Up @@ -702,21 +711,12 @@ public function process($path = '', array $request = array(), $method = \Restful
$this->setMethod($method);
$this->setPath($path);
$this->setRequest($request);
// Override the range with the value in the URL.
if (!empty($request['range'])) {
$url_params = $this->getPluginKey('url_params');
if (!$url_params['range']) {
throw new \RestfulBadRequestException('The range parameter has been disabled in server configuration.');
}

if (!ctype_digit((string) $request['range']) || $request['range'] < 1) {
throw new \RestfulBadRequestException('"Range" property should be numeric and higher than 0.');
}
if ($request['range'] < $this->getRange()) {
// If there is a valid range property in the request override the range.
$this->setRange($request['range']);
}
}
// Clear all static caches from previous requests.
$this->staticCache->clearAll();

// Override the range with the value in the URL.
$this->overrideRange();

$version = $this->getVersion();
$this->setHttpHeaders('X-API-Version', 'v' . $version['major'] . '.' . $version['minor']);
Expand Down Expand Up @@ -1163,7 +1163,7 @@ protected function clearRenderedCache(array $context = array()) {
protected function generateCacheId(array $context = array()) {
// For performance reasons create the request part and cache it, then add
// the context part.
$request_cid = &drupal_static(__CLASS__ . '::' . __FUNCTION__);
$request_cid = $this->staticCache->get(__CLASS__ . '::' . __FUNCTION__);
if (!isset($request_cid)) {
// Get the cache ID from the selected params. We will use a complex cache
// ID for smarter invalidation. The cache id will be like:
Expand All @@ -1182,6 +1182,7 @@ protected function generateCacheId(array $context = array()) {
$cid_params = static::addCidParams($request);
}
$request_cid = $cid . implode('::', $cid_params);
$this->staticCache->set(__CLASS__ . '::' . __FUNCTION__, $request_cid);
}
// Now add the context part to the cid
$cid_params = static::addCidParams($context);
Expand Down Expand Up @@ -1506,4 +1507,27 @@ protected static function notImplementedCrudOperation($operation) {
throw new \RestfulNotImplementedException(format_string('The "@method" method is not implemented in class @class.', array('@method' => $operation, '@class' => __CLASS__)));
}

/**
* Overrides the range parameter with the URL value if any.
*
* @throws RestfulBadRequestException
*/
protected function overrideRange() {
$request = $this->getRequest();
if (!empty($request['range'])) {
$url_params = $this->getPluginKey('url_params');
if (!$url_params['range']) {
throw new \RestfulBadRequestException('The range parameter has been disabled in server configuration.');
}

if (!ctype_digit((string) $request['range']) || $request['range'] < 1) {
throw new \RestfulBadRequestException('"Range" property should be numeric and higher than 0.');
}
if ($request['range'] < $this->getRange()) {
// If there is a valid range property in the request override the range.
$this->setRange($request['range']);
}
}
}

}
4 changes: 2 additions & 2 deletions plugins/restful/RestfulDataProviderDbQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -408,14 +408,14 @@ public function remove($id) {
public function mapDbRowToPublicFields($row) {
if ($this->getMethod() == \RestfulInterface::GET) {
// For read operations cache the result.
$output = &drupal_static(__CLASS__ . '::' . __FUNCTION__ . '::' . $this->getUniqueId($row));
$output = &$this->staticCache->get(__CLASS__ . '::' . __FUNCTION__ . '::' . $this->getUniqueId($row));
if (isset($output)) {
return $output;
}
}
else {
// Clear the cache if the request is not GET.
drupal_static_reset(__CLASS__ . '::' . __FUNCTION__ . '::' . $this->getUniqueId($row));
$this->staticCache->clear(__CLASS__ . '::' . __FUNCTION__ . '::' . $this->getUniqueId($row));
}
// Loop over all the defined public fields.
foreach ($this->getPublicFields() as $public_field_name => $info) {
Expand Down
2 changes: 1 addition & 1 deletion plugins/restful/RestfulEntityBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ protected function getTargetTypeFromEntityReference(\EntityMetadataWrapper $wrap
* The value if found, or NULL if bundle not defined.
*/
protected function getValueFromResource(EntityMetadataWrapper $wrapper, $property, $resource, $public_field_name = NULL, $host_id = NULL) {
$handlers = &drupal_static(__FUNCTION__, array());
$handlers = &$this->staticCache->get(__CLASS__ . '::' . __FUNCTION__, array());

if (!$entity = $wrapper->value()) {
return;
Expand Down
6 changes: 0 additions & 6 deletions tests/RestfulHookMenuTestCase.test
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ class RestfulHookMenuTestCase extends RestfulCurlBaseTestCase {

$node1 = node_load($node1->nid);
$this->assertEqual($node1->title, 'new title', 'HTTP method was overriden.');


}

/**
Expand Down Expand Up @@ -126,30 +124,26 @@ class RestfulHookMenuTestCase extends RestfulCurlBaseTestCase {
$this->assertEqual($handler->getVersion(), array('major' => 1, 'minor' => 1), 'api/v1.1/articles resolves 1.1');

// 2. my-api/v1/articles yields version 1.6 (update to last 1.x version)
drupal_static_reset('RestfulBase::getVersion');
drupal_static_reset('RestfulBase::getVersionFromRequest');
$handler = restful_get_restful_handler_for_path('api/v1/articles');
$this->assertEqual($handler->getVersion(), array('major' => 1, 'minor' => 6), 'api/v1.6/articles resolves 1.6');

// 3. my-api/articles with header X-API-Version: v1.1 yields 1.1
// Fake the HTTP header.
$_SERVER['HTTP_X_API_VERSION'] = 'v1.1';
drupal_static_reset('RestfulBase::getVersion');
drupal_static_reset('RestfulBase::getVersionFromRequest');
$handler = restful_get_restful_handler_for_path('api/articles');
$this->assertEqual($handler->getVersion(), array('major' => 1, 'minor' => 1), 'api/articles resolves 1.1');

// 4. my-api/articles with header X-API-Version: v1 yields 1.6
// Fake the HTTP header.
$_SERVER['HTTP_X_API_VERSION'] = 'v1';
drupal_static_reset('RestfulBase::getVersion');
drupal_static_reset('RestfulBase::getVersionFromRequest');
drupal_static_reset('restful_get_restful_handler_for_path');
$handler = restful_get_restful_handler_for_path('api/articles');
$this->assertEqual($handler->getVersion(), array('major' => 1, 'minor' => 6), 'api/articles resolves 1.6');

// 5. my-api/articles without header X-API-Version yields 2.0
drupal_static_reset('RestfulBase::getVersion');
drupal_static_reset('RestfulBase::getVersionFromRequest');
drupal_static_reset('restful_get_restful_handler_for_path');
unset($_SERVER['HTTP_X_API_VERSION']);
Expand Down
4 changes: 0 additions & 4 deletions tests/RestfulRenderCacheTestCase.test
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ class RestfulRenderCacheTestCase extends DrupalWebTestCase {

// Test that cache is being generated correctly.
// Get the articles.
drupal_static_reset('RestfulBase::generateCacheId');
drupal_static_reset('RestfulBase::getVersion');
drupal_static_reset('RestfulBase::getVersionFromRequest');
$pre_cache_results = $handler->get();
// Make sure some cache entries are generated.
Expand Down Expand Up @@ -84,9 +82,7 @@ class RestfulRenderCacheTestCase extends DrupalWebTestCase {
// Test cache segmentation with request params.
// Rebuild caches.
$cache->clear('*', TRUE);
drupal_static_reset('RestfulBase::generateCacheId');
$results_wo_request = $handler->get();
drupal_static_reset('RestfulBase::generateCacheId');
$results_w_request = $handler->get('', array('fields' => 'id,label'));
// Check that the cached results for the entity without request array are
// different than with the request array.
Expand Down

0 comments on commit e7702a6

Please sign in to comment.