You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
4.5 KiB

  1. <?php
  2. namespace p3k\url;
  3. function display_url($url) {
  4. # remove scheme and www.
  5. $url = preg_replace('/^https?:\/\/(www\.)?/', '', $url);
  6. # if the remaining string has no path components but has a trailing slash, remove the trailing slash
  7. $url = preg_replace('/^([^\/]+)\/$/', '$1', $url);
  8. return $url;
  9. }
  10. function add_query_params_to_url($url, $add_params) {
  11. $parts = parse_url($url);
  12. if(array_key_exists('query', $parts) && $parts['query']) {
  13. parse_str($parts['query'], $params);
  14. } else {
  15. $params = [];
  16. }
  17. foreach($add_params as $k=>$v) {
  18. $params[$k] = $v;
  19. }
  20. $parts['query'] = http_build_query($params);
  21. return build_url($parts);
  22. }
  23. function strip_tracking_params($url) {
  24. $parts = parse_url($url);
  25. if(!array_key_exists('query', $parts))
  26. return $url;
  27. parse_str($parts['query'], $params);
  28. $new_params = [];
  29. foreach($params as $key=>$val) {
  30. if(substr($key, 0, 4) != 'utm_')
  31. $new_params[$key] = $val;
  32. }
  33. $parts['query'] = http_build_query($new_params);
  34. return build_url($parts);
  35. }
  36. // Input: Any URL or string like "aaronparecki.com"
  37. // Output: Normalized URL (default to http if no scheme, force "/" path)
  38. // or return false if not a valid URL
  39. function normalize($url) {
  40. $parts = parse_url($url);
  41. if(array_key_exists('path', $parts) && $parts['path'] == '')
  42. return false;
  43. // parse_url returns just "path" for naked domains
  44. if(count($parts) == 1 && array_key_exists('path', $parts)) {
  45. $parts['host'] = $parts['path'];
  46. unset($parts['path']);
  47. }
  48. if(!array_key_exists('scheme', $parts))
  49. $parts['scheme'] = 'http';
  50. if(!array_key_exists('path', $parts))
  51. $parts['path'] = '/';
  52. // Invalid scheme
  53. if(!in_array($parts['scheme'], array('http','https')))
  54. return false;
  55. return build_url($parts);
  56. }
  57. // Inverse of parse_url()
  58. // http://php.net/parse_url
  59. function build_url($parsed_url) {
  60. $scheme = !empty($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
  61. $host = !empty($parsed_url['host']) ? $parsed_url['host'] : '';
  62. $port = !empty($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
  63. $user = !empty($parsed_url['user']) ? $parsed_url['user'] : '';
  64. $pass = !empty($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
  65. $pass = ($user || $pass) ? "$pass@" : '';
  66. $path = !empty($parsed_url['path']) ? $parsed_url['path'] : '';
  67. $query = !empty($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
  68. $fragment = !empty($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
  69. return "$scheme$user$pass$host$port$path$query$fragment";
  70. }
  71. function host_matches($a, $b) {
  72. return parse_url($a, PHP_URL_HOST) == parse_url($b, PHP_URL_HOST);
  73. }
  74. function is_url($url) {
  75. return is_string($url) && preg_match('/^https?:\/\/[a-z0-9\.\-]\/?/', $url);
  76. }
  77. function is_public_ip($ip) {
  78. // http://stackoverflow.com/a/30143143
  79. //Private ranges...
  80. //http://www.iana.org/assignments/iana-ipv4-special-registry/
  81. $networks = array('10.0.0.0' => '255.0.0.0', //LAN.
  82. '172.16.0.0' => '255.240.0.0', //LAN.
  83. '192.168.0.0' => '255.255.0.0', //LAN.
  84. '127.0.0.0' => '255.0.0.0', //Loopback.
  85. '169.254.0.0' => '255.255.0.0', //Link-local.
  86. '100.64.0.0' => '255.192.0.0', //Carrier.
  87. '192.0.2.0' => '255.255.255.0', //Testing.
  88. '198.18.0.0' => '255.254.0.0', //Testing.
  89. '198.51.100.0' => '255.255.255.0', //Testing.
  90. '203.0.113.0' => '255.255.255.0', //Testing.
  91. '192.0.0.0' => '255.255.255.0', //Reserved.
  92. '224.0.0.0' => '224.0.0.0', //Reserved.
  93. '0.0.0.0' => '255.0.0.0'); //Reserved.
  94. $ip = @inet_pton($ip);
  95. if (strlen($ip) !== 4) { return false; }
  96. //Is the IP in a private range?
  97. foreach($networks as $network_address => $network_mask) {
  98. $network_address = inet_pton($network_address);
  99. $network_mask = inet_pton($network_mask);
  100. assert(strlen($network_address) === 4);
  101. assert(strlen($network_mask) === 4);
  102. if (($ip & $network_mask) === $network_address)
  103. return false;
  104. }
  105. return true;
  106. }
  107. function geo_to_latlng($uri) {
  108. if(preg_match('/geo:([\-\+]?[0-9\.]+),([\-\+]?[0-9\.]+)/', $uri, $match)) {
  109. return array(
  110. 'latitude' => (double)$match[1],
  111. 'longitude' => (double)$match[2],
  112. );
  113. } else {
  114. return false;
  115. }
  116. }