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.
  • Loading branch information
raphaeltraviss authored and Mateu Aguiló Bosch committed Jan 24, 2015
1 parent 0aaa911 commit bad9c9b
Show file tree
Hide file tree
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
Expand Up @@ -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();
}

/**
Expand Down
110 changes: 61 additions & 49 deletions plugins/restful/RestfulDataProviderDbQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -230,7 +246,8 @@ public function getQueryCount() {
public function getTotalCount() {
return intval($this
->getQueryCount()
->execute());
->execute()
->fetchField());
}

/**
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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);
}
}

/**
Expand Down
Loading

0 comments on commit bad9c9b

Please sign in to comment.