blob: 6770d9a3b011aec1e3d9bb5d91784a48d7c38b9a [file] [log] [blame]
Derek Allard2067d1a2008-11-13 22:59:24 +00001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * CodeIgniter
4 *
Greg Aker741de1c2010-11-10 14:52:57 -06005 * An open source application development framework for PHP 5.1.6 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
7 * @package CodeIgniter
8 * @author ExpressionEngine Dev Team
Derek Jones7f3719f2010-01-05 13:35:37 +00009 * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc.
Derek Allard2067d1a2008-11-13 22:59:24 +000010 * @license http://codeigniter.com/user_guide/license.html
11 * @link http://codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * CodeIgniter Compatibility Helpers
20 *
21 * This helper contains some functions based on the PEAR PHP_Compat library
22 * http://pear.php.net/package/PHP_Compat
Barry Mienydd671972010-10-04 16:33:58 +020023 *
Derek Allard2067d1a2008-11-13 22:59:24 +000024 * The PEAR compat library is a little bloated and the code doesn't harmonize
25 * well with CodeIgniter, so those functions have been refactored.
26 * We cheat a little and use CI's _exception_handler() to output our own PHP errors
27 * so that the behavior fully mimicks the PHP 5 counterparts. -- Derek Jones
Derek Jonesfc5c7e52010-03-11 10:29:13 -060028 * @PHP4
Barry Mienydd671972010-10-04 16:33:58 +020029 *
Derek Allard2067d1a2008-11-13 22:59:24 +000030 * @package CodeIgniter
31 * @subpackage Helpers
32 * @category Helpers
33 * @author ExpressionEngine Dev Team
34 * @link http://codeigniter.com/user_guide/helpers/compatibility_helper.html
35 */
36
37// ------------------------------------------------------------------------
38
39if ( ! defined('PHP_EOL'))
40{
41 define('PHP_EOL', (DIRECTORY_SEPARATOR == '/') ? "\n" : "\r\n");
Barry Mienydd671972010-10-04 16:33:58 +020042}
Derek Allard2067d1a2008-11-13 22:59:24 +000043
44// ------------------------------------------------------------------------
45
46/**
47 * file_put_contents()
48 *
49 * Writes a string to a file
50 * http://us.php.net/manual/en/function.file_put_contents.php
51 * argument 4, $context, not supported
52 *
53 * @access public
54 * @param string file name
55 * @param mixed data to be written
56 * @param int flags
57 * @return int length of written string
58 */
59if ( ! function_exists('file_put_contents'))
60{
61 function file_put_contents($filename, $data, $flags = NULL)
62 {
63 if (is_scalar($data))
64 {
65 settype($data, 'STRING');
66 }
67
68 if ( ! is_string($data) && ! is_array($data) && ! is_resource($data))
69 {
70 $backtrace = debug_backtrace();
71 _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']);
72 return FALSE;
73 }
74
75 // read stream if given a stream resource
76 if (is_resource($data))
77 {
78 if (get_resource_type($data) !== 'stream')
79 {
80 $backtrace = debug_backtrace();
81 _exception_handler(E_USER_WARNING, 'file_put_contents(): supplied resource is not a valid stream resource', $backtrace[0]['file'], $backtrace[0]['line']);
82 return FALSE;
83 }
84
85 $text = '';
Barry Mienydd671972010-10-04 16:33:58 +020086
Derek Allard2067d1a2008-11-13 22:59:24 +000087 while ( ! feof($data))
88 {
89 $text .= fread($data, 4096);
90 }
Barry Mienydd671972010-10-04 16:33:58 +020091
Derek Allard2067d1a2008-11-13 22:59:24 +000092 $data = $text;
93 unset($text);
94 }
Barry Mienydd671972010-10-04 16:33:58 +020095
Derek Allard2067d1a2008-11-13 22:59:24 +000096 // strings only please!
97 if (is_array($data))
98 {
99 $data = implode('', $data);
100 }
101
102 // Set the appropriate mode
103 if (($flags & 8) > 0) // 8 = FILE_APPEND flag
104 {
105 $mode = FOPEN_WRITE_CREATE;
106 }
107 else
108 {
109 $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE;
110 }
Barry Mienydd671972010-10-04 16:33:58 +0200111
Derek Allard2067d1a2008-11-13 22:59:24 +0000112 // Check if we're using the include path
113 if (($flags & 1) > 0) // 1 = FILE_USE_INCLUDE_PATH flag
114 {
115 $use_include_path = TRUE;
116 }
117 else
118 {
119 $use_include_path = FALSE;
120 }
Barry Mienydd671972010-10-04 16:33:58 +0200121
Derek Allard2067d1a2008-11-13 22:59:24 +0000122 $fp = @fopen($filename, $mode, $use_include_path);
Barry Mienydd671972010-10-04 16:33:58 +0200123
Derek Allard2067d1a2008-11-13 22:59:24 +0000124 if ($fp === FALSE)
125 {
126 $backtrace = debug_backtrace();
127 _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to open stream', $backtrace[0]['file'], $backtrace[0]['line']);
128 return FALSE;
129 }
Barry Mienydd671972010-10-04 16:33:58 +0200130
Derek Allard2067d1a2008-11-13 22:59:24 +0000131 if (($flags & LOCK_EX) > 0)
132 {
133 if ( ! flock($fp, LOCK_EX))
134 {
135 $backtrace = debug_backtrace();
136 _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') unable to acquire an exclusive lock on file', $backtrace[0]['file'], $backtrace[0]['line']);
137 return FALSE;
138 }
139 }
Barry Mienydd671972010-10-04 16:33:58 +0200140
Derek Allard2067d1a2008-11-13 22:59:24 +0000141 // write it
142 if (($written = @fwrite($fp, $data)) === FALSE)
143 {
144 $backtrace = debug_backtrace();
145 _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to write to '.htmlentities($filename), $backtrace[0]['file'], $backtrace[0]['line']);
146 }
Barry Mienydd671972010-10-04 16:33:58 +0200147
Derek Allard2067d1a2008-11-13 22:59:24 +0000148 // Close the handle
149 @fclose($fp);
Barry Mienydd671972010-10-04 16:33:58 +0200150
Derek Allard2067d1a2008-11-13 22:59:24 +0000151 // Return length
152 return $written;
153 }
154}
155
156// ------------------------------------------------------------------------
157
158/**
159 * fputcsv()
160 *
161 * Format line as CSV and write to file pointer
162 * http://us.php.net/manual/en/function.fputcsv.php
163 *
164 * @access public
165 * @param resource file pointer
166 * @param array data to be written
167 * @param string delimiter
168 * @param string enclosure
169 * @return int length of written string
170 */
171if ( ! function_exists('fputcsv'))
172{
173 function fputcsv($handle, $fields, $delimiter = ',', $enclosure = '"')
174 {
175 // Checking for a handle resource
176 if ( ! is_resource($handle))
177 {
178 $backtrace = debug_backtrace();
179 _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.gettype($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
180 return FALSE;
181 }
Barry Mienydd671972010-10-04 16:33:58 +0200182
Derek Allard2067d1a2008-11-13 22:59:24 +0000183 // OK, it is a resource, but is it a stream?
184 if (get_resource_type($handle) !== 'stream')
185 {
186 $backtrace = debug_backtrace();
187 _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.get_resource_type($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
188 return FALSE;
189 }
Barry Mienydd671972010-10-04 16:33:58 +0200190
Derek Allard2067d1a2008-11-13 22:59:24 +0000191 // Checking for an array of fields
192 if ( ! is_array($fields))
193 {
194 $backtrace = debug_backtrace();
195 _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 2 to be array, '.gettype($fields).' given', $backtrace[0]['file'], $backtrace[0]['line']);
196 return FALSE;
197 }
Barry Mienydd671972010-10-04 16:33:58 +0200198
Derek Allard2067d1a2008-11-13 22:59:24 +0000199 // validate delimiter
200 if (strlen($delimiter) > 1)
201 {
202 $delimiter = substr($delimiter, 0, 1);
203 $backtrace = debug_backtrace();
204 _exception_handler(E_NOTICE, 'fputcsv() delimiter must be one character long, "'.htmlentities($delimiter).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
205 }
Barry Mienydd671972010-10-04 16:33:58 +0200206
Derek Allard2067d1a2008-11-13 22:59:24 +0000207 // validate enclosure
208 if (strlen($enclosure) > 1)
209 {
210 $enclosure = substr($enclosure, 0, 1);
211 $backtrace = debug_backtrace();
212 _exception_handler(E_NOTICE, 'fputcsv() enclosure must be one character long, "'.htmlentities($enclosure).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
213
214 }
Barry Mienydd671972010-10-04 16:33:58 +0200215
Derek Allard2067d1a2008-11-13 22:59:24 +0000216 $out = '';
Barry Mienydd671972010-10-04 16:33:58 +0200217
Derek Allard2067d1a2008-11-13 22:59:24 +0000218 foreach ($fields as $cell)
219 {
220 $cell = str_replace($enclosure, $enclosure.$enclosure, $cell);
221
222 if (strpos($cell, $delimiter) !== FALSE OR strpos($cell, $enclosure) !== FALSE OR strpos($cell, "\n") !== FALSE)
223 {
224 $out .= $enclosure.$cell.$enclosure.$delimiter;
225 }
226 else
227 {
228 $out .= $cell.$delimiter;
229 }
230 }
Barry Mienydd671972010-10-04 16:33:58 +0200231
Derek Allard2067d1a2008-11-13 22:59:24 +0000232 $length = @fwrite($handle, substr($out, 0, -1)."\n");
Barry Mienydd671972010-10-04 16:33:58 +0200233
Derek Allard2067d1a2008-11-13 22:59:24 +0000234 return $length;
235 }
236}
237
238// ------------------------------------------------------------------------
239
240/**
241 * stripos()
242 *
243 * Find position of first occurrence of a case-insensitive string
244 * http://us.php.net/manual/en/function.stripos.php
245 *
246 * @access public
247 * @param string haystack
248 * @param string needle
249 * @param int offset
250 * @return int numeric position of the first occurrence of needle in the haystack
251 */
252if ( ! function_exists('stripos'))
253{
254 function stripos($haystack, $needle, $offset = NULL)
255 {
256 // Cast non string scalar values
257 if (is_scalar($haystack))
258 {
259 settype($haystack, 'STRING');
260 }
Barry Mienydd671972010-10-04 16:33:58 +0200261
Derek Allard2067d1a2008-11-13 22:59:24 +0000262 if ( ! is_string($haystack))
263 {
264 $backtrace = debug_backtrace();
265 _exception_handler(E_USER_WARNING, 'stripos() expects parameter 1 to be string, '.gettype($haystack).' given', $backtrace[0]['file'], $backtrace[0]['line']);
266 return FALSE;
267 }
Barry Mienydd671972010-10-04 16:33:58 +0200268
Derek Allard2067d1a2008-11-13 22:59:24 +0000269 if ( ! is_scalar($needle))
270 {
271 $backtrace = debug_backtrace();
272 _exception_handler(E_USER_WARNING, 'stripos() needle is not a string or an integer in '.$backtrace[0]['file'], $backtrace[0]['line']);
273 return FALSE;
274 }
Barry Mienydd671972010-10-04 16:33:58 +0200275
Derek Allard2067d1a2008-11-13 22:59:24 +0000276 if (is_float($offset))
277 {
278 $offset = (int)$offset;
279 }
Barry Mienydd671972010-10-04 16:33:58 +0200280
Derek Allard2067d1a2008-11-13 22:59:24 +0000281 if ( ! is_int($offset) && ! is_bool($offset) && ! is_null($offset))
282 {
283 $backtrace = debug_backtrace();
284 _exception_handler(E_USER_WARNING, 'stripos() expects parameter 3 to be long, '.gettype($offset).' given', $backtrace[0]['file'], $backtrace[0]['line']);
285 return NULL;
286 }
Barry Mienydd671972010-10-04 16:33:58 +0200287
Derek Allard2067d1a2008-11-13 22:59:24 +0000288 return strpos(strtolower($haystack), strtolower($needle), $offset);
289 }
290}
291
292// ------------------------------------------------------------------------
293
294/**
295 * str_ireplace()
296 *
297 * Find position of first occurrence of a case-insensitive string
298 * http://us.php.net/manual/en/function.str-ireplace.php
299 * (parameter 4, $count, is not supported as to do so in PHP 4 would make
300 * it a required parameter)
301 *
302 * @access public
303 * @param mixed search
304 * @param mixed replace
305 * @param mixed subject
306 * @return int numeric position of the first occurrence of needle in the haystack
307 */
308if ( ! function_exists('str_ireplace'))
309{
310 function str_ireplace($search, $replace, $subject)
311 {
312 // Nothing to do here
313 if ($search === NULL OR $subject === NULL)
314 {
315 return $subject;
316 }
Barry Mienydd671972010-10-04 16:33:58 +0200317
Derek Allard2067d1a2008-11-13 22:59:24 +0000318 // Crazy arguments
319 if (is_scalar($search) && is_array($replace))
320 {
321 $backtrace = debug_backtrace();
322
323 if (is_object($replace))
324 {
325 show_error('Object of class '.get_class($replace).' could not be converted to string in '.$backtrace[0]['file'].' on line '.$backtrace[0]['line']);
326 }
327 else
328 {
329 _exception_handler(E_USER_NOTICE, 'Array to string conversion in '.$backtrace[0]['file'], $backtrace[0]['line']);
330 }
331 }
Barry Mienydd671972010-10-04 16:33:58 +0200332
Derek Allard2067d1a2008-11-13 22:59:24 +0000333 // Searching for an array
334 if (is_array($search))
335 {
336 // Replacing with an array
337 if (is_array($replace))
338 {
339 $search = array_values($search);
340 $replace = array_values($replace);
341
342 if (count($search) >= count($replace))
343 {
344 $replace = array_pad($replace, count($search), '');
345 }
346 else
347 {
348 $replace = array_slice($replace, 0, count($search));
349 }
350 }
351 else
352 {
353 // Replacing with a string all positions
354 $replace = array_fill(0, count($search), $replace);
355 }
356 }
357 else
358 {
359 //Searching for a string and replacing with a string.
360 $search = array((string)$search);
361 $replace = array((string)$replace);
362 }
Barry Mienydd671972010-10-04 16:33:58 +0200363
Derek Allard2067d1a2008-11-13 22:59:24 +0000364 // Prepare the search array
365 foreach ($search as $search_key => $search_value)
366 {
367 $search[$search_key] = '/'.preg_quote($search_value, '/').'/i';
368 }
Barry Mienydd671972010-10-04 16:33:58 +0200369
Derek Allard2067d1a2008-11-13 22:59:24 +0000370 // Prepare the replace array (escape backreferences)
371 foreach ($replace as $k => $v)
372 {
373 $replace[$k] = str_replace(array(chr(92), '$'), array(chr(92).chr(92), '\$'), $v);
374 }
Barry Mienydd671972010-10-04 16:33:58 +0200375
Derek Allard2067d1a2008-11-13 22:59:24 +0000376 // do the replacement
377 $result = preg_replace($search, $replace, (array)$subject);
Barry Mienydd671972010-10-04 16:33:58 +0200378
Derek Allard2067d1a2008-11-13 22:59:24 +0000379 // Check if subject was initially a string and return it as a string
380 if ( ! is_array($subject))
381 {
382 return current($result);
383 }
Barry Mienydd671972010-10-04 16:33:58 +0200384
Derek Allard2067d1a2008-11-13 22:59:24 +0000385 // Otherwise, just return the array
386 return $result;
387 }
388}
389
390// ------------------------------------------------------------------------
391
392/**
393 * http_build_query()
394 *
395 * Generate URL-encoded query string
396 * http://us.php.net/manual/en/function.http-build-query.php
397 *
398 * @access public
399 * @param array form data
400 * @param string numeric prefix
401 * @param string argument separator
402 * @return string URL-encoded string
403 */
404if ( ! function_exists('http_build_query'))
405{
406 function http_build_query($formdata, $numeric_prefix = NULL, $separator = NULL)
407 {
408 // Check the data
409 if ( ! is_array($formdata) && ! is_object($formdata))
410 {
411 $backtrace = debug_backtrace();
412 _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']);
413 return FALSE;
414 }
Barry Mienydd671972010-10-04 16:33:58 +0200415
Derek Allard2067d1a2008-11-13 22:59:24 +0000416 // Cast it as array
417 if (is_object($formdata))
418 {
419 $formdata = get_object_vars($formdata);
420 }
Barry Mienydd671972010-10-04 16:33:58 +0200421
Derek Allard2067d1a2008-11-13 22:59:24 +0000422 // If the array is empty, return NULL
423 if (empty($formdata))
424 {
425 return NULL;
426 }
Barry Mienydd671972010-10-04 16:33:58 +0200427
Derek Allard2067d1a2008-11-13 22:59:24 +0000428 // Argument separator
429 if ($separator === NULL)
430 {
431 $separator = ini_get('arg_separator.output');
432
433 if (strlen($separator) == 0)
434 {
435 $separator = '&';
436 }
437 }
Barry Mienydd671972010-10-04 16:33:58 +0200438
Derek Allard2067d1a2008-11-13 22:59:24 +0000439 // Start building the query
440 $tmp = array();
441
442 foreach ($formdata as $key => $val)
443 {
444 if ($val === NULL)
445 {
446 continue;
447 }
Barry Mienydd671972010-10-04 16:33:58 +0200448
Derek Allard2067d1a2008-11-13 22:59:24 +0000449 if (is_integer($key) && $numeric_prefix != NULL)
450 {
451 $key = $numeric_prefix.$key;
452 }
Barry Mienydd671972010-10-04 16:33:58 +0200453
Derek Allard2067d1a2008-11-13 22:59:24 +0000454 if (is_resource($val))
455 {
456 return NULL;
457 }
Barry Mienydd671972010-10-04 16:33:58 +0200458
Derek Allard2067d1a2008-11-13 22:59:24 +0000459 // hand it off to a recursive parser
460 $tmp[] = _http_build_query_helper($key, $val, $separator);
461 }
Barry Mienydd671972010-10-04 16:33:58 +0200462
Derek Allard2067d1a2008-11-13 22:59:24 +0000463 return implode($separator, $tmp);
464 }
Barry Mienydd671972010-10-04 16:33:58 +0200465
466
Derek Allard2067d1a2008-11-13 22:59:24 +0000467 // Helper helper. Remind anyone of college?
468 // Required to handle recursion in nested arrays.
Barry Mienydd671972010-10-04 16:33:58 +0200469 //
Derek Allard2067d1a2008-11-13 22:59:24 +0000470 // You could shave fractions of fractions of a second by moving where
471 // the urlencoding takes place, but it's much less intuitive, and if
472 // your application has 10,000 form fields, well, you have other problems ;)
473 function _http_build_query_helper($key, $val, $separator = '&')
Barry Mienydd671972010-10-04 16:33:58 +0200474 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000475 if (is_scalar($val))
476 {
Barry Mienydd671972010-10-04 16:33:58 +0200477 return urlencode($key).'='.urlencode($val);
Derek Allard2067d1a2008-11-13 22:59:24 +0000478 }
479 else
480 {
481 // arrays please
482 if (is_object($val))
483 {
484 $val = get_object_vars($val);
485 }
Barry Mienydd671972010-10-04 16:33:58 +0200486
Derek Allard2067d1a2008-11-13 22:59:24 +0000487 foreach ($val as $k => $v)
488 {
489 $tmp[] = _http_build_query_helper($key.'['.$k.']', $v, $separator);
490 }
491 }
Barry Mienydd671972010-10-04 16:33:58 +0200492
Derek Allard2067d1a2008-11-13 22:59:24 +0000493 return implode($separator, $tmp);
494 }
495}
496
497
498/* End of file compatibility_helper.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +0000499/* Location: ./system/helpers/compatibility_helper.php */