1 <?php
2
3 /**
4 * ArangoDB PHP client: AqlUserFunction
5 *
6 * @author Frank Mayer
7 * @copyright Copyright 2013, triagens GmbH, Cologne, Germany
8 */
9
10 namespace triagens\ArangoDb;
11
12 /**
13 * Provides management of user-functions
14 *
15 * AqlUserFunction object<br>
16 * An AqlUserFunction is an object that is used to manage AQL User Functions.<br>
17 * It registers, un-registers and lists user functions on the server<br>
18 * <br>
19 * The object encapsulates:<br>
20 * <br>
21 * <ul>
22 * <li> the name of the function
23 * <li> the actual javascript function
24 * </ul>
25 * <br>
26 * The object requires the connection object and can be initialized
27 * with or without initial configuration.<br>
28 * <br>
29 * Any configuration can be set and retrieved by the object's methods like this:<br>
30 * <br>
31 * <pre>
32 * $this->setName('myFunctions:myFunction');<br>
33 * $this->setCode('function (){your code};');
34 * </pre>
35 *
36 * <br>
37 * or like this:<br>
38 * <br>
39 * <pre>
40 * $this->name('myFunctions:myFunction');<br>
41 * $this->code('function (){your code};');
42 * </pre>
43 *
44 * @property string $name - The name of the user function
45 * @property string $code - The code of the user function
46 * @property string _action
47 *
48 * @package triagens\ArangoDb
49 * @since 1.3
50 */
51 class AqlUserFunction
52 {
53 /**
54 * The connection object
55 *
56 * @var Connection
57 */
58 private $_connection;
59
60 /**
61 * The transaction's attributes.
62 *
63 * @var array
64 */
65 protected $attributes = [];
66
67 /**
68 * The transaction's action.
69 *
70 * @var string
71 */
72 protected $_action = '';
73
74 /**
75 * Collections index
76 */
77 const ENTRY_NAME = 'name';
78
79 /**
80 * Action index
81 */
82 const ENTRY_CODE = 'code';
83
84
85 /**
86 * Initialise the AqlUserFunction object
87 *
88 * The $attributesArray array can be used to specify the name and code for the user function in form of an array.
89 *
90 * Example:
91 * array(
92 * 'name' => 'myFunctions:myFunction',
93 * 'code' => 'function (){}'
94 * )
95 *
96 *
97 * @param Connection $connection - the connection to be used
98 * @param array $attributesArray - user function initialization data
99 *
100 * @throws \triagens\ArangoDb\ClientException
101 */
102 public function __construct(Connection $connection, array $attributesArray = null)
103 {
104 $this->_connection = $connection;
105 if (is_array($attributesArray)) {
106 $this->buildAttributesFromArray($attributesArray);
107 }
108 }
109
110
111 /**
112 * Registers the user function
113 *
114 * If no parameters ($name,$code) are passed, it will use the properties of the object.
115 *
116 * If $name and/or $code are passed, it will override the object's properties with the passed ones
117 *
118 * @param null $name
119 * @param null $code
120 *
121 * @throws Exception throws exception if registration failed
122 *
123 * @return mixed true if registration was successful.
124 */
125 public function register($name = null, $code = null)
126 {
127 $attributes = $this->attributes;
128
129
130 if ($name) {
131 $attributes['name'] = $name;
132 }
133
134 if ($code) {
135 $attributes['code'] = $code;
136 }
137
138 $response = $this->_connection->post(
139 Urls::URL_AQL_USER_FUNCTION,
140 $this->getConnection()->json_encode_wrapper($attributes)
141 );
142
143 return $response->getJson();
144 }
145
146
147 /**
148 * Un-register the user function
149 *
150 * If no parameter ($name) is passed, it will use the property of the object.
151 *
152 * If $name is passed, it will override the object's property with the passed one
153 *
154 * @param string $name
155 * @param boolean $namespace
156 *
157 * @throws Exception throw exception if the request fails
158 *
159 * @return mixed true if successful without a return value or the return value if one was set in the action
160 */
161 public function unregister($name = null, $namespace = false)
162 {
163 if (null === $name) {
164 $name = $this->getName();
165 }
166
167 $url = UrlHelper::buildUrl(Urls::URL_AQL_USER_FUNCTION, [$name]);
168
169 if ($namespace) {
170 $url = UrlHelper::appendParamsUrl($url, ['group' => true]);
171 }
172
173 $response = $this->_connection->delete($url);
174
175 return $response->getJson();
176 }
177
178
179 /**
180 * Get registered user functions
181 *
182 * The method can optionally be passed a $namespace parameter to narrow the results down to a specific namespace.
183 *
184 * @param null $namespace
185 *
186 * @throws Exception throw exception if the request failed
187 *
188 * @return mixed true if successful without a return value or the return value if one was set in the action
189 */
190 public function getRegisteredUserFunctions($namespace = null)
191 {
192 $url = UrlHelper::buildUrl(Urls::URL_AQL_USER_FUNCTION, []);
193 if (null !== $namespace) {
194 $url = UrlHelper::appendParamsUrl($url, ['namespace' => $namespace]);
195 }
196 $response = $this->_connection->get($url);
197
198 return $response->getJson();
199 }
200
201
202 /**
203 * Return the connection object
204 *
205 * @return Connection - the connection object
206 */
207 protected function getConnection()
208 {
209 return $this->_connection;
210 }
211
212
213 /**
214 * Set name of the user function. It must have at least one namespace, but also can have sub-namespaces.
215 * correct:
216 * 'myNamespace:myFunction'
217 * 'myRootNamespace:mySubNamespace:myFunction'
218 *
219 * wrong:
220 * 'myFunction'
221 *
222 *
223 * @param string $value
224 *
225 * @throws \triagens\ArangoDb\ClientException
226 */
227 public function setName($value)
228 {
229 $this->set(self::ENTRY_NAME, (string) $value);
230 }
231
232
233 /**
234 * Get name value
235 *
236 * @return string name
237 */
238 public function getName()
239 {
240 return $this->get(self::ENTRY_NAME);
241 }
242
243 /**
244 * Set user function code
245 *
246 * @param string $value
247 *
248 * @throws \triagens\ArangoDb\ClientException
249 */
250 public function setCode($value)
251 {
252 $this->set(self::ENTRY_CODE, (string) $value);
253 }
254
255
256 /**
257 * Get user function code
258 *
259 * @return string name
260 */
261 public function getCode()
262 {
263 return $this->get(self::ENTRY_CODE);
264 }
265
266
267 /**
268 * Set an attribute
269 *
270 * @param $key
271 * @param $value
272 *
273 * @return $this
274 * @throws ClientException
275 */
276 public function set($key, $value)
277 {
278 if (!is_string($key)) {
279 throw new ClientException('Invalid attribute key');
280 }
281
282 $this->attributes[$key] = $value;
283
284 return $this;
285 }
286
287
288 /**
289 * Set an attribute, magic method
290 *
291 * This is a magic method that allows the object to be used without
292 * declaring all attributes first.
293 *
294 * @throws ClientException
295 *
296 * @magic
297 *
298 * @param string $key - attribute name
299 * @param mixed $value - value for attribute
300 */
301 public function __set($key, $value)
302 {
303 switch ($key) {
304 case self::ENTRY_NAME :
305 $this->setName($value);
306 break;
307 case self::ENTRY_CODE :
308 $this->setCode($value);
309 break;
310 default:
311 $this->set($key, $value);
312 break;
313 }
314 }
315
316 /**
317 * Get an attribute
318 *
319 * @param string $key - name of attribute
320 *
321 * @return mixed - value of attribute, NULL if attribute is not set
322 */
323 public function get($key)
324 {
325 if (isset($this->attributes[$key])) {
326 return $this->attributes[$key];
327 }
328
329 return null;
330 }
331
332 /**
333 * Is triggered by calling isset() or empty() on inaccessible properties.
334 *
335 * @param string $key - name of attribute
336 *
337 * @return boolean returns true or false (set or not set)
338 */
339 public function __isset($key)
340 {
341 if (isset($this->attributes[$key])) {
342 return true;
343 }
344
345 return false;
346 }
347
348 /**
349 * Get an attribute, magic method
350 *
351 * This function is mapped to get() internally.
352 *
353 * @magic
354 *
355 * @param string $key - name of attribute
356 *
357 * @return mixed - value of attribute, NULL if attribute is not set
358 */
359 public function __get($key)
360 {
361 return $this->get($key);
362 }
363
364
365 /**
366 * Returns the action string
367 *
368 * @magic
369 *
370 * @return string - the current action string
371 */
372 public function __toString()
373 {
374 return $this->_action;
375 }
376
377 /**
378 * Build the object's attributes from a given array
379 *
380 * @param $options
381 *
382 * @throws \triagens\ArangoDb\ClientException
383 */
384 public function buildAttributesFromArray($options)
385 {
386 if (isset($options[self::ENTRY_NAME])) {
387 $this->setName($options[self::ENTRY_NAME]);
388 }
389
390 if (isset($options[self::ENTRY_CODE])) {
391 $this->setCode($options[self::ENTRY_CODE]);
392 }
393 }
394 }
395