BAOBAB
CO_places_Basalt_Plugin Class Reference
Inheritance diagram for CO_places_Basalt_Plugin:
Collaboration diagram for CO_places_Basalt_Plugin:

Public Member Functions

 plugin_name ()
 
 process_command ( $in_andisol_instance, $in_http_method, $in_response_type, $in_path=[], $in_query=[])
 

Static Public Member Functions

static classes_managed ()
 

Protected Member Functions

 _get_short_description ( $in_object)
 
 _get_long_place_description ( $in_place_object, $in_show_parents=false)
 
 _get_xsd ()
 
 _process_parameters ( $in_andisol_instance, $in_query)
 
 _process_place_delete ( $in_andisol_instance, $in_object_list=[], $in_path=[], $in_query=[], $in_show_parents=false)
 
 _process_place_post ( $in_andisol_instance, $in_path=[], $in_query=[])
 
 _process_place_put ( $in_andisol_instance, $in_object_list=[], $in_path=[], $in_query=[], $in_show_parents=false)
 
 _process_place_get ( $in_andisol_instance, $in_object_list=[], $in_show_details=false, $in_show_parents=false, $in_search_count_only=false, $in_search_ids_only=false, $in_path=[], $in_query=[])
 
- Protected Member Functions inherited from A_CO_Basalt_Plugin
 _get_long_description ( $in_object, $in_show_parents=false)
 
 _get_xml_header ()
 
 _get_xsd_header ()
 
 _process_xsd ( $in_schema_file_path)
 
 _condition_response ( $in_response_type, $in_response_as_associative_array=NULL)
 
 _get_child_ids ( $in_object)
 
 _get_child_handler_data ( $in_object)
 

Static Protected Member Functions

static _lookup_address ( $in_address_string, $in_region_bias=NULL)
 
- Static Protected Member Functions inherited from A_CO_Basalt_Plugin
static _get_handler ( $in_classname)
 
static _server_url ()
 
static _array2xml ( $in_array)
 

Additional Inherited Members

- Static Protected Attributes inherited from A_CO_Basalt_Plugin
static $_s_cached_list = NULL
 This will contain caches of our handler list. More...
 

Detailed Description

This is a REST plugin that allows access to places (locations).

Definition at line 39 of file co_places_basalt_plugin.class.php.

Member Function Documentation

◆ _get_long_place_description()

CO_places_Basalt_Plugin::_get_long_place_description (   $in_place_object,
  $in_show_parents = false 
)
protected

This returns a more comprehensive description of the place.

Returns
an associative array of strings and integers.
Parameters
$in_place_objectREQUIRED: The object to display.
$in_show_parentsOPTIONAL: (Default is false). If true, then the parents will be shown. This can be a time-consuming operation, so it needs to be explicitly requested.

Definition at line 94 of file co_places_basalt_plugin.class.php.

96  {
97  $ret = parent::_get_long_description($in_place_object, $in_show_parents);
98 
99  $address_elements = $in_place_object->get_address_elements();
100 
101  if (isset($address_elements) && is_array($address_elements) && (0 < count($address_elements))) {
102  $ret['address_elements'] = $address_elements;
103  }
104 
105  if (isset($in_place_object->tags()[8]) && trim($in_place_object->tags()[8])) {
106  $ret['tag8'] = trim($in_place_object->tags()[8]);
107  }
108 
109  if (isset($in_place_object->tags()[9]) && trim($in_place_object->tags()[9])) {
110  $ret['tag9'] = trim($in_place_object->tags()[9]);
111  }
112 
113  return $ret;
114  }

Referenced by _process_place_delete(), _process_place_get(), _process_place_post(), and _process_place_put().

Here is the caller graph for this function:

◆ _get_short_description()

CO_places_Basalt_Plugin::_get_short_description (   $in_object)
protected

This returns a fairly short summary of the place.

Returns
an associative array of strings and integers.
Parameters
$in_objectREQUIRED: The user or login object to extract information from.

Reimplemented from A_CO_Basalt_Plugin.

Definition at line 75 of file co_places_basalt_plugin.class.php.

76  {
77  $ret = parent::_get_short_description($in_object);
78 
79  $address = trim($in_object->get_readable_address());
80 
81  if (isset($address) && $address) {
82  $ret['address'] = $address;
83  }
84 
85  return $ret;
86  }

Referenced by _process_place_get().

Here is the caller graph for this function:

◆ _get_xsd()

CO_places_Basalt_Plugin::_get_xsd ( )
protected
Returns
XML, containing the schema for this plugin's responses. The schema needs to be comprehensive.

Reimplemented from A_CO_Basalt_Plugin.

Definition at line 120 of file co_places_basalt_plugin.class.php.

120  {
121  return $this->_process_xsd(dirname(__FILE__).'/schema.xsd');
122  }
_process_xsd( $in_schema_file_path)

References A_CO_Basalt_Plugin\_process_xsd().

Here is the call graph for this function:

◆ _lookup_address()

static CO_places_Basalt_Plugin::_lookup_address (   $in_address_string,
  $in_region_bias = NULL 
)
staticprotected

This static protected method will allow us to do a Google lookup of an address, and return a long/lat.

Returns
an associative array of floats ("longitude" and "latitude"). NULL, if lookup failed.
Parameters
$in_address_stringThe address to look up, in a single string (Google will do its best to parse the string).
$in_region_biasAny region bias (like "us" or "sv"). Max. 3 characters.

Definition at line 46 of file co_places_basalt_plugin.class.php.

48  {
49  if (isset(CO_Config::$allow_address_lookup) && CO_Config::$allow_address_lookup && CO_Config::$google_api_key) {
50  $in_address_string = urlencode($in_address_string);
51  $in_region_bias = urlencode(strtolower(trim(substr($in_region_bias, 0, 3))));
52  $bias = (NULL != $in_region_bias) ? 'region='.$in_region_bias.'&' : '';
53  $http_status = '';
54  $error_catcher = '';
55 
56  $uri = 'https://maps.googleapis.com/maps/api/geocode/json?'.$bias.'key='.CO_Config::$google_api_key.'&address='.$in_address_string;
57 
58  $resulting_json = json_decode(CO_Chameleon_Utils::call_curl($uri, false, $http_status, $error_catcher));
59  if (isset($resulting_json) && $resulting_json &&isset($resulting_json->results) && is_array($resulting_json->results) && count($resulting_json->results)) {
60  if (isset($resulting_json->results[0]->geometry) && isset($resulting_json->results[0]->geometry->location) && isset($resulting_json->results[0]->geometry->location->lng) && isset($resulting_json->results[0]->geometry->location->lat)) {
61  return Array( 'longitude' => floatval($resulting_json->results[0]->geometry->location->lng), 'latitude' => floatval($resulting_json->results[0]->geometry->location->lat));
62  }
63  }
64  }
65 
66  return NULL;
67  }
static call_curl( $in_uri, $in_post=false, &$http_status=NULL, &$content_failure_note=NULL)
This is a function that returns the results of an HTTP call to a URI. It is a lot more secure than fi...

References CO_Chameleon_Utils\call_curl().

Referenced by process_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _process_parameters()

CO_places_Basalt_Plugin::_process_parameters (   $in_andisol_instance,
  $in_query 
)
protected

Parses the query parameters and cleans them for the database.

Returns
an associative array of the parameters, parsed for submission to the database.
Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases.
$in_queryREQUIRED: The query string to be parsed.

Reimplemented from A_CO_Basalt_Plugin.

Definition at line 130 of file co_places_basalt_plugin.class.php.

132  {
133  $ret = parent::_process_parameters($in_andisol_instance, $in_query);
134 
135  if (isset($in_query) && is_array($in_query)) {
136  // See if we are to geocode, reverse geocode, or do nothing (This depends on the Google API Key being enabled).
137  if (isset($in_query['geocode'])) {
138  $ret['geocode'] = 1;
139  } elseif (isset($in_query['reverse-geocode'])) {
140  $ret['geocode'] = -1;
141  } else {
142  $ret['geocode'] = 0;
143  }
144 
145  if (isset($in_query['address_venue'])) {
146  $ret['address_venue'] = trim($in_query['address_venue']);
147  }
148 
149  if (isset($in_query['address_street_address'])) {
150  $ret['address_street_address'] = trim($in_query['address_street_address']);
151  }
152 
153  if (isset($in_query['address_extra_information'])) {
154  $ret['address_extra_information'] = trim($in_query['address_extra_information']);
155  }
156 
157  if (isset($in_query['address_town'])) {
158  $ret['address_town'] = trim($in_query['address_town']);
159  }
160 
161  if (isset($in_query['address_county'])) {
162  $ret['address_county'] = trim($in_query['address_county']);
163  }
164 
165  if (isset($in_query['address_state'])) {
166  $ret['address_state'] = trim($in_query['address_state']);
167  }
168 
169  if (isset($in_query['address_postal_code'])) {
170  $ret['address_postal_code'] = trim($in_query['address_postal_code']);
171  }
172 
173  if (isset($in_query['address_nation'])) {
174  $ret['address_nation'] = trim($in_query['address_nation']);
175  }
176 
177  // Next, look for the last two tags (the only ones we're allowed to change).
178  if (isset($in_query['tag8'])) {
179  $ret['tag8'] = trim(strval($in_query['tag8']));
180  }
181 
182  if (isset($in_query['tag9'])) {
183  $ret['tag9'] = trim(strval($in_query['tag9']));
184  }
185  }
186 
187  return $ret;
188  }

Referenced by _process_place_put().

Here is the caller graph for this function:

◆ _process_place_delete()

CO_places_Basalt_Plugin::_process_place_delete (   $in_andisol_instance,
  $in_object_list = [],
  $in_path = [],
  $in_query = [],
  $in_show_parents = false 
)
protected

Handles the DELETE operation.

Returns
an associative array, with the "raw" response.
Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases.
$in_object_listOPTIONAL: This function is worthless without at least one object. This will be an array of place objects, holding the places to delete.
$in_pathOPTIONAL: The REST path, as an array of strings.
$in_queryOPTIONAL: The query parameters, as an associative array.
$in_show_parentsOPTIONAL: (Default is false). If true, then the parents will be shown. This can be a time-consuming operation, so it needs to be explicitly requested.

Definition at line 196 of file co_places_basalt_plugin.class.php.

201  {
202  $ret = [];
203 
204  if ($in_andisol_instance->logged_in()) { // Must be logged in to DELETE.
205  if (isset($in_object_list) && is_array($in_object_list) && (0 < count($in_object_list))) {
206  foreach ($in_object_list as $place) {
207  $to_be_deleted = $this->_get_long_place_description($place, $in_show_parents);
208  if ($place->user_can_write() && $place->delete_from_db()) {
209  $ret['deleted_places'][] = $to_be_deleted;
210  }
211  }
212  }
213  } else {
214  header('HTTP/1.1 403 Forbidden');
215  exit();
216  }
217 
218  return $ret;
219  }
_get_long_place_description( $in_place_object, $in_show_parents=false)

References _get_long_place_description().

Referenced by process_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _process_place_get()

CO_places_Basalt_Plugin::_process_place_get (   $in_andisol_instance,
  $in_object_list = [],
  $in_show_details = false,
  $in_show_parents = false,
  $in_search_count_only = false,
  $in_search_ids_only = false,
  $in_path = [],
  $in_query = [] 
)
protected

Handles the GET operation (list records).

Returns
an associative array, with the "raw" response.
Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases.
$in_object_listOPTIONAL: This function is worthless without at least one object. This will be an array of place objects, holding the places to examine.
$in_show_detailsOPTIONAL: If true (default is false), then the resulting record will be returned in "detailed" format.
$in_show_parentsOPTIONAL: (Default is false). If true, then the parents will be shown. This can be a time-consuming operation, so it needs to be explicitly requested.
$in_search_count_onlyOPTIONAL: If true, then we are only looking for a single integer count.
$in_search_ids_onlyOPTIONAL: If true, then we are going to return just an array of int (the IDs of the resources).
$in_pathOPTIONAL: The REST path, as an array of strings.
$in_queryOPTIONAL: The query parameters, as an associative array.

Definition at line 463 of file co_places_basalt_plugin.class.php.

471  {
472  $ret = [];
473 
474  if ($in_search_count_only) {
475  $ret['count'] = intval($in_object_list);
476  } elseif (isset($in_object_list) && is_array($in_object_list) && (0 < count($in_object_list))) {
477  if ($in_search_ids_only) {
478  $ret['ids'] = $in_object_list;
479  } else {
480  foreach ($in_object_list as $place) {
481  if ($in_show_details) {
482  $ret[] = $this->_get_long_place_description($place, $in_show_parents);
483  } else {
484  $ret[] = $this->_get_short_description($place);
485  }
486  }
487  }
488  }
489 
490  return $ret;
491  }

References _get_long_place_description(), and _get_short_description().

Referenced by process_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _process_place_post()

CO_places_Basalt_Plugin::_process_place_post (   $in_andisol_instance,
  $in_path = [],
  $in_query = [] 
)
protected

Handles the POST operation (new).

Returns
an associative array, with the "raw" response.
Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases.
$in_pathOPTIONAL: The REST path, as an array of strings.
$in_queryOPTIONAL: The query parameters, as an associative array.

Definition at line 227 of file co_places_basalt_plugin.class.php.

230  {
231  $ret = [];
232 
233  if ($in_andisol_instance->logged_in()) { // Must be logged in to POST.
234  $new_record = $in_andisol_instance->create_general_data_item(0, NULL, 'CO_Place_Collection');
235 
236  if ($new_record instanceof CO_Place_Collection) {
237  if (isset($in_query) && is_array($in_query) && count($in_query)) {
238  $temp = $this->_process_place_put($in_andisol_instance, [$new_record], $in_path, $in_query);
239  if (isset($temp) && is_array($temp) && count($temp)) {
240  $ret['new_place'] = $temp['changed_places'][0]['after'];
241  } else {
242  $new_record-delete_from_db();
243  header('HTTP/1.1 400 Resource Not Created');
244  exit();
245  }
246  } else {
247  $ret['new_place'] = $this->_get_long_place_description($new_record);
248  }
249  } else {
250  header('HTTP/1.1 400 Resource Not Created');
251  exit();
252  }
253  } else {
254  header('HTTP/1.1 403 Forbidden');
255  exit();
256  }
257 
258  return $ret;
259  }
_process_place_put( $in_andisol_instance, $in_object_list=[], $in_path=[], $in_query=[], $in_show_parents=false)

References _get_long_place_description(), and _process_place_put().

Referenced by process_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _process_place_put()

CO_places_Basalt_Plugin::_process_place_put (   $in_andisol_instance,
  $in_object_list = [],
  $in_path = [],
  $in_query = [],
  $in_show_parents = false 
)
protected

Handle the PUT operation (modify).

Returns
an associative array, with the "raw" response.
Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases.
$in_object_listOPTIONAL: This function is worthless without at least one object. This will be an array of place objects, holding the places to modify.
$in_pathOPTIONAL: The REST path, as an array of strings.
$in_queryOPTIONAL: The query parameters, as an associative array.
$in_show_parentsOPTIONAL: (Default is false). If true, then the parents will be shown. This can be a time-consuming operation, so it needs to be explicitly requested.

Definition at line 267 of file co_places_basalt_plugin.class.php.

272  {
273  if ($in_andisol_instance->logged_in()) { // Must be logged in to PUT.
274  $ret = ['changed_places' => []];
275  $fuzz_factor = isset($in_query) && is_array($in_query) && isset($in_query['fuzz_factor']) ? floatval($in_query['fuzz_factor']) : 0; // Set any fuzz factor.
276 
277  $parameters = $this->_process_parameters($in_andisol_instance, $in_query);
278  if (isset($parameters) && is_array($parameters) && count($parameters) && isset($in_object_list) && is_array($in_object_list) && count($in_object_list)) {
279  /*
280  What we are doing here, is using the "batch mode" for each record object to set the changes in place without doing a DB update.
281  We generate a change report, but don't add the report to the final report yet, as the change isn't "set" yet.
282  After we make all the changes, we cycle through the records, clearing the "batch mode" for each record object, which sends it to the DB.
283  If the clear works, then we set it into the final report.
284  This makes the process work much better in a multiuser environment, where other clients could be querying the DB.
285  */
286  $change_reports = []; // We will keep our interin reports here.
287 
288  foreach ($in_object_list as $place) {
289  if ($place->user_can_write()) { // Belt and suspenders. Make sure we can write.
290  $place->set_batch_mode();
291  // Take a "before" snapshot.
292  $changed_place = ['before' => $this->_get_long_place_description($place, $in_show_parents)];
293  $result = true;
294 
295  if ($result && isset($parameters['name'])) {
296  $result = $place->set_name($parameters['name']);
297  }
298 
299  if ($result && isset($parameters['write_token'])) {
300  $result = $place->set_write_security_id($parameters['write_token']);
301  }
302 
303  if ($result && isset($parameters['lang'])) {
304  $result = $place->set_lang($parameters['lang']);
305  }
306 
307  if (isset($parameters['longitude'])) {
308  $result = $place->set_longitude($parameters['longitude']);
309  }
310 
311  if ($result && isset($parameters['latitude'])) {
312  $result = $place->set_latitude($parameters['latitude']);
313  }
314 
315  if ($result && isset($parameters['fuzz_factor'])) {
316  $result = $place->set_fuzz_factor($parameters['fuzz_factor']);
317  }
318 
319  if ($result && isset($parameters['address_venue'])) {
320  $result = $place->set_address_element(0, $parameters['address_venue']);
321  }
322 
323  if ($result && isset($parameters['address_street_address'])) {
324  $result = $place->set_address_element(1, $parameters['address_street_address']);
325  }
326 
327  if ($result && isset($parameters['address_extra_information'])) {
328  $result = $place->set_address_element(2, $parameters['address_extra_information']);
329  }
330 
331  if ($result && isset($parameters['address_town'])) {
332  $result = $place->set_address_element(3, $parameters['address_town']);
333  }
334 
335  if ($result && isset($parameters['address_county'])) {
336  $result = $place->set_address_element(4, $parameters['address_county']);
337  }
338 
339  if ($result && isset($parameters['address_state'])) {
340  $result = $place->set_address_element(5, $parameters['address_state']);
341  }
342 
343  if ($result && isset($parameters['address_postal_code'])) {
344  $result = $place->set_address_element(6, $parameters['address_postal_code']);
345  }
346 
347  if ($result && isset($parameters['can_see_through_the_fuzz'])) {
348  $result = $place->set_can_see_through_the_fuzz($parameters['can_see_through_the_fuzz']);
349  }
350 
351  if ($result && isset($parameters['address_nation'])) { // This might fail, if it's a nation-specific one, so we don't test for the result.
352  $test = $place->set_address_element(7, $parameters['address_nation']);
353  if (!$test) { // If so, we add a note to the change record.
354  $changed_place['nation_not_changed'] = true;
355  }
356  }
357 
358  // Geocode requires that address information already be set. Geolocation requires that the long/lat already be set.
359  if ($result && isset($parameters['geocode']) && (0 != intval($parameters['geocode']))) {
360  if (1 == intval($parameters['geocode'])) {
361  $long_lat = $place->lookup_address();
362 
363  if (isset($long_lat) && is_array($long_lat) && 1 < count($long_lat)) {
364  $result = $place->set_longitude(floatval($long_lat['longitude']));
365  if ($result) {
366  $result = $place->set_latitude(floatval($long_lat['latitude']));
367  }
368  }
369  } else {
370  $address_elements = $place->geocode_long_lat();
371  if (isset($address_elements) && is_array($address_elements) && count($address_elements)) {
372  $result = $place->set_address_elements($address_elements);
373  }
374  }
375  }
376 
377  if ($result && isset($parameters['tag8'])) {
378  $result = $place->set_tag(8, $parameters['tag8']);
379  }
380 
381  if ($result && isset($parameters['tag9'])) {
382  $result = $place->set_tag(9, $parameters['tag9']);
383  }
384 
385  if ($result && isset($parameters['remove_payload'])) {
386  $result = $place->set_payload(NULL);
387  } elseif ($result && isset($parameters['payload'])) {
388  $result = $place->set_payload($parameters['payload']);
389  }
390 
391  // We have previously split into "add" and "remove" lists (dictated by the sign of the integer).
392  if ($result && isset($parameters['child_ids'])) {
393  $add = $parameters['child_ids']['add'];
394  $remove = $parameters['child_ids']['remove'];
395 
396  foreach ($remove as $id) {
397  if ($id != $place->id()) {
398  $child = $in_andisol_instance->get_single_data_record_by_id($id);
399  if (isset($child)) {
400  $result = $place->deleteThisElement($child);
401  }
402 
403  if (!$result) {
404  break;
405  }
406  }
407  }
408 
409  if ($result) {
410  foreach ($add as $id) {
411  if ($id != $place->id()) {
412  $child = $in_andisol_instance->get_single_data_record_by_id($id);
413  if (isset($child)) {
414  $result = $place->appendElement($child);
415 
416  if (!$result) {
417  break;
418  }
419  }
420  }
421  }
422  }
423  }
424 
425  // We do this last, so we have the option of doing a "lock" (which isn't necessary in "batch mode").
426  if ($result && isset($parameters['read_token'])) {
427  $result = $place->set_read_security_id($parameters['read_token']);
428  }
429 
430  if ($result) { // Assuming all went well to this point, we take an "after" snapshot, and save the object and interim report in our "final clear" list.
431  $changed_place['after'] = $this->_get_long_place_description($place, $in_show_parents);
432  $change_reports[] = ['object' => $place, 'report' => $changed_place];
433  }
434  }
435  }
436 
437  // Here's where we actually set each record into the DB, and generate the full final report.
438  if ($result && count($change_reports)) {
439  $ret['changed_places'] = [];
440  foreach ($change_reports as $value) {
441  $result = $value['object']->clear_batch_mode();
442  if ($result) { // We only report the ones that work.
443  $ret['changed_places'][] = $value['report'];
444  } else {
445  break;
446  }
447  }
448  }
449  }
450  } else {
451  header('HTTP/1.1 403 Forbidden');
452  exit();
453  }
454  return $ret;
455  }
_process_parameters( $in_andisol_instance, $in_query)

References _get_long_place_description(), and _process_parameters().

Referenced by _process_place_post(), and process_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ classes_managed()

static CO_places_Basalt_Plugin::classes_managed ( )
static

This returns an array of classnames, handled by this plugin.

Returns
an array of string, with the names of the classes handled by this plugin.

Reimplemented from A_CO_Basalt_Plugin.

Definition at line 507 of file co_places_basalt_plugin.class.php.

507  {
508  return ['CO_Place_Collection', 'CO_US_Place_Collection', 'CO_Place', 'CO_US_Place', 'CO_LL_Location'];
509  }

◆ plugin_name()

CO_places_Basalt_Plugin::plugin_name ( )
Returns
a string, with our plugin name.

Reimplemented from A_CO_Basalt_Plugin.

Definition at line 497 of file co_places_basalt_plugin.class.php.

497  {
498  return 'places';
499  }

◆ process_command()

CO_places_Basalt_Plugin::process_command (   $in_andisol_instance,
  $in_http_method,
  $in_response_type,
  $in_path = [],
  $in_query = [] 
)

This runs our plugin command.

Returns
the HTTP response string, as either JSON or XML.
Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases.
$in_http_methodREQUIRED: 'GET', 'POST', 'PUT' or 'DELETE'
$in_response_typeREQUIRED: Either 'json' or 'xml' -the response type.
$in_pathOPTIONAL: The REST path, as an array of strings.
$in_queryOPTIONAL: The query parameters, as an associative array.

Reimplemented from A_CO_Basalt_Plugin.

Definition at line 517 of file co_places_basalt_plugin.class.php.

522  {
523  $ret = [];
524 
525  if ('POST' == $in_http_method) { // We handle POST directly.
526  $ret = $this->_process_place_post($in_andisol_instance, $in_path, $in_query);
527  } else {
528  $show_parents = isset($in_query) && is_array($in_query) && isset($in_query['show_parents']); // Show all places in detail, as well as the parents (applies only to GET or DELETE).
529  $show_details = $show_parents || (isset($in_query) && is_array($in_query) && isset($in_query['show_details'])); // Show all places in detail (applies only to GET).
530  $writeable = isset($in_query) && is_array($in_query) && isset($in_query['writeable']); // Show/list only places this user can modify.
531  $search_count_only = isset($in_query) && is_array($in_query) && isset($in_query['search_count_only']); // Ignored for discrete IDs. If true, then a simple "count" result is returned as an integer.
532  $search_ids_only = isset($in_query) && is_array($in_query) && isset($in_query['search_ids_only']); // Ignored for discrete IDs. If true, then the response will be an array of integers, denoting resource IDs.
533  $search_page_size = isset($in_query) && is_array($in_query) && isset($in_query['search_page_size']) ? abs(intval($in_query['search_page_size'])) : 0; // Ignored for discrete IDs. This is the size of a page of results (1-based result count. 0 is no page size).
534  $search_page_number = isset($in_query) && is_array($in_query) && isset($in_query['search_page_number']) ? abs(intval($in_query['search_page_number'])) : 0; // Ignored for discrete IDs, or if search_page_size is 0. The page we are interested in (0-based. 0 is the first page).
535  $search_name = isset($in_query) && is_array($in_query) && isset($in_query['search_name']) ? trim($in_query['search_name']) : NULL; // Search in the object name.
536 
537  // For the default (no place ID), we simply act on a list of all available places (or filtered by some search criteria).
538  if (0 == count($in_path)) {
539  $radius = isset($in_query) && is_array($in_query) && isset($in_query['search_radius']) && (0.0 < floatval($in_query['search_radius'])) ? floatval($in_query['search_radius']) : NULL;
540  $longitude = isset($in_query) && is_array($in_query) && isset($in_query['search_longitude']) ? floatval($in_query['search_longitude']) : NULL;
541  $latitude = isset($in_query) && is_array($in_query) && isset($in_query['search_latitude']) ? floatval($in_query['search_latitude']) : NULL;
542  $search_region_bias = isset($in_query) && is_array($in_query) && isset($in_query['search_region_bias']) ? strtolower(trim($search_region_bias)) : CO_Config::$default_region_bias; // This is a region bias for an address lookup. Ignored if search_address is not specified.
543  $search_address = isset($in_query) && is_array($in_query) && isset($in_query['search_address']) && trim($in_query['search_address']) ? trim($in_query['search_address']) : NULL;
544 
545  $tags = [];
546  $tags_temp = [];
547 
548  // This mess allows us to use the field names set up in the CHAMELEON class as search query bases.
549  for ($count = 0; $count < 8; $count++) {
550  $eval_line = '$parameter_name = CO_CHAMELEON_Lang_Common::$chameleon_co_place_tag_'.$count.';';
551  eval($eval_line);
552  $parameter_name = 'search_'.$parameter_name;
553  if (isset($in_query) && is_array($in_query) && isset($in_query[$parameter_name])) {
554  $parameter_value = strval(trim($in_query[$parameter_name]));
555  $tags_temp[] = $parameter_value;
556  } else {
557  $tags_temp[] = NULL;
558  }
559  }
560 
561  // These two tags are available for whatever we want them for.
562  if (isset($in_query) && is_array($in_query) && isset($in_query['search_tag8'])) {
563  $tags_temp[] = trim($in_query['search_tag8']);
564  } else {
565  $tags_temp[] = NULL;
566  }
567 
568  if (isset($in_query) && is_array($in_query) && isset($in_query['search_tag9'])) {
569  $tags_temp[] = trim($in_query['search_tag9']);
570  } else {
571  $tags_temp[] = NULL;
572  }
573 
574  // See if we will even be looking at our tags.
575  if(array_reduce($tags_temp, function($prev, $current) { return $prev || (NULL !== $current) ? true : $prev; }, false)) {
576  $tags = $tags_temp;
577  }
578 
579  $address = NULL;
580 
581  // Long/lat trumps an address.
582  // If we have an address, and no long/lat, we see if we can do a lookup.
583  if (isset(CO_Config::$allow_address_lookup) && CO_Config::$allow_address_lookup && CO_Config::$google_api_key) {
584  $address = isset($in_query) && is_array($in_query) && isset($in_query['search_address']) && trim($in_query['search_address']) ? trim($in_query['search_address']) : NULL;
585  if (isset($search_address) && $search_address && !(isset($longitude) && isset($latitude))) {
586  if (CO_Config::$allow_general_address_lookup || $in_andisol_instance->logged_in()) {
587  $result = self::_lookup_address($search_address, $search_region_bias);
588 
589  if ($result && is_array($result) && (1 < count($result))) {
590  $longitude = $result['longitude'];
591  $latitude = $result['latitude'];
592  }
593  } else {
594  header('HTTP/1.1 400 Improper Distance Search (Login Required)');
595  exit();
596  }
597  }
598  } elseif ($search_address) {
599  header('HTTP/1.1 400 Incomplete Distance Search');
600  exit();
601  }
602 
603  $location_search = NULL;
604 
605  // We make sure that we puke if they give us a bad distance search.
606  if (isset($radius) && isset($longitude) && isset($latitude)) {
607  $location_search = Array('radius' => $radius, 'longitude' => $longitude, 'latitude' => $latitude);
608  } elseif (isset($radius) || isset($longitude) || isset($latitude)) {
609  header('HTTP/1.1 400 Incomplete Distance Search');
610  exit();
611  }
612 
613  $class_search = Array('%_Place_Collection', 'use_like' => 1);
614  $search_array['access_class'] = $class_search;
615 
616  // Now, I had initially considered doing a cool recursive-descent parser in the directories for a value search, but realized that could be a security vector. So instead, I am implementing a rather primitive, AND-connected query-based lookup.
617  // You can put SQL wildcards ('%') into the values, and specifying multiple values will act as an AND search.
618  if (count($tags)) {
619  $tags['use_like'] = 1;
620  $search_array['tags'] = $tags;
621  }
622 
623  if (isset($location_search)) {
624  $search_array['location'] = $location_search;
625  if (isset($search_address) && $search_address && !(isset($longitude) && isset($latitude))) {
626  $search_array['location']['address'] = $search_address;
627  }
628  }
629 
630  if (isset($search_name)) {
631  $search_array['name'] = Array($search_name, 'use_like' => 1);
632  }
633 
634  $placelist = $in_andisol_instance->generic_search($search_array, false, $search_page_size, $search_page_number, $writeable, $search_count_only, $search_ids_only);
635 
636  if ('GET' == $in_http_method) {
637  $ret = $this->_process_place_get($in_andisol_instance, $placelist, $show_details, $show_parents, $search_count_only, $search_ids_only, $in_path, $in_query);
638  $ret = Array('results' => $ret);
639  } elseif ('PUT' == $in_http_method) {
640  $ret = $this->_process_place_put($in_andisol_instance, $placelist, $in_path, $in_query, $show_parents);
641  } elseif ('DELETE' == $in_http_method) {
642  $ret = $this->_process_place_delete($in_andisol_instance, $placelist, $in_path, $in_query, $show_parents);
643  }
644 
645  if ($location_search && !$search_count_only) {
646  $ret['search_location'] = $location_search;
647  }
648  } else {
649  $first_directory = $in_path[0]; // Get the first directory.
650 
651  // This tests to see if we only got one single digit as our "command."
652  $single_place_id = (ctype_digit($first_directory) && (1 < intval($first_directory))) ? intval($first_directory) : NULL; // This will be for if we are looking only one single place.
653 
654  // The first thing that we'll do, is look for a list of place IDs. If that is the case, we split them into an array of int.
655 
656  $place_id_list = explode(',', $first_directory);
657 
658  // If we do, indeed, have a list, we will force them to be ints, and cycle through them.
659  if ($single_place_id || (1 < count($place_id_list))) {
660  $place_id_list = ($single_place_id ? [$single_place_id] : array_unique(array_map('intval', $place_id_list)));
661  $placelist = [];
662 
663  foreach ($place_id_list as $id) {
664  if (0 < $id) {
665  $place = $in_andisol_instance->get_single_data_record_by_id($id);
666  if (isset($place) && ($place instanceof CO_Place)) {
667  $placelist[] = $place;
668  }
669  }
670  }
671 
672  if ('GET' == $in_http_method) {
673  $ret = $this->_process_place_get($in_andisol_instance, $placelist, $show_details, $show_parents, $search_count_only, $search_ids_only, $in_path, $in_query);
674  $ret = Array('results' => $ret);
675  } elseif ('PUT' == $in_http_method) {
676  $ret = $this->_process_place_put($in_andisol_instance, $placelist, $in_path, $in_query, $show_parents);
677  } elseif ('DELETE' == $in_http_method) {
678  $ret = $this->_process_place_delete($in_andisol_instance, $placelist, $in_path, $in_query, $show_parents);
679  }
680  }
681  }
682  }
683 
684  return $this->_condition_response($in_response_type, $ret);
685  }
_condition_response( $in_response_type, $in_response_as_associative_array=NULL)
_process_place_delete( $in_andisol_instance, $in_object_list=[], $in_path=[], $in_query=[], $in_show_parents=false)
_process_place_post( $in_andisol_instance, $in_path=[], $in_query=[])
_process_place_get( $in_andisol_instance, $in_object_list=[], $in_show_details=false, $in_show_parents=false, $in_search_count_only=false, $in_search_ids_only=false, $in_path=[], $in_query=[])
static _lookup_address( $in_address_string, $in_region_bias=NULL)

References A_CO_Basalt_Plugin\_condition_response(), _lookup_address(), _process_place_delete(), _process_place_get(), _process_place_post(), and _process_place_put().

Here is the call graph for this function: