Prechádzať zdrojové kódy

#2135 Search by radius in custom search forms

RomanL 7 rokov pred
rodič
commit
0bbd7c9cab

+ 1 - 1
inc/classes/BxDolMetatagsQuery.php

@@ -118,7 +118,7 @@ class BxDolMetatagsQuery extends BxDolDb
                 continue;
 
             if ('bounds' == $sIndex) {
-                $sWhereBounds = $this->prepareAsString("AND `tl`.`lat` != 0 AND `tl`.`lng` != 0 AND `tl`.`lat` > ? AND `tl`.`lat` < ? AND `tl`.`lng` > ? AND `tl`.`lng` < ?", ${$sVar}['min_lat'], ${$sVar}['max_lat'], ${$sVar}['min_lng'], ${$sVar}['max_lng']);
+                $sWhereBounds = $this->prepareAsString(" AND `tl`.`lat` != 0 AND `tl`.`lng` != 0 AND `tl`.`lat` > ? AND `tl`.`lat` < ? AND `tl`.`lng` > ? AND `tl`.`lng` < ?", ${$sVar}['min_lat'], ${$sVar}['max_lat'], ${$sVar}['min_lng'], ${$sVar}['max_lng']);
             } 
             else {
                 $aWhere['tl`.`' . $sIndex] = $$sVar;

+ 5 - 3
inc/classes/BxDolSearchExtended.php

@@ -17,7 +17,7 @@ class BxDolSearchExtended extends BxDolFactory implements iBxDolFactoryObject
         'checkbox_set', 'select_multiple',
         'checkbox', 'switcher',
         'datepicker', 'datetime',
-        'location'
+        'location', 'location_radius'
     );
 
     public static $TYPE_TO_TYPE_SEARCH = array(
@@ -33,7 +33,8 @@ class BxDolSearchExtended extends BxDolFactory implements iBxDolFactoryObject
         'switcher' => array('checkbox', 'switcher'),
         'datepicker' => array('datepicker_range', 'datepicker_range_age'),
         'datetime' => array('datetime_range', 'datetime_range_age'),
-        'location' => array('location')
+        'location' => array('location'),
+        'location_radius' => array('location_radius')
     );
 
     public static $TYPE_TO_OPERATOR = array(
@@ -49,7 +50,8 @@ class BxDolSearchExtended extends BxDolFactory implements iBxDolFactoryObject
         'switcher' => array('='),
     	'datepicker' => array('between'), 
     	'datetime' => array('between'),
-        'location' => array('locate')
+        'location' => array('locate'),
+        'location_radius' => array('locate_in_radius')
     );
 
     protected $_oDb;

+ 12 - 0
inc/utils.inc.php

@@ -1119,6 +1119,18 @@ function bx_get_base_url($sPageLink)
     return array($sPageLink, $aPageParams);
 }
 
+function bx_get_location_bounds_latlng($fLatitude, $fLongitude, $iRadiusInKm)
+{
+    $fEquatorLatInKm = 111.321;
+    $aRv = array();
+    $aRv['max_lat'] = $fLatitude + $iRadiusInKm / $fEquatorLatInKm;
+    $aRv['min_lat'] = $fLatitude - ($aRv['max_lat'] - $fLatitude);
+    $aRv['max_lng'] = $fLongitude + $iRadiusInKm / (cos($aRv['min_lat'] * M_PI / 180) * $fEquatorLatInKm);
+    $aRv['min_lng'] = $fLongitude - ($aRv['max_lng'] - $fLongitude);
+    return $aRv;
+    
+}
+
 function bx_encode_url_params ($a, $aExcludeKeys = array (), $aOnlyKeys = false)
 {
     $s = '';

+ 17 - 0
modules/base/general/classes/BxBaseModGeneralDb.php

@@ -205,6 +205,23 @@ class BxBaseModGeneralDb extends BxDolModuleDb
                             $sJoinClause .= $aSql['join'];
                     }
                     break;
+                    
+                case 'locate_in_radius':
+                    if(!isset($CNF['OBJECT_METATAGS']))
+                        break;
+                    
+                    list($fLatitude, $fLongitude, $sCountry, $sState, $sCity, $sZip, $sStreet, $sStreetNumber, $iRadius) = $aSearchParam['value']['array'];
+                    $aBounds = bx_get_location_bounds_latlng($fLatitude, $fLongitude, $iRadius);
+                    
+                    $aSql = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS'])->locationsGetAsSQLPart($CNF['TABLE_ENTRIES'], $CNF['FIELD_ID'], '', '', '', '', $aBounds);
+                    
+                    if(!empty($aSql['where'])) {
+                        $sWhereConditions .= $aSql['where'];
+
+                        if(!empty($aSql['join']))
+                            $sJoinClause .= $aSql['join'];
+                    }
+                    break;
 
                 case 'between':
                     if(!is_array($aSearchParam['value']) || count($aSearchParam['value']) != 2) 

+ 10 - 0
modules/base/general/classes/BxBaseModGeneralModule.php

@@ -233,6 +233,16 @@ class BxBaseModGeneralModule extends BxDolModule
 
                 $aResult[$aInput['name']] = $aField;
             }
+            if(!empty($CNF['FIELD_LOCATION_PREFIX']) && !in_array($CNF['FIELD_LOCATION_PREFIX'], $this->_aSearchableNamesExcept))
+                $aResult['location_radius'] = array(
+                    'type' => 'location_radius', 
+                    'caption' => '_sys_form_input_location_radius',
+                    'caption_system' => '_sys_form_input_sys_location_radius',
+                    'info' => '',
+            	    'value' => '',
+                    'values' => '',
+                    'pass' => ''
+                );
 
         return $aResult;
     }

+ 4 - 1
modules/boonex/english/data/langs/system/en.xml

@@ -2038,8 +2038,11 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_form_input_age"><![CDATA[Age]]></string>
 	<string name="_sys_form_input_sys_location"><![CDATA[Location]]></string>
 	<string name="_sys_form_input_location"><![CDATA[Location]]></string>
+  <string name="_sys_form_input_sys_location_radius"><![CDATA[Location Radius]]></string>
+	<string name="_sys_form_input_location_radius"><![CDATA[Location Radius]]></string>
+  <string name="_sys_form_input_location_radius_label"><![CDATA[Radius (in km)]]></string>
 	<string name="_sys_form_input_sys_labels"><![CDATA[Labels]]></string>
-    <string name="_sys_form_input_labels"><![CDATA[Labels]]></string>
+  <string name="_sys_form_input_labels"><![CDATA[Labels]]></string>
 	<string name="_sys_form_input_sys_anonymous"><![CDATA[Post as anonymous]]></string>
 	<string name="_sys_form_input_anonymous"><![CDATA[Post as anonymous]]></string>
 	<string name="_sys_form_login"><![CDATA[Log in]]></string>

+ 4 - 1
modules/boonex/russian/data/langs/system/ru.xml

@@ -2038,7 +2038,10 @@
 	<string name="_sys_form_forgot_password_input_submit"><![CDATA[Выполнить]]></string>
 	<string name="_sys_form_input_age"><![CDATA[Возраст]]></string>
 	<string name="_sys_form_input_sys_location"><![CDATA[Расположение]]></string>
-    <string name="_sys_form_input_location"><![CDATA[Расположение]]></string>
+    <string name="_sys_form_input_location"><![CDATA[Расположение по радиусу]]></string>
+  <string name="_sys_form_input_sys_location_radius"><![CDATA[Расположение по радиусу]]></string>
+  <string name="_sys_form_input_location_radius_label"><![CDATA[Радиус (в км)]]></string>
+  <string name="_sys_form_input_location_radius"><![CDATA[Расположение]]></string>
 	<string name="_sys_form_input_sys_labels"><![CDATA[Метки]]></string>
     <string name="_sys_form_input_labels"><![CDATA[Метки]]></string>
 	<string name="_sys_form_input_sys_anonymous"><![CDATA[Анонимная публикация]]></string>

+ 10 - 0
template/css/search_extended.css

@@ -0,0 +1,10 @@
+/*-- Search extended custom fields --*/
+.bx-form-input-wrapper-location-radius > div{
+    display:inline-block;
+}
+.bx-form-input-wrapper-location-radius > div:first-child{
+    width:70%;
+}
+.bx-form-input-wrapper-location-radius > div:last-child{
+    width:29%;
+}

+ 8 - 0
template/form_field_location_radius.html

@@ -0,0 +1,8 @@
+<div class="bx-form-input-wrapper-location-radius">
+    <div>
+        __location_input__
+    </div>
+    <div>
+        __radius_input__
+    </div>
+</div>

+ 30 - 1
template/scripts/BxBaseSearchExtendedForm.php

@@ -35,7 +35,17 @@ class BxBaseSearchExtendedForm extends BxTemplFormView
                 'string' => parent::getCleanValue($sName), 
                 'array' => BxDolMetatags::locationsRetrieveFromForm($sName, $this)
             );
-
+        
+        if($bType && $this->aInputs[$sName]['type'] == 'location_radius'){
+            $aTmp = BxDolMetatags::locationsRetrieveFromForm($sName, $this);   
+            $sValue = bx_get($sName . '_rad');
+            $iValue = is_numeric($sValue) ? (int)$sValue : 0;
+            array_push($aTmp, $iValue);
+            return array(
+                'string' => parent::getCleanValue($sName), 
+                'array' => $aTmp
+            );
+        }
         //--- Process field with 'Date Range Age' and 'Date-Time Range Age' type.
         if($bType && in_array($this->aInputs[$sName]['type'], array('datepicker_range_age', 'datetime_range_age'))) {
             $bTypeDateTime = $this->aInputs[$sName]['type'] == 'datetime_range_age';
@@ -131,6 +141,25 @@ class BxBaseSearchExtendedForm extends BxTemplFormView
 
         return $this->genCustomInputUsernamesSuggestions($aInput);
     }
+    
+    public function genCustomInputLocationRadius(&$aInput)
+    {
+        $aInput['manual_input'] = true;
+        
+        $aInputRadius = $aInput;
+        $aInputRadius['type'] = 'text';
+        $aInputRadius['name'] = $aInputRadius['name'] . '_rad';
+        $sValue = bx_get($aInputRadius['name']);
+        $aInputRadius['value'] = is_numeric($sValue) ? $sValue : 0;
+        $aInputRadius['attrs']['placeholder'] = _t('_sys_form_input_location_radius_label');
+        
+        $aVars = array (
+            'location_input' => parent::genInputLocation($aInput),
+            'radius_input' => parent::genInputStandard($aInputRadius),
+        );
+        $this->_addCss('search_extended.css');
+        return $this->oTemplate->parseHtmlByName('form_field_location_radius.html', $aVars);
+    }
 }
 
 /** @} */