HierarchicalFormat.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  */
12 
18 
19 /**
20  * HierarchicalFormat is used as base class for formats that
21  * are able to represent hierarchical data like JSON or XML. This format
22  * automatically iterates over data when de-/serializing and uses template
23  * methods to implement the specific format.
24  *
25  * @author ingo herwig <ingo@wemove.com>
26  */
27 abstract class HierarchicalFormat extends AbstractFormat {
28 
29  /**
30  * @see AbstractFormat::deserializeValues()
31  */
32  protected function deserializeValues(Request $request) {
33  return $this->deserializeHierarchy($request->getValues());
34  }
35 
36  /**
37  * @see AbstractFormat::serializeValues()
38  */
39  protected function serializeValues(Response $response) {
40  return $this->serializeHierarchy($response->getValues());
41  }
42 
43  /**
44  * Deserialize the given values recursively
45  * @param $values
46  * @return Array
47  */
48  private function deserializeHierarchy($values) {
49  if ($this->isSerializedNode($values)) {
50  // the values represent a node
51  $result = $this->deserializeNode($values);
52  $node = $result['node'];
53  $values = $result['data'];
54  $values[$node->getOID()->__toString()] = $node;
55  }
56  else {
57  foreach ($values as $key => $value) {
58  if (is_array($value) || is_object($value)) {
59  // array/object value
60  $result = $this->deserializeHierarchy($value);
61  // flatten the array, if the deserialization result is only an array
62  // with size 1 and the key is an oid (e.g. if a node was deserialized)
63  if (is_array($result) && sizeof($result) == 1 && ObjectId::isValid(key($result))) {
64  unset($values[$key]);
65  $values[key($result)] = current($result);
66  }
67  else {
68  $values[$key] = $result;
69  }
70  }
71  else {
72  // string value
73  $values[$key] = $value;
74  }
75  }
76  }
77  return $values;
78  }
79 
80  /**
81  * Serialize the given values recursively
82  * @param $values
83  * @return Array
84  */
85  private function serializeHierarchy($values) {
86  if ($this->isDeserializedNode($values)) {
87  // the values represent a node
88  $values = $this->serializeNode($values);
89  }
90  else {
91  if (is_array($values) || ($values instanceof \Traversable)) {
92  foreach ($values as $key => $value) {
93  if ($value != null && !is_scalar($value)) {
94  // array/object value
95  $result = $this->serializeHierarchy($value);
96  if (ObjectId::isValid($key)) {
97  $values = $result;
98  }
99  else {
100  $values[$key] = $result;
101  }
102  }
103  else {
104  // string value
105  $values[$key] = $value;
106  }
107  }
108  }
109  }
110  return $values;
111  }
112 
113  /**
114  * Determine if the value is a serialized Node. The default
115  * implementation returns false.
116  * @param $value The data value
117  * @return Boolean
118  * @note Subclasses override this if necessary
119  */
120  protected function isSerializedNode($value) {
121  return false;
122  }
123 
124  /**
125  * Determine if the value is a deserialized Node. The default
126  * implementation checks if the value is an object of type Node.
127  * @param $value The data value
128  * @return Boolean
129  * @note Subclasses override this if necessary
130  */
131  protected function isDeserializedNode($value) {
132  return ($value instanceof Node);
133  }
134 
135  /**
136  * Serialize a Node
137  * @param $value The data value
138  * @return The serialized Node
139  */
140  protected abstract function serializeNode($value);
141 
142  /**
143  * Deserialize a Node
144  * @param $value The data value
145  * @return An array with keys 'node' and 'data' where the node
146  * value is the Node instance and the data value is the
147  * remaining part of data, that is not used for deserializing the Node
148  */
149  protected abstract function deserializeNode($value);
150 }
151 ?>
Response holds the response values that are used as output from Controller instances.
Definition: Response.php:20
Request holds the request values that are used as input to Controller instances.
Definition: Request.php:18
isDeserializedNode($value)
Determine if the value is a deserialized Node.
getValues()
Get all key value pairs.
isSerializedNode($value)
Determine if the value is a serialized Node.
ObjectId is the unique identifier of an object.
Definition: ObjectId.php:28
HierarchicalFormat is used as base class for formats that are able to represent hierarchical data lik...
Node adds the concept of relations to PersistentObject.
Definition: Node.php:34
static isValid($oid)
Check if a serialized ObjectId has a valid syntax, the type is known and if the number of primary key...
Definition: ObjectId.php:123
AbstractFormat is used as base class for specialized formats.