/src/CountryLoader.php

https://github.com/rinvex/country · PHP · 248 lines · 121 code · 37 blank · 90 comment · 21 complexity · 4ac2a4c984c4157210ca6e43abba948a MD5 · raw file

  1. <?php
  2. declare(strict_types=1);
  3. namespace Rinvex\Country;
  4. use Closure;
  5. class CountryLoader
  6. {
  7. /**
  8. * The countries array.
  9. *
  10. * @var array
  11. */
  12. protected static $countries;
  13. /**
  14. * Get the country by it's ISO 3166-1 alpha-2.
  15. *
  16. * @param string $code
  17. * @param bool $hydrate
  18. *
  19. * @throws \Rinvex\Country\CountryLoaderException
  20. *
  21. * @return \Rinvex\Country\Country|array
  22. */
  23. public static function country($code, $hydrate = true)
  24. {
  25. $code = mb_strtolower($code);
  26. if (! isset(static::$countries[$code])) {
  27. static::$countries[$code] = json_decode(static::getFile(__DIR__.'/../resources/data/'.$code.'.json'), true);
  28. }
  29. return $hydrate ? new Country(static::$countries[$code]) : static::$countries[$code];
  30. }
  31. /**
  32. * Get all countries short-listed.
  33. *
  34. * @param bool $longlist
  35. * @param bool $hydrate
  36. *
  37. * @throws \Rinvex\Country\CountryLoaderException
  38. *
  39. * @return array
  40. */
  41. public static function countries($longlist = false, $hydrate = false)
  42. {
  43. $list = $longlist ? 'longlist' : 'shortlist';
  44. if (! isset(static::$countries[$list])) {
  45. static::$countries[$list] = json_decode(static::getFile(__DIR__.'/../resources/data/'.$list.'.json'), true);
  46. }
  47. return $hydrate ? array_map(function ($country) {
  48. return new Country($country);
  49. }, static::$countries[$list]) : static::$countries[$list];
  50. }
  51. /**
  52. * Filter items by the given key value pair.
  53. *
  54. * @param string $key
  55. * @param mixed $operator
  56. * @param mixed $value
  57. *
  58. * @throws \Rinvex\Country\CountryLoaderException
  59. *
  60. * @return array
  61. */
  62. public static function where($key, $operator, $value = null)
  63. {
  64. if (func_num_args() === 2) {
  65. $value = $operator;
  66. $operator = '=';
  67. }
  68. if (! isset(static::$countries['longlist'])) {
  69. static::$countries['longlist'] = json_decode(static::getFile(__DIR__.'/../resources/data/longlist.json'), true);
  70. }
  71. return static::filter(static::$countries['longlist'], static::operatorForWhere($key, $operator, $value));
  72. }
  73. /**
  74. * Get an operator checker callback.
  75. *
  76. * @param string $key
  77. * @param string $operator
  78. * @param mixed $value
  79. *
  80. * @return \Closure
  81. */
  82. protected static function operatorForWhere($key, $operator, $value)
  83. {
  84. return function ($item) use ($key, $operator, $value) {
  85. $retrieved = static::get($item, $key);
  86. switch ($operator) {
  87. default:
  88. case '=':
  89. case '==': return $retrieved == $value;
  90. case '!=':
  91. case '<>': return $retrieved != $value;
  92. case '<': return $retrieved < $value;
  93. case '>': return $retrieved > $value;
  94. case '<=': return $retrieved <= $value;
  95. case '>=': return $retrieved >= $value;
  96. case '===': return $retrieved === $value;
  97. case '!==': return $retrieved !== $value;
  98. }
  99. };
  100. }
  101. /**
  102. * Run a filter over each of the items.
  103. *
  104. * @param array $items
  105. * @param callable|null $callback
  106. *
  107. * @return array
  108. */
  109. protected static function filter($items, callable $callback = null)
  110. {
  111. if ($callback) {
  112. return array_filter($items, $callback, ARRAY_FILTER_USE_BOTH);
  113. }
  114. return array_filter($items);
  115. }
  116. /**
  117. * Get an item from an array or object using "dot" notation.
  118. *
  119. * @param mixed $target
  120. * @param string|array $key
  121. * @param mixed $default
  122. *
  123. * @return mixed
  124. */
  125. protected static function get($target, $key, $default = null)
  126. {
  127. if (is_null($key)) {
  128. return $target;
  129. }
  130. $key = is_array($key) ? $key : explode('.', $key);
  131. while (($segment = array_shift($key)) !== null) {
  132. if ($segment === '*') {
  133. if (! is_array($target)) {
  134. return $default instanceof Closure ? $default() : $default;
  135. }
  136. $result = static::pluck($target, $key);
  137. return in_array('*', $key) ? static::collapse($result) : $result;
  138. }
  139. if (is_array($target) && array_key_exists($segment, $target)) {
  140. $target = $target[$segment];
  141. } elseif (is_object($target) && isset($target->{$segment})) {
  142. $target = $target->{$segment};
  143. } else {
  144. return $default instanceof Closure ? $default() : $default;
  145. }
  146. }
  147. return $target;
  148. }
  149. /**
  150. * Pluck an array of values from an array.
  151. *
  152. * @param array $array
  153. * @param string|array $value
  154. * @param string|array|null $key
  155. *
  156. * @return array
  157. */
  158. protected static function pluck($array, $value, $key = null)
  159. {
  160. $results = [];
  161. $value = is_string($value) ? explode('.', $value) : $value;
  162. $key = is_null($key) || is_array($key) ? $key : explode('.', $key);
  163. foreach ($array as $item) {
  164. $itemValue = static::get($item, $value);
  165. // If the key is "null", we will just append the value to the array and keep
  166. // looping. Otherwise we will key the array using the value of the key we
  167. // received from the developer. Then we'll return the final array form.
  168. if (is_null($key)) {
  169. $results[] = $itemValue;
  170. } else {
  171. $itemKey = static::get($item, $key);
  172. $results[$itemKey] = $itemValue;
  173. }
  174. }
  175. return $results;
  176. }
  177. /**
  178. * Collapse an array of arrays into a single array.
  179. *
  180. * @param array $array
  181. *
  182. * @return array
  183. */
  184. protected static function collapse($array)
  185. {
  186. $results = [];
  187. foreach ($array as $values) {
  188. if (! is_array($values)) {
  189. continue;
  190. }
  191. $results = array_merge($results, $values);
  192. }
  193. return $results;
  194. }
  195. /**
  196. * Get contents of the given file path.
  197. *
  198. * @param string $filePath
  199. *
  200. * @throws \Rinvex\Country\CountryLoaderException
  201. *
  202. * @return string
  203. */
  204. protected static function getFile($filePath)
  205. {
  206. if (! file_exists($filePath)) {
  207. throw CountryLoaderException::invalidCountry();
  208. }
  209. return file_get_contents($filePath);
  210. }
  211. }