26 defined(
'LGV_MD_CATCHER' ) or die ( 'Cannot Execute Directly' );
28 if ( !defined('LGV_ADB_CATCHER') ) {
29 define(
'LGV_ADB_CATCHER', 1);
32 require_once(CO_Config::db_class_dir().
'/a_co_db.class.php');
56 if (($lat1 == $lat2) && ($lon1 == $lon2)) {
63 $L = ($lon2-$lon1)/57.2957795131;
64 $U1 = atan((1.0-$f) * tan($lat1/57.2957795131));
65 $U2 = atan((1.0-$f) * tan($lat2/57.2957795131));
76 $sinLambda = sin($lambda);
77 $cosLambda = cos($lambda);
78 $sinSigma = sqrt(($cosU2*$sinLambda) * ($cosU2*$sinLambda) + ($cosU1*$sinU2-$sinU1*$cosU2*$cosLambda) * ($cosU1*$sinU2-$sinU1*$cosU2*$cosLambda));
83 $cosSigma = $sinU1*$sinU2 + ($cosU1*$cosU2*$cosLambda);
84 $sigma = atan2($sinSigma, $cosSigma);
85 $sinAlpha = ($cosU1 * $cosU2 * $sinLambda) / $sinSigma;
86 $cosSqAlpha = 1.0 - $sinAlpha*$sinAlpha;
88 if (0 == $cosSqAlpha) {
92 $cos2SigmaM = $cosSigma - 2.0*$sinU1*$sinU2/$cosSqAlpha;
94 $divisor = (16.0*$cosSqAlpha*(4.0+$f*(4.0-3.0*$cosSqAlpha)));
103 $lambda = $L + (1.0-$C) * $f * $sinAlpha * ($sigma + $C*$sinSigma*($cos2SigmaM+$C*$cosSigma*(-1.0+2.0*$cos2SigmaM*$cos2SigmaM)));
104 }
while (abs($lambda-$lambdaP) > 1e-12 && --$iterLimit>0);
106 $uSq = $cosSqAlpha * ($a*$a - $b*$b) / ($b*$b);
107 $A = 1.0 + $uSq/16384.0*(4096.0+$uSq*(-768.0+$uSq*(320.0-175.0*$uSq)));
108 $B = $uSq/1024.0 * (256.0+$uSq*(-128.0+$uSq*(74.0-47.0*$uSq)));
109 $deltaSigma = $B*$sinSigma*($cos2SigmaM+$B/4.0*($cosSigma*(-1.0+2.0*$cos2SigmaM*$cos2SigmaM)-$B/6.0*$cos2SigmaM*(-3.0+4.0*$sinSigma*$sinSigma)*(-3.0+4.0*$cos2SigmaM*$cos2SigmaM)));
110 $s = $b*$A*($sigma-$deltaSigma);
112 return ( abs ( round ( $s ) / 1000.0 ) );
127 $and_writeable =
false,
130 $ret = Array(
'sql' =>
'',
'params' => Array());
138 $ret[
'sql'] = $count_only ?
'SELECT COUNT(*) FROM (' :
'';
139 $ret[
'sql'] .=
"SELECT * FROM (
143 * DEGREES(ACOS(COS(RADIANS(p.latpoint))
144 * COS(RADIANS(z.latitude))
145 * COS(RADIANS(p.longpoint - z.longitude))
146 + SIN(RADIANS(p.latpoint))
147 * SIN(RADIANS(z.latitude)))) AS distance
148 FROM ".$this->table_name.
" AS z
149 JOIN ( /* these are the query parameters */
150 SELECT ".floatval($in_latitude).
" AS latpoint, ".floatval($in_longitude).
" AS longpoint,
151 ".floatval($in_radius_in_km).
" AS radius, 111.045 AS distance_unit
154 BETWEEN p.latpoint - (p.radius / p.distance_unit)
155 AND p.latpoint + (p.radius / p.distance_unit)
157 BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
158 AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
160 WHERE ($predicate AND ((distance <= radius)";
173 $ret = Array(
'sql' =>
'',
'params' => Array());
174 if (isset($in_value) && is_array($in_value) && count($in_value)) {
177 if (isset($in_value[
'use_like'])) {
179 unset($in_value[
'use_like']);
184 for ($i = 0; $i < count($in_value); $i++) {
186 $value = $in_value[$i];
188 if ((NULL !== $value) && (
'%' != $value)) {
189 if (is_array($value) && count($value)) {
190 $use_like_old = $use_like;
192 if (isset($value[
'use_like'])) {
194 unset($value[
'use_like']);
197 $inner_array = Array();
198 foreach ($value as $val) {
200 $val = trim(strval($val));
203 $inner_array[] =
'((tag'.intval($i).
' IS NULL) OR (tag'.intval($i).
'=\'\'))';
204 } elseif (
'%' == $val) {
205 $inner_array[] =
'(tag'.intval($i).
'<>\'\')';
207 $like_me = (
false !== strpos($val,
'%')) && $use_like;
209 $inner_array[] =
'LOWER(tag'.intval($i).
')'.($like_me ?
' LIKE ' :
'=').
'LOWER(?)';
210 array_push($ret[
'params'], $val);
215 if (1 < count($inner_array)) {
216 $sql_temp[$i] =
'('.implode(
') OR (', $inner_array).
')';
217 } elseif (count($inner_array)) {
218 $sql_temp[$i] = $inner_array[0];
221 $use_like = $use_like_old;
223 if (NULL !== $value) {
224 $value = trim(strval($value));
227 $sql_temp[$i] =
'((tag'.intval($i).
' IS NULL) OR (tag'.intval($i).
'=\'\'))';
229 $like_me = (
false !== strpos($value,
'%')) && $use_like;
231 $sql_temp[$i] =
'LOWER(tag'.intval($i).
')'.($like_me ?
' LIKE ' :
'=').
'LOWER(?)';
232 array_push($ret[
'params'], strval($value));
236 } elseif (
'%' == $value) {
237 $sql_temp[$i] =
'(tag'.intval($i).
'<>\'\')';
241 $temp_array = Array();
244 foreach ($sql_temp as $array_element) {
245 if (
'' != $array_element) {
246 array_push($temp_array, $array_element);
249 if (1 < count($temp_array)) {
250 $ret[
'sql'] =
'(('.implode(
') AND (', $temp_array).
'))';
251 } elseif (1 == count($temp_array)) {
252 $ret[
'sql'] = $temp_array[0];
255 $in_value = trim(strval($in_value));
256 if (NULL !== $in_value) {
257 if (
'' == $in_value) {
258 $ret[
'sql'] =
'((tag0 IS NULL) OR (tag0=\'\'))';
260 $like_me = (
false !== strpos($in_value,
'%')) && $use_like;
262 $ret[
'sql'] =
'(LOWER(tag0)'.($like_me ?
' LIKE ' :
'=').
'LOWER(?))';
263 array_push($ret[
'params'], strval($value));
280 $ret = Array(
'sql' =>
'',
'params' => Array());
282 if (isset($in_value) && is_array($in_value) && count($in_value)) {
283 $in_value = array_unique(array_map(
'intval', $in_value));
285 $sql_array = Array();
287 foreach ($in_value as $value) {
288 if (NULL !== $value) {
289 $sql_array[] = strval($in_db_key).
'=?';
290 array_push($ret[
'params'], $value);
294 $ret[
'sql'] =
'('.implode(
') OR (', $sql_array).
')';
296 $ret[
'sql'] =
''.strval($in_db_key).
'=?';
297 array_push($ret[
'params'], $in_value);
312 $ret = Array(
'sql' =>
'',
'params' => Array());
314 if (isset($in_value) && is_array($in_value) && count($in_value)) {
317 if (isset($in_value[
'use_like'])) {
319 unset($in_value[
'use_like']);
322 $in_value = array_unique(array_map(
function($in){
return strtolower(trim(strval($in)));}, $in_value));
323 $sql_array = Array();
325 foreach ($in_value as $value) {
326 if ((NULL != $value) && (
'%' != $value)) {
327 $sql_array[] =
'LOWER('.strval($in_db_key).
')'.($use_like ?
' LIKE ' :
'=').
'LOWER(?)';
328 array_push($ret[
'params'], $value);
329 } elseif (
'%' == $value) {
330 $sql_array[] =
'('.strval($in_db_key).
'<>\'\')';
334 $ret[
'sql'] =
'(('.implode(
') OR (', $sql_array).
'))';
336 $ret[
'sql'] =
'LOWER('.strval($in_db_key).
')=LOWER(?)';
337 $ret[
'params'][0] = $in_value;
363 $ret = Array(
'sql' =>
'',
'params' => Array());
365 if (isset($in_search_parameters) && is_array($in_search_parameters) && count ($in_search_parameters)) {
366 $sql_array = Array();
367 $param_array = Array();
369 foreach ($in_search_parameters as $key => $value) {
397 if (isset($temp) && is_array($temp) && count($temp)) {
398 $sql_array[] = $temp[
'sql'];
399 $ret[
'params'] = array_merge($ret[
'params'], $temp[
'params']);
403 if (1 < count($sql_array)) {
404 $link = $or_search ?
') OR (' :
') AND (';
406 $ret[
'sql'] =
'(('.implode($link, $sql_array).
'))';
407 } elseif (count($sql_array)) {
408 $ret[
'sql'] = $sql_array[0];
444 $and_writeable =
false,
448 $ret = Array(
'sql' =>
'',
'params' => Array());
451 $location_search =
false;
455 if (isset($in_search_parameters[
'location']) && isset($in_search_parameters[
'location'][
'longitude']) && isset($in_search_parameters[
'location'][
'latitude']) && isset($in_search_parameters[
'location'][
'radius'])) {
457 $predicate_temp = $this->
_location_predicate($in_search_parameters[
'location'][
'longitude'], $in_search_parameters[
'location'][
'latitude'], floatval($in_search_parameters[
'location'][
'radius']) * 1.02, $and_writeable, $count_only);
458 $sql = $predicate_temp[
'sql'];
459 $ret[
'params'] = $predicate_temp[
'params'];
460 $closure = $count_only ?
')' :
') ORDER BY distance,id';
461 $location_search =
true;
470 $sql = $count_only ?
'SELECT COUNT(*) FROM (' :
'';
471 $sql .=
'SELECT * FROM '.$this->table_name.
' WHERE ('.$predicate.
' AND (';
472 $closure = $count_only ?
')' :
') ORDER BY id';
478 if (isset($in_search_parameters) && is_array($in_search_parameters) && count($in_search_parameters)) {
482 if ($param_ret[
'sql']) {
483 $sql .= $link.$param_ret[
'sql'];
484 if (count($param_ret[
'params'])) {
485 $ret[
'params'] = array_merge($ret[
'params'], $param_ret[
'params']);
492 $closure =
")$closure";
494 $page_size = intval($page_size);
496 if (0 < $page_size) {
497 $initial_page = intval($initial_page);
498 $start = $initial_page * $page_size;
500 if ( ((
'mysql' == $this->_pdo_object->driver_type) || (
'mysqli' == $this->_pdo_object->driver_type))) {
501 $closure .=
' LIMIT '.$start.
', '.$page_size;
502 } elseif (
'pgsql' == $this->_pdo_object->driver_type) {
503 $closure .=
' LIMIT '.$page_size.
' OFFSET '.$start;
508 $closure .=
') AS count';
509 } elseif ($ids_only && !$location_search) {
510 $replacement =
'SELECT (id)';
511 $sql = preg_replace(
'|^SELECT \*|', $replacement, $sql);
514 $ret[
'sql'] = $sql.$closure;
525 $in_access_object = NULL
527 parent::__construct($in_pdo_object, $in_access_object);
529 $this->table_name =
'co_data_nodes';
531 $this->class_description =
'The main data database class.';
543 $in_visibility_test =
false
547 $sql =
'SELECT id FROM '.$this->table_name.
' WHERE ';
549 if ($in_visibility_test) {
553 $sql =
"$sql$predicate AND ";
558 $sql .=
'id='.intval($in_id);
561 if (isset($temp) && $temp && is_array($temp) && count($temp) ) {
577 $sql =
'SELECT id,object_name FROM '.$this->table_name.
' WHERE';
582 $sql =
"$sql $predicate AND";
585 $sql =
"$sql access_class='CO_User_Collection'";
588 if (isset($temp) && $temp && is_array($temp) && count($temp) ) {
589 foreach($temp as $value) {
590 $ret[$value[
"id"]] = $value[
"object_name"];
610 $sql =
'SELECT * FROM '.$this->table_name.
' WHERE (access_class LIKE \'%_User_Collection\') AND (tag0=\''.intval($in_login_id).
'\')
';
612 $temp = $this->execute_query($sql, Array($in_login_id));
613 if (isset($temp) && $temp && is_array($temp) && count($temp) ) {
614 // We instantiate, as opposed to check the access_class, because we want to give the implementation the option of subclassing.
615 $result = $this->_instantiate_record($temp[0]);
616 if ($result instanceof CO_User_Collection) { // This will crash if we aren't looking at it from a CHAMELEON (at least) level. That
's good.
624 /***********************/
628 public function tag0_is_unique( $in_tag0, ///< The key to test (a string).
633 $sql = 'SELECT
id FROM
'.$this->table_name.' WHERE (access_class=?) AND (tag0=?)';
634 $params = [$in_classname, $in_tag0];
636 if (isset($temp) && $temp && is_array($temp) && count($temp) ) {
681 $and_writeable =
false,
688 $location_count = $count_only;
689 $location_ids_only = $ids_only;
690 $location_search = (isset($in_search_parameters[
'location']) && isset($in_search_parameters[
'location'][
'longitude']) && isset($in_search_parameters[
'location'][
'latitude']) && isset($in_search_parameters[
'location'][
'radius']));
692 if ($location_search) {
697 $sql_and_params = $this->
_build_sql_query($in_search_parameters, $or_search, $page_size, $initial_page, $and_writeable, $count_only, $ids_only);
698 $sql = $sql_and_params[
'sql'];
699 $params = $sql_and_params[
'params'];
707 if (isset($temp) && $temp && is_array($temp) && count($temp) ) {
709 if (isset($temp[0][
'count(*)'])) {
710 $ret = intval($temp[0][
'count(*)']);
712 if (isset($temp[0][
'count'])) {
713 $ret = intval($temp[0][
'count']);
718 foreach ($temp as $result) {
721 array_push($ret, $result);
726 if ($location_search) {
730 foreach ($ret as $item) {
731 $latitude = floatval($item->raw_latitude());
732 $longitude = floatval($item->raw_longitude());
734 $accurate_distance =
self::get_accurate_distance(floatval($in_search_parameters[
'location'][
'latitude']), floatval($in_search_parameters[
'location'][
'longitude']), $latitude, $longitude);
735 if ($accurate_distance <= floatval($in_search_parameters[
'location'][
'radius'])) {
736 $item->distance = $accurate_distance;
737 array_push($ret_temp, $item);
742 if ($location_count) {
745 usort($ret_temp,
function($a, $b){
return ($a->distance > $b->distance);});
747 if ($location_ids_only) {
748 $ret_temp = array_map(
function($in_item) {
return $in_item->id(); }, $ret_temp);
if(!defined( 'LGV_ADB_CATCHER'))
_create_read_security_predicate()
execute_query( $in_sql, $in_parameters=NULL, $exec_only=false)
_instantiate_record( $in_db_result)
_create_security_predicate( $write=false)
generic_search( $in_search_parameters=NULL, $or_search=false, $page_size=0, $initial_page=0, $and_writeable=false, $count_only=false, $ids_only=false)
_location_predicate( $in_longitude, $in_latitude, $in_radius_in_km, $and_writeable=false, $count_only=false)
__construct( $in_pdo_object, $in_access_object=NULL)
_parse_string_parameter( $in_db_key, $in_value)
_parse_parameters( $in_search_parameters=NULL, $or_search=false)
_parse_integer_parameter( $in_db_key, $in_value)
_build_sql_query( $in_search_parameters=NULL, $or_search=false, $page_size=0, $initial_page=0, $and_writeable=false, $count_only=false, $ids_only=false)
item_exists( $in_id, $in_visibility_test=false)
see_if_user_exists( $in_login_id)
static get_accurate_distance( $lat1, $lon1, $lat2, $lon2)
Uses the Vincenty calculation to determine the distance (in Kilometers) between the two given lat/lon...