Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
3f4d8bc4
Commit
3f4d8bc4
authored
Dec 19, 2012
by
Dries
Browse files
Issue
#1826688
by klausi | mitchell: Added REST module: PATCH/update.
parent
63fa77ec
Changes
8
Hide whitespace changes
Inline
Side-by-side
core/lib/Drupal/Core/Entity/EntityNG.php
View file @
3f4d8bc4
...
...
@@ -368,7 +368,7 @@ public function __isset($name) {
return
isset
(
$this
->
values
[
$name
]);
}
elseif
(
$this
->
getPropertyDefinition
(
$name
))
{
return
(
bool
)
count
(
$this
->
get
(
$name
));
return
$this
->
get
(
$name
)
->
valueIsSet
(
);
}
}
...
...
@@ -380,7 +380,7 @@ public function __unset($name) {
unset
(
$this
->
values
[
$name
]);
}
elseif
(
$this
->
getPropertyDefinition
(
$name
))
{
$this
->
get
(
$name
)
->
setValue
(
array
()
);
$this
->
get
(
$name
)
->
un
setValue
();
}
}
...
...
core/lib/Drupal/Core/Entity/Field/Type/Field.php
View file @
3f4d8bc4
...
...
@@ -50,6 +50,13 @@ class Field extends TypedData implements IteratorAggregate, FieldInterface {
*/
protected
$list
=
array
();
/**
* Flag to indicate if this field has been set.
*
* @var bool
*/
protected
$isset
=
FALSE
;
/**
* Implements TypedDataInterface::getValue().
*/
...
...
@@ -68,6 +75,7 @@ public function getValue() {
* An array of values of the field items.
*/
public
function
setValue
(
$values
)
{
$this
->
isset
=
TRUE
;
if
(
isset
(
$values
)
&&
$values
!==
array
())
{
// Support passing in only the value of the first item.
if
(
!
is_array
(
$values
)
||
!
is_numeric
(
current
(
array_keys
(
$values
))))
{
...
...
@@ -100,6 +108,14 @@ public function setValue($values) {
}
}
/**
* Mark this field as not set.
*/
public
function
unsetValue
()
{
$this
->
list
=
array
();
$this
->
isset
=
FALSE
;
}
/**
* Returns a string representation of the field.
*
...
...
@@ -256,13 +272,14 @@ public function get($property_name) {
*/
public
function
__set
(
$property_name
,
$value
)
{
$this
->
offsetGet
(
0
)
->
__set
(
$property_name
,
$value
);
$this
->
isset
=
TRUE
;
}
/**
* Delegate.
*/
public
function
__isset
(
$property_name
)
{
return
$this
->
offsetGet
(
0
)
->
__isset
(
$property_name
);
return
$this
->
isset
&&
$this
->
offsetGet
(
0
)
->
__isset
(
$property_name
);
}
/**
...
...
@@ -284,6 +301,15 @@ public function isEmpty() {
return
TRUE
;
}
/**
* Determines if this field has been set.
*
* @return bool
*/
public
function
valueIsSet
()
{
return
$this
->
isset
;
}
/**
* Implements a deep clone.
*/
...
...
core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityNormalizer.php
View file @
3f4d8bc4
...
...
@@ -79,11 +79,17 @@ public function denormalize($data, $class, $format = null) {
if
(
$fieldName
[
0
]
===
'@'
)
{
continue
;
}
// If the incoming value is an empty array we set the property to mark it
// for deletion.
if
(
empty
(
$incomingFieldValues
)
&&
is_array
(
$incomingFieldValues
))
{
$entity
->
{
$fieldName
}
=
array
();
}
// Figure out the designated class for this field type, which is used by
// the Serializer to determine which Denormalizer to use.
// @todo Is there a better way to get the field type's associated class?
$fieldItemClass
=
get_class
(
$entity
->
get
(
$fieldName
)
->
offsetGet
(
0
));
// Iterate through the language keyed values and add them to the entity.
// The vnd.drupal.ld+json mime type will always use language keys, per
// http://drupal.org/node/1838700.
...
...
core/modules/rest/lib/Drupal/rest/Plugin/rest/resource/EntityResource.php
View file @
3f4d8bc4
...
...
@@ -85,6 +85,49 @@ public function post($id, EntityInterface $entity) {
}
}
/**
* Responds to entity PATCH requests.
*
* @param mixed $id
* The entity ID.
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity.
*
* @return \Drupal\rest\ResourceResponse
* The HTTP response object.
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*/
public
function
patch
(
$id
,
EntityInterface
$entity
)
{
if
(
empty
(
$id
))
{
throw
new
NotFoundHttpException
();
}
$definition
=
$this
->
getDefinition
();
if
(
$entity
->
entityType
()
!=
$definition
[
'entity_type'
])
{
throw
new
BadRequestHttpException
(
'Invalid entity type'
);
}
$original_entity
=
entity_load
(
$definition
[
'entity_type'
],
$id
);
// We don't support creating entities with PATCH, so we throw an error if
// there is no existing entity.
if
(
$original_entity
==
FALSE
)
{
throw
new
NotFoundHttpException
();
}
// Overwrite the received properties.
foreach
(
$entity
->
getProperties
()
as
$name
=>
$property
)
{
if
(
isset
(
$entity
->
{
$name
}))
{
$original_entity
->
{
$name
}
=
$property
;
}
}
try
{
$original_entity
->
save
();
// Update responses have an empty body.
return
new
ResourceResponse
(
NULL
,
204
);
}
catch
(
EntityStorageException
$e
)
{
throw
new
HttpException
(
500
,
'Internal Server Error'
,
$e
);
}
}
/**
* Responds to entity DELETE requests.
*
...
...
core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php
View file @
3f4d8bc4
...
...
@@ -48,7 +48,7 @@ public function testCreate() {
$entity
=
entity_create
(
$entity_type
,
$entity_values
);
$serialized
=
$serializer
->
serialize
(
$entity
,
'drupal_jsonld'
);
// Create the entity over the web API.
$response
=
$this
->
httpRequest
(
'entity/'
.
$entity_type
,
'POST'
,
$serialized
,
'application/vnd.drupal.ld+json'
);
$this
->
httpRequest
(
'entity/'
.
$entity_type
,
'POST'
,
$serialized
,
'application/vnd.drupal.ld+json'
);
$this
->
assertResponse
(
'201'
,
'HTTP response code is correct.'
);
// Get the new entity ID from the location header and try to read it from
...
...
@@ -63,13 +63,14 @@ public function testCreate() {
// entity references is implemented.
unset
(
$entity_values
[
'user_id'
]);
foreach
(
$entity_values
as
$property
=>
$value
)
{
$actual_value
=
$loaded_entity
->
get
(
$property
);
$this
->
assertEqual
(
$value
,
$actual_value
->
value
,
'Created property '
.
$property
.
' expected: '
.
$value
.
', actual: '
.
$actual_value
->
value
);
$actual_value
=
$loaded_entity
->
get
(
$property
)
->
value
;
$send_value
=
$entity
->
get
(
$property
)
->
value
;
$this
->
assertEqual
(
$send_value
,
$actual_value
,
'Created property '
.
$property
.
' expected: '
.
$send_value
.
', actual: '
.
$actual_value
);
}
// Try to create an entity without proper permissions.
$this
->
drupalLogout
();
$response
=
$this
->
httpRequest
(
'entity/'
.
$entity_type
,
'POST'
,
$serialized
,
'application/vnd.drupal.ld+json'
);
$this
->
httpRequest
(
'entity/'
.
$entity_type
,
'POST'
,
$serialized
,
'application/vnd.drupal.ld+json'
);
$this
->
assertResponse
(
403
);
// Try to create a resource which is not web API enabled.
...
...
core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php
View file @
3f4d8bc4
...
...
@@ -68,6 +68,17 @@ protected function httpRequest($url, $method, $body = NULL, $format = 'applicati
);
break
;
case
'PATCH'
:
$curl_options
=
array
(
CURLOPT_HTTPGET
=>
FALSE
,
CURLOPT_CUSTOMREQUEST
=>
'PATCH'
,
CURLOPT_POSTFIELDS
=>
$body
,
CURLOPT_URL
=>
url
(
$url
,
array
(
'absolute'
=>
TRUE
)),
CURLOPT_NOBODY
=>
FALSE
,
CURLOPT_HTTPHEADER
=>
array
(
'Content-Type: '
.
$format
),
);
break
;
case
'DELETE'
:
$curl_options
=
array
(
CURLOPT_HTTPGET
=>
FALSE
,
...
...
@@ -127,7 +138,11 @@ protected function entityCreate($entity_type) {
protected
function
entityValues
(
$entity_type
)
{
switch
(
$entity_type
)
{
case
'entity_test'
:
return
array
(
'name'
=>
$this
->
randomName
(),
'user_id'
=>
1
);
return
array
(
'name'
=>
$this
->
randomName
(),
'user_id'
=>
1
,
'field_test_text'
=>
array
(
0
=>
array
(
'value'
=>
$this
->
randomString
())),
);
case
'node'
:
return
array
(
'title'
=>
$this
->
randomString
());
case
'user'
:
...
...
core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php
0 → 100644
View file @
3f4d8bc4
<?php
/**
* @file
* Contains Drupal\rest\test\UpdateTest.
*/
namespace
Drupal\rest\Tests
;
use
Drupal\rest\Tests\RESTTestBase
;
/**
* Tests resource updates on test entities.
*/
class
UpdateTest
extends
RESTTestBase
{
/**
* Modules to enable.
*
* @var array
*/
public
static
$modules
=
array
(
'rest'
,
'entity_test'
);
public
static
function
getInfo
()
{
return
array
(
'name'
=>
'Update resource'
,
'description'
=>
'Tests the update of resources.'
,
'group'
=>
'REST'
,
);
}
/**
* Tests several valid and invalid partial update requests on test entities.
*/
public
function
testPatchUpdate
()
{
$serializer
=
drupal_container
()
->
get
(
'serializer'
);
// @todo once EntityNG is implemented for other entity types test all other
// entity types here as well.
$entity_type
=
'entity_test'
;
$this
->
enableService
(
'entity:'
.
$entity_type
);
// Create a user account that has the required permissions to create
// resources via the web API.
$account
=
$this
->
drupalCreateUser
(
array
(
'restful patch entity:'
.
$entity_type
));
$this
->
drupalLogin
(
$account
);
// Create an entity and save it to the database.
$entity
=
$this
->
entityCreate
(
$entity_type
);
$entity
->
save
();
// Create a second stub entity for overwriting a field.
$patch_values
[
'field_test_text'
]
=
array
(
0
=>
array
(
'value'
=>
$this
->
randomString
()));
$patch_entity
=
entity_create
(
$entity_type
,
$patch_values
);
// We don't want to overwrite the UUID.
unset
(
$patch_entity
->
uuid
);
$serialized
=
$serializer
->
serialize
(
$patch_entity
,
'drupal_jsonld'
);
// Update the entity over the web API.
$this
->
httpRequest
(
'entity/'
.
$entity_type
.
'/'
.
$entity
->
id
(),
'PATCH'
,
$serialized
,
'application/vnd.drupal.ld+json'
);
$this
->
assertResponse
(
204
);
// Re-load updated entity from the database.
$entity
=
entity_load
(
$entity_type
,
$entity
->
id
(),
TRUE
);
$this
->
assertEqual
(
$entity
->
field_test_text
->
value
,
$patch_entity
->
field_test_text
->
value
,
'Field was successfully updated.'
);
// Try to empty a field.
$normalized
=
$serializer
->
normalize
(
$patch_entity
,
'drupal_jsonld'
);
$normalized
[
'field_test_text'
]
=
array
();
$serialized
=
$serializer
->
encode
(
$normalized
,
'jsonld'
);
// Update the entity over the web API.
$this
->
httpRequest
(
'entity/'
.
$entity_type
.
'/'
.
$entity
->
id
(),
'PATCH'
,
$serialized
,
'application/vnd.drupal.ld+json'
);
$this
->
assertResponse
(
204
);
// Re-load updated entity from the database.
$entity
=
entity_load
(
$entity_type
,
$entity
->
id
(),
TRUE
);
$this
->
assertNull
(
$entity
->
field_test_text
->
value
,
'Test field has been cleared.'
);
// Try to update a non-existing entity with ID 9999.
$this
->
httpRequest
(
'entity/'
.
$entity_type
.
'/9999'
,
'PATCH'
,
$serialized
,
'application/vnd.drupal.ld+json'
);
$this
->
assertResponse
(
404
);
$loaded_entity
=
entity_load
(
$entity_type
,
9999
,
TRUE
);
$this
->
assertFalse
(
$loaded_entity
,
'Entity 9999 was not created.'
);
// Try to update an entity without proper permissions.
$this
->
drupalLogout
();
$this
->
httpRequest
(
'entity/'
.
$entity_type
.
'/'
.
$entity
->
id
(),
'PATCH'
,
$serialized
,
'application/vnd.drupal.ld+json'
);
$this
->
assertResponse
(
403
);
// Try to update a resource which is not web API enabled.
$this
->
enableService
(
FALSE
);
// Reset cURL here because it is confused from our previously used cURL
// options.
unset
(
$this
->
curlHandle
);
$this
->
drupalLogin
(
$account
);
$this
->
httpRequest
(
'entity/'
.
$entity_type
.
'/'
.
$entity
->
id
(),
'PATCH'
,
$serialized
,
'application/vnd.drupal.ld+json'
);
$this
->
assertResponse
(
404
);
}
}
core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php
View file @
3f4d8bc4
...
...
@@ -128,6 +128,12 @@ public function testReadWrite() {
$this
->
assertFalse
(
isset
(
$entity
->
name
[
0
]
->
value
),
'Name is not set.'
);
$this
->
assertFalse
(
isset
(
$entity
->
name
->
value
),
'Name is not set.'
);
$entity
->
name
=
array
();
$this
->
assertTrue
(
isset
(
$entity
->
name
),
'Name field is set.'
);
$this
->
assertFalse
(
isset
(
$entity
->
name
[
0
]),
'Name field item is not set.'
);
$this
->
assertFalse
(
isset
(
$entity
->
name
[
0
]
->
value
),
'First name item value is not set.'
);
$this
->
assertFalse
(
isset
(
$entity
->
name
->
value
),
'Name value is not set.'
);
$entity
->
name
->
value
=
'a value'
;
$this
->
assertTrue
(
isset
(
$entity
->
name
->
value
),
'Name is set.'
);
unset
(
$entity
->
name
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment