PageRenderTime 24ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/system/helpers/compatibility_helper.php

https://github.com/katzgrau/notes
PHP | 498 lines | 290 code | 68 blank | 140 comment | 57 complexity | 1732fa6774010d1384f2c4784611581e MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP 4.3.2 or newer
  6. *
  7. * @package CodeIgniter
  8. * @author ExpressionEngine Dev Team
  9. * @copyright Copyright (c) 2008, EllisLab, Inc.
  10. * @license http://codeigniter.com/user_guide/license.html
  11. * @link http://codeigniter.com
  12. * @since Version 1.0
  13. * @filesource
  14. */
  15. // ------------------------------------------------------------------------
  16. /**
  17. * CodeIgniter Compatibility Helpers
  18. *
  19. * This helper contains some functions based on the PEAR PHP_Compat library
  20. * http://pear.php.net/package/PHP_Compat
  21. *
  22. * The PEAR compat library is a little bloated and the code doesn't harmonize
  23. * well with CodeIgniter, so those functions have been refactored.
  24. * We cheat a little and use CI's _exception_handler() to output our own PHP errors
  25. * so that the behavior fully mimicks the PHP 5 counterparts. -- Derek Jones
  26. *
  27. * @package CodeIgniter
  28. * @subpackage Helpers
  29. * @category Helpers
  30. * @author ExpressionEngine Dev Team
  31. * @link http://codeigniter.com/user_guide/helpers/compatibility_helper.html
  32. */
  33. // ------------------------------------------------------------------------
  34. if ( ! defined('PHP_EOL'))
  35. {
  36. define('PHP_EOL', (DIRECTORY_SEPARATOR == '/') ? "\n" : "\r\n");
  37. }
  38. // ------------------------------------------------------------------------
  39. /**
  40. * file_put_contents()
  41. *
  42. * Writes a string to a file
  43. * http://us.php.net/manual/en/function.file_put_contents.php
  44. * argument 4, $context, not supported
  45. *
  46. * @access public
  47. * @param string file name
  48. * @param mixed data to be written
  49. * @param int flags
  50. * @return int length of written string
  51. */
  52. if ( ! function_exists('file_put_contents'))
  53. {
  54. function file_put_contents($filename, $data, $flags = NULL)
  55. {
  56. if (is_scalar($data))
  57. {
  58. settype($data, 'STRING');
  59. }
  60. if ( ! is_string($data) && ! is_array($data) && ! is_resource($data))
  61. {
  62. $backtrace = debug_backtrace();
  63. _exception_handler(E_USER_WARNING, 'file_put_contents(): the 2nd parameter should be either a string or an array', $backtrace[0]['file'], $backtrace[0]['line']);
  64. return FALSE;
  65. }
  66. // read stream if given a stream resource
  67. if (is_resource($data))
  68. {
  69. if (get_resource_type($data) !== 'stream')
  70. {
  71. $backtrace = debug_backtrace();
  72. _exception_handler(E_USER_WARNING, 'file_put_contents(): supplied resource is not a valid stream resource', $backtrace[0]['file'], $backtrace[0]['line']);
  73. return FALSE;
  74. }
  75. $text = '';
  76. while ( ! feof($data))
  77. {
  78. $text .= fread($data, 4096);
  79. }
  80. $data = $text;
  81. unset($text);
  82. }
  83. // strings only please!
  84. if (is_array($data))
  85. {
  86. $data = implode('', $data);
  87. }
  88. // Set the appropriate mode
  89. if (($flags & 8) > 0) // 8 = FILE_APPEND flag
  90. {
  91. $mode = FOPEN_WRITE_CREATE;
  92. }
  93. else
  94. {
  95. $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE;
  96. }
  97. // Check if we're using the include path
  98. if (($flags & 1) > 0) // 1 = FILE_USE_INCLUDE_PATH flag
  99. {
  100. $use_include_path = TRUE;
  101. }
  102. else
  103. {
  104. $use_include_path = FALSE;
  105. }
  106. $fp = @fopen($filename, $mode, $use_include_path);
  107. if ($fp === FALSE)
  108. {
  109. $backtrace = debug_backtrace();
  110. _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to open stream', $backtrace[0]['file'], $backtrace[0]['line']);
  111. return FALSE;
  112. }
  113. if (($flags & LOCK_EX) > 0)
  114. {
  115. if ( ! flock($fp, LOCK_EX))
  116. {
  117. $backtrace = debug_backtrace();
  118. _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') unable to acquire an exclusive lock on file', $backtrace[0]['file'], $backtrace[0]['line']);
  119. return FALSE;
  120. }
  121. }
  122. // write it
  123. if (($written = @fwrite($fp, $data)) === FALSE)
  124. {
  125. $backtrace = debug_backtrace();
  126. _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to write to '.htmlentities($filename), $backtrace[0]['file'], $backtrace[0]['line']);
  127. }
  128. // Close the handle
  129. @fclose($fp);
  130. // Return length
  131. return $written;
  132. }
  133. }
  134. // ------------------------------------------------------------------------
  135. /**
  136. * fputcsv()
  137. *
  138. * Format line as CSV and write to file pointer
  139. * http://us.php.net/manual/en/function.fputcsv.php
  140. *
  141. * @access public
  142. * @param resource file pointer
  143. * @param array data to be written
  144. * @param string delimiter
  145. * @param string enclosure
  146. * @return int length of written string
  147. */
  148. if ( ! function_exists('fputcsv'))
  149. {
  150. function fputcsv($handle, $fields, $delimiter = ',', $enclosure = '"')
  151. {
  152. // Checking for a handle resource
  153. if ( ! is_resource($handle))
  154. {
  155. $backtrace = debug_backtrace();
  156. _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.gettype($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
  157. return FALSE;
  158. }
  159. // OK, it is a resource, but is it a stream?
  160. if (get_resource_type($handle) !== 'stream')
  161. {
  162. $backtrace = debug_backtrace();
  163. _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.get_resource_type($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
  164. return FALSE;
  165. }
  166. // Checking for an array of fields
  167. if ( ! is_array($fields))
  168. {
  169. $backtrace = debug_backtrace();
  170. _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 2 to be array, '.gettype($fields).' given', $backtrace[0]['file'], $backtrace[0]['line']);
  171. return FALSE;
  172. }
  173. // validate delimiter
  174. if (strlen($delimiter) > 1)
  175. {
  176. $delimiter = substr($delimiter, 0, 1);
  177. $backtrace = debug_backtrace();
  178. _exception_handler(E_NOTICE, 'fputcsv() delimiter must be one character long, "'.htmlentities($delimiter).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
  179. }
  180. // validate enclosure
  181. if (strlen($enclosure) > 1)
  182. {
  183. $enclosure = substr($enclosure, 0, 1);
  184. $backtrace = debug_backtrace();
  185. _exception_handler(E_NOTICE, 'fputcsv() enclosure must be one character long, "'.htmlentities($enclosure).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
  186. }
  187. $out = '';
  188. foreach ($fields as $cell)
  189. {
  190. $cell = str_replace($enclosure, $enclosure.$enclosure, $cell);
  191. if (strpos($cell, $delimiter) !== FALSE OR strpos($cell, $enclosure) !== FALSE OR strpos($cell, "\n") !== FALSE)
  192. {
  193. $out .= $enclosure.$cell.$enclosure.$delimiter;
  194. }
  195. else
  196. {
  197. $out .= $cell.$delimiter;
  198. }
  199. }
  200. $length = @fwrite($handle, substr($out, 0, -1)."\n");
  201. return $length;
  202. }
  203. }
  204. // ------------------------------------------------------------------------
  205. /**
  206. * stripos()
  207. *
  208. * Find position of first occurrence of a case-insensitive string
  209. * http://us.php.net/manual/en/function.stripos.php
  210. *
  211. * @access public
  212. * @param string haystack
  213. * @param string needle
  214. * @param int offset
  215. * @return int numeric position of the first occurrence of needle in the haystack
  216. */
  217. if ( ! function_exists('stripos'))
  218. {
  219. function stripos($haystack, $needle, $offset = NULL)
  220. {
  221. // Cast non string scalar values
  222. if (is_scalar($haystack))
  223. {
  224. settype($haystack, 'STRING');
  225. }
  226. if ( ! is_string($haystack))
  227. {
  228. $backtrace = debug_backtrace();
  229. _exception_handler(E_USER_WARNING, 'stripos() expects parameter 1 to be string, '.gettype($haystack).' given', $backtrace[0]['file'], $backtrace[0]['line']);
  230. return FALSE;
  231. }
  232. if ( ! is_scalar($needle))
  233. {
  234. $backtrace = debug_backtrace();
  235. _exception_handler(E_USER_WARNING, 'stripos() needle is not a string or an integer in '.$backtrace[0]['file'], $backtrace[0]['line']);
  236. return FALSE;
  237. }
  238. if (is_float($offset))
  239. {
  240. $offset = (int)$offset;
  241. }
  242. if ( ! is_int($offset) && ! is_bool($offset) && ! is_null($offset))
  243. {
  244. $backtrace = debug_backtrace();
  245. _exception_handler(E_USER_WARNING, 'stripos() expects parameter 3 to be long, '.gettype($offset).' given', $backtrace[0]['file'], $backtrace[0]['line']);
  246. return NULL;
  247. }
  248. return strpos(strtolower($haystack), strtolower($needle), $offset);
  249. }
  250. }
  251. // ------------------------------------------------------------------------
  252. /**
  253. * str_ireplace()
  254. *
  255. * Find position of first occurrence of a case-insensitive string
  256. * http://us.php.net/manual/en/function.str-ireplace.php
  257. * (parameter 4, $count, is not supported as to do so in PHP 4 would make
  258. * it a required parameter)
  259. *
  260. * @access public
  261. * @param mixed search
  262. * @param mixed replace
  263. * @param mixed subject
  264. * @return int numeric position of the first occurrence of needle in the haystack
  265. */
  266. if ( ! function_exists('str_ireplace'))
  267. {
  268. function str_ireplace($search, $replace, $subject)
  269. {
  270. // Nothing to do here
  271. if ($search === NULL OR $subject === NULL)
  272. {
  273. return $subject;
  274. }
  275. // Crazy arguments
  276. if (is_scalar($search) && is_array($replace))
  277. {
  278. $backtrace = debug_backtrace();
  279. if (is_object($replace))
  280. {
  281. show_error('Object of class '.get_class($replace).' could not be converted to string in '.$backtrace[0]['file'].' on line '.$backtrace[0]['line']);
  282. }
  283. else
  284. {
  285. _exception_handler(E_USER_NOTICE, 'Array to string conversion in '.$backtrace[0]['file'], $backtrace[0]['line']);
  286. }
  287. }
  288. // Searching for an array
  289. if (is_array($search))
  290. {
  291. // Replacing with an array
  292. if (is_array($replace))
  293. {
  294. $search = array_values($search);
  295. $replace = array_values($replace);
  296. if (count($search) >= count($replace))
  297. {
  298. $replace = array_pad($replace, count($search), '');
  299. }
  300. else
  301. {
  302. $replace = array_slice($replace, 0, count($search));
  303. }
  304. }
  305. else
  306. {
  307. // Replacing with a string all positions
  308. $replace = array_fill(0, count($search), $replace);
  309. }
  310. }
  311. else
  312. {
  313. //Searching for a string and replacing with a string.
  314. $search = array((string)$search);
  315. $replace = array((string)$replace);
  316. }
  317. // Prepare the search array
  318. foreach ($search as $search_key => $search_value)
  319. {
  320. $search[$search_key] = '/'.preg_quote($search_value, '/').'/i';
  321. }
  322. // Prepare the replace array (escape backreferences)
  323. foreach ($replace as $k => $v)
  324. {
  325. $replace[$k] = str_replace(array(chr(92), '$'), array(chr(92).chr(92), '\$'), $v);
  326. }
  327. // do the replacement
  328. $result = preg_replace($search, $replace, (array)$subject);
  329. // Check if subject was initially a string and return it as a string
  330. if ( ! is_array($subject))
  331. {
  332. return current($result);
  333. }
  334. // Otherwise, just return the array
  335. return $result;
  336. }
  337. }
  338. // ------------------------------------------------------------------------
  339. /**
  340. * http_build_query()
  341. *
  342. * Generate URL-encoded query string
  343. * http://us.php.net/manual/en/function.http-build-query.php
  344. *
  345. * @access public
  346. * @param array form data
  347. * @param string numeric prefix
  348. * @param string argument separator
  349. * @return string URL-encoded string
  350. */
  351. if ( ! function_exists('http_build_query'))
  352. {
  353. function http_build_query($formdata, $numeric_prefix = NULL, $separator = NULL)
  354. {
  355. // Check the data
  356. if ( ! is_array($formdata) && ! is_object($formdata))
  357. {
  358. $backtrace = debug_backtrace();
  359. _exception_handler(E_USER_WARNING, 'http_build_query() Parameter 1 expected to be Array or Object. Incorrect value given', $backtrace[0]['file'], $backtrace[0]['line']);
  360. return FALSE;
  361. }
  362. // Cast it as array
  363. if (is_object($formdata))
  364. {
  365. $formdata = get_object_vars($formdata);
  366. }
  367. // If the array is empty, return NULL
  368. if (empty($formdata))
  369. {
  370. return NULL;
  371. }
  372. // Argument separator
  373. if ($separator === NULL)
  374. {
  375. $separator = ini_get('arg_separator.output');
  376. if (strlen($separator) == 0)
  377. {
  378. $separator = '&';
  379. }
  380. }
  381. // Start building the query
  382. $tmp = array();
  383. foreach ($formdata as $key => $val)
  384. {
  385. if ($val === NULL)
  386. {
  387. continue;
  388. }
  389. if (is_integer($key) && $numeric_prefix != NULL)
  390. {
  391. $key = $numeric_prefix.$key;
  392. }
  393. if (is_resource($val))
  394. {
  395. return NULL;
  396. }
  397. // hand it off to a recursive parser
  398. $tmp[] = _http_build_query_helper($key, $val, $separator);
  399. }
  400. return implode($separator, $tmp);
  401. }
  402. // Helper helper. Remind anyone of college?
  403. // Required to handle recursion in nested arrays.
  404. //
  405. // You could shave fractions of fractions of a second by moving where
  406. // the urlencoding takes place, but it's much less intuitive, and if
  407. // your application has 10,000 form fields, well, you have other problems ;)
  408. function _http_build_query_helper($key, $val, $separator = '&')
  409. {
  410. if (is_scalar($val))
  411. {
  412. return urlencode($key).'='.urlencode($val);
  413. }
  414. else
  415. {
  416. // arrays please
  417. if (is_object($val))
  418. {
  419. $val = get_object_vars($val);
  420. }
  421. foreach ($val as $k => $v)
  422. {
  423. $tmp[] = _http_build_query_helper($key.'['.$k.']', $v, $separator);
  424. }
  425. }
  426. return implode($separator, $tmp);
  427. }
  428. }
  429. /* End of file compatibility_helper.php */
  430. /* Location: ./system/helpers/compatibility_helper.php */