Просмотр исходного кода

Merge branch 'master' of https://github.com/boonex/dolphin

AntonLV 10 лет назад
Родитель
Сommit
ac295ed9b3

+ 16 - 7
inc/classes/BxDolMetatags.php

@@ -403,11 +403,13 @@ class BxDolMetatags extends BxDol implements iBxDolFactoryObject
      * @param $sState optional state/province/territory name
      * @param $sCity optional city name
      * @param $sZip optional ZIP/postcode
+     * @param $sStreet optional street name
+     * @param $sStreetNumber optional street number
      * @return true if location was added, or false otherwise
      */
-    public function locationsAdd($iId, $sLatitude, $sLongitude, $sCountryCode, $sState, $sCity, $sZip = '') 
+    public function locationsAdd($iId, $sLatitude, $sLongitude, $sCountryCode, $sState, $sCity, $sZip = '', $sStreet = '', $sStreetNumber = '') 
     {
-        return $this->_oQuery->locationsAdd($iId, $sLatitude, $sLongitude, $sCountryCode, $sState, $sCity, $sZip);
+        return $this->_oQuery->locationsAdd($iId, $sLatitude, $sLongitude, $sCountryCode, $sState, $sCity, $sZip, $sStreet, $sStreetNumber);
     }
 
     /**
@@ -425,7 +427,7 @@ class BxDolMetatags extends BxDol implements iBxDolFactoryObject
             $sPrefix .= '_';
         if (!$oForm)
             $oForm = new BxDolForm(array(), false);
-        $this->locationsAdd($iId, $oForm->getCleanValue($sPrefix.'lat'), $oForm->getCleanValue($sPrefix.'lng'), $oForm->getCleanValue($sPrefix.'country'), $oForm->getCleanValue($sPrefix.'state'), $oForm->getCleanValue($sPrefix.'city'), $oForm->getCleanValue($sPrefix.'zip'));
+        $this->locationsAdd($iId, $oForm->getCleanValue($sPrefix.'lat'), $oForm->getCleanValue($sPrefix.'lng'), $oForm->getCleanValue($sPrefix.'country'), $oForm->getCleanValue($sPrefix.'state'), $oForm->getCleanValue($sPrefix.'city'), $oForm->getCleanValue($sPrefix.'zip'), $oForm->getCleanValue($sPrefix.'street'), $oForm->getCleanValue($sPrefix.'street_number'));
     }
 
     /**
@@ -433,7 +435,7 @@ class BxDolMetatags extends BxDol implements iBxDolFactoryObject
      * @param $iId content id
      * @return string with links to country and city
      */
-    public function locationsString($iId)
+    public function locationsString($iId, $bHTML = true)
     {
         bx_import('BxDolForm');
         $aCountries = BxDolFormQuery::getDataItems('Country');
@@ -446,8 +448,15 @@ class BxDolMetatags extends BxDol implements iBxDolFactoryObject
             return _t('_sys_location_country', $sCountryUrl);
 
         $sCityUrl = '<a href="' . BX_DOL_URL_ROOT . 'searchKeyword.php?type=location_country_city&keyword=' . $aLocation['country'] . '&state=' . rawurlencode($aLocation['state']) . '&city=' . rawurlencode($aLocation['city']) . '">' . $aLocation['city'] . '</a>';
-            
-        return _t('_sys_location_country_city', $sCountryUrl, $sCityUrl);
+
+        $sStateUrl = '<a href="' . BX_DOL_URL_ROOT . 'searchKeyword.php?type=location_country_state&keyword=' . $aLocation['country'] . '&state=' . rawurlencode($aLocation['state']) . '">' . $aLocation['state'] . '</a>';
+
+        if ($aLocation['street'])
+            $s = _t('_sys_location_country_city_street', $sCountryUrl, $sStateUrl, $sCityUrl, $aLocation['street'], $aLocation['street_number']);
+        else
+            $s = _t('_sys_location_country_city', $sCountryUrl, $sStateUrl, $sCityUrl);
+
+        return $bHTML ? $s : trim(strip_tags($s));
     }
 
     /**
@@ -504,7 +513,7 @@ class BxDolMetatags extends BxDol implements iBxDolFactoryObject
      * Get location
      * @param $iId content id
      * @param $sPrefix field prefix for returning data array
-     * @return location array with the following keys (when no prefix specified): object_id, lat, lng, country, state, city, zip
+     * @return location array with the following keys (when no prefix specified): object_id, lat, lng, country, state, city, zip, street, street_number
      */
     public function locationGet($iId, $sPrefix = '')
     {

+ 2 - 2
inc/classes/BxDolMetatagsQuery.php

@@ -66,13 +66,13 @@ class BxDolMetatagsQuery extends BxDolDb
 
 
 
-    public function locationsAdd($mixedContentId, $fLat, $fLng, $sCountryCode, $sState, $sCity, $sZip)
+    public function locationsAdd($mixedContentId, $fLat, $fLng, $sCountryCode, $sState, $sCity, $sZip, $sStreet, $sStreetNumber)
     {
         $this->locationsDelete($mixedContentId);
         if (!$fLat && !$fLng)
             return true;
 
-        $sQuery = $this->prepare("INSERT INTO `{$this->_aObject['table_locations']}` SET `object_id` = ?, `lat` = ?, `lng` = ?, `country` = ?, `state` = ?, `city` = ?, `zip` = ?", $mixedContentId, $fLat, $fLng, $sCountryCode, $sState, $sCity, $sZip);
+        $sQuery = $this->prepare("INSERT INTO `{$this->_aObject['table_locations']}` SET `object_id` = ?, `lat` = ?, `lng` = ?, `country` = ?, `state` = ?, `city` = ?, `zip` = ?, `street` = ?, `street_number` = ?", $mixedContentId, $fLat, $fLng, $sCountryCode, $sState, $sCity, $sZip, $sStreet, $sStreetNumber);
         return $this->query($sQuery);
     }
     

+ 4 - 1
inc/classes/BxDolSearch.php

@@ -130,7 +130,7 @@ class BxDolSearch extends BxDol
 
     public function setMetaType($s)
     {
-        $aMetaTypes = array('location_country', 'location_country_city', 'mention', 'keyword');
+        $aMetaTypes = array('location_country', 'location_country_city', 'location_country_state', 'mention', 'keyword');
         if (in_array($s, $aMetaTypes))
             $this->_sMetaType = $s;
     }
@@ -612,6 +612,9 @@ class BxDolSearchResult implements iBxDolReplaceable
                     case 'location_country':
                         $o->locationsSetSearchCondition($this, $sKeyword);
                         break;
+                    case 'location_country_state':
+                        $o->locationsSetSearchCondition($this, $sKeyword, bx_process_input(bx_get('state')));
+                        break;
                     case 'location_country_city':
                         $o->locationsSetSearchCondition($this, $sKeyword, bx_process_input(bx_get('state')), bx_process_input(bx_get('city')));
                         break;

+ 3 - 1
install/sql/system.sql

@@ -334,7 +334,9 @@ INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `ex
 
 (@iCategoryId, 'sys_transcoder_queue_storage', '_adm_stg_cpt_option_sys_transcoder_queue_storage', '', 'checkbox', '', '', '', 50),
 
-(@iCategoryId, 'sys_default_payment', '_adm_stg_cpt_option_sys_default_payment', 'payment', 'select', 'a:3:{s:6:"module";s:6:"system";s:6:"method";s:12:"get_payments";s:5:"class";s:21:"TemplPaymentsServices";}', '', '', 60);
+(@iCategoryId, 'sys_default_payment', '_adm_stg_cpt_option_sys_default_payment', 'payment', 'select', 'a:3:{s:6:"module";s:6:"system";s:6:"method";s:12:"get_payments";s:5:"class";s:21:"TemplPaymentsServices";}', '', '', 60),
+
+(@iCategoryId, 'sys_maps_api_key', '_adm_stg_cpt_option_sys_maps_api_key', '', 'digit', '', '', '', 70);
 
 
 --

+ 14 - 35
modules/base/general/classes/BxBaseModGeneralFormEntry.php

@@ -38,9 +38,22 @@ class BxBaseModGeneralFormEntry extends BxTemplFormView
         if (isset($CNF['FIELD_CHANGED']) && isset($this->aInputs[$CNF['FIELD_CHANGED']])) {
             $this->aInputs[$CNF['FIELD_CHANGED']]['date_filter'] = BX_DATA_INT;
             $this->aInputs[$CNF['FIELD_CHANGED']]['date_format'] = BX_FORMAT_DATE;
-        }        
+        }
+
+        if (isset($CNF['FIELD_LOCATION_PREFIX']) && isset($this->aInputs[$CNF['FIELD_LOCATION_PREFIX']])) {
+            $this->aInputs[$CNF['FIELD_LOCATION_PREFIX']]['manual_input'] = true;
+        }
     }
 
+    function initChecker ($aValues = array (), $aSpecificValues = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        if (!empty($CNF['FIELD_LOCATION_PREFIX']) && isset($this->aInputs[$CNF['FIELD_LOCATION_PREFIX']]) && isset($aValues[$CNF['FIELD_ID']]) && !empty($CNF['OBJECT_METATAGS']) && ($oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS'])) && $oMetatags->locationsIsEnabled())
+            $this->aInputs[$CNF['FIELD_LOCATION_PREFIX']]['value'] = $oMetatags->locationsString($aValues[$CNF['FIELD_ID']], false);
+
+        parent::initChecker ($aValues, $aSpecificValues);
+    }
+    
     public function insert ($aValsToAdd = array(), $isIgnore = false)
     {
         $CNF = &$this->_oModule->_oConfig->CNF;
@@ -106,40 +119,6 @@ class BxBaseModGeneralFormEntry extends BxTemplFormView
         return parent::delete($iContentId);
     }
 
-    protected function genCustomInputLocation ($aInput) 
-    {
-        $sProto = (0 == strncmp('https', BX_DOL_URL_ROOT, 5)) ? 'https' : 'http';
-        $this->oTemplate->addJs($sProto . '://maps.google.com/maps/api/js?sensor=false');
-
-        $aInput['checked'] = $this->getCleanValue($aInput['name'] . '_lat') && $this->getCleanValue($aInput['name'] . '_lng') ? 1 : 0;
-
-        $aVars = array (
-            'name' => $aInput['name'],
-            'id_status' => $this->getInputId($aInput) . '_status',
-            'location_string' => _t('_sys_location_undefined'),
-        );
-        $aLocationIndexes = array ('lat', 'lng', 'country', 'state', 'city', 'zip');
-        foreach ($aLocationIndexes as $sKey)
-            $aVars[$sKey] = $this->getLoctionVal($aInput, $sKey);
-        if ($aVars['country']) {
-            $aCountries = BxDolFormQuery::getDataItems('Country');
-            $aVars['location_string'] = ($aVars['city'] ? $aVars['city'] . ', ' : '') . $aCountries[$aVars['country']];
-        }
-        if ($this->getLoctionVal($aInput, 'lat') && $this->getLoctionVal($aInput, 'lng'))
-            $aInput['checked'] = true;
-        $aVars['input'] = $this->genInputSwitcher($aInput);
-
-        return $this->oTemplate->parseHtmlByName('form_field_location.html', $aVars);
-    }
-
-    protected function getLoctionVal ($aInput, $sIndex) 
-    {
-        $s = $aInput['name'] . '_' . $sIndex;
-        if (isset($this->_aSpecificValues[$s]))
-            return $this->_aSpecificValues[$s];
-        return $this->getCleanValue($s);
-    }
-
     public function processFiles ($sFieldFile, $iContentId = 0, $isAssociateWithContent = false)
     {
         $CNF = &$this->_oModule->_oConfig->CNF;

+ 0 - 77
modules/base/general/template/form_field_location.html

@@ -1,77 +0,0 @@
-
-<div class="bx-form-input-location-cont bx-clearfix">
-    __input__
-    <div id="__id_status__" class="bx-def-margin-left">__location_string__</div>
-</div>
-
-<input type="hidden" name="__name___lat" value="__lat__" />
-<input type="hidden" name="__name___lng" value="__lng__" />
-<input type="hidden" name="__name___country" value="__country__" />
-<input type="hidden" name="__name___state" value="__state__" />
-<input type="hidden" name="__name___city" value="__city__" />
-<input type="hidden" name="__name___zip" value="__zip__" />
-
-<script>
-    $('input[name=__name__]').on('change', function () {
-        var oMap = {
-            '__name___lat': '', 
-            '__name___lng': '', 
-            '__name___city': 'locality', 
-            '__name___state': 'administrative_area_level_1', 
-            '__name___country': 'country',  
-            '__name___zip': 'postal_code'
-        };
-
-        var callbackOnLocationReset = function (error) {
-            var sKey;
-            for (sKey in oMap) 
-                $('[name="' + sKey + '"]').val('');
-            $('#__id_status__').html("<bx_text_js:_sys_location_undefined />");
-        }
-
-        var callbackOnLocationSucess = function (position) {
-            $('[name="__name___lat"]').val(position.coords.latitude);
-            $('[name="__name___lng"]').val(position.coords.longitude);
-
-            var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
-            var geocoder = new google.maps.Geocoder();
-
-            geocoder.geocode({'latLng': latlng}, function (results, status) {
-                if (status == google.maps.GeocoderStatus.OK) {                
-                    var i, sKey, sCountry, sCity, o = results[0]['address_components'];
-                    for (i in o) {
-                        for (sKey in oMap) {
-                            if (o[i].types.indexOf(oMap[sKey]) > -1)
-                                $('[name="' + sKey + '"]').val(o[i].short_name);
-                            
-                            if (o[i].types.indexOf('locality') > -1)
-                                sCity = o[i].short_name;
-                            else if (o[i].types.indexOf('country') > -1)
-                                sCountry = o[i].long_name;
-                        }
-                    }
-                    if ('undefined' != typeof(sCity) && sCity.length)
-                        $('#__id_status__').html(sCity + ", " + sCountry);
-                    else
-                        $('#__id_status__').html(sCountry);
-                } 
-                else {
-                    $('#__id_status__').html(status);
-                }
-            });
-
-        }
-
-        if ($(this).is(':checked')) {
-            $('#__id_status__').html('<bx_text_js:_sys_location_determining />');
-            if (navigator.geolocation)
-                navigator.geolocation.getCurrentPosition(callbackOnLocationSucess, callbackOnLocationReset);
-            else
-                $('#__id_status__').html('<bx_text_js:_sys_location_geolocation_not_supported_by_browser />');
-        } else {
-            callbackOnLocationReset();
-        }
-    });
-
-</script>
-

+ 3 - 1
modules/boonex/albums/install/sql/install.sql

@@ -194,6 +194,8 @@ CREATE TABLE `bx_albums_meta_locations` (
   `state` varchar(255) NOT NULL,
   `city` varchar(255) NOT NULL,
   `zip` varchar(255) NOT NULL,
+  `street` varchar(255) NOT NULL,
+  `street_number` varchar(255) NOT NULL,
   PRIMARY KEY (`object_id`),
   KEY `country_state_city` (`country`,`state`(8),`city`(8))
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@@ -269,7 +271,7 @@ INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `ch
 ('bx_albums', 'bx_albums', 'text', '', '', 0, 'textarea', '_bx_albums_form_entry_input_sys_text', '_bx_albums_form_entry_input_text', '', 0, 0, 2, '', '', '', '', '', '', 'XssHtml', '', 1, 0),
 ('bx_albums', 'bx_albums', 'pictures', 'a:2:{i:0;s:15:"bx_albums_html5";i:1;s:14:"bx_albums_crop";}', 'a:3:{s:16:"bx_albums_simple";s:26:"_sys_uploader_simple_title";s:15:"bx_albums_html5";s:25:"_sys_uploader_html5_title";s:14:"bx_albums_crop";s:24:"_sys_uploader_crop_title";}', 0, 'files', '_bx_albums_form_entry_input_sys_pictures', '_bx_albums_form_entry_input_pictures', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_albums', 'bx_albums', 'allow_view_to', '', '', 0, 'custom', '_bx_albums_form_entry_input_sys_allow_view_to', '_bx_albums_form_entry_input_allow_view_to', '', 1, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
-('bx_albums', 'bx_albums', 'location', '', '', 0, 'custom', '_sys_form_input_sys_location', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_albums', 'bx_albums', 'location', '', '', 0, 'location', '_sys_form_input_sys_location', '_sys_form_input_location', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 ('bx_albums', 'bx_albums', 'added', '', '', 0, 'datetime', '_bx_albums_form_entry_input_sys_date_added', '_bx_albums_form_entry_input_date_added', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_albums', 'bx_albums', 'changed', '', '', 0, 'datetime', '_bx_albums_form_entry_input_sys_date_changed', '_bx_albums_form_entry_input_date_changed', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0);
 

+ 0 - 3
modules/boonex/albums/template/form_field_location.html

@@ -1,3 +0,0 @@
-
-<bx_include_base:../modules/base/general/template/form_field_location.html />
-

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

@@ -1193,6 +1193,7 @@
 	<string name="_adm_stg_cpt_option_sys_ftp_password"><![CDATA[FTP server password]]></string>
 	<string name="_adm_stg_cpt_option_sys_install_time"><![CDATA[Installation date]]></string>
 	<string name="_adm_stg_cpt_option_sys_live_updates_interval"><![CDATA[Live updates interval (in milliseconds)]]></string>
+	<string name="_adm_stg_cpt_option_sys_maps_api_key"><![CDATA[Google Maps API key]]></string>
 	<string name="_adm_stg_cpt_option_sys_oauth_key"><![CDATA[UNA account key]]></string>
 	<string name="_adm_stg_cpt_option_sys_oauth_secret"><![CDATA[UNA account secret]]></string>
 	<string name="_adm_stg_cpt_option_sys_page_cache_enable"><![CDATA[Enable Page cache]]></string>
@@ -1887,7 +1888,8 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_layout_topbottom_area_2_columns"><![CDATA[Top&bottom areas with 2 columns in the middle]]></string>
 	<string name="_sys_loading"><![CDATA[Loading...]]></string>
 	<string name="_sys_location_country"><![CDATA[<i class="sys-icon location-arrow"></i> {0}]]></string>
-	<string name="_sys_location_country_city"><![CDATA[<i class="sys-icon location-arrow"></i> {1}, {0}]]></string>
+	<string name="_sys_location_country_city"><![CDATA[<i class="sys-icon location-arrow"></i> {2}, {1}, {0}]]></string>
+    <string name="_sys_location_country_city_street"><![CDATA[<i class="sys-icon location-arrow"></i> {4} {3}, {2}, {1}, {0} ]]></string>
 	<string name="_sys_location_determining"><![CDATA[Determining location...]]></string>
 	<string name="_sys_location_geolocation_not_supported_by_browser"><![CDATA[Geolocation is not supported by this browser]]></string>
 	<string name="_sys_location_undefined"><![CDATA[Location off]]></string>

+ 3 - 1
modules/boonex/market/install/sql/install.sql

@@ -192,6 +192,8 @@ CREATE TABLE `bx_market_meta_locations` (
   `state` varchar(255) NOT NULL,
   `city` varchar(255) NOT NULL,
   `zip` varchar(255) NOT NULL,
+  `street` varchar(255) NOT NULL,
+  `street_number` varchar(255) NOT NULL,
   PRIMARY KEY (`object_id`),
   KEY `country_state_city` (`country`,`state`(8),`city`(8))
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@@ -253,7 +255,7 @@ INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `ch
 ('bx_market', 'bx_market', 'delete_confirm', 1, '', 0, 'checkbox', '_bx_market_form_entry_input_sys_delete_confirm', '_bx_market_form_entry_input_delete_confirm', '_bx_market_form_entry_input_delete_confirm_info', 1, 0, 0, '', '', '', 'Avail', '', '_bx_market_form_entry_input_delete_confirm_error', '', '', 1, 0),
 ('bx_market', 'bx_market', 'do_publish', '_bx_market_form_entry_input_do_publish', '', 0, 'submit', '_bx_market_form_entry_input_sys_do_publish', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_market', 'bx_market', 'do_submit', '_bx_market_form_entry_input_do_submit', '', 0, 'submit', '_bx_market_form_entry_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
-('bx_market', 'bx_market', 'location', '', '', 0, 'custom', '_sys_form_input_sys_location', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'location', '', '', 0, 'location', '_sys_form_input_sys_location', '_sys_form_input_location', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_market', 'bx_market', 'pictures', 'a:1:{i:0;s:15:"bx_market_html5";}', 'a:2:{s:16:"bx_market_simple";s:26:"_sys_uploader_simple_title";s:15:"bx_market_html5";s:25:"_sys_uploader_html5_title";}', 0, 'files', '_bx_market_form_entry_input_sys_pictures', '_bx_market_form_entry_input_pictures', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_market', 'bx_market', 'files', 'a:1:{i:0;s:15:"bx_market_html5";}', 'a:2:{s:16:"bx_market_simple";s:26:"_sys_uploader_simple_title";s:15:"bx_market_html5";s:25:"_sys_uploader_html5_title";}', 0, 'files', '_bx_market_form_entry_input_sys_files', '_bx_market_form_entry_input_files', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_market', 'bx_market', 'text', '', '', 0, 'textarea', '_bx_market_form_entry_input_sys_text', '_bx_market_form_entry_input_text', '', 1, 0, 2, '', '', '', 'Avail', '', '_bx_market_form_entry_input_text_err', 'XssHtml', '', 1, 0),

+ 0 - 3
modules/boonex/market/template/form_field_location.html

@@ -1,3 +0,0 @@
-
-<bx_include_base:../modules/base/general/template/form_field_location.html />
-

+ 3 - 1
modules/boonex/posts/install/sql/install.sql

@@ -121,6 +121,8 @@ CREATE TABLE `bx_posts_meta_locations` (
   `state` varchar(255) NOT NULL,
   `city` varchar(255) NOT NULL,
   `zip` varchar(255) NOT NULL,
+  `street` varchar(255) NOT NULL,
+  `street_number` varchar(255) NOT NULL,
   PRIMARY KEY (`object_id`),
   KEY `country_state_city` (`country`,`state`(8),`city`(8))
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@@ -175,7 +177,7 @@ INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `ch
 ('bx_posts', 'bx_posts', 'delete_confirm', 1, '', 0, 'checkbox', '_bx_posts_form_entry_input_sys_delete_confirm', '_bx_posts_form_entry_input_delete_confirm', '_bx_posts_form_entry_input_delete_confirm_info', 1, 0, 0, '', '', '', 'Avail', '', '_bx_posts_form_entry_input_delete_confirm_error', '', '', 1, 0),
 ('bx_posts', 'bx_posts', 'do_publish', '_bx_posts_form_entry_input_do_publish', '', 0, 'submit', '_bx_posts_form_entry_input_sys_do_publish', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_posts', 'bx_posts', 'do_submit', '_bx_posts_form_entry_input_do_submit', '', 0, 'submit', '_bx_posts_form_entry_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
-('bx_posts', 'bx_posts', 'location', '', '', 0, 'custom', '_sys_form_input_sys_location', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_posts', 'bx_posts', 'location', '', '', 0, 'location', '_sys_form_input_sys_location', '_sys_form_input_location', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_posts', 'bx_posts', 'pictures', 'a:1:{i:0;s:9:"sys_html5";}', 'a:2:{s:10:"sys_simple";s:26:"_sys_uploader_simple_title";s:9:"sys_html5";s:25:"_sys_uploader_html5_title";}', 0, 'files', '_bx_posts_form_entry_input_sys_pictures', '_bx_posts_form_entry_input_pictures', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_posts', 'bx_posts', 'text', '', '', 0, 'textarea', '_bx_posts_form_entry_input_sys_text', '_bx_posts_form_entry_input_text', '', 1, 0, 2, '', '', '', 'Avail', '', '_bx_posts_form_entry_input_text_err', 'XssHtml', '', 1, 0),
 ('bx_posts', 'bx_posts', 'title', '', '', 0, 'text', '_bx_posts_form_entry_input_sys_title', '_bx_posts_form_entry_input_title', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_posts_form_entry_input_title_err', 'Xss', '', 1, 0),

+ 0 - 3
modules/boonex/posts/template/form_field_location.html

@@ -1,3 +0,0 @@
-
-<bx_include_base:../modules/base/general/template/form_field_location.html />
-

+ 3 - 0
modules/boonex/protean/data/template/system/css/default.less

@@ -31,6 +31,9 @@
 	padding: @bx-content-padding-block;
 }
 
+#bx-logo {
+    margin-top:-@bx-content-padding-header;
+}
 
 /* shadow */
 .bx-shadow-header {

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

@@ -1190,7 +1190,8 @@
 	<string name="_adm_stg_cpt_option_sys_ftp_login"><![CDATA[FTP-сервер - Логин]]></string>
 	<string name="_adm_stg_cpt_option_sys_ftp_password"><![CDATA[FTP-сервер - Пароль]]></string>
 	<string name="_adm_stg_cpt_option_sys_install_time"><![CDATA[Дата установки]]></string>
-	<string name="_adm_stg_cpt_option_sys_live_updates_interval"><![CDATA[Интервал обновлений (в миллисекундах)]]></string>
+    <string name="_adm_stg_cpt_option_sys_live_updates_interval"><![CDATA[Интервал обновлений (в миллисекундах)]]></string>
+    <string name="_adm_stg_cpt_option_sys_maps_api_key"><![CDATA[Ключ Google Maps API]]></string>
 	<string name="_adm_stg_cpt_option_sys_oauth_key"><![CDATA[UNA-аккаунт - Key (ключ)]]></string>
 	<string name="_adm_stg_cpt_option_sys_oauth_secret"><![CDATA[UNA-аккаунт - Secret (секретное слово)]]></string>
 	<string name="_adm_stg_cpt_option_sys_page_cache_enable"><![CDATA[Задействовать кэш для Страниц]]></string>
@@ -1885,7 +1886,8 @@
 	<string name="_sys_layout_topbottom_area_2_columns"><![CDATA[Верхнее и нижнее пространства с 2 столбцами посередине]]></string>
 	<string name="_sys_loading"><![CDATA[Загрузка...]]></string>
 	<string name="_sys_location_country"><![CDATA[<i class="sys-icon location-arrow"></i> {0}]]></string>
-	<string name="_sys_location_country_city"><![CDATA[<i class="sys-icon location-arrow"></i> {1}, {0}]]></string>
+	<string name="_sys_location_country_city"><![CDATA[<i class="sys-icon location-arrow"></i> {2}, {1}, {0}]]></string>
+    <string name="_sys_location_country_city_street"><![CDATA[<i class="sys-icon location-arrow"></i> {4} {3}, {2}, {1}, {0} ]]></string>
 	<string name="_sys_location_determining"><![CDATA[Определение местоположения...]]></string>
 	<string name="_sys_location_geolocation_not_supported_by_browser"><![CDATA[Геолокация не поддерживается этим браузером]]></string>
 	<string name="_sys_location_undefined"><![CDATA[Отключить местоположение]]></string>

+ 3 - 0
modules/boonex/timeline/classes/BxTimelineFormPost.php

@@ -67,6 +67,9 @@ class BxTimelineFormPost extends BxBaseModGeneralFormEntry
 
         if(isset($this->aInputs['attachments']))
             $this->aInputs['attachments']['content'] = '__attachments_menu__';
+
+        if (isset($this->_oModule->_oConfig->CNF['FIELD_LOCATION_PREFIX']) && isset($this->aInputs[$this->_oModule->_oConfig->CNF['FIELD_LOCATION_PREFIX']]))
+            $this->aInputs[$this->_oModule->_oConfig->CNF['FIELD_LOCATION_PREFIX']]['manual_input'] = false;
     }
 
     public function getCode($bDynamicMode = false)

+ 3 - 1
modules/boonex/timeline/install/sql/install.sql

@@ -204,6 +204,8 @@ CREATE TABLE IF NOT EXISTS `bx_timeline_meta_locations` (
   `state` varchar(255) NOT NULL,
   `city` varchar(255) NOT NULL,
   `zip` varchar(255) NOT NULL,
+  `street` varchar(255) NOT NULL,
+  `street_number` varchar(255) NOT NULL,
   PRIMARY KEY (`object_id`),
   KEY `country_state_city` (`country`,`state`(8),`city`(8))
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@@ -269,7 +271,7 @@ INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `c
 ('bx_timeline_post', @sName, 'action', '', '', 0, 'hidden', '_bx_timeline_form_post_input_sys_action', '', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
 ('bx_timeline_post', @sName, 'owner_id', '0', '', 0, 'hidden', '_bx_timeline_form_post_input_sys_owner_id', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
 ('bx_timeline_post', @sName, 'text', '', '', 0, 'textarea', '_bx_timeline_form_post_input_sys_text', '_bx_timeline_form_post_input_text', '', 0, 0, 0, 'a:1:{s:12:"autocomplete";s:3:"off";}', '', '', '', '', '', 'Xss', '', 0, 0),
-('bx_timeline_post', @sName, 'location', '', '', 0, 'custom', '_sys_form_input_sys_location', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_timeline_post', @sName, 'location', '', '', 0, 'location', '_sys_form_input_sys_location', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 ('bx_timeline_post', @sName, 'link', '', '', 0, 'custom', '_bx_timeline_form_post_input_sys_link', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 ('bx_timeline_post', @sName, 'photo', 'a:1:{i:0;s:24:"bx_timeline_simple_photo";}', 'a:1:{s:24:"bx_timeline_simple_photo";s:26:"_sys_uploader_simple_title";}', 0, 'files', '_bx_timeline_form_post_input_sys_photo', '_bx_timeline_form_post_input_photo', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 ('bx_timeline_post', @sName, 'video', 'a:1:{i:0;s:24:"bx_timeline_simple_video";}', 'a:1:{s:24:"bx_timeline_simple_video";s:26:"_sys_uploader_simple_title";}', 0, 'files', '_bx_timeline_form_post_input_sys_video', '_bx_timeline_form_post_input_video', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),

+ 0 - 1
modules/boonex/timeline/template/form_field_location.html

@@ -1 +0,0 @@
-<bx_include_base:../modules/base/general/template/form_field_location.html />

+ 0 - 1
template/css/general.css

@@ -91,7 +91,6 @@
 
 #bx-logo {
     vertical-align:middle;
-    margin-top:-0.375rem;
 }
 
 /* --------------- submenu */

+ 144 - 0
template/form_field_location.html

@@ -0,0 +1,144 @@
+
+<div class="bx-form-input-location-cont bx-clearfix">
+    __input__
+    <bx_if:auto_input>
+        <div id="__id_status__" class="bx-def-margin-left">__location_string__</div>
+    </bx_if:auto_input>
+</div>
+
+<input type="hidden" name="__name___lat" value="__lat__" />
+<input type="hidden" name="__name___lng" value="__lng__" />
+<input type="hidden" name="__name___country" value="__country__" />
+<input type="hidden" name="__name___state" value="__state__" />
+<input type="hidden" name="__name___city" value="__city__" />
+<input type="hidden" name="__name___zip" value="__zip__" />
+<input type="hidden" name="__name___street" value="__street__" />
+<input type="hidden" name="__name___street_number" value="__street_number__" />
+
+<script>
+
+    var oBxLocationHashMap = {
+        '__name___lat': '',
+        '__name___lng': '',
+        '__name___city': 'locality',
+        '__name___state': 'administrative_area_level_1',
+        '__name___country': 'country',
+        '__name___zip': 'postal_code',
+        '__name___street': 'route',
+        '__name___street_number': 'street_number'
+    };
+
+    var bx_location_reset = function () {
+        for (sKey in oBxLocationHashMap)
+            $('[name="' + sKey + '"]').val('');
+    };
+
+    var bx_location_process_address = function (o) {
+        var i, sKey, sCountry, sCity;
+        for (i in o) {
+            for (sKey in oBxLocationHashMap) {
+                if (o[i].types.indexOf(oBxLocationHashMap[sKey]) > -1) {
+                    var sIndex = 'route' == oBxLocationHashMap[sKey] || 'locality' == oBxLocationHashMap[sKey] ? 'long_name' : 'short_name';
+                    $('[name="' + sKey + '"]').val(o[i][sIndex]);
+                }
+                
+                if (o[i].types.indexOf('locality') > -1)
+                    sCity = o[i].short_name;
+                else if (o[i].types.indexOf('country') > -1)
+                    sCountry = o[i].long_name;
+            }
+        }
+        if ('undefined' != typeof(sCity) && sCity.length)
+            $('#__id_status__').html(sCity + ", " + sCountry);
+        else
+            $('#__id_status__').html(sCountry);
+    };
+
+    var bx_location_geolocate = function () {
+        if (navigator.geolocation) {
+            navigator.geolocation.getCurrentPosition(function(position) {
+                var geolocation = {
+                    lat: position.coords.latitude,
+                    lng: position.coords.longitude
+                };
+                var circle = new google.maps.Circle({
+                    center: geolocation,
+                    radius: position.coords.accuracy
+                });
+                glBxAutocomplete__name__.setBounds(circle.getBounds());
+            });
+        }
+    }
+
+    $('input[name=__name__][type=checkbox]').on('change', function () {
+
+        var callbackOnLocationReset = function (error) {
+            var sKey;
+            for (sKey in oBxLocationHashMap) 
+                $('[name="' + sKey + '"]').val('');
+            $('#__id_status__').html("<bx_text_js:_sys_location_undefined />");
+        }
+
+        var callbackOnLocationSucess = function (position) {
+            bx_location_reset ();
+
+            $('[name="__name___lat"]').val(position.coords.latitude);
+            $('[name="__name___lng"]').val(position.coords.longitude);
+
+            var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
+            var geocoder = new google.maps.Geocoder();
+
+            geocoder.geocode({'latLng': latlng}, function (results, status) {
+                if (status == google.maps.GeocoderStatus.OK) {
+                    bx_location_process_address(results[0]['address_components']);
+                } 
+                else {
+                    $('#__id_status__').html(status);
+                }
+            });
+
+        }
+
+        if ($(this).is(':checked')) {
+            $('#__id_status__').html('<bx_text_js:_sys_location_determining />');
+            if (navigator.geolocation)
+                navigator.geolocation.getCurrentPosition(callbackOnLocationSucess, callbackOnLocationReset);
+            else
+                $('#__id_status__').html('<bx_text_js:_sys_location_geolocation_not_supported_by_browser />');
+        } else {
+            callbackOnLocationReset();
+        }
+    });
+
+
+    $(document).ready(function () {
+
+        var callbackFillInAddress = function () {
+            // Get the place details from the autocomplete object.
+            var place = glBxAutocomplete__name__.getPlace();
+
+            bx_location_reset ();
+
+            $('[name="__name___lat"]').val(place.geometry.location.lat);
+            $('[name="__name___lng"]').val(place.geometry.location.lng);
+            
+            bx_location_process_address(place.address_components);
+        }
+        
+        $('input[name=__name__][type=text]').on('focus', bx_location_geolocate);
+
+        if ($('input[name=__name__][type=text]').size()) {
+
+            // Create the autocomplete object, restricting the search to geographical location types.
+            glBxAutocomplete__name__ = new google.maps.places.Autocomplete(
+                /** @type {!HTMLInputElement} */(document.getElementById('__id_input__')),
+                {types: ['geocode']});
+
+            // When the user selects an address from the dropdown, populate the address fields in the form.
+            glBxAutocomplete__name__.addListener('place_changed', callbackFillInAddress);
+        }
+
+    });
+
+</script>
+

+ 62 - 0
template/scripts/BxBaseFormView.php

@@ -614,6 +614,10 @@ BLAH;
                 $sInput = $this->genInputCaptcha($aInput);
             break;
 
+            case 'location':
+                $sInput = $this->genInputLocation($aInput);
+            break;
+
             case 'value':
                 $sInput = isset($aInput['value']) ? $aInput['value'] : '';
             break;
@@ -1074,6 +1078,64 @@ BLAH;
         return $sCode;
     }
 
+    function genInputLocation(&$aInput)
+    {
+        $isManualInput = (int)(isset($aInput['manual_input']) && $aInput['manual_input']);
+        $sIdStatus = $this->getInputId($aInput) . '_status';
+        $sIdInput = $this->getInputId($aInput) . '_location';
+        $sProto = (0 == strncmp('https', BX_DOL_URL_ROOT, 5)) ? 'https' : 'http';
+        $this->oTemplate->addJs($sProto . '://maps.google.com/maps/api/js?libraries=places&language=' . bx_lang_name() . '&key=' . trim(getParam('sys_maps_api_key')));
+
+        $aVars = array (
+            'name' => $aInput['name'],
+            'id_status' => $sIdStatus,
+            'id_input' => $sIdInput,
+            'manual_input' => $isManualInput,            
+            'bx_if:manual_input' => array(
+                'condition' => $isManualInput,
+                'content' => array(),
+            ),
+            'bx_if:auto_input' => array(
+                'condition' => !$isManualInput,
+                'content' => array(
+                    'id_status' => $sIdStatus,
+                    'location_string' => _t('_sys_location_undefined'),
+                ),
+            ),            
+        );
+        $aLocationIndexes = array ('lat', 'lng', 'country', 'state', 'city', 'zip', 'street', 'street_number');
+        foreach ($aLocationIndexes as $sKey)
+            $aVars[$sKey] = $this->getLocationVal($aInput, $sKey);
+        if ($aVars['country']) {
+            $aCountries = BxDolFormQuery::getDataItems('Country');
+            $s = ($aVars['street_number'] ? $aVars['street_number'] . ', ' : '') . ($aVars['street'] ? $aVars['street'] . ', ' : '') . ($aVars['city'] ? $aVars['city'] . ', ' : '') . ($aVars['state'] ? $aVars['state'] . ', ' : '') . $aCountries[$aVars['country']];
+            $aVars['bx_if:auto_input']['content']['location_string'] = $s;
+        }
+
+        if ($isManualInput) {
+            $aInput['type'] = 'text';
+            $aInput['attrs']['id'] = $sIdInput;
+            $aVars['input'] = $this->genInputStandard($aInput);
+        } 
+        else {
+            if ($this->getLocationVal($aInput, 'lat') && $this->getLocationVal($aInput, 'lng'))
+                $aInput['checked'] = true;
+            else
+                $aInput['checked'] = $this->getCleanValue($aInput['name'] . '_lat') && $this->getCleanValue($aInput['name'] . '_lng') ? 1 : 0;
+            $aVars['input'] = $isManualInput ? $this->genInputStandard($aInput) : $this->genInputSwitcher($aInput);
+        }
+
+        return $this->oTemplate->parseHtmlByName('form_field_location.html', $aVars);
+    }
+
+    protected function getLocationVal ($aInput, $sIndex) 
+    {
+        $s = $aInput['name'] . '_' . $sIndex;
+        if (isset($this->_aSpecificValues[$s]))
+            return $this->_aSpecificValues[$s];
+        return $this->getCleanValue($s);
+    }
+    
     function genInputCaptcha(&$aInput)
     {
         $aAttrs = empty($aInput['attrs']) ? array() : $aInput['attrs'];

+ 4 - 2
template/scripts/BxBaseServiceMetatags.php

@@ -78,8 +78,10 @@ class BxBaseServiceMetatags extends BxDol
      * @param $iId content id
      * @return map HTML string
      */
-    public function serviceLocationsMap ($sObject, $iId, $sMapSize = '1000x144', $sMapKey = '')
+    public function serviceLocationsMap ($sObject, $iId, $sMapSize = '1000x144')
     {
+        $sMapKey = trim(getParam('sys_maps_api_key'));
+
         $o = BxDolMetatags::getObjectInstance($sObject);
         $sLocationHtml = $o->locationsString($iId);
         if (!$sLocationHtml)
@@ -88,7 +90,7 @@ class BxBaseServiceMetatags extends BxDol
         $sLocationEncoded = rawurlencode(strip_tags($sLocationHtml));
         $sProto = (0 == strncmp('https', BX_DOL_URL_ROOT, 5)) ? 'https' : 'http';
         $iScale = isset($_COOKIE['devicePixelRatio']) && (int)$_COOKIE['devicePixelRatio'] >= 2 ? 2 : 1;
-        $sLang = BxDolLanguages::getInstance()->getCurrentLanguage();
+        $sLang = bx_lang_name();
         $aVars = array (
             'map_img' => $sProto . '://maps.googleapis.com/maps/api/staticmap?center=' . $sLocationEncoded . '&zoom=7&size=' . $sMapSize . '&maptype=roadmap&markers=size:small%7C' . $sLocationEncoded . '&scale=' . $iScale . '&language=' . $sLang  . ($sMapKey ? '&key=' . $sMapKey : ''),
             'location_string' => $sLocationHtml,