diff --git a/IP2Location/Lib/IP2Location.php b/IP2Location/Lib/IP2Location.php new file mode 100644 index 0000000..04a2787 --- /dev/null +++ b/IP2Location/Lib/IP2Location.php @@ -0,0 +1,463 @@ +. + */ + +class IP2LocationRecord { + public $ipAddress, $ipNumber, $countryCode, $countryName, $regionName, $cityName, $latitude, $longitude, $isp, $domainName, $zipCode, $timeZone, $netSpeed, $iddCode, $areaCode, $weatherStationCode, $weatherStationName, $mcc, $mnc, $mobileCarrierName, $elevation, $usageType; +} + +class IP2Location { + // Current version + const VERSION = '6.0.0'; + + // Database storage method + const FILE_IO = 0; + const MEMORY_CACHE = 1; + const SHARED_MEMORY = 2; + + // Unpack method + const ENDIAN = 0; + const BIG_ENDIAN = 1; + + // Record field + const ALL = 0; + const COUNTRY_CODE = 1; + const COUNTRY_NAME = 2; + const REGION_NAME = 3; + const CITY_NAME = 4; + const LATITUDE = 5; + const LONGITUDE = 6; + const ISP = 7; + const DOMAIN_NAME = 8; + const ZIP_CODE = 9; + const TIME_ZONE = 10; + const NET_SPEED = 11; + const IDD_CODE = 12; + const AREA_CODE = 13; + const WEATHER_STATION_CODE = 14; + const WEATHER_STATION_NAME = 15; + const MCC = 16; + const MNC = 17; + const MOBILE_CARRIER_NAME = 18; + const ELEVATION = 19; + const USAGE_TYPE = 20; + + // IP version + const IPV4 = 0; + const IPV6 = 1; + + // SHMOP memory address + const SHM_KEY = 4194500608; + + // Message + const FIELD_NOT_SUPPORTED = 'This field is not supported in DB%TYPE%. Please upgrade your IP2Location database.'; + const INVALID_IPV4 = 'Invalid IPv4 address.'; + const INVALID_IPV6 = 'Invalid IPv6 address.'; + + private $columns = array( + 'COUNTRY_CODE' => array(0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), + 'COUNTRY_NAME' => array(0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), + 'REGION_NAME' => array(0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3), + 'CITY_NAME' => array(0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4), + 'LATITUDE' => array(0, 0, 0, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5), + 'LONGITUDE' => array(0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6), + 'ISP' => array(0, 0, 3, 0, 5, 0, 7, 5, 7, 0, 8, 0, 9, 0, 9, 0, 9, 0, 9, 7, 9, 0, 9, 7, 9), + 'DOMAIN_NAME' => array(0, 0, 0, 0, 0, 0, 0, 6, 8, 0, 9, 0, 10, 0, 10, 0, 10, 0, 10, 8, 10, 0, 10, 8, 10), + 'ZIP_CODE' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 7, 7, 7, 0, 7, 0, 7, 7, 7, 0, 7), + 'TIME_ZONE' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 7, 8, 8, 8, 7, 8, 0, 8, 8, 8, 0, 8), + 'NET_SPEED' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 11, 0, 11, 8, 11, 0, 11, 0, 11, 0, 11), + 'IDD_CODE' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 12, 0, 12, 0, 12, 9, 12, 0, 12), + 'AREA_CODE' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 13, 0, 13, 0, 13, 10, 13, 0, 13), + 'WEATHER_STATION_CODE' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 14, 0, 14, 0, 14, 0, 14), + 'WEATHER_STATION_NAME' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 15, 0, 15, 0, 15, 0, 15), + 'MCC' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 16, 0, 16, 9, 16), + 'MNC' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 17, 0, 17, 10, 17), + 'MOBILE_CARRIER_NAME' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 18, 0, 18, 11, 18), + 'ELEVATION' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 19, 0, 19), + 'USAGE_TYPE' => array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 20), + ); + + private $shmId = ''; + private $db = array(); + private $unpack; + private $buffer; + private $mode; + private $handle; + + public function __construct($file=NULL, $mode=self::FILE_IO){ + if(!is_file($file)) throw new Exception('Unable to open file "' . $file . '".'); + + // Define system unpack method + list($test) = array_values(unpack('L1L', pack('V', 1))); + + // Use Big Endian Unpack if endian test failed + $this->unpack = (($test != 1)) ? self::BIG_ENDIAN : self::ENDIAN; + + switch($mode){ + case self::SHARED_MEMORY: + if(!function_exists('shmop_open')) throw new Exception('Please make sure your PHP setup has "php_shmop" enabled.'); + $this->mode = self::SHARED_MEMORY; + + $this->shmId = @shmop_open(self::SHM_KEY, 'a', 0, 0); + + /*shmop_delete($this->shmId); + shmop_close($this->shmId); + die;*/ + + if($this->shmId === FALSE){ + // First execution, load database into memory + if(($fp = fopen($file, 'rb')) === FALSE) throw new Exception('Unable to open file "' . $file . '".'); + + $stats = fstat($fp); + + if($shmId = @shmop_open(self::SHM_KEY, 'w', 0, 0)){ + shmop_delete($shmId); + shmop_close($shmId); + } + + if($shmId = @shmop_open(self::SHM_KEY, 'c', 0644, $stats['size'])){ + /*$buf = fread($fp, $stats['size']); + shmop_write($shmId, $buf, 0);*/ + + $offset = 0; + while($offset < $stats['size']){ + $buf = fread($fp, 524288); + shmop_write($shmId, $buf, $offset); + $offset += 524288; + } + shmop_close($shmId); + } + fclose($fp); + + $this->shmId = @shmop_open(self::SHM_KEY, 'a', 0, 0); + + if($this->shmId === FALSE){ + throw new Exception('Unable to access shared memory block.'); + } + } + break; + + default: + $this->mode = self::FILE_IO; + $this->handle = fopen($file, 'rb'); + + if($mode == self::MEMORY_CACHE){ + $this->mode = self::MEMORY_CACHE; + $stats = fstat($this->handle); + $this->buffer = fread($this->handle, $stats['size']); + } + } + + $this->db['type'] = $this->readByte(1, '8'); + $this->db['column'] = $this->readByte(2, '8'); + $this->db['year'] = $this->readByte(3, '8'); + $this->db['month'] = $this->readByte(4, '8'); + $this->db['day'] = $this->readByte(5, '8'); + $this->db['count'] = $this->readByte(6, '32'); + $this->db['base_address'] = $this->readByte(10, '32'); + $this->db['ip_version'] = $this->readByte(14, '32'); + } + + private function readByte($pos, $mode='string', $autoSize = false){ + switch($this->mode){ + case self::SHARED_MEMORY: + if($mode == 'string'){ + $data = shmop_read($this->shmId, $pos, ($autoSize) ? shmop_size($this->shmId)-$pos : 100); + } + else{ + $data = shmop_read($this->shmId, $pos-1, 50); + } + break; + + case self::MEMORY_CACHE: + $data = substr($this->buffer, (($mode == 'string') ? $pos : $pos-1), 100); + break; + + default: + if($mode == 'string'){ + fseek($this->handle, $pos, SEEK_SET); + $data = @fread($this->handle, 1); + } + else{ + fseek($this->handle, $pos-1, SEEK_SET); + $data = @fread($this->handle, 50); + } + } + + switch($mode){ + case '8': + $out = $this->readBinary('C', $data); + return $out[1]; + break; + + case '32': + $out = $this->readBinary('V', $data); + if($out[1]<0) $out[1] += 4294967296; + + return (int)$out[1]; + break; + + case '128': + $array = preg_split('//', $data, -1, PREG_SPLIT_NO_EMPTY); + + if(count($array) != 16) return 0; + + $ip96_127 = $this->readBinary('V', $array[0] . $array[1] . $array[2] . $array[3]); + $ip64_95 = $this->readBinary('V', $array[4] . $array[5] . $array[6] . $array[7]); + $ip32_63 = $this->readBinary('V', $array[8] . $array[9] . $array[10] . $array[11]); + $ip1_31 = $this->readBinary('V', $array[12] . $array[13] . $array[14] . $array[15]); + + if($ip96_127[1]<0) $ip96_127[1] += 4294967296; + if($ip64_95[1]<0) $ip64_95[1] += 4294967296; + if($ip32_63[1]<0) $ip32_63[1] += 4294967296; + if($ip1_31[1]<0) $ip1_31[1] += 4294967296; + + return bcadd(bcadd(bcmul($ip1_31[1], bcpow(4294967296, 3)), bcmul($ip32_63[1], bcpow(4294967296, 2))), bcadd( bcmul($ip64_95[1], 4294967296), $ip96_127[1])); + break; + + case 'float': + $out = $this->readBinary('f', $data); + + return $out[1]; + break; + + default: + $out = $this->readBinary('C', $data); + return (in_array($this->mode, array(self::SHARED_MEMORY, self::MEMORY_CACHE))) ? substr($data, 1, $out[1]) : @fread($this->handle, $out[1]); + } + } + + private function readBinary($format, $data){ + if($this->unpack == self::BIG_ENDIAN){ + $ar = unpack($format, $data); + $vals = array_values($ar); + $f = explode('/', $format); + $i = 0; + + foreach($f as $fKey=>$fValue){ + $repeater = intval (substr ($fValue, 1)); + + if($repeater == 0) $repeater = 1; + if($fValue{1} == '*') $repeater = count ($ar) - $i; + if($fValue{0} != 'd') $i += $repeater; continue; + + $j = $i + $repeater; + + for($a=$i; $a<$j; ++$a){ + $p = pack('d', $vals[$i]); + $p = strrev ($p); + list($vals[$i]) = array_values(unpack('d1d', $p)); + ++$i; + } + } + + $a = 0; + foreach($ar as $arKey=>$arValue){ + $ar[$arKey] = $vals[$a]; + ++$a; + } + return $ar; + } + return unpack($format, $data); + } + + private function ipv6ToLong($ip){ + $n = substr_count($ip, ':'); + + if($n < 7){ + $expanded = '::'; + + while($n < 7){ + $expanded .= ':'; + $n++; + } + $ip = preg_replace('/::/', $expanded, $ip); + } + + $subLoc = 8; + $ipv6No = '0'; + + foreach(preg_split('/:/', $ip) as $ipSub){ + $subLoc--; + + if($ipSub == '') continue; + $ipv6No = bcadd( $ipv6No, bcmul(hexdec($ipSub), bcpow(hexdec('0x10000'), $subLoc))); + } + return $ipv6No; + } + + public function lookup($ip, $field=self::ALL){ + $keys = array_keys($this->columns); + + // Get record by single field name + if($field != self::ALL){ + if($this->columns[$keys[$field-1]][$this->db['type']] == 0) return str_replace('%TYPE%', $this->db['type'], self::FIELD_NOT_SUPPORTED); + } + + $result = new IP2LocationRecord(); + $result->ipAddress = $ip; + + // IPv4 database + if($this->db['ip_version'] == self::IPV4){ + if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)){ + if($field != self::ALL){ + return self::INVALID_IPV4; + } + else{ + $result->countryCode = $result->countryName = $result->regionName = $result->cityName = $result->latitude = $result->longitude = $result->isp = $result->domainName = $result->zipCode = $result->timeZone = $result->netSpeed = $result->iddCode = $result->areaCode = $result->weatherStationCode = $result->weatherStationName = $result->mcc = $result->mnc = $result->mobileCarrierName = $result->elevation = $result->usageType = self::INVALID_IPV4; + return $result; + } + } + $ipNumber = sprintf('%u', ip2long($ip)); + $ipNumber = ($ipNumber >= 4294967295) ? ($ipNumber-1) : $ipNumber; + } + else{ + if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)){ + if($field != self::ALL){ + return self::INVALID_IPV6; + } + else{ + $result->countryCode = $result->countryName = $result->regionName = $result->cityName = $result->latitude = $result->longitude = $result->isp = $result->domainName = $result->zipCode = $result->timeZone = $result->netSpeed = $result->iddCode = $result->areaCode = $result->weatherStationCode = $result->weatherStationName = $result->mcc = $result->mnc = $result->mobileCarrierName = $result->elevation = $result->usageType = self::INVALID_IPV6; + return $result; + } + } + $ipNumber = $this->ipv6ToLong($ip); + $ipNumber = (bccomp($ipNumber , 340282366920938463463374607431768211455) == 0) ? bcsub($ipNumber , 1) : $ipNumber; + } + + $result->ipNumber = $ipNumber; + + $low = 0; + $high = $this->db['count']; + $mid = 0; + $ipFrom = 0; + $ipTo = 0; + + while($low <= $high){ + $mid = (int)(($low + $high)/2); + $ipFrom = $this->readByte($this->db['base_address'] + $mid * $this->db['column'] * 4, '32'); + $ipTo = $this->readByte($this->db['base_address'] + ($mid + 1) * $this->db['column'] * 4, '32'); + + if($ipFrom < 0) $ipFrom += pow(2, 32); + if($ipTo < 0) $ipTo += pow(2, 32); + + if(($ipNumber >= $ipFrom) && ($ipNumber < $ipTo)){ + $offset = $this->db['base_address'] + ($mid * $this->db['column'] * 4); + switch($field){ + case self::COUNTRY_CODE: + case self::REGION_NAME: + case self::CITY_NAME: + case self::ISP: + case self::DOMAIN_NAME: + case self::ZIP_CODE: + case self::TIME_ZONE: + case self::NET_SPEED: + case self::IDD_CODE: + case self::AREA_CODE: + case self::WEATHER_STATION_CODE: + case self::WEATHER_STATION_NAME: + case self::MCC: + case self::MNC: + case self::MOBILE_CARRIER_NAME: + case self::ELEVATION: + return $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[$field-1]][$this->db['type']]-1), '32'), 'string', true); + + case self::COUNTRY_NAME: + return $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[$field-1]][$this->db['type']]-1), '32')+3, 'string', true); + + case self::LATITUDE: + case self::LONGITUDE: + return $this->readByte($offset + 4 * ($this->columns[$keys[$field-1]][$this->db['type']]-1), 'float', true); + + case self::USAGE_TYPE: + return $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[$field-1]][$this->db['type']]-1), '32'), 'string', true); + + default: + $result->regionName = $result->cityName = $result->latitude = $result->longitude = $result->isp = $result->domainName = $result->zipCode = $result->timeZone = $result->netSpeed = $result->iddCode = $result->areaCode = $result->weatherStationCode = $result->weatherStationName = $result->mcc = $result->mnc = $result->mobileCarrierName = $result->elevation = $result->usageType = str_replace('%TYPE%', $this->db['type'], self::FIELD_NOT_SUPPORTED); + + $result->countryCode = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::COUNTRY_CODE-1]][$this->db['type']]-1), '32'), 'string', true); + $result->countryName = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::COUNTRY_NAME-1]][$this->db['type']]-1), '32')+3, 'string', true); + + if($this->columns[$keys[self::REGION_NAME-1]][$this->db['type']] != 0) + $result->regionName = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::REGION_NAME-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::CITY_NAME-1]][$this->db['type']] != 0) + $result->cityName = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::CITY_NAME-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::LATITUDE-1]][$this->db['type']] != 0) + $result->latitude = $this->readByte($offset + 4 * ($this->columns[$keys[self::LATITUDE-1]][$this->db['type']]-1), 'float', true); + + if($this->columns[$keys[self::LONGITUDE-1]][$this->db['type']] != 0) + $result->longitude = $this->readByte($offset + 4 * ($this->columns[$keys[self::LONGITUDE-1]][$this->db['type']]-1), 'float', true); + + if($this->columns[$keys[self::ISP-1]][$this->db['type']] != 0)$result->isp = $this->readByte($this->readByte($offset + 4 * + ($this->columns[$keys[self::ISP-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::DOMAIN_NAME-1]][$this->db['type']] != 0) + $result->domainName = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::DOMAIN_NAME-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::ZIP_CODE-1]][$this->db['type']] != 0) + $result->zipCode = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::ZIP_CODE-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::TIME_ZONE-1]][$this->db['type']] != 0) + $result->timeZone = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::TIME_ZONE-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::NET_SPEED-1]][$this->db['type']] != 0)$result->netSpeed = $this->readByte($this->readByte($offset + 4 * + ($this->columns[$keys[self::NET_SPEED-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::IDD_CODE-1]][$this->db['type']] != 0)$result->iddCode = $this->readByte($this->readByte($offset + 4 * + ($this->columns[$keys[self::IDD_CODE-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::AREA_CODE-1]][$this->db['type']] != 0) + $result->areaCode = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::AREA_CODE-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::WEATHER_STATION_CODE-1]][$this->db['type']] != 0) + $result->weatherStationCode = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::WEATHER_STATION_CODE-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::WEATHER_STATION_NAME-1]][$this->db['type']] != 0) + $result->weatherStationName = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::WEATHER_STATION_NAME-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::MCC-1]][$this->db['type']] != 0) + $result->mcc = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::MCC-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::MNC-1]][$this->db['type']] != 0) + $result->mnc = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::MNC-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::MOBILE_CARRIER_NAME-1]][$this->db['type']] != 0) + $result->mobileCarrierName = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::MOBILE_CARRIER_NAME-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::ELEVATION-1]][$this->db['type']] != 0) + $result->elevation = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::ELEVATION-1]][$this->db['type']]-1), '32'), 'string', true); + + if($this->columns[$keys[self::USAGE_TYPE-1]][$this->db['type']] != 0) + $result->usageType = $this->readByte($this->readByte($offset + 4 * ($this->columns[$keys[self::USAGE_TYPE-1]][$this->db['type']]-1), '32'), 'string', true); + + return $result; + } + } + else{ + if($ipNumber < $ipFrom){ + $high = $mid - 1; + } + else{ + $low = $mid + 1; + } + } + } + } +} +?> \ No newline at end of file diff --git a/IP2Location/Model/IP2LocationCore.php b/IP2Location/Model/IP2LocationCore.php new file mode 100644 index 0000000..f61f10e --- /dev/null +++ b/IP2Location/Model/IP2LocationCore.php @@ -0,0 +1,69 @@ + + * @copyright Copyright 2014, IP2Location.com (http://www.ip2location.com) + * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + * @version 1.0 + * @since File available since Release 2.0 + */ + +App::uses('AppModel', 'Model'); + +/** + * Include PEAR Net_GeoIP class + */ +App::import('IP2Location.Lib', 'IP2Location'); + +/** + * GeoIP Location class + */ +class IP2LocationCore extends AppModel +{ + /** + * Container for data returned by the find method + * + * @var array + * @access public + */ + public $data = array(); + + /** + * The name of the model + * + * @var string + * @access public + */ + public $name = 'IP2LocationCore'; + + public $useTable = false; + + /** + * Find + * + * @param string $ipAddr The IP Address for which to find the location. + * @return mixed Array of location data or null if no location found. + * @access public + */ + public function get($ip, $query = array()) + { + $obj = new IP2Location(dirname(dirname(__FILE__)) . DS . 'data' . DS . 'IP2LOCATION.BIN', IP2Location::FILE_IO); + + try { + $records = $obj->lookup($ip, IP2Location::ALL); + } catch (Exception $e) { + return null; + } + return $records; + } +} diff --git a/IP2Location/data/IP2LOCATION.BIN b/IP2Location/data/IP2LOCATION.BIN new file mode 100644 index 0000000..d65f2c2 Binary files /dev/null and b/IP2Location/data/IP2LOCATION.BIN differ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..729c84e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 IP2Location.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..b1cbfbc --- /dev/null +++ b/README @@ -0,0 +1,59 @@ +IP2Location CakePHP Plugin +========================== +IP2Location CakePHP plugin enables the user to find the country, region, city, coordinates, zip code, +time zone, ISP, domain name, connection type, area code, weather, MCC, MNC, mobile brand name, elevation +and usage type that any IP address or hostname originates from. It has been optimized for speed and memory +utilization. Developers can use the API to query all IP2Location BIN databases for applications +written using CakePHP. + + +INSTALLATION +------------ + +1. Copy the IP2Location folder to app/Plugin. +2. Add "CakePlugin::load('IP2Location');" to the last line of "app/Config/bootstrap.php" +3. Download IP2Location BIN database + - IP2Location free LITE database at http://lite.ip2location.com + - IP2Location commercial database at http://www.ip2location.com +4. Unzip and copy the BIN file into app/Plugin/IP2Location/data folder. +5. Rename the BIN file to IP2LOCATION.BIN. + +Note: The plugin has included an old BIN database for your testing and development. +You may want to download a latest copy of BIN database as the URL stated above. + + +USAGE +--------------- + +App::uses('IP2LocationCore', 'IP2Location.Model'); +$IP2Location = new IP2LocationCore(); +$record = $IP2Location->get($this->request->clientIp()); + +echo 'IP Address: ' . $record->ipAddress . '
'; +echo 'IP Number: ' . $record->ipNumber . '
'; +echo 'ISO Country Code: ' . $record->countryCode . '
'; +echo 'Country Name: ' . $record->countryName . '
'; +echo 'Region Name: ' . $record->regionName . '
'; +echo 'City Name: ' . $record->cityName . '
'; +echo 'Latitude: ' . $record->latitude . '
'; +echo 'Longitude: ' . $record->longitude . '
'; +echo 'ZIP Code: ' . $record->zipCode . '
'; +echo 'Time Zone: ' . $record->timeZone . '
'; +echo 'ISP Name: ' . $record->isp . '
'; +echo 'Domain Name: ' . $record->domainName . '
'; +echo 'Net Speed: ' . $record->netSpeed . '
'; +echo 'IDD Code: ' . $record->iddCode . '
'; +echo 'Area Code: ' . $record->areaCode . '
'; +echo 'Weather Station Code: ' . $record->weatherStationCode . '
'; +echo 'Weather Station Name: ' . $record->weatherStationName . '
'; +echo 'MCC: ' . $record->mcc . '
'; +echo 'MNC: ' . $record->mnc . '
'; +echo 'Mobile Carrier Name: ' . $record->mobileCarrierName . '
'; +echo 'Elevation: ' . $record->elevation . '
'; +echo 'Usage Type: ' . $record->usageType . '
'; + + +SUPPORT +------- +Email: support@ip2location.com +Website: http://www.ip2location.com