1 <?php
2
3 /**
4 * ArangoDB PHP client: document handler
5 *
6 * @package triagens\ArangoDb
7 * @author Jan Steemann
8 * @author Frank Mayer
9 * @copyright Copyright 2012, triagens GmbH, Cologne, Germany
10 */
11
12 namespace triagens\ArangoDb;
13
14 /**
15 * A handler that manages edges
16 *
17 * An edge-document handler that fetches edges from the server and
18 * persists them on the server. It does so by issuing the
19 * appropriate HTTP requests to the server.
20 *
21 * @package triagens\ArangoDb
22 * @since 1.0
23 */
24 class EdgeHandler extends
25 DocumentHandler
26 {
27 /**
28 * documents array index
29 */
30 const ENTRY_DOCUMENTS = 'edge';
31
32 /**
33 * edges array index
34 */
35 const ENTRY_EDGES = 'edges';
36
37 /**
38 * collection parameter
39 */
40 const OPTION_COLLECTION = 'collection';
41
42 /**
43 * example parameter
44 */
45 const OPTION_EXAMPLE = 'example';
46
47 /**
48 * example parameter
49 */
50 const OPTION_FROM = 'from';
51
52 /**
53 * example parameter
54 */
55 const OPTION_TO = 'to';
56
57 /**
58 * vertex parameter
59 */
60 const OPTION_VERTEX = 'vertex';
61
62 /**
63 * direction parameter
64 */
65 const OPTION_DIRECTION = 'direction';
66
67 /**
68 * Intermediate function to call the createFromArray function from the right context
69 *
70 * @param $data
71 * @param $options
72 *
73 * @return Edge
74 * @throws \triagens\ArangoDb\ClientException
75 */
76 public function createFromArrayWithContext($data, $options)
77 {
78 return Edge::createFromArray($data, $options);
79 }
80
81
82 /**
83 * Just throw an exception if save() is called on edges.
84 *
85 * @internal
86 *
87 * @param mixed $collection - collection id as string or number
88 * @param Document $document - the document to be added
89 * @param array $options
90 *
91 * @return mixed|void
92 * @throws ClientException
93 *
94 * @see EdgeHandler::saveEdge()
95 *
96 */
97 public function save($collection, $document, array $options = [])
98 {
99 throw new ClientException("Edges don't have a save() method. Please use saveEdge()");
100 }
101
102
103 /**
104 * save an edge to an edge-collection
105 *
106 * This will save the edge to the collection and return the edges-document's id
107 *
108 * This will throw if the document cannot be saved
109 *
110 * @throws Exception
111 *
112 * @param mixed $collection - collection id as string or number
113 * @param mixed $from - from vertex
114 * @param mixed $to - to vertex
115 * @param mixed $document - the edge-document to be added, can be passed as an object or an array
116 * @param array $options - optional, array of options.
117 * <p>Options are :<br>
118 * <li>'createCollection' - create the collection if it does not yet exist.</li>
119 * <li>'waitForSync' - if set to true, then all removal operations will instantly be synchronised to disk.<br>
120 * If this is not specified, then the collection's default sync behavior will be applied.</li>
121 * </p>
122 *
123 * @return mixed - id of document created
124 * @since 1.0
125 */
126 public function saveEdge($collection, $from, $to, $document, array $options = [])
127 {
128 $collection = $this->makeCollection($collection);
129
130 if (is_array($document)) {
131 $document = Edge::createFromArray($document);
132 }
133 $document->setFrom($from);
134 $document->setTo($to);
135
136 $params = $this->includeOptionsInParams(
137 $options, [
138 'waitForSync' => $this->getConnectionOption(ConnectionOptions::OPTION_WAIT_SYNC),
139 'createCollection' => $this->getConnectionOption(ConnectionOptions::OPTION_CREATE)
140 ]
141 );
142
143 $this->createCollectionIfOptions($collection, $params);
144
145 $data = $document->getAllForInsertUpdate();
146
147 $url = UrlHelper::appendParamsUrl(Urls::URL_EDGE . '/' . $collection, $params);
148 $response = $this->getConnection()->post($url, $this->json_encode_wrapper($data));
149
150 $location = $response->getLocationHeader();
151 if (!$location) {
152 throw new ClientException('Did not find location header in server response');
153 }
154
155 $json = $response->getJson();
156 $id = UrlHelper::getDocumentIdFromLocation($location);
157
158 $document->setInternalId($json[Edge::ENTRY_ID]);
159 $document->setRevision($json[Edge::ENTRY_REV]);
160
161 if ($id !== $document->getId()) {
162 throw new ClientException('Got an invalid response from the server');
163 }
164
165 $document->setIsNew(false);
166
167 return $document->getId();
168 }
169
170
171 /**
172 * Get connected edges for a given vertex
173 *
174 * @throws Exception
175 *
176 * @param mixed $collection - edge-collection id as string or number
177 * @param mixed $vertexHandle - the vertex involved
178 * @param string $direction - optional defaults to 'any'. Other possible Values 'in' & 'out'
179 * @param array $options - optional, array of options
180 * <p>Options are :
181 * <li>'_includeInternals' - true to include the internal attributes. Defaults to false</li>
182 * <li>'_ignoreHiddenAttributes' - true to show hidden attributes. Defaults to false</li>
183 * </p>
184 *
185 * @return array - array of connected edges
186 * @since 1.0
187 */
188 public function edges($collection, $vertexHandle, $direction = 'any', array $options = [])
189 {
190 $collection = $this->makeCollection($collection);
191
192 $params = [
193 self::OPTION_VERTEX => $vertexHandle,
194 self::OPTION_DIRECTION => $direction
195 ];
196 $url = UrlHelper::appendParamsUrl(Urls::URL_EDGES . '/' . urlencode($collection), $params);
197 $response = $this->getConnection()->get($url);
198 $json = $response->getJson();
199
200 $edges = [];
201 foreach ($json[self::ENTRY_EDGES] as $data) {
202 $edges[] = $this->createFromArrayWithContext($data, $options);
203 }
204
205 return $edges;
206 }
207
208
209 /**
210 * Get connected inbound edges for a given vertex
211 *
212 * @throws Exception
213 *
214 * @param mixed $collection - edge-collection id as string or number
215 * @param mixed $vertexHandle - the vertex involved
216 *
217 * @return array - array of connected edges
218 */
219 public function inEdges($collection, $vertexHandle)
220 {
221 return $this->edges($collection, $vertexHandle, 'in');
222 }
223
224 /**
225 * Get connected outbound edges for a given vertex
226 *
227 * @throws Exception
228 *
229 * @param mixed $collection - edge-collection id as string or number
230 * @param mixed $vertexHandle - the vertex involved
231 *
232 * @return array - array of connected edges
233 */
234 public function outEdges($collection, $vertexHandle)
235 {
236 return $this->edges($collection, $vertexHandle, 'out');
237 }
238
239 /**
240 * @param $collection mixed collection name or id
241 * @param array $options - optional, array of options
242 * <p>Options are :
243 * <li>'createCollection' - true to create the collection if it does not exist</li>
244 * <li>'createCollectionType' - "document" or 2 for document collection</li>
245 * <li> "edge" or 3 for edge collection</li>
246 * </p>
247 */
248 protected function createCollectionIfOptions($collection, $options)
249 {
250 $options['createCollectionType'] = 3;
251 parent::createCollectionIfOptions($collection, $options);
252 }
253 }
254