├── README.md ├── app ├── code │ └── community │ │ └── Sandfox │ │ └── GeoIP │ │ ├── Block │ │ ├── Adminhtml │ │ │ └── Notifications.php │ │ └── System │ │ │ └── Config │ │ │ ├── Status.php │ │ │ └── Synchronize.php │ │ ├── Helper │ │ └── Data.php │ │ ├── Model │ │ ├── Abstract.php │ │ ├── Country.php │ │ ├── Cron.php │ │ ├── Info.php │ │ ├── Observer.php │ │ └── Wrapper.php │ │ ├── controllers │ │ └── Adminhtml │ │ │ └── GeoipController.php │ │ └── etc │ │ ├── config.xml │ │ └── system.xml ├── design │ └── adminhtml │ │ └── default │ │ └── default │ │ ├── layout │ │ └── sandfox │ │ │ └── geoip.xml │ │ └── template │ │ └── sandfox │ │ └── geoip │ │ ├── notifications.phtml │ │ └── system │ │ └── config │ │ └── synchronize.phtml └── etc │ └── modules │ └── Sandfox_GeoIP.xml ├── composer.json └── modman /README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | This extension allows you to use free [GeoIP Lite](http://www.maxmind.com/app/geolite) database by [MaxMind](http://www.maxmind.com/) with your Magento installation. 5 | 6 | Installation 7 | ============ 8 | 9 | Just copy all files to your Magento installation respecting directory structure. Make sure your `var` directory is writable by web-server user (by default it should be). If you want GeoIP database to be updated automatically make sure your Magento cron-job is set up and running. Logging out and in is not required. 10 | 11 | Configuration 12 | ============= 13 | 14 | After installation a new field will be added to *System\Configuration\General\General\Countries Options* group indicating the date of last database update and the button to force synchronization. Note that frequent synchronizations will result you being banned at MaxMind server for several hours. MaxMind GeoIP Lite database is updated on first Thursday of the month so if you have have Magento cron-job running you will not need to force synchronization anymore but on the first run. 15 | 16 | Usage 17 | ===== 18 | 19 | This extension only adds MaxMind GeoIP Lite database to your Magento installation and maintains its updates. It doesn't do anything else out of the box (yet). However if comes with a set of methods you can implement in your template or extension. 20 | 21 | $geoIP = Mage::getSingleton('geoip/country'); 22 | 23 | /** 24 | * Returns you the ISO 3166-1 code of visitors country. 25 | */ 26 | echo $geoIP->getCountry(); 27 | 28 | /** 29 | * Returns true or false depending if current visitors country is among allowed countries. 30 | * If there are no allowed countries in the system returns true. 31 | */ 32 | if ($geoIP->isCountryAllowed()) { 33 | // ... 34 | } 35 | 36 | /** 37 | * Adds country (or array of countries) to list of allowed countries. 38 | */ 39 | $geoIP->addAllowedCountry('DE'); 40 | $geoIP->addAllowedCountry(array( 41 | 'US', 42 | 'CA' 43 | )); 44 | 45 | /** 46 | * Or just get a country code of a specific IP 47 | */ 48 | echo $geoIP->getCountryByIp('94.230.212.77'); 49 | 50 | Please note that `geoip/country` is initialized at each Magento load. In order to save system resources please always use it as a singleton. 51 | 52 | The list of allowed countries is initially populated from *System\Configuration\General\General\Countries Options\Alowed Countries* multi-select field of your Magento configuration. The `addAllowedCountry` method is not adding country to system configuration but adds it to internal list extension uses for `isCountryAllowed` method. 53 | 54 | Global Restrict 55 | =============== 56 | 57 | To globally restrict access to your site by IP consider extending the controller_front_init_before event in your own module and add dependancy to geoip 58 | 59 | Credits 60 | ======= 61 | 62 | Thanks a lot to MaxMind for providing a free database. Additionally this extension partly uses the code from [MaxMind GeoIP PHP API](http://www.maxmind.com/download/geoip/api/php/). 63 | -------------------------------------------------------------------------------- /app/code/community/Sandfox/GeoIP/Block/Adminhtml/Notifications.php: -------------------------------------------------------------------------------- 1 | checkFilePermissions(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/code/community/Sandfox/GeoIP/Block/System/Config/Status.php: -------------------------------------------------------------------------------- 1 | unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue(); 14 | return parent::render($element); 15 | } 16 | 17 | protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) 18 | { 19 | /** @var $info Sandfox_GeoIP_Model_Info */ 20 | $info = Mage::getModel('geoip/info'); 21 | if ($date = $info->getDatFileDownloadDate()) { 22 | $format = Mage::app()->getLocale()->getDateTimeFormat(Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM); 23 | $date = Mage::app()->getLocale()->date(intval($date))->toString($format); 24 | } else { 25 | $date = '-'; 26 | } 27 | return '
' . $date . '
'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/code/community/Sandfox/GeoIP/Block/System/Config/Synchronize.php: -------------------------------------------------------------------------------- 1 | setTemplate('sandfox/geoip/system/config/synchronize.phtml'); 12 | } 13 | 14 | /** 15 | * Remove scope label 16 | * 17 | * @param Varien_Data_Form_Element_Abstract $element 18 | * @return string 19 | */ 20 | public function render(Varien_Data_Form_Element_Abstract $element) 21 | { 22 | $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue(); 23 | return parent::render($element); 24 | } 25 | 26 | /** 27 | * Return element html 28 | * 29 | * @param Varien_Data_Form_Element_Abstract $element 30 | * @return string 31 | */ 32 | protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) 33 | { 34 | return $this->_toHtml(); 35 | } 36 | 37 | /** 38 | * Return ajax url for synchronize button 39 | * 40 | * @return string 41 | */ 42 | public function getAjaxSyncUrl() 43 | { 44 | return Mage::getSingleton('adminhtml/url')->getUrl('adminhtml/geoip/synchronize'); 45 | } 46 | 47 | /** 48 | * Return ajax url for synchronize button 49 | * 50 | * @return string 51 | */ 52 | public function getAjaxStatusUpdateUrl() 53 | { 54 | return Mage::getSingleton('adminhtml/url')->getUrl('adminhtml/geoip/status'); 55 | } 56 | 57 | /** 58 | * Generate synchronize button html 59 | * 60 | * @return string 61 | */ 62 | public function getButtonHtml() 63 | { 64 | /** @var $button Mage_Adminhtml_Block_Widget_Button */ 65 | $button = $this->getLayout()->createBlock('adminhtml/widget_button'); 66 | $button->setData(array( 67 | 'id' => 'synchronize_button', 68 | 'label' => $this->helper('adminhtml')->__('Synchronize'), 69 | 'onclick' => 'javascript:synchronize(); return false;' 70 | )); 71 | 72 | return $button->toHtml(); 73 | } 74 | 75 | /** 76 | * Retrieve last sync params settings 77 | * 78 | * Return array format: 79 | * array ( 80 | * => storage_type int, 81 | * => connection_name string 82 | * ) 83 | * 84 | * @return array 85 | */ 86 | public function getSyncStorageParams() 87 | { 88 | $flag = Mage::getSingleton('core/file_storage')->getSyncFlag(); 89 | $flagData = $flag->getFlagData(); 90 | 91 | if ($flag->getState() == Mage_Core_Model_File_Storage_Flag::STATE_NOTIFIED 92 | && is_array($flagData) 93 | && isset($flagData['destination_storage_type']) && $flagData['destination_storage_type'] != '' 94 | && isset($flagData['destination_connection_name']) 95 | ) { 96 | $storageType = $flagData['destination_storage_type']; 97 | $connectionName = $flagData['destination_connection_name']; 98 | } else { 99 | $storageType = Mage_Core_Model_File_Storage::STORAGE_MEDIA_FILE_SYSTEM; 100 | $connectionName = ''; 101 | } 102 | 103 | return array( 104 | 'storage_type' => $storageType, 105 | 'connection_name' => $connectionName 106 | ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /app/code/community/Sandfox/GeoIP/Helper/Data.php: -------------------------------------------------------------------------------- 1 | local_dir = 'geoip'; 10 | $this->local_file = $this->getAbsoluteDirectoryPath() . '/' . $this->local_dir . '/GeoIP.dat'; 11 | $this->local_archive = $this->getAbsoluteDirectoryPath() . '/' . $this->local_dir . '/GeoIP.dat.gz'; 12 | $this->remote_archive = 'http://www.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz'; 13 | } 14 | 15 | public function getArchivePath() 16 | { 17 | return $this->local_archive; 18 | } 19 | 20 | public function getRelativeDirectoryPath() 21 | { 22 | return Mage::getStoreConfig('general/country/geoip_directory'); 23 | } 24 | 25 | public function getAbsoluteDirectoryPath() 26 | { 27 | return Mage::getBaseDir($this->getRelativeDirectoryPath()); 28 | } 29 | 30 | public function checkFilePermissions() 31 | { 32 | /** @var $helper Sandfox_GeoIP_Helper_Data */ 33 | $helper = Mage::helper('geoip'); 34 | 35 | $relativeDirPath = $this->getRelativeDirectoryPath(); 36 | 37 | $dir = $this->getAbsoluteDirectoryPath() . '/' . $this->local_dir; 38 | if (file_exists($dir)) { 39 | if (!is_dir($dir)) { 40 | return sprintf($helper->__('%s exists but it is file, not dir.'), "$relativeDirPath/{$this->local_dir}"); 41 | } elseif ((!file_exists($this->local_file) || !file_exists($this->local_archive)) && !is_writable($dir)) { 42 | return sprintf($helper->__('%s exists but files are not and directory is not writable.'), "$relativeDirPath/{$this->local_dir}"); 43 | } elseif (file_exists($this->local_file) && !is_writable($this->local_file)) { 44 | return sprintf($helper->__('%s is not writable.'), "$relativeDirPath/{$this->local_dir}" . '/GeoIP.dat'); 45 | } elseif (file_exists($this->local_archive) && !is_writable($this->local_archive)) { 46 | return sprintf($helper->__('%s is not writable.'), "$relativeDirPath/{$this->local_dir}" . '/GeoIP.dat.gz'); 47 | } 48 | } elseif (!@mkdir($dir)) { 49 | return sprintf($helper->__('Can\'t create %s directory.'), "$relativeDirPath/{$this->local_dir}"); 50 | } 51 | 52 | return ''; 53 | } 54 | 55 | public function update(){ 56 | /** @var $helper Sandfox_GeoIP_Helper_Data */ 57 | $helper = Mage::helper('geoip'); 58 | 59 | $ret = array('status' => 'error'); 60 | 61 | if ($permissions_error = $this->checkFilePermissions()) { 62 | $ret['message'] = $permissions_error; 63 | } else { 64 | $remote_file_size = $helper->getSize($this->remote_archive); 65 | if ($remote_file_size < 100000) { 66 | $ret['message'] = $helper->__('You are banned from downloading the file. Please try again in several hours.'); 67 | } else { 68 | /** @var $_session Mage_Core_Model_Session */ 69 | $_session = Mage::getSingleton('core/session'); 70 | $_session->setData('_geoip_file_size', $remote_file_size); 71 | 72 | $src = fopen($this->remote_archive, 'r'); 73 | $target = fopen($this->local_archive, 'w'); 74 | stream_copy_to_stream($src, $target); 75 | fclose($target); 76 | 77 | if (filesize($this->local_archive)) { 78 | if ($helper->unGZip($this->local_archive, $this->local_file)) { 79 | $ret['status'] = 'success'; 80 | $format = Mage::app()->getLocale()->getDateTimeFormat(Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM); 81 | $ret['date'] = Mage::app()->getLocale()->date(filemtime($this->local_file))->toString($format); 82 | } else { 83 | $ret['message'] = $helper->__('UnGzipping failed'); 84 | } 85 | } else { 86 | $ret['message'] = $helper->__('Download failed.'); 87 | } 88 | } 89 | } 90 | 91 | echo json_encode($ret); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /app/code/community/Sandfox/GeoIP/Model/Country.php: -------------------------------------------------------------------------------- 1 | country = $this->getCountryByIp(Mage::helper('core/http')->getRemoteAddr()); 13 | $allowCountries = explode(',', (string)Mage::getStoreConfig('general/country/allow')); 14 | $this->defaultCountry = (string)Mage::getStoreConfig('general/country/default'); 15 | $this->addAllowedCountry($allowCountries); 16 | } 17 | 18 | public function getCountryByIp($ip) 19 | { 20 | /** @var $wrapper Sandfox_GeoIP_Model_Wrapper */ 21 | $wrapper = Mage::getSingleton('geoip/wrapper'); 22 | if ($wrapper->geoip_open($this->local_file, 0)) { 23 | $country = $wrapper->geoip_country_code_by_addr($ip); 24 | $wrapper->geoip_close(); 25 | 26 | return $country; 27 | } else { 28 | return null; 29 | } 30 | } 31 | 32 | public function getCountry() 33 | { 34 | return $this->country; 35 | } 36 | 37 | public function isCountryAllowed($country = '') 38 | { 39 | $country = $country ? $country : $this->country; 40 | if (count($this->allowed_countries) && $country) { 41 | return in_array($country, $this->allowed_countries); 42 | } else { 43 | return true; 44 | } 45 | } 46 | 47 | public function isDefaultCountry($country = '') 48 | { 49 | $country = $country ? $country : $this->country; 50 | if (!empty($this->defaultCountry) && $country) { 51 | return ($this->defaultCountry == $country); 52 | } else { 53 | return false; 54 | } 55 | } 56 | 57 | public function addAllowedCountry($countries) 58 | { 59 | $countries = is_array($countries) ? $countries : array($countries); 60 | $this->allowed_countries = array_merge($this->allowed_countries, $countries); 61 | 62 | return $this; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/code/community/Sandfox/GeoIP/Model/Cron.php: -------------------------------------------------------------------------------- 1 | update(); 10 | } 11 | } -------------------------------------------------------------------------------- /app/code/community/Sandfox/GeoIP/Model/Info.php: -------------------------------------------------------------------------------- 1 | local_file) ? filemtime($this->local_file) : 0; 8 | } 9 | } -------------------------------------------------------------------------------- /app/code/community/Sandfox/GeoIP/Model/Observer.php: -------------------------------------------------------------------------------- 1 | 0, "AP" => 1, "EU" => 2, "AD" => 3, "AE" => 4, "AF" => 5, 34 | "AG" => 6, "AI" => 7, "AL" => 8, "AM" => 9, "CW" => 10, "AO" => 11, 35 | "AQ" => 12, "AR" => 13, "AS" => 14, "AT" => 15, "AU" => 16, "AW" => 17, 36 | "AZ" => 18, "BA" => 19, "BB" => 20, "BD" => 21, "BE" => 22, "BF" => 23, 37 | "BG" => 24, "BH" => 25, "BI" => 26, "BJ" => 27, "BM" => 28, "BN" => 29, 38 | "BO" => 30, "BR" => 31, "BS" => 32, "BT" => 33, "BV" => 34, "BW" => 35, 39 | "BY" => 36, "BZ" => 37, "CA" => 38, "CC" => 39, "CD" => 40, "CF" => 41, 40 | "CG" => 42, "CH" => 43, "CI" => 44, "CK" => 45, "CL" => 46, "CM" => 47, 41 | "CN" => 48, "CO" => 49, "CR" => 50, "CU" => 51, "CV" => 52, "CX" => 53, 42 | "CY" => 54, "CZ" => 55, "DE" => 56, "DJ" => 57, "DK" => 58, "DM" => 59, 43 | "DO" => 60, "DZ" => 61, "EC" => 62, "EE" => 63, "EG" => 64, "EH" => 65, 44 | "ER" => 66, "ES" => 67, "ET" => 68, "FI" => 69, "FJ" => 70, "FK" => 71, 45 | "FM" => 72, "FO" => 73, "FR" => 74, "SX" => 75, "GA" => 76, "GB" => 77, 46 | "GD" => 78, "GE" => 79, "GF" => 80, "GH" => 81, "GI" => 82, "GL" => 83, 47 | "GM" => 84, "GN" => 85, "GP" => 86, "GQ" => 87, "GR" => 88, "GS" => 89, 48 | "GT" => 90, "GU" => 91, "GW" => 92, "GY" => 93, "HK" => 94, "HM" => 95, 49 | "HN" => 96, "HR" => 97, "HT" => 98, "HU" => 99, "ID" => 100, "IE" => 101, 50 | "IL" => 102, "IN" => 103, "IO" => 104, "IQ" => 105, "IR" => 106, "IS" => 107, 51 | "IT" => 108, "JM" => 109, "JO" => 110, "JP" => 111, "KE" => 112, "KG" => 113, 52 | "KH" => 114, "KI" => 115, "KM" => 116, "KN" => 117, "KP" => 118, "KR" => 119, 53 | "KW" => 120, "KY" => 121, "KZ" => 122, "LA" => 123, "LB" => 124, "LC" => 125, 54 | "LI" => 126, "LK" => 127, "LR" => 128, "LS" => 129, "LT" => 130, "LU" => 131, 55 | "LV" => 132, "LY" => 133, "MA" => 134, "MC" => 135, "MD" => 136, "MG" => 137, 56 | "MH" => 138, "MK" => 139, "ML" => 140, "MM" => 141, "MN" => 142, "MO" => 143, 57 | "MP" => 144, "MQ" => 145, "MR" => 146, "MS" => 147, "MT" => 148, "MU" => 149, 58 | "MV" => 150, "MW" => 151, "MX" => 152, "MY" => 153, "MZ" => 154, "NA" => 155, 59 | "NC" => 156, "NE" => 157, "NF" => 158, "NG" => 159, "NI" => 160, "NL" => 161, 60 | "NO" => 162, "NP" => 163, "NR" => 164, "NU" => 165, "NZ" => 166, "OM" => 167, 61 | "PA" => 168, "PE" => 169, "PF" => 170, "PG" => 171, "PH" => 172, "PK" => 173, 62 | "PL" => 174, "PM" => 175, "PN" => 176, "PR" => 177, "PS" => 178, "PT" => 179, 63 | "PW" => 180, "PY" => 181, "QA" => 182, "RE" => 183, "RO" => 184, "RU" => 185, 64 | "RW" => 186, "SA" => 187, "SB" => 188, "SC" => 189, "SD" => 190, "SE" => 191, 65 | "SG" => 192, "SH" => 193, "SI" => 194, "SJ" => 195, "SK" => 196, "SL" => 197, 66 | "SM" => 198, "SN" => 199, "SO" => 200, "SR" => 201, "ST" => 202, "SV" => 203, 67 | "SY" => 204, "SZ" => 205, "TC" => 206, "TD" => 207, "TF" => 208, "TG" => 209, 68 | "TH" => 210, "TJ" => 211, "TK" => 212, "TM" => 213, "TN" => 214, "TO" => 215, 69 | "TL" => 216, "TR" => 217, "TT" => 218, "TV" => 219, "TW" => 220, "TZ" => 221, 70 | "UA" => 222, "UG" => 223, "UM" => 224, "US" => 225, "UY" => 226, "UZ" => 227, 71 | "VA" => 228, "VC" => 229, "VE" => 230, "VG" => 231, "VI" => 232, "VN" => 233, 72 | "VU" => 234, "WF" => 235, "WS" => 236, "YE" => 237, "YT" => 238, "RS" => 239, 73 | "ZA" => 240, "ZM" => 241, "ME" => 242, "ZW" => 243, "A1" => 244, "A2" => 245, 74 | "O1" => 246, "AX" => 247, "GG" => 248, "IM" => 249, "JE" => 250, "BL" => 251, 75 | "MF" => 252, "BQ" => 253, 76 | ); 77 | private $GEOIP_COUNTRY_CODES = array( 78 | "","AP","EU","AD","AE","AF","AG","AI","AL","AM","CW", 79 | "AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB", 80 | "BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO", 81 | "BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD", 82 | "CF","CG","CH","CI","CK","CL","CM","CN","CO","CR", 83 | "CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO", 84 | "DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ", 85 | "FK","FM","FO","FR","SX","GA","GB","GD","GE","GF", 86 | "GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT", 87 | "GU","GW","GY","HK","HM","HN","HR","HT","HU","ID", 88 | "IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO", 89 | "JP","KE","KG","KH","KI","KM","KN","KP","KR","KW", 90 | "KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT", 91 | "LU","LV","LY","MA","MC","MD","MG","MH","MK","ML", 92 | "MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV", 93 | "MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI", 94 | "NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF", 95 | "PG","PH","PK","PL","PM","PN","PR","PS","PT","PW", 96 | "PY","QA","RE","RO","RU","RW","SA","SB","SC","SD", 97 | "SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO", 98 | "SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH", 99 | "TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW", 100 | "TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE", 101 | "VG","VI","VN","VU","WF","WS","YE","YT","RS","ZA", 102 | "ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE", 103 | "BL","MF", "BQ"); 104 | private $GEOIP_COUNTRY_CODES3 = array( 105 | "","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","CUW", 106 | "AGO","ATA","ARG","ASM","AUT","AUS","ABW","AZE","BIH","BRB", 107 | "BGD","BEL","BFA","BGR","BHR","BDI","BEN","BMU","BRN","BOL", 108 | "BRA","BHS","BTN","BVT","BWA","BLR","BLZ","CAN","CCK","COD", 109 | "CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI", 110 | "CUB","CPV","CXR","CYP","CZE","DEU","DJI","DNK","DMA","DOM", 111 | "DZA","ECU","EST","EGY","ESH","ERI","ESP","ETH","FIN","FJI", 112 | "FLK","FSM","FRO","FRA","SXM","GAB","GBR","GRD","GEO","GUF", 113 | "GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","SGS","GTM", 114 | "GUM","GNB","GUY","HKG","HMD","HND","HRV","HTI","HUN","IDN", 115 | "IRL","ISR","IND","IOT","IRQ","IRN","ISL","ITA","JAM","JOR", 116 | "JPN","KEN","KGZ","KHM","KIR","COM","KNA","PRK","KOR","KWT", 117 | "CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU", 118 | "LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI", 119 | "MMR","MNG","MAC","MNP","MTQ","MRT","MSR","MLT","MUS","MDV", 120 | "MWI","MEX","MYS","MOZ","NAM","NCL","NER","NFK","NGA","NIC", 121 | "NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER","PYF", 122 | "PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW", 123 | "PRY","QAT","REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN", 124 | "SWE","SGP","SHN","SVN","SJM","SVK","SLE","SMR","SEN","SOM", 125 | "SUR","STP","SLV","SYR","SWZ","TCA","TCD","ATF","TGO","THA", 126 | "TJK","TKL","TKM","TUN","TON","TLS","TUR","TTO","TUV","TWN", 127 | "TZA","UKR","UGA","UMI","USA","URY","UZB","VAT","VCT","VEN", 128 | "VGB","VIR","VNM","VUT","WLF","WSM","YEM","MYT","SRB","ZAF", 129 | "ZMB","MNE","ZWE","A1","A2","O1","ALA","GGY","IMN","JEY", 130 | "BLM","MAF", "BES" 131 | ); 132 | private $GEOIP_COUNTRY_NAMES = array( 133 | "","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Curacao", 134 | "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados", 135 | "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia", 136 | "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the", 137 | "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica", 138 | "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic", 139 | "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji", 140 | "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","Sint Maarten (Dutch part)","Gabon","United Kingdom","Grenada","Georgia","French Guiana", 141 | "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala", 142 | "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia", 143 | "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan", 144 | "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait", 145 | "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania", 146 | "Luxembourg","Latvia","Libya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali", 147 | "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives", 148 | "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua", 149 | "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia", 150 | "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau", 151 | "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan", 152 | "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname", 153 | "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand", 154 | "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan", 155 | "Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela", 156 | "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa", 157 | "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey", 158 | "Saint Barthelemy","Saint Martin", "Bonaire, Saint Eustatius and Saba" 159 | ); 160 | 161 | private $GEOIP_CONTINENT_CODES = array( 162 | "--", "AS","EU","EU","AS","AS","NA","NA","EU","AS","NA", 163 | "AF","AN","SA","OC","EU","OC","NA","AS","EU","NA", 164 | "AS","EU","AF","EU","AS","AF","AF","NA","AS","SA", 165 | "SA","NA","AS","AN","AF","EU","NA","NA","AS","AF", 166 | "AF","AF","EU","AF","OC","SA","AF","AS","SA","NA", 167 | "NA","AF","AS","AS","EU","EU","AF","EU","NA","NA", 168 | "AF","SA","EU","AF","AF","AF","EU","AF","EU","OC", 169 | "SA","OC","EU","EU","NA","AF","EU","NA","AS","SA", 170 | "AF","EU","NA","AF","AF","NA","AF","EU","AN","NA", 171 | "OC","AF","SA","AS","AN","NA","EU","NA","EU","AS", 172 | "EU","AS","AS","AS","AS","AS","EU","EU","NA","AS", 173 | "AS","AF","AS","AS","OC","AF","NA","AS","AS","AS", 174 | "NA","AS","AS","AS","NA","EU","AS","AF","AF","EU", 175 | "EU","EU","AF","AF","EU","EU","AF","OC","EU","AF", 176 | "AS","AS","AS","OC","NA","AF","NA","EU","AF","AS", 177 | "AF","NA","AS","AF","AF","OC","AF","OC","AF","NA", 178 | "EU","EU","AS","OC","OC","OC","AS","NA","SA","OC", 179 | "OC","AS","AS","EU","NA","OC","NA","AS","EU","OC", 180 | "SA","AS","AF","EU","EU","AF","AS","OC","AF","AF", 181 | "EU","AS","AF","EU","EU","EU","AF","EU","AF","AF", 182 | "SA","AF","NA","AS","AF","NA","AF","AN","AF","AS", 183 | "AS","OC","AS","AF","OC","AS","EU","NA","OC","AS", 184 | "AF","EU","AF","OC","NA","SA","AS","EU","NA","SA", 185 | "NA","NA","AS","OC","OC","OC","AS","AF","EU","AF", 186 | "AF","EU","AF","--","--","--","EU","EU","EU","EU", 187 | "NA","NA","NA" 188 | ); 189 | 190 | private $GEOIP_COUNTRY_BEGIN = 16776960; 191 | private $GEOIP_STATE_BEGIN_REV0 = 16700000; 192 | private $GEOIP_STATE_BEGIN_REV1 = 16000000; 193 | private $GEOIP_STANDARD = 0; 194 | private $GEOIP_MEMORY_CACHE = 1; 195 | private $GEOIP_SHARED_MEMORY = 2; 196 | private $STRUCTURE_INFO_MAX_SIZE = 20; 197 | private $DATABASE_INFO_MAX_SIZE = 100; 198 | private $GEOIP_COUNTRY_EDITION = 106; 199 | private $GEOIP_PROXY_EDITION = 8; 200 | private $GEOIP_ASNUM_EDITION = 9; 201 | private $GEOIP_NETSPEED_EDITION = 10; 202 | private $GEOIP_REGION_EDITION_REV0 = 112; 203 | private $GEOIP_REGION_EDITION_REV1 = 3; 204 | private $GEOIP_CITY_EDITION_REV0 = 111; 205 | private $GEOIP_CITY_EDITION_REV1 = 2; 206 | private $GEOIP_ORG_EDITION = 110; 207 | private $GEOIP_ISP_EDITION = 4; 208 | private $SEGMENT_RECORD_LENGTH = 3; 209 | private $STANDARD_RECORD_LENGTH = 3; 210 | private $ORG_RECORD_LENGTH = 4; 211 | private $MAX_RECORD_LENGTH = 4; 212 | private $MAX_ORG_RECORD_LENGTH = 300; 213 | private $GEOIP_SHM_KEY = 0x4f415401; 214 | private $US_OFFSET = 1; 215 | private $CANADA_OFFSET = 677; 216 | private $WORLD_OFFSET = 1353; 217 | private $FIPS_RANGE = 360; 218 | private $GEOIP_UNKNOWN_SPEED = 0; 219 | private $GEOIP_DIALUP_SPEED = 1; 220 | private $GEOIP_CABLEDSL_SPEED = 2; 221 | private $GEOIP_CORPORATE_SPEED = 3; 222 | private $GEOIP_DOMAIN_EDITION = 11; 223 | private $GEOIP_COUNTRY_EDITION_V6 = 12; 224 | private $GEOIP_LOCATIONA_EDITION = 13; 225 | private $GEOIP_ACCURACYRADIUS_EDITION = 14; 226 | private $GEOIP_CITYCOMBINED_EDITION = 15; 227 | private $GEOIP_CITY_EDITION_REV1_V6 = 30; 228 | private $GEOIP_CITY_EDITION_REV0_V6 = 31; 229 | private $GEOIP_NETSPEED_EDITION_REV1 = 32; 230 | private $GEOIP_NETSPEED_EDITION_REV1_V6 = 33; 231 | private $GEOIP_USERTYPE_EDITION = 28; 232 | private $GEOIP_USERTYPE_EDITION_V6 = 29; 233 | private $GEOIP_ASNUM_EDITION_V6 = 21; 234 | private $GEOIP_ISP_EDITION_V6 = 22; 235 | private $GEOIP_ORG_EDITION_V6 = 23; 236 | private $GEOIP_DOMAIN_EDITION_V6 = 24; 237 | private $CITYCOMBINED_FIXED_RECORD = 7 ; 238 | 239 | public function geoip_open($filename, $flags) { 240 | $this->flags = $flags; 241 | if ($this->flags & $this->GEOIP_SHARED_MEMORY) { 242 | $this->shmid = @shmop_open ($this->GEOIP_SHM_KEY, "a", 0, 0); 243 | } else { 244 | if (file_exists($filename) && $this->filehandle = fopen($filename,"rb")) { 245 | if ($this->flags & $this->GEOIP_MEMORY_CACHE) { 246 | $s_array = fstat($this->filehandle); 247 | $this->memory_buffer = fread($this->filehandle, $s_array['size']); 248 | } 249 | } else { 250 | return false; 251 | } 252 | } 253 | 254 | $this->_setup_segments(); 255 | return true; 256 | } 257 | 258 | public function geoip_close() { 259 | if ($this->flags & $this->GEOIP_SHARED_MEMORY) { 260 | return true; 261 | } 262 | 263 | return fclose($this->filehandle); 264 | } 265 | 266 | public function geoip_country_code_by_addr($addr) { 267 | $country_id = $this->geoip_country_id_by_addr($addr); 268 | return $country_id !== false ? $this->GEOIP_COUNTRY_CODES[$country_id] : false; 269 | } 270 | 271 | public function geoip_country_id_by_addr($addr) { 272 | $ipnum = ip2long($addr); 273 | return $this->_geoip_seek_country($ipnum) - $this->GEOIP_COUNTRY_BEGIN; 274 | } 275 | 276 | private function _geoip_seek_country($ipnum) { 277 | $offset = 0; 278 | for ($depth = 31; $depth >= 0; --$depth) { 279 | if ($this->flags & $this->GEOIP_MEMORY_CACHE) { 280 | // workaround php's broken substr, strpos, etc handling with 281 | // mbstring.func_overload and mbstring.internal_encoding 282 | $enc = mb_internal_encoding(); 283 | mb_internal_encoding('ISO-8859-1'); 284 | 285 | $buf = substr($this->memory_buffer, 286 | 2 * $this->record_length * $offset, 287 | 2 * $this->record_length); 288 | 289 | mb_internal_encoding($enc); 290 | } elseif ($this->flags & $this->GEOIP_SHARED_MEMORY) { 291 | $buf = @shmop_read ($this->shmid, 292 | 2 * $this->record_length * $offset, 293 | 2 * $this->record_length ); 294 | } else { 295 | fseek($this->filehandle, 2 * $this->record_length * $offset, SEEK_SET) == 0 296 | or die("fseek failed"); 297 | $buf = fread($this->filehandle, 2 * $this->record_length); 298 | } 299 | $x = array(0,0); 300 | for ($i = 0; $i < 2; ++$i) { 301 | for ($j = 0; $j < $this->record_length; ++$j) { 302 | $x[$i] += ord($buf[$this->record_length * $i + $j]) << ($j * 8); 303 | } 304 | } 305 | if ($ipnum & (1 << $depth)) { 306 | if ($x[1] >= $this->databaseSegments) { 307 | return $x[1]; 308 | } 309 | $offset = $x[1]; 310 | } else { 311 | if ($x[0] >= $this->databaseSegments) { 312 | return $x[0]; 313 | } 314 | $offset = $x[0]; 315 | } 316 | } 317 | trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR); 318 | return false; 319 | } 320 | 321 | private function _setup_segments(){ 322 | $this->databaseType = $this->GEOIP_COUNTRY_EDITION; 323 | $this->record_length = $this->STANDARD_RECORD_LENGTH; 324 | if ($this->flags & $this->GEOIP_SHARED_MEMORY) { 325 | $offset = @shmop_size ($this->shmid) - 3; 326 | for ($i = 0; $i < $this->STRUCTURE_INFO_MAX_SIZE; $i++) { 327 | $delim = @shmop_read ($this->shmid, $offset, 3); 328 | $offset += 3; 329 | if ($delim == (chr(255).chr(255).chr(255))) { 330 | $this->databaseType = ord(@shmop_read ($this->shmid, $offset, 1)); 331 | $offset++; 332 | 333 | if ($this->databaseType == $this->GEOIP_REGION_EDITION_REV0){ 334 | $this->databaseSegments = $this->GEOIP_STATE_BEGIN_REV0; 335 | } else if ($this->databaseType == $this->GEOIP_REGION_EDITION_REV1){ 336 | $this->databaseSegments = $this->GEOIP_STATE_BEGIN_REV1; 337 | } else if (($this->databaseType == $this->GEOIP_CITY_EDITION_REV0)|| 338 | ($this->databaseType == $this->GEOIP_CITY_EDITION_REV1) 339 | || ($this->databaseType == $this->GEOIP_ORG_EDITION) 340 | || ($this->databaseType == $this->GEOIP_ORG_EDITION_V6) 341 | || ($this->databaseType == $this->GEOIP_DOMAIN_EDITION) 342 | || ($this->databaseType == $this->GEOIP_DOMAIN_EDITION_V6) 343 | || ($this->databaseType == $this->GEOIP_ISP_EDITION) 344 | || ($this->databaseType == $this->GEOIP_ISP_EDITION_V6) 345 | || ($this->databaseType == $this->GEOIP_USERTYPE_EDITION) 346 | || ($this->databaseType == $this->GEOIP_USERTYPE_EDITION_V6) 347 | || ($this->databaseType == $this->GEOIP_LOCATIONA_EDITION) 348 | || ($this->databaseType == $this->GEOIP_ACCURACYRADIUS_EDITION) 349 | || ($this->databaseType == $this->GEOIP_CITY_EDITION_REV0_V6) 350 | || ($this->databaseType == $this->GEOIP_CITY_EDITION_REV1_V6) 351 | || ($this->databaseType == $this->GEOIP_NETSPEED_EDITION_REV1) 352 | || ($this->databaseType == $this->GEOIP_NETSPEED_EDITION_REV1_V6) 353 | || ($this->databaseType == $this->GEOIP_ASNUM_EDITION) 354 | || ($this->databaseType == $this->GEOIP_ASNUM_EDITION_V6)){ 355 | $this->databaseSegments = 0; 356 | $buf = @shmop_read ($this->shmid, $offset, $this->SEGMENT_RECORD_LENGTH); 357 | for ($j = 0;$j < $this->SEGMENT_RECORD_LENGTH;$j++){ 358 | $this->databaseSegments += (ord($buf[$j]) << ($j * 8)); 359 | } 360 | if (($this->databaseType == $this->GEOIP_ORG_EDITION) 361 | || ($this->databaseType == $this->GEOIP_ORG_EDITION_V6) 362 | || ($this->databaseType == $this->GEOIP_DOMAIN_EDITION) 363 | || ($this->databaseType == $this->GEOIP_DOMAIN_EDITION_V6) 364 | || ($this->databaseType == $this->GEOIP_ISP_EDITION) 365 | || ($this->databaseType == $this->GEOIP_ISP_EDITION_V6)) { 366 | $this->record_length = $this->ORG_RECORD_LENGTH; 367 | } 368 | } 369 | break; 370 | } else { 371 | $offset -= 4; 372 | } 373 | } 374 | if (($this->databaseType == $this->GEOIP_COUNTRY_EDITION)|| 375 | ($this->databaseType == $this->GEOIP_COUNTRY_EDITION_V6)|| 376 | ($this->databaseType == $this->GEOIP_PROXY_EDITION)|| 377 | ($this->databaseType == $this->GEOIP_NETSPEED_EDITION)){ 378 | $this->databaseSegments = $this->GEOIP_COUNTRY_BEGIN; 379 | } 380 | } else { 381 | $filepos = ftell($this->filehandle); 382 | fseek($this->filehandle, -3, SEEK_END); 383 | for ($i = 0; $i < $this->STRUCTURE_INFO_MAX_SIZE; $i++) { 384 | $delim = fread($this->filehandle,3); 385 | if ($delim == (chr(255).chr(255).chr(255))){ 386 | $this->databaseType = ord(fread($this->filehandle,1)); 387 | if ($this->databaseType == $this->GEOIP_REGION_EDITION_REV0){ 388 | $this->databaseSegments = $this->GEOIP_STATE_BEGIN_REV0; 389 | } 390 | else if ($this->databaseType == $this->GEOIP_REGION_EDITION_REV1){ 391 | $this->databaseSegments = $this->GEOIP_STATE_BEGIN_REV1; 392 | } else if (($this->databaseType == $this->GEOIP_CITY_EDITION_REV0) 393 | || ($this->databaseType == $this->GEOIP_CITY_EDITION_REV1) 394 | || ($this->databaseType == $this->GEOIP_CITY_EDITION_REV0_V6) 395 | || ($this->databaseType == $this->GEOIP_CITY_EDITION_REV1_V6) 396 | || ($this->databaseType == $this->GEOIP_ORG_EDITION) 397 | || ($this->databaseType == $this->GEOIP_DOMAIN_EDITION) 398 | || ($this->databaseType == $this->GEOIP_ISP_EDITION) 399 | || ($this->databaseType == $this->GEOIP_ORG_EDITION_V6) 400 | || ($this->databaseType == $this->GEOIP_DOMAIN_EDITION_V6) 401 | || ($this->databaseType == $this->GEOIP_ISP_EDITION_V6) 402 | || ($this->databaseType == $this->GEOIP_LOCATIONA_EDITION) 403 | || ($this->databaseType == $this->GEOIP_ACCURACYRADIUS_EDITION) 404 | || ($this->databaseType == $this->GEOIP_CITY_EDITION_REV0_V6) 405 | || ($this->databaseType == $this->GEOIP_CITY_EDITION_REV1_V6) 406 | || ($this->databaseType == $this->GEOIP_NETSPEED_EDITION_REV1) 407 | || ($this->databaseType == $this->GEOIP_NETSPEED_EDITION_REV1_V6) 408 | || ($this->databaseType == $this->GEOIP_USERTYPE_EDITION) 409 | || ($this->databaseType == $this->GEOIP_USERTYPE_EDITION_V6) 410 | || ($this->databaseType == $this->GEOIP_ASNUM_EDITION) 411 | || ($this->databaseType == $this->GEOIP_ASNUM_EDITION_V6)){ 412 | $this->databaseSegments = 0; 413 | $buf = fread($this->filehandle, $this->SEGMENT_RECORD_LENGTH); 414 | for ($j = 0;$j < $this->SEGMENT_RECORD_LENGTH;$j++){ 415 | $this->databaseSegments += (ord($buf[$j]) << ($j * 8)); 416 | } 417 | if ( ( $this->databaseType == $this->GEOIP_ORG_EDITION ) 418 | || ( $this->databaseType == $this->GEOIP_DOMAIN_EDITION ) 419 | || ( $this->databaseType == $this->GEOIP_ISP_EDITION ) 420 | || ( $this->databaseType == $this->GEOIP_ORG_EDITION_V6 ) 421 | || ( $this->databaseType == $this->GEOIP_DOMAIN_EDITION_V6 ) 422 | || ( $this->databaseType == $this->GEOIP_ISP_EDITION_V6 )) { 423 | $this->record_length = $this->ORG_RECORD_LENGTH; 424 | } 425 | } 426 | break; 427 | } else { 428 | fseek($this->filehandle, -4, SEEK_CUR); 429 | } 430 | } 431 | if (($this->databaseType == $this->GEOIP_COUNTRY_EDITION)|| 432 | ($this->databaseType == $this->GEOIP_COUNTRY_EDITION_V6)|| 433 | ($this->databaseType == $this->GEOIP_PROXY_EDITION)|| 434 | ($this->databaseType == $this->GEOIP_NETSPEED_EDITION)){ 435 | $this->databaseSegments = $this->GEOIP_COUNTRY_BEGIN; 436 | } 437 | fseek($this->filehandle,$filepos,SEEK_SET); 438 | } 439 | } 440 | } -------------------------------------------------------------------------------- /app/code/community/Sandfox/GeoIP/controllers/Adminhtml/GeoipController.php: -------------------------------------------------------------------------------- 1 | getArchivePath()); 13 | $_totalSize = $_session->getData('_geoip_file_size'); 14 | echo $_totalSize ? $_realSize / $_totalSize * 100 : 0; 15 | } 16 | 17 | public function synchronizeAction() 18 | { 19 | /** @var $info Sandfox_GeoIP_Model_Info */ 20 | $info = Mage::getModel('geoip/info'); 21 | $info->update(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/code/community/Sandfox/GeoIP/etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 0.2.0 6 | 7 | 8 | 9 | 10 | 11 | Sandfox_GeoIP_Block 12 | 13 | 14 | 15 | 16 | Sandfox_GeoIP_Model 17 | 18 | 19 | 20 | 21 | Sandfox_GeoIP_Helper 22 | 23 | 24 | 25 | 26 | 27 | 28 | singleton 29 | geoip/observer 30 | controllerFrontInitBefore 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Sandfox_GeoIP_Adminhtml 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | sandfox/geoip.xml 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 0 0 * * 5 61 | geoip/cron::run 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | var 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /app/code/community/Sandfox/GeoIP/etc/system.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | label 10 | geoip/system_config_status 11 | 7000 12 | 1 13 | 0 14 | 0 15 | 16 | 17 | button 18 | geoip/system_config_synchronize 19 | 7010 20 | 1 21 | 0 22 | 0 23 | If you synchronize GeoIP database too often you may be banned for several hours. 24 | 25 | 26 | 27 | The base directory in which the GeoIP database will be stored 28 | text 29 | 7020 30 | 1 31 | 0 32 | 0 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/default/layout/sandfox/geoip.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/default/template/sandfox/geoip/notifications.phtml: -------------------------------------------------------------------------------- 1 | checkFilePermissions()) : ?> 2 |
GeoIP:
3 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/default/template/sandfox/geoip/system/config/synchronize.phtml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 67 | 68 | getButtonHtml() ?>Synchronize 69 |   -------------------------------------------------------------------------------- /app/etc/modules/Sandfox_GeoIP.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | community 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"tim-bezhashvyly/geoip", 3 | "type":"magento-module", 4 | "license":"OSL-3.0", 5 | "homepage":"https://github.com/tim-bezhashvyly/geoip", 6 | "description":"Connects MaxMind GeoIP DB to Magento", 7 | "authors":[ 8 | { 9 | "name":"Tim Bezhashvyly", 10 | "email":"tim.bezhashvyly@gmail.com" 11 | } 12 | ], 13 | "require":{ 14 | "magento-hackathon/magento-composer-installer":"*" 15 | } 16 | } -------------------------------------------------------------------------------- /modman: -------------------------------------------------------------------------------- 1 | app/etc/modules/Sandfox_GeoIP.xml app/etc/modules/Sandfox_GeoIP.xml 2 | app/design/adminhtml/default/default/layout/sandfox/geoip.xml app/design/adminhtml/default/default/layout/sandfox/geoip.xml 3 | app/design/adminhtml/default/default/template/sandfox/geoip app/design/adminhtml/default/default/template/sandfox/geoip 4 | app/code/community/Sandfox/GeoIP app/code/community/Sandfox/GeoIP --------------------------------------------------------------------------------