Определение города на сайте, кто как реализовывал?

Этой теме почти 2 года, а хоть какого-то решения так и не появилось?
Есть хоть одно , платное или бесплатное, рабочее решение определения города России по IP для Prestashop?
Готовый модуль или хотя бы кусок кода?
romeo143, Zix , Jackk, что можете посоветовать?
Есть пример определения "Страны", "Региона", "Города"
Если бы кто доработал, чтобы эти значения подставлялись в поля Страна, Регион и город...
Вместо "#user-city", "#user-region", "#user-country" прописать переменные престашоп?
Код:
<html>
<body>
<script src="http://yastatic.net/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
  window.onload = function () {
    jQuery("#user-city").text(ymaps.geolocation.city);
    jQuery("#user-region").text(ymaps.geolocation.region);
    jQuery("#user-country").text(ymaps.geolocation.country);  }
</script>
<script src="http://api-maps.yandex.ru/2.0-stable/?load=package.standard&lang=ru-RU" type="text/javascript"></script>
<div>Vi prozhivaete v gorode - <span id="user-city"></span></div> <div id="user-region"></div> <div id="user-country"></div>
</body>
</html>
 
Последнее редактирование:
Есть пример определения "Страны", "Региона", "Города"
Если бы кто доработал, чтобы эти значения подставлялись в поля Страна, Регион и город...
Вместо "#user-city", "#user-region", "#user-country" прописать переменные престашоп?
Код:
<html>
<body>
<script src="http://yastatic.net/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
  window.onload = function () {
    jQuery("#user-city").text(ymaps.geolocation.city);
    jQuery("#user-region").text(ymaps.geolocation.region);
    jQuery("#user-country").text(ymaps.geolocation.country);  }
</script>
<script src="http://api-maps.yandex.ru/2.0-stable/?load=package.standard&lang=ru-RU" type="text/javascript"></script>
<div>Vi prozhivaete v gorode - <span id="user-city"></span></div> <div id="user-region"></div> <div id="user-country"></div>
</body>
</html>
В PS страна и регион это выпадающие списки, там нужны айдишники соответствующих стран и регионов. Для города попробуйте заменить "#user-city" на "#city" для PS 1.6 и "input[name='city']" для PS 1.7 (в случае если стандартно все, без навороченных модулей).
 
Код:
$( document ).ready( function( ) {
    $( '#city' ).autocomplete( urlMap.cityPanel, {
        extraParams: { action: 'cityAc' },
        minChars: 0,
        selectFirst: false,
        scroll: true,
        width: 'auto',
        max: 50,
        dataType: 'json',
        formatItem: function( data, i, max, value, term ) {
            return value;
        },
        parse: function( data ) {
            var ret = new Array( );
            for( var i = 0; i < data.length; ++i ) {
                ret.push( { data: data[ i ], value: data[ i ].title } );
            }
           
            return ret;
        }
    } ).result( function( e, data, formatted ) {
        $( '#city_panel' ).append( '<img src="/img/loader.gif" alt=""/>' );
       
        $( '#city' ).val( data.city );
        $( '#region' ).val( data.region );
       
        $.ajax( {
            url: urlMap.cityPanel,
            data: {
                ajax: true,
                action: 'update',
                city: data.city,
                region: data.region
            },
            dataType: 'json',
            complete: function( request, status ) {
                window.location.reload( false );
            }
        } );
    } );
   
    $( '#region' ).autocomplete( urlMap.cityPanel, {
        extraParams: { action: 'regionAc' },
        minChars: 0,
        selectFirst: false,
        scroll: true,
        max: 50,
        dataType: 'json',
        formatItem: function( data, i, max, value, term ) {
            return value;
        },
        parse: function( data ) {
            var ret = new Array( );
            for( var i = 0; i < data.length; ++i ) {
                ret.push( { data: data[ i ], value: data[ i ] } );
            }
           
            return ret;
        }
    } ).result( function( e, data, formatted ) {
        $( '#city_panel' ).append( '<img src="/img/loader.gif" alt=""/>' );
       
        $( '#region' ).val( data );
       
        $.ajax( {
            url: urlMap.cityPanel,
            data: {
                ajax: true,
                action: 'update',
                region: data
            },
            dataType: 'json',
            complete: function( request, status ) {
                window.location.reload( false );
            }
        } );
    } );
} );
 
Код:
<?php
    /**
     * Контроллер общего назначения
     */
    class timecostdeliverycitypanelModuleFrontController extends ModuleFrontController {
        public $ajax = true;
       
        public function init( ) {
            parent::init( );
           
            header( 'Content-Type: text/json; charset=UTF-8', true );
           
            $action = ( string ) Tools::getValue( 'action' );
           
            switch( $action ) {
                case 'cityAc':        $this->ActionCityAc( );        break;
                case 'regionAc':    $this->ActionRegionAc( );    break;
                case 'update':        $this->ActionUpdate( );        break;
            }
        }
       
        /**
         * Автокомплит города
         */
        private function ActionCityAc( ) {
            $result = array( );
            $q = ( string ) Tools::getValue( 'q' );
            $query = Location::FindCity( $q );
            while( $obj = $query->fetchObject( ) ) {
                $title = '';
                   
                if ( !empty( $obj->type ) ) {
                    $title .= $obj->type.'. ';
                }
                   
                $title .= $obj->title;
                   
                if ( !empty( $obj->region ) ) {
                    $title .= ' ('.$obj->region.')';
                }
                   
                $result[ ] = array(
                    'title'        => $title,
                    'city'        => $obj->title,
                    'region'     => $obj->region
                );
            }
           
            echo json_encode( $result );
            exit;
        }
       
        /**
         * Автокомплит региона
         */
        private function ActionRegionAc( ) {
            $db = Db::getInstance( );
            $q = ( string ) Tools::getValue( 'q' );
            $result = array( );
           
            $query = $db->query( 'SELECT `title_full` `title` FROM `'._DB_PREFIX_.'tcd_ref_region` WHERE `title_full` LIKE \'%'.$db->escape( $q ).'%\' ORDER BY `title` ASC' );
            while( $obj = $query->fetchObject( ) ) {
                $result[ ] = $obj->title;
            }
           
            echo json_encode( $result );
            exit;
        }
       
        /**
         * Обновление города и региона
         */
        private function ActionUpdate( ) {
            $city = ( string ) Tools::getValue( 'city' );
            if ( !empty( $city ) ) {
                $this->module->SetCity( $city );
            }
           
            $region = ( string ) Tools::getValue( 'region' );
            if ( !empty( $region ) ) {
                $this->module->SetRegion( $region );
            }
           
            echo json_encode( 1 );
            exit;
        }
    }
 
Код:
<?php
    /**
     * Пункты приема/отправки
     */
    class Location extends ObjectModel {
        const    LOCATION_CITY    = 0,
                LOCATION_REGION    = 1;
       
        public    $id        = NULL,
                $code    = NULL,
                $title    = NULL,
                $api    = NULL,
                $type    = self::LOCATION_CITY;
       
        public static $definition = array(
            'table' => 'tcd_location',
            'primary' => 'id_location',
            'multilang' => false,
            'fields' => array(
                'code'    => array( 'type' => self::TYPE_STRING, 'required' => true ),
                'title'    => array( 'type' => self::TYPE_STRING, 'required' => true ),
                'api'    => array( 'type' => self::TYPE_STRING, 'required' => true ),
                'type'    => array( 'type' => self::TYPE_INT )
            )
        );
       
        /**
         * Выборка локаций по названию города, опционально еще по API
         *
         * @param string $city наименование локации
         * @param string $api наименование API
         * @param bool $strict строгое совпадение по названию
         */
        public static function GetByCity( $city, $api = NULL, $strict = true ) {
            return self::GetByTitle( $city, self::LOCATION_CITY, $api, $strict );
        }
       
        /**
         * Выборка по названию, типу и апи
         */
        public static function GetByTitle( $title, $type, $api, $strict = true ) {
            $ret = array( );
            $db = Db::getInstance( );
            $szQuery = 'SELECT `id_location` FROM `'._DB_PREFIX_.'tcd_location` WHERE `type`='.$type.' AND ';
           
            if ( is_array( $title ) ) {
                $tmp = array( );
                foreach( $title as $value ) {
                    if ( $strict ) {
                        $tmp[ ] = 'LOWER(`title`)=\''.$db->escape( mb_strtolower( $value, 'UTF-8' ) ).'\'';
                    } else {
                        $tmp[ ] = '`title` LIKE \'%'.$db->escape( $value ).'%\'';
                    }
                }
                $szQuery .= join( ' AND ', $tmp );
            } elseif ( $strict ) {
                $szQuery .= 'LOWER(`title`)=\''.$db->escape( mb_strtolower( $title, 'UTF-8' ) ).'\'';
            } else {
                $szQuery .= '`title` LIKE \'%'.$db->escape( $title ).'%\'';
            }
           
            $szQuery .= 'AND `api`=\''.$db->escape( $api ).'\'';
            $query = $db->query( $szQuery );
           
            while( $obj = $query->fetchObject( ) ) {
                $ret[ ] = new Location( ( int ) $obj->id_location );
            }
           
            return $ret;
        }
       
        /**
         * Подготовка названия города к поиску локации
         *
         * формат города: город (регион)
         *
         * если для города задан регион, то локации надо искать по сочетанию города и региона
         * если не найден по город+регион, то по городу (сначала точное совпадение, потом частичное)
         * просто склеивать название города и региона
         */
        public static function PrepareCityForAddress( $city, $region ) {
            $regions = self::GetRegionsByCity( $city );
            $lcRegion = mb_strtolower( $region );
           
            foreach( $regions as $obj ) {
                $currentRegion = mb_strtolower( trim( $obj->title_full ) );
               
                if ( $currentRegion == $lcRegion ) {
                    return $city.' ('.trim( $obj->title_full ).')';
                }
            }
           
            // в итоге, если не будет найден регион, то будет указан в ручную, если был введен
            return $city.( empty( $region ) ? '' : ' ('.$region.')' );
        }
       
        /**
         * Проверяет наличие города
         */
        public static function CityExists( $title, $strict = false ) {
            $db = Db::getInstance( );
           
            return ( bool ) $db->getValue( 'SELECT COUNT(*) FROM `'._DB_PREFIX_.'tcd_ref_city` WHERE `title`'.( $strict ? '=\''.$db->escape( $title ).'\'' : ' LIKE \'%'.$db->escape( $title ).'%\'' ) );
        }
       
        /**
         * Проверяет наличие региона
         */
        public static function RegionExists( $title, $strict = false ) {
            $db = Db::getInstance( );
           
            return ( bool ) $db->getValue( 'SELECT COUNT(*) FROM `'._DB_PREFIX_.'tcd_ref_region` WHERE `title_full`'.( $strict ? '=\''.$db->escape( $title ).'\'' : ' LIKE \'%'.$db->escape( $title ).'%\'' ) );
        }
       
        public static function CityAndRegionExists( $cityTitle, $regionTitle, $strict = false ) {
            $db = Db::getInstance( );
           
            return ( bool ) $db->getValue(
                'SELECT COUNT(*) FROM `'._DB_PREFIX_.'tcd_ref_city` c LEFT JOIN `'._DB_PREFIX_.'tcd_ref_region` r ON r.`id`=c.`region_id`'.
                'WHERE c.`title`'.( $strict ? '=\''.$db->escape( $cityTitle ).'\'' : ' LIKE \'%'.$db->escape( $cityTitle ).'%\'' ).
                ' AND r.`title_full`'.( $strict ? '=\''.$db->escape( $regionTitle ).'\'' : ' LIKE \'%'.$db->escape( $regionTitle ).'%\'' )
            );
        }
       
        /**
         * Получение регионов, в которых встречается данный город
         */
        public static function GetRegionsByCity( $title ) {
            $ret = array( );
           
            if ( self::CityExists( $title ) && ( $title != '' ) ) {
                $db = Db::getInstance( );
                $query = $db->query( 'SELECT r.* FROM `'._DB_PREFIX_.'tcd_ref_city` c LEFT JOIN `'._DB_PREFIX_.'tcd_ref_region` r ON r.`id`=c.`region_id` WHERE c.`title` LIKE \'%'.$db->escape( $title ).'%\' ORDER BY r.`title` ASC' );
               
                while( $obj = $query->fetchObject( ) ) {
                    $ret[ ] = $obj;
                }
            }
           
            return $ret;
        }
       
        /**
         * Выборка первого региона из справочников
         */
        public static function GetFirstRegion( ) {
            $db = Db::getInstance( );
            $query = $db->query( 'SELECT * FROM `'._DB_PREFIX_.'tcd_ref_region` ORDER BY `title` ASC LIMIT 1' );
           
            return $query->fetchObject( );
        }
       
        /**
         * Поиск столицы региона
         */
        public static function GetRegionCapital( $title ) {
            $db = Db::getInstance( );
            $title = mb_strtolower( $title, 'UTF-8' );
            $query = $db->query( 'SELECT c.* FROM `'._DB_PREFIX_.'tcd_ref_city` c LEFT JOIN `'._DB_PREFIX_.'tcd_ref_region` r ON r.`id`=c.`region_id` WHERE LOWER(r.`title_full`)=\''.$db->escape( $title ).'\' AND c.`is_capital`=1 LIMIT 1' );
           
            return ( $query === false ) ? false : $query->fetchObject( );
        }
       
        /**
         * Поиск региона по столице
         */
        public static function GetRegionByCapital( $title ) {
            $db = Db::getInstance( );
            $title = mb_strtolower( $title, 'UTF-8' );
            $query = $db->query( 'SELECT r.* FROM `'._DB_PREFIX_.'tcd_ref_city` c LEFT JOIN `'._DB_PREFIX_.'tcd_ref_region` r ON r.`id`=c.`region_id` WHERE LOWER(c.`title`)=\''.$db->escape( $title ).'\' AND c.`is_capital`=1 LIMIT 1' );
           
            return ( $query === false ) ? false : $query->fetchObject( );
        }
       
        /**
         * Поиск региона на названию
         */
        public static function GetRegionByTitle( $title ) {
            $db = Db::getInstance( );
            $title = mb_strtolower( $title, 'UTF-8' );
            $title = $db->escape( $title );
            $query = $db->query( 'SELECT * FROM `'._DB_PREFIX_.'tcd_ref_region` WHERE LOWER(`title_full`)=\''.$title.'\' OR LOWER(`title_full`) LIKE \'%'.$title.'%\' LIMIT 1' );
           
            return ( $query === false ) ? false : $query->fetchObject( );
        }
       
        /**
         * Замена сокращений в названиях регионов
         */
        public static function ReplaceShort( $value ) {
            return preg_replace(
                array( '/респ\./', '/обл\./' ),
                array( 'республика', 'область' ),
                $value
            );
        }
       
        /**
         * Вырезает регион из названия города
         * возвращает оба значения
         */
        public static function StripRegion( $title ) {
            $city = $region = '';
           
            if ( preg_match( '/^([^\)]*)\((.*)\)$/', $title, $matches ) ) {
                $city = trim( $matches[ 1 ] );
                $region = trim( $matches[ 2 ] );
            } else {
                $city = $title;
            }
           
            return array( $city, $region );
        }
       
        /**
         * Поиск города по части названия
         */
        public static function FindCity( $title, $limit = 100 ) {
            $db = Db::getInstance( );
           
            return $db->query(
                //'SELECT c.`type`, c.`region_id`, c.`title` `title`, r.`title_full` `region`, CONCAT(a.`title`, \' \', a.`type`) `area` '.
                'SELECT c.`type`, c.`region_id`, c.`title` `title`, r.`title_full` `region`, CONCAT(c.`region_code`, c.`title`) `pair`, '.
                'CONCAT(c.`type`, c.`title`, r.`title_full`) `full`'.
                'FROM `'._DB_PREFIX_.'tcd_ref_city` c '.
                'LEFT JOIN `'._DB_PREFIX_.'tcd_ref_region` r ON r.`id`=c.`region_id` '.
                //'LEFT JOIN `'._DB_PREFIX_.'tcd_ref_area` a ON a.`id`=c.`area_id` '.
                'WHERE c.`title` LIKE \'%'.$db->escape( $title ).'%\' '.
                'GROUP BY `pair` ORDER BY `full` ASC LIMIT '.$limit
            );
        }
    }
 
Ребята, действительно, у кого есть наработка Зикса, выложите сюда. Чтобы мы могли ознакомиться и довести до ума...
 
Назад
Сверху