CI3 => CI4
This commit is contained in:
@@ -1,116 +1,220 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Array Helpers
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/array_helper.html
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// CodeIgniter Array Helpers
|
||||
|
||||
if ( ! function_exists('element'))
|
||||
{
|
||||
/**
|
||||
* Element
|
||||
*
|
||||
* Lets you determine whether an array index is set and whether it has a value.
|
||||
* If the element is empty it returns NULL (or whatever you specify as the default value.)
|
||||
*
|
||||
* @param string
|
||||
* @param array
|
||||
* @param mixed
|
||||
* @return mixed depends on what the array contains
|
||||
*/
|
||||
function element($item, array $array, $default = NULL)
|
||||
{
|
||||
return array_key_exists($item, $array) ? $array[$item] : $default;
|
||||
}
|
||||
if (! function_exists('dot_array_search')) {
|
||||
/**
|
||||
* Searches an array through dot syntax. Supports
|
||||
* wildcard searches, like foo.*.bar
|
||||
*
|
||||
* @return array|bool|int|object|string|null
|
||||
*/
|
||||
function dot_array_search(string $index, array $array)
|
||||
{
|
||||
// See https://regex101.com/r/44Ipql/1
|
||||
$segments = preg_split(
|
||||
'/(?<!\\\\)\./',
|
||||
rtrim($index, '* '),
|
||||
0,
|
||||
PREG_SPLIT_NO_EMPTY
|
||||
);
|
||||
|
||||
$segments = array_map(static fn ($key) => str_replace('\.', '.', $key), $segments);
|
||||
|
||||
return _array_search_dot($segments, $array);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
if (! function_exists('_array_search_dot')) {
|
||||
/**
|
||||
* Used by `dot_array_search` to recursively search the
|
||||
* array with wildcards.
|
||||
*
|
||||
* @internal This should not be used on its own.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function _array_search_dot(array $indexes, array $array)
|
||||
{
|
||||
// If index is empty, returns null.
|
||||
if ($indexes === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( ! function_exists('random_element'))
|
||||
{
|
||||
/**
|
||||
* Random Element - Takes an array as input and returns a random element
|
||||
*
|
||||
* @param array
|
||||
* @return mixed depends on what the array contains
|
||||
*/
|
||||
function random_element($array)
|
||||
{
|
||||
return is_array($array) ? $array[array_rand($array)] : $array;
|
||||
}
|
||||
// Grab the current index
|
||||
$currentIndex = array_shift($indexes);
|
||||
|
||||
if (! isset($array[$currentIndex]) && $currentIndex !== '*') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Handle Wildcard (*)
|
||||
if ($currentIndex === '*') {
|
||||
$answer = [];
|
||||
|
||||
foreach ($array as $value) {
|
||||
if (! is_array($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$answer[] = _array_search_dot($indexes, $value);
|
||||
}
|
||||
|
||||
$answer = array_filter($answer, static fn ($value) => $value !== null);
|
||||
|
||||
if ($answer !== []) {
|
||||
if (count($answer) === 1) {
|
||||
// If array only has one element, we return that element for BC.
|
||||
return current($answer);
|
||||
}
|
||||
|
||||
return $answer;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// If this is the last index, make sure to return it now,
|
||||
// and not try to recurse through things.
|
||||
if (empty($indexes)) {
|
||||
return $array[$currentIndex];
|
||||
}
|
||||
|
||||
// Do we need to recursively search this value?
|
||||
if (is_array($array[$currentIndex]) && $array[$currentIndex] !== []) {
|
||||
return _array_search_dot($indexes, $array[$currentIndex]);
|
||||
}
|
||||
|
||||
// Otherwise, not found.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
if (! function_exists('array_deep_search')) {
|
||||
/**
|
||||
* Returns the value of an element at a key in an array of uncertain depth.
|
||||
*
|
||||
* @param mixed $key
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
function array_deep_search($key, array $array)
|
||||
{
|
||||
if (isset($array[$key])) {
|
||||
return $array[$key];
|
||||
}
|
||||
|
||||
if ( ! function_exists('elements'))
|
||||
{
|
||||
/**
|
||||
* Elements
|
||||
*
|
||||
* Returns only the array items specified. Will return a default value if
|
||||
* it is not set.
|
||||
*
|
||||
* @param array
|
||||
* @param array
|
||||
* @param mixed
|
||||
* @return mixed depends on what the array contains
|
||||
*/
|
||||
function elements($items, array $array, $default = NULL)
|
||||
{
|
||||
$return = array();
|
||||
foreach ($array as $value) {
|
||||
if (is_array($value) && ($result = array_deep_search($key, $value))) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
is_array($items) OR $items = array($items);
|
||||
|
||||
foreach ($items as $item)
|
||||
{
|
||||
$return[$item] = array_key_exists($item, $array) ? $array[$item] : $default;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('array_sort_by_multiple_keys')) {
|
||||
/**
|
||||
* Sorts a multidimensional array by its elements values. The array
|
||||
* columns to be used for sorting are passed as an associative
|
||||
* array of key names and sorting flags.
|
||||
*
|
||||
* Both arrays of objects and arrays of array can be sorted.
|
||||
*
|
||||
* Example:
|
||||
* array_sort_by_multiple_keys($players, [
|
||||
* 'team.hierarchy' => SORT_ASC,
|
||||
* 'position' => SORT_ASC,
|
||||
* 'name' => SORT_STRING,
|
||||
* ]);
|
||||
*
|
||||
* The '.' dot operator in the column name indicates a deeper array or
|
||||
* object level. In principle, any number of sublevels could be used,
|
||||
* as long as the level and column exist in every array element.
|
||||
*
|
||||
* For information on multi-level array sorting, refer to Example #3 here:
|
||||
* https://www.php.net/manual/de/function.array-multisort.php
|
||||
*
|
||||
* @param array $array the reference of the array to be sorted
|
||||
* @param array $sortColumns an associative array of columns to sort
|
||||
* after and their sorting flags
|
||||
*/
|
||||
function array_sort_by_multiple_keys(array &$array, array $sortColumns): bool
|
||||
{
|
||||
// Check if there really are columns to sort after
|
||||
if (empty($sortColumns) || empty($array)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Group sorting indexes and data
|
||||
$tempArray = [];
|
||||
|
||||
foreach ($sortColumns as $key => $sortFlag) {
|
||||
// Get sorting values
|
||||
$carry = $array;
|
||||
|
||||
// The '.' operator separates nested elements
|
||||
foreach (explode('.', $key) as $keySegment) {
|
||||
// Loop elements if they are objects
|
||||
if (is_object(reset($carry))) {
|
||||
// Extract the object attribute
|
||||
foreach ($carry as $index => $object) {
|
||||
$carry[$index] = $object->{$keySegment};
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Extract the target column if elements are arrays
|
||||
$carry = array_column($carry, $keySegment);
|
||||
}
|
||||
|
||||
// Store the collected sorting parameters
|
||||
$tempArray[] = $carry;
|
||||
$tempArray[] = $sortFlag;
|
||||
}
|
||||
|
||||
// Append the array as reference
|
||||
$tempArray[] = &$array;
|
||||
|
||||
// Pass sorting arrays and flags as an argument list.
|
||||
return array_multisort(...$tempArray);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('array_flatten_with_dots')) {
|
||||
/**
|
||||
* Flatten a multidimensional array using dots as separators.
|
||||
*
|
||||
* @param iterable $array The multi-dimensional array
|
||||
* @param string $id Something to initially prepend to the flattened keys
|
||||
*
|
||||
* @return array The flattened array
|
||||
*/
|
||||
function array_flatten_with_dots(iterable $array, string $id = ''): array
|
||||
{
|
||||
$flattened = [];
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
$newKey = $id . $key;
|
||||
|
||||
if (is_array($value) && $value !== []) {
|
||||
$flattened = array_merge($flattened, array_flatten_with_dots($value, $newKey . '.'));
|
||||
} else {
|
||||
$flattened[$newKey] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $flattened;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,353 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter CAPTCHA Helper
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/captcha_helper.html
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('create_captcha'))
|
||||
{
|
||||
/**
|
||||
* Create CAPTCHA
|
||||
*
|
||||
* @param array $data Data for the CAPTCHA
|
||||
* @param string $img_path Path to create the image in (deprecated)
|
||||
* @param string $img_url URL to the CAPTCHA image folder (deprecated)
|
||||
* @param string $font_path Server path to font (deprecated)
|
||||
* @return string
|
||||
*/
|
||||
function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '')
|
||||
{
|
||||
$defaults = array(
|
||||
'word' => '',
|
||||
'img_path' => '',
|
||||
'img_url' => '',
|
||||
'img_width' => '150',
|
||||
'img_height' => '30',
|
||||
'font_path' => '',
|
||||
'expiration' => 7200,
|
||||
'word_length' => 8,
|
||||
'font_size' => 16,
|
||||
'img_id' => '',
|
||||
'pool' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'colors' => array(
|
||||
'background' => array(255,255,255),
|
||||
'border' => array(153,102,102),
|
||||
'text' => array(204,153,153),
|
||||
'grid' => array(255,182,182)
|
||||
)
|
||||
);
|
||||
|
||||
foreach ($defaults as $key => $val)
|
||||
{
|
||||
if ( ! is_array($data) && empty($$key))
|
||||
{
|
||||
$$key = $val;
|
||||
}
|
||||
else
|
||||
{
|
||||
$$key = isset($data[$key]) ? $data[$key] : $val;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! extension_loaded('gd'))
|
||||
{
|
||||
log_message('error', 'create_captcha(): GD extension is not loaded.');
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ($img_path === '' OR $img_url === '')
|
||||
{
|
||||
log_message('error', 'create_captcha(): $img_path and $img_url are required.');
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! is_dir($img_path) OR ! is_really_writable($img_path))
|
||||
{
|
||||
log_message('error', "create_captcha(): '{$img_path}' is not a dir, nor is it writable.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
// Remove old images
|
||||
// -----------------------------------
|
||||
|
||||
$now = microtime(TRUE);
|
||||
|
||||
$current_dir = @opendir($img_path);
|
||||
while ($filename = @readdir($current_dir))
|
||||
{
|
||||
if (in_array(substr($filename, -4), array('.jpg', '.png'))
|
||||
&& (str_replace(array('.jpg', '.png'), '', $filename) + $expiration) < $now)
|
||||
{
|
||||
@unlink($img_path.$filename);
|
||||
}
|
||||
}
|
||||
|
||||
@closedir($current_dir);
|
||||
|
||||
// -----------------------------------
|
||||
// Do we have a "word" yet?
|
||||
// -----------------------------------
|
||||
|
||||
if (empty($word))
|
||||
{
|
||||
$word = '';
|
||||
$pool_length = strlen($pool);
|
||||
$rand_max = $pool_length - 1;
|
||||
|
||||
// PHP7 or a suitable polyfill
|
||||
if (function_exists('random_int'))
|
||||
{
|
||||
try
|
||||
{
|
||||
for ($i = 0; $i < $word_length; $i++)
|
||||
{
|
||||
$word .= $pool[random_int(0, $rand_max)];
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
// This means fallback to the next possible
|
||||
// alternative to random_int()
|
||||
$word = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($word))
|
||||
{
|
||||
// Nobody will have a larger character pool than
|
||||
// 256 characters, but let's handle it just in case ...
|
||||
//
|
||||
// No, I do not care that the fallback to mt_rand() can
|
||||
// handle it; if you trigger this, you're very obviously
|
||||
// trying to break it. -- Narf
|
||||
if ($pool_length > 256)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// We'll try using the operating system's PRNG first,
|
||||
// which we can access through CI_Security::get_random_bytes()
|
||||
$security = get_instance()->security;
|
||||
|
||||
// To avoid numerous get_random_bytes() calls, we'll
|
||||
// just try fetching as much bytes as we need at once.
|
||||
if (($bytes = $security->get_random_bytes($pool_length)) !== FALSE)
|
||||
{
|
||||
$byte_index = $word_index = 0;
|
||||
while ($word_index < $word_length)
|
||||
{
|
||||
// Do we have more random data to use?
|
||||
// It could be exhausted by previous iterations
|
||||
// ignoring bytes higher than $rand_max.
|
||||
if ($byte_index === $pool_length)
|
||||
{
|
||||
// No failures should be possible if the
|
||||
// first get_random_bytes() call didn't
|
||||
// return FALSE, but still ...
|
||||
for ($i = 0; $i < 5; $i++)
|
||||
{
|
||||
if (($bytes = $security->get_random_bytes($pool_length)) === FALSE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$byte_index = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($bytes === FALSE)
|
||||
{
|
||||
// Sadly, this means fallback to mt_rand()
|
||||
$word = '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list(, $rand_index) = unpack('C', $bytes[$byte_index++]);
|
||||
if ($rand_index > $rand_max)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$word .= $pool[$rand_index];
|
||||
$word_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($word))
|
||||
{
|
||||
for ($i = 0; $i < $word_length; $i++)
|
||||
{
|
||||
$word .= $pool[mt_rand(0, $rand_max)];
|
||||
}
|
||||
}
|
||||
elseif ( ! is_string($word))
|
||||
{
|
||||
$word = (string) $word;
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
// Determine angle and position
|
||||
// -----------------------------------
|
||||
$length = strlen($word);
|
||||
$angle = ($length >= 6) ? mt_rand(-($length-6), ($length-6)) : 0;
|
||||
$x_axis = mt_rand(6, (360/$length)-16);
|
||||
$y_axis = ($angle >= 0) ? mt_rand($img_height, $img_width) : mt_rand(6, $img_height);
|
||||
|
||||
// Create image
|
||||
// PHP.net recommends imagecreatetruecolor(), but it isn't always available
|
||||
$im = function_exists('imagecreatetruecolor')
|
||||
? imagecreatetruecolor($img_width, $img_height)
|
||||
: imagecreate($img_width, $img_height);
|
||||
|
||||
// -----------------------------------
|
||||
// Assign colors
|
||||
// ----------------------------------
|
||||
|
||||
is_array($colors) OR $colors = $defaults['colors'];
|
||||
|
||||
foreach (array_keys($defaults['colors']) as $key)
|
||||
{
|
||||
// Check for a possible missing value
|
||||
is_array($colors[$key]) OR $colors[$key] = $defaults['colors'][$key];
|
||||
$colors[$key] = imagecolorallocate($im, $colors[$key][0], $colors[$key][1], $colors[$key][2]);
|
||||
}
|
||||
|
||||
// Create the rectangle
|
||||
ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $colors['background']);
|
||||
|
||||
// -----------------------------------
|
||||
// Create the spiral pattern
|
||||
// -----------------------------------
|
||||
$theta = 1;
|
||||
$thetac = 7;
|
||||
$radius = 16;
|
||||
$circles = 20;
|
||||
$points = 32;
|
||||
|
||||
for ($i = 0, $cp = ($circles * $points) - 1; $i < $cp; $i++)
|
||||
{
|
||||
$theta += $thetac;
|
||||
$rad = $radius * ($i / $points);
|
||||
$x = ($rad * cos($theta)) + $x_axis;
|
||||
$y = ($rad * sin($theta)) + $y_axis;
|
||||
$theta += $thetac;
|
||||
$rad1 = $radius * (($i + 1) / $points);
|
||||
$x1 = ($rad1 * cos($theta)) + $x_axis;
|
||||
$y1 = ($rad1 * sin($theta)) + $y_axis;
|
||||
imageline($im, $x, $y, $x1, $y1, $colors['grid']);
|
||||
$theta -= $thetac;
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
// Write the text
|
||||
// -----------------------------------
|
||||
|
||||
$use_font = ($font_path !== '' && file_exists($font_path) && function_exists('imagettftext'));
|
||||
if ($use_font === FALSE)
|
||||
{
|
||||
($font_size > 5) && $font_size = 5;
|
||||
$x = mt_rand(0, $img_width / ($length / 3));
|
||||
$y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
($font_size > 30) && $font_size = 30;
|
||||
$x = mt_rand(0, $img_width / ($length / 1.5));
|
||||
$y = $font_size + 2;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $length; $i++)
|
||||
{
|
||||
if ($use_font === FALSE)
|
||||
{
|
||||
$y = mt_rand(0 , $img_height / 2);
|
||||
imagestring($im, $font_size, $x, $y, $word[$i], $colors['text']);
|
||||
$x += ($font_size * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
$y = mt_rand($img_height / 2, $img_height - 3);
|
||||
imagettftext($im, $font_size, $angle, $x, $y, $colors['text'], $font_path, $word[$i]);
|
||||
$x += $font_size;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the border
|
||||
imagerectangle($im, 0, 0, $img_width - 1, $img_height - 1, $colors['border']);
|
||||
|
||||
// -----------------------------------
|
||||
// Generate the image
|
||||
// -----------------------------------
|
||||
$img_url = rtrim($img_url, '/').'/';
|
||||
|
||||
if (function_exists('imagejpeg'))
|
||||
{
|
||||
$img_filename = $now.'.jpg';
|
||||
imagejpeg($im, $img_path.$img_filename);
|
||||
}
|
||||
elseif (function_exists('imagepng'))
|
||||
{
|
||||
$img_filename = $now.'.png';
|
||||
imagepng($im, $img_path.$img_filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$img = '<img '.($img_id === '' ? '' : 'id="'.$img_id.'"').' src="'.$img_url.$img_filename.'" style="width: '.$img_width.'px; height: '.$img_height .'px; border: 0;" alt=" " />';
|
||||
ImageDestroy($im);
|
||||
|
||||
return array('word' => $word, 'time' => $now, 'image' => $img, 'filename' => $img_filename);
|
||||
}
|
||||
}
|
||||
Regular → Executable
+97
-101
@@ -1,114 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Cookie Helpers
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/cookie_helper.html
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
use Config\App;
|
||||
use Config\Cookie;
|
||||
use Config\Services;
|
||||
|
||||
if ( ! function_exists('set_cookie'))
|
||||
{
|
||||
/**
|
||||
* Set cookie
|
||||
*
|
||||
* Accepts seven parameters, or you can submit an associative
|
||||
* array in the first parameter containing all the values.
|
||||
*
|
||||
* @param mixed
|
||||
* @param string the value of the cookie
|
||||
* @param string the number of seconds until expiration
|
||||
* @param string the cookie domain. Usually: .yourdomain.com
|
||||
* @param string the cookie path
|
||||
* @param string the cookie prefix
|
||||
* @param bool true makes the cookie secure
|
||||
* @param bool true makes the cookie accessible via http(s) only (no javascript)
|
||||
* @return void
|
||||
*/
|
||||
function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL)
|
||||
{
|
||||
// Set the config file options
|
||||
get_instance()->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly);
|
||||
}
|
||||
// =============================================================================
|
||||
// CodeIgniter Cookie Helpers
|
||||
// =============================================================================
|
||||
|
||||
if (! function_exists('set_cookie')) {
|
||||
/**
|
||||
* Set cookie
|
||||
*
|
||||
* Accepts seven parameters, or you can submit an associative
|
||||
* array in the first parameter containing all the values.
|
||||
*
|
||||
* @param array|string $name Cookie name or array containing binds
|
||||
* @param string $value The value of the cookie
|
||||
* @param string $expire The number of seconds until expiration
|
||||
* @param string $domain For site-wide cookie. Usually: .yourdomain.com
|
||||
* @param string $path The cookie path
|
||||
* @param string $prefix The cookie prefix ('': the default prefix)
|
||||
* @param bool|null $secure True makes the cookie secure
|
||||
* @param bool|null $httpOnly True makes the cookie accessible via http(s) only (no javascript)
|
||||
* @param string|null $sameSite The cookie SameSite value
|
||||
*
|
||||
* @see \CodeIgniter\HTTP\Response::setCookie()
|
||||
*/
|
||||
function set_cookie(
|
||||
$name,
|
||||
string $value = '',
|
||||
string $expire = '',
|
||||
string $domain = '',
|
||||
string $path = '/',
|
||||
string $prefix = '',
|
||||
?bool $secure = null,
|
||||
?bool $httpOnly = null,
|
||||
?string $sameSite = null
|
||||
) {
|
||||
$response = Services::response();
|
||||
$response->setCookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httpOnly, $sameSite);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
if (! function_exists('get_cookie')) {
|
||||
/**
|
||||
* Fetch an item from the $_COOKIE array
|
||||
*
|
||||
* @param string $index
|
||||
* @param string|null $prefix Cookie name prefix.
|
||||
* '': the prefix in Config\Cookie
|
||||
* null: no prefix
|
||||
*
|
||||
* @return array|string|null
|
||||
*
|
||||
* @see \CodeIgniter\HTTP\IncomingRequest::getCookie()
|
||||
*/
|
||||
function get_cookie($index, bool $xssClean = false, ?string $prefix = '')
|
||||
{
|
||||
if ($prefix === '') {
|
||||
/** @var Cookie|null $cookie */
|
||||
$cookie = config('Cookie');
|
||||
|
||||
if ( ! function_exists('get_cookie'))
|
||||
{
|
||||
/**
|
||||
* Fetch an item from the COOKIE array
|
||||
*
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return mixed
|
||||
*/
|
||||
function get_cookie($index, $xss_clean = NULL)
|
||||
{
|
||||
is_bool($xss_clean) OR $xss_clean = (config_item('global_xss_filtering') === TRUE);
|
||||
$prefix = isset($_COOKIE[$index]) ? '' : config_item('cookie_prefix');
|
||||
return get_instance()->input->cookie($prefix.$index, $xss_clean);
|
||||
}
|
||||
// @TODO Remove Config\App fallback when deprecated `App` members are removed.
|
||||
$prefix = $cookie instanceof Cookie ? $cookie->prefix : config(App::class)->cookiePrefix;
|
||||
}
|
||||
|
||||
$request = Services::request();
|
||||
$filter = $xssClean ? FILTER_SANITIZE_FULL_SPECIAL_CHARS : FILTER_DEFAULT;
|
||||
|
||||
return $request->getCookie($prefix . $index, $filter);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('delete_cookie'))
|
||||
{
|
||||
/**
|
||||
* Delete a COOKIE
|
||||
*
|
||||
* @param mixed
|
||||
* @param string the cookie domain. Usually: .yourdomain.com
|
||||
* @param string the cookie path
|
||||
* @param string the cookie prefix
|
||||
* @return void
|
||||
*/
|
||||
function delete_cookie($name, $domain = '', $path = '/', $prefix = '')
|
||||
{
|
||||
set_cookie($name, '', '', $domain, $path, $prefix);
|
||||
}
|
||||
if (! function_exists('delete_cookie')) {
|
||||
/**
|
||||
* Delete a cookie
|
||||
*
|
||||
* @param mixed $name
|
||||
* @param string $domain the cookie domain. Usually: .yourdomain.com
|
||||
* @param string $path the cookie path
|
||||
* @param string $prefix the cookie prefix
|
||||
*
|
||||
* @see \CodeIgniter\HTTP\Response::deleteCookie()
|
||||
*/
|
||||
function delete_cookie($name, string $domain = '', string $path = '/', string $prefix = '')
|
||||
{
|
||||
Services::response()->deleteCookie($name, $domain, $path, $prefix);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('has_cookie')) {
|
||||
/**
|
||||
* Checks if a cookie exists by name.
|
||||
*/
|
||||
function has_cookie(string $name, ?string $value = null, string $prefix = ''): bool
|
||||
{
|
||||
return Services::response()->hasCookie($name, $value, $prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,743 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Date Helpers
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/date_helper.html
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// CodeIgniter Date Helpers
|
||||
|
||||
if ( ! function_exists('now'))
|
||||
{
|
||||
/**
|
||||
* Get "now" time
|
||||
*
|
||||
* Returns time() based on the timezone parameter or on the
|
||||
* "time_reference" setting
|
||||
*
|
||||
* @param string
|
||||
* @return int
|
||||
*/
|
||||
function now($timezone = NULL)
|
||||
{
|
||||
if (empty($timezone))
|
||||
{
|
||||
$timezone = config_item('time_reference');
|
||||
}
|
||||
if (! function_exists('now')) {
|
||||
/**
|
||||
* Get "now" time
|
||||
*
|
||||
* Returns time() based on the timezone parameter or on the
|
||||
* app_timezone() setting
|
||||
*
|
||||
* @param string $timezone
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
function now(?string $timezone = null): int
|
||||
{
|
||||
$timezone = empty($timezone) ? app_timezone() : $timezone;
|
||||
|
||||
if ($timezone === 'local' OR $timezone === date_default_timezone_get())
|
||||
{
|
||||
return time();
|
||||
}
|
||||
if ($timezone === 'local' || $timezone === date_default_timezone_get()) {
|
||||
return time();
|
||||
}
|
||||
|
||||
$datetime = new DateTime('now', new DateTimeZone($timezone));
|
||||
sscanf($datetime->format('j-n-Y G:i:s'), '%d-%d-%d %d:%d:%d', $day, $month, $year, $hour, $minute, $second);
|
||||
$datetime = new DateTime('now', new DateTimeZone($timezone));
|
||||
sscanf($datetime->format('j-n-Y G:i:s'), '%d-%d-%d %d:%d:%d', $day, $month, $year, $hour, $minute, $second);
|
||||
|
||||
return mktime($hour, $minute, $second, $month, $day, $year);
|
||||
}
|
||||
return mktime($hour, $minute, $second, $month, $day, $year);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
if (! function_exists('timezone_select')) {
|
||||
/**
|
||||
* Generates a select field of all available timezones
|
||||
*
|
||||
* Returns a string with the formatted HTML
|
||||
*
|
||||
* @param string $class Optional class to apply to the select field
|
||||
* @param string $default Default value for initial selection
|
||||
* @param int $what One of the DateTimeZone class constants (for listIdentifiers)
|
||||
* @param string $country A two-letter ISO 3166-1 compatible country code (for listIdentifiers)
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
function timezone_select(string $class = '', string $default = '', int $what = DateTimeZone::ALL, ?string $country = null): string
|
||||
{
|
||||
$timezones = DateTimeZone::listIdentifiers($what, $country);
|
||||
|
||||
if ( ! function_exists('mdate'))
|
||||
{
|
||||
/**
|
||||
* Convert MySQL Style Datecodes
|
||||
*
|
||||
* This function is identical to PHPs date() function,
|
||||
* except that it allows date codes to be formatted using
|
||||
* the MySQL style, where each code letter is preceded
|
||||
* with a percent sign: %Y %m %d etc...
|
||||
*
|
||||
* The benefit of doing dates this way is that you don't
|
||||
* have to worry about escaping your text letters that
|
||||
* match the date codes.
|
||||
*
|
||||
* @param string
|
||||
* @param int
|
||||
* @return int
|
||||
*/
|
||||
function mdate($datestr = '', $time = '')
|
||||
{
|
||||
if ($datestr === '')
|
||||
{
|
||||
return '';
|
||||
}
|
||||
elseif (empty($time))
|
||||
{
|
||||
$time = now();
|
||||
}
|
||||
$buffer = "<select name='timezone' class='{$class}'>\n";
|
||||
|
||||
$datestr = str_replace(
|
||||
'%\\',
|
||||
'',
|
||||
preg_replace('/([a-z]+?){1}/i', '\\\\\\1', $datestr)
|
||||
);
|
||||
foreach ($timezones as $timezone) {
|
||||
$selected = ($timezone === $default) ? 'selected' : '';
|
||||
$buffer .= "<option value='{$timezone}' {$selected}>{$timezone}</option>\n";
|
||||
}
|
||||
|
||||
return date($datestr, $time);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('standard_date'))
|
||||
{
|
||||
/**
|
||||
* Standard Date
|
||||
*
|
||||
* Returns a date formatted according to the submitted standard.
|
||||
*
|
||||
* As of PHP 5.2, the DateTime extension provides constants that
|
||||
* serve for the exact same purpose and are used with date().
|
||||
*
|
||||
* @todo Remove in version 3.1+.
|
||||
* @deprecated 3.0.0 Use PHP's native date() instead.
|
||||
* @link https://www.php.net/manual/en/class.datetime.php#datetime.constants.types
|
||||
*
|
||||
* @example date(DATE_RFC822, now()); // default
|
||||
* @example date(DATE_W3C, $time); // a different format and time
|
||||
*
|
||||
* @param string $fmt = 'DATE_RFC822' the chosen format
|
||||
* @param int $time = NULL Unix timestamp
|
||||
* @return string
|
||||
*/
|
||||
function standard_date($fmt = 'DATE_RFC822', $time = NULL)
|
||||
{
|
||||
if (empty($time))
|
||||
{
|
||||
$time = now();
|
||||
}
|
||||
|
||||
// Procedural style pre-defined constants from the DateTime extension
|
||||
if (strpos($fmt, 'DATE_') !== 0 OR defined($fmt) === FALSE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return date(constant($fmt), $time);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('timespan'))
|
||||
{
|
||||
/**
|
||||
* Timespan
|
||||
*
|
||||
* Returns a span of seconds in this format:
|
||||
* 10 days 14 hours 36 minutes 47 seconds
|
||||
*
|
||||
* @param int a number of seconds
|
||||
* @param int Unix timestamp
|
||||
* @param int a number of display units
|
||||
* @return string
|
||||
*/
|
||||
function timespan($seconds = 1, $time = '', $units = 7)
|
||||
{
|
||||
$CI =& get_instance();
|
||||
$CI->lang->load('date');
|
||||
|
||||
is_numeric($seconds) OR $seconds = 1;
|
||||
is_numeric($time) OR $time = time();
|
||||
is_numeric($units) OR $units = 7;
|
||||
|
||||
$seconds = ($time <= $seconds) ? 1 : $time - $seconds;
|
||||
|
||||
$str = array();
|
||||
$years = floor($seconds / 31557600);
|
||||
|
||||
if ($years > 0)
|
||||
{
|
||||
$str[] = $years.' '.$CI->lang->line($years > 1 ? 'date_years' : 'date_year');
|
||||
}
|
||||
|
||||
$seconds -= $years * 31557600;
|
||||
$months = floor($seconds / 2629743);
|
||||
|
||||
if (count($str) < $units && ($years > 0 OR $months > 0))
|
||||
{
|
||||
if ($months > 0)
|
||||
{
|
||||
$str[] = $months.' '.$CI->lang->line($months > 1 ? 'date_months' : 'date_month');
|
||||
}
|
||||
|
||||
$seconds -= $months * 2629743;
|
||||
}
|
||||
|
||||
$weeks = floor($seconds / 604800);
|
||||
|
||||
if (count($str) < $units && ($years > 0 OR $months > 0 OR $weeks > 0))
|
||||
{
|
||||
if ($weeks > 0)
|
||||
{
|
||||
$str[] = $weeks.' '.$CI->lang->line($weeks > 1 ? 'date_weeks' : 'date_week');
|
||||
}
|
||||
|
||||
$seconds -= $weeks * 604800;
|
||||
}
|
||||
|
||||
$days = floor($seconds / 86400);
|
||||
|
||||
if (count($str) < $units && ($months > 0 OR $weeks > 0 OR $days > 0))
|
||||
{
|
||||
if ($days > 0)
|
||||
{
|
||||
$str[] = $days.' '.$CI->lang->line($days > 1 ? 'date_days' : 'date_day');
|
||||
}
|
||||
|
||||
$seconds -= $days * 86400;
|
||||
}
|
||||
|
||||
$hours = floor($seconds / 3600);
|
||||
|
||||
if (count($str) < $units && ($days > 0 OR $hours > 0))
|
||||
{
|
||||
if ($hours > 0)
|
||||
{
|
||||
$str[] = $hours.' '.$CI->lang->line($hours > 1 ? 'date_hours' : 'date_hour');
|
||||
}
|
||||
|
||||
$seconds -= $hours * 3600;
|
||||
}
|
||||
|
||||
$minutes = floor($seconds / 60);
|
||||
|
||||
if (count($str) < $units && ($days > 0 OR $hours > 0 OR $minutes > 0))
|
||||
{
|
||||
if ($minutes > 0)
|
||||
{
|
||||
$str[] = $minutes.' '.$CI->lang->line($minutes > 1 ? 'date_minutes' : 'date_minute');
|
||||
}
|
||||
|
||||
$seconds -= $minutes * 60;
|
||||
}
|
||||
|
||||
if (count($str) === 0)
|
||||
{
|
||||
$str[] = $seconds.' '.$CI->lang->line($seconds > 1 ? 'date_seconds' : 'date_second');
|
||||
}
|
||||
|
||||
return implode(', ', $str);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('days_in_month'))
|
||||
{
|
||||
/**
|
||||
* Number of days in a month
|
||||
*
|
||||
* Takes a month/year as input and returns the number of days
|
||||
* for the given month/year. Takes leap years into consideration.
|
||||
*
|
||||
* @param int a numeric month
|
||||
* @param int a numeric year
|
||||
* @return int
|
||||
*/
|
||||
function days_in_month($month = 0, $year = '')
|
||||
{
|
||||
if ($month < 1 OR $month > 12)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
elseif ( ! is_numeric($year) OR strlen($year) !== 4)
|
||||
{
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
if (defined('CAL_GREGORIAN'))
|
||||
{
|
||||
return cal_days_in_month(CAL_GREGORIAN, $month, $year);
|
||||
}
|
||||
|
||||
if ($year >= 1970)
|
||||
{
|
||||
return (int) date('t', mktime(12, 0, 0, $month, 1, $year));
|
||||
}
|
||||
|
||||
if ($month == 2)
|
||||
{
|
||||
if ($year % 400 === 0 OR ($year % 4 === 0 && $year % 100 !== 0))
|
||||
{
|
||||
return 29;
|
||||
}
|
||||
}
|
||||
|
||||
$days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
|
||||
return $days_in_month[$month - 1];
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('local_to_gmt'))
|
||||
{
|
||||
/**
|
||||
* Converts a local Unix timestamp to GMT
|
||||
*
|
||||
* @param int Unix timestamp
|
||||
* @return int
|
||||
*/
|
||||
function local_to_gmt($time = '')
|
||||
{
|
||||
if ($time === '')
|
||||
{
|
||||
$time = time();
|
||||
}
|
||||
|
||||
return mktime(
|
||||
gmdate('G', $time),
|
||||
gmdate('i', $time),
|
||||
gmdate('s', $time),
|
||||
gmdate('n', $time),
|
||||
gmdate('j', $time),
|
||||
gmdate('Y', $time)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('gmt_to_local'))
|
||||
{
|
||||
/**
|
||||
* Converts GMT time to a localized value
|
||||
*
|
||||
* Takes a Unix timestamp (in GMT) as input, and returns
|
||||
* at the local value based on the timezone and DST setting
|
||||
* submitted
|
||||
*
|
||||
* @param int Unix timestamp
|
||||
* @param string timezone
|
||||
* @param bool whether DST is active
|
||||
* @return int
|
||||
*/
|
||||
function gmt_to_local($time = '', $timezone = 'UTC', $dst = FALSE)
|
||||
{
|
||||
if ($time === '')
|
||||
{
|
||||
return now();
|
||||
}
|
||||
|
||||
$time += timezones($timezone) * 3600;
|
||||
|
||||
return ($dst === TRUE) ? $time + 3600 : $time;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('mysql_to_unix'))
|
||||
{
|
||||
/**
|
||||
* Converts a MySQL Timestamp to Unix
|
||||
*
|
||||
* @param int MySQL timestamp YYYY-MM-DD HH:MM:SS
|
||||
* @return int Unix timstamp
|
||||
*/
|
||||
function mysql_to_unix($time = '')
|
||||
{
|
||||
// We'll remove certain characters for backward compatibility
|
||||
// since the formatting changed with MySQL 4.1
|
||||
// YYYY-MM-DD HH:MM:SS
|
||||
|
||||
$time = str_replace(array('-', ':', ' '), '', $time);
|
||||
|
||||
// YYYYMMDDHHMMSS
|
||||
return mktime(
|
||||
substr($time, 8, 2),
|
||||
substr($time, 10, 2),
|
||||
substr($time, 12, 2),
|
||||
substr($time, 4, 2),
|
||||
substr($time, 6, 2),
|
||||
substr($time, 0, 4)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('unix_to_human'))
|
||||
{
|
||||
/**
|
||||
* Unix to "Human"
|
||||
*
|
||||
* Formats Unix timestamp to the following prototype: 2006-08-21 11:35 PM
|
||||
*
|
||||
* @param int Unix timestamp
|
||||
* @param bool whether to show seconds
|
||||
* @param string format: us or euro
|
||||
* @return string
|
||||
*/
|
||||
function unix_to_human($time = '', $seconds = FALSE, $fmt = 'us')
|
||||
{
|
||||
$r = date('Y', $time).'-'.date('m', $time).'-'.date('d', $time).' ';
|
||||
|
||||
if ($fmt === 'us')
|
||||
{
|
||||
$r .= date('h', $time).':'.date('i', $time);
|
||||
}
|
||||
else
|
||||
{
|
||||
$r .= date('H', $time).':'.date('i', $time);
|
||||
}
|
||||
|
||||
if ($seconds)
|
||||
{
|
||||
$r .= ':'.date('s', $time);
|
||||
}
|
||||
|
||||
if ($fmt === 'us')
|
||||
{
|
||||
return $r.' '.date('A', $time);
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('human_to_unix'))
|
||||
{
|
||||
/**
|
||||
* Convert "human" date to GMT
|
||||
*
|
||||
* Reverses the above process
|
||||
*
|
||||
* @param string format: us or euro
|
||||
* @return int
|
||||
*/
|
||||
function human_to_unix($datestr = '')
|
||||
{
|
||||
if ($datestr === '')
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$datestr = preg_replace('/\040+/', ' ', trim($datestr));
|
||||
|
||||
if ( ! preg_match('/^(\d{2}|\d{4})\-[0-9]{1,2}\-[0-9]{1,2}\s[0-9]{1,2}:[0-9]{1,2}(?::[0-9]{1,2})?(?:\s[AP]M)?$/i', $datestr))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sscanf($datestr, '%d-%d-%d %s %s', $year, $month, $day, $time, $ampm);
|
||||
sscanf($time, '%d:%d:%d', $hour, $min, $sec);
|
||||
isset($sec) OR $sec = 0;
|
||||
|
||||
if (isset($ampm))
|
||||
{
|
||||
$ampm = strtolower($ampm);
|
||||
|
||||
if ($ampm[0] === 'p' && $hour < 12)
|
||||
{
|
||||
$hour += 12;
|
||||
}
|
||||
elseif ($ampm[0] === 'a' && $hour === 12)
|
||||
{
|
||||
$hour = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return mktime($hour, $min, $sec, $month, $day, $year);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('nice_date'))
|
||||
{
|
||||
/**
|
||||
* Turns many "reasonably-date-like" strings into something
|
||||
* that is actually useful. This only works for dates after unix epoch.
|
||||
*
|
||||
* @deprecated 3.1.3 Use DateTime::createFromFormat($input_format, $input)->format($output_format);
|
||||
* @param string The terribly formatted date-like string
|
||||
* @param string Date format to return (same as php date function)
|
||||
* @return string
|
||||
*/
|
||||
function nice_date($bad_date = '', $format = FALSE)
|
||||
{
|
||||
if (empty($bad_date))
|
||||
{
|
||||
return 'Unknown';
|
||||
}
|
||||
elseif (empty($format))
|
||||
{
|
||||
$format = 'U';
|
||||
}
|
||||
|
||||
// Date like: YYYYMM
|
||||
if (preg_match('/^\d{6}$/i', $bad_date))
|
||||
{
|
||||
if (in_array(substr($bad_date, 0, 2), array('19', '20')))
|
||||
{
|
||||
$year = substr($bad_date, 0, 4);
|
||||
$month = substr($bad_date, 4, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
$month = substr($bad_date, 0, 2);
|
||||
$year = substr($bad_date, 2, 4);
|
||||
}
|
||||
|
||||
return date($format, strtotime($year.'-'.$month.'-01'));
|
||||
}
|
||||
|
||||
// Date Like: YYYYMMDD
|
||||
if (preg_match('/^\d{8}$/i', $bad_date, $matches))
|
||||
{
|
||||
return DateTime::createFromFormat('Ymd', $bad_date)->format($format);
|
||||
}
|
||||
|
||||
// Date Like: MM-DD-YYYY __or__ M-D-YYYY (or anything in between)
|
||||
if (preg_match('/^(\d{1,2})-(\d{1,2})-(\d{4})$/i', $bad_date, $matches))
|
||||
{
|
||||
return date($format, strtotime($matches[3].'-'.$matches[1].'-'.$matches[2]));
|
||||
}
|
||||
|
||||
// Any other kind of string, when converted into UNIX time,
|
||||
// produces "0 seconds after epoc..." is probably bad...
|
||||
// return "Invalid Date".
|
||||
if (date('U', strtotime($bad_date)) === '0')
|
||||
{
|
||||
return 'Invalid Date';
|
||||
}
|
||||
|
||||
// It's probably a valid-ish date format already
|
||||
return date($format, strtotime($bad_date));
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('timezone_menu'))
|
||||
{
|
||||
/**
|
||||
* Timezone Menu
|
||||
*
|
||||
* Generates a drop-down menu of timezones.
|
||||
*
|
||||
* @param string timezone
|
||||
* @param string classname
|
||||
* @param string menu name
|
||||
* @param mixed attributes
|
||||
* @return string
|
||||
*/
|
||||
function timezone_menu($default = 'UTC', $class = '', $name = 'timezones', $attributes = '')
|
||||
{
|
||||
$CI =& get_instance();
|
||||
$CI->lang->load('date');
|
||||
|
||||
$default = ($default === 'GMT') ? 'UTC' : $default;
|
||||
|
||||
$menu = '<select name="'.$name.'"';
|
||||
|
||||
if ($class !== '')
|
||||
{
|
||||
$menu .= ' class="'.$class.'"';
|
||||
}
|
||||
|
||||
$menu .= _stringify_attributes($attributes).">\n";
|
||||
|
||||
foreach (timezones() as $key => $val)
|
||||
{
|
||||
$selected = ($default === $key) ? ' selected="selected"' : '';
|
||||
$menu .= '<option value="'.$key.'"'.$selected.'>'.$CI->lang->line($key)."</option>\n";
|
||||
}
|
||||
|
||||
return $menu.'</select>';
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('timezones'))
|
||||
{
|
||||
/**
|
||||
* Timezones
|
||||
*
|
||||
* Returns an array of timezones. This is a helper function
|
||||
* for various other ones in this library
|
||||
*
|
||||
* @param string timezone
|
||||
* @return string
|
||||
*/
|
||||
function timezones($tz = '')
|
||||
{
|
||||
// Note: Don't change the order of these even though
|
||||
// some items appear to be in the wrong order
|
||||
|
||||
$zones = array(
|
||||
'UM12' => -12,
|
||||
'UM11' => -11,
|
||||
'UM10' => -10,
|
||||
'UM95' => -9.5,
|
||||
'UM9' => -9,
|
||||
'UM8' => -8,
|
||||
'UM7' => -7,
|
||||
'UM6' => -6,
|
||||
'UM5' => -5,
|
||||
'UM45' => -4.5,
|
||||
'UM4' => -4,
|
||||
'UM35' => -3.5,
|
||||
'UM3' => -3,
|
||||
'UM2' => -2,
|
||||
'UM1' => -1,
|
||||
'UTC' => 0,
|
||||
'UP1' => +1,
|
||||
'UP2' => +2,
|
||||
'UP3' => +3,
|
||||
'UP35' => +3.5,
|
||||
'UP4' => +4,
|
||||
'UP45' => +4.5,
|
||||
'UP5' => +5,
|
||||
'UP55' => +5.5,
|
||||
'UP575' => +5.75,
|
||||
'UP6' => +6,
|
||||
'UP65' => +6.5,
|
||||
'UP7' => +7,
|
||||
'UP8' => +8,
|
||||
'UP875' => +8.75,
|
||||
'UP9' => +9,
|
||||
'UP95' => +9.5,
|
||||
'UP10' => +10,
|
||||
'UP105' => +10.5,
|
||||
'UP11' => +11,
|
||||
'UP115' => +11.5,
|
||||
'UP12' => +12,
|
||||
'UP1275' => +12.75,
|
||||
'UP13' => +13,
|
||||
'UP14' => +14
|
||||
);
|
||||
|
||||
if ($tz === '')
|
||||
{
|
||||
return $zones;
|
||||
}
|
||||
|
||||
return isset($zones[$tz]) ? $zones[$tz] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('date_range'))
|
||||
{
|
||||
/**
|
||||
* Date range
|
||||
*
|
||||
* Returns a list of dates within a specified period.
|
||||
*
|
||||
* @param int unix_start UNIX timestamp of period start date
|
||||
* @param int unix_end|days UNIX timestamp of period end date
|
||||
* or interval in days.
|
||||
* @param mixed is_unix Specifies whether the second parameter
|
||||
* is a UNIX timestamp or a day interval
|
||||
* - TRUE or 'unix' for a timestamp
|
||||
* - FALSE or 'days' for an interval
|
||||
* @param string date_format Output date format, same as in date()
|
||||
* @return array
|
||||
*/
|
||||
function date_range($unix_start = '', $mixed = '', $is_unix = TRUE, $format = 'Y-m-d')
|
||||
{
|
||||
if ($unix_start == '' OR $mixed == '' OR $format == '')
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$is_unix = ! ( ! $is_unix OR $is_unix === 'days');
|
||||
|
||||
// Validate input and try strtotime() on invalid timestamps/intervals, just in case
|
||||
if ( ( ! ctype_digit((string) $unix_start) && ($unix_start = @strtotime($unix_start)) === FALSE)
|
||||
OR ( ! ctype_digit((string) $mixed) && ($is_unix === FALSE OR ($mixed = @strtotime($mixed)) === FALSE))
|
||||
OR ($is_unix === TRUE && $mixed < $unix_start))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ($is_unix && ($unix_start == $mixed OR date($format, $unix_start) === date($format, $mixed)))
|
||||
{
|
||||
return array(date($format, $unix_start));
|
||||
}
|
||||
|
||||
$range = array();
|
||||
|
||||
$from = new DateTime();
|
||||
$from->setTimestamp($unix_start);
|
||||
|
||||
if ($is_unix)
|
||||
{
|
||||
$arg = new DateTime();
|
||||
$arg->setTimestamp($mixed);
|
||||
}
|
||||
else
|
||||
{
|
||||
$arg = (int) $mixed;
|
||||
}
|
||||
|
||||
$period = new DatePeriod($from, new DateInterval('P1D'), $arg);
|
||||
foreach ($period as $date)
|
||||
{
|
||||
$range[] = $date->format($format);
|
||||
}
|
||||
|
||||
/* If a period end date was passed to the DatePeriod constructor, it might not
|
||||
* be in our results. Not sure if this is a bug or it's just possible because
|
||||
* the end date might actually be less than 24 hours away from the previously
|
||||
* generated DateTime object, but either way - we have to append it manually.
|
||||
*/
|
||||
if ( ! is_int($arg) && $range[count($range) - 1] !== $arg->format($format))
|
||||
{
|
||||
$range[] = $arg->format($format);
|
||||
}
|
||||
|
||||
return $range;
|
||||
}
|
||||
return $buffer . ("</select>\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Directory Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/directory_helper.html
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('directory_map'))
|
||||
{
|
||||
/**
|
||||
* Create a Directory Map
|
||||
*
|
||||
* Reads the specified directory and builds an array
|
||||
* representation of it. Sub-folders contained with the
|
||||
* directory will be mapped as well.
|
||||
*
|
||||
* @param string $source_dir Path to source
|
||||
* @param int $directory_depth Depth of directories to traverse
|
||||
* (0 = fully recursive, 1 = current dir, etc)
|
||||
* @param bool $hidden Whether to show hidden files
|
||||
* @return array
|
||||
*/
|
||||
function directory_map($source_dir, $directory_depth = 0, $hidden = FALSE)
|
||||
{
|
||||
if ($fp = @opendir($source_dir))
|
||||
{
|
||||
$filedata = array();
|
||||
$new_depth = $directory_depth - 1;
|
||||
$source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
|
||||
|
||||
while (FALSE !== ($file = readdir($fp)))
|
||||
{
|
||||
// Remove '.', '..', and hidden files [optional]
|
||||
if ($file === '.' OR $file === '..' OR ($hidden === FALSE && $file[0] === '.'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
is_dir($source_dir.$file) && $file .= DIRECTORY_SEPARATOR;
|
||||
|
||||
if (($directory_depth < 1 OR $new_depth > 0) && is_dir($source_dir.$file))
|
||||
{
|
||||
$filedata[$file] = directory_map($source_dir.$file, $new_depth, $hidden);
|
||||
}
|
||||
else
|
||||
{
|
||||
$filedata[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
closedir($fp);
|
||||
return $filedata;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Download Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/download_helper.html
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('force_download'))
|
||||
{
|
||||
/**
|
||||
* Force Download
|
||||
*
|
||||
* Generates headers that force a download to happen
|
||||
*
|
||||
* @param string filename
|
||||
* @param mixed the data to be downloaded
|
||||
* @param bool whether to try and send the actual file MIME type
|
||||
* @return void
|
||||
*/
|
||||
function force_download($filename = '', $data = '', $set_mime = FALSE)
|
||||
{
|
||||
if ($filename === '' OR $data === '')
|
||||
{
|
||||
return;
|
||||
}
|
||||
elseif ($data === NULL)
|
||||
{
|
||||
if ( ! @is_file($filename) OR ($filesize = @filesize($filename)) === FALSE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$filepath = $filename;
|
||||
$filename = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $filename));
|
||||
$filename = end($filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
$filesize = strlen($data);
|
||||
}
|
||||
|
||||
// Set the default MIME type to send
|
||||
$mime = 'application/octet-stream';
|
||||
|
||||
$x = explode('.', $filename);
|
||||
$extension = end($x);
|
||||
|
||||
if ($set_mime === TRUE)
|
||||
{
|
||||
if (count($x) === 1 OR $extension === '')
|
||||
{
|
||||
/* If we're going to detect the MIME type,
|
||||
* we'll need a file extension.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the mime types
|
||||
$mimes =& get_mimes();
|
||||
|
||||
// Only change the default MIME if we can find one
|
||||
if (isset($mimes[$extension]))
|
||||
{
|
||||
$mime = is_array($mimes[$extension]) ? $mimes[$extension][0] : $mimes[$extension];
|
||||
}
|
||||
}
|
||||
|
||||
/* It was reported that browsers on Android 2.1 (and possibly older as well)
|
||||
* need to have the filename extension upper-cased in order to be able to
|
||||
* download it.
|
||||
*
|
||||
* Reference: http://digiblog.de/2011/04/19/android-and-the-download-file-headers/
|
||||
*/
|
||||
if (count($x) !== 1 && isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/Android\s(1|2\.[01])/', $_SERVER['HTTP_USER_AGENT']))
|
||||
{
|
||||
$x[count($x) - 1] = strtoupper($extension);
|
||||
$filename = implode('.', $x);
|
||||
}
|
||||
|
||||
if ($data === NULL && ($fp = @fopen($filepath, 'rb')) === FALSE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean output buffer
|
||||
if (ob_get_level() !== 0 && @ob_end_clean() === FALSE)
|
||||
{
|
||||
@ob_clean();
|
||||
}
|
||||
|
||||
// Generate the server headers
|
||||
header('Content-Type: '.$mime);
|
||||
header('Content-Disposition: attachment; filename="'.$filename.'"');
|
||||
header('Expires: 0');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Content-Length: '.$filesize);
|
||||
header('Cache-Control: private, no-transform, no-store, must-revalidate');
|
||||
|
||||
// If we have raw data - just dump it
|
||||
if ($data !== NULL)
|
||||
{
|
||||
exit($data);
|
||||
}
|
||||
|
||||
// Flush 1MB chunks of data
|
||||
while ( ! feof($fp) && ($data = fread($fp, 1048576)) !== FALSE)
|
||||
{
|
||||
echo $data;
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Email Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/email_helper.html
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('valid_email'))
|
||||
{
|
||||
/**
|
||||
* Validate email address
|
||||
*
|
||||
* @deprecated 3.0.0 Use PHP's filter_var() instead
|
||||
* @param string $email
|
||||
* @return bool
|
||||
*/
|
||||
function valid_email($email)
|
||||
{
|
||||
return (bool) filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('send_email'))
|
||||
{
|
||||
/**
|
||||
* Send an email
|
||||
*
|
||||
* @deprecated 3.0.0 Use PHP's mail() instead
|
||||
* @param string $recipient
|
||||
* @param string $subject
|
||||
* @param string $message
|
||||
* @return bool
|
||||
*/
|
||||
function send_email($recipient, $subject, $message)
|
||||
{
|
||||
return mail($recipient, $subject, $message);
|
||||
}
|
||||
}
|
||||
@@ -1,454 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter File Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/file_helper.html
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('read_file'))
|
||||
{
|
||||
/**
|
||||
* Read File
|
||||
*
|
||||
* Opens the file specified in the path and returns it as a string.
|
||||
*
|
||||
* @todo Remove in version 3.1+.
|
||||
* @deprecated 3.0.0 It is now just an alias for PHP's native file_get_contents().
|
||||
* @param string $file Path to file
|
||||
* @return string File contents
|
||||
*/
|
||||
function read_file($file)
|
||||
{
|
||||
return @file_get_contents($file);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('write_file'))
|
||||
{
|
||||
/**
|
||||
* Write File
|
||||
*
|
||||
* Writes data to the file specified in the path.
|
||||
* Creates a new file if non-existent.
|
||||
*
|
||||
* @param string $path File path
|
||||
* @param string $data Data to write
|
||||
* @param string $mode fopen() mode (default: 'wb')
|
||||
* @return bool
|
||||
*/
|
||||
function write_file($path, $data, $mode = 'wb')
|
||||
{
|
||||
if ( ! $fp = @fopen($path, $mode))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
flock($fp, LOCK_EX);
|
||||
|
||||
for ($result = $written = 0, $length = strlen($data); $written < $length; $written += $result)
|
||||
{
|
||||
if (($result = fwrite($fp, substr($data, $written))) === FALSE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
|
||||
return is_int($result);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('delete_files'))
|
||||
{
|
||||
/**
|
||||
* Delete Files
|
||||
*
|
||||
* Deletes all files contained in the supplied directory path.
|
||||
* Files must be writable or owned by the system in order to be deleted.
|
||||
* If the second parameter is set to TRUE, any directories contained
|
||||
* within the supplied base directory will be nuked as well.
|
||||
*
|
||||
* @param string $path File path
|
||||
* @param bool $del_dir Whether to delete any directories found in the path
|
||||
* @param bool $htdocs Whether to skip deleting .htaccess and index page files
|
||||
* @param int $_level Current directory depth level (default: 0; internal use only)
|
||||
* @return bool
|
||||
*/
|
||||
function delete_files($path, $del_dir = FALSE, $htdocs = FALSE, $_level = 0)
|
||||
{
|
||||
// Trim the trailing slash
|
||||
$path = rtrim($path, '/\\');
|
||||
|
||||
if ( ! $current_dir = @opendir($path))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (FALSE !== ($filename = @readdir($current_dir)))
|
||||
{
|
||||
if ($filename !== '.' && $filename !== '..')
|
||||
{
|
||||
$filepath = $path.DIRECTORY_SEPARATOR.$filename;
|
||||
|
||||
if (is_dir($filepath) && $filename[0] !== '.' && ! is_link($filepath))
|
||||
{
|
||||
delete_files($filepath, $del_dir, $htdocs, $_level + 1);
|
||||
}
|
||||
elseif ($htdocs !== TRUE OR ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename))
|
||||
{
|
||||
@unlink($filepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir($current_dir);
|
||||
|
||||
return ($del_dir === TRUE && $_level > 0)
|
||||
? @rmdir($path)
|
||||
: TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('get_filenames'))
|
||||
{
|
||||
/**
|
||||
* Get Filenames
|
||||
*
|
||||
* Reads the specified directory and builds an array containing the filenames.
|
||||
* Any sub-folders contained within the specified path are read as well.
|
||||
*
|
||||
* @param string path to source
|
||||
* @param bool whether to include the path as part of the filename
|
||||
* @param bool internal variable to determine recursion status - do not use in calls
|
||||
* @return array
|
||||
*/
|
||||
function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE)
|
||||
{
|
||||
static $_filedata = array();
|
||||
|
||||
if ($fp = @opendir($source_dir))
|
||||
{
|
||||
// reset the array and make sure $source_dir has a trailing slash on the initial call
|
||||
if ($_recursion === FALSE)
|
||||
{
|
||||
$_filedata = array();
|
||||
$source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
while (FALSE !== ($file = readdir($fp)))
|
||||
{
|
||||
if (is_dir($source_dir.$file) && $file[0] !== '.')
|
||||
{
|
||||
get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);
|
||||
}
|
||||
elseif ($file[0] !== '.')
|
||||
{
|
||||
$_filedata[] = ($include_path === TRUE) ? $source_dir.$file : $file;
|
||||
}
|
||||
}
|
||||
|
||||
closedir($fp);
|
||||
return $_filedata;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('get_dir_file_info'))
|
||||
{
|
||||
/**
|
||||
* Get Directory File Information
|
||||
*
|
||||
* Reads the specified directory and builds an array containing the filenames,
|
||||
* filesize, dates, and permissions
|
||||
*
|
||||
* Any sub-folders contained within the specified path are read as well.
|
||||
*
|
||||
* @param string path to source
|
||||
* @param bool Look only at the top level directory specified?
|
||||
* @param bool internal variable to determine recursion status - do not use in calls
|
||||
* @return array
|
||||
*/
|
||||
function get_dir_file_info($source_dir, $top_level_only = TRUE, $_recursion = FALSE)
|
||||
{
|
||||
static $_filedata = array();
|
||||
$relative_path = $source_dir;
|
||||
|
||||
if ($fp = @opendir($source_dir))
|
||||
{
|
||||
// reset the array and make sure $source_dir has a trailing slash on the initial call
|
||||
if ($_recursion === FALSE)
|
||||
{
|
||||
$_filedata = array();
|
||||
$source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
// Used to be foreach (scandir($source_dir, 1) as $file), but scandir() is simply not as fast
|
||||
while (FALSE !== ($file = readdir($fp)))
|
||||
{
|
||||
if (is_dir($source_dir.$file) && $file[0] !== '.' && $top_level_only === FALSE)
|
||||
{
|
||||
get_dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $top_level_only, TRUE);
|
||||
}
|
||||
elseif ($file[0] !== '.')
|
||||
{
|
||||
$_filedata[$file] = get_file_info($source_dir.$file);
|
||||
$_filedata[$file]['relative_path'] = $relative_path;
|
||||
}
|
||||
}
|
||||
|
||||
closedir($fp);
|
||||
return $_filedata;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('get_file_info'))
|
||||
{
|
||||
/**
|
||||
* Get File Info
|
||||
*
|
||||
* Given a file and path, returns the name, path, size, date modified
|
||||
* Second parameter allows you to explicitly declare what information you want returned
|
||||
* Options are: name, server_path, size, date, readable, writable, executable, fileperms
|
||||
* Returns FALSE if the file cannot be found.
|
||||
*
|
||||
* @param string path to file
|
||||
* @param mixed array or comma separated string of information returned
|
||||
* @return array
|
||||
*/
|
||||
function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date'))
|
||||
{
|
||||
if ( ! file_exists($file))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (is_string($returned_values))
|
||||
{
|
||||
$returned_values = explode(',', $returned_values);
|
||||
}
|
||||
|
||||
foreach ($returned_values as $key)
|
||||
{
|
||||
switch ($key)
|
||||
{
|
||||
case 'name':
|
||||
$fileinfo['name'] = basename($file);
|
||||
break;
|
||||
case 'server_path':
|
||||
$fileinfo['server_path'] = $file;
|
||||
break;
|
||||
case 'size':
|
||||
$fileinfo['size'] = filesize($file);
|
||||
break;
|
||||
case 'date':
|
||||
$fileinfo['date'] = filemtime($file);
|
||||
break;
|
||||
case 'readable':
|
||||
$fileinfo['readable'] = is_readable($file);
|
||||
break;
|
||||
case 'writable':
|
||||
$fileinfo['writable'] = is_really_writable($file);
|
||||
break;
|
||||
case 'executable':
|
||||
$fileinfo['executable'] = is_executable($file);
|
||||
break;
|
||||
case 'fileperms':
|
||||
$fileinfo['fileperms'] = fileperms($file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $fileinfo;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('get_mime_by_extension'))
|
||||
{
|
||||
/**
|
||||
* Get Mime by Extension
|
||||
*
|
||||
* Translates a file extension into a mime type based on config/mimes.php.
|
||||
* Returns FALSE if it can't determine the type, or open the mime config file
|
||||
*
|
||||
* Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience
|
||||
* It should NOT be trusted, and should certainly NOT be used for security
|
||||
*
|
||||
* @param string $filename File name
|
||||
* @return string
|
||||
*/
|
||||
function get_mime_by_extension($filename)
|
||||
{
|
||||
static $mimes;
|
||||
|
||||
if ( ! is_array($mimes))
|
||||
{
|
||||
$mimes = get_mimes();
|
||||
|
||||
if (empty($mimes))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
$extension = strtolower(substr(strrchr($filename, '.'), 1));
|
||||
|
||||
if (isset($mimes[$extension]))
|
||||
{
|
||||
return is_array($mimes[$extension])
|
||||
? current($mimes[$extension]) // Multiple mime types, just give the first one
|
||||
: $mimes[$extension];
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('symbolic_permissions'))
|
||||
{
|
||||
/**
|
||||
* Symbolic Permissions
|
||||
*
|
||||
* Takes a numeric value representing a file's permissions and returns
|
||||
* standard symbolic notation representing that value
|
||||
*
|
||||
* @param int $perms Permissions
|
||||
* @return string
|
||||
*/
|
||||
function symbolic_permissions($perms)
|
||||
{
|
||||
if (($perms & 0xC000) === 0xC000)
|
||||
{
|
||||
$symbolic = 's'; // Socket
|
||||
}
|
||||
elseif (($perms & 0xA000) === 0xA000)
|
||||
{
|
||||
$symbolic = 'l'; // Symbolic Link
|
||||
}
|
||||
elseif (($perms & 0x8000) === 0x8000)
|
||||
{
|
||||
$symbolic = '-'; // Regular
|
||||
}
|
||||
elseif (($perms & 0x6000) === 0x6000)
|
||||
{
|
||||
$symbolic = 'b'; // Block special
|
||||
}
|
||||
elseif (($perms & 0x4000) === 0x4000)
|
||||
{
|
||||
$symbolic = 'd'; // Directory
|
||||
}
|
||||
elseif (($perms & 0x2000) === 0x2000)
|
||||
{
|
||||
$symbolic = 'c'; // Character special
|
||||
}
|
||||
elseif (($perms & 0x1000) === 0x1000)
|
||||
{
|
||||
$symbolic = 'p'; // FIFO pipe
|
||||
}
|
||||
else
|
||||
{
|
||||
$symbolic = 'u'; // Unknown
|
||||
}
|
||||
|
||||
// Owner
|
||||
$symbolic .= (($perms & 0x0100) ? 'r' : '-')
|
||||
.(($perms & 0x0080) ? 'w' : '-')
|
||||
.(($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-'));
|
||||
|
||||
// Group
|
||||
$symbolic .= (($perms & 0x0020) ? 'r' : '-')
|
||||
.(($perms & 0x0010) ? 'w' : '-')
|
||||
.(($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-'));
|
||||
|
||||
// World
|
||||
$symbolic .= (($perms & 0x0004) ? 'r' : '-')
|
||||
.(($perms & 0x0002) ? 'w' : '-')
|
||||
.(($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-'));
|
||||
|
||||
return $symbolic;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('octal_permissions'))
|
||||
{
|
||||
/**
|
||||
* Octal Permissions
|
||||
*
|
||||
* Takes a numeric value representing a file's permissions and returns
|
||||
* a three character string representing the file's octal permissions
|
||||
*
|
||||
* @param int $perms Permissions
|
||||
* @return string
|
||||
*/
|
||||
function octal_permissions($perms)
|
||||
{
|
||||
return substr(sprintf('%o', $perms), -3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,450 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
// CodeIgniter File System Helpers
|
||||
|
||||
if (! function_exists('directory_map')) {
|
||||
/**
|
||||
* Create a Directory Map
|
||||
*
|
||||
* Reads the specified directory and builds an array
|
||||
* representation of it. Sub-folders contained with the
|
||||
* directory will be mapped as well.
|
||||
*
|
||||
* @param string $sourceDir Path to source
|
||||
* @param int $directoryDepth Depth of directories to traverse
|
||||
* (0 = fully recursive, 1 = current dir, etc)
|
||||
* @param bool $hidden Whether to show hidden files
|
||||
*/
|
||||
function directory_map(string $sourceDir, int $directoryDepth = 0, bool $hidden = false): array
|
||||
{
|
||||
try {
|
||||
$fp = opendir($sourceDir);
|
||||
|
||||
$fileData = [];
|
||||
$newDepth = $directoryDepth - 1;
|
||||
$sourceDir = rtrim($sourceDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
|
||||
while (false !== ($file = readdir($fp))) {
|
||||
// Remove '.', '..', and hidden files [optional]
|
||||
if ($file === '.' || $file === '..' || ($hidden === false && $file[0] === '.')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_dir($sourceDir . $file)) {
|
||||
$file .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
if (($directoryDepth < 1 || $newDepth > 0) && is_dir($sourceDir . $file)) {
|
||||
$fileData[$file] = directory_map($sourceDir . $file, $newDepth, $hidden);
|
||||
} else {
|
||||
$fileData[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
closedir($fp);
|
||||
|
||||
return $fileData;
|
||||
} catch (Throwable $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('directory_mirror')) {
|
||||
/**
|
||||
* Recursively copies the files and directories of the origin directory
|
||||
* into the target directory, i.e. "mirror" its contents.
|
||||
*
|
||||
* @param bool $overwrite Whether individual files overwrite on collision
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
function directory_mirror(string $originDir, string $targetDir, bool $overwrite = true): void
|
||||
{
|
||||
if (! is_dir($originDir = rtrim($originDir, '\\/'))) {
|
||||
throw new InvalidArgumentException(sprintf('The origin directory "%s" was not found.', $originDir));
|
||||
}
|
||||
|
||||
if (! is_dir($targetDir = rtrim($targetDir, '\\/'))) {
|
||||
@mkdir($targetDir, 0755, true);
|
||||
}
|
||||
|
||||
$dirLen = strlen($originDir);
|
||||
|
||||
/**
|
||||
* @var SplFileInfo $file
|
||||
*/
|
||||
foreach (new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($originDir, FilesystemIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
) as $file) {
|
||||
$origin = $file->getPathname();
|
||||
$target = $targetDir . substr($origin, $dirLen);
|
||||
|
||||
if ($file->isDir()) {
|
||||
if (! is_dir($target)) {
|
||||
mkdir($target, 0755);
|
||||
}
|
||||
} elseif (! is_file($target) || ($overwrite && is_file($target))) {
|
||||
copy($origin, $target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('write_file')) {
|
||||
/**
|
||||
* Write File
|
||||
*
|
||||
* Writes data to the file specified in the path.
|
||||
* Creates a new file if non-existent.
|
||||
*
|
||||
* @param string $path File path
|
||||
* @param string $data Data to write
|
||||
* @param string $mode fopen() mode (default: 'wb')
|
||||
*/
|
||||
function write_file(string $path, string $data, string $mode = 'wb'): bool
|
||||
{
|
||||
try {
|
||||
$fp = fopen($path, $mode);
|
||||
|
||||
flock($fp, LOCK_EX);
|
||||
|
||||
for ($result = $written = 0, $length = strlen($data); $written < $length; $written += $result) {
|
||||
if (($result = fwrite($fp, substr($data, $written))) === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
|
||||
return is_int($result);
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('delete_files')) {
|
||||
/**
|
||||
* Delete Files
|
||||
*
|
||||
* Deletes all files contained in the supplied directory path.
|
||||
* Files must be writable or owned by the system in order to be deleted.
|
||||
* If the second parameter is set to true, any directories contained
|
||||
* within the supplied base directory will be nuked as well.
|
||||
*
|
||||
* @param string $path File path
|
||||
* @param bool $delDir Whether to delete any directories found in the path
|
||||
* @param bool $htdocs Whether to skip deleting .htaccess and index page files
|
||||
* @param bool $hidden Whether to include hidden files (files beginning with a period)
|
||||
*/
|
||||
function delete_files(string $path, bool $delDir = false, bool $htdocs = false, bool $hidden = false): bool
|
||||
{
|
||||
$path = realpath($path) ?: $path;
|
||||
$path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
|
||||
try {
|
||||
foreach (new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::CHILD_FIRST
|
||||
) as $object) {
|
||||
$filename = $object->getFilename();
|
||||
if (! $hidden && $filename[0] === '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $htdocs || ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename)) {
|
||||
$isDir = $object->isDir();
|
||||
if ($isDir && $delDir) {
|
||||
rmdir($object->getPathname());
|
||||
|
||||
continue;
|
||||
}
|
||||
if (! $isDir) {
|
||||
unlink($object->getPathname());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_filenames')) {
|
||||
/**
|
||||
* Get Filenames
|
||||
*
|
||||
* Reads the specified directory and builds an array containing the filenames.
|
||||
* Any sub-folders contained within the specified path are read as well.
|
||||
*
|
||||
* @param string $sourceDir Path to source
|
||||
* @param bool|null $includePath Whether to include the path as part of the filename; false for no path, null for a relative path, true for full path
|
||||
* @param bool $hidden Whether to include hidden files (files beginning with a period)
|
||||
* @param bool $includeDir Whether to include directories
|
||||
*/
|
||||
function get_filenames(
|
||||
string $sourceDir,
|
||||
?bool $includePath = false,
|
||||
bool $hidden = false,
|
||||
bool $includeDir = true
|
||||
): array {
|
||||
$files = [];
|
||||
|
||||
$sourceDir = realpath($sourceDir) ?: $sourceDir;
|
||||
$sourceDir = rtrim($sourceDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
|
||||
try {
|
||||
foreach (new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($sourceDir, RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
) as $name => $object) {
|
||||
$basename = pathinfo($name, PATHINFO_BASENAME);
|
||||
if (! $hidden && $basename[0] === '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($includeDir || ! $object->isDir()) {
|
||||
if ($includePath === false) {
|
||||
$files[] = $basename;
|
||||
} elseif ($includePath === null) {
|
||||
$files[] = str_replace($sourceDir, '', $name);
|
||||
} else {
|
||||
$files[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
sort($files);
|
||||
|
||||
return $files;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_dir_file_info')) {
|
||||
/**
|
||||
* Get Directory File Information
|
||||
*
|
||||
* Reads the specified directory and builds an array containing the filenames,
|
||||
* filesize, dates, and permissions
|
||||
*
|
||||
* Any sub-folders contained within the specified path are read as well.
|
||||
*
|
||||
* @param string $sourceDir Path to source
|
||||
* @param bool $topLevelOnly Look only at the top level directory specified?
|
||||
* @param bool $recursion Internal variable to determine recursion status - do not use in calls
|
||||
*/
|
||||
function get_dir_file_info(string $sourceDir, bool $topLevelOnly = true, bool $recursion = false): array
|
||||
{
|
||||
static $fileData = [];
|
||||
$relativePath = $sourceDir;
|
||||
|
||||
try {
|
||||
$fp = opendir($sourceDir);
|
||||
|
||||
// reset the array and make sure $source_dir has a trailing slash on the initial call
|
||||
if ($recursion === false) {
|
||||
$fileData = [];
|
||||
$sourceDir = rtrim(realpath($sourceDir), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
// Used to be foreach (scandir($source_dir, 1) as $file), but scandir() is simply not as fast
|
||||
while (false !== ($file = readdir($fp))) {
|
||||
if (is_dir($sourceDir . $file) && $file[0] !== '.' && $topLevelOnly === false) {
|
||||
get_dir_file_info($sourceDir . $file . DIRECTORY_SEPARATOR, $topLevelOnly, true);
|
||||
} elseif ($file[0] !== '.') {
|
||||
$fileData[$file] = get_file_info($sourceDir . $file);
|
||||
$fileData[$file]['relative_path'] = $relativePath;
|
||||
}
|
||||
}
|
||||
|
||||
closedir($fp);
|
||||
|
||||
return $fileData;
|
||||
} catch (Throwable $fe) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_file_info')) {
|
||||
/**
|
||||
* Get File Info
|
||||
*
|
||||
* Given a file and path, returns the name, path, size, date modified
|
||||
* Second parameter allows you to explicitly declare what information you want returned
|
||||
* Options are: name, server_path, size, date, readable, writable, executable, fileperms
|
||||
* Returns false if the file cannot be found.
|
||||
*
|
||||
* @param string $file Path to file
|
||||
* @param mixed $returnedValues Array or comma separated string of information returned
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
function get_file_info(string $file, $returnedValues = ['name', 'server_path', 'size', 'date'])
|
||||
{
|
||||
if (! is_file($file)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$fileInfo = [];
|
||||
|
||||
if (is_string($returnedValues)) {
|
||||
$returnedValues = explode(',', $returnedValues);
|
||||
}
|
||||
|
||||
foreach ($returnedValues as $key) {
|
||||
switch ($key) {
|
||||
case 'name':
|
||||
$fileInfo['name'] = basename($file);
|
||||
break;
|
||||
|
||||
case 'server_path':
|
||||
$fileInfo['server_path'] = $file;
|
||||
break;
|
||||
|
||||
case 'size':
|
||||
$fileInfo['size'] = filesize($file);
|
||||
break;
|
||||
|
||||
case 'date':
|
||||
$fileInfo['date'] = filemtime($file);
|
||||
break;
|
||||
|
||||
case 'readable':
|
||||
$fileInfo['readable'] = is_readable($file);
|
||||
break;
|
||||
|
||||
case 'writable':
|
||||
$fileInfo['writable'] = is_really_writable($file);
|
||||
break;
|
||||
|
||||
case 'executable':
|
||||
$fileInfo['executable'] = is_executable($file);
|
||||
break;
|
||||
|
||||
case 'fileperms':
|
||||
$fileInfo['fileperms'] = fileperms($file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $fileInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('symbolic_permissions')) {
|
||||
/**
|
||||
* Symbolic Permissions
|
||||
*
|
||||
* Takes a numeric value representing a file's permissions and returns
|
||||
* standard symbolic notation representing that value
|
||||
*
|
||||
* @param int $perms Permissions
|
||||
*/
|
||||
function symbolic_permissions(int $perms): string
|
||||
{
|
||||
if (($perms & 0xC000) === 0xC000) {
|
||||
$symbolic = 's'; // Socket
|
||||
} elseif (($perms & 0xA000) === 0xA000) {
|
||||
$symbolic = 'l'; // Symbolic Link
|
||||
} elseif (($perms & 0x8000) === 0x8000) {
|
||||
$symbolic = '-'; // Regular
|
||||
} elseif (($perms & 0x6000) === 0x6000) {
|
||||
$symbolic = 'b'; // Block special
|
||||
} elseif (($perms & 0x4000) === 0x4000) {
|
||||
$symbolic = 'd'; // Directory
|
||||
} elseif (($perms & 0x2000) === 0x2000) {
|
||||
$symbolic = 'c'; // Character special
|
||||
} elseif (($perms & 0x1000) === 0x1000) {
|
||||
$symbolic = 'p'; // FIFO pipe
|
||||
} else {
|
||||
$symbolic = 'u'; // Unknown
|
||||
}
|
||||
|
||||
// Owner
|
||||
$symbolic .= (($perms & 0x0100) ? 'r' : '-')
|
||||
. (($perms & 0x0080) ? 'w' : '-')
|
||||
. (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x') : (($perms & 0x0800) ? 'S' : '-'));
|
||||
|
||||
// Group
|
||||
$symbolic .= (($perms & 0x0020) ? 'r' : '-')
|
||||
. (($perms & 0x0010) ? 'w' : '-')
|
||||
. (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x') : (($perms & 0x0400) ? 'S' : '-'));
|
||||
|
||||
// World
|
||||
$symbolic .= (($perms & 0x0004) ? 'r' : '-')
|
||||
. (($perms & 0x0002) ? 'w' : '-')
|
||||
. (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x') : (($perms & 0x0200) ? 'T' : '-'));
|
||||
|
||||
return $symbolic;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('octal_permissions')) {
|
||||
/**
|
||||
* Octal Permissions
|
||||
*
|
||||
* Takes a numeric value representing a file's permissions and returns
|
||||
* a three character string representing the file's octal permissions
|
||||
*
|
||||
* @param int $perms Permissions
|
||||
*/
|
||||
function octal_permissions(int $perms): string
|
||||
{
|
||||
return substr(sprintf('%o', $perms), -3);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('same_file')) {
|
||||
/**
|
||||
* Checks if two files both exist and have identical hashes
|
||||
*
|
||||
* @return bool Same or not
|
||||
*/
|
||||
function same_file(string $file1, string $file2): bool
|
||||
{
|
||||
return is_file($file1) && is_file($file2) && md5_file($file1) === md5_file($file2);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('set_realpath')) {
|
||||
/**
|
||||
* Set Realpath
|
||||
*
|
||||
* @param bool $checkExistence Checks to see if the path exists
|
||||
*/
|
||||
function set_realpath(string $path, bool $checkExistence = false): string
|
||||
{
|
||||
// Security check to make sure the path is NOT a URL. No remote file inclusion!
|
||||
if (preg_match('#^(http:\/\/|https:\/\/|www\.|ftp)#i', $path) || filter_var($path, FILTER_VALIDATE_IP) === $path) {
|
||||
throw new InvalidArgumentException('The path you submitted must be a local server path, not a URL');
|
||||
}
|
||||
|
||||
// Resolve the path
|
||||
if (realpath($path) !== false) {
|
||||
$path = realpath($path);
|
||||
} elseif ($checkExistence && ! is_dir($path) && ! is_file($path)) {
|
||||
throw new InvalidArgumentException('Not a valid path: ' . $path);
|
||||
}
|
||||
|
||||
// Add a trailing slash, if this is a directory
|
||||
return is_dir($path) ? rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $path;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Regular → Executable
+499
-364
@@ -1,410 +1,545 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter HTML Helpers
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/html_helper.html
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
use CodeIgniter\Files\Exceptions\FileNotFoundException;
|
||||
use Config\DocTypes;
|
||||
use Config\Mimes;
|
||||
|
||||
if ( ! function_exists('heading'))
|
||||
{
|
||||
/**
|
||||
* Heading
|
||||
*
|
||||
* Generates an HTML heading tag.
|
||||
*
|
||||
* @param string content
|
||||
* @param int heading level
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function heading($data = '', $h = '1', $attributes = '')
|
||||
{
|
||||
return '<h'.$h._stringify_attributes($attributes).'>'.$data.'</h'.$h.'>';
|
||||
}
|
||||
// CodeIgniter HTML Helpers
|
||||
|
||||
if (! function_exists('ul')) {
|
||||
/**
|
||||
* Unordered List
|
||||
*
|
||||
* Generates an HTML unordered list from an single or
|
||||
* multi-dimensional array.
|
||||
*
|
||||
* @param array|object|string $attributes HTML attributes string, array, object
|
||||
*/
|
||||
function ul(array $list, $attributes = ''): string
|
||||
{
|
||||
return _list('ul', $list, $attributes);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('ul'))
|
||||
{
|
||||
/**
|
||||
* Unordered List
|
||||
*
|
||||
* Generates an HTML unordered list from an single or multi-dimensional array.
|
||||
*
|
||||
* @param array
|
||||
* @param mixed
|
||||
* @return string
|
||||
*/
|
||||
function ul($list, $attributes = '')
|
||||
{
|
||||
return _list('ul', $list, $attributes);
|
||||
}
|
||||
if (! function_exists('ol')) {
|
||||
/**
|
||||
* Ordered List
|
||||
*
|
||||
* Generates an HTML ordered list from an single or multi-dimensional array.
|
||||
*
|
||||
* @param array|object|string $attributes HTML attributes string, array, object
|
||||
*/
|
||||
function ol(array $list, $attributes = ''): string
|
||||
{
|
||||
return _list('ol', $list, $attributes);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
if (! function_exists('_list')) {
|
||||
/**
|
||||
* Generates the list
|
||||
*
|
||||
* Generates an HTML ordered list from an single or multi-dimensional array.
|
||||
*
|
||||
* @param array $list
|
||||
* @param array|object|string $attributes string, array, object
|
||||
*/
|
||||
function _list(string $type = 'ul', $list = [], $attributes = '', int $depth = 0): string
|
||||
{
|
||||
// Set the indentation based on the depth
|
||||
$out = str_repeat(' ', $depth)
|
||||
// Write the opening list tag
|
||||
. '<' . $type . stringify_attributes($attributes) . ">\n";
|
||||
|
||||
if ( ! function_exists('ol'))
|
||||
{
|
||||
/**
|
||||
* Ordered List
|
||||
*
|
||||
* Generates an HTML ordered list from an single or multi-dimensional array.
|
||||
*
|
||||
* @param array
|
||||
* @param mixed
|
||||
* @return string
|
||||
*/
|
||||
function ol($list, $attributes = '')
|
||||
{
|
||||
return _list('ol', $list, $attributes);
|
||||
}
|
||||
// Cycle through the list elements. If an array is
|
||||
// encountered we will recursively call _list()
|
||||
|
||||
foreach ($list as $key => $val) {
|
||||
$out .= str_repeat(' ', $depth + 2) . '<li>';
|
||||
|
||||
if (! is_array($val)) {
|
||||
$out .= $val;
|
||||
} else {
|
||||
$out .= $key
|
||||
. "\n"
|
||||
. _list($type, $val, '', $depth + 4)
|
||||
. str_repeat(' ', $depth + 2);
|
||||
}
|
||||
|
||||
$out .= "</li>\n";
|
||||
}
|
||||
|
||||
// Set the indentation for the closing tag and apply it
|
||||
return $out . str_repeat(' ', $depth) . '</' . $type . ">\n";
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
if (! function_exists('img')) {
|
||||
/**
|
||||
* Image
|
||||
*
|
||||
* Generates an image element
|
||||
*
|
||||
* @param array|string $src Image source URI, or array of attributes and values
|
||||
* @param bool $indexPage Whether to treat $src as a routed URI string
|
||||
* @param array|object|string $attributes Additional HTML attributes
|
||||
*/
|
||||
function img($src = '', bool $indexPage = false, $attributes = ''): string
|
||||
{
|
||||
if (! is_array($src)) {
|
||||
$src = ['src' => $src];
|
||||
}
|
||||
if (! isset($src['src'])) {
|
||||
$src['src'] = $attributes['src'] ?? '';
|
||||
}
|
||||
if (! isset($src['alt'])) {
|
||||
$src['alt'] = $attributes['alt'] ?? '';
|
||||
}
|
||||
|
||||
if ( ! function_exists('_list'))
|
||||
{
|
||||
/**
|
||||
* Generates the list
|
||||
*
|
||||
* Generates an HTML ordered list from an single or multi-dimensional array.
|
||||
*
|
||||
* @param string
|
||||
* @param mixed
|
||||
* @param mixed
|
||||
* @param int
|
||||
* @return string
|
||||
*/
|
||||
function _list($type = 'ul', $list = array(), $attributes = '', $depth = 0)
|
||||
{
|
||||
// If an array wasn't submitted there's nothing to do...
|
||||
if ( ! is_array($list))
|
||||
{
|
||||
return $list;
|
||||
}
|
||||
$img = '<img';
|
||||
|
||||
// Set the indentation based on the depth
|
||||
$out = str_repeat(' ', $depth)
|
||||
// Write the opening list tag
|
||||
.'<'.$type._stringify_attributes($attributes).">\n";
|
||||
// Check for a relative URI
|
||||
if (! preg_match('#^([a-z]+:)?//#i', $src['src']) && strpos($src['src'], 'data:') !== 0) {
|
||||
if ($indexPage === true) {
|
||||
$img .= ' src="' . site_url($src['src']) . '"';
|
||||
} else {
|
||||
$img .= ' src="' . slash_item('baseURL') . $src['src'] . '"';
|
||||
}
|
||||
|
||||
// Cycle through the list elements. If an array is
|
||||
// encountered we will recursively call _list()
|
||||
unset($src['src']);
|
||||
}
|
||||
|
||||
static $_last_list_item = '';
|
||||
foreach ($list as $key => $val)
|
||||
{
|
||||
$_last_list_item = $key;
|
||||
// Append any other values
|
||||
foreach ($src as $key => $value) {
|
||||
$img .= ' ' . $key . '="' . $value . '"';
|
||||
}
|
||||
|
||||
$out .= str_repeat(' ', $depth + 2).'<li>';
|
||||
// Prevent passing completed values to stringify_attributes
|
||||
if (is_array($attributes)) {
|
||||
unset($attributes['alt'], $attributes['src']);
|
||||
}
|
||||
|
||||
if ( ! is_array($val))
|
||||
{
|
||||
$out .= $val;
|
||||
}
|
||||
else
|
||||
{
|
||||
$out .= $_last_list_item."\n"._list($type, $val, '', $depth + 4).str_repeat(' ', $depth + 2);
|
||||
}
|
||||
|
||||
$out .= "</li>\n";
|
||||
}
|
||||
|
||||
// Set the indentation for the closing tag and apply it
|
||||
return $out.str_repeat(' ', $depth).'</'.$type.">\n";
|
||||
}
|
||||
return $img . stringify_attributes($attributes) . ' />';
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
if (! function_exists('img_data')) {
|
||||
/**
|
||||
* Image (data)
|
||||
*
|
||||
* Generates a src-ready string from an image using the "data:" protocol
|
||||
*
|
||||
* @param string $path Image source path
|
||||
* @param string|null $mime MIME type to use, or null to guess
|
||||
*/
|
||||
function img_data(string $path, ?string $mime = null): string
|
||||
{
|
||||
if (! is_file($path) || ! is_readable($path)) {
|
||||
throw FileNotFoundException::forFileNotFound($path);
|
||||
}
|
||||
|
||||
if ( ! function_exists('img'))
|
||||
{
|
||||
/**
|
||||
* Image
|
||||
*
|
||||
* Generates an <img /> element
|
||||
*
|
||||
* @param mixed
|
||||
* @param bool
|
||||
* @param mixed
|
||||
* @return string
|
||||
*/
|
||||
function img($src = '', $index_page = FALSE, $attributes = '')
|
||||
{
|
||||
if ( ! is_array($src) )
|
||||
{
|
||||
$src = array('src' => $src);
|
||||
}
|
||||
// Read in file binary data
|
||||
$handle = fopen($path, 'rb');
|
||||
$data = fread($handle, filesize($path));
|
||||
fclose($handle);
|
||||
|
||||
// If there is no alt attribute defined, set it to an empty string
|
||||
if ( ! isset($src['alt']))
|
||||
{
|
||||
$src['alt'] = '';
|
||||
}
|
||||
// Encode as base64
|
||||
$data = base64_encode($data);
|
||||
|
||||
$img = '<img';
|
||||
// Figure out the type (Hail Mary to JPEG)
|
||||
$mime ??= Mimes::guessTypeFromExtension(pathinfo($path, PATHINFO_EXTENSION)) ?? 'image/jpg';
|
||||
|
||||
foreach ($src as $k => $v)
|
||||
{
|
||||
if ($k === 'src' && ! preg_match('#^(data:[a-z,;])|(([a-z]+:)?(?<!data:)//)#i', $v))
|
||||
{
|
||||
if ($index_page === TRUE)
|
||||
{
|
||||
$img .= ' src="'.get_instance()->config->site_url($v).'"';
|
||||
}
|
||||
else
|
||||
{
|
||||
$img .= ' src="'.get_instance()->config->base_url($v).'"';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$img .= ' '.$k.'="'.$v.'"';
|
||||
}
|
||||
}
|
||||
|
||||
return $img._stringify_attributes($attributes).' />';
|
||||
}
|
||||
return 'data:' . $mime . ';base64,' . $data;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
if (! function_exists('doctype')) {
|
||||
/**
|
||||
* Doctype
|
||||
*
|
||||
* Generates a page document type declaration
|
||||
*
|
||||
* Examples of valid options: html5, xhtml-11, xhtml-strict, xhtml-trans,
|
||||
* xhtml-frame, html4-strict, html4-trans, and html4-frame.
|
||||
* All values are saved in the doctypes config file.
|
||||
*
|
||||
* @param string $type The doctype to be generated
|
||||
*/
|
||||
function doctype(string $type = 'html5'): string
|
||||
{
|
||||
$config = new DocTypes();
|
||||
$doctypes = $config->list;
|
||||
|
||||
if ( ! function_exists('doctype'))
|
||||
{
|
||||
/**
|
||||
* Doctype
|
||||
*
|
||||
* Generates a page document type declaration
|
||||
*
|
||||
* Examples of valid options: html5, xhtml-11, xhtml-strict, xhtml-trans,
|
||||
* xhtml-frame, html4-strict, html4-trans, and html4-frame.
|
||||
* All values are saved in the doctypes config file.
|
||||
*
|
||||
* @param string type The doctype to be generated
|
||||
* @return string
|
||||
*/
|
||||
function doctype($type = 'xhtml1-strict')
|
||||
{
|
||||
static $doctypes;
|
||||
|
||||
if ( ! is_array($doctypes))
|
||||
{
|
||||
if (file_exists(APPPATH.'config/doctypes.php'))
|
||||
{
|
||||
include(APPPATH.'config/doctypes.php');
|
||||
}
|
||||
|
||||
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/doctypes.php'))
|
||||
{
|
||||
include(APPPATH.'config/'.ENVIRONMENT.'/doctypes.php');
|
||||
}
|
||||
|
||||
if (empty($_doctypes) OR ! is_array($_doctypes))
|
||||
{
|
||||
$doctypes = array();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$doctypes = $_doctypes;
|
||||
}
|
||||
|
||||
return isset($doctypes[$type]) ? $doctypes[$type] : FALSE;
|
||||
}
|
||||
return $doctypes[$type] ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
if (! function_exists('script_tag')) {
|
||||
/**
|
||||
* Script
|
||||
*
|
||||
* Generates link to a JS file
|
||||
*
|
||||
* @param array|string $src Script source or an array of attributes
|
||||
* @param bool $indexPage Should indexPage be added to the JS path
|
||||
*/
|
||||
function script_tag($src = '', bool $indexPage = false): string
|
||||
{
|
||||
$cspNonce = csp_script_nonce();
|
||||
$cspNonce = $cspNonce ? ' ' . $cspNonce : $cspNonce;
|
||||
$script = '<script' . $cspNonce . ' ';
|
||||
if (! is_array($src)) {
|
||||
$src = ['src' => $src];
|
||||
}
|
||||
|
||||
if ( ! function_exists('link_tag'))
|
||||
{
|
||||
/**
|
||||
* Link
|
||||
*
|
||||
* Generates link to a CSS file
|
||||
*
|
||||
* @param mixed stylesheet hrefs or an array
|
||||
* @param string rel
|
||||
* @param string type
|
||||
* @param string title
|
||||
* @param string media
|
||||
* @param bool should index_page be added to the css path
|
||||
* @return string
|
||||
*/
|
||||
function link_tag($href = '', $rel = 'stylesheet', $type = 'text/css', $title = '', $media = '', $index_page = FALSE)
|
||||
{
|
||||
$CI =& get_instance();
|
||||
$link = '<link ';
|
||||
foreach ($src as $k => $v) {
|
||||
if ($k === 'src' && ! preg_match('#^([a-z]+:)?//#i', $v)) {
|
||||
if ($indexPage === true) {
|
||||
$script .= 'src="' . site_url($v) . '" ';
|
||||
} else {
|
||||
$script .= 'src="' . slash_item('baseURL') . $v . '" ';
|
||||
}
|
||||
} else {
|
||||
// for attributes without values, like async or defer, use NULL.
|
||||
$script .= $k . (null === $v ? ' ' : '="' . $v . '" ');
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($href))
|
||||
{
|
||||
foreach ($href as $k => $v)
|
||||
{
|
||||
if ($k === 'href' && ! preg_match('#^([a-z]+:)?//#i', $v))
|
||||
{
|
||||
if ($index_page === TRUE)
|
||||
{
|
||||
$link .= 'href="'.$CI->config->site_url($v).'" ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$link .= 'href="'.$CI->config->base_url($v).'" ';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$link .= $k.'="'.$v.'" ';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (preg_match('#^([a-z]+:)?//#i', $href))
|
||||
{
|
||||
$link .= 'href="'.$href.'" ';
|
||||
}
|
||||
elseif ($index_page === TRUE)
|
||||
{
|
||||
$link .= 'href="'.$CI->config->site_url($href).'" ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$link .= 'href="'.$CI->config->base_url($href).'" ';
|
||||
}
|
||||
|
||||
$link .= 'rel="'.$rel.'" type="'.$type.'" ';
|
||||
|
||||
if ($media !== '')
|
||||
{
|
||||
$link .= 'media="'.$media.'" ';
|
||||
}
|
||||
|
||||
if ($title !== '')
|
||||
{
|
||||
$link .= 'title="'.$title.'" ';
|
||||
}
|
||||
}
|
||||
|
||||
return $link."/>\n";
|
||||
}
|
||||
return $script . 'type="text/javascript"></script>';
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
if (! function_exists('link_tag')) {
|
||||
/**
|
||||
* Link
|
||||
*
|
||||
* Generates link to a CSS file
|
||||
*
|
||||
* @param array|string $href Stylesheet href or an array
|
||||
* @param bool $indexPage should indexPage be added to the CSS path.
|
||||
*/
|
||||
function link_tag($href = '', string $rel = 'stylesheet', string $type = 'text/css', string $title = '', string $media = '', bool $indexPage = false, string $hreflang = ''): string
|
||||
{
|
||||
$link = '<link ';
|
||||
|
||||
if ( ! function_exists('meta'))
|
||||
{
|
||||
/**
|
||||
* Generates meta tags from an array of key/values
|
||||
*
|
||||
* @param array
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function meta($name = '', $content = '', $type = 'name', $newline = "\n")
|
||||
{
|
||||
// Since we allow the data to be passes as a string, a simple array
|
||||
// or a multidimensional one, we need to do a little prepping.
|
||||
if ( ! is_array($name))
|
||||
{
|
||||
$name = array(array('name' => $name, 'content' => $content, 'type' => $type, 'newline' => $newline));
|
||||
}
|
||||
elseif (isset($name['name']))
|
||||
{
|
||||
// Turn single array into multidimensional
|
||||
$name = array($name);
|
||||
}
|
||||
// extract fields if needed
|
||||
if (is_array($href)) {
|
||||
$rel = $href['rel'] ?? $rel;
|
||||
$type = $href['type'] ?? $type;
|
||||
$title = $href['title'] ?? $title;
|
||||
$media = $href['media'] ?? $media;
|
||||
$hreflang = $href['hreflang'] ?? '';
|
||||
$indexPage = $href['indexPage'] ?? $indexPage;
|
||||
$href = $href['href'] ?? '';
|
||||
}
|
||||
|
||||
$str = '';
|
||||
foreach ($name as $meta)
|
||||
{
|
||||
$type = (isset($meta['type']) && $meta['type'] !== 'name') ? 'http-equiv' : 'name';
|
||||
$name = isset($meta['name']) ? $meta['name'] : '';
|
||||
$content = isset($meta['content']) ? $meta['content'] : '';
|
||||
$newline = isset($meta['newline']) ? $meta['newline'] : "\n";
|
||||
if (! preg_match('#^([a-z]+:)?//#i', $href)) {
|
||||
if ($indexPage === true) {
|
||||
$link .= 'href="' . site_url($href) . '" ';
|
||||
} else {
|
||||
$link .= 'href="' . slash_item('baseURL') . $href . '" ';
|
||||
}
|
||||
} else {
|
||||
$link .= 'href="' . $href . '" ';
|
||||
}
|
||||
|
||||
$str .= '<meta '.$type.'="'.$name.'" content="'.$content.'" />'.$newline;
|
||||
}
|
||||
if ($hreflang !== '') {
|
||||
$link .= 'hreflang="' . $hreflang . '" ';
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
$link .= 'rel="' . $rel . '" ';
|
||||
|
||||
if (! in_array($rel, ['alternate', 'canonical'], true)) {
|
||||
$link .= 'type="' . $type . '" ';
|
||||
}
|
||||
|
||||
if ($media !== '') {
|
||||
$link .= 'media="' . $media . '" ';
|
||||
}
|
||||
|
||||
if ($title !== '') {
|
||||
$link .= 'title="' . $title . '" ';
|
||||
}
|
||||
|
||||
return $link . '/>';
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
if (! function_exists('video')) {
|
||||
/**
|
||||
* Video
|
||||
*
|
||||
* Generates a video element to embed videos. The video element can
|
||||
* contain one or more video sources
|
||||
*
|
||||
* @param array|string $src Either a source string or an array of sources
|
||||
* @param string $unsupportedMessage The message to display if the media tag is not supported by the browser
|
||||
* @param string $attributes HTML attributes
|
||||
*/
|
||||
function video($src, string $unsupportedMessage = '', string $attributes = '', array $tracks = [], bool $indexPage = false): string
|
||||
{
|
||||
if (is_array($src)) {
|
||||
return _media('video', $src, $unsupportedMessage, $attributes, $tracks);
|
||||
}
|
||||
|
||||
if ( ! function_exists('br'))
|
||||
{
|
||||
/**
|
||||
* Generates HTML BR tags based on number supplied
|
||||
*
|
||||
* @deprecated 3.0.0 Use str_repeat() instead
|
||||
* @param int $count Number of times to repeat the tag
|
||||
* @return string
|
||||
*/
|
||||
function br($count = 1)
|
||||
{
|
||||
return str_repeat('<br />', $count);
|
||||
}
|
||||
$video = '<video';
|
||||
|
||||
if (_has_protocol($src)) {
|
||||
$video .= ' src="' . $src . '"';
|
||||
} elseif ($indexPage === true) {
|
||||
$video .= ' src="' . site_url($src) . '"';
|
||||
} else {
|
||||
$video .= ' src="' . slash_item('baseURL') . $src . '"';
|
||||
}
|
||||
|
||||
if ($attributes !== '') {
|
||||
$video .= ' ' . $attributes;
|
||||
}
|
||||
|
||||
$video .= ">\n";
|
||||
|
||||
foreach ($tracks as $track) {
|
||||
$video .= _space_indent() . $track . "\n";
|
||||
}
|
||||
|
||||
if (! empty($unsupportedMessage)) {
|
||||
$video .= _space_indent()
|
||||
. $unsupportedMessage
|
||||
. "\n";
|
||||
}
|
||||
|
||||
return $video . "</video>\n";
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
if (! function_exists('audio')) {
|
||||
/**
|
||||
* Audio
|
||||
*
|
||||
* Generates an audio element to embed sounds
|
||||
*
|
||||
* @param array|string $src Either a source string or an array of sources
|
||||
* @param string $unsupportedMessage The message to display if the media tag is not supported by the browser.
|
||||
* @param string $attributes HTML attributes
|
||||
*/
|
||||
function audio($src, string $unsupportedMessage = '', string $attributes = '', array $tracks = [], bool $indexPage = false): string
|
||||
{
|
||||
if (is_array($src)) {
|
||||
return _media('audio', $src, $unsupportedMessage, $attributes, $tracks);
|
||||
}
|
||||
|
||||
if ( ! function_exists('nbs'))
|
||||
{
|
||||
/**
|
||||
* Generates non-breaking space entities based on number supplied
|
||||
*
|
||||
* @deprecated 3.0.0 Use str_repeat() instead
|
||||
* @param int
|
||||
* @return string
|
||||
*/
|
||||
function nbs($num = 1)
|
||||
{
|
||||
return str_repeat(' ', $num);
|
||||
}
|
||||
$audio = '<audio';
|
||||
|
||||
if (_has_protocol($src)) {
|
||||
$audio .= ' src="' . $src . '"';
|
||||
} elseif ($indexPage === true) {
|
||||
$audio .= ' src="' . site_url($src) . '"';
|
||||
} else {
|
||||
$audio .= ' src="' . slash_item('baseURL') . $src . '"';
|
||||
}
|
||||
|
||||
if ($attributes !== '') {
|
||||
$audio .= ' ' . $attributes;
|
||||
}
|
||||
|
||||
$audio .= '>';
|
||||
|
||||
foreach ($tracks as $track) {
|
||||
$audio .= "\n" . _space_indent() . $track;
|
||||
}
|
||||
|
||||
if (! empty($unsupportedMessage)) {
|
||||
$audio .= "\n" . _space_indent() . $unsupportedMessage . "\n";
|
||||
}
|
||||
|
||||
return $audio . "</audio>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('_media')) {
|
||||
/**
|
||||
* Generate media based tag
|
||||
*
|
||||
* @param string $unsupportedMessage The message to display if the media tag is not supported by the browser.
|
||||
*/
|
||||
function _media(string $name, array $types = [], string $unsupportedMessage = '', string $attributes = '', array $tracks = []): string
|
||||
{
|
||||
$media = '<' . $name;
|
||||
|
||||
if (empty($attributes)) {
|
||||
$media .= '>';
|
||||
} else {
|
||||
$media .= ' ' . $attributes . '>';
|
||||
}
|
||||
|
||||
$media .= "\n";
|
||||
|
||||
foreach ($types as $option) {
|
||||
$media .= _space_indent() . $option . "\n";
|
||||
}
|
||||
|
||||
foreach ($tracks as $track) {
|
||||
$media .= _space_indent() . $track . "\n";
|
||||
}
|
||||
|
||||
if (! empty($unsupportedMessage)) {
|
||||
$media .= _space_indent() . $unsupportedMessage . "\n";
|
||||
}
|
||||
|
||||
return $media . ('</' . $name . ">\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('source')) {
|
||||
/**
|
||||
* Source
|
||||
*
|
||||
* Generates a source element that specifies multiple media resources
|
||||
* for either audio or video element
|
||||
*
|
||||
* @param string $src The path of the media resource
|
||||
* @param string $type The MIME-type of the resource with optional codecs parameters
|
||||
* @param string $attributes HTML attributes
|
||||
*/
|
||||
function source(string $src, string $type = 'unknown', string $attributes = '', bool $indexPage = false): string
|
||||
{
|
||||
if (! _has_protocol($src)) {
|
||||
$src = $indexPage === true ? site_url($src) : slash_item('baseURL') . $src;
|
||||
}
|
||||
|
||||
$source = '<source src="' . $src
|
||||
. '" type="' . $type . '"';
|
||||
|
||||
if (! empty($attributes)) {
|
||||
$source .= ' ' . $attributes;
|
||||
}
|
||||
|
||||
return $source . ' />';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('track')) {
|
||||
/**
|
||||
* Track
|
||||
*
|
||||
* Generates a track element to specify timed tracks. The tracks are
|
||||
* formatted in WebVTT format.
|
||||
*
|
||||
* @param string $src The path of the .VTT file
|
||||
*/
|
||||
function track(string $src, string $kind, string $srcLanguage, string $label): string
|
||||
{
|
||||
return '<track src="' . $src
|
||||
. '" kind="' . $kind
|
||||
. '" srclang="' . $srcLanguage
|
||||
. '" label="' . $label
|
||||
. '" />';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('object')) {
|
||||
/**
|
||||
* Object
|
||||
*
|
||||
* Generates an object element that represents the media
|
||||
* as either image or a resource plugin such as audio, video,
|
||||
* Java applets, ActiveX, PDF and Flash
|
||||
*
|
||||
* @param string $data A resource URL
|
||||
* @param string $type Content-type of the resource
|
||||
* @param string $attributes HTML attributes
|
||||
*/
|
||||
function object(string $data, string $type = 'unknown', string $attributes = '', array $params = [], bool $indexPage = false): string
|
||||
{
|
||||
if (! _has_protocol($data)) {
|
||||
$data = $indexPage === true ? site_url($data) : slash_item('baseURL') . $data;
|
||||
}
|
||||
|
||||
$object = '<object data="' . $data . '" '
|
||||
. $attributes . '>';
|
||||
|
||||
if (! empty($params)) {
|
||||
$object .= "\n";
|
||||
}
|
||||
|
||||
foreach ($params as $param) {
|
||||
$object .= _space_indent() . $param . "\n";
|
||||
}
|
||||
|
||||
return $object . "</object>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('param')) {
|
||||
/**
|
||||
* Param
|
||||
*
|
||||
* Generates a param element that defines parameters
|
||||
* for the object element.
|
||||
*
|
||||
* @param string $name The name of the parameter
|
||||
* @param string $value The value of the parameter
|
||||
* @param string $type The MIME-type
|
||||
* @param string $attributes HTML attributes
|
||||
*/
|
||||
function param(string $name, string $value, string $type = 'ref', string $attributes = ''): string
|
||||
{
|
||||
return '<param name="' . $name
|
||||
. '" type="' . $type
|
||||
. '" value="' . $value
|
||||
. '" ' . $attributes . ' />';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('embed')) {
|
||||
/**
|
||||
* Embed
|
||||
*
|
||||
* Generates an embed element
|
||||
*
|
||||
* @param string $src The path of the resource to embed
|
||||
* @param string $type MIME-type
|
||||
* @param string $attributes HTML attributes
|
||||
*/
|
||||
function embed(string $src, string $type = 'unknown', string $attributes = '', bool $indexPage = false): string
|
||||
{
|
||||
if (! _has_protocol($src)) {
|
||||
$src = $indexPage === true ? site_url($src) : slash_item('baseURL') . $src;
|
||||
}
|
||||
|
||||
return '<embed src="' . $src
|
||||
. '" type="' . $type . '" '
|
||||
. $attributes . " />\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('_has_protocol')) {
|
||||
/**
|
||||
* Test the protocol of a URI.
|
||||
*
|
||||
* @return false|int
|
||||
*/
|
||||
function _has_protocol(string $url)
|
||||
{
|
||||
return preg_match('#^([a-z]+:)?//#i', $url);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('_space_indent')) {
|
||||
/**
|
||||
* Provide space indenting.
|
||||
*/
|
||||
function _space_indent(int $depth = 2): string
|
||||
{
|
||||
return str_repeat(' ', $depth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Regular → Executable
+291
-257
@@ -1,288 +1,322 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Inflector Helpers
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/inflector_helper.html
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// CodeIgniter Inflector Helpers
|
||||
|
||||
if ( ! function_exists('singular'))
|
||||
{
|
||||
/**
|
||||
* Singular
|
||||
*
|
||||
* Takes a plural word and makes it singular
|
||||
*
|
||||
* @param string $str Input string
|
||||
* @return string
|
||||
*/
|
||||
function singular($str)
|
||||
{
|
||||
$result = strval($str);
|
||||
if (! function_exists('singular')) {
|
||||
/**
|
||||
* Singular
|
||||
*
|
||||
* Takes a plural word and makes it singular
|
||||
*
|
||||
* @param string $string Input string
|
||||
*/
|
||||
function singular(string $string): string
|
||||
{
|
||||
$result = $string;
|
||||
|
||||
if ( ! word_is_countable($result))
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
if (! is_pluralizable($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$singular_rules = array(
|
||||
'/(matr)ices$/' => '\1ix',
|
||||
'/(vert|ind)ices$/' => '\1ex',
|
||||
'/^(ox)en/' => '\1',
|
||||
'/(alias)es$/' => '\1',
|
||||
'/([octop|vir])i$/' => '\1us',
|
||||
'/(cris|ax|test)es$/' => '\1is',
|
||||
'/(shoe)s$/' => '\1',
|
||||
'/(o)es$/' => '\1',
|
||||
'/(bus|campus)es$/' => '\1',
|
||||
'/([m|l])ice$/' => '\1ouse',
|
||||
'/(x|ch|ss|sh)es$/' => '\1',
|
||||
'/(m)ovies$/' => '\1\2ovie',
|
||||
'/(s)eries$/' => '\1\2eries',
|
||||
'/([^aeiouy]|qu)ies$/' => '\1y',
|
||||
'/([lr])ves$/' => '\1f',
|
||||
'/(tive)s$/' => '\1',
|
||||
'/(hive)s$/' => '\1',
|
||||
'/([^f])ves$/' => '\1fe',
|
||||
'/(^analy)ses$/' => '\1sis',
|
||||
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/' => '\1\2sis',
|
||||
'/([ti])a$/' => '\1um',
|
||||
'/(p)eople$/' => '\1\2erson',
|
||||
'/(m)en$/' => '\1an',
|
||||
'/(s)tatuses$/' => '\1\2tatus',
|
||||
'/(c)hildren$/' => '\1\2hild',
|
||||
'/(n)ews$/' => '\1\2ews',
|
||||
'/(quiz)zes$/' => '\1',
|
||||
'/([^us])s$/' => '\1'
|
||||
);
|
||||
// Arranged in order.
|
||||
$singularRules = [
|
||||
'/(matr)ices$/' => '\1ix',
|
||||
'/(vert|ind)ices$/' => '\1ex',
|
||||
'/^(ox)en/' => '\1',
|
||||
'/(alias)es$/' => '\1',
|
||||
'/([octop|vir])i$/' => '\1us',
|
||||
'/(cris|ax|test)es$/' => '\1is',
|
||||
'/(shoe)s$/' => '\1',
|
||||
'/(o)es$/' => '\1',
|
||||
'/(bus|campus)es$/' => '\1',
|
||||
'/([m|l])ice$/' => '\1ouse',
|
||||
'/(x|ch|ss|sh)es$/' => '\1',
|
||||
'/(m)ovies$/' => '\1\2ovie',
|
||||
'/(s)eries$/' => '\1\2eries',
|
||||
'/([^aeiouy]|qu)ies$/' => '\1y',
|
||||
'/([lr])ves$/' => '\1f',
|
||||
'/(tive)s$/' => '\1',
|
||||
'/(hive)s$/' => '\1',
|
||||
'/([^f])ves$/' => '\1fe',
|
||||
'/(^analy)ses$/' => '\1sis',
|
||||
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/' => '\1\2sis',
|
||||
'/([ti])a$/' => '\1um',
|
||||
'/(p)eople$/' => '\1\2erson',
|
||||
'/(m)en$/' => '\1an',
|
||||
'/(s)tatuses$/' => '\1\2tatus',
|
||||
'/(c)hildren$/' => '\1\2hild',
|
||||
'/(n)ews$/' => '\1\2ews',
|
||||
'/(quiz)zes$/' => '\1',
|
||||
'/([^us])s$/' => '\1',
|
||||
];
|
||||
|
||||
foreach ($singular_rules as $rule => $replacement)
|
||||
{
|
||||
if (preg_match($rule, $result))
|
||||
{
|
||||
$result = preg_replace($rule, $replacement, $result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach ($singularRules as $rule => $replacement) {
|
||||
if (preg_match($rule, $result)) {
|
||||
$result = preg_replace($rule, $replacement, $result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
if (! function_exists('plural')) {
|
||||
/**
|
||||
* Plural
|
||||
*
|
||||
* Takes a singular word and makes it plural
|
||||
*
|
||||
* @param string $string Input string
|
||||
*/
|
||||
function plural(string $string): string
|
||||
{
|
||||
$result = $string;
|
||||
|
||||
if ( ! function_exists('plural'))
|
||||
{
|
||||
/**
|
||||
* Plural
|
||||
*
|
||||
* Takes a singular word and makes it plural
|
||||
*
|
||||
* @param string $str Input string
|
||||
* @return string
|
||||
*/
|
||||
function plural($str)
|
||||
{
|
||||
$result = strval($str);
|
||||
if (! is_pluralizable($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ( ! word_is_countable($result))
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
$pluralRules = [
|
||||
'/(quiz)$/' => '\1zes', // quizzes
|
||||
'/^(ox)$/' => '\1\2en', // ox
|
||||
'/([m|l])ouse$/' => '\1ice', // mouse, louse
|
||||
'/(matr|vert|ind)ix|ex$/' => '\1ices', // matrix, vertex, index
|
||||
'/(x|ch|ss|sh)$/' => '\1es', // search, switch, fix, box, process, address
|
||||
'/([^aeiouy]|qu)y$/' => '\1ies', // query, ability, agency
|
||||
'/(hive)$/' => '\1s', // archive, hive
|
||||
'/(?:([^f])fe|([lr])f)$/' => '\1\2ves', // half, safe, wife
|
||||
'/sis$/' => 'ses', // basis, diagnosis
|
||||
'/([ti])um$/' => '\1a', // datum, medium
|
||||
'/(p)erson$/' => '\1eople', // person, salesperson
|
||||
'/(m)an$/' => '\1en', // man, woman, spokesman
|
||||
'/(c)hild$/' => '\1hildren', // child
|
||||
'/(buffal|tomat)o$/' => '\1\2oes', // buffalo, tomato
|
||||
'/(bu|campu)s$/' => '\1\2ses', // bus, campus
|
||||
'/(alias|status|virus)$/' => '\1es', // alias
|
||||
'/(octop)us$/' => '\1i', // octopus
|
||||
'/(ax|cris|test)is$/' => '\1es', // axis, crisis
|
||||
'/s$/' => 's', // no change (compatibility)
|
||||
'/$/' => 's',
|
||||
];
|
||||
|
||||
$plural_rules = array(
|
||||
'/(quiz)$/' => '\1zes', // quizzes
|
||||
'/^(ox)$/' => '\1\2en', // ox
|
||||
'/([m|l])ouse$/' => '\1ice', // mouse, louse
|
||||
'/(matr|vert|ind)ix|ex$/' => '\1ices', // matrix, vertex, index
|
||||
'/(x|ch|ss|sh)$/' => '\1es', // search, switch, fix, box, process, address
|
||||
'/([^aeiouy]|qu)y$/' => '\1ies', // query, ability, agency
|
||||
'/(hive)$/' => '\1s', // archive, hive
|
||||
'/(?:([^f])fe|([lr])f)$/' => '\1\2ves', // half, safe, wife
|
||||
'/sis$/' => 'ses', // basis, diagnosis
|
||||
'/([ti])um$/' => '\1a', // datum, medium
|
||||
'/(p)erson$/' => '\1eople', // person, salesperson
|
||||
'/(m)an$/' => '\1en', // man, woman, spokesman
|
||||
'/(c)hild$/' => '\1hildren', // child
|
||||
'/(buffal|tomat)o$/' => '\1\2oes', // buffalo, tomato
|
||||
'/(bu|campu)s$/' => '\1\2ses', // bus, campus
|
||||
'/(alias|status|virus)$/' => '\1es', // alias
|
||||
'/(octop)us$/' => '\1i', // octopus
|
||||
'/(ax|cris|test)is$/' => '\1es', // axis, crisis
|
||||
'/s$/' => 's', // no change (compatibility)
|
||||
'/$/' => 's',
|
||||
);
|
||||
foreach ($pluralRules as $rule => $replacement) {
|
||||
if (preg_match($rule, $result)) {
|
||||
$result = preg_replace($rule, $replacement, $result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($plural_rules as $rule => $replacement)
|
||||
{
|
||||
if (preg_match($rule, $result))
|
||||
{
|
||||
$result = preg_replace($rule, $replacement, $result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
if (! function_exists('counted')) {
|
||||
/**
|
||||
* Counted
|
||||
*
|
||||
* Takes a number and a word to return the plural or not
|
||||
* E.g. 0 cats, 1 cat, 2 cats, ...
|
||||
*
|
||||
* @param int $count Number of items
|
||||
* @param string $string Input string
|
||||
*/
|
||||
function counted(int $count, string $string): string
|
||||
{
|
||||
$result = "{$count} ";
|
||||
|
||||
if ( ! function_exists('camelize'))
|
||||
{
|
||||
/**
|
||||
* Camelize
|
||||
*
|
||||
* Takes multiple words separated by spaces or underscores and camelizes them
|
||||
*
|
||||
* @param string $str Input string
|
||||
* @return string
|
||||
*/
|
||||
function camelize($str)
|
||||
{
|
||||
return strtolower($str[0]).substr(str_replace(' ', '', ucwords(preg_replace('/[\s_]+/', ' ', $str))), 1);
|
||||
}
|
||||
return $result . ($count === 1 ? singular($string) : plural($string));
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('underscore'))
|
||||
{
|
||||
/**
|
||||
* Underscore
|
||||
*
|
||||
* Takes multiple words separated by spaces and underscores them
|
||||
*
|
||||
* @param string $str Input string
|
||||
* @return string
|
||||
*/
|
||||
function underscore($str)
|
||||
{
|
||||
return preg_replace('/[\s]+/', '_', trim(MB_ENABLED ? mb_strtolower($str) : strtolower($str)));
|
||||
}
|
||||
if (! function_exists('camelize')) {
|
||||
/**
|
||||
* Camelize
|
||||
*
|
||||
* Takes multiple words separated by spaces or
|
||||
* underscores and converts them to camel case.
|
||||
*
|
||||
* @param string $string Input string
|
||||
*/
|
||||
function camelize(string $string): string
|
||||
{
|
||||
return lcfirst(str_replace(' ', '', ucwords(preg_replace('/[\s_]+/', ' ', $string))));
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('humanize'))
|
||||
{
|
||||
/**
|
||||
* Humanize
|
||||
*
|
||||
* Takes multiple words separated by the separator and changes them to spaces
|
||||
*
|
||||
* @param string $str Input string
|
||||
* @param string $separator Input separator
|
||||
* @return string
|
||||
*/
|
||||
function humanize($str, $separator = '_')
|
||||
{
|
||||
return ucwords(preg_replace('/['.preg_quote($separator).']+/', ' ', trim(MB_ENABLED ? mb_strtolower($str) : strtolower($str))));
|
||||
}
|
||||
if (! function_exists('pascalize')) {
|
||||
/**
|
||||
* Pascalize
|
||||
*
|
||||
* Takes multiple words separated by spaces or
|
||||
* underscores and converts them to Pascal case,
|
||||
* which is camel case with an uppercase first letter.
|
||||
*
|
||||
* @param string $string Input string
|
||||
*/
|
||||
function pascalize(string $string): string
|
||||
{
|
||||
return ucfirst(camelize($string));
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
if (! function_exists('underscore')) {
|
||||
/**
|
||||
* Underscore
|
||||
*
|
||||
* Takes multiple words separated by spaces and underscores them
|
||||
*
|
||||
* @param string $string Input string
|
||||
*/
|
||||
function underscore(string $string): string
|
||||
{
|
||||
$replacement = trim($string);
|
||||
|
||||
if ( ! function_exists('word_is_countable'))
|
||||
{
|
||||
/**
|
||||
* Checks if the given word has a plural version.
|
||||
*
|
||||
* @param string $word Word to check
|
||||
* @return bool
|
||||
*/
|
||||
function word_is_countable($word)
|
||||
{
|
||||
return ! in_array(
|
||||
strtolower($word),
|
||||
array(
|
||||
'audio',
|
||||
'bison',
|
||||
'chassis',
|
||||
'compensation',
|
||||
'coreopsis',
|
||||
'data',
|
||||
'deer',
|
||||
'education',
|
||||
'emoji',
|
||||
'equipment',
|
||||
'fish',
|
||||
'furniture',
|
||||
'gold',
|
||||
'information',
|
||||
'knowledge',
|
||||
'love',
|
||||
'rain',
|
||||
'money',
|
||||
'moose',
|
||||
'nutrition',
|
||||
'offspring',
|
||||
'plankton',
|
||||
'pokemon',
|
||||
'police',
|
||||
'rice',
|
||||
'series',
|
||||
'sheep',
|
||||
'species',
|
||||
'swine',
|
||||
'traffic',
|
||||
'wheat'
|
||||
)
|
||||
);
|
||||
}
|
||||
return preg_replace('/[\s]+/', '_', $replacement);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
if (! function_exists('humanize')) {
|
||||
/**
|
||||
* Humanize
|
||||
*
|
||||
* Takes multiple words separated by the separator,
|
||||
* camelizes and changes them to spaces
|
||||
*
|
||||
* @param string $string Input string
|
||||
* @param string $separator Input separator
|
||||
*/
|
||||
function humanize(string $string, string $separator = '_'): string
|
||||
{
|
||||
$replacement = trim($string);
|
||||
|
||||
if ( ! function_exists('is_countable'))
|
||||
{
|
||||
function is_countable($word)
|
||||
{
|
||||
trigger_error('is_countable() is a native PHP function since version 7.3.0; use word_is_countable() instead', E_USER_WARNING);
|
||||
return word_is_countable($word);
|
||||
}
|
||||
return ucwords(preg_replace('/[' . $separator . ']+/', ' ', $replacement));
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('is_pluralizable')) {
|
||||
/**
|
||||
* Checks if the given word has a plural version.
|
||||
*
|
||||
* @param string $word Word to check
|
||||
*/
|
||||
function is_pluralizable(string $word): bool
|
||||
{
|
||||
$uncountables = in_array(
|
||||
strtolower($word),
|
||||
[
|
||||
'advice',
|
||||
'bravery',
|
||||
'butter',
|
||||
'chaos',
|
||||
'clarity',
|
||||
'coal',
|
||||
'courage',
|
||||
'cowardice',
|
||||
'curiosity',
|
||||
'education',
|
||||
'equipment',
|
||||
'evidence',
|
||||
'fish',
|
||||
'fun',
|
||||
'furniture',
|
||||
'greed',
|
||||
'help',
|
||||
'homework',
|
||||
'honesty',
|
||||
'information',
|
||||
'insurance',
|
||||
'jewelry',
|
||||
'knowledge',
|
||||
'livestock',
|
||||
'love',
|
||||
'luck',
|
||||
'marketing',
|
||||
'meta',
|
||||
'money',
|
||||
'mud',
|
||||
'news',
|
||||
'patriotism',
|
||||
'racism',
|
||||
'rice',
|
||||
'satisfaction',
|
||||
'scenery',
|
||||
'series',
|
||||
'sexism',
|
||||
'silence',
|
||||
'species',
|
||||
'spelling',
|
||||
'sugar',
|
||||
'water',
|
||||
'weather',
|
||||
'wisdom',
|
||||
'work',
|
||||
],
|
||||
true
|
||||
);
|
||||
|
||||
return ! $uncountables;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('dasherize')) {
|
||||
/**
|
||||
* Replaces underscores with dashes in the string.
|
||||
*
|
||||
* @param string $string Input string
|
||||
*/
|
||||
function dasherize(string $string): string
|
||||
{
|
||||
return str_replace('_', '-', $string);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('ordinal')) {
|
||||
/**
|
||||
* Returns the suffix that should be added to a
|
||||
* number to denote the position in an ordered
|
||||
* sequence such as 1st, 2nd, 3rd, 4th.
|
||||
*
|
||||
* @param int $integer The integer to determine the suffix
|
||||
*/
|
||||
function ordinal(int $integer): string
|
||||
{
|
||||
$suffixes = [
|
||||
'th',
|
||||
'st',
|
||||
'nd',
|
||||
'rd',
|
||||
'th',
|
||||
'th',
|
||||
'th',
|
||||
'th',
|
||||
'th',
|
||||
'th',
|
||||
];
|
||||
|
||||
return $integer % 100 >= 11 && $integer % 100 <= 13 ? 'th' : $suffixes[$integer % 10];
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('ordinalize')) {
|
||||
/**
|
||||
* Turns a number into an ordinal string used
|
||||
* to denote the position in an ordered sequence
|
||||
* such as 1st, 2nd, 3rd, 4th.
|
||||
*
|
||||
* @param int $integer The integer to ordinalize
|
||||
*/
|
||||
function ordinalize(int $integer): string
|
||||
{
|
||||
return $integer . ordinal($integer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Language Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/language_helper.html
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('lang'))
|
||||
{
|
||||
/**
|
||||
* Lang
|
||||
*
|
||||
* Fetches a language variable and optionally outputs a form label
|
||||
*
|
||||
* @param string $line The language line
|
||||
* @param string $for The "for" value (id of the form element)
|
||||
* @param array $attributes Any additional HTML attributes
|
||||
* @return string
|
||||
*/
|
||||
function lang($line, $for = '', $attributes = array())
|
||||
{
|
||||
$line = get_instance()->lang->line($line);
|
||||
|
||||
if ($for !== '')
|
||||
{
|
||||
$line = '<label for="'.$for.'"'._stringify_attributes($attributes).'>'.$line.'</label>';
|
||||
}
|
||||
|
||||
return $line;
|
||||
}
|
||||
}
|
||||
@@ -1,95 +1,212 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Number Helpers
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/number_helper.html
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// CodeIgniter Number Helpers
|
||||
|
||||
if ( ! function_exists('byte_format'))
|
||||
{
|
||||
/**
|
||||
* Formats a numbers as bytes, based on size, and adds the appropriate suffix
|
||||
*
|
||||
* @param mixed will be cast as int
|
||||
* @param int
|
||||
* @return string
|
||||
*/
|
||||
function byte_format($num, $precision = 1)
|
||||
{
|
||||
$CI =& get_instance();
|
||||
$CI->lang->load('number');
|
||||
if (! function_exists('number_to_size')) {
|
||||
/**
|
||||
* Formats a numbers as bytes, based on size, and adds the appropriate suffix
|
||||
*
|
||||
* @param mixed $num Will be cast as int
|
||||
* @param string $locale
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
function number_to_size($num, int $precision = 1, ?string $locale = null)
|
||||
{
|
||||
// Strip any formatting & ensure numeric input
|
||||
try {
|
||||
$num = 0 + str_replace(',', '', $num);
|
||||
} catch (ErrorException $ee) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($num >= 1000000000000)
|
||||
{
|
||||
$num = round($num / 1099511627776, $precision);
|
||||
$unit = $CI->lang->line('terabyte_abbr');
|
||||
}
|
||||
elseif ($num >= 1000000000)
|
||||
{
|
||||
$num = round($num / 1073741824, $precision);
|
||||
$unit = $CI->lang->line('gigabyte_abbr');
|
||||
}
|
||||
elseif ($num >= 1000000)
|
||||
{
|
||||
$num = round($num / 1048576, $precision);
|
||||
$unit = $CI->lang->line('megabyte_abbr');
|
||||
}
|
||||
elseif ($num >= 1000)
|
||||
{
|
||||
$num = round($num / 1024, $precision);
|
||||
$unit = $CI->lang->line('kilobyte_abbr');
|
||||
}
|
||||
else
|
||||
{
|
||||
$unit = $CI->lang->line('bytes');
|
||||
return number_format($num).' '.$unit;
|
||||
}
|
||||
// ignore sub part
|
||||
$generalLocale = $locale;
|
||||
if (! empty($locale) && ($underscorePos = strpos($locale, '_'))) {
|
||||
$generalLocale = substr($locale, 0, $underscorePos);
|
||||
}
|
||||
|
||||
return number_format($num, $precision).' '.$unit;
|
||||
}
|
||||
if ($num >= 1_000_000_000_000) {
|
||||
$num = round($num / 1_099_511_627_776, $precision);
|
||||
$unit = lang('Number.terabyteAbbr', [], $generalLocale);
|
||||
} elseif ($num >= 1_000_000_000) {
|
||||
$num = round($num / 1_073_741_824, $precision);
|
||||
$unit = lang('Number.gigabyteAbbr', [], $generalLocale);
|
||||
} elseif ($num >= 1_000_000) {
|
||||
$num = round($num / 1_048_576, $precision);
|
||||
$unit = lang('Number.megabyteAbbr', [], $generalLocale);
|
||||
} elseif ($num >= 1000) {
|
||||
$num = round($num / 1024, $precision);
|
||||
$unit = lang('Number.kilobyteAbbr', [], $generalLocale);
|
||||
} else {
|
||||
$unit = lang('Number.bytes', [], $generalLocale);
|
||||
}
|
||||
|
||||
return format_number($num, $precision, $locale, ['after' => ' ' . $unit]);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('number_to_amount')) {
|
||||
/**
|
||||
* Converts numbers to a more readable representation
|
||||
* when dealing with very large numbers (in the thousands or above),
|
||||
* up to the quadrillions, because you won't often deal with numbers
|
||||
* larger than that.
|
||||
*
|
||||
* It uses the "short form" numbering system as this is most commonly
|
||||
* used within most English-speaking countries today.
|
||||
*
|
||||
* @see https://simple.wikipedia.org/wiki/Names_for_large_numbers
|
||||
*
|
||||
* @param string $num
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
function number_to_amount($num, int $precision = 0, ?string $locale = null)
|
||||
{
|
||||
// Strip any formatting & ensure numeric input
|
||||
try {
|
||||
$num = 0 + str_replace(',', '', $num);
|
||||
} catch (ErrorException $ee) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$suffix = '';
|
||||
|
||||
// ignore sub part
|
||||
$generalLocale = $locale;
|
||||
if (! empty($locale) && ($underscorePos = strpos($locale, '_'))) {
|
||||
$generalLocale = substr($locale, 0, $underscorePos);
|
||||
}
|
||||
|
||||
if ($num > 1_000_000_000_000_000) {
|
||||
$suffix = lang('Number.quadrillion', [], $generalLocale);
|
||||
$num = round(($num / 1_000_000_000_000_000), $precision);
|
||||
} elseif ($num > 1_000_000_000_000) {
|
||||
$suffix = lang('Number.trillion', [], $generalLocale);
|
||||
$num = round(($num / 1_000_000_000_000), $precision);
|
||||
} elseif ($num > 1_000_000_000) {
|
||||
$suffix = lang('Number.billion', [], $generalLocale);
|
||||
$num = round(($num / 1_000_000_000), $precision);
|
||||
} elseif ($num > 1_000_000) {
|
||||
$suffix = lang('Number.million', [], $generalLocale);
|
||||
$num = round(($num / 1_000_000), $precision);
|
||||
} elseif ($num > 1000) {
|
||||
$suffix = lang('Number.thousand', [], $generalLocale);
|
||||
$num = round(($num / 1000), $precision);
|
||||
}
|
||||
|
||||
return format_number($num, $precision, $locale, ['after' => $suffix]);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('number_to_currency')) {
|
||||
function number_to_currency(float $num, string $currency, ?string $locale = null, int $fraction = 0): string
|
||||
{
|
||||
return format_number($num, 1, $locale, [
|
||||
'type' => NumberFormatter::CURRENCY,
|
||||
'currency' => $currency,
|
||||
'fraction' => $fraction,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('format_number')) {
|
||||
/**
|
||||
* A general purpose, locale-aware, number_format method.
|
||||
* Used by all of the functions of the number_helper.
|
||||
*/
|
||||
function format_number(float $num, int $precision = 1, ?string $locale = null, array $options = []): string
|
||||
{
|
||||
// If locale is not passed, get from the default locale that is set from our config file
|
||||
// or set by HTTP content negotiation.
|
||||
$locale ??= Locale::getDefault();
|
||||
|
||||
// Type can be any of the NumberFormatter options, but provide a default.
|
||||
$type = (int) ($options['type'] ?? NumberFormatter::DECIMAL);
|
||||
|
||||
$formatter = new NumberFormatter($locale, $type);
|
||||
|
||||
// Try to format it per the locale
|
||||
if ($type === NumberFormatter::CURRENCY) {
|
||||
$formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $options['fraction']);
|
||||
$output = $formatter->formatCurrency($num, $options['currency']);
|
||||
} else {
|
||||
// In order to specify a precision, we'll have to modify
|
||||
// the pattern used by NumberFormatter.
|
||||
$pattern = '#,##0.' . str_repeat('#', $precision);
|
||||
|
||||
$formatter->setPattern($pattern);
|
||||
$output = $formatter->format($num);
|
||||
}
|
||||
|
||||
// This might lead a trailing period if $precision == 0
|
||||
$output = trim($output, '. ');
|
||||
|
||||
if (intl_is_failure($formatter->getErrorCode())) {
|
||||
throw new BadFunctionCallException($formatter->getErrorMessage());
|
||||
}
|
||||
|
||||
// Add on any before/after text.
|
||||
if (isset($options['before']) && is_string($options['before'])) {
|
||||
$output = $options['before'] . $output;
|
||||
}
|
||||
|
||||
if (isset($options['after']) && is_string($options['after'])) {
|
||||
$output .= $options['after'];
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('number_to_roman')) {
|
||||
/**
|
||||
* Convert a number to a roman numeral.
|
||||
*
|
||||
* @param string $num it will convert to int
|
||||
*/
|
||||
function number_to_roman(string $num): ?string
|
||||
{
|
||||
static $map = [
|
||||
'M' => 1000,
|
||||
'CM' => 900,
|
||||
'D' => 500,
|
||||
'CD' => 400,
|
||||
'C' => 100,
|
||||
'XC' => 90,
|
||||
'L' => 50,
|
||||
'XL' => 40,
|
||||
'X' => 10,
|
||||
'IX' => 9,
|
||||
'V' => 5,
|
||||
'IV' => 4,
|
||||
'I' => 1,
|
||||
];
|
||||
|
||||
$num = (int) $num;
|
||||
|
||||
if ($num < 1 || $num > 3999) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$result = '';
|
||||
|
||||
foreach ($map as $roman => $arabic) {
|
||||
$repeat = (int) floor($num / $arabic);
|
||||
$result .= str_repeat($roman, $repeat);
|
||||
$num %= $arabic;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Path Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/path_helper.html
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('set_realpath'))
|
||||
{
|
||||
/**
|
||||
* Set Realpath
|
||||
*
|
||||
* @param string
|
||||
* @param bool checks to see if the path exists
|
||||
* @return string
|
||||
*/
|
||||
function set_realpath($path, $check_existance = FALSE)
|
||||
{
|
||||
// Security check to make sure the path is NOT a URL. No remote file inclusion!
|
||||
if (preg_match('#^(http:\/\/|https:\/\/|www\.|ftp|php:\/\/)#i', $path) OR filter_var($path, FILTER_VALIDATE_IP) === $path)
|
||||
{
|
||||
show_error('The path you submitted must be a local server path, not a URL');
|
||||
}
|
||||
|
||||
// Resolve the path
|
||||
if (realpath($path) !== FALSE)
|
||||
{
|
||||
$path = realpath($path);
|
||||
}
|
||||
elseif ($check_existance && ! is_dir($path) && ! is_file($path))
|
||||
{
|
||||
show_error('Not a valid path: '.$path);
|
||||
}
|
||||
|
||||
// Add a trailing slash, if this is a directory
|
||||
return is_dir($path) ? rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR : $path;
|
||||
}
|
||||
}
|
||||
@@ -1,138 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Security Helpers
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/security_helper.html
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
use Config\Services;
|
||||
|
||||
if ( ! function_exists('xss_clean'))
|
||||
{
|
||||
/**
|
||||
* XSS Filtering
|
||||
*
|
||||
* @param string
|
||||
* @param bool whether or not the content is an image file
|
||||
* @return string
|
||||
*/
|
||||
function xss_clean($str, $is_image = FALSE)
|
||||
{
|
||||
return get_instance()->security->xss_clean($str, $is_image);
|
||||
}
|
||||
// CodeIgniter Security Helpers
|
||||
|
||||
if (! function_exists('sanitize_filename')) {
|
||||
/**
|
||||
* Sanitize a filename to use in a URI.
|
||||
*/
|
||||
function sanitize_filename(string $filename): string
|
||||
{
|
||||
return Services::security()->sanitizeFilename($filename);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('sanitize_filename'))
|
||||
{
|
||||
/**
|
||||
* Sanitize Filename
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function sanitize_filename($filename)
|
||||
{
|
||||
return get_instance()->security->sanitize_filename($filename);
|
||||
}
|
||||
if (! function_exists('strip_image_tags')) {
|
||||
/**
|
||||
* Strip Image Tags
|
||||
*/
|
||||
function strip_image_tags(string $str): string
|
||||
{
|
||||
return preg_replace(
|
||||
[
|
||||
'#<img[\s/]+.*?src\s*=\s*(["\'])([^\\1]+?)\\1.*?\>#i',
|
||||
'#<img[\s/]+.*?src\s*=\s*?(([^\s"\'=<>`]+)).*?\>#i',
|
||||
],
|
||||
'\\2',
|
||||
$str
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('do_hash'))
|
||||
{
|
||||
/**
|
||||
* Hash encode a string
|
||||
*
|
||||
* @todo Remove in version 3.1+.
|
||||
* @deprecated 3.0.0 Use PHP's native hash() instead.
|
||||
* @param string $str
|
||||
* @param string $type = 'sha1'
|
||||
* @return string
|
||||
*/
|
||||
function do_hash($str, $type = 'sha1')
|
||||
{
|
||||
if ( ! in_array(strtolower($type), hash_algos()))
|
||||
{
|
||||
$type = 'md5';
|
||||
}
|
||||
|
||||
return hash($type, $str);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('strip_image_tags'))
|
||||
{
|
||||
/**
|
||||
* Strip Image Tags
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function strip_image_tags($str)
|
||||
{
|
||||
return get_instance()->security->strip_image_tags($str);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('encode_php_tags'))
|
||||
{
|
||||
/**
|
||||
* Convert PHP tags to entities
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function encode_php_tags($str)
|
||||
{
|
||||
return str_replace(array('<?', '?>'), array('<?', '?>'), $str);
|
||||
}
|
||||
if (! function_exists('encode_php_tags')) {
|
||||
/**
|
||||
* Convert PHP tags to entities
|
||||
*/
|
||||
function encode_php_tags(string $str): string
|
||||
{
|
||||
return str_replace(['<?', '?>'], ['<?', '?>'], $str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,256 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Smiley Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/smiley_helper.html
|
||||
* @deprecated 3.0.0 This helper is too specific for CI.
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('smiley_js'))
|
||||
{
|
||||
/**
|
||||
* Smiley Javascript
|
||||
*
|
||||
* Returns the javascript required for the smiley insertion. Optionally takes
|
||||
* an array of aliases to loosely couple the smiley array to the view.
|
||||
*
|
||||
* @param mixed alias name or array of alias->field_id pairs
|
||||
* @param string field_id if alias name was passed in
|
||||
* @param bool
|
||||
* @return array
|
||||
*/
|
||||
function smiley_js($alias = '', $field_id = '', $inline = TRUE)
|
||||
{
|
||||
static $do_setup = TRUE;
|
||||
$r = '';
|
||||
|
||||
if ($alias !== '' && ! is_array($alias))
|
||||
{
|
||||
$alias = array($alias => $field_id);
|
||||
}
|
||||
|
||||
if ($do_setup === TRUE)
|
||||
{
|
||||
$do_setup = FALSE;
|
||||
$m = array();
|
||||
|
||||
if (is_array($alias))
|
||||
{
|
||||
foreach ($alias as $name => $id)
|
||||
{
|
||||
$m[] = '"'.$name.'" : "'.$id.'"';
|
||||
}
|
||||
}
|
||||
|
||||
$m = '{'.implode(',', $m).'}';
|
||||
|
||||
$r .= <<<EOF
|
||||
var smiley_map = {$m};
|
||||
|
||||
function insert_smiley(smiley, field_id) {
|
||||
var el = document.getElementById(field_id), newStart;
|
||||
|
||||
if ( ! el && smiley_map[field_id]) {
|
||||
el = document.getElementById(smiley_map[field_id]);
|
||||
|
||||
if ( ! el)
|
||||
return false;
|
||||
}
|
||||
|
||||
el.focus();
|
||||
smiley = " " + smiley;
|
||||
|
||||
if ('selectionStart' in el) {
|
||||
newStart = el.selectionStart + smiley.length;
|
||||
|
||||
el.value = el.value.substr(0, el.selectionStart) +
|
||||
smiley +
|
||||
el.value.substr(el.selectionEnd, el.value.length);
|
||||
el.setSelectionRange(newStart, newStart);
|
||||
}
|
||||
else if (document.selection) {
|
||||
document.selection.createRange().text = smiley;
|
||||
}
|
||||
}
|
||||
EOF;
|
||||
}
|
||||
elseif (is_array($alias))
|
||||
{
|
||||
foreach ($alias as $name => $id)
|
||||
{
|
||||
$r .= 'smiley_map["'.$name.'"] = "'.$id."\";\n";
|
||||
}
|
||||
}
|
||||
|
||||
return ($inline)
|
||||
? '<script type="text/javascript" charset="utf-8">/*<![CDATA[ */'.$r.'// ]]></script>'
|
||||
: $r;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('get_clickable_smileys'))
|
||||
{
|
||||
/**
|
||||
* Get Clickable Smileys
|
||||
*
|
||||
* Returns an array of image tag links that can be clicked to be inserted
|
||||
* into a form field.
|
||||
*
|
||||
* @param string the URL to the folder containing the smiley images
|
||||
* @param array
|
||||
* @return array
|
||||
*/
|
||||
function get_clickable_smileys($image_url, $alias = '')
|
||||
{
|
||||
// For backward compatibility with js_insert_smiley
|
||||
if (is_array($alias))
|
||||
{
|
||||
$smileys = $alias;
|
||||
}
|
||||
elseif (FALSE === ($smileys = _get_smiley_array()))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Add a trailing slash to the file path if needed
|
||||
$image_url = rtrim($image_url, '/').'/';
|
||||
|
||||
$used = array();
|
||||
foreach ($smileys as $key => $val)
|
||||
{
|
||||
// Keep duplicates from being used, which can happen if the
|
||||
// mapping array contains multiple identical replacements. For example:
|
||||
// :-) and :) might be replaced with the same image so both smileys
|
||||
// will be in the array.
|
||||
if (isset($used[$smileys[$key][0]]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$link[] = '<a href="javascript:void(0);" onclick="insert_smiley(\''.$key.'\', \''.$alias.'\')"><img src="'.$image_url.$smileys[$key][0].'" alt="'.$smileys[$key][3].'" style="width: '.$smileys[$key][1].'; height: '.$smileys[$key][2].'; border: 0;" /></a>';
|
||||
$used[$smileys[$key][0]] = TRUE;
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('parse_smileys'))
|
||||
{
|
||||
/**
|
||||
* Parse Smileys
|
||||
*
|
||||
* Takes a string as input and swaps any contained smileys for the actual image
|
||||
*
|
||||
* @param string the text to be parsed
|
||||
* @param string the URL to the folder containing the smiley images
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
function parse_smileys($str = '', $image_url = '', $smileys = NULL)
|
||||
{
|
||||
if ($image_url === '' OR ( ! is_array($smileys) && FALSE === ($smileys = _get_smiley_array())))
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
// Add a trailing slash to the file path if needed
|
||||
$image_url = rtrim($image_url, '/').'/';
|
||||
|
||||
foreach ($smileys as $key => $val)
|
||||
{
|
||||
$str = str_replace($key, '<img src="'.$image_url.$smileys[$key][0].'" alt="'.$smileys[$key][3].'" style="width: '.$smileys[$key][1].'; height: '.$smileys[$key][2].'; border: 0;" />', $str);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('_get_smiley_array'))
|
||||
{
|
||||
/**
|
||||
* Get Smiley Array
|
||||
*
|
||||
* Fetches the config/smiley.php file
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function _get_smiley_array()
|
||||
{
|
||||
static $_smileys;
|
||||
|
||||
if ( ! is_array($_smileys))
|
||||
{
|
||||
if (file_exists(APPPATH.'config/smileys.php'))
|
||||
{
|
||||
include(APPPATH.'config/smileys.php');
|
||||
}
|
||||
|
||||
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/smileys.php'))
|
||||
{
|
||||
include(APPPATH.'config/'.ENVIRONMENT.'/smileys.php');
|
||||
}
|
||||
|
||||
if (empty($smileys) OR ! is_array($smileys))
|
||||
{
|
||||
$_smileys = array();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$_smileys = $smileys;
|
||||
}
|
||||
|
||||
return $_smileys;
|
||||
}
|
||||
}
|
||||
@@ -1,305 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter String Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/string_helper.html
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('trim_slashes'))
|
||||
{
|
||||
/**
|
||||
* Trim Slashes
|
||||
*
|
||||
* Removes any leading/trailing slashes from a string:
|
||||
*
|
||||
* /this/that/theother/
|
||||
*
|
||||
* becomes:
|
||||
*
|
||||
* this/that/theother
|
||||
*
|
||||
* @todo Remove in version 3.1+.
|
||||
* @deprecated 3.0.0 This is just an alias for PHP's native trim()
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function trim_slashes($str)
|
||||
{
|
||||
return trim($str, '/');
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('strip_slashes'))
|
||||
{
|
||||
/**
|
||||
* Strip Slashes
|
||||
*
|
||||
* Removes slashes contained in a string or in an array
|
||||
*
|
||||
* @param mixed string or array
|
||||
* @return mixed string or array
|
||||
*/
|
||||
function strip_slashes($str)
|
||||
{
|
||||
if ( ! is_array($str))
|
||||
{
|
||||
return stripslashes($str);
|
||||
}
|
||||
|
||||
foreach ($str as $key => $val)
|
||||
{
|
||||
$str[$key] = strip_slashes($val);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('strip_quotes'))
|
||||
{
|
||||
/**
|
||||
* Strip Quotes
|
||||
*
|
||||
* Removes single and double quotes from a string
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function strip_quotes($str)
|
||||
{
|
||||
return str_replace(array('"', "'"), '', $str);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('quotes_to_entities'))
|
||||
{
|
||||
/**
|
||||
* Quotes to Entities
|
||||
*
|
||||
* Converts single and double quotes to entities
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function quotes_to_entities($str)
|
||||
{
|
||||
return str_replace(array("\'","\"","'",'"'), array("'",""","'","""), $str);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('reduce_double_slashes'))
|
||||
{
|
||||
/**
|
||||
* Reduce Double Slashes
|
||||
*
|
||||
* Converts double slashes in a string to a single slash,
|
||||
* except those found in http://
|
||||
*
|
||||
* http://www.some-site.com//index.php
|
||||
*
|
||||
* becomes:
|
||||
*
|
||||
* http://www.some-site.com/index.php
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function reduce_double_slashes($str)
|
||||
{
|
||||
return preg_replace('#(^|[^:])//+#', '\\1/', $str);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('reduce_multiples'))
|
||||
{
|
||||
/**
|
||||
* Reduce Multiples
|
||||
*
|
||||
* Reduces multiple instances of a particular character. Example:
|
||||
*
|
||||
* Fred, Bill,, Joe, Jimmy
|
||||
*
|
||||
* becomes:
|
||||
*
|
||||
* Fred, Bill, Joe, Jimmy
|
||||
*
|
||||
* @param string
|
||||
* @param string the character you wish to reduce
|
||||
* @param bool TRUE/FALSE - whether to trim the character from the beginning/end
|
||||
* @return string
|
||||
*/
|
||||
function reduce_multiples($str, $character = ',', $trim = FALSE)
|
||||
{
|
||||
$str = preg_replace('#'.preg_quote($character, '#').'{2,}#', $character, $str);
|
||||
return ($trim === TRUE) ? trim($str, $character) : $str;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('random_string'))
|
||||
{
|
||||
/**
|
||||
* Create a "Random" String
|
||||
*
|
||||
* @param string type of random string. basic, alpha, alnum, numeric, nozero, unique, md5, encrypt and sha1
|
||||
* @param int number of characters
|
||||
* @return string
|
||||
*/
|
||||
function random_string($type = 'alnum', $len = 8)
|
||||
{
|
||||
switch ($type)
|
||||
{
|
||||
case 'basic':
|
||||
return mt_rand();
|
||||
case 'alnum':
|
||||
case 'numeric':
|
||||
case 'nozero':
|
||||
case 'alpha':
|
||||
switch ($type)
|
||||
{
|
||||
case 'alpha':
|
||||
$pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
break;
|
||||
case 'alnum':
|
||||
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
break;
|
||||
case 'numeric':
|
||||
$pool = '0123456789';
|
||||
break;
|
||||
case 'nozero':
|
||||
$pool = '123456789';
|
||||
break;
|
||||
}
|
||||
return substr(str_shuffle(str_repeat($pool, ceil($len / strlen($pool)))), 0, $len);
|
||||
case 'unique': // todo: remove in 3.1+
|
||||
case 'md5':
|
||||
return md5(uniqid(mt_rand()));
|
||||
case 'encrypt': // todo: remove in 3.1+
|
||||
case 'sha1':
|
||||
return sha1(uniqid(mt_rand(), TRUE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('increment_string'))
|
||||
{
|
||||
/**
|
||||
* Add's _1 to a string or increment the ending number to allow _2, _3, etc
|
||||
*
|
||||
* @param string required
|
||||
* @param string What should the duplicate number be appended with
|
||||
* @param string Which number should be used for the first dupe increment
|
||||
* @return string
|
||||
*/
|
||||
function increment_string($str, $separator = '_', $first = 1)
|
||||
{
|
||||
preg_match('/(.+)'.preg_quote($separator, '/').'([0-9]+)$/', $str, $match);
|
||||
return isset($match[2]) ? $match[1].$separator.($match[2] + 1) : $str.$separator.$first;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('alternator'))
|
||||
{
|
||||
/**
|
||||
* Alternator
|
||||
*
|
||||
* Allows strings to be alternated. See docs...
|
||||
*
|
||||
* @param string (as many parameters as needed)
|
||||
* @return string
|
||||
*/
|
||||
function alternator()
|
||||
{
|
||||
static $i;
|
||||
|
||||
if (func_num_args() === 0)
|
||||
{
|
||||
$i = 0;
|
||||
return '';
|
||||
}
|
||||
|
||||
$args = func_get_args();
|
||||
return $args[($i++ % count($args))];
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('repeater'))
|
||||
{
|
||||
/**
|
||||
* Repeater function
|
||||
*
|
||||
* @todo Remove in version 3.1+.
|
||||
* @deprecated 3.0.0 This is just an alias for PHP's native str_repeat()
|
||||
*
|
||||
* @param string $data String to repeat
|
||||
* @param int $num Number of repeats
|
||||
* @return string
|
||||
*/
|
||||
function repeater($data, $num = 1)
|
||||
{
|
||||
return ($num > 0) ? str_repeat($data, $num) : '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use CodeIgniter\Exceptions\TestException;
|
||||
use CodeIgniter\Model;
|
||||
use CodeIgniter\Test\Fabricator;
|
||||
use Config\Services;
|
||||
|
||||
// CodeIgniter Test Helpers
|
||||
|
||||
if (! function_exists('fake')) {
|
||||
/**
|
||||
* Creates a single item using Fabricator.
|
||||
*
|
||||
* @param Model|object|string $model Instance or name of the model
|
||||
* @param array|null $overrides Overriding data to pass to Fabricator::setOverrides()
|
||||
* @param bool $persist
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
function fake($model, ?array $overrides = null, $persist = true)
|
||||
{
|
||||
$fabricator = new Fabricator($model);
|
||||
|
||||
if ($overrides) {
|
||||
$fabricator->setOverrides($overrides);
|
||||
}
|
||||
|
||||
if ($persist) {
|
||||
return $fabricator->create();
|
||||
}
|
||||
|
||||
return $fabricator->make();
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('mock')) {
|
||||
/**
|
||||
* Used within our test suite to mock certain system tools.
|
||||
*
|
||||
* @param string $className Fully qualified class name
|
||||
*/
|
||||
function mock(string $className)
|
||||
{
|
||||
$mockClass = $className::$mockClass;
|
||||
$mockService = $className::$mockServiceName ?? '';
|
||||
|
||||
if (empty($mockClass) || ! class_exists($mockClass)) {
|
||||
throw TestException::forInvalidMockClass($mockClass);
|
||||
}
|
||||
|
||||
$mock = new $mockClass();
|
||||
|
||||
if (! empty($mockService)) {
|
||||
Services::injectMock($mockService, $mock);
|
||||
}
|
||||
|
||||
return $mock;
|
||||
}
|
||||
}
|
||||
Regular → Executable
+610
-498
File diff suppressed because it is too large
Load Diff
@@ -1,105 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter Typography Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/typography_helper.html
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('nl2br_except_pre'))
|
||||
{
|
||||
/**
|
||||
* Convert newlines to HTML line breaks except within PRE tags
|
||||
*
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function nl2br_except_pre($str)
|
||||
{
|
||||
$CI =& get_instance();
|
||||
$CI->load->library('typography');
|
||||
return $CI->typography->nl2br_except_pre($str);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('auto_typography'))
|
||||
{
|
||||
/**
|
||||
* Auto Typography Wrapper Function
|
||||
*
|
||||
* @param string $str
|
||||
* @param bool $reduce_linebreaks = FALSE whether to reduce multiple instances of double newlines to two
|
||||
* @return string
|
||||
*/
|
||||
function auto_typography($str, $reduce_linebreaks = FALSE)
|
||||
{
|
||||
$CI =& get_instance();
|
||||
$CI->load->library('typography');
|
||||
return $CI->typography->auto_typography($str, $reduce_linebreaks);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
if ( ! function_exists('entity_decode'))
|
||||
{
|
||||
/**
|
||||
* HTML Entities Decode
|
||||
*
|
||||
* This function is a replacement for html_entity_decode()
|
||||
*
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function entity_decode($str, $charset = NULL)
|
||||
{
|
||||
return get_instance()->security->entity_decode($str, $charset);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,91 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 - 2022, CodeIgniter Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @author EllisLab Dev Team
|
||||
* @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
|
||||
* @copyright Copyright (c) 2019 - 2022, CodeIgniter Foundation (https://codeigniter.com/)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* CodeIgniter XML Helpers
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* @package CodeIgniter
|
||||
* @subpackage Helpers
|
||||
* @category Helpers
|
||||
* @author EllisLab Dev Team
|
||||
* @link https://codeigniter.com/userguide3/helpers/xml_helper.html
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// CodeIgniter XML Helpers
|
||||
|
||||
if ( ! function_exists('xml_convert'))
|
||||
{
|
||||
/**
|
||||
* Convert Reserved XML characters to Entities
|
||||
*
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return string
|
||||
*/
|
||||
function xml_convert($str, $protect_all = FALSE)
|
||||
{
|
||||
$temp = '__TEMP_AMPERSANDS__';
|
||||
if (! function_exists('xml_convert')) {
|
||||
/**
|
||||
* Convert Reserved XML characters to Entities
|
||||
*/
|
||||
function xml_convert(string $str, bool $protectAll = false): string
|
||||
{
|
||||
$temp = '__TEMP_AMPERSANDS__';
|
||||
|
||||
// Replace entities to temporary markers so that
|
||||
// ampersands won't get messed up
|
||||
$str = preg_replace('/&#(\d+);/', $temp.'\\1;', $str);
|
||||
// Replace entities to temporary markers so that
|
||||
// ampersands won't get messed up
|
||||
$str = preg_replace('/&#(\d+);/', $temp . '\\1;', $str);
|
||||
|
||||
if ($protect_all === TRUE)
|
||||
{
|
||||
$str = preg_replace('/&(\w+);/', $temp.'\\1;', $str);
|
||||
}
|
||||
if ($protectAll === true) {
|
||||
$str = preg_replace('/&(\w+);/', $temp . '\\1;', $str);
|
||||
}
|
||||
|
||||
$str = str_replace(
|
||||
array('&', '<', '>', '"', "'", '-'),
|
||||
array('&', '<', '>', '"', ''', '-'),
|
||||
$str
|
||||
);
|
||||
$original = [
|
||||
'&',
|
||||
'<',
|
||||
'>',
|
||||
'"',
|
||||
"'",
|
||||
'-',
|
||||
];
|
||||
|
||||
// Decode the temp markers back to entities
|
||||
$str = preg_replace('/'.$temp.'(\d+);/', '&#\\1;', $str);
|
||||
$replacement = [
|
||||
'&',
|
||||
'<',
|
||||
'>',
|
||||
'"',
|
||||
''',
|
||||
'-',
|
||||
];
|
||||
|
||||
if ($protect_all === TRUE)
|
||||
{
|
||||
return preg_replace('/'.$temp.'(\w+);/', '&\\1;', $str);
|
||||
}
|
||||
$str = str_replace($original, $replacement, $str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
// Decode the temp markers back to entities
|
||||
$str = preg_replace('/' . $temp . '(\d+);/', '&#\\1;', $str);
|
||||
|
||||
if ($protectAll === true) {
|
||||
return preg_replace('/' . $temp . '(\w+);/', '&\\1;', $str);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user