DojoNodeSerializer.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2020 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
11 namespace wcmf\lib\model\impl;
12 
20 
21 /**
22  * DojoNodeSerializer is used to serialize Nodes into the Dojo rest format and
23  * vice versa. The format of serialized Nodes is defined in the Dojo documentation (See:
24  * http://dojotoolkit.org/reference-guide/1.10/quickstart/rest.html)
25  *
26  * @author ingo herwig <ingo@wemove.com>
27  */
29 
30  /**
31  * @see NodeSerializer::isSerializedNode
32  */
33  public function isSerializedNode($data) {
34  if (is_object($data)) {
35  $data = (array)$data;
36  }
37  $syntaxOk = (is_array($data) && (isset($data['oid'])));
38  // check for oid variables
39  if ($syntaxOk && isset($data['oid']) && preg_match('/^\{.+\}$/', $data['oid'])) {
40  $syntaxOk = false;
41  }
42  return $syntaxOk;
43  }
44 
45  /**
46  * @see NodeSerializer::deserializeNode
47  */
48  public function deserializeNode($data, Node $parent=null, $role=null) {
49  if (!isset($data['oid'])) {
50  throw new IllegalArgumentException("Serialized Node data must contain an 'oid' parameter");
51  }
52  $oid = ObjectId::parse($data['oid']);
53  if ($oid == null) {
54  throw new IllegalArgumentException("The object id '".$oid."' is invalid");
55  }
56 
57  // create request node
58  $node = $this->getNodeTemplate($oid);
59  $remainingData = [];
60  $mapper = $node->getMapper();
61  foreach($data as $key => $value) {
62  if ($mapper->hasAttribute($key)) {
63  $this->deserializeValue($node, $key, $value);
64  }
65  else {
66  $remainingData[$key] = $value;
67  }
68  }
69 
70  // set oid after attributes in order to
71  // avoid it being changed from missing pk values
72  $node->setOID($oid);
73 
74  // create hierarchy
75  if ($parent != null) {
76  $parent->addNode($node, $role);
77  }
78 
79  return ['node' => $node, 'data' => $remainingData];
80  }
81 
82  /**
83  * @see NodeSerializer::serializeNode
84  */
85  public function serializeNode($node, $rolesToRefOnly=[], $serializedOids=[]) {
86  if (!($node instanceof Node)) {
87  return null;
88  }
89  $oid = $node->getOID()->__toString();
90  if (!in_array($oid, $serializedOids)) {
91  $curResult = [];
92  $curResult['oid'] = $oid;
93 
94  // serialize attributes
95  // use NodeValueIterator to iterate over all Node values
96  $valueIter = new NodeValueIterator($node, false);
97  foreach($valueIter as $valueName => $value) {
98  $curResult[$valueName] = $value;
99  }
100 
101  $serializedOids[] = $curResult['oid'];
102 
103  // add related objects by creating an attribute that is named as the role of the object
104  // multivalued relations will be serialized into an array
105  $mapper = $node->getMapper();
106  foreach ($mapper->getRelations() as $relation) {
107  $role = $relation->getOtherRole();
108  $relatedNodes = $node->getValue($role);
109  if ($relatedNodes) {
110  // serialize the nodes
111  $isMultiValued = $relation->isMultiValued();
112  if ($isMultiValued) {
113  $curResult[$role] = [];
114  foreach ($relatedNodes as $relatedNode) {
115  if ($relatedNode instanceof PersistentObjectProxy || in_array($role, $rolesToRefOnly)) {
116  // add the reference to the relation attribute
117  $curResult[$role][] = ['$ref' => $relatedNode->getOID()->__toString()];
118  }
119  else {
120  $curResult[$role][] = $this->serializeNode($relatedNode, [$relation->getThisRole()], $serializedOids);
121  }
122  }
123  }
124  else {
125  $relatedNode = $relatedNodes;
126  if ($relatedNode instanceof PersistentObjectProxy || in_array($role, $rolesToRefOnly)) {
127  // add the reference to the relation attribute
128  $curResult[$role] = ['$ref' => $relatedNode->getOID()->__toString()];
129  }
130  else {
131  $curResult[$role] = $this->serializeNode($relatedNode, [$relation->getThisRole()], $serializedOids);
132  }
133  }
134  }
135  }
136  }
137  else {
138  // only add a reference for already serialized nodes to prevent recursion
139  $curResult = ['ref' => $oid];
140  }
141  return $curResult;
142  }
143 }
144 ?>
deserializeNode($data, Node $parent=null, $role=null)
NodeSerializer implementations are used to serialize Nodes into an array representation or deserializ...
NodeValueIterator is used to iterate over all persistent values of a Node (not including relations).
IllegalArgumentException signals an exception in method arguments.
deserializeValue(Node $node, $key, $value)
Deserialize a node value.
ObjectId is the unique identifier of an object.
Definition: ObjectId.php:28
static parse($oid)
Parse a serialized object id string into an ObjectId instance.
Definition: ObjectId.php:135
getNodeTemplate($oid)
Get a Node instance based on the original values to merge the deserialized values into.
NodeSerializerBase is a base class for NodeSerialize implementations.
Node adds the concept of relations to PersistentObject.
Definition: Node.php:34
PersistentObjectProxy is proxy for an PersistentObject instance.
serializeNode($node, $rolesToRefOnly=[], $serializedOids=[])
DojoNodeSerializer is used to serialize Nodes into the Dojo rest format and vice versa.