1 <?php
2
3 /**
4 * ArangoDB PHP client: single document
5 *
6 * @package triagens\ArangoDb
7 * @author Jan Steemann
8 * @author Florian Bartels
9 * @copyright Copyright 2014, triagens GmbH, Cologne, Germany
10 *
11 * @since 1.2
12 */
13
14 namespace triagens\ArangoDb;
15
16 /**
17 * Value object representing a graph
18 *
19 * <br>
20 *
21 * @package triagens\ArangoDb
22 * @since 1.2
23 */
24 class Graph extends
25 Document
26 {
27 /**
28 * Graph edge definitions
29 */
30 const ENTRY_EDGE_DEFINITIONS = 'edgeDefinitions';
31
32 /**
33 * Graph edge definitions from collections
34 */
35 const ENTRY_FROM = 'from';
36
37 /**
38 * Graph edge definitions to collections
39 */
40 const ENTRY_TO = 'to';
41
42 /**
43 * Graph edge definitions collections
44 */
45 const ENTRY_COLLECTION = 'collection';
46
47 /**
48 * Graph orphan collections
49 */
50 const ENTRY_ORPHAN_COLLECTIONS = 'orphanCollections';
51
52 /**
53 * The list of edge definitions defining the graph.
54 *
55 * @var EdgeDefinition[] list of edge definitions.
56 */
57 protected $_edgeDefinitions = [];
58
59 /**
60 * The list of orphan collections defining the graph.
61 * These collections are not used in any edge definition of the graph.
62 *
63 * @var array list of orphan collections.
64 */
65 protected $_orphanCollections = [];
66
67
68 /**
69 * Constructs an empty graph
70 *
71 * @param array $name - optional, initial name for graph
72 * @param array $options - optional, initial options for graph
73 *
74 * @since 1.2
75 *
76 * @throws \triagens\ArangoDb\ClientException
77 */
78 public function __construct($name = null, array $options = [])
79 {
80
81 // prevent backwards compatibility break where the first parameter is the $options array
82 if (!is_array($name) && $name !== null) {
83 $this->set('_key', $name);
84 }
85
86 // pass the $options to the parent constructor to do the actual work
87 parent::__construct($options);
88 }
89
90
91 /**
92 * Adds an edge definition to the graph.
93 *
94 * @param EdgeDefinition $edgeDefinition - the edge Definition.
95 *
96 * @return Graph
97 * @since 2.2
98 */
99 public function addEdgeDefinition(EdgeDefinition $edgeDefinition)
100 {
101 $this->_edgeDefinitions[] = $edgeDefinition;
102
103 return $this;
104 }
105
106 /**
107 * Get the edge definitions of the graph.
108 *
109 * @return EdgeDefinition[]
110 * @since 2.2
111 */
112 public function getEdgeDefinitions()
113 {
114 return $this->_edgeDefinitions;
115 }
116
117
118 /**
119 * Adds an orphan collection to the graph.
120 *
121 * @param string $orphanCollection - the orphan collection.
122 *
123 * @return Graph
124 * @since 2.2
125 */
126 public function addOrphanCollection($orphanCollection)
127 {
128 $this->_orphanCollections[] = $orphanCollection;
129
130 return $this;
131 }
132
133 /**
134 * Get the orphan collections of the graph.
135 *
136 * @return string[]
137 * @since 2.2
138 */
139 public function getOrphanCollections()
140 {
141 return $this->_orphanCollections;
142 }
143
144
145 /**
146 * Set a graph attribute
147 *
148 * The key (attribute name) must be a string.
149 * This will validate the value of the attribute and might throw an
150 * exception if the value is invalid.
151 *
152 * @throws ClientException
153 *
154 * @param string $key - attribute name
155 * @param mixed $value - value for attribute
156 *
157 * @return void
158 */
159 public function set($key, $value)
160 {
161 if ($key === self::ENTRY_EDGE_DEFINITIONS) {
162 if ($this->_doValidate) {
163 ValueValidator::validate($value);
164 }
165
166 foreach ($value as $ed) {
167 $edgeDefinition = new EdgeDefinition();
168 foreach ($ed[self::ENTRY_FROM] as $from) {
169 $edgeDefinition->addFromCollection($from);
170 }
171 foreach ($ed[self::ENTRY_TO] as $to) {
172 $edgeDefinition->addToCollection($to);
173 }
174 $edgeDefinition->setRelation($ed[self::ENTRY_COLLECTION]);
175 $this->addEdgeDefinition($edgeDefinition);
176 }
177 } else if ($key === self::ENTRY_ORPHAN_COLLECTIONS) {
178 if ($this->_doValidate) {
179 ValueValidator::validate($value);
180 }
181
182 foreach ($value as $o) {
183 $this->addOrphanCollection($o);
184 }
185 } else {
186 parent::set($key, $value);
187 }
188 }
189
190 /**
191 * returns (or creates) the edge definition for single-vertexcollection-undirected graphs, throw an exception for any other type of graph.
192 *
193 * @throws ClientException
194 * @return EdgeDefinition
195 */
196 private function getSingleUndirectedRelation()
197 {
198 $ed = $this->getEdgeDefinitions();
199 if (count($ed) > 0) {
200 $a = $ed[0];
201 $b = $a->getFromCollections();
202 $c = $a->getToCollections();
203 }
204 if (count($ed) > 1 ||
205 (
206 count($ed) === 1 && (
207 count($a->getFromCollections()) > 1 ||
208 count($a->getToCollections()) > 1 ||
209 $b[0] !== $c[0]
210
211 )
212 )
213 ) {
214 throw new ClientException('This operation only supports graphs with one undirected single collection relation');
215 }
216 if (count($ed) === 1) {
217 $eD = $ed[0];
218 $this->_edgeDefinitions = [];
219 } else {
220 $eD = new EdgeDefinition();
221 }
222
223 return $eD;
224 }
225
226 }
227