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