Skip to content

Commit

Permalink
Apply custom validation rules to REST API node creation (#2521)
Browse files Browse the repository at this point in the history
  • Loading branch information
dafeder authored and fmizzell committed May 17, 2018
1 parent a1481c5 commit be50cdb
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

/**
* @file
* Hooks provided by the DKAN Dataset REST API module.
*/

/**
* @addtogroup hooks
* @{
*/

/**
* Alter the list of validation handlers applied to all fields submited via API.
*
* @param $handlers
* Array of validation handler functions to call. Handlers should be functions
* that accept arguments:
* * $node - the node object being validated, not yet saved. Passed as
* reference.
* * $field_name - the field name being validated.
* * $info - the info array for the field.
*
*/
function hook_dkan_dataset_rest_api_field_validate_alter(&$handlers) {
$handlers[] = 'mymodule_dkan_dataset_rest_api_validation_handler';
}

/**
* @} End of "addtogroup hooks".
*/
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function _dkan_dataset_rest_api_resource_create($request) {

try {
field_attach_validate('node', $node);
_dkan_dataset_rest_api_field_validation($node);
_dkan_dataset_rest_api_validate_fields($node);
}
catch (\Exception $e) {
return services_error($e->getMessage());
Expand Down Expand Up @@ -118,7 +118,7 @@ function _dkan_dataset_rest_api_resource_update($nid, $request) {

try {
field_attach_validate('node', $node);
_dkan_dataset_rest_api_field_validation($node);
_dkan_dataset_rest_api_validate_fields($node);
}
catch (\Exception $e) {
return services_error($e->getMessage());
Expand Down Expand Up @@ -152,21 +152,33 @@ function _dkan_dataset_rest_api_resource_update($nid, $request) {
* Currently we are only checking for required fields, and that the
* values in an options/select list field are valid.
*/
function _dkan_dataset_rest_api_field_validation($node) {
function _dkan_dataset_rest_api_validate_fields($node) {
$instances = field_info_instances('node', $node->type);

foreach ($instances as $field_name => $info) {
if ($info['required'] == 1 && empty($node->{$field_name})) {
throw new Exception("Field {$field_name} is required");
$handlers = array('dkan_dataset_rest_api_validate_field');
drupal_alter('dkan_dataset_rest_api_field_validate', $handlers);
foreach($handlers as $function) {
$function($node, $field_name, $info);
}

if (!empty($node->{$field_name})) {
$options = _dkan_dataset_rest_api_field_validation_get_options($node, $field_name, $info);
}
}

// Check that the values match the options.
if (!empty($options) && is_array($options)) {
_dkan_dataset_rest_api_field_validation_check_field_values_against_options($field_name, $node->{$field_name}, $options);
}
/**
* Default validation handler for Dataset REST API
*/

function dkan_dataset_rest_api_validate_field(&$node, $field_name, $info) {
if ($info['required'] == 1 && empty($node->{$field_name})) {
throw new Exception("Field {$field_name} is required");
}
if (!empty($node->{$field_name})) {
$options = _dkan_dataset_rest_api_field_validation_get_options($node, $field_name, $info);

// Check that the values match the options.
if (!empty($options) && is_array($options)) {
_dkan_dataset_rest_api_field_validation_check_field_values_against_options($field_name, $node->{$field_name}, $options);
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions modules/dkan/dkan_dataset/tests/dkan_dataset_test.info
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name = DKAN Dataset test module
description = Functionality to assist DKAN Dataset testing.
core = 7.x
dependencies[] = dkan_dataset
dependencies[] = dkan_dataset_rest_api
hidden = TRUE
16 changes: 16 additions & 0 deletions modules/dkan/dkan_dataset/tests/dkan_dataset_test.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/**
* @file
* Test module for DKAN Dataset and child modules.
*/

function dkan_dataset_test_dkan_dataset_rest_api_field_validate_alter(&$handlers) {
$handlers[] = 'dkan_dataset_test_validation_handler';
}

function dkan_dataset_test_validation_handler(&$node, $field_name, $info) {
if ($field_name == "body" && $node->body['und'][0]['value'] == "PHPUNIT Test Dataset Custom Validation") {
throw new Exception("Test validation rejection");
}
}
32 changes: 32 additions & 0 deletions test/phpunit/dkan_dataset/ApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ public function __construct($name = NULL, array $data = [], $dataName = '') {
$this->client->login('admin', 'admin');
}

/**
* {@inheritdoc}
*/
public static function setUpBeforeClass() {
// We need this module for the testResourceRedirect test.
module_enable(array('dkan_dataset_test'));
}

/**
* Test required fields.
*/
Expand Down Expand Up @@ -55,4 +63,28 @@ public function testOptions() {
}
}

/**
* Test options.
*/
public function testCustomValidation() {
try {
$this->client->nodeCreate((object) [
'title' => 'PHPUNIT Custom Validation',
'body' => ['und' => [0 => ['value => "PHPUNIT Test Dataset Custom Validation"']]],
'type' => 'dataset',
]);
}
catch (\Exception $e) {
$message = $e->getMessage();
$this->assertContains("Test validation rejection", $message);
}
}

/**
* {@inheritdoc}
*/
public static function tearDownAfterClass() {
// Clean enabled modules.
module_disable(array('dkan_dataset_test'));
}
}

0 comments on commit be50cdb

Please sign in to comment.