PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/cp/expressionengine/helpers/compat_helper.php

https://bitbucket.org/sbeuken/artelux
PHP | 297 lines | 180 code | 49 blank | 68 comment | 53 complexity | d846ddbc5b61c2e30bd97de6e1d3fb91 MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * ExpressionEngine - by EllisLab
  4. *
  5. * @package ExpressionEngine
  6. * @author EllisLab Dev Team
  7. * @copyright Copyright (c) 2003 - 2012, EllisLab, Inc.
  8. * @license http://ellislab.com/expressionengine/user-guide/license.html
  9. * @link http://ellislab.com
  10. * @since Version 2.0
  11. * @filesource
  12. */
  13. // ------------------------------------------------------------------------
  14. /**
  15. * ExpressionEngine Compat Helper
  16. *
  17. * @package ExpressionEngine
  18. * @subpackage Helpers
  19. * @category Helpers
  20. * @author EllisLab Dev Team
  21. * @link http://ellislab.com
  22. */
  23. // ------------------------------------------------------------------------
  24. /**
  25. * Fixes a bug in PHP 5.2.9 where sort flags defaulted
  26. * to SORT_REGULAR, resulting in some very odd removal
  27. * behavior. And since we have now started using it,
  28. * we stupidly need to compat the whole thing. -pk
  29. */
  30. function ee_array_unique(array $arr, $sort_flags = SORT_STRING)
  31. {
  32. // 5.2.9 introduced both the flags and the bug
  33. if (is_php('5.2.9'))
  34. {
  35. return array_unique($arr, $sort_flags);
  36. }
  37. // before 5.2.9 sort_string was the default
  38. if ($sort_flags === SORT_STRING)
  39. {
  40. return array_unique($arr);
  41. }
  42. // no point uniquing an array of 1 or nil
  43. if (count($arr) < 2)
  44. {
  45. return $arr;
  46. }
  47. // to be in parity with php's solution,
  48. // we need to keep the original key positions
  49. $key_pos = array_flip(array_keys($arr));
  50. $ret_arr = $arr;
  51. asort($arr, $sort_flags);
  52. $last_kept = reset($arr);
  53. $last_kept_k = key($arr);
  54. next($arr); // skip ahead
  55. while (list($k, $v) = each($arr))
  56. {
  57. if ($sort_flags === SORT_NUMERIC)
  58. {
  59. $keep = (bool) ((float) $last_kept - (float) $v);
  60. }
  61. else // SORT_REGULAR
  62. {
  63. $keep = ($last_kept != $v);
  64. }
  65. if ($keep)
  66. {
  67. $last_kept = $v;
  68. $last_kept_k = $k;
  69. }
  70. else
  71. {
  72. // This is the mind boggling and in my opinion buggy part of
  73. // the algorithm php uses. We unset any duplicates that follow
  74. // the first value. Which is fine thinking narrowly about unique
  75. // array values.
  76. // However, it's extremely unintuitive when thinking about php
  77. // arrays, where duplicate keys override earlier keys.
  78. // It also makes this algorithm unstable, so that moving a boolean
  79. // true value to different spots in the array vastly changes the
  80. // output.
  81. $unset = $k;
  82. if ($key_pos[$last_kept_k] > $key_pos[$k])
  83. {
  84. $unset = $last_kept_k;
  85. $last_kept = $v;
  86. $last_kept_k = $k;
  87. }
  88. unset($arr[$unset]);
  89. unset($ret_arr[$unset]);
  90. }
  91. }
  92. unset($arr);
  93. return $ret_arr;
  94. }
  95. // ------------------------------------------------------------------------
  96. /**
  97. * Based on the c implementation from the ISC
  98. */
  99. function ee_inet_ntop($ip)
  100. {
  101. // unpack the binary
  102. $hex = unpack('H*', $ip);
  103. $hex = current($hex);
  104. $len = strlen($hex);
  105. // ipv4
  106. if ($len == 8)
  107. {
  108. $parts = str_split($hex, 2);
  109. $parts = array_map('hexdec', $parts);
  110. return implode('.', $parts);
  111. }
  112. // ipv6
  113. if ($len != 32)
  114. {
  115. show_error('Invalid IP address.');
  116. }
  117. $parts = str_split($hex, 4);
  118. // find the longest run of zeros
  119. $start = -1;
  120. $len = 0;
  121. $best_start = -1;
  122. $best_len = 0;
  123. foreach ($parts as $i => &$part)
  124. {
  125. if ($part == '0000')
  126. {
  127. if ($start == -1)
  128. {
  129. $start = $i;
  130. $len = 0;
  131. }
  132. $len++;
  133. }
  134. elseif ($start != -1 && ($best_start == -1 OR $len > $best_len))
  135. {
  136. $best_start = $start;
  137. $best_len = $len;
  138. $start = -1;
  139. }
  140. }
  141. // didn't move best?
  142. if ($start != -1 && ($best_start == -1 OR $len > $best_len))
  143. {
  144. $best_start = $start;
  145. $best_len = $len;
  146. }
  147. // print out the result
  148. $out = '';
  149. foreach ($parts as $i => &$part)
  150. {
  151. if ($best_start != -1)
  152. {
  153. if ($i >= $best_start && $i < ($best_start + $best_len))
  154. {
  155. if ($i == $best_start)
  156. {
  157. $out .= ':';
  158. }
  159. continue;
  160. }
  161. }
  162. if ($i)
  163. {
  164. $out .= ':';
  165. }
  166. // ipv4 mapped?
  167. if ($i == 6 && $best_start == 0 &&
  168. ($best_len == 6 OR ($best_len == 5 && $parts[5] == 'ffff')))
  169. {
  170. $out .= ee_inet_ntop(pack('H4H4', $parts[6], $parts[7]));
  171. break;
  172. }
  173. // collapse the hex string
  174. $out .= sprintf('%x', hexdec($part));
  175. }
  176. return $out;
  177. }
  178. // ------------------------------------------------------------------------
  179. /**
  180. * Based loosely on the c implementation from the ISC
  181. */
  182. function ee_inet_pton($str)
  183. {
  184. $pad_off = -1;
  185. if (strpos($str, ':') !== FALSE)
  186. {
  187. $parts = explode(':', $str);
  188. foreach ($parts as $i => &$part)
  189. {
  190. if ($part === '' && $pad_off == -1)
  191. {
  192. $pad_off = $i;
  193. continue;
  194. }
  195. // ipv4 mapped?
  196. if (strpos($part, '.'))
  197. {
  198. if ($i + 1 != count($parts))
  199. {
  200. show_error('Invalid IP address.');
  201. }
  202. // convert the ipv4 one, unpack as hex, pad, and add
  203. // I'm sure there is a way to just concatenate the binary
  204. // but I can't figure it out right now
  205. $ipv4 = unpack('H*', ee_inet_pton($part));
  206. list($cur, $next) = str_split(current($ipv4), 4);
  207. $part = str_pad($cur, 4, '0', STR_PAD_LEFT);
  208. $parts[$i + 1] = str_pad($next, 4, '0', STR_PAD_LEFT);
  209. break;
  210. }
  211. $part = str_pad($part, 4, '0', STR_PAD_LEFT);
  212. }
  213. if ($pad_off != -1)
  214. {
  215. $pad_len = 9 - count($parts);
  216. $zeros = array_fill(0, $pad_len, '0000');
  217. array_splice($parts, $pad_off, 1, $zeros);
  218. }
  219. $args = $parts;
  220. array_unshift($args, str_repeat('H4', 8));
  221. return call_user_func_array('pack', $args);
  222. }
  223. if (strpos($str, '.'))
  224. {
  225. return pack('N', ip2long($str));
  226. }
  227. show_error('Invalid IP address.');
  228. }
  229. // ------------------------------------------------------------------------
  230. /**
  231. * Some windows servers don't have the inet_* functions
  232. */
  233. if ( ! function_exists('inet_ntop'))
  234. {
  235. function inet_ntop($in)
  236. {
  237. return ee_inet_ntop($in);
  238. }
  239. }
  240. if ( ! function_exists('inet_pton'))
  241. {
  242. function inet_pton($in)
  243. {
  244. return ee_inet_pton($in);
  245. }
  246. }
  247. /* End of file */
  248. /* Location: ./system/expressionengine/helpers/compat_helper.php */