Skip to content

Correctly set type and serialize correct value for References #101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 16, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ dev-master
### Bug fixes

- [mixin] Node mxin remove does not accept a path
- [node:edit] Cannot edit nodes with multivalue References

### Enhancements

Expand Down
16 changes: 16 additions & 0 deletions features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,22 @@ public function theNodeAtShouldHaveThePropertyWithValueAtIndex($arg1, $arg2, $ar
PHPUnit_Framework_Assert::assertEquals($arg3, $propertyType[$index]);
}

/**
* @Given /^the property "([^"]*)" should have type "([^"]*)"$/
*/
public function thePropertyShouldHaveType($arg1, $arg2)
{
$session = $this->getSession();
$property = $session->getItem($arg1);
if (!$property instanceof PropertyInterface) {
throw new \InvalidArgumentException(sprintf(
'Item at "%s" is not a property', $arg1
));
}

PHPUnit_Framework_Assert::assertEquals($arg2, PropertyType::nameFromValue($property->getType()));
}


/**
* @Given /^the property "([^"]*)" should have type "([^"]*)" and value "([^"]*)"$/
Expand Down
26 changes: 26 additions & 0 deletions features/fixtures/cms.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
<sv:value>two</sv:value>
<sv:value>three</sv:value>
</sv:property>
<sv:property sv:name="articles" sv:type="Reference" multiple="true">
<sv:value>66666fc6-1abf-4708-bfcc-e49511754b40</sv:value>
<sv:value>77777777-1abf-4708-bfcc-e49511754b40</sv:value>
</sv:property>
</sv:node>
</sv:node>

Expand Down Expand Up @@ -87,6 +91,28 @@
<sv:value>Planes</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="article2">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>nt:unstructured</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>77777777-1abf-4708-bfcc-e49511754b40</sv:value>
</sv:property>
<sv:property sv:name="title" sv:type="String">
<sv:value>Article 1</sv:value>
</sv:property>
<sv:property sv:name="tags" sv:type="String" sv:multiple="true">
<sv:value>Planes</sv:value>
<sv:value>Trains</sv:value>
<sv:value>Automobiles</sv:value>
</sv:property>
<sv:property sv:name="tag" sv:type="String" sv:multiple="true">
<sv:value>Planes</sv:value>
</sv:property>
</sv:node>
</sv:node>
</sv:node>

Expand Down
30 changes: 29 additions & 1 deletion features/phpcr_node_edit.feature
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,20 @@ Feature: Edit a node
tags:
type: String
value: [one, two, three]
articles:
type: Reference
value: [ 66666fc6-1abf-4708-bfcc-e49511754b40, 77777777-1abf-4708-bfcc-e49511754b40 ]
'jcr:primaryType':
type: Name
value: 'nt:unstructured'
"""
And I execute the "node:edit cms/products/product1" command
And I execute the "node:edit cms/products/product1 --no-interaction" command
Then the command should not fail
And the property "/cms/products/product1/weight" should have type "Long" and value "10"
And the property "/cms/products/product1/cost" should have type "Double" and value "12.13"
And the property "/cms/products/product1/size" should have type "String" and value "XL"
And the property "/cms/products/product1/name" should have type "String" and value "Product One"
And the property "/cms/products/product1/articles" should have type "Reference"
And the property "/cms/products/product1/jcr:primaryType" should have type "Name" and value "nt:unstructured"

Scenario: Remove some properties
Expand Down Expand Up @@ -171,3 +175,27 @@ Feature: Edit a node
And I save the session
Then the command should not fail
And the property "/cms/articles/article1/foobar" should have type "String" and value "FOOOOOOO"

Scenario: Change a property type (cost from Double to Long
Given I have an editor which produces the following:
""""
cost:
type: Long
value: 100
weight:
type: String
value: 10
size:
value: 10
'jcr:primaryType':
type: Name
value: 'nt:unstructured'
"""
And I execute the "node:edit cms/products/product1" command
Then the command should not fail
And I save the session
Then the command should not fail
And the property "/cms/products/product1/cost" should have type "Long" and value "100"
And the property "/cms/products/product1/weight" should have type "String" and value "10"
And the property "/cms/products/product1/size" should have type "Long" and value "10"

6 changes: 3 additions & 3 deletions features/phpcr_query_delete.feature
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ Feature: Execute a a raw DELETE query in JCR_SQL2
"""
Examples:
| query | path |
| DELETE FROM [nt:unstructured] AS a WHERE localname() = 'article1' | /cms/articles/article1 |
| delete FROM [nt:unstructured] as a where localname() = 'article1' | /cms/articles/article1 |
| DELETE FROM nt:unstructured AS a WHERE localname() = 'article1' | /cms/articles/article1 |
| DELETE FROM [nt:unstructured] AS a WHERE localname() = 'product1' | /cms/products/product1 |
| delete FROM [nt:unstructured] as a where localname() = 'product1' | /cms/products/product1 |
| DELETE FROM nt:unstructured AS a WHERE localname() = 'product1' | /cms/products/product1 |
2 changes: 1 addition & 1 deletion features/phpcr_query_update.feature
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ Feature: Execute a a raw UPDATE query in JCR_SQL2
Then the command should not fail
And I should see the following:
"""
1 row(s) affected
2 row(s) affected
"""
And the node at "/cms/articles/article1" should have the property "tag" with value "Rockets" at index "0"
30 changes: 16 additions & 14 deletions src/PHPCR/Shell/Serializer/NodeNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,14 @@ public function normalize($node, $format = null, array $context = array())
}

$propertyType = $property->getType();

$propertyValue = $property->getValue();
$propertyName = $property->getName();

if (in_array($property->getType(), array(PropertyType::REFERENCE, PropertyType::WEAKREFERENCE))) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any other properties that will need a similar approach here?

i.e. REFERENCES have an associative array of UUID => Object, and we want to expose the UUID.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BINARY is another candidate for special treatment. not sure but i think value would be stream in this case, but you probably want to output something like "binary data (302882 Bytes)"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Binary properties are already filtered, but I like the idea of having a read-only representation.

$propertyValue = array_keys($propertyValue);
}

$res[$propertyName] = array(
'type' => PropertyType::nameFromValue($propertyType),
'value' => $propertyValue
Expand Down Expand Up @@ -97,22 +102,19 @@ public function denormalize($data, $class, $format = null, array $context = arra
}

$datum = $this->normalizeDatum($data[$property->getName()]);
$typeValue = isset($datum['type']) ? PropertyType::valueFromName($datum['type']) : null;

if (isset($datum['type'])) {
$typeName = $datum['type'];
if (isset($datum['value'])) {

if ($datum['type'] != $typeName) {
throw new \InvalidArgumentException(sprintf(
'Cannot currently change a properties type for property "%s" (trying to change from "%s" to "%s")',
$property->getPath(),
$typeName, $datum['type']
));
}
}
// if the type or the value is differnet, update the property
if ($datum['value'] != $property->getValue() || $typeValue != $property->getType()) {

if (isset($datum['value'])) {
if ($datum['value'] != $property->getValue()) {
$property->setValue($datum['value']);
// setValue doesn't like being passed a null value as a type ...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could translate that to PropertyType::UNDEFINED. but your approach is just as well. PR seems good to me, go ahead and merge.

if ($typeValue !== null) {
$property->setValue($datum['value'], $typeValue);
} else {
$property->setValue($datum['value']);
}
}
}
} catch (\Exception $e) {
Expand Down Expand Up @@ -162,7 +164,7 @@ private function normalizeDatum($value)
if (is_scalar($value)) {
return array(
'value' => $value,
'type' => 'String'
'type' => null
);
}

Expand Down