PageRenderTime 40ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/Country.php

https://gitlab.com/goolic/PrestaShop
PHP | 417 lines | 272 code | 52 blank | 93 comment | 27 complexity | 01b8a9fd76527cb6215c9378e22b457b MD5 | raw file
  1. <?php
  2. /**
  3. * 2007-2015 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2015 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. class CountryCore extends ObjectModel
  27. {
  28. public $id;
  29. /** @var int Zone id which country belongs */
  30. public $id_zone;
  31. /** @var int Currency id which country belongs */
  32. public $id_currency;
  33. /** @var string 2 letters iso code */
  34. public $iso_code;
  35. /** @var int international call prefix */
  36. public $call_prefix;
  37. /** @var string Name */
  38. public $name;
  39. /** @var bool Contain states */
  40. public $contains_states;
  41. /** @var bool Need identification number dni/nif/nie */
  42. public $need_identification_number;
  43. /** @var bool Need Zip Code */
  44. public $need_zip_code;
  45. /** @var string Zip Code Format */
  46. public $zip_code_format;
  47. /** @var bool Display or not the tax incl./tax excl. mention in the front office */
  48. public $display_tax_label = true;
  49. /** @var bool Status for delivery */
  50. public $active = true;
  51. protected static $_idZones = array();
  52. /**
  53. * @see ObjectModel::$definition
  54. */
  55. public static $definition = array(
  56. 'table' => 'country',
  57. 'primary' => 'id_country',
  58. 'multilang' => true,
  59. 'fields' => array(
  60. 'id_zone' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
  61. 'id_currency' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
  62. 'call_prefix' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
  63. 'iso_code' => array('type' => self::TYPE_STRING, 'validate' => 'isLanguageIsoCode', 'required' => true, 'size' => 3),
  64. 'active' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
  65. 'contains_states' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool', 'required' => true),
  66. 'need_identification_number' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool', 'required' => true),
  67. 'need_zip_code' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
  68. 'zip_code_format' => array('type' => self::TYPE_STRING, 'validate' => 'isZipCodeFormat'),
  69. 'display_tax_label' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool', 'required' => true),
  70. /* Lang fields */
  71. 'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 64),
  72. ),
  73. 'associations' => array(
  74. 'zone' => array('type' => self::HAS_ONE),
  75. 'currency' => array('type' => self::HAS_ONE),
  76. )
  77. );
  78. protected static $cache_iso_by_id = array();
  79. protected $webserviceParameters = array(
  80. 'objectsNodeName' => 'countries',
  81. 'fields' => array(
  82. 'id_zone' => array('xlink_resource'=> 'zones'),
  83. 'id_currency' => array('xlink_resource'=> 'currencies'),
  84. ),
  85. );
  86. public function delete()
  87. {
  88. if (!parent::delete()) {
  89. return false;
  90. }
  91. return Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'cart_rule_country WHERE id_country = '.(int)$this->id);
  92. }
  93. /**
  94. * @brief Return available countries
  95. *
  96. * @param int $id_lang Language ID
  97. * @param bool $active return only active coutries
  98. * @param bool $contain_states return only country with states
  99. * @param bool $list_states Include the states list with the returned list
  100. *
  101. * @return Array Countries and corresponding zones
  102. */
  103. public static function getCountries($id_lang, $active = false, $contain_states = false, $list_states = true)
  104. {
  105. $countries = array();
  106. $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
  107. SELECT cl.*,c.*, cl.`name` country, z.`name` zone
  108. FROM `'._DB_PREFIX_.'country` c '.Shop::addSqlAssociation('country', 'c').'
  109. LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (c.`id_country` = cl.`id_country` AND cl.`id_lang` = '.(int)$id_lang.')
  110. LEFT JOIN `'._DB_PREFIX_.'zone` z ON (z.`id_zone` = c.`id_zone`)
  111. WHERE 1'.($active ? ' AND c.active = 1' : '').($contain_states ? ' AND c.`contains_states` = '.(int)$contain_states : '').'
  112. ORDER BY cl.name ASC');
  113. foreach ($result as $row) {
  114. $countries[$row['id_country']] = $row;
  115. }
  116. if ($list_states) {
  117. $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('SELECT * FROM `'._DB_PREFIX_.'state` ORDER BY `name` ASC');
  118. foreach ($result as $row) {
  119. if (isset($countries[$row['id_country']]) && $row['active'] == 1) { /* Does not keep the state if its country has been disabled and not selected */
  120. $countries[$row['id_country']]['states'][] = $row;
  121. }
  122. }
  123. }
  124. return $countries;
  125. }
  126. public static function getCountriesByIdShop($id_shop, $id_lang)
  127. {
  128. return Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
  129. SELECT *
  130. FROM `'._DB_PREFIX_.'country` c
  131. LEFT JOIN `'._DB_PREFIX_.'country_shop` cs ON (cs.`id_country`= c.`id_country`)
  132. LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (c.`id_country` = cl.`id_country` AND cl.`id_lang` = '.(int)$id_lang.')
  133. WHERE `id_shop` = '.(int)$id_shop);
  134. }
  135. /**
  136. * Get a country ID with its iso code
  137. *
  138. * @param string $iso_code Country iso code
  139. * @param bool $active return only active coutries
  140. * @return int Country ID
  141. */
  142. public static function getByIso($iso_code, $active = false)
  143. {
  144. if (!Validate::isLanguageIsoCode($iso_code)) {
  145. die(Tools::displayError());
  146. }
  147. $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
  148. SELECT `id_country`
  149. FROM `'._DB_PREFIX_.'country`
  150. WHERE `iso_code` = \''.pSQL(strtoupper($iso_code)).'\''
  151. .($active ? ' AND active = 1' : '')
  152. );
  153. if (isset($result['id_country'])) {
  154. return (int)$result['id_country'];
  155. }
  156. return false;
  157. }
  158. public static function getIdZone($id_country)
  159. {
  160. if (!Validate::isUnsignedId($id_country)) {
  161. die(Tools::displayError());
  162. }
  163. if (isset(self::$_idZones[$id_country])) {
  164. return (int)self::$_idZones[$id_country];
  165. }
  166. $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
  167. SELECT `id_zone`
  168. FROM `'._DB_PREFIX_.'country`
  169. WHERE `id_country` = '.(int)$id_country);
  170. if (isset($result['id_zone'])) {
  171. self::$_idZones[$id_country] = (int)$result['id_zone'];
  172. return (int)$result['id_zone'];
  173. }
  174. return false;
  175. }
  176. /**
  177. * Get a country name with its ID
  178. *
  179. * @param int $id_lang Language ID
  180. * @param int $id_country Country ID
  181. * @return string Country name
  182. */
  183. public static function getNameById($id_lang, $id_country)
  184. {
  185. $key = 'country_getNameById_'.$id_country.'_'.$id_lang;
  186. if (!Cache::isStored($key)) {
  187. $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
  188. SELECT `name`
  189. FROM `'._DB_PREFIX_.'country_lang`
  190. WHERE `id_lang` = '.(int)$id_lang.'
  191. AND `id_country` = '.(int)$id_country
  192. );
  193. Cache::store($key, $result);
  194. return $result;
  195. }
  196. return Cache::retrieve($key);
  197. }
  198. /**
  199. * Get a country iso with its ID
  200. *
  201. * @param int $id_country Country ID
  202. * @return string Country iso
  203. */
  204. public static function getIsoById($id_country)
  205. {
  206. if (!isset(Country::$cache_iso_by_id[$id_country])) {
  207. Country::$cache_iso_by_id[$id_country] = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
  208. SELECT `iso_code`
  209. FROM `'._DB_PREFIX_.'country`
  210. WHERE `id_country` = '.(int)$id_country);
  211. }
  212. if (isset(Country::$cache_iso_by_id[$id_country])) {
  213. return Country::$cache_iso_by_id[$id_country];
  214. }
  215. return false;
  216. }
  217. /**
  218. * Get a country id with its name
  219. *
  220. * @param int $id_lang Language ID
  221. * @param string $country Country Name
  222. * @return int Country ID
  223. */
  224. public static function getIdByName($id_lang = null, $country)
  225. {
  226. $sql = '
  227. SELECT `id_country`
  228. FROM `'._DB_PREFIX_.'country_lang`
  229. WHERE `name` = \''.pSQL($country).'\'';
  230. if ($id_lang) {
  231. $sql .= ' AND `id_lang` = '.(int)$id_lang;
  232. }
  233. $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql);
  234. if (isset($result['id_country'])) {
  235. return (int)$result['id_country'];
  236. }
  237. return false;
  238. }
  239. public static function getNeedZipCode($id_country)
  240. {
  241. if (!(int)$id_country) {
  242. return false;
  243. }
  244. return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
  245. SELECT `need_zip_code`
  246. FROM `'._DB_PREFIX_.'country`
  247. WHERE `id_country` = '.(int)$id_country);
  248. }
  249. public static function getZipCodeFormat($id_country)
  250. {
  251. if (!(int)$id_country) {
  252. return false;
  253. }
  254. $zip_code_format = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
  255. SELECT `zip_code_format`
  256. FROM `'._DB_PREFIX_.'country`
  257. WHERE `id_country` = '.(int)$id_country);
  258. if (isset($zip_code_format) && $zip_code_format) {
  259. return $zip_code_format;
  260. }
  261. return false;
  262. }
  263. /**
  264. * Returns the default country Id
  265. *
  266. * @deprecated as of 1.5 use $context->country->id instead
  267. * @return int default country id
  268. */
  269. public static function getDefaultCountryId()
  270. {
  271. Tools::displayAsDeprecated();
  272. return Context::getContext()->country->id;
  273. }
  274. public static function getCountriesByZoneId($id_zone, $id_lang)
  275. {
  276. if (empty($id_zone) || empty($id_lang)) {
  277. die(Tools::displayError());
  278. }
  279. $sql = ' SELECT DISTINCT c.*, cl.*
  280. FROM `'._DB_PREFIX_.'country` c
  281. '.Shop::addSqlAssociation('country', 'c', false).'
  282. LEFT JOIN `'._DB_PREFIX_.'state` s ON (s.`id_country` = c.`id_country`)
  283. LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (c.`id_country` = cl.`id_country`)
  284. WHERE (c.`id_zone` = '.(int)$id_zone.' OR s.`id_zone` = '.(int)$id_zone.')
  285. AND `id_lang` = '.(int)$id_lang;
  286. return Db::getInstance()->executeS($sql);
  287. }
  288. public function isNeedDni()
  289. {
  290. return Country::isNeedDniByCountryId($this->id);
  291. }
  292. public static function isNeedDniByCountryId($id_country)
  293. {
  294. return (bool)Db::getInstance()->getValue('
  295. SELECT `need_identification_number`
  296. FROM `'._DB_PREFIX_.'country`
  297. WHERE `id_country` = '.(int)$id_country);
  298. }
  299. public static function containsStates($id_country)
  300. {
  301. return (bool)Db::getInstance()->getValue('
  302. SELECT `contains_states`
  303. FROM `'._DB_PREFIX_.'country`
  304. WHERE `id_country` = '.(int)$id_country);
  305. }
  306. /**
  307. * @param $ids_countries
  308. * @param $id_zone
  309. * @return bool
  310. */
  311. public function affectZoneToSelection($ids_countries, $id_zone)
  312. {
  313. // cast every array values to int (security)
  314. $ids_countries = array_map('intval', $ids_countries);
  315. return Db::getInstance()->execute('
  316. UPDATE `'._DB_PREFIX_.'country` SET `id_zone` = '.(int)$id_zone.' WHERE `id_country` IN ('.implode(',', $ids_countries).')
  317. ');
  318. }
  319. /**
  320. * Replace letters of zip code format And check this format on the zip code
  321. * @param $zip_code
  322. * @return (bool)
  323. */
  324. public function checkZipCode($zip_code)
  325. {
  326. $zip_regexp = '/^'.$this->zip_code_format.'$/ui';
  327. $zip_regexp = str_replace(' ', '( |)', $zip_regexp);
  328. $zip_regexp = str_replace('-', '(-|)', $zip_regexp);
  329. $zip_regexp = str_replace('N', '[0-9]', $zip_regexp);
  330. $zip_regexp = str_replace('L', '[a-zA-Z]', $zip_regexp);
  331. $zip_regexp = str_replace('C', $this->iso_code, $zip_regexp);
  332. return (bool)preg_match($zip_regexp, $zip_code);
  333. }
  334. public static function addModuleRestrictions(array $shops = array(), array $countries = array(), array $modules = array())
  335. {
  336. if (!count($shops)) {
  337. $shops = Shop::getShops(true, null, true);
  338. }
  339. if (!count($countries)) {
  340. $countries = Country::getCountries((int)Context::getContext()->cookie->id_lang);
  341. }
  342. if (!count($modules)) {
  343. $modules = Module::getPaymentModules();
  344. }
  345. $sql = false;
  346. foreach ($shops as $id_shop) {
  347. foreach ($countries as $country) {
  348. foreach ($modules as $module) {
  349. $sql .= '('.(int)$module['id_module'].', '.(int)$id_shop.', '.(int)$country['id_country'].'),';
  350. }
  351. }
  352. }
  353. if ($sql) {
  354. $sql = 'INSERT IGNORE INTO `'._DB_PREFIX_.'module_country` (`id_module`, `id_shop`, `id_country`) VALUES '.rtrim($sql, ',');
  355. return Db::getInstance()->execute($sql);
  356. } else {
  357. return true;
  358. }
  359. }
  360. public function add($autodate = true, $null_values = false)
  361. {
  362. $return = parent::add($autodate, $null_values) && self::addModuleRestrictions(array(), array(array('id_country' => $this->id)), array());
  363. return $return;
  364. }
  365. }