Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

270 lines (256 sloc) 8.175 kB
<?php
/**
* Elefant CMS - http://www.elefantcms.com/
*
* Copyright (c) 2011 Johnny Broadway
*
* 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.
*/
/**
* This is a collection of utility functions that are too small to merit their
* own class, or even their own file, so they're aggregated here. They include:
*
* - `info()` - Dumps a formatted data structure for quick debugging.
* - `conf()` - Retrieves a value from the global configuration.
* - `simple_auth()` - Provides a means of implementing custom auth schemes
* (includes built-in HTTP Basic support).
* - `sql_split()` - Parses SQL data, removes comments, and splits it into
* individual queries.
* - `format_filesize()` - Formats a byte value into more readable output.
* - `detect()` - Simpel browser and browser type (e.g., mobile) detection.
*/
/**
* Wraps a `print_r()` or `var_dump()` of the given `$value` with a set of `<pre></pre>`
* tags around it, and echoes it.
*/
function info ($value, $full = false) {
if (php_sapi_name () !== 'cli') {
echo '<pre>';
if ($full) {
var_dump ($value);
} else {
print_r ($value);
}
echo '</pre>';
} else {
if ($full) {
var_dump ($value);
} else {
print_r ($value);
}
}
}
/**
* Get any global configuration section or individual setting value.
* Lazy loads the configuration upon first use, and stores it privately
* to avoid polluting the global space. Useful in templates as well.
* Note: Uses ELEFANT_ENV, defined in the front controller, to determine
* which configuration file to load, allowing for alternate dev, staging,
* and production configurations in a single codebase.
*
* To update a value after the initial configuration has been loaded,
* pass the new value as a third parameter, e.g.:
*
* // Enable debugging
* conf ('General', 'debug', true);
*/
function conf ($section, $value = false, $update = false) {
static $conf;
if ($conf === null) {
if (isset ($GLOBALS['conf'])) {
$conf =& $GLOBALS['conf'];
} else {
$conf = parse_ini_file ('conf/' . ELEFANT_ENV . '.php', true);
}
}
if ($value) {
if ($update) {
$conf[$section][$value] = $update;
}
return $conf[$section][$value];
}
return $conf[$section];
}
/**
* Implements a simple authentication mechanism based on callbacks.
* You provide a verifier function and a communication method function.
* It then returns them like this:
*
* method(verifier(user, pass));
*
* Implements HTTP Basic auth as a default method if none is given, and
* uses the master account defined in `conf/global.php` if no verifier is
* given.
*/
function simple_auth ($verifier = false, $method = false) {
$verifier = ($verifier) ? $verifier : 'simple_auth_verifier';
$method = ($method) ? $method : 'simple_auth_basic';
return call_user_func ($method, $verifier);
}
/**
* Default verifier for `simple_auth()`. This is meant to serve
* as an example, and should be overridden with your own
* implementation. Note its use of `conf()` variables that are
* likely not set in a default Elefant installation.
*/
function simple_auth_verifier ($user, $pass) {
if ($user == conf ('General', 'master_username') && $pass == conf ('General', 'master_password')) {
return true;
}
return false;
}
/**
* Default method for `simple_auth()`. Implements an HTTP basic
* protocol.
*/
function simple_auth_basic ($callback) {
if (! isset ($_SERVER['PHP_AUTH_USER']) || ! call_user_func ($callback, $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) {
header ('WWW-Authenticate: Basic realm="This Website"');
header ('HTTP/1.0 401 Unauthorized');
return false;
}
return true;
}
/**
* Splits an SQL script into distinct queries which can be evaluated or
* manipulated individually.
*/
function sql_split ($sql) {
$out = array ('');
$broken = preg_split ('/[\n\r]+/s', $sql);
foreach ($broken as $row) {
$row = trim ($row);
if (strpos ($row, '#') === 0 || strpos ($row, '--') === 0 || empty ($row)) {
continue;
} elseif (preg_match ('/;$/', $row)) {
$out[count ($out) - 1] .= substr ($row, 0, strlen ($row) - 1) . "\n";
$out[] = '';
} else {
$out[count ($out) - 1] .= $row . "\n";
}
}
if (empty ($out[count ($out) - 1])) {
array_pop ($out);
}
return $out;
}
/**
* Returns a file size formatted in a more human-friendly format, rounded
* to the nearest GB, MB, KB, or byte.
*/
function format_filesize ($size = 0) {
if ($size >= 1073741824) {
return round ($size / 1073741824 * 10) / 10 . " GB";
} elseif ($size >= 1048576) {
return round ($size / 1048576 * 10) / 10 . " MB";
} elseif ($size >= 1024) {
return round ($size / 1024) . " KB";
} else {
return $size . " b";
}
}
/**
* Very basic browser detection. `$browser` can be one of:
*
* - msie, ie
* - firefox, ff, moz
* - chrome
* - safari
* - webkit
* - opera
* - opera mini
* - opera mobi
* - ios
* - iphone
* - ipad
* - android
* - iemobile
* - webos
* - blackberry
* - googlebot
* - bot
* - mobile
* - tablet
*
* Notes:
*
* - `mobile` and `tablet` matches are not exhaustive, they only list the common
* platforms.
*
* - iPad and iPod are both reported as mobile devices in the user agent string,
* but `detect()` corrects for this in the case of the iPad.
*
* - Android reports as true for both mobile and tablet currently.
*
* - Some matches might be seen as false-positives, such as Chrome matching Safari.
* In these cases, look at other detection options. For example with Chrome, the
* rendering engine is Webkit, so better to simply use that.
*
* - No version detection. For IE version-specific needs, use conditional comments
* in your HTML, or use a string like `msie 10`.
*
* - Other lowercase strings that are not listed above can be used as well,
* for example `wap`, or `smartphone`.
*/
function detect ($browser) {
$ua = strtolower ($_SERVER['HTTP_USER_AGENT']);
$ver = '';
// Normalize names
$browser = ($browser === 'ie') ? 'msie' : $browser;
$browser = ($browser === 'ff') ? 'firefox' : $browser;
$browser = ($browser === 'moz') ? 'firefox' : $browser;
if ($browser === 'mobile') {
if (! preg_match ('/(iphone|ipod|android|opera mini|opera mobi|symb|phone|webos|blackberry|mobile)/', $ua)) {
// No common mobile platform
return false;
} elseif (strpos ($ua, 'ipad') !== false) {
// iPad should be separate from mobile
return false;
}
return true;
} elseif ($browser === 'tablet') {
if (! preg_match ('/(ipad|android|tablet)/', $ua)) {
// Not iPad, Android, or tablet
return false;
}
return true;
} elseif ($browser === 'ios') {
if (! preg_match ('/(ipad|iphone|ipod)/', $ua)) {
// Not iOS
return false;
}
return true;
} elseif (strpos ($ua, $browser) === false) {
return false;
}
return true;
}
/**
* Recursively delete a folder and all its contents.
* Handles hidden dot-files as well as regular files.
*/
function rmdir_recursive ($path) {
if (preg_match ('|/\.+$|', $path)) {
return;
}
return is_file ($path)
? unlink ($path)
: array_map ('rmdir_recursive', glob ($path . '/{,.}*', GLOB_BRACE)) == rmdir ($path);
}
?>
Jump to Line
Something went wrong with that request. Please try again.