First Local Commit - After Clean up.
Signed-off-by: Rick Hays <rhays@haysgang.com>
This commit is contained in:
124
system/Helpers/array_helper.php
Normal file
124
system/Helpers/array_helper.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 4.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
/**
|
||||
* CodeIgniter Array Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
|
||||
if (! function_exists('dot_array_search'))
|
||||
{
|
||||
/**
|
||||
* Searches an array through dot syntax. Supports
|
||||
* wildcard searches, like foo.*.bar
|
||||
*
|
||||
* @param string $index
|
||||
* @param array $array
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
function dot_array_search(string $index, array $array)
|
||||
{
|
||||
$segments = explode('.', rtrim(rtrim($index, '* '), '.'));
|
||||
|
||||
return _array_search_dot($segments, $array);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('_array_search_dot'))
|
||||
{
|
||||
/**
|
||||
* Used by dot_array_search to recursively search the
|
||||
* array with wildcards.
|
||||
*
|
||||
* @param array $indexes
|
||||
* @param array $array
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
function _array_search_dot(array $indexes, array $array)
|
||||
{
|
||||
// Grab the current index
|
||||
$currentIndex = $indexes
|
||||
? array_shift($indexes)
|
||||
: null;
|
||||
|
||||
if (empty($currentIndex) || (! isset($array[$currentIndex]) && $currentIndex !== '*'))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Handle Wildcard (*)
|
||||
if ($currentIndex === '*')
|
||||
{
|
||||
// If $array has more than 1 item, we have to loop over each.
|
||||
if (is_array($array))
|
||||
{
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
$answer = _array_search_dot($indexes, $value);
|
||||
|
||||
if ($answer !== null)
|
||||
{
|
||||
return $answer;
|
||||
}
|
||||
}
|
||||
|
||||
// Still here after searching all child nodes?
|
||||
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 we've found our match!
|
||||
return $array[$currentIndex];
|
||||
}
|
||||
}
|
||||
124
system/Helpers/cookie_helper.php
Normal file
124
system/Helpers/cookie_helper.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 4.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* CodeIgniter Cookie Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
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 string|array $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
|
||||
* @param boolean $secure True makes the cookie secure
|
||||
* @param boolean $httpOnly True makes the cookie accessible via
|
||||
* http(s) only (no javascript)
|
||||
*
|
||||
* @see (\Config\Services::response())->setCookie()
|
||||
* @see \CodeIgniter\HTTP\Response::setCookie()
|
||||
*/
|
||||
function set_cookie($name, string $value = '', string $expire = '', string $domain = '', string $path = '/', string $prefix = '', bool $secure = false, bool $httpOnly = false)
|
||||
{
|
||||
// The following line shows as a syntax error in NetBeans IDE
|
||||
//(\Config\Services::response())->setcookie
|
||||
$response = \Config\Services::response();
|
||||
$response->setcookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httpOnly);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('get_cookie'))
|
||||
{
|
||||
/**
|
||||
* Fetch an item from the COOKIE array
|
||||
*
|
||||
* @param string $index
|
||||
* @param boolean $xssClean
|
||||
*
|
||||
* @see (\Config\Services::request())->getCookie()
|
||||
* @see \CodeIgniter\HTTP\IncomingRequest::getCookie()
|
||||
* @return mixed
|
||||
*/
|
||||
function get_cookie($index, bool $xssClean = false)
|
||||
{
|
||||
$app = config(\Config\App::class);
|
||||
$appCookiePrefix = $app->cookiePrefix;
|
||||
$prefix = isset($_COOKIE[$index]) ? '' : $appCookiePrefix;
|
||||
|
||||
$request = \Config\Services::request();
|
||||
$filter = true === $xssClean ? FILTER_SANITIZE_STRING : null;
|
||||
$cookie = $request->getCookie($prefix . $index, $filter);
|
||||
|
||||
return $cookie;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
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 (\Config\Services::response())->setCookie()
|
||||
* @see \CodeIgniter\HTTP\Response::setcookie()
|
||||
* @return void
|
||||
*/
|
||||
function delete_cookie($name, string $domain = '', string $path = '/', string $prefix = '')
|
||||
{
|
||||
\Config\Services::response()->deleteCookie($name, $domain, $path, $prefix);
|
||||
}
|
||||
}
|
||||
103
system/Helpers/date_helper.php
Normal file
103
system/Helpers/date_helper.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 4.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
/**
|
||||
* CodeIgniter Date Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
|
||||
if (! function_exists('now'))
|
||||
{
|
||||
/**
|
||||
* Get "now" time
|
||||
*
|
||||
* Returns time() based on the timezone parameter or on the
|
||||
* app_timezone() setting
|
||||
*
|
||||
* @param string $timezone
|
||||
*
|
||||
* @return integer
|
||||
* @throws \Exception
|
||||
*/
|
||||
function now(string $timezone = null): int
|
||||
{
|
||||
$timezone = empty($timezone) ? app_timezone() : $timezone;
|
||||
|
||||
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);
|
||||
|
||||
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 integer $what One of the DateTimeZone class constants (for listIdentifiers)
|
||||
* @param string $country A two-letter ISO 3166-1 compatible country code (for listIdentifiers)
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
function timezone_select(string $class = '', string $default = '', int $what = \DateTimeZone::ALL, string $country = null): string
|
||||
{
|
||||
$timezones = \DateTimeZone::listIdentifiers($what, $country);
|
||||
|
||||
$buffer = "<select name='timezone' class='{$class}'>" . PHP_EOL;
|
||||
foreach ($timezones as $timezone)
|
||||
{
|
||||
$selected = ($timezone === $default) ? 'selected' : '';
|
||||
$buffer .= "<option value='{$timezone}' {$selected}>{$timezone}</option>" . PHP_EOL;
|
||||
}
|
||||
$buffer .= '</select>' . PHP_EOL;
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
}
|
||||
494
system/Helpers/filesystem_helper.php
Normal file
494
system/Helpers/filesystem_helper.php
Normal file
@@ -0,0 +1,494 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2008-2014 EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
/**
|
||||
* CodeIgniter File System Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
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 integer $directory_depth Depth of directories to traverse
|
||||
* (0 = fully recursive, 1 = current dir, etc)
|
||||
* @param boolean $hidden Whether to show hidden files
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function directory_map(string $source_dir, int $directory_depth = 0, bool $hidden = false): array
|
||||
{
|
||||
try
|
||||
{
|
||||
$fp = opendir($source_dir);
|
||||
|
||||
$fileData = [];
|
||||
$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 === '.' || $file === '..' || ($hidden === false && $file[0] === '.'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
is_dir($source_dir . $file) && $file .= DIRECTORY_SEPARATOR;
|
||||
|
||||
if (($directory_depth < 1 || $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;
|
||||
}
|
||||
catch (\Exception $fe)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
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 boolean
|
||||
*/
|
||||
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 (\Exception $fe)
|
||||
{
|
||||
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 boolean $del_dir Whether to delete any directories found in the path
|
||||
* @param boolean $htdocs Whether to skip deleting .htaccess and index page files
|
||||
* @param integer $_level Current directory depth level (default: 0; internal use only)
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function delete_files(string $path, bool $del_dir = false, bool $htdocs = false, int $_level = 0): bool
|
||||
{
|
||||
// Trim the trailing slash
|
||||
$path = rtrim($path, '/\\');
|
||||
|
||||
try
|
||||
{
|
||||
$current_dir = opendir($path);
|
||||
|
||||
while (false !== ($filename = @readdir($current_dir)))
|
||||
{
|
||||
if ($filename !== '.' && $filename !== '..')
|
||||
{
|
||||
if (is_dir($path . DIRECTORY_SEPARATOR . $filename) && $filename[0] !== '.')
|
||||
{
|
||||
delete_files($path . DIRECTORY_SEPARATOR . $filename, $del_dir, $htdocs, $_level + 1);
|
||||
}
|
||||
elseif ($htdocs !== true || ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename))
|
||||
{
|
||||
@unlink($path . DIRECTORY_SEPARATOR . $filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir($current_dir);
|
||||
|
||||
return ($del_dir === true && $_level > 0) ? @rmdir($path) : true;
|
||||
}
|
||||
catch (\Exception $fe)
|
||||
{
|
||||
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 $source_dir Path to source
|
||||
* @param boolean $include_path Whether to include the path as part of the filename
|
||||
* @param boolean $recursion Internal variable to determine recursion status - do not use in calls
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_filenames(string $source_dir, bool $include_path = false, bool $recursion = false): array
|
||||
{
|
||||
static $fileData = [];
|
||||
|
||||
try
|
||||
{
|
||||
$fp = opendir($source_dir);
|
||||
// reset the array and make sure $source_dir has a trailing slash on the initial call
|
||||
if ($recursion === false)
|
||||
{
|
||||
$fileData = [];
|
||||
$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;
|
||||
}
|
||||
catch (\Exception $fe)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
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 $source_dir Path to source
|
||||
* @param boolean $top_level_only Look only at the top level directory specified?
|
||||
* @param boolean $recursion Internal variable to determine recursion status - do not use in calls
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_dir_file_info(string $source_dir, bool $top_level_only = true, bool $recursion = false): array
|
||||
{
|
||||
static $fileData = [];
|
||||
$relative_path = $source_dir;
|
||||
|
||||
try
|
||||
{
|
||||
$fp = @opendir($source_dir); {
|
||||
// reset the array and make sure $source_dir has a trailing slash on the initial call
|
||||
if ($recursion === false)
|
||||
{
|
||||
$fileData = [];
|
||||
$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;
|
||||
}
|
||||
}
|
||||
catch (\Exception $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 $returned_values Array or comma separated string of information returned
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
function get_file_info(string $file, $returned_values = ['name', 'server_path', 'size', 'date'])
|
||||
{
|
||||
if (! is_file($file))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
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('symbolic_permissions'))
|
||||
{
|
||||
/**
|
||||
* Symbolic Permissions
|
||||
*
|
||||
* Takes a numeric value representing a file's permissions and returns
|
||||
* standard symbolic notation representing that value
|
||||
*
|
||||
* @param integer $perms Permissions
|
||||
* @return string
|
||||
*/
|
||||
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 integer $perms Permissions
|
||||
* @return string
|
||||
*/
|
||||
function octal_permissions(int $perms): string
|
||||
{
|
||||
return substr(sprintf('%o', $perms), -3);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('set_realpath'))
|
||||
{
|
||||
/**
|
||||
* Set Realpath
|
||||
*
|
||||
* @param string $path
|
||||
* @param boolean $check_existence Checks to see if the path exists
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function set_realpath(string $path, bool $check_existence = 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 ($check_existence && ! 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;
|
||||
}
|
||||
}
|
||||
965
system/Helpers/form_helper.php
Normal file
965
system/Helpers/form_helper.php
Normal file
@@ -0,0 +1,965 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 4.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
use Config\Services;
|
||||
|
||||
/**
|
||||
* CodeIgniter Form Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_open'))
|
||||
{
|
||||
/**
|
||||
* Form Declaration
|
||||
*
|
||||
* Creates the opening portion of the form.
|
||||
*
|
||||
* @param string $action the URI segments of the form destination
|
||||
* @param array|string $attributes a key/value pair of attributes, or string representation
|
||||
* @param array $hidden a key/value pair hidden data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_open(string $action = '', $attributes = [], array $hidden = []): string
|
||||
{
|
||||
// If no action is provided then set to the current url
|
||||
if (! $action)
|
||||
{
|
||||
$action = current_url(true);
|
||||
} // If an action is not a full URL then turn it into one
|
||||
elseif (strpos($action, '://') === false)
|
||||
{
|
||||
$action = site_url($action);
|
||||
}
|
||||
|
||||
if (is_array($attributes) && array_key_exists('csrf_id', $attributes))
|
||||
{
|
||||
$csrfId = $attributes['csrf_id'];
|
||||
unset($attributes['csrf_id']);
|
||||
}
|
||||
|
||||
$attributes = stringify_attributes($attributes);
|
||||
|
||||
if (stripos($attributes, 'method=') === false)
|
||||
{
|
||||
$attributes .= ' method="post"';
|
||||
}
|
||||
if (stripos($attributes, 'accept-charset=') === false)
|
||||
{
|
||||
$config = config(\Config\App::class);
|
||||
$attributes .= ' accept-charset="' . strtolower($config->charset) . '"';
|
||||
}
|
||||
|
||||
$form = '<form action="' . $action . '"' . $attributes . ">\n";
|
||||
|
||||
// Add CSRF field if enabled, but leave it out for GET requests and requests to external websites
|
||||
$before = Services::filters()
|
||||
->getFilters()['before'];
|
||||
|
||||
if ((in_array('csrf', $before) || array_key_exists('csrf', $before)) && strpos($action, base_url()) !== false && ! stripos($form, 'method="get"'))
|
||||
{
|
||||
$form .= csrf_field($csrfId ?? null);
|
||||
}
|
||||
|
||||
if (is_array($hidden))
|
||||
{
|
||||
foreach ($hidden as $name => $value)
|
||||
{
|
||||
$form .= form_hidden($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_open_multipart'))
|
||||
{
|
||||
/**
|
||||
* Form Declaration - Multipart type
|
||||
*
|
||||
* Creates the opening portion of the form, but with "multipart/form-data".
|
||||
*
|
||||
* @param string $action The URI segments of the form destination
|
||||
* @param array|string $attributes A key/value pair of attributes, or the same as a string
|
||||
* @param array $hidden A key/value pair hidden data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_open_multipart(string $action = '', $attributes = [], array $hidden = []): string
|
||||
{
|
||||
if (is_string($attributes))
|
||||
{
|
||||
$attributes .= ' enctype="' . esc('multipart/form-data', 'attr') . '"';
|
||||
}
|
||||
else
|
||||
{
|
||||
$attributes['enctype'] = 'multipart/form-data';
|
||||
}
|
||||
|
||||
return form_open($action, $attributes, $hidden);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_hidden'))
|
||||
{
|
||||
/**
|
||||
* Hidden Input Field
|
||||
*
|
||||
* Generates hidden fields. You can pass a simple key/value string or
|
||||
* an associative array with multiple values.
|
||||
*
|
||||
* @param string|array $name Field name or associative array to create multiple fields
|
||||
* @param string|array $value Field value
|
||||
* @param boolean $recursing
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_hidden($name, $value = '', bool $recursing = false): string
|
||||
{
|
||||
static $form;
|
||||
|
||||
if ($recursing === false)
|
||||
{
|
||||
$form = "\n";
|
||||
}
|
||||
|
||||
if (is_array($name))
|
||||
{
|
||||
foreach ($name as $key => $val)
|
||||
{
|
||||
form_hidden($key, $val, true);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
if (! is_array($value))
|
||||
{
|
||||
$form .= '<input type="hidden" name="' . $name . '" value="' . esc($value, 'html') . "\" style=\"display:none;\" />\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($value as $k => $v)
|
||||
{
|
||||
$k = is_int($k) ? '' : $k;
|
||||
form_hidden($name . '[' . $k . ']', $v, true);
|
||||
}
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_input'))
|
||||
{
|
||||
/**
|
||||
* Text Input Field. If 'type' is passed in the $type field, it will be
|
||||
* used as the input type, for making 'email', 'phone', etc input fields.
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param string $value
|
||||
* @param mixed $extra
|
||||
* @param string $type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_input($data = '', string $value = '', $extra = '', string $type = 'text'): string
|
||||
{
|
||||
$defaults = [
|
||||
'type' => $type,
|
||||
'name' => is_array($data) ? '' : $data,
|
||||
'value' => $value,
|
||||
];
|
||||
|
||||
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . " />\n";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_password'))
|
||||
{
|
||||
/**
|
||||
* Password Field
|
||||
*
|
||||
* Identical to the input function but adds the "password" type
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param string $value
|
||||
* @param mixed $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_password($data = '', string $value = '', $extra = ''): string
|
||||
{
|
||||
is_array($data) || $data = ['name' => $data];
|
||||
$data['type'] = 'password';
|
||||
|
||||
return form_input($data, $value, $extra);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_upload'))
|
||||
{
|
||||
/**
|
||||
* Upload Field
|
||||
*
|
||||
* Identical to the input function but adds the "file" type
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param string $value
|
||||
* @param mixed $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_upload($data = '', string $value = '', $extra = ''): string
|
||||
{
|
||||
$defaults = [
|
||||
'type' => 'file',
|
||||
'name' => '',
|
||||
];
|
||||
is_array($data) || $data = ['name' => $data];
|
||||
$data['type'] = 'file';
|
||||
|
||||
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . " />\n";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_textarea'))
|
||||
{
|
||||
/**
|
||||
* Textarea field
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param string $value
|
||||
* @param mixed $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_textarea($data = '', string $value = '', $extra = ''): string
|
||||
{
|
||||
$defaults = [
|
||||
'name' => is_array($data) ? '' : $data,
|
||||
'cols' => '40',
|
||||
'rows' => '10',
|
||||
];
|
||||
if (! is_array($data) || ! isset($data['value']))
|
||||
{
|
||||
$val = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$val = $data['value'];
|
||||
unset($data['value']); // textareas don't use the value attribute
|
||||
}
|
||||
|
||||
return '<textarea ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . '>'
|
||||
. htmlspecialchars($val)
|
||||
. "</textarea>\n";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_multiselect'))
|
||||
{
|
||||
/**
|
||||
* Multi-select menu
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $options
|
||||
* @param array $selected
|
||||
* @param mixed $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_multiselect(string $name = '', array $options = [], array $selected = [], $extra = ''): string
|
||||
{
|
||||
$extra = stringify_attributes($extra);
|
||||
|
||||
if (stripos($extra, 'multiple') === false)
|
||||
{
|
||||
$extra .= ' multiple="multiple"';
|
||||
}
|
||||
|
||||
return form_dropdown($name, $options, $selected, $extra);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_dropdown'))
|
||||
{
|
||||
/**
|
||||
* Drop-down Menu
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param mixed $options
|
||||
* @param mixed $selected
|
||||
* @param mixed $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_dropdown($data = '', $options = [], $selected = [], $extra = ''): string
|
||||
{
|
||||
$defaults = [];
|
||||
if (is_array($data))
|
||||
{
|
||||
if (isset($data['selected']))
|
||||
{
|
||||
$selected = $data['selected'];
|
||||
unset($data['selected']); // select tags don't have a selected attribute
|
||||
}
|
||||
if (isset($data['options']))
|
||||
{
|
||||
$options = $data['options'];
|
||||
unset($data['options']); // select tags don't use an options attribute
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$defaults = ['name' => $data];
|
||||
}
|
||||
|
||||
is_array($selected) || $selected = [$selected];
|
||||
is_array($options) || $options = [$options];
|
||||
|
||||
// If no selected state was submitted we will attempt to set it automatically
|
||||
if (empty($selected))
|
||||
{
|
||||
if (is_array($data))
|
||||
{
|
||||
if (isset($data['name'], $_POST[$data['name']]))
|
||||
{
|
||||
$selected = [$_POST[$data['name']]];
|
||||
}
|
||||
}
|
||||
elseif (isset($_POST[$data]))
|
||||
{
|
||||
$selected = [$_POST[$data]];
|
||||
}
|
||||
}
|
||||
|
||||
$extra = stringify_attributes($extra);
|
||||
$multiple = (count($selected) > 1 && stripos($extra, 'multiple') === false) ? ' multiple="multiple"' : '';
|
||||
$form = '<select ' . rtrim(parse_form_attributes($data, $defaults)) . $extra . $multiple . ">\n";
|
||||
foreach ($options as $key => $val)
|
||||
{
|
||||
$key = (string) $key;
|
||||
if (is_array($val))
|
||||
{
|
||||
if (empty($val))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$form .= '<optgroup label="' . $key . "\">\n";
|
||||
foreach ($val as $optgroup_key => $optgroup_val)
|
||||
{
|
||||
$sel = in_array($optgroup_key, $selected) ? ' selected="selected"' : '';
|
||||
$form .= '<option value="' . htmlspecialchars($optgroup_key) . '"' . $sel . '>'
|
||||
. (string) $optgroup_val . "</option>\n";
|
||||
}
|
||||
$form .= "</optgroup>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$form .= '<option value="' . htmlspecialchars($key) . '"'
|
||||
. (in_array($key, $selected) ? ' selected="selected"' : '') . '>'
|
||||
. (string) $val . "</option>\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $form . "</select>\n";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_checkbox'))
|
||||
{
|
||||
/**
|
||||
* Checkbox Field
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param string $value
|
||||
* @param boolean $checked
|
||||
* @param mixed $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_checkbox($data = '', string $value = '', bool $checked = false, $extra = ''): string
|
||||
{
|
||||
$defaults = [
|
||||
'type' => 'checkbox',
|
||||
'name' => ( ! is_array($data) ? $data : ''),
|
||||
'value' => $value,
|
||||
];
|
||||
|
||||
if (is_array($data) && array_key_exists('checked', $data))
|
||||
{
|
||||
$checked = $data['checked'];
|
||||
if ($checked === false)
|
||||
{
|
||||
unset($data['checked']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['checked'] = 'checked';
|
||||
}
|
||||
}
|
||||
|
||||
if ($checked === true)
|
||||
{
|
||||
$defaults['checked'] = 'checked';
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($defaults['checked']);
|
||||
}
|
||||
|
||||
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . " />\n";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_radio'))
|
||||
{
|
||||
/**
|
||||
* Radio Button
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param string $value
|
||||
* @param boolean $checked
|
||||
* @param mixed $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_radio($data = '', string $value = '', bool $checked = false, $extra = ''): string
|
||||
{
|
||||
is_array($data) || $data = ['name' => $data];
|
||||
$data['type'] = 'radio';
|
||||
|
||||
return form_checkbox($data, $value, $checked, $extra);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_submit'))
|
||||
{
|
||||
/**
|
||||
* Submit Button
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param string $value
|
||||
* @param mixed $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_submit($data = '', string $value = '', $extra = ''): string
|
||||
{
|
||||
$defaults = [
|
||||
'type' => 'submit',
|
||||
'name' => is_array($data) ? '' : $data,
|
||||
'value' => $value,
|
||||
];
|
||||
|
||||
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . " />\n";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_reset'))
|
||||
{
|
||||
/**
|
||||
* Reset Button
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param string $value
|
||||
* @param mixed $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_reset($data = '', string $value = '', $extra = ''): string
|
||||
{
|
||||
$defaults = [
|
||||
'type' => 'reset',
|
||||
'name' => is_array($data) ? '' : $data,
|
||||
'value' => $value,
|
||||
];
|
||||
|
||||
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . " />\n";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_button'))
|
||||
{
|
||||
/**
|
||||
* Form Button
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param string $content
|
||||
* @param mixed $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_button($data = '', string $content = '', $extra = ''): string
|
||||
{
|
||||
$defaults = [
|
||||
'name' => is_array($data) ? '' : $data,
|
||||
'type' => 'button',
|
||||
];
|
||||
|
||||
if (is_array($data) && isset($data['content']))
|
||||
{
|
||||
$content = $data['content'];
|
||||
unset($data['content']); // content is not an attribute
|
||||
}
|
||||
|
||||
return '<button ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . '>'
|
||||
. $content
|
||||
. "</button>\n";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_label'))
|
||||
{
|
||||
/**
|
||||
* Form Label Tag
|
||||
*
|
||||
* @param string $label_text The text to appear onscreen
|
||||
* @param string $id The id the label applies to
|
||||
* @param array $attributes Additional attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_label(string $label_text = '', string $id = '', array $attributes = []): string
|
||||
{
|
||||
$label = '<label';
|
||||
|
||||
if ($id !== '')
|
||||
{
|
||||
$label .= ' for="' . $id . '"';
|
||||
}
|
||||
|
||||
if (is_array($attributes) && $attributes)
|
||||
{
|
||||
foreach ($attributes as $key => $val)
|
||||
{
|
||||
$label .= ' ' . $key . '="' . $val . '"';
|
||||
}
|
||||
}
|
||||
|
||||
return $label . '>' . $label_text . '</label>';
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_datalist'))
|
||||
{
|
||||
/**
|
||||
* Datalist
|
||||
*
|
||||
* The <datalist> element specifies a list of pre-defined options for an <input> element.
|
||||
* Users will see a drop-down list of pre-defined options as they input data.
|
||||
* The list attribute of the <input> element, must refer to the id attribute of the <datalist> element.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_datalist(string $name, string $value, array $options): string
|
||||
{
|
||||
$data = [
|
||||
'type' => 'text',
|
||||
'name' => $name,
|
||||
'list' => $name . '_list',
|
||||
'value' => $value,
|
||||
];
|
||||
|
||||
$out = form_input($data) . "\n";
|
||||
$out .= "<datalist id='" . $name . '_list' . "'>";
|
||||
|
||||
foreach ($options as $option)
|
||||
{
|
||||
$out .= "<option value='$option'>" . "\n";
|
||||
}
|
||||
|
||||
$out .= '</datalist>' . "\n";
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_fieldset'))
|
||||
{
|
||||
/**
|
||||
* Fieldset Tag
|
||||
*
|
||||
* Used to produce <fieldset><legend>text</legend>. To close fieldset
|
||||
* use form_fieldset_close()
|
||||
*
|
||||
* @param string $legend_text The legend text
|
||||
* @param array $attributes Additional attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_fieldset(string $legend_text = '', array $attributes = []): string
|
||||
{
|
||||
$fieldset = '<fieldset' . stringify_attributes($attributes) . ">\n";
|
||||
|
||||
if ($legend_text !== '')
|
||||
{
|
||||
return $fieldset . '<legend>' . $legend_text . "</legend>\n";
|
||||
}
|
||||
|
||||
return $fieldset;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_fieldset_close'))
|
||||
{
|
||||
/**
|
||||
* Fieldset Close Tag
|
||||
*
|
||||
* @param string $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_fieldset_close(string $extra = ''): string
|
||||
{
|
||||
return '</fieldset>' . $extra;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('form_close'))
|
||||
{
|
||||
/**
|
||||
* Form Close Tag
|
||||
*
|
||||
* @param string $extra
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function form_close(string $extra = ''): string
|
||||
{
|
||||
return '</form>' . $extra;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('set_value'))
|
||||
{
|
||||
/**
|
||||
* Form Value
|
||||
*
|
||||
* Grabs a value from the POST array for the specified field so you can
|
||||
* re-populate an input field or textarea
|
||||
*
|
||||
* @param string $field Field name
|
||||
* @param string $default Default value
|
||||
* @param boolean $html_escape Whether to escape HTML special characters or not
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function set_value(string $field, string $default = '', bool $html_escape = true): string
|
||||
{
|
||||
$request = Services::request();
|
||||
|
||||
// Try any old input data we may have first
|
||||
$value = $request->getOldInput($field);
|
||||
|
||||
if ($value === null)
|
||||
{
|
||||
$value = $request->getPost($field) ?? $default;
|
||||
}
|
||||
|
||||
return ($html_escape) ? esc($value, 'html') : $value;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('set_select'))
|
||||
{
|
||||
/**
|
||||
* Set Select
|
||||
*
|
||||
* Let's you set the selected value of a <select> menu via data in the POST array.
|
||||
* If Form Validation is active it retrieves the info from the validation class
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
* @param boolean $default
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function set_select(string $field, string $value = '', bool $default = false): string
|
||||
{
|
||||
$request = Services::request();
|
||||
|
||||
// Try any old input data we may have first
|
||||
$input = $request->getOldInput($field);
|
||||
|
||||
if ($input === null)
|
||||
{
|
||||
$input = $request->getPost($field);
|
||||
}
|
||||
|
||||
if ($input === null)
|
||||
{
|
||||
return ($default === true) ? ' selected="selected"' : '';
|
||||
}
|
||||
|
||||
if (is_array($input))
|
||||
{
|
||||
// Note: in_array('', array(0)) returns TRUE, do not use it
|
||||
foreach ($input as &$v)
|
||||
{
|
||||
if ($value === $v)
|
||||
{
|
||||
return ' selected="selected"';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
return ($input === $value) ? ' selected="selected"' : '';
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('set_checkbox'))
|
||||
{
|
||||
/**
|
||||
* Set Checkbox
|
||||
*
|
||||
* Let's you set the selected value of a checkbox via the value in the POST array.
|
||||
* If Form Validation is active it retrieves the info from the validation class
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
* @param boolean $default
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function set_checkbox(string $field, string $value = '', bool $default = false): string
|
||||
{
|
||||
$request = Services::request();
|
||||
|
||||
// Try any old input data we may have first
|
||||
$input = $request->getOldInput($field);
|
||||
|
||||
if ($input === null)
|
||||
{
|
||||
$input = $request->getPost($field);
|
||||
}
|
||||
|
||||
if (is_array($input))
|
||||
{
|
||||
// Note: in_array('', array(0)) returns TRUE, do not use it
|
||||
foreach ($input as &$v)
|
||||
{
|
||||
if ($value === $v)
|
||||
{
|
||||
return ' checked="checked"';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
// Unchecked checkbox and radio inputs are not even submitted by browsers ...
|
||||
if (! empty($request->getPost()) || ! empty(old($field)))
|
||||
{
|
||||
return ($input === $value) ? ' checked="checked"' : '';
|
||||
}
|
||||
|
||||
return ($default === true) ? ' checked="checked"' : '';
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('set_radio'))
|
||||
{
|
||||
/**
|
||||
* Set Radio
|
||||
*
|
||||
* Let's you set the selected value of a radio field via info in the POST array.
|
||||
* If Form Validation is active it retrieves the info from the validation class
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
* @param boolean $default
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function set_radio(string $field, string $value = '', bool $default = false): string
|
||||
{
|
||||
$request = Services::request();
|
||||
|
||||
// Try any old input data we may have first
|
||||
$input = $request->getOldInput($field);
|
||||
if ($input === null)
|
||||
{
|
||||
$input = $request->getPost($field) ?? $default;
|
||||
}
|
||||
|
||||
if (is_array($input))
|
||||
{
|
||||
// Note: in_array('', array(0)) returns TRUE, do not use it
|
||||
foreach ($input as &$v)
|
||||
{
|
||||
if ($value === $v)
|
||||
{
|
||||
return ' checked="checked"';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
// Unchecked checkbox and radio inputs are not even submitted by browsers ...
|
||||
$result = '';
|
||||
if (! empty($input = $request->getPost($field)) || ! empty($input = old($field)))
|
||||
{
|
||||
$result = ($input === $value) ? ' checked="checked"' : '';
|
||||
}
|
||||
|
||||
if (empty($result))
|
||||
{
|
||||
$result = ($default === true) ? ' checked="checked"' : '';
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('parse_form_attributes'))
|
||||
{
|
||||
/**
|
||||
* Parse the form attributes
|
||||
*
|
||||
* Helper function used by some of the form helpers
|
||||
*
|
||||
* @param string|array $attributes List of attributes
|
||||
* @param array $default Default values
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function parse_form_attributes($attributes, array $default): string
|
||||
{
|
||||
if (is_array($attributes))
|
||||
{
|
||||
foreach ($default as $key => $val)
|
||||
{
|
||||
if (isset($attributes[$key]))
|
||||
{
|
||||
$default[$key] = $attributes[$key];
|
||||
unset($attributes[$key]);
|
||||
}
|
||||
}
|
||||
if (! empty($attributes))
|
||||
{
|
||||
$default = array_merge($default, $attributes);
|
||||
}
|
||||
}
|
||||
|
||||
$att = '';
|
||||
|
||||
foreach ($default as $key => $val)
|
||||
{
|
||||
if (! is_bool($val))
|
||||
{
|
||||
if ($key === 'value')
|
||||
{
|
||||
$val = esc($val, 'html');
|
||||
}
|
||||
elseif ($key === 'name' && ! strlen($default['name']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$att .= $key . '="' . $val . '" ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$att .= $key . ' ';
|
||||
}
|
||||
}
|
||||
|
||||
return $att;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
}
|
||||
726
system/Helpers/html_helper.php
Normal file
726
system/Helpers/html_helper.php
Normal file
@@ -0,0 +1,726 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 4.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* CodeIgniter HTML Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
if (! function_exists('ul'))
|
||||
{
|
||||
/**
|
||||
* Unordered List
|
||||
*
|
||||
* Generates an HTML unordered list from an single or
|
||||
* multi-dimensional array.
|
||||
*
|
||||
* @param array $list
|
||||
* @param string $attributes HTML attributes
|
||||
* @return string
|
||||
*/
|
||||
function ul(array $list, string $attributes = ''): string
|
||||
{
|
||||
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 $list
|
||||
* @param string $attributes HTML attributes
|
||||
* @return string
|
||||
*/
|
||||
function ol(array $list, string $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 string $type
|
||||
* @param mixed $list
|
||||
* @param string $attributes
|
||||
* @param integer $depth
|
||||
* @return string
|
||||
*/
|
||||
function _list(string $type = 'ul', $list = [], string $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";
|
||||
|
||||
// Cycle through the list elements. If an array is
|
||||
// encountered we will recursively call _list()
|
||||
|
||||
static $_last_list_item = '';
|
||||
foreach ($list as $key => $val)
|
||||
{
|
||||
$_last_list_item = $key;
|
||||
|
||||
$out .= str_repeat(' ', $depth + 2) . '<li>';
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('img'))
|
||||
{
|
||||
/**
|
||||
* Image
|
||||
*
|
||||
* Generates an image element
|
||||
*
|
||||
* @param mixed $src
|
||||
* @param boolean $indexPage
|
||||
* @param mixed $attributes
|
||||
* @return string
|
||||
*/
|
||||
function img($src = '', bool $indexPage = false, $attributes = ''): string
|
||||
{
|
||||
if (! is_array($src))
|
||||
{
|
||||
$src = ['src' => $src];
|
||||
}
|
||||
|
||||
if (! isset($src['alt']))
|
||||
{
|
||||
$src['alt'] = $attributes['alt'] ?? '';
|
||||
}
|
||||
|
||||
$img = '<img';
|
||||
|
||||
foreach ($src as $k => $v)
|
||||
{
|
||||
//Include a protocol if nothing is explicitely defined.
|
||||
if ($k === 'src' && ! preg_match('#^([a-z]+:)?//#i', $v))
|
||||
{
|
||||
if ($indexPage === true)
|
||||
{
|
||||
$img .= ' src="' . site_url($v) . '"';
|
||||
}
|
||||
else
|
||||
{
|
||||
$img .= ' src="' . slash_item('baseURL') . $v . '"';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$img .= ' ' . $k . '="' . $v . '"';
|
||||
}
|
||||
}
|
||||
|
||||
// prevent passing "alt" to stringify_attributes
|
||||
if (is_array($attributes) && isset($attributes['alt']))
|
||||
{
|
||||
unset($attributes['alt']);
|
||||
}
|
||||
|
||||
return $img . stringify_attributes($attributes) . ' />';
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
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(string $type = 'html5'): string
|
||||
{
|
||||
$config = new \Config\DocTypes();
|
||||
$doctypes = $config->list;
|
||||
return $doctypes[$type] ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('script_tag'))
|
||||
{
|
||||
/**
|
||||
* Script
|
||||
*
|
||||
* Generates link to a JS file
|
||||
*
|
||||
* @param mixed $src Script source or an array
|
||||
* @param boolean $indexPage Should indexPage be added to the JS path
|
||||
* @return string
|
||||
*/
|
||||
function script_tag($src = '', bool $indexPage = false): string
|
||||
{
|
||||
$script = '<script ';
|
||||
if (! is_array($src))
|
||||
{
|
||||
$src = ['src' => $src];
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
$script .= $k . '="' . $v . '" ';
|
||||
}
|
||||
}
|
||||
|
||||
return $script . 'type="text/javascript"' . '></script>';
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('link_tag'))
|
||||
{
|
||||
/**
|
||||
* Link
|
||||
*
|
||||
* Generates link to a CSS file
|
||||
*
|
||||
* @param mixed $href Stylesheet href or an array
|
||||
* @param string $rel
|
||||
* @param string $type
|
||||
* @param string $title
|
||||
* @param string $media
|
||||
* @param boolean $indexPage should indexPage be added to the CSS path.
|
||||
* @return string
|
||||
*/
|
||||
function link_tag($href = '', string $rel = 'stylesheet', string $type = 'text/css', string $title = '', string $media = '', bool $indexPage = false): string
|
||||
{
|
||||
$link = '<link ';
|
||||
|
||||
// extract fields if needed
|
||||
if (is_array($href))
|
||||
{
|
||||
$rel = $href['rel'] ?? $rel;
|
||||
$type = $href['type'] ?? $type;
|
||||
$title = $href['title'] ?? $title;
|
||||
$media = $href['media'] ?? $media;
|
||||
$indexPage = $href['indexPage'] ?? $indexPage;
|
||||
$href = $href['href'] ?? '';
|
||||
}
|
||||
|
||||
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 . '" ';
|
||||
}
|
||||
|
||||
$link .= 'rel="' . $rel . '" 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 mixed $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
|
||||
* @param array $tracks
|
||||
* @param boolean $indexPage
|
||||
* @return string
|
||||
*/
|
||||
function video($src, string $unsupportedMessage = '', string $attributes = '', array $tracks = [], bool $indexPage = false): string
|
||||
{
|
||||
if (is_array($src))
|
||||
{
|
||||
return _media('video', $src, $unsupportedMessage, $attributes, $tracks);
|
||||
}
|
||||
|
||||
$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";
|
||||
|
||||
if (! empty($tracks))
|
||||
{
|
||||
foreach ($tracks as $track)
|
||||
{
|
||||
$video .= _space_indent() . $track . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($unsupportedMessage))
|
||||
{
|
||||
$video .= _space_indent()
|
||||
. $unsupportedMessage
|
||||
. "\n";
|
||||
}
|
||||
|
||||
$video .= "</video>\n";
|
||||
|
||||
return $video;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('audio'))
|
||||
{
|
||||
/**
|
||||
* Audio
|
||||
*
|
||||
* Generates an audio element to embed sounds
|
||||
*
|
||||
* @param mixed $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
|
||||
* @param array $tracks
|
||||
* @param boolean $indexPage
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function audio($src, string $unsupportedMessage = '', string $attributes = '', array $tracks = [], bool $indexPage = false): string
|
||||
{
|
||||
if (is_array($src))
|
||||
{
|
||||
return _media('audio', $src, $unsupportedMessage, $attributes, $tracks);
|
||||
}
|
||||
|
||||
$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 .= '>';
|
||||
|
||||
if (! empty($tracks))
|
||||
{
|
||||
foreach ($tracks as $track)
|
||||
{
|
||||
$audio .= "\n" . _space_indent() . $track;
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($unsupportedMessage))
|
||||
{
|
||||
$audio .= "\n" . _space_indent() . $unsupportedMessage . "\n";
|
||||
}
|
||||
|
||||
$audio .= "</audio>\n";
|
||||
|
||||
return $audio;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('_media'))
|
||||
{
|
||||
/**
|
||||
* Generate media based tag
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $types
|
||||
* @param string $unsupportedMessage The message to display if the media tag is not supported by the browser.
|
||||
* @param string $attributes
|
||||
* @param array $tracks
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
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";
|
||||
}
|
||||
|
||||
if (! empty($tracks))
|
||||
{
|
||||
foreach ($tracks as $track)
|
||||
{
|
||||
$media .= _space_indent() . $track . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($unsupportedMessage))
|
||||
{
|
||||
$media .= _space_indent() . $unsupportedMessage . "\n";
|
||||
}
|
||||
|
||||
$media .= '</' . $name . ">\n";
|
||||
|
||||
return $media;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
* @param boolean $indexPage
|
||||
* @return string
|
||||
*/
|
||||
function source(string $src, string $type = 'unknown', string $attributes = '', bool $indexPage = false): string
|
||||
{
|
||||
if (! _has_protocol($src))
|
||||
{
|
||||
if ($indexPage === true)
|
||||
{
|
||||
$src = site_url($src);
|
||||
}
|
||||
else
|
||||
{
|
||||
$src = slash_item('baseURL') . $src;
|
||||
}
|
||||
}
|
||||
|
||||
$source = '<source src="' . $src
|
||||
. '" type="' . $type . '"';
|
||||
|
||||
if (! empty($attributes))
|
||||
{
|
||||
$source .= ' ' . $attributes;
|
||||
}
|
||||
|
||||
$source .= ' />';
|
||||
|
||||
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
|
||||
* @param string $kind
|
||||
* @param string $srcLanguage
|
||||
* @param string $label
|
||||
* @return string
|
||||
*/
|
||||
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
|
||||
* @param array $params
|
||||
* @param boolean $indexPage
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function object(string $data, string $type = 'unknown', string $attributes = '', array $params = [], bool $indexPage = false): string
|
||||
{
|
||||
if (! _has_protocol($data))
|
||||
{
|
||||
if ($indexPage === true)
|
||||
{
|
||||
$data = site_url($data);
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = slash_item('baseURL') . $data;
|
||||
}
|
||||
}
|
||||
|
||||
$object = '<object data="' . $data . '" '
|
||||
. $attributes . '>';
|
||||
|
||||
if (! empty($params))
|
||||
{
|
||||
$object .= "\n";
|
||||
}
|
||||
|
||||
foreach ($params as $param)
|
||||
{
|
||||
$object .= _space_indent() . $param . "\n";
|
||||
}
|
||||
|
||||
$object .= "</object>\n";
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
* @return string
|
||||
*/
|
||||
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
|
||||
* @param boolean $indexPage
|
||||
* @return string
|
||||
*/
|
||||
function embed(string $src, string $type = 'unknown', string $attributes = '', bool $indexPage = false): string
|
||||
{
|
||||
if (! _has_protocol($src))
|
||||
{
|
||||
if ($indexPage === true)
|
||||
{
|
||||
$src = site_url($src);
|
||||
}
|
||||
else
|
||||
{
|
||||
$src = slash_item('baseURL') . $src;
|
||||
}
|
||||
}
|
||||
|
||||
return '<embed src="' . $src
|
||||
. '" type="' . $type . '" '
|
||||
. $attributes . " />\n";
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('_has_protocol'))
|
||||
{
|
||||
/**
|
||||
* Test the protocol of a URI.
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return false|integer
|
||||
*/
|
||||
function _has_protocol(string $url)
|
||||
{
|
||||
return preg_match('#^([a-z]+:)?//#i', $url);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('_space_indent'))
|
||||
{
|
||||
/**
|
||||
* Provide space indenting.
|
||||
*
|
||||
* @param integer $depth
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function _space_indent(int $depth = 2): string
|
||||
{
|
||||
return str_repeat(' ', $depth);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
406
system/Helpers/inflector_helper.php
Normal file
406
system/Helpers/inflector_helper.php
Normal file
@@ -0,0 +1,406 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 4.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* CodeIgniter Inflector Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
if (! function_exists('singular'))
|
||||
{
|
||||
/**
|
||||
* Singular
|
||||
*
|
||||
* Takes a plural word and makes it singular
|
||||
*
|
||||
* @param string $string Input string
|
||||
* @return string
|
||||
*/
|
||||
function singular(string $string): string
|
||||
{
|
||||
$result = strval($string);
|
||||
|
||||
if (! is_pluralizable($result))
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
|
||||
//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 ($singularRules as $rule => $replacement)
|
||||
{
|
||||
if (preg_match($rule, $result))
|
||||
{
|
||||
$result = preg_replace($rule, $replacement, $result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('plural'))
|
||||
{
|
||||
/**
|
||||
* Plural
|
||||
*
|
||||
* Takes a singular word and makes it plural
|
||||
*
|
||||
* @param string $string Input string
|
||||
* @return string
|
||||
*/
|
||||
function plural(string $string): string
|
||||
{
|
||||
$result = strval($string);
|
||||
|
||||
if (! is_pluralizable($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',
|
||||
];
|
||||
|
||||
foreach ($pluralRules as $rule => $replacement)
|
||||
{
|
||||
if (preg_match($rule, $result))
|
||||
{
|
||||
$result = preg_replace($rule, $replacement, $result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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 integer $count Number of items
|
||||
* @param string $string Input string
|
||||
* @return string
|
||||
*/
|
||||
function counted(int $count, string $string): string
|
||||
{
|
||||
$result = "{$count} ";
|
||||
$result .= $count === 1 ? singular($string) : plural($string);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('camelize'))
|
||||
{
|
||||
/**
|
||||
* Camelize
|
||||
*
|
||||
* Takes multiple words separated by spaces or
|
||||
* underscores and converts them to camel case.
|
||||
*
|
||||
* @param string $string Input string
|
||||
* @return string
|
||||
*/
|
||||
function camelize(string $string): string
|
||||
{
|
||||
return lcfirst(str_replace(' ', '', ucwords(preg_replace('/[\s_]+/', ' ', $string))));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
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
|
||||
* @return 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
|
||||
* @return string
|
||||
*/
|
||||
function underscore(string $string): string
|
||||
{
|
||||
$replacement = trim($string);
|
||||
|
||||
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
|
||||
* @return string
|
||||
*/
|
||||
function humanize(string $string, string $separator = '_'): string
|
||||
{
|
||||
$replacement = trim($string);
|
||||
$upperCased = ucwords
|
||||
(
|
||||
preg_replace('/[' . $separator . ']+/', ' ', $replacement)
|
||||
);
|
||||
|
||||
return $upperCased;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('is_pluralizable'))
|
||||
{
|
||||
/**
|
||||
* Checks if the given word has a plural version.
|
||||
*
|
||||
* @param string $word Word to check
|
||||
* @return boolean
|
||||
*/
|
||||
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',
|
||||
]);
|
||||
|
||||
return ! $uncountables;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('dasherize'))
|
||||
{
|
||||
/**
|
||||
* Replaces underscores with dashes in the string.
|
||||
*
|
||||
* @param string $string Input string
|
||||
* @return 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 integer $integer The integer to determine
|
||||
* the suffix
|
||||
* @return string
|
||||
*/
|
||||
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 integer $integer The integer to ordinalize
|
||||
* @return string
|
||||
*/
|
||||
function ordinalize(int $integer): string
|
||||
{
|
||||
return $integer . ordinal($integer);
|
||||
}
|
||||
}
|
||||
338
system/Helpers/number_helper.php
Normal file
338
system/Helpers/number_helper.php
Normal file
@@ -0,0 +1,338 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2008-2014 EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
/**
|
||||
* CodeIgniter Number Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
|
||||
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 integer $precision
|
||||
* @param string $locale
|
||||
*
|
||||
* @return boolean|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;
|
||||
}
|
||||
|
||||
// ignore sub part
|
||||
$generalLocale = $locale;
|
||||
if (! empty($locale) && ( $underscorePos = strpos($locale, '_')))
|
||||
{
|
||||
$generalLocale = substr($locale, 0, $underscorePos);
|
||||
}
|
||||
|
||||
if ($num >= 1000000000000)
|
||||
{
|
||||
$num = round($num / 1099511627776, $precision);
|
||||
$unit = lang('Number.terabyteAbbr', [], $generalLocale);
|
||||
}
|
||||
elseif ($num >= 1000000000)
|
||||
{
|
||||
$num = round($num / 1073741824, $precision);
|
||||
$unit = lang('Number.gigabyteAbbr', [], $generalLocale);
|
||||
}
|
||||
elseif ($num >= 1000000)
|
||||
{
|
||||
$num = round($num / 1048576, $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
|
||||
* @param integer $precision
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return boolean|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 > 1000000000000000)
|
||||
{
|
||||
$suffix = lang('Number.quadrillion', [], $generalLocale);
|
||||
$num = round(($num / 1000000000000000), $precision);
|
||||
}
|
||||
elseif ($num > 1000000000000)
|
||||
{
|
||||
$suffix = lang('Number.trillion', [], $generalLocale);
|
||||
$num = round(($num / 1000000000000), $precision);
|
||||
}
|
||||
else if ($num > 1000000000)
|
||||
{
|
||||
$suffix = lang('Number.billion', [], $generalLocale);
|
||||
$num = round(($num / 1000000000), $precision);
|
||||
}
|
||||
else if ($num > 1000000)
|
||||
{
|
||||
$suffix = lang('Number.million', [], $generalLocale);
|
||||
$num = round(($num / 1000000), $precision);
|
||||
}
|
||||
else if ($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'))
|
||||
{
|
||||
/**
|
||||
* @param float $num
|
||||
* @param string $currency
|
||||
* @param string $locale
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function number_to_currency(float $num, string $currency, string $locale = null): string
|
||||
{
|
||||
return format_number($num, 1, $locale, [
|
||||
'type' => NumberFormatter::CURRENCY,
|
||||
'currency' => $currency,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('format_number'))
|
||||
{
|
||||
/**
|
||||
* A general purpose, locale-aware, number_format method.
|
||||
* Used by all of the functions of the number_helper.
|
||||
*
|
||||
* @param float $num
|
||||
* @param integer $precision
|
||||
* @param string|null $locale
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function format_number(float $num, int $precision = 1, string $locale = null, array $options = []): string
|
||||
{
|
||||
// Locale is either passed in here, negotiated with client, or grabbed from our config file.
|
||||
$locale = $locale ?? \CodeIgniter\Config\Services::request()->getLocale();
|
||||
|
||||
// Type can be any of the NumberFormatter options, but provide a default.
|
||||
$type = (int) ($options['type'] ?? NumberFormatter::DECIMAL);
|
||||
|
||||
// In order to specify a precision, we'll have to modify
|
||||
// the pattern used by NumberFormatter.
|
||||
$pattern = '#,##0.' . str_repeat('#', $precision);
|
||||
|
||||
$formatter = new NumberFormatter($locale, $type);
|
||||
|
||||
// Try to format it per the locale
|
||||
if ($type === NumberFormatter::CURRENCY)
|
||||
{
|
||||
$output = $formatter->formatCurrency($num, $options['currency']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$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
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function number_to_roman(string $num): ?string
|
||||
{
|
||||
$num = (int) $num;
|
||||
if ($num < 1 || $num > 3999)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$_number_to_roman = function ($num, $th) use (&$_number_to_roman) {
|
||||
$return = '';
|
||||
$key1 = null;
|
||||
$key2 = null;
|
||||
switch ($th) {
|
||||
case 1:
|
||||
$key1 = 'I';
|
||||
$key2 = 'V';
|
||||
$key_f = 'X';
|
||||
break;
|
||||
case 2:
|
||||
$key1 = 'X';
|
||||
$key2 = 'L';
|
||||
$key_f = 'C';
|
||||
break;
|
||||
case 3:
|
||||
$key1 = 'C';
|
||||
$key2 = 'D';
|
||||
$key_f = 'M';
|
||||
break;
|
||||
case 4:
|
||||
$key1 = 'M';
|
||||
break;
|
||||
}
|
||||
$n = $num % 10;
|
||||
switch ($n) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
$return = str_repeat($key1, $n);
|
||||
break;
|
||||
case 4:
|
||||
$return = $key1 . $key2;
|
||||
break;
|
||||
case 5:
|
||||
$return = $key2;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
$return = $key2 . str_repeat($key1, $n - 5);
|
||||
break;
|
||||
case 9:
|
||||
$return = $key1 . $key_f;
|
||||
break;
|
||||
}
|
||||
switch ($num) {
|
||||
case 10:
|
||||
$return = $key_f;
|
||||
break;
|
||||
}
|
||||
if ($num > 10)
|
||||
{
|
||||
$return = $_number_to_roman($num / 10, ++ $th) . $return;
|
||||
}
|
||||
return $return;
|
||||
};
|
||||
return $_number_to_roman($num, 1);
|
||||
}
|
||||
}
|
||||
99
system/Helpers/security_helper.php
Normal file
99
system/Helpers/security_helper.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 4.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
use Config\Services;
|
||||
|
||||
/**
|
||||
* CodeIgniter Security Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
|
||||
if (! function_exists('sanitize_filename'))
|
||||
{
|
||||
/**
|
||||
* Sanitize a filename to use in a URI.
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function sanitize_filename(string $filename): string
|
||||
{
|
||||
return Services::security()->sanitizeFilename($filename);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('strip_image_tags'))
|
||||
{
|
||||
/**
|
||||
* Strip Image Tags
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
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('encode_php_tags'))
|
||||
{
|
||||
/**
|
||||
* Convert PHP tags to entities
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
function encode_php_tags(string $str): string
|
||||
{
|
||||
return str_replace(['<?', '?>'], ['<?', '?>'], $str);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
883
system/Helpers/text_helper.php
Normal file
883
system/Helpers/text_helper.php
Normal file
@@ -0,0 +1,883 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2008-2014 EllisLab, Inc. (https://ellislab.com/)
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
/**
|
||||
* CodeIgniter Text Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('word_limiter'))
|
||||
{
|
||||
/**
|
||||
* Word Limiter
|
||||
*
|
||||
* Limits a string to X number of words.
|
||||
*
|
||||
* @param string $str
|
||||
* @param integer $limit
|
||||
* @param string $end_char the end character. Usually an ellipsis
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function word_limiter(string $str, int $limit = 100, string $end_char = '…'): string
|
||||
{
|
||||
if (trim($str) === '')
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
preg_match('/^\s*+(?:\S++\s*+){1,' . (int) $limit . '}/', $str, $matches);
|
||||
|
||||
if (strlen($str) === strlen($matches[0]))
|
||||
{
|
||||
$end_char = '';
|
||||
}
|
||||
|
||||
return rtrim($matches[0]) . $end_char;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('character_limiter'))
|
||||
{
|
||||
/**
|
||||
* Character Limiter
|
||||
*
|
||||
* Limits the string based on the character count. Preserves complete words
|
||||
* so the character count may not be exactly as specified.
|
||||
*
|
||||
* @param string $str
|
||||
* @param integer $n
|
||||
* @param string $end_char the end character. Usually an ellipsis
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function character_limiter(string $str, int $n = 500, string $end_char = '…'): string
|
||||
{
|
||||
if (mb_strlen($str) < $n)
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
// a bit complicated, but faster than preg_replace with \s+
|
||||
$str = preg_replace('/ {2,}/', ' ', str_replace(["\r", "\n", "\t", "\x0B", "\x0C"], ' ', $str));
|
||||
|
||||
if (mb_strlen($str) <= $n)
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
$out = '';
|
||||
|
||||
foreach (explode(' ', trim($str)) as $val)
|
||||
{
|
||||
$out .= $val . ' ';
|
||||
if (mb_strlen($out) >= $n)
|
||||
{
|
||||
$out = trim($out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (mb_strlen($out) === mb_strlen($str)) ? $out : $out . $end_char;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('ascii_to_entities'))
|
||||
{
|
||||
/**
|
||||
* High ASCII to Entities
|
||||
*
|
||||
* Converts high ASCII text and MS Word special characters to character entities
|
||||
*
|
||||
* @param string $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function ascii_to_entities(string $str): string
|
||||
{
|
||||
$out = '';
|
||||
|
||||
for ($i = 0, $s = strlen($str) - 1, $count = 1, $temp = []; $i <= $s; $i ++)
|
||||
{
|
||||
$ordinal = ord($str[$i]);
|
||||
|
||||
if ($ordinal < 128)
|
||||
{
|
||||
/*
|
||||
If the $temp array has a value but we have moved on, then it seems only
|
||||
fair that we output that entity and restart $temp before continuing.
|
||||
*/
|
||||
if (count($temp) === 1)
|
||||
{
|
||||
$out .= '&#' . array_shift($temp) . ';';
|
||||
$count = 1;
|
||||
}
|
||||
|
||||
$out .= $str[$i];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (empty($temp))
|
||||
{
|
||||
$count = ($ordinal < 224) ? 2 : 3;
|
||||
}
|
||||
|
||||
$temp[] = $ordinal;
|
||||
|
||||
if (count($temp) === $count)
|
||||
{
|
||||
$number = ($count === 3) ? (($temp[0] % 16) * 4096) + (($temp[1] % 64) * 64) + ($temp[2] % 64) : (($temp[0] % 32) * 64) + ($temp[1] % 64);
|
||||
$out .= '&#' . $number . ';';
|
||||
$count = 1;
|
||||
$temp = [];
|
||||
}
|
||||
// If this is the last iteration, just output whatever we have
|
||||
elseif ($i === $s)
|
||||
{
|
||||
$out .= '&#' . implode(';', $temp) . ';';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('entities_to_ascii'))
|
||||
{
|
||||
/**
|
||||
* Entities to ASCII
|
||||
*
|
||||
* Converts character entities back to ASCII
|
||||
*
|
||||
* @param string $str
|
||||
* @param boolean $all
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function entities_to_ascii(string $str, bool $all = true): string
|
||||
{
|
||||
if (preg_match_all('/\&#(\d+)\;/', $str, $matches))
|
||||
{
|
||||
for ($i = 0, $s = count($matches[0]); $i < $s; $i ++)
|
||||
{
|
||||
$digits = $matches[1][$i];
|
||||
$out = '';
|
||||
if ($digits < 128)
|
||||
{
|
||||
$out .= chr($digits);
|
||||
}
|
||||
elseif ($digits < 2048)
|
||||
{
|
||||
$out .= chr(192 + (($digits - ($digits % 64)) / 64)) . chr(128 + ($digits % 64));
|
||||
}
|
||||
else
|
||||
{
|
||||
$out .= chr(224 + (($digits - ($digits % 4096)) / 4096))
|
||||
. chr(128 + ((($digits % 4096) - ($digits % 64)) / 64))
|
||||
. chr(128 + ($digits % 64));
|
||||
}
|
||||
$str = str_replace($matches[0][$i], $out, $str);
|
||||
}
|
||||
}
|
||||
|
||||
if ($all)
|
||||
{
|
||||
return str_replace([
|
||||
'&',
|
||||
'<',
|
||||
'>',
|
||||
'"',
|
||||
''',
|
||||
'-',
|
||||
], [
|
||||
'&',
|
||||
'<',
|
||||
'>',
|
||||
'"',
|
||||
"'",
|
||||
'-',
|
||||
], $str
|
||||
);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('word_censor'))
|
||||
{
|
||||
/**
|
||||
* Word Censoring Function
|
||||
*
|
||||
* Supply a string and an array of disallowed words and any
|
||||
* matched words will be converted to #### or to the replacement
|
||||
* word you've submitted.
|
||||
*
|
||||
* @param string $str the text string
|
||||
* @param array $censored the array of censored words
|
||||
* @param string $replacement the optional replacement value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function word_censor(string $str, array $censored, string $replacement = ''): string
|
||||
{
|
||||
if (empty($censored))
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
$str = ' ' . $str . ' ';
|
||||
|
||||
// \w, \b and a few others do not match on a unicode character
|
||||
// set for performance reasons. As a result words like über
|
||||
// will not match on a word boundary. Instead, we'll assume that
|
||||
// a bad word will be bookended by any of these characters.
|
||||
$delim = '[-_\'\"`(){}<>\[\]|!?@#%&,.:;^~*+=\/ 0-9\n\r\t]';
|
||||
|
||||
foreach ($censored as $badword)
|
||||
{
|
||||
$badword = str_replace('\*', '\w*?', preg_quote($badword, '/'));
|
||||
|
||||
if ($replacement !== '')
|
||||
{
|
||||
$str = preg_replace(
|
||||
"/({$delim})(" . $badword . ")({$delim})/i", "\\1{$replacement}\\3", $str
|
||||
);
|
||||
}
|
||||
elseif (preg_match_all("/{$delim}(" . $badword . "){$delim}/i", $str, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE))
|
||||
{
|
||||
$matches = $matches[1];
|
||||
|
||||
for ($i = count($matches) - 1; $i >= 0; $i --)
|
||||
{
|
||||
$length = strlen($matches[$i][0]);
|
||||
$str = substr_replace(
|
||||
$str, str_repeat('#', $length), $matches[$i][1], $length
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return trim($str);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('highlight_code'))
|
||||
{
|
||||
/**
|
||||
* Code Highlighter
|
||||
*
|
||||
* Colorizes code strings
|
||||
*
|
||||
* @param string $str the text string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function highlight_code(string $str): string
|
||||
{
|
||||
/* The highlight string function encodes and highlights
|
||||
* brackets so we need them to start raw.
|
||||
*
|
||||
* Also replace any existing PHP tags to temporary markers
|
||||
* so they don't accidentally break the string out of PHP,
|
||||
* and thus, thwart the highlighting.
|
||||
*/
|
||||
$str = str_replace([
|
||||
'<',
|
||||
'>',
|
||||
'<?',
|
||||
'?>',
|
||||
'<%',
|
||||
'%>',
|
||||
'\\',
|
||||
'</script>',
|
||||
], [
|
||||
'<',
|
||||
'>',
|
||||
'phptagopen',
|
||||
'phptagclose',
|
||||
'asptagopen',
|
||||
'asptagclose',
|
||||
'backslashtmp',
|
||||
'scriptclose',
|
||||
], $str
|
||||
);
|
||||
|
||||
// The highlight_string function requires that the text be surrounded
|
||||
// by PHP tags, which we will remove later
|
||||
$str = highlight_string('<?php ' . $str . ' ?>', true);
|
||||
|
||||
// Remove our artificially added PHP, and the syntax highlighting that came with it
|
||||
$str = preg_replace([
|
||||
'/<span style="color: #([A-Z0-9]+)"><\?php( | )/i',
|
||||
'/(<span style="color: #[A-Z0-9]+">.*?)\?><\/span>\n<\/span>\n<\/code>/is',
|
||||
'/<span style="color: #[A-Z0-9]+"\><\/span>/i',
|
||||
], [
|
||||
'<span style="color: #$1">',
|
||||
"$1</span>\n</span>\n</code>",
|
||||
'',
|
||||
], $str
|
||||
);
|
||||
|
||||
// Replace our markers back to PHP tags.
|
||||
return str_replace([
|
||||
'phptagopen',
|
||||
'phptagclose',
|
||||
'asptagopen',
|
||||
'asptagclose',
|
||||
'backslashtmp',
|
||||
'scriptclose',
|
||||
], [
|
||||
'<?',
|
||||
'?>',
|
||||
'<%',
|
||||
'%>',
|
||||
'\\',
|
||||
'</script>',
|
||||
], $str
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('highlight_phrase'))
|
||||
{
|
||||
/**
|
||||
* Phrase Highlighter
|
||||
*
|
||||
* Highlights a phrase within a text string
|
||||
*
|
||||
* @param string $str the text string
|
||||
* @param string $phrase the phrase you'd like to highlight
|
||||
* @param string $tag_open the opening tag to precede the phrase with
|
||||
* @param string $tag_close the closing tag to end the phrase with
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function highlight_phrase(string $str, string $phrase, string $tag_open = '<mark>', string $tag_close = '</mark>'): string
|
||||
{
|
||||
return ($str !== '' && $phrase !== '') ? preg_replace('/(' . preg_quote($phrase, '/') . ')/i', $tag_open . '\\1' . $tag_close, $str) : $str;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('convert_accented_characters'))
|
||||
{
|
||||
/**
|
||||
* Convert Accented Foreign Characters to ASCII
|
||||
*
|
||||
* @param string $str Input string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function convert_accented_characters(string $str): string
|
||||
{
|
||||
static $array_from, $array_to;
|
||||
|
||||
if (! is_array($array_from))
|
||||
{
|
||||
$config = new Config\ForeignCharacters();
|
||||
|
||||
if (empty($config->characterList) || ! is_array($config->characterList))
|
||||
{
|
||||
$array_from = [];
|
||||
$array_to = [];
|
||||
|
||||
return $str;
|
||||
}
|
||||
$array_from = array_keys($config->characterList);
|
||||
$array_to = array_values($config->characterList);
|
||||
|
||||
unset($config);
|
||||
}
|
||||
|
||||
return preg_replace($array_from, $array_to, $str);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('word_wrap'))
|
||||
{
|
||||
/**
|
||||
* Word Wrap
|
||||
*
|
||||
* Wraps text at the specified character. Maintains the integrity of words.
|
||||
* Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor
|
||||
* will URLs.
|
||||
*
|
||||
* @param string $str the text string
|
||||
* @param integer $charlim = 76 the number of characters to wrap at
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function word_wrap(string $str, int $charlim = 76): string
|
||||
{
|
||||
// Set the character limit
|
||||
is_numeric($charlim) || $charlim = 76;
|
||||
|
||||
// Reduce multiple spaces
|
||||
$str = preg_replace('| +|', ' ', $str);
|
||||
|
||||
// Standardize newlines
|
||||
if (strpos($str, "\r") !== false)
|
||||
{
|
||||
$str = str_replace(["\r\n", "\r"], "\n", $str);
|
||||
}
|
||||
|
||||
// If the current word is surrounded by {unwrap} tags we'll
|
||||
// strip the entire chunk and replace it with a marker.
|
||||
$unwrap = [];
|
||||
|
||||
if (preg_match_all('|\{unwrap\}(.+?)\{/unwrap\}|s', $str, $matches))
|
||||
{
|
||||
for ($i = 0, $c = count($matches[0]); $i < $c; $i ++)
|
||||
{
|
||||
$unwrap[] = $matches[1][$i];
|
||||
$str = str_replace($matches[0][$i], '{{unwrapped' . $i . '}}', $str);
|
||||
}
|
||||
}
|
||||
|
||||
// Use PHP's native function to do the initial wordwrap.
|
||||
// We set the cut flag to FALSE so that any individual words that are
|
||||
// too long get left alone. In the next step we'll deal with them.
|
||||
$str = wordwrap($str, $charlim, "\n", false);
|
||||
|
||||
// Split the string into individual lines of text and cycle through them
|
||||
$output = '';
|
||||
|
||||
foreach (explode("\n", $str) as $line)
|
||||
{
|
||||
// Is the line within the allowed character count?
|
||||
// If so we'll join it to the output and continue
|
||||
if (mb_strlen($line) <= $charlim)
|
||||
{
|
||||
$output .= $line . "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
$temp = '';
|
||||
|
||||
while (mb_strlen($line) > $charlim)
|
||||
{
|
||||
// If the over-length word is a URL we won't wrap it
|
||||
if (preg_match('!\[url.+\]|://|www\.!', $line))
|
||||
{
|
||||
break;
|
||||
}
|
||||
// Trim the word down
|
||||
$temp .= mb_substr($line, 0, $charlim - 1);
|
||||
$line = mb_substr($line, $charlim - 1);
|
||||
}
|
||||
|
||||
// If $temp contains data it means we had to split up an over-length
|
||||
// word into smaller chunks so we'll add it back to our current line
|
||||
if ($temp !== '')
|
||||
{
|
||||
$output .= $temp . "\n" . $line . "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$output .= $line . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Put our markers back
|
||||
if (! empty($unwrap))
|
||||
{
|
||||
foreach ($unwrap as $key => $val)
|
||||
{
|
||||
$output = str_replace('{{unwrapped' . $key . '}}', $val, $output);
|
||||
}
|
||||
}
|
||||
|
||||
// remove any trailing newline
|
||||
$output = rtrim($output);
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('ellipsize'))
|
||||
{
|
||||
/**
|
||||
* Ellipsize String
|
||||
*
|
||||
* This function will strip tags from a string, split it at its max_length and ellipsize
|
||||
*
|
||||
* @param string $str String to ellipsize
|
||||
* @param integer $max_length Max length of string
|
||||
* @param mixed $position int (1|0) or float, .5, .2, etc for position to split
|
||||
* @param string $ellipsis ellipsis ; Default '...'
|
||||
*
|
||||
* @return string Ellipsized string
|
||||
*/
|
||||
function ellipsize(string $str, int $max_length, $position = 1, string $ellipsis = '…'): string
|
||||
{
|
||||
// Strip tags
|
||||
$str = trim(strip_tags($str));
|
||||
|
||||
// Is the string long enough to ellipsize?
|
||||
if (mb_strlen($str) <= $max_length)
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
$beg = mb_substr($str, 0, floor($max_length * $position));
|
||||
$position = ($position > 1) ? 1 : $position;
|
||||
|
||||
if ($position === 1)
|
||||
{
|
||||
$end = mb_substr($str, 0, -($max_length - mb_strlen($beg)));
|
||||
}
|
||||
else
|
||||
{
|
||||
$end = mb_substr($str, -($max_length - mb_strlen($beg)));
|
||||
}
|
||||
|
||||
return $beg . $ellipsis . $end;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('strip_slashes'))
|
||||
{
|
||||
/**
|
||||
* Strip Slashes
|
||||
*
|
||||
* Removes slashes contained in a string or in an array
|
||||
*
|
||||
* @param mixed $str 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 $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function strip_quotes(string $str): string
|
||||
{
|
||||
return str_replace(['"', "'"], '', $str);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('quotes_to_entities'))
|
||||
{
|
||||
/**
|
||||
* Quotes to Entities
|
||||
*
|
||||
* Converts single and double quotes to entities
|
||||
*
|
||||
* @param string $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function quotes_to_entities(string $str): string
|
||||
{
|
||||
return str_replace(["\'", '"', "'", '"'], [''', '"', ''', '"'], $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 $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function reduce_double_slashes(string $str): string
|
||||
{
|
||||
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 $str
|
||||
* @param string $character the character you wish to reduce
|
||||
* @param boolean $trim TRUE/FALSE - whether to trim the character from the beginning/end
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function reduce_multiples(string $str, string $character = ',', bool $trim = false): string
|
||||
{
|
||||
$str = preg_replace('#' . preg_quote($character, '#') . '{2,}#', $character, $str);
|
||||
|
||||
return ($trim) ? trim($str, $character) : $str;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('random_string'))
|
||||
{
|
||||
/**
|
||||
* Create a Random String
|
||||
*
|
||||
* Useful for generating passwords or hashes.
|
||||
*
|
||||
* @param string $type Type of random string. basic, alpha, alnum, numeric, nozero, md5, sha1, and crypto
|
||||
* @param integer $len Number of characters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function random_string(string $type = 'alnum', int $len = 8): string
|
||||
{
|
||||
switch ($type)
|
||||
{
|
||||
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 'md5':
|
||||
return md5(uniqid(mt_rand(), true));
|
||||
case 'sha1':
|
||||
return sha1(uniqid(mt_rand(), true));
|
||||
case 'crypto':
|
||||
return bin2hex(random_bytes($len / 2));
|
||||
}
|
||||
// 'basic' type treated as default
|
||||
return (string) mt_rand();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('increment_string'))
|
||||
{
|
||||
/**
|
||||
* Add's _1 to a string or increment the ending number to allow _2, _3, etc
|
||||
*
|
||||
* @param string $str Required
|
||||
* @param string $separator What should the duplicate number be appended with
|
||||
* @param integer $first Which number should be used for the first dupe increment
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function increment_string(string $str, string $separator = '_', int $first = 1): string
|
||||
{
|
||||
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(): string
|
||||
{
|
||||
static $i;
|
||||
|
||||
if (func_num_args() === 0)
|
||||
{
|
||||
$i = 0;
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$args = func_get_args();
|
||||
|
||||
return $args[($i++ % count($args))];
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('excerpt'))
|
||||
{
|
||||
/**
|
||||
* Excerpt.
|
||||
*
|
||||
* Allows to extract a piece of text surrounding a word or phrase.
|
||||
*
|
||||
* @param string $text String to search the phrase
|
||||
* @param string $phrase Phrase that will be searched for.
|
||||
* @param integer $radius The amount of characters returned around the phrase.
|
||||
* @param string $ellipsis Ending that will be appended
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* If no $phrase is passed, will generate an excerpt of $radius characters
|
||||
* from the beginning of $text.
|
||||
*/
|
||||
function excerpt(string $text, string $phrase = null, int $radius = 100, string $ellipsis = '...'): string
|
||||
{
|
||||
if (isset($phrase))
|
||||
{
|
||||
$phrasePos = strpos(strtolower($text), strtolower($phrase));
|
||||
$phraseLen = strlen($phrase);
|
||||
}
|
||||
elseif (! isset($phrase))
|
||||
{
|
||||
$phrasePos = $radius / 2;
|
||||
$phraseLen = 1;
|
||||
}
|
||||
|
||||
$pre = explode(' ', substr($text, 0, $phrasePos));
|
||||
$pos = explode(' ', substr($text, $phrasePos + $phraseLen));
|
||||
|
||||
$prev = ' ';
|
||||
$post = ' ';
|
||||
$count = 0;
|
||||
|
||||
foreach (array_reverse($pre) as $pr => $e)
|
||||
{
|
||||
if ((strlen($e) + $count + 1) < $radius)
|
||||
{
|
||||
$prev = ' ' . $e . $prev;
|
||||
}
|
||||
$count = ++ $count + strlen($e);
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
|
||||
foreach ($pos as $po => $s)
|
||||
{
|
||||
if ((strlen($s) + $count + 1) < $radius)
|
||||
{
|
||||
$post .= $s . ' ';
|
||||
}
|
||||
$count = ++ $count + strlen($s);
|
||||
}
|
||||
|
||||
$ellPre = $phrase ? $ellipsis : '';
|
||||
|
||||
return str_replace(' ', ' ', $ellPre . $prev . $phrase . $post . $ellipsis);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
}
|
||||
593
system/Helpers/url_helper.php
Normal file
593
system/Helpers/url_helper.php
Normal file
@@ -0,0 +1,593 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 4.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
/**
|
||||
* CodeIgniter URL Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
|
||||
if (! function_exists('site_url'))
|
||||
{
|
||||
/**
|
||||
* Return a site URL to use in views
|
||||
*
|
||||
* @param mixed $uri URI string or array of URI segments
|
||||
* @param string|null $protocol
|
||||
* @param \Config\App|null $altConfig Alternate configuration to use
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function site_url($uri = '', string $protocol = null, \Config\App $altConfig = null): string
|
||||
{
|
||||
// convert segment array to string
|
||||
if (is_array($uri))
|
||||
{
|
||||
$uri = implode('/', $uri);
|
||||
}
|
||||
|
||||
// use alternate config if provided, else default one
|
||||
$config = $altConfig ?? config(\Config\App::class);
|
||||
|
||||
$fullPath = rtrim(base_url(), '/') . '/';
|
||||
|
||||
// Add index page, if so configured
|
||||
if (! empty($config->indexPage))
|
||||
{
|
||||
$fullPath .= rtrim($config->indexPage, '/');
|
||||
}
|
||||
if (! empty($uri))
|
||||
{
|
||||
$fullPath .= '/' . $uri;
|
||||
}
|
||||
|
||||
$url = new \CodeIgniter\HTTP\URI($fullPath);
|
||||
|
||||
// allow the scheme to be over-ridden; else, use default
|
||||
if (! empty($protocol))
|
||||
{
|
||||
$url->setScheme($protocol);
|
||||
}
|
||||
|
||||
return (string) $url;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('base_url'))
|
||||
{
|
||||
/**
|
||||
* Return the base URL to use in views
|
||||
*
|
||||
* @param mixed $uri URI string or array of URI segments
|
||||
* @param string $protocol
|
||||
* @return string
|
||||
*/
|
||||
function base_url($uri = '', string $protocol = null): string
|
||||
{
|
||||
// convert segment array to string
|
||||
if (is_array($uri))
|
||||
{
|
||||
$uri = implode('/', $uri);
|
||||
}
|
||||
|
||||
// We should be using the configured baseURL that the user set;
|
||||
// otherwise get rid of the path, because we have
|
||||
// no way of knowing the intent...
|
||||
$config = \CodeIgniter\Config\Services::request()->config;
|
||||
$url = new \CodeIgniter\HTTP\URI($config->baseURL);
|
||||
unset($config);
|
||||
|
||||
// Merge in the path set by the user, if any
|
||||
if (! empty($uri))
|
||||
{
|
||||
$url = $url->resolveRelativeURI($uri);
|
||||
}
|
||||
|
||||
// If the scheme wasn't provided, check to
|
||||
// see if it was a secure request
|
||||
if (empty($protocol) && \CodeIgniter\Config\Services::request()->isSecure())
|
||||
{
|
||||
$protocol = 'https';
|
||||
}
|
||||
|
||||
if (! empty($protocol))
|
||||
{
|
||||
$url->setScheme($protocol);
|
||||
}
|
||||
|
||||
return (string) $url;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('current_url'))
|
||||
{
|
||||
/**
|
||||
* Current URL
|
||||
*
|
||||
* Returns the full URL (including segments) of the page where this
|
||||
* function is placed
|
||||
*
|
||||
* @param boolean $returnObject True to return an object instead of a strong
|
||||
*
|
||||
* @return string|\CodeIgniter\HTTP\URI
|
||||
*/
|
||||
function current_url(bool $returnObject = false)
|
||||
{
|
||||
return $returnObject ? \CodeIgniter\Config\Services::request()->uri : (string) \CodeIgniter\Config\Services::request()->uri;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('previous_url'))
|
||||
{
|
||||
/**
|
||||
* Returns the previous URL the current visitor was on. For security reasons
|
||||
* we first check in a saved session variable, if it exists, and use that.
|
||||
* If that's not available, however, we'll use a sanitized url from $_SERVER['HTTP_REFERER']
|
||||
* which can be set by the user so is untrusted and not set by certain browsers/servers.
|
||||
*
|
||||
* @param boolean $returnObject
|
||||
*
|
||||
* @return \CodeIgniter\HTTP\URI|mixed|string
|
||||
*/
|
||||
function previous_url(bool $returnObject = false)
|
||||
{
|
||||
// Grab from the session first, if we have it,
|
||||
// since it's more reliable and safer.
|
||||
// Otherwise, grab a sanitized version from $_SERVER.
|
||||
$referer = $_SESSION['_ci_previous_url'] ?? \CodeIgniter\Config\Services::request()->getServer('HTTP_REFERER', FILTER_SANITIZE_URL);
|
||||
|
||||
$referer = $referer ?? site_url('/');
|
||||
|
||||
return $returnObject ? new \CodeIgniter\HTTP\URI($referer) : $referer;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('uri_string'))
|
||||
{
|
||||
/**
|
||||
* URL String
|
||||
*
|
||||
* Returns the path part of the current URL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function uri_string(): string
|
||||
{
|
||||
return \CodeIgniter\Config\Services::request()->uri->getPath();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('index_page'))
|
||||
{
|
||||
/**
|
||||
* Index page
|
||||
*
|
||||
* Returns the "index_page" from your config file
|
||||
*
|
||||
* @param \Config\App|null $altConfig Alternate configuration to use
|
||||
* @return string
|
||||
*/
|
||||
function index_page(\Config\App $altConfig = null): string
|
||||
{
|
||||
// use alternate config if provided, else default one
|
||||
$config = $altConfig ?? config(\Config\App::class);
|
||||
|
||||
return $config->indexPage;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('anchor'))
|
||||
{
|
||||
/**
|
||||
* Anchor Link
|
||||
*
|
||||
* Creates an anchor based on the local URL.
|
||||
*
|
||||
* @param mixed $uri URI string or array of URI segments
|
||||
* @param string $title The link title
|
||||
* @param mixed $attributes Any attributes
|
||||
* @param \Config\App|null $altConfig Alternate configuration to use
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function anchor($uri = '', string $title = '', $attributes = '', \Config\App $altConfig = null): string
|
||||
{
|
||||
// use alternate config if provided, else default one
|
||||
$config = $altConfig ?? config(\Config\App::class);
|
||||
|
||||
$site_url = is_array($uri) ? site_url($uri, null, $config) : (preg_match('#^(\w+:)?//#i', $uri) ? $uri : site_url($uri, null, $config));
|
||||
// eliminate trailing slash
|
||||
$site_url = rtrim($site_url, '/');
|
||||
|
||||
if ($title === '')
|
||||
{
|
||||
$title = $site_url;
|
||||
}
|
||||
|
||||
if ($attributes !== '')
|
||||
{
|
||||
$attributes = stringify_attributes($attributes);
|
||||
}
|
||||
|
||||
return '<a href="' . $site_url . '"' . $attributes . '>' . $title . '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('anchor_popup'))
|
||||
{
|
||||
/**
|
||||
* Anchor Link - Pop-up version
|
||||
*
|
||||
* Creates an anchor based on the local URL. The link
|
||||
* opens a new window based on the attributes specified.
|
||||
*
|
||||
* @param string $uri the URL
|
||||
* @param string $title the link title
|
||||
* @param mixed $attributes any attributes
|
||||
* @param \Config\App|null $altConfig Alternate configuration to use
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function anchor_popup($uri = '', string $title = '', $attributes = false, \Config\App $altConfig = null): string
|
||||
{
|
||||
// use alternate config if provided, else default one
|
||||
$config = $altConfig ?? config(\Config\App::class);
|
||||
|
||||
$site_url = preg_match('#^(\w+:)?//#i', $uri) ? $uri : site_url($uri, '', $config);
|
||||
$site_url = rtrim($site_url, '/');
|
||||
|
||||
if ($title === '')
|
||||
{
|
||||
$title = $site_url;
|
||||
}
|
||||
|
||||
if ($attributes === false)
|
||||
{
|
||||
return '<a href="' . $site_url . '" onclick="window.open(\'' . $site_url . "', '_blank'); return false;\">" . $title . '</a>';
|
||||
}
|
||||
|
||||
if (! is_array($attributes))
|
||||
{
|
||||
$attributes = [$attributes];
|
||||
|
||||
// Ref: http://www.w3schools.com/jsref/met_win_open.asp
|
||||
$window_name = '_blank';
|
||||
}
|
||||
elseif (! empty($attributes['window_name']))
|
||||
{
|
||||
$window_name = $attributes['window_name'];
|
||||
unset($attributes['window_name']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$window_name = '_blank';
|
||||
}
|
||||
|
||||
foreach (['width' => '800', 'height' => '600', 'scrollbars' => 'yes', 'menubar' => 'no', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => '0', 'screeny' => '0'] as $key => $val)
|
||||
{
|
||||
$atts[$key] = $attributes[$key] ?? $val;
|
||||
unset($attributes[$key]);
|
||||
}
|
||||
|
||||
$attributes = stringify_attributes($attributes);
|
||||
|
||||
return '<a href="' . $site_url
|
||||
. '" onclick="window.open(\'' . $site_url . "', '" . $window_name . "', '" . stringify_attributes($atts, true) . "'); return false;\""
|
||||
. $attributes . '>' . $title . '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('mailto'))
|
||||
{
|
||||
/**
|
||||
* Mailto Link
|
||||
*
|
||||
* @param string $email the email address
|
||||
* @param string $title the link title
|
||||
* @param mixed $attributes any attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function mailto(string $email, string $title = '', $attributes = ''): string
|
||||
{
|
||||
if (trim($title) === '')
|
||||
{
|
||||
$title = $email;
|
||||
}
|
||||
|
||||
return '<a href="mailto:' . $email . '"' . stringify_attributes($attributes) . '>' . $title . '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('safe_mailto'))
|
||||
{
|
||||
/**
|
||||
* Encoded Mailto Link
|
||||
*
|
||||
* Create a spam-protected mailto link written in Javascript
|
||||
*
|
||||
* @param string $email the email address
|
||||
* @param string $title the link title
|
||||
* @param mixed $attributes any attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function safe_mailto(string $email, string $title = '', $attributes = ''): string
|
||||
{
|
||||
if (trim($title) === '')
|
||||
{
|
||||
$title = $email;
|
||||
}
|
||||
|
||||
$x = str_split('<a href="mailto:', 1);
|
||||
|
||||
for ($i = 0, $l = strlen($email); $i < $l; $i ++)
|
||||
{
|
||||
$x[] = '|' . ord($email[$i]);
|
||||
}
|
||||
|
||||
$x[] = '"';
|
||||
|
||||
if ($attributes !== '')
|
||||
{
|
||||
if (is_array($attributes))
|
||||
{
|
||||
foreach ($attributes as $key => $val)
|
||||
{
|
||||
$x[] = ' ' . $key . '="';
|
||||
for ($i = 0, $l = strlen($val); $i < $l; $i ++)
|
||||
{
|
||||
$x[] = '|' . ord($val[$i]);
|
||||
}
|
||||
$x[] = '"';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ($i = 0, $l = strlen($attributes); $i < $l; $i ++)
|
||||
{
|
||||
$x[] = $attributes[$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$x[] = '>';
|
||||
|
||||
$temp = [];
|
||||
for ($i = 0, $l = strlen($title); $i < $l; $i ++)
|
||||
{
|
||||
$ordinal = ord($title[$i]);
|
||||
|
||||
if ($ordinal < 128)
|
||||
{
|
||||
$x[] = '|' . $ordinal;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (empty($temp))
|
||||
{
|
||||
$count = ($ordinal < 224) ? 2 : 3;
|
||||
}
|
||||
|
||||
$temp[] = $ordinal;
|
||||
if (count($temp) === $count)
|
||||
{
|
||||
$number = ($count === 3) ? (($temp[0] % 16) * 4096) + (($temp[1] % 64) * 64) + ($temp[2] % 64) : (($temp[0] % 32) * 64) + ($temp[1] % 64);
|
||||
$x[] = '|' . $number;
|
||||
$count = 1;
|
||||
$temp = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$x[] = '<';
|
||||
$x[] = '/';
|
||||
$x[] = 'a';
|
||||
$x[] = '>';
|
||||
|
||||
$x = array_reverse($x);
|
||||
|
||||
// improve obfuscation by eliminating newlines & whitespace
|
||||
$output = '<script type="text/javascript">'
|
||||
. 'var l=new Array();';
|
||||
|
||||
for ($i = 0, $c = count($x); $i < $c; $i ++)
|
||||
{
|
||||
$output .= 'l[' . $i . "] = '" . $x[$i] . "';";
|
||||
}
|
||||
|
||||
$output .= 'for (var i = l.length-1; i >= 0; i=i-1) {'
|
||||
. "if (l[i].substring(0, 1) === '|') document.write(\"&#\"+unescape(l[i].substring(1))+\";\");"
|
||||
. 'else document.write(unescape(l[i]));'
|
||||
. '}'
|
||||
. '</script>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('auto_link'))
|
||||
{
|
||||
/**
|
||||
* Auto-linker
|
||||
*
|
||||
* Automatically links URL and Email addresses.
|
||||
* Note: There's a bit of extra code here to deal with
|
||||
* URLs or emails that end in a period. We'll strip these
|
||||
* off and add them after the link.
|
||||
*
|
||||
* @param string $str the string
|
||||
* @param string $type the type: email, url, or both
|
||||
* @param boolean $popup whether to create pop-up links
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function auto_link(string $str, string $type = 'both', bool $popup = false): string
|
||||
{
|
||||
// Find and replace any URLs.
|
||||
if ($type !== 'email' && preg_match_all('#(\w*://|www\.)[^\s()<>;]+\w#i', $str, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER))
|
||||
{
|
||||
// Set our target HTML if using popup links.
|
||||
$target = ($popup) ? ' target="_blank"' : '';
|
||||
|
||||
// We process the links in reverse order (last -> first) so that
|
||||
// the returned string offsets from preg_match_all() are not
|
||||
// moved as we add more HTML.
|
||||
foreach (array_reverse($matches) as $match)
|
||||
{
|
||||
// $match[0] is the matched string/link
|
||||
// $match[1] is either a protocol prefix or 'www.'
|
||||
//
|
||||
// With PREG_OFFSET_CAPTURE, both of the above is an array,
|
||||
// where the actual value is held in [0] and its offset at the [1] index.
|
||||
$a = '<a href="' . (strpos($match[1][0], '/') ? '' : 'http://') . $match[0][0] . '"' . $target . '>' . $match[0][0] . '</a>';
|
||||
$str = substr_replace($str, $a, $match[0][1], strlen($match[0][0]));
|
||||
}
|
||||
}
|
||||
|
||||
// Find and replace any emails.
|
||||
if ($type !== 'url' && preg_match_all('#([\w\.\-\+]+@[a-z0-9\-]+\.[a-z0-9\-\.]+[^[:punct:]\s])#i', $str, $matches, PREG_OFFSET_CAPTURE))
|
||||
{
|
||||
foreach (array_reverse($matches[0]) as $match)
|
||||
{
|
||||
if (filter_var($match[0], FILTER_VALIDATE_EMAIL) !== false)
|
||||
{
|
||||
$str = substr_replace($str, safe_mailto($match[0]), $match[1], strlen($match[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('prep_url'))
|
||||
{
|
||||
/**
|
||||
* Prep URL - Simply adds the http:// part if no scheme is included.
|
||||
*
|
||||
* Formerly used URI, but that does not play nicely with URIs missing
|
||||
* the scheme.
|
||||
*
|
||||
* @param string $str the URL
|
||||
* @return string
|
||||
*/
|
||||
function prep_url(string $str = ''): string
|
||||
{
|
||||
if ($str === 'http://' || $str === '')
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$url = parse_url($str);
|
||||
|
||||
if (! $url || ! isset($url['scheme']))
|
||||
{
|
||||
return 'http://' . $str;
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (! function_exists('url_title'))
|
||||
{
|
||||
/**
|
||||
* Create URL Title
|
||||
*
|
||||
* Takes a "title" string as input and creates a
|
||||
* human-friendly URL string with a "separator" string
|
||||
* as the word separator.
|
||||
*
|
||||
* @param string $str Input string
|
||||
* @param string $separator Word separator (usually '-' or '_')
|
||||
* @param boolean $lowercase Whether to transform the output string to lowercase
|
||||
* @return string
|
||||
*/
|
||||
function url_title(string $str, string $separator = '-', bool $lowercase = false): string
|
||||
{
|
||||
$q_separator = preg_quote($separator, '#');
|
||||
|
||||
$trans = [
|
||||
'&.+?;' => '',
|
||||
'[^\w\d _-]' => '',
|
||||
'\s+' => $separator,
|
||||
'(' . $q_separator . ')+' => $separator,
|
||||
];
|
||||
|
||||
$str = strip_tags($str);
|
||||
foreach ($trans as $key => $val)
|
||||
{
|
||||
// $str = preg_replace('#'.$key.'#i'.( UTF8_ENABLED ? 'u' : ''), $val, $str);
|
||||
$str = preg_replace('#' . $key . '#iu', $val, $str);
|
||||
}
|
||||
|
||||
if ($lowercase === true)
|
||||
{
|
||||
$str = mb_strtolower($str);
|
||||
}
|
||||
|
||||
return trim(trim($str, $separator));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
95
system/Helpers/xml_helper.php
Normal file
95
system/Helpers/xml_helper.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* CodeIgniter
|
||||
*
|
||||
* An open source application development framework for PHP
|
||||
*
|
||||
* This content is released under the MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2019 British Columbia Institute of Technology
|
||||
* Copyright (c) 2019 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 CodeIgniter Dev Team
|
||||
* @copyright 2019 CodeIgniter Foundation
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
* @link https://codeigniter.com
|
||||
* @since Version 1.0.0
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
/**
|
||||
* CodeIgniter XML Helpers
|
||||
*
|
||||
* @package CodeIgniter
|
||||
*/
|
||||
|
||||
if (! function_exists('xml_convert'))
|
||||
{
|
||||
/**
|
||||
* Convert Reserved XML characters to Entities
|
||||
*
|
||||
* @param string $str
|
||||
* @param boolean $protect_all
|
||||
* @return string
|
||||
*/
|
||||
function xml_convert(string $str, bool $protect_all = 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);
|
||||
|
||||
if ($protect_all === true)
|
||||
{
|
||||
$str = preg_replace('/&(\w+);/', $temp . '\\1;', $str);
|
||||
}
|
||||
|
||||
$original = [
|
||||
'&',
|
||||
'<',
|
||||
'>',
|
||||
'"',
|
||||
"'",
|
||||
'-',
|
||||
];
|
||||
$replacement = [
|
||||
'&',
|
||||
'<',
|
||||
'>',
|
||||
'"',
|
||||
''',
|
||||
'-',
|
||||
];
|
||||
$str = str_replace($original, $replacement, $str);
|
||||
|
||||
// Decode the temp markers back to entities
|
||||
$str = preg_replace('/' . $temp . '(\d+);/', '&#\\1;', $str);
|
||||
|
||||
if ($protect_all === true)
|
||||
{
|
||||
return preg_replace('/' . $temp . '(\w+);/', '&\\1;', $str);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user