/kirby.php
PHP | 3409 lines | 1353 code | 509 blank | 1547 comment | 250 complexity | ccdbce8f7d5838457b80f02ace0a3298 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- <?php
- /**
- * Kirby -- A stripped down and easy to use toolkit for PHP
- *
- * @version 0.94
- * @author Bastian Allgeier <bastian@getkirby.com>
- * @link http://toolkit.getkirby.com
- * @copyright Copyright 2009-2012 Bastian Allgeier
- * @license http://www.opensource.org/licenses/mit-license.php MIT License
- * @package Kirby
- */
- c::set('version', 0.94);
- c::set('language', 'en');
- c::set('charset', 'utf-8');
- c::set('root', dirname(__FILE__));
- /**
- * Redirects the user to a new URL
- *
- * @param string $url The URL to redirect to
- * @param boolean $code The HTTP status code, which should be sent (301, 302 or 303)
- * @package Kirby
- */
- function go($url=false, $code=false) {
- if(empty($url)) $url = c::get('url', '/');
- // send an appropriate header
- if($code) {
- switch($code) {
- case 301:
- header('HTTP/1.1 301 Moved Permanently');
- break;
- case 302:
- header('HTTP/1.1 302 Found');
- break;
- case 303:
- header('HTTP/1.1 303 See Other');
- break;
- }
- }
- // send to new page
- header('Location:' . $url);
- exit();
- }
- /**
- * Returns the status from a Kirby response
- *
- * @param array $response The Kirby response array
- * @return string "error" or "success"
- * @package Kirby
- */
- function status($response) {
- return a::get($response, 'status');
- }
- /**
- * Returns the message from a Kirby response
- *
- * @param array $response The Kirby response array
- * @return string The message
- * @package Kirby
- */
- function msg($response) {
- return a::get($response, 'msg');
- }
- /**
- * Checks if a Kirby response is an error response or not.
- *
- * @param array $response The Kirby response array
- * @return boolean Returns true if the response is an error, returns false if no error occurred
- * @package Kirby
- */
- function error($response) {
- return (status($response) == 'error') ? true : false;
- }
- /**
- * Checks if a Kirby response is a success response.
- *
- * @param array $response The Kirby response array
- * @return boolean Returns true if the response is a success, returns false if an error occurred
- * @package Kirby
- */
- function success($response) {
- return !error($response);
- }
- /**
- * Loads additional PHP files
- *
- * You can set the root directory with c::set('root', 'my/root');
- * By default the same directory in which the kirby toolkit file is located will be used.
- *
- * @param args A list filenames as individual arguments
- * @return array Returns a Kirby response array. On error the response array includes the unloadable files (errors).
- * @package Kirby
- */
- function load() {
- $root = c::get('root');
- $files = func_get_args();
- $errors = array();
- foreach((array)$files AS $f) {
- $file = $root . '/' . $f . '.php';
- if(file_exists($file)) {
- include_once($file);
- } else {
- $errors[] = $file;
- }
- }
-
- if(!empty($errors)) return array(
- 'status' => 'error',
- 'msg' => 'some files could not be loaded',
- 'errors' => $errors
- );
-
- return array(
- 'status' => 'success',
- 'msg' => 'all files have been loaded'
- );
- }
- /**
- *
- * Array
- *
- * This class is supposed to simplify array handling
- * and make it more consistent.
- *
- * @package Kirby
- */
- class a {
- /**
- * Gets an element of an array by key
- *
- * @param array $array The source array
- * @param mixed $key The key to look for
- * @param mixed $default Optional default value, which should be returned if no element has been found
- * @return mixed
- */
- static function get($array, $key, $default=null) {
- return (isset($array[ $key ])) ? $array[ $key ] : $default;
- }
-
- /**
- * Gets all elements for an array of key
- *
- * @param array $array The source array
- * @keys array $keys An array of keys to fetch
- * @return array An array of keys and matching values
- */
- static function getall($array, $keys) {
- $result = array();
- foreach($keys as $key) $result[$key] = $array[$key];
- return $result;
- }
- /**
- * Removes an element from an array
- *
- * @param array $array The source array
- * @param mixed $search The value or key to look for
- * @param boolean $key Pass true to search for an key, pass false to search for an value.
- * @return array The result array without the removed element
- */
- static function remove($array, $search, $key=true) {
- if($key) {
- unset($array[$search]);
- } else {
- $found_all = false;
- while(!$found_all) {
- $index = array_search($search, $array);
- if($index !== false) {
- unset($array[$index]);
- } else {
- $found_all = true;
- }
- }
- }
- return $array;
- }
- /**
- * Injects an element into an array
- *
- * @param array $array The source array
- * @param int $position The position, where to inject the element
- * @param mixed $element The element, which should be injected
- * @return array The result array including the new element
- */
- static function inject($array, $position, $element='placeholder') {
- $start = array_slice($array, 0, $position);
- $end = array_slice($array, $position);
- return array_merge($start, (array)$element, $end);
- }
- /**
- * Shows an entire array or object in a human readable way
- * This is perfect for debugging
- *
- * @param array $array The source array
- * @param boolean $echo By default the result will be echoed instantly. You can switch that off here.
- * @return mixed If echo is false, this will return the generated array output.
- */
- static function show($array, $echo=true) {
- $output = '<pre>';
- $output .= htmlspecialchars(print_r($array, true));
- $output .= '</pre>';
- if($echo==true) echo $output;
- return $output;
- }
- /**
- * Converts an array to a JSON string
- * It's basically a shortcut for json_encode()
- *
- * @param array $array The source array
- * @return string The JSON string
- */
- static function json($array) {
- return @json_encode( (array)$array );
- }
- /**
- * Converts an array to a XML string
- *
- * @param array $array The source array
- * @param string $tag The name of the root element
- * @param boolean $head Include the xml declaration head or not
- * @param string $charset The charset, which should be used for the header
- * @param int $level The indendation level
- * @return string The XML string
- */
- static function xml($array, $tag='root', $head=true, $charset='utf-8', $tab=' ', $level=0) {
- $result = ($level==0 && $head) ? '<?xml version="1.0" encoding="' . $charset . '"?>' . "\n" : '';
- $nlevel = ($level+1);
- $result .= str_repeat($tab, $level) . '<' . $tag . '>' . "\n";
- foreach($array AS $key => $value) {
- $key = str::lower($key);
- if(is_array($value)) {
- $mtags = false;
- foreach($value AS $key2 => $value2) {
- if(is_array($value2)) {
- $result .= self::xml($value2, $key, $head, $charset, $tab, $nlevel);
- } else if(trim($value2) != '') {
- $value2 = (htmlspecialchars($value2) != $value2) ? '<![CDATA[' . $value2 . ']]>' : $value2;
- $result .= str_repeat($tab, $nlevel) . '<' . $key . '>' . $value2 . '</' . $key . '>' . "\n";
- }
- $mtags = true;
- }
- if(!$mtags && count($value) > 0) {
- $result .= self::xml($value, $key, $head, $charset, $tab, $nlevel);
- }
- } else if(trim($value) != '') {
- $value = (htmlspecialchars($value) != $value) ? '<![CDATA[' . $value . ']]>' : $value;
- $result .= str_repeat($tab, $nlevel) . '<' . $key . '>' . $value . '</' . $key . '>' . "\n";
- }
- }
- return $result . str_repeat($tab, $level) . '</' . $tag . '>' . "\n";
- }
- /**
- * Extracts a single column from an array
- *
- * @param array $array The source array
- * @param string $key The key name of the column to extract
- * @return array The result array with all values from that column.
- */
- static function extract($array, $key) {
- $output = array();
- foreach($array AS $a) if(isset($a[$key])) $output[] = $a[ $key ];
- return $output;
- }
- /**
- * Shuffles an array and keeps the keys
- *
- * @param array $array The source array
- * @return array The shuffled result array
- */
- static function shuffle($array) {
- $keys = array_keys($array);
- shuffle($keys);
- return array_merge(array_flip($keys), $array);
- }
- /**
- * Returns the first element of an array
- *
- * I always have to lookup the names of that function
- * so I decided to make this shortcut which is
- * easier to remember.
- *
- * @param array $array The source array
- * @return mixed The first element
- */
- static function first($array) {
- return array_shift($array);
- }
- /**
- * Returns the last element of an array
- *
- * I always have to lookup the names of that function
- * so I decided to make this shortcut which is
- * easier to remember.
- *
- * @param array $array The source array
- * @return mixed The last element
- */
- static function last($array) {
- return array_pop($array);
- }
- /**
- * Search for elements in an array by regular expression
- *
- * @param array $array The source array
- * @param string $search The regular expression
- * @return array The array of results
- */
- static function search($array, $search) {
- return preg_grep('#' . preg_quote($search) . '#i' , $array);
- }
- /**
- * Checks if an array contains a certain string
- *
- * @param array $array The source array
- * @param string $search The string to search for
- * @return boolean true: the array contains the string, false: it doesn't
- */
- static function contains($array, $search) {
- $search = self::search($array, $search);
- return (empty($search)) ? false : true;
- }
- /**
- * Fills an array up with additional elements to certain amount.
- *
- * @param array $array The source array
- * @param int $limit The number of elements the array should contain after filling it up.
- * @param mixed $fill The element, which should be used to fill the array
- * @return array The filled-up result array
- */
- static function fill($array, $limit, $fill='placeholder') {
- if(count($array) < $limit) {
- $diff = $limit-count($array);
- for($x=0; $x<$diff; $x++) $array[] = $fill;
- }
- return $array;
- }
- /**
- * Checks for missing elements in an array
- *
- * This is very handy to check for missing
- * user values in a request for example.
- *
- * @param array $array The source array
- * @param array $required An array of required keys
- * @return array An array of missing fields. If this is empty, nothing is missing.
- */
- static function missing($array, $required=array()) {
- $missing = array();
- foreach($required AS $r) {
- if(empty($array[$r])) $missing[] = $r;
- }
- return $missing;
- }
- /**
- * Sorts a multi-dimensional array by a certain column
- *
- * @param array $array The source array
- * @param string $field The name of the column
- * @param string $direction desc (descending) or asc (ascending)
- * @param const $method A PHP sort method flag.
- * @return array The sorted array
- */
- static function sort($array, $field, $direction='desc', $method=SORT_REGULAR) {
- $direction = (strtolower($direction) == 'desc') ? SORT_DESC : SORT_ASC;
- $helper = array();
- foreach($array as $key => $row) {
- $helper[$key] = (is_object($row)) ? (method_exists($row, $field)) ? str::lower($row->$field()) : str::lower($row->$field) : str::lower($row[$field]);
- }
-
- array_multisort($helper, $direction, $method, $array);
- return $array;
-
- }
- }
- /**
- *
- * Browser
- *
- * Browser sniffing is bad - I know!
- * But sometimes this class is very helpful to
- * react on certain browsers and build browser-specific
- * css selectors for example. It's up to you to use it.
- *
- * @package Kirby
- */
- class browser {
-
- /**
- * The entire user agent string
- *
- * @var string
- */
- static public $ua = false;
- /**
- * The readable name of the browser
- * For example: "ie"
- *
- * @var string
- */
- static public $name = false;
- /**
- * The readable browser engine name
- * For example: "webkit"
- *
- * @var string
- */
- static public $engine = false;
- /**
- * The browser version number
- * For example: "3.6"
- *
- * @var string
- */
- static public $version = false;
- /**
- * The platform name
- * For example: "mac"
- *
- * @var string
- */
- static public $platform = false;
- /**
- * True or false if it is a mobile device or not
- *
- * @var boolean
- */
- static public $mobile = false;
- /**
- * True or false if it is an iOS device or not
- *
- * @var boolean
- */
- static public $ios = false;
- /**
- * True or false if it is an iPhone or not
- *
- * @var boolean
- */
- static public $iphone = false;
- /**
- * Returns the name of the browser
- *
- * @param string $ua The user agent string
- * @return string The browser name
- */
- static function name($ua=null) {
- self::detect($ua);
- return self::$name;
- }
- /**
- * Returns the browser engine
- *
- * @param string $ua The user agent string
- * @return string The browser engine
- */
- static function engine($ua=null) {
- self::detect($ua);
- return self::$engine;
- }
- /**
- * Returns the browser version
- *
- * @param string $ua The user agent string
- * @return string The browser version
- */
- static function version($ua=null) {
- self::detect($ua);
- return self::$version;
- }
- /**
- * Returns the platform
- *
- * @param string $ua The user agent string
- * @return string The platform name
- */
- static function platform($ua=null) {
- self::detect($ua);
- return self::$platform;
- }
- /**
- * Checks if the user agent string is from a mobile device
- *
- * @param string $ua The user agent string
- * @return boolean True: mobile device, false: not a mobile device
- */
- static function mobile($ua=null) {
- self::detect($ua);
- return self::$mobile;
- }
- /**
- * Checks if the user agent string is from an iPhone
- *
- * @param string $ua The user agent string
- * @return boolean True: iPhone, false: not an iPhone
- */
- static function iphone($ua=null) {
- self::detect($ua);
- return self::$iphone;
- }
- /**
- * Checks if the user agent string is from an iOS device
- *
- * @param string $ua The user agent string
- * @return boolean True: iOS device, false: not an iOS device
- */
- static function ios($ua=null) {
- self::detect($ua);
- return self::$ios;
- }
- /**
- * Returns a browser-specific css selector string
- *
- * @param string $ua The user agent string
- * @param boolean $array True: return an array, false: return a string
- * @return mixed
- */
- static function css($ua=null, $array=false) {
- self::detect($ua);
- $css[] = self::$engine;
- $css[] = self::$name;
- if(self::$version) $css[] = self::$name . str_replace('.', '_', self::$version);
- $css[] = self::$platform;
- return ($array) ? $css : implode(' ', $css);
- }
- /**
- * The core detection method, which parses the user agent string
- *
- * @todo add new browser versions
- * @param string $ua The user agent string
- * @return array An array with all parsed info
- */
- static function detect($ua=null) {
- $ua = ($ua) ? str::lower($ua) : str::lower(server::get('http_user_agent'));
- // don't do the detection twice
- if(self::$ua == $ua) return array(
- 'name' => self::$name,
- 'engine' => self::$engine,
- 'version' => self::$version,
- 'platform' => self::$platform,
- 'agent' => self::$ua,
- 'mobile' => self::$mobile,
- 'iphone' => self::$iphone,
- 'ios' => self::$ios,
- );
- self::$ua = $ua;
- self::$name = false;
- self::$engine = false;
- self::$version = false;
- self::$platform = false;
- // browser
- if(!preg_match('/opera|webtv/i', self::$ua) && preg_match('/msie\s(\d)/', self::$ua, $array)) {
- self::$version = $array[1];
- self::$name = 'ie';
- self::$engine = 'trident';
- } else if(strstr(self::$ua, 'firefox/3.6')) {
- self::$version = 3.6;
- self::$name = 'fx';
- self::$engine = 'gecko';
- } else if (strstr(self::$ua, 'firefox/3.5')) {
- self::$version = 3.5;
- self::$name = 'fx';
- self::$engine = 'gecko';
- } else if(preg_match('/firefox\/(\d+)/i', self::$ua, $array)) {
- self::$version = $array[1];
- self::$name = 'fx';
- self::$engine = 'gecko';
- } else if(preg_match('/opera(\s|\/)(\d+)/', self::$ua, $array)) {
- self::$engine = 'presto';
- self::$name = 'opera';
- self::$version = $array[2];
- } else if(strstr(self::$ua, 'konqueror')) {
- self::$name = 'konqueror';
- self::$engine = 'webkit';
- } else if(strstr(self::$ua, 'iron')) {
- self::$name = 'iron';
- self::$engine = 'webkit';
- } else if(strstr(self::$ua, 'chrome')) {
- self::$name = 'chrome';
- self::$engine = 'webkit';
- if(preg_match('/chrome\/(\d+)/i', self::$ua, $array)) { self::$version = $array[1]; }
- } else if(strstr(self::$ua, 'applewebkit/')) {
- self::$name = 'safari';
- self::$engine = 'webkit';
- if(preg_match('/version\/(\d+)/i', self::$ua, $array)) { self::$version = $array[1]; }
- } else if(strstr(self::$ua, 'mozilla/')) {
- self::$engine = 'gecko';
- self::$name = 'fx';
- }
- // platform
- if(strstr(self::$ua, 'j2me')) {
- self::$platform = 'mobile';
- } else if(strstr(self::$ua, 'iphone')) {
- self::$platform = 'iphone';
- } else if(strstr(self::$ua, 'ipod')) {
- self::$platform = 'ipod';
- } else if(strstr(self::$ua, 'ipad')) {
- self::$platform = 'ipad';
- } else if(strstr(self::$ua, 'mac')) {
- self::$platform = 'mac';
- } else if(strstr(self::$ua, 'darwin')) {
- self::$platform = 'mac';
- } else if(strstr(self::$ua, 'webtv')) {
- self::$platform = 'webtv';
- } else if(strstr(self::$ua, 'win')) {
- self::$platform = 'win';
- } else if(strstr(self::$ua, 'freebsd')) {
- self::$platform = 'freebsd';
- } else if(strstr(self::$ua, 'x11') || strstr(self::$ua, 'linux')) {
- self::$platform = 'linux';
- }
- self::$mobile = (self::$platform == 'mobile') ? true : false;
- self::$iphone = (in_array(self::$platform, array('ipod', 'iphone'))) ? true : false;
- self::$ios = (in_array(self::$platform, array('ipod', 'iphone', 'ipad'))) ? true : false;
- return array(
- 'name' => self::$name,
- 'engine' => self::$engine,
- 'version' => self::$version,
- 'platform' => self::$platform,
- 'agent' => self::$ua,
- 'mobile' => self::$mobile,
- 'iphone' => self::$iphone,
- 'ios' => self::$ios,
- );
- }
- }
- /**
- *
- * Config
- *
- * This is the core class to handle
- * configuration values/constants.
- *
- * @package Kirby
- */
- class c {
- /**
- * The static config array
- * It contains all config values
- *
- * @var array
- */
- private static $config = array();
-
- /**
- * Gets a config value by key
- *
- * @param string $key The key to look for. Pass false to get the entire config array
- * @param mixed $default The default value, which will be returned if the key has not been found
- * @return mixed The found config value
- */
- static function get($key=null, $default=null) {
- if(empty($key)) return self::$config;
- return a::get(self::$config, $key, $default);
- }
- /**
- * Sets a config value by key
- *
- * @param string $key The key to define
- * @param mixed $value The value for the passed key
- */
- static function set($key, $value=null) {
- if(is_array($key)) {
- // set all new values
- self::$config = array_merge(self::$config, $key);
- } else {
- self::$config[$key] = $value;
- }
- }
- /**
- * Loads an additional config file
- * Returns the entire configuration array
- *
- * @param string $file The path to the config file
- * @return array The entire config array
- */
- static function load($file) {
- if(file_exists($file)) require_once($file);
- return c::get();
- }
- }
- /**
- *
- * Content
- *
- * This class handles output buffering,
- * content loading and setting content type headers.
- *
- * @package Kirby
- */
- class content {
-
- /**
- * Starts the output buffer
- *
- */
- static function start() {
- ob_start();
- }
- /**
- * Stops the output buffer
- * and flush the content or return it.
- *
- * @param boolean $return Pass true to return the content instead of flushing it
- * @return mixed
- */
- static function end($return=false) {
- if($return) {
- $content = ob_get_contents();
- ob_end_clean();
- return $content;
- }
- ob_end_flush();
- }
- /**
- * Loads content from a passed file
- *
- * @param string $file The path to the file
- * @param boolean $return True: return the content of the file, false: echo the content
- * @return mixed
- */
- static function load($file, $return=true) {
- self::start();
- require_once($file);
- $content = self::end(true);
- if($return) return $content;
- echo $content;
- }
- /**
- * Simplifies setting content type headers
- *
- * @param string $ctype The shortcut for the content type. See the keys of the $ctypes array for all available shortcuts
- * @param string $charset The charset definition for the content type header. Default is "utf-8"
- */
- static function type() {
- $args = func_get_args();
- // shortcuts for content types
- $ctypes = array(
- 'html' => 'text/html',
- 'css' => 'text/css',
- 'js' => 'text/javascript',
- 'jpg' => 'image/jpeg',
- 'png' => 'image/png',
- 'gif' => 'image/gif',
- 'json' => 'application/json'
- );
- $ctype = a::get($args, 0, c::get('content_type', 'text/html'));
- $ctype = a::get($ctypes, $ctype, $ctype);
- $charset = a::get($args, 1, c::get('charset', 'utf-8'));
- header('Content-type: ' . $ctype . '; charset=' . $charset);
- }
- }
- /**
- *
- * Cookie
- *
- * This class makes cookie handling easy
- *
- * @package Kirby
- */
- class cookie {
- /**
- * Set a new cookie
- *
- * @param string $key The name of the cookie
- * @param string $value The cookie content
- * @param int $expires The number of seconds until the cookie expires
- * @param string $domain The domain to set this cookie for.
- * @return boolean true: the cookie has been created, false: cookie creation failed
- */
- static function set($key, $value, $expires=3600, $domain='/') {
- if(is_array($value)) $value = a::json($value);
- $_COOKIE[$key] = $value;
- return @setcookie($key, $value, time()+$expires, $domain);
- }
- /**
- * Get a cookie value
- *
- * @param string $key The name of the cookie
- * @param string $default The default value, which should be returned if the cookie has not been found
- * @return mixed The found value
- */
- static function get($key, $default=null) {
- return a::get($_COOKIE, $key, $default);
- }
- /**
- * Remove a cookie
- *
- * @param string $key The name of the cookie
- * @param string $domain The domain of the cookie
- * @return mixed true: the cookie has been removed, false: the cookie could not be removed
- */
- static function remove($key, $domain='/') {
- $_COOKIE[$key] = false;
- return @setcookie($key, false, time()-3600, $domain);
- }
- }
- /**
- *
- * Database
- *
- * Database handling sucks - not with this class :)
- *
- * Configure your database connection like this:
- *
- * <code>
- * c::set('db.host', 'localhost');
- * c::set('db.user', 'root');
- * c::set('db.password', '');
- * c::set('db.name', 'mydb');
- * c::set('db.prefix', '');
- * </code>
- *
- * @package Kirby
- */
- class db {
- /**
- * Traces all db queries
- *
- * @var array
- */
- public static $trace = array();
- /**
- * The connection resource
- *
- * @var mixed
- */
- private static $connection = false;
- /**
- * The selected database
- *
- * @var string
- */
- private static $database = false;
- /**
- * The used charset
- * Default is "utf8"
- *
- * @var string
- */
- private static $charset = false;
- /**
- * The last used query
- *
- * @var string
- */
- private static $last_query = false;
- /**
- * The number of affected rows
- * for the last query
- *
- * @var int
- */
- private static $affected = 0;
- /**
- * The core connection method
- * Tries to connect to the server
- * Selects the database and sets the charset
- *
- * It will only connect once and return
- * that same connection for all following queries
- *
- * @return mixed
- */
- static function connect() {
- $connection = self::connection();
- $args = func_get_args();
- $host = a::get($args, 0, c::get('db.host', 'localhost'));
- $user = a::get($args, 1, c::get('db.user', 'root'));
- $password = a::get($args, 2, c::get('db.password'));
- $database = a::get($args, 3, c::get('db.name'));
- $charset = a::get($args, 4, c::get('db.charset', 'utf8'));
- // don't connect again if it's already done
- $connection = (!$connection) ? @mysql_connect($host, $user, $password) : $connection;
- // react on connection failures
- if(!$connection) return self::error(l::get('db.errors.connect', 'Database connection failed'), true);
- self::$connection = $connection;
- // select the database
- $database = self::database($database);
- if(error($database)) return $database;
- // set the right charset
- $charset = self::charset($charset);
- if(error($charset)) return $charset;
- return $connection;
- }
- /**
- * Returns the current connection or false
- *
- * @return mixed
- */
- static function connection() {
- return (is_resource(self::$connection)) ? self::$connection : false;
- }
- /**
- * Disconnects from the server
- *
- * @return boolean
- */
- static function disconnect() {
- if(!c::get('db.disconnect')) return false;
- $connection = self::connection();
- if(!$connection) return false;
- // kill the connection
- $disconnect = @mysql_close($connection);
- self::$connection = false;
- if(!$disconnect) return self::error(l::get('db.errors.disconnect', 'Disconnecting database failed'));
- return true;
- }
- /**
- * Selects a database
- *
- * @param string $database
- * @return mixed
- */
- static function database($database) {
- if(!$database) return self::error(l::get('db.errors.missing_db_name', 'Please provide a database name'), true);
- // check if there is a selected database
- if(self::$database == $database) return true;
- // select a new database
- $select = @mysql_select_db($database, self::connection());
- if(!$select) return self::error(l::get('db.errors.missing_db', 'Selecting database failed'), true);
- self::$database = $database;
- return $database;
- }
- /**
- * Sets the charset for all queries
- * The default and recommended charset is utf8
- *
- * @param string $charset
- * @return mixed
- */
- static function charset($charset='utf8') {
- // check if there is a assigned charset and compare it
- if(self::$charset == $charset) return true;
- // set the new charset
- $set = @mysql_query('SET NAMES ' . $charset);
- if(!$set) return self::error(l::get('db.errors.setting_charset_failed', 'Setting database charset failed'));
- // save the new charset to the globals
- self::$charset = $charset;
- return $charset;
- }
- /**
- * Runs a MySQL query.
- * You can use any valid MySQL query here.
- * This is also the fallback method if you
- * can't use one of the provided shortcut methods
- * from this class.
- *
- * @param string $sql The sql query
- * @param boolean $fetch True: apply db::fetch to the result, false: go without db::fetch
- * @return mixed
- */
- static function query($sql, $fetch=true) {
- $connection = self::connect();
- if(error($connection)) return $connection;
- // save the query
- self::$last_query = $sql;
- // execute the query
- $result = @mysql_query($sql, $connection);
- self::$affected = @mysql_affected_rows();
- self::$trace[] = $sql;
- if(!$result) return self::error(l::get('db.errors.query_failed', 'The database query failed'));
- if(!$fetch) return $result;
- $array = array();
- while($r = self::fetch($result)) array_push($array, $r);
- return $array;
- }
- /**
- * Executes a MySQL query without result set.
- * This is used for queries like update, delete or insert
- *
- * @param string $sql The sql query
- * @return mixed
- */
- static function execute($sql) {
- $connection = self::connect();
- if(error($connection)) return $connection;
- // save the query
- self::$last_query = $sql;
- // execute the query
- $execute = @mysql_query($sql, $connection);
- self::$affected = @mysql_affected_rows();
- self::$trace[] = $sql;
- if(!$execute) return self::error(l::get('db.errors.query_failed', 'The database query failed'));
-
- $last_id = self::last_id();
- return ($last_id === false) ? self::$affected : self::last_id();
- }
- /**
- * Returns the number of affected rows for the last query
- *
- * @return int
- */
- static function affected() {
- return self::$affected;
- }
- /**
- * Returns the last returned insert id
- *
- * @return int
- */
- static function last_id() {
- $connection = self::connection();
- return @mysql_insert_id($connection);
- }
- /**
- * Shortcut for mysql_fetch_array
- *
- * @param resource $result the unfetched result from db::query()
- * @param const $type PHP flag for mysql_fetch_array
- * @return array The key/value result array
- */
- static function fetch($result, $type=MYSQL_ASSOC) {
- if(!$result) return array();
- return @mysql_fetch_array($result, $type);
- }
- /**
- * Returns an array of fields in a given table
- *
- * @param string $table The table name
- * @return array The array of field names
- */
- static function fields($table) {
- $connection = self::connect();
- if(error($connection)) return $connection;
- $fields = @mysql_list_fields(self::$database, self::prefix($table), $connection);
- if(!$fields) return self::error(l::get('db.errors.listing_fields_failed', 'Listing fields failed'));
- $output = array();
- $count = @mysql_num_fields($fields);
- for($x=0; $x<$count; $x++) {
- $output[] = @mysql_field_name($fields, $x);
- }
- return $output;
- }
- /**
- * Runs a INSERT query
- *
- * @param string $table The table name
- * @param mixed $input Either a key/value array or a valid MySQL insert string
- * @param boolean $ignore Set this to true to ignore duplicates
- * @return mixed The last inserted id if everything went fine or an error response.
- */
- static function insert($table, $input, $ignore=false) {
- $ignore = ($ignore) ? ' IGNORE' : '';
- return self::execute('INSERT' . ($ignore) . ' INTO ' . self::prefix($table) . ' SET ' . self::values($input));
- }
- /**
- * Runs a INSERT query with values
- *
- * @param string $table The table name
- * @param array $fields an array of field names
- * @param array $values an array of array of keys and values.
- * @return mixed The last inserted id if everything went fine or an error response.
- */
- static function insert_all($table, $fields, $values) {
-
- $query = 'INSERT INTO ' . self::prefix($table) . ' (' . implode(',', $fields) . ') VALUES ';
- $rows = array();
-
- foreach($values AS $v) {
- $str = '(\'';
- $sep = '';
-
- foreach($v AS $input) {
- $str .= $sep . db::escape($input);
- $sep = "','";
- }
- $str .= '\')';
- $rows[] = $str;
- }
-
- $query .= implode(',', $rows);
- return db::execute($query);
-
- }
- /**
- * Runs a REPLACE query
- *
- * @param string $table The table name
- * @param mixed $input Either a key/value array or a valid MySQL insert string
- * @return mixed The last inserted id if everything went fine or an error response.
- */
- static function replace($table, $input) {
- return self::execute('REPLACE INTO ' . self::prefix($table) . ' SET ' . self::values($input));
- }
- /**
- * Runs an UPDATE query
- *
- * @param string $table The table name
- * @param mixed $input Either a key/value array or a valid MySQL insert string
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @return mixed The number of affected rows or an error response
- */
- static function update($table, $input, $where) {
- return self::execute('UPDATE ' . self::prefix($table) . ' SET ' . self::values($input) . ' WHERE ' . self::where($where));
- }
- /**
- * Runs a DELETE query
- *
- * @param string $table The table name
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @return mixed The number of affected rows or an error response
- */
- static function delete($table, $where='') {
- $sql = 'DELETE FROM ' . self::prefix($table);
- if(!empty($where)) $sql .= ' WHERE ' . self::where($where);
- return self::execute($sql);
- }
- /**
- * Returns multiple rows from a table
- *
- * @param string $table The table name
- * @param mixed $select Either an array of fields or a MySQL string of fields
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @param string $order Order clause without the order keyword. ie: "added desc"
- * @param int $page a page number
- * @param int $limit a number for rows to return
- * @param boolean $fetch true: apply db::fetch(), false: don't apply db::fetch()
- * @return mixed
- */
- static function select($table, $select='*', $where=null, $order=null, $page=null, $limit=null, $fetch=true) {
- if($limit === 0) return array();
- if(is_array($select)) $select = self::select_clause($select);
- $sql = 'SELECT ' . $select . ' FROM ' . self::prefix($table);
- if(!empty($where)) $sql .= ' WHERE ' . self::where($where);
- if(!empty($order)) $sql .= ' ORDER BY ' . $order;
- if($page !== null && $limit !== null) $sql .= ' LIMIT ' . $page . ',' . $limit;
- return self::query($sql, $fetch);
- }
- /**
- * Returns a single row from a table
- *
- * @param string $table The table name
- * @param mixed $select Either an array of fields or a MySQL string of fields
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @param string $order Order clause without the order keyword. ie: "added desc"
- * @return mixed
- */
- static function row($table, $select='*', $where=null, $order=null) {
- $result = self::select($table, $select, $where, $order, 0,1, false);
- return self::fetch($result);
- }
- /**
- * Returns all values from single column of a table
- *
- * @param string $table The table name
- * @param string $column The name of the column
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @param string $order Order clause without the order keyword. ie: "added desc"
- * @param int $page a page number
- * @param int $limit a number for rows to return
- * @return mixed
- */
- static function column($table, $column, $where=null, $order=null, $page=null, $limit=null) {
- $result = self::select($table, $column, $where, $order, $page, $limit, false);
- $array = array();
- while($r = self::fetch($result)) array_push($array, a::get($r, $column));
- return $array;
- }
- /**
- * Returns a single field value from a table
- *
- * @param string $table The table name
- * @param string $field The name of the field
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @param string $order Order clause without the order keyword. ie: "added desc"
- * @return mixed
- */
- static function field($table, $field, $where=null, $order=null) {
- $result = self::row($table, $field, $where, $order);
- return a::get($result, $field);
- }
- /**
- * Joins two tables and returns data from them
- *
- * @param string $table_1 The table name of the first table
- * @param string $table_2 The table name of the second table
- * @param string $on The MySQL ON clause without the ON keyword. ie: "user_id = comment_user"
- * @param mixed $select Either an array of fields or a MySQL string of fields
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @param string $order Order clause without the order keyword. ie: "added desc"
- * @param int $page a page number
- * @param int $limit a number for rows to return
- * @param string $type The join type (JOIN, LEFT, RIGHT, INNER)
- * @return mixed
- */
- static function join($table_1, $table_2, $on, $select, $where=null, $order=null, $page=null, $limit=null, $type="JOIN") {
- return self::select(
- self::prefix($table_1) . ' ' . $type . ' ' .
- self::prefix($table_2) . ' ON ' .
- self::where($on),
- $select,
- self::where($where),
- $order,
- $page,
- $limit
- );
- }
- /**
- * Runs a LEFT JOIN
- *
- * @param string $table_1 The table name of the first table
- * @param string $table_2 The table name of the second table
- * @param string $on The MySQL ON clause without the ON keyword. ie: "user_id = comment_user"
- * @param mixed $select Either an array of fields or a MySQL string of fields
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @param string $order Order clause without the order keyword. ie: "added desc"
- * @param int $page a page number
- * @param int $limit a number for rows to return
- * @return mixed
- */
- static function left_join($table_1, $table_2, $on, $select, $where=null, $order=null, $page=null, $limit=null) {
- return self::join($table_1, $table_2, $on, $select, $where, $order, $page, $limit, 'LEFT JOIN');
- }
- /**
- * Counts a number of rows in a table
- *
- * @param string $table The table name
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @return int
- */
- static function count($table, $where='') {
- $result = self::row($table, 'count(*)', $where);
- return ($result) ? a::get($result, 'count(*)') : 0;
- }
- /**
- * Gets the minimum value in a column of a table
- *
- * @param string $table The table name
- * @param string $column The name of the column
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @return mixed
- */
- static function min($table, $column, $where=null) {
- $sql = 'SELECT MIN(' . $column . ') AS min FROM ' . self::prefix($table);
- if(!empty($where)) $sql .= ' WHERE ' . self::where($where);
- $result = self::query($sql, false);
- $result = self::fetch($result);
- return a::get($result, 'min', 1);
- }
- /**
- * Gets the maximum value in a column of a table
- *
- * @param string $table The table name
- * @param string $column The name of the column
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @return mixed
- */
- static function max($table, $column, $where=null) {
- $sql = 'SELECT MAX(' . $column . ') AS max FROM ' . self::prefix($table);
- if(!empty($where)) $sql .= ' WHERE ' . self::where($where);
- $result = self::query($sql, false);
- $result = self::fetch($result);
- return a::get($result, 'max', 1);
- }
- /**
- * Gets the sum of values in a column of a table
- *
- * @param string $table The table name
- * @param string $column The name of the column
- * @param mixed $where Either a key/value array as AND connected where clause or a simple MySQL where clause string
- * @return mixed
- */
- static function sum($table, $column, $where=null) {
- $sql = 'SELECT SUM(' . $column . ') AS sum FROM ' . self::prefix($table);
- if(!empty($where)) $sql .= ' WHERE ' . self::where($where);
- $result = self::query($sql, false);
- $result = self::fetch($result);
- return a::get($result, 'sum', 0);
- }
-
- /**
- * Adds a prefix to a table name if set in c::set('db.prefix', 'myprefix_');
- * This makes it possible to use table names in all methods without prefix
- * and it will still be applied automatically.
- *
- * @param string $table The name of the table with or without prefix
- * @return string The sanitized table name.
- */
- static function prefix($table) {
- $prefix = c::get('db.prefix');
- if(!$prefix) return $table;
- return (!str::contains($table,$prefix)) ? $prefix . $table : $table;
- }
- /**
- * Strips table specific column prefixes from the result array
- *
- * If you use column names like user_username, user_id, etc.
- * use this method on the result array to strip user_ of all fields
- *
- * @param array $array The result array
- * @return array The result array without those damn prefixes.
- */
- static function simple_fields($array) {
- if(empty($array)) return false;
- $output = array();
- foreach($array AS $key => $value) {
- $key = substr($key, strpos($key, '_')+1);
- $output[$key] = $value;
- }
- return $output;
- }
- /**
- * Makes it possible to use arrays for inputs instead of MySQL strings
- *
- * @param array $input
- * @return string The final MySQL string, which will be used in the queries.
- */
- static function values($input) {
- if(!is_array($input)) return $input;
- $output = array();
- foreach($input AS $key => $value) {
- if($value === 'NOW()')
- $output[] = $key . ' = NOW()';
- elseif(is_array($value))
- $output[] = $key . ' = \'' . a::json($value) . '\'';
- else
- $output[] = $key . ' = \'' . self::escape($value) . '\'';
- }
- return implode(', ', $output);
- }
-
- /**
- * Escapes unwanted stuff in values like slashes, etc.
- *
- * @param string $value
- * @return string Returns the escaped string
- */
- static function escape($value) {
- $value = str::stripslashes($value);
- return mysql_real_escape_string((string)$value, self::connect());
- }
-
- /**
- * A simplifier to build search clauses
- *
- * @param string $search The search word
- * @param array $fields An array of fields to search
- * @param string $mode OR or AND
- * @return string Returns the final where clause
- */
- static function search_clause($search, $fields, $mode='OR') {
- if(empty($search)) return false;
- $arr = array();
- foreach($fields AS $f) {
- array_push($arr, $f . ' LIKE \'%' . $search . '%\'');
- //array_push($arr, $f . ' REGEXP "[[:<:]]' . db::escape($search) . '[[:>:]]"');
- }
- return '(' . implode(' ' . trim($mode) . ' ', $arr) . ')';
- }
-
- /**
- * An easy method to build a part of the where clause to find stuff by its first character
- *
- * @param string $field The name of the field
- * @param string $char The character to search for
- * @return string Returns the where clause part
- */
- static function with($field, $char) {
- return 'LOWER(SUBSTRING(' . $field . ',1,1)) = "' . db::escape($char) . '"';
- }
- /**
- * Builds a select clause from a simple array
- *
- * @param array $field An array of field names
- * @return string The MySQL string
- */
- static function select_clause($fields) {
- return implode(', ', $fields);
- }
- /**
- * A simplifier to build IN clauses
- *
- * @param array $array An array of fieldnames
- * @return string The MySQL string for the where clause
- */
- static function in($array) {
- return '\'' . implode('\',\'', $array) . '\'';
- }
- /**
- * A handler to convert key/value arrays to an where clause
- *
- * @param array $array keys/values for the where clause
- * @param string $method AND or OR
- * @return string The MySQL string for the where clause
- */
- static function where($array, $method='AND') {
- if(!is_array($array)) return $array;
- $output = array();
- foreach($array AS $field => $value) {
- $output[] = $field . ' = \'' . self::escape($value) . '\'';
- $separator = ' ' . $method . ' ';
- }
- return implode(' ' . $method . ' ', $output);
- }
- /**
- * An internal error handler
- *
- * @param string $msg The error/success message to return
- * @param boolean $exit die after this error?
- * @return mixed
- */
- static function error($msg=null, $exit=false) {
- $connection = self::connection();
- $error = (mysql_error()) ? @mysql_error($connection) : false;
- $number = (mysql_errno()) ? @mysql_errno($connection) : 0;
- if(c::get('db.debugging')) {
- if($error) $msg .= ' -> ' . $error . ' (' . $number . ')';
- if(self::$last_query) $msg .= ' Query: ' . self::$last_query;
- } else $msg .= ' - ' . l::get('db.errors.msg', 'This will be fixed soon!');
- if($exit || c::get('db.debugging')) die($msg);
- return array(
- 'status' => 'error',
- 'msg' => $msg
- );
- }
- }
- /**
- *
- * Directory
- *
- * This class makes it easy to create/edit/delete
- * directories on the filesystem
- *
- * @package Kirby
- */
- class dir {
-
- /**
- * Creates a new directory
- *
- * @param string $dir The path for the new directory
- * @return boolean True: the dir has been created, false: creating failed
- */
- static function make($dir) {
- if(is_dir($dir)) return true;
- if(!@mkdir($dir, 0755)) return false;
- @chmod($dir, 0755);
- return true;
- }
- /**
- * Reads all files from a directory and returns them as an array.
- * It skips unwanted invisible stuff.
- *
- * @param string $dir The path of directory
- * @return mixed An array of filenames or false
- */
- static function read($dir) {
- if(!is_dir($dir)) return false;
- $skip = array('.', '..', '.DS_Store');
- return array_diff(scandir($dir),$skip);
- }
- /**
- * Reads a directory and returns a full set of info about it
- *
- * @param string $dir The path of directory
- * @return mixed An info array or false
- */
- static function inspect($dir) {
-
- if(!is_dir($dir)) return array();
- $files = dir::read($dir);
- $modified = filemtime($dir);
-
- $data = array(
- 'name' => basename($dir),
- 'root' => $dir,
- 'modified' => $modified,
- 'files' => array(),
- 'children' => array()
- );
- foreach($files AS $file) {
- if(is_dir($dir . '/' . $file)) {
- $data['children'][] = $file;
- } else {
- $data['files'][] = $file;
- }
- }
-
- return $data;
-
- }
- /**
- * Moves a directory to a new location
- *
- * @param string $old The current path of the directory
- * @param string $new The desired path where the dir should be moved to
- * @return boolean True: the directory has been moved, false: moving failed
- */
- static function move($old, $new) {
- if(!is_dir($old)) return false;
- return (@rename($old, $new) && is_dir($new)) ? true : false;
- }
- /**
- * Deletes a directory
- *
- * @param string $dir The path of the directory
- * @param boolean $keep If set to true, the directory will flushed but not removed.
- * @return boolean True: the directory has been removed, false: removing failed
- */
- static function remove($dir, $keep=false) {
- if(!is_dir($dir)) return false;
- $handle = @opendir($dir);
- $skip = array('.', '..');
- if(!$handle) return false;
- while($item = @readdir($handle)) {
- if(is_dir($dir . '/' . $item) && !in_array($item, $skip)) {
- self::remove($dir . '/' . $item);
- } else if(!in_array($item, $skip)) {
- @unlink($dir . '/' . $item);
- }
- }
- @closedir($handle);
- if(!$keep) return @rmdir($dir);
- return true;
- }
- /**
- * Flushes a directory
- *
- * @param string $dir The path of the directory
- * @return boolean True: the directory has been flushed, false: flushing failed
- */
- static function clean($dir) {
- return self::remove($dir, true);
- }
- /**
- * Gets the size of the directory and all subfolders and files
- *
- * @param string $dir The path of the directory
- * @param boolean $recursive
- * @param boolean $nice returns the size in a human readable size
- * @return mixed
- */
- static function size($path, $recursive=true, $nice=false) {
- if(!file_exists($path)) return false;
- if(is_file($path)) return self::size(…
Large files files are truncated, but you can click here to view the full file