Skip to content

Commit

Permalink
Issue #196: Added data provider for variables.
Browse files Browse the repository at this point in the history
Also adds support for drupal_write_record on DB query.
raphaeltraviss authored and Mateu Aguiló Bosch committed Jan 24, 2015
1 parent 0aaa911 commit bad9c9b
Showing 15 changed files with 717 additions and 165 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

/**
* @file
* Contains RestfulEntityBase.
*/

class RestFulWatchdogResource extends \RestfulDataProviderDbQuery implements \RestfulDataProviderDbQueryInterface {
public function publicFieldsInfo() {

$public_fields['log_id'] = array(
'property' => 'wid',
);

$public_fields['log_type'] = array(
'property' => 'type',
);

$public_fields['log_text'] = array(
'property' => 'message',
);

$public_fields['log_variables'] = array(
'property' => 'variables',
);

$public_fields['log_level'] = array(
'property' => 'severity',
);

$public_fields['log_path'] = array(
'property' => 'location',
);

return $public_fields;
}

/**
* {@inheritdoc}
*/
public function access() {
$account = $this->getAccount();
return user_access('view site reports', $account);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

$plugin = array(
'label' => t('Watchdog entries'),
'resource' => 'watchdog',
'name' => 'watchdog',
'data_provider_options' => array(
'table_name' => 'watchdog',
'id_column' => 'wid',
),
'description' => t('Expose watchdog entries to the REST API.'),
'class' => 'RestfulWatchdogResource',
'authentication_types' => TRUE,
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

/**
* @file
* Contains \RestfulQueryVariable
*/

class RestfulVariableResource extends \RestfulDataProviderVariable {

/**
* {@inheritdoc}
*/
public function publicFieldsInfo() {
return array(
'variable_name' => array(
'property' => 'name',
),
'variable_value' => array(
'property' => 'value',
),
);
}

/**
* {@inheritdoc}
*/
public function access() {
$account = $this->getAccount();
return user_access('adminsiter site configuration', $account);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

$plugin = array(
'label' => t('Variable'),
'description' => t('Expose site variables to the REST API.'),
'resource' => 'variables',
'class' => 'RestfulVariableResource',
'authentication_types' => TRUE,
'render_cache' => array(
'render' => TRUE,
),
);
Original file line number Diff line number Diff line change
@@ -11,13 +11,12 @@ class RestfulTokenAuthenticationTestCase extends DrupalWebTestCase {
return array(
'name' => 'Token Authentication',
'description' => 'Test the request authentication with a token.',
'group' => 'Restful',
'group' => 'RESTful',
);
}

function setUp() {
parent::setUp('restful_example', 'restful_token_auth', 'entityreference');
restful_create_field_refresh_token();
}

/**
110 changes: 61 additions & 49 deletions plugins/restful/RestfulDataProviderDbQuery.php
Original file line number Diff line number Diff line change
@@ -75,6 +75,20 @@ public function setTableName($table_name) {
$this->tableName = $table_name;
}

/**
* @return string
**/
public function getPrimary() {
return $this->primary;
}

/**
* @param string $primary
**/
public function setPrimary($primary) {
$this->primary = $primary;
}

/**
* Constructs a RestfulDataProviderDbQuery object.
*
@@ -112,7 +126,9 @@ public function defaultSortInfo() {
$sorts = array();
foreach ($this->getIdColumn() as $column) {
if (!empty($this->getPublicFields[$column])) {
// Sort by the first ID column that is a public field.
$sorts[$column] = 'ASC';
break;
}
}
return $sorts;
@@ -230,7 +246,8 @@ public function getQueryCount() {
public function getTotalCount() {
return intval($this
->getQueryCount()
->execute());
->execute()
->fetchField());
}

/**
@@ -341,22 +358,20 @@ protected function replace($id) {
* {@inheritdoc}
*/
public function update($id, $full_replace = FALSE) {
$query = db_update($this->getTableName());
foreach ($this->getIdColumn() as $index => $column) {
$query->condition($column, current($this->getColumnFromIds(array($id), $index)));
}

// Build the update array.
$request = $this->getRequest();
static::cleanRequest($request);
$save = FALSE;
$original_request = $request;

$public_fields = $this->getPublicFields();
$fields = array();

$id_columns = $this->getIdColumn();

$record = array();
foreach ($public_fields as $public_field_name => $info) {
// Ignore passthrough public fields.
if (!empty($info['create_or_update_passthrough'])) {
// Allow passing the value in the request.
unset($original_request[$public_field_name]);
continue;
}
@@ -365,62 +380,67 @@ public function update($id, $full_replace = FALSE) {
if ($this->isPrimaryField($info['property'])) {
continue;
}
// Check if the public property is set in the payload.
if (!isset($request[$public_field_name])) {
if ($full_replace) {
$fields[$info['property']] = NULL;
}

if (isset($request[$public_field_name])) {
$record[$info['property']] = $request[$public_field_name];
}
else {
$fields[$info['property']] = $request[$public_field_name];
// For unset fields on full updates, pass NULL to drupal_write_record().
elseif ($full_replace) {
$record[$info['property']] = NULL;
}

unset($original_request[$public_field_name]);
$save = TRUE;
}

// No request was sent.
if (!$save) {
// No request was sent.
throw new \RestfulBadRequestException('No values were sent with the request.');
}

if ($original_request) {
// Request had illegal values.
// If the original request is not empty, then illegal values are present.
if (!empty($original_request)) {
$error_message = format_plural(count($original_request), 'Property @names is invalid.', 'Property @names are invalid.', array('@names' => implode(', ', array_keys($original_request))));
throw new \RestfulBadRequestException($error_message);
}

// Once the update array is built, execute the query.
$query->fields($fields)->execute();
// Add the id column values into the record.
foreach ($this->getIdColumn() as $index => $column) {
$record[$column] = current($this->getColumnFromIds(array($id), $index));
}

// Once the record is built, write it.
if (!drupal_write_record($this->getTableName(), $record, $id_columns)) {
throw new \RestfulServiceUnavailable('Record could not be updated to the database.');
}

// Clear the rendered cache before calling the view method.
$this->clearRenderedCache(array(
'tb' => $this->getTableName(),
'cl' => implode(',', $this->getIdColumn()),
'id' => $id,
));
return $this->view($id, TRUE);

return $this->view($id);
}

/**
* {@inheritdoc}
*/
public function create() {
$query = db_insert($this->getTableName());

// Build the update array.
$request = $this->getRequest();
static::cleanRequest($request);
$save = FALSE;
$original_request = $request;

$public_fields = $this->getPublicFields();
$fields = array();
$id_values = array_fill(0, count($this->getIdColumn()), FALSE);
$id_columns = $this->getIdColumn();


$record = array();
foreach ($public_fields as $public_field_name => $info) {
// Ignore passthrough public fields.
if (!empty($info['create_or_update_passthrough'])) {
// Allow passing the value in the request.
unset($original_request[$public_field_name]);
continue;
}
@@ -431,46 +451,38 @@ public function create() {
continue;
}

// Check if the public property is set in the payload.
if (($index = array_search($info['property'], $this->getIdColumn())) !== FALSE) {
$id_values[$index] = $request[$public_field_name];
}

if (isset($request[$public_field_name])) {
$fields[$info['property']] = $request[$public_field_name];
$record[$info['property']] = $request[$public_field_name];
}

unset($original_request[$public_field_name]);
$save = TRUE;
}

// No request was sent.
if (!$save) {
// No request was sent.
throw new \RestfulBadRequestException('No values were sent with the request.');
}

if ($original_request) {
// Request had illegal values.
// If the original request is not empty, then illegal values are present.
if (!empty($original_request)) {
$error_message = format_plural(count($original_request), 'Property @names is invalid.', 'Property @names are invalid.', array('@names' => implode(', ', array_keys($original_request))));
throw new \RestfulBadRequestException($error_message);
}

$passed_id = NULL;

// If we have the full primary key passed use it.
if (count(array_filter($id_values)) == count($id_values)) {
$passed_id = implode(self::COLUMN_IDS_SEPARATOR, $id_values);
}
// Once the record is built, write it and view it.
if (drupal_write_record($this->getTableName(), $record)) {
// Handle multiple id columns.
$id_values = array();
foreach ($id_columns as $id_column) {
$id_values[$id_column] = $record[$id_column];
}
$id = implode(self::COLUMN_IDS_SEPARATOR, $id_values);

// Once the update array is built, execute the query.
if ($id = $query->fields($fields)->execute()) {
return $this->view($id, TRUE);
return $this->view($id);
}
return;

// Some times db_insert() does not know how to get the ID.
if ($passed_id) {
return $this->view($passed_id);
}
}

/**
Loading

0 comments on commit bad9c9b

Please sign in to comment.