PageRenderTime 57ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/cp/expressionengine/modules/ip_to_nation/models/ip_to_nation_data.php

https://bitbucket.org/sbeuken/artelux
PHP | 190 lines | 113 code | 37 blank | 40 comment | 10 complexity | d8135fad4c7e52fb5049ec05fc1e0e25 MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. class Ip_to_nation_data extends CI_Model {
  3. private $table = 'ip2nation';
  4. private $c_table = 'ip2nation_countries';
  5. // ----------------------------------------------------------------------
  6. /**
  7. * Get a country by ip address
  8. */
  9. function find($ip)
  10. {
  11. $BIN = $this->to_binary($ip);
  12. $query = $this->db
  13. ->select('country')
  14. ->where("ip_range_low <= '".$BIN."'", '', FALSE)
  15. ->where("ip_range_high >= '".$BIN."'", '', FALSE)
  16. ->order_by('ip_range_low', 'desc')
  17. ->limit(1, 0)
  18. ->get($this->table);
  19. if ( ! $query->num_rows())
  20. {
  21. return FALSE;
  22. }
  23. return $query->row('country');
  24. }
  25. // ----------------------------------------------------------------------
  26. /**
  27. * Replace IP data with that of all the files in `$dir`
  28. */
  29. function load_dir($dir)
  30. {
  31. $dir = rtrim($dir, '/');
  32. return $this->load(
  33. glob($dir.'/*.csv')
  34. );
  35. }
  36. // ----------------------------------------------------------------------
  37. /**
  38. * Replace IP data with that in `$files`
  39. */
  40. function load($files)
  41. {
  42. // get old banned info
  43. $banned = $this->db
  44. ->select('code')
  45. ->get_where($this->c_table, array('banned' => 'y'))
  46. ->result_array();
  47. // all we care about is if it's set
  48. $banned = array_map('array_pop', $banned);
  49. $banned = array_flip($banned);
  50. // remove all data
  51. $this->db->truncate($this->table);
  52. $this->db->truncate($this->c_table);
  53. // populate the db with file data
  54. $files = (array) $files;
  55. $countries = array();
  56. foreach ($files as $file)
  57. {
  58. $add_countries = $this->_read_and_insert($file);
  59. $countries = array_merge($countries, $add_countries);
  60. }
  61. // sort the new ones for a pretty db
  62. sort($countries);
  63. $countries = array_unique($countries);
  64. $countries = array_map('strtolower', $countries);
  65. // merge with the banned and insert
  66. foreach ($countries as &$c)
  67. {
  68. $c = array(
  69. 'code' => $c,
  70. 'banned' => isset($banned[$c]) ? 'y' : 'n'
  71. );
  72. }
  73. $this->db->insert_batch($this->c_table, $countries);
  74. }
  75. // ----------------------------------------------------------------------
  76. /**
  77. * Ban a countries by their country code
  78. */
  79. function ban($countries)
  80. {
  81. // Set all countries to unbanned
  82. $this->db->update($this->c_table, array('banned' => 'n'));
  83. // And then reban those we know about
  84. if (count($countries))
  85. {
  86. $this->db
  87. ->where_in('code', $countries)
  88. ->update($this->c_table, array('banned' => 'y'));
  89. }
  90. }
  91. // ----------------------------------------------------------------------
  92. /**
  93. * Convert an IP address to its IPv6 packed format
  94. */
  95. function to_binary($addr)
  96. {
  97. // all IPv4 go to IPv6 mapped
  98. if (strpos($addr, ':') === FALSE && strpos($addr, '.') !== FALSE)
  99. {
  100. $addr = '::'.$addr;
  101. }
  102. return inet_pton($addr);
  103. }
  104. // ----------------------------------------------------------------------
  105. /**
  106. * Read the ip file and update the db
  107. *
  108. * Returns a list of countries in the file
  109. */
  110. private function _read_and_insert($file)
  111. {
  112. if (($fh = fopen($file, 'r')) === FALSE)
  113. {
  114. return FALSE;
  115. }
  116. $batch = 0;
  117. $insert = array();
  118. $countries = array();
  119. while (($data = fgetcsv($fh, 300, ',')) !== FALSE)
  120. {
  121. if (count($data) < 5)
  122. {
  123. continue;
  124. }
  125. // $low, $high, $dec_low, $dec_high, $c_code, $c_name
  126. $insert[$batch++] = array(
  127. 'ip_range_low' => $this->to_binary($data[0]),
  128. 'ip_range_high' => $this->to_binary($data[1]),
  129. 'country' => strtolower($data[4])
  130. );
  131. $countries[] = $data[4];
  132. if ($batch >= 1000)
  133. {
  134. $countries = array_unique($countries);
  135. $this->db->insert_batch('exp_ip2nation', $insert);
  136. $batch = 0;
  137. $insert = array();
  138. }
  139. }
  140. // deal with leftovers
  141. if (count($insert))
  142. {
  143. $this->db->insert_batch('exp_ip2nation', $insert);
  144. }
  145. $countries = array_unique($countries);
  146. sort($countries);
  147. fclose($fh);
  148. return $countries;
  149. }
  150. }
  151. /* End of file Iptonation_math.php */
  152. /* Location: system/expressionengine/modules/ip_to_nation/libraries/Iptonation_math.php
  153. */