diff --git a/.gitignore b/.gitignore index b451ef4..6ab4777 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ # Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file # /composer.lock +/fuel/core /fuel/vendor +/fuel/packages # the fuelphp document /docs/ @@ -24,3 +26,4 @@ /fuel/app/config/lock.php /.idea +composer.lock diff --git a/fuel/core/.gitignore b/fuel/core/.gitignore deleted file mode 100755 index 8b0bd70..0000000 --- a/fuel/core/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -*~ -*.bak -Thumbs.db -desktop.ini -.DS_Store -.buildpath -.project -.settings -fuel/app/logs/*/*/* -fuel/app/cache/*/* -nbproject/ -.idea -*.tmproj -*.sublime-project -*.sublime-workspace \ No newline at end of file diff --git a/fuel/core/CONTRIBUTING.md b/fuel/core/CONTRIBUTING.md deleted file mode 100755 index 89a5c47..0000000 --- a/fuel/core/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -Please read the project contibuting guidelines before creating an issue of sending in a pull request: - -https://github.com/fuel/fuel/wiki/Contributing diff --git a/fuel/core/base.php b/fuel/core/base.php deleted file mode 100755 index 440a1b0..0000000 --- a/fuel/core/base.php +++ /dev/null @@ -1,572 +0,0 @@ -= 50600) -{ - include "base56.php"; -} - -/** - * Loads in a core class and optionally an app class override if it exists. - * - * @param string $path - * @param string $folder - * @return void - */ -if ( ! function_exists('import')) -{ - function import($path, $folder = 'classes') - { - $path = str_replace('/', DIRECTORY_SEPARATOR, $path); - // load it ffrom the core if it exists - if (is_file(COREPATH.$folder.DIRECTORY_SEPARATOR.$path.'.php')) - { - require_once COREPATH.$folder.DIRECTORY_SEPARATOR.$path.'.php'; - } - // if the app has an override (or a non-core file), load that too - if (is_file(APPPATH.$folder.DIRECTORY_SEPARATOR.$path.'.php')) - { - require_once APPPATH.$folder.DIRECTORY_SEPARATOR.$path.'.php'; - } - } -} - -/** - * Shortcut for writing to the Log - * - * @param int|string the error level - * @param string the error message - * @param string information about the method - * @return bool - */ -if ( ! function_exists('logger')) -{ - function logger($level, $msg, $method = null) - { - static $labels = array( - 100 => 'DEBUG', - 200 => 'INFO', - 250 => 'NOTICE', - 300 => 'WARNING', - 400 => 'ERROR', - 500 => 'CRITICAL', - 550 => 'ALERT', - 600 => 'EMERGENCY', - 700 => 'ALL', - ); - - // make sure $level has the correct value - if ((is_int($level) and ! isset($labels[$level])) or (is_string($level) and ! array_search(strtoupper($level), $labels))) - { - throw new \FuelException('Invalid level "'.$level.'" passed to logger()'); - } - - if(is_string($level)) $level = array_search(strtoupper($level), $labels); - - // get the levels defined to be logged - $loglabels = \Config::get('log_threshold'); - - // bail out if we don't need logging at all - if ($loglabels == \Fuel::L_NONE) - { - return false; - } - - // if profiling is active log the message to the profile - if (\Config::get('profiling')) - { - \Console::log($method.' - '.$msg); - } - - // if it's not an array, assume it's an "up to" level - if ( ! is_array($loglabels)) - { - $a = array(); - foreach ($labels as $l => $label) - { - $l >= $loglabels and $a[] = $l; - } - $loglabels = $a; - } - - // do we need to log the message with this level? - if ( ! in_array($level, $loglabels)) - { - return false; - } - - return \Log::instance()->log($level, (empty($method) ? '' : $method.' - ').$msg); - } -} - -/** - * Takes an array of attributes and turns it into a string for an html tag - * - * @param array $attr - * @return string - */ -if ( ! function_exists('array_to_attr')) -{ - function array_to_attr($attr) - { - $attr_str = ''; - - foreach ((array) $attr as $property => $value) - { - // Ignore null/false - if ($value === null or $value === false) - { - continue; - } - - // If the key is numeric then it must be something like selected="selected" - if (is_numeric($property)) - { - $property = $value; - } - - $attr_str .= $property.'="'.str_replace('"', '"', $value).'" '; - } - - // We strip off the last space for return - return trim($attr_str); - } -} - -/** - * Create a XHTML tag - * - * @param string The tag name - * @param array|string The tag attributes - * @param string|bool The content to place in the tag, or false for no closing tag - * @return string - */ -if ( ! function_exists('html_tag')) -{ - function html_tag($tag, $attr = array(), $content = false) - { - // list of void elements (tags that can not have content) - static $void_elements = array( - // html4 - "area","base","br","col","hr","img","input","link","meta","param", - // html5 - "command","embed","keygen","source","track","wbr", - // html5.1 - "menuitem", - ); - - // construct the HTML - $html = '<'.$tag; - $html .= ( ! empty($attr)) ? ' '.(is_array($attr) ? array_to_attr($attr) : $attr) : ''; - - // a void element? - if (in_array(strtolower($tag), $void_elements)) - { - // these can not have content - $html .= ' />'; - } - else - { - // add the content and close the tag - $html .= '>'.$content.''; - } - - return $html; - } -} - -/** - * A case-insensitive version of in_array. - * - * @param mixed $needle - * @param array $haystack - * @return bool - */ -if ( ! function_exists('in_arrayi')) -{ - function in_arrayi($needle, $haystack) - { - return in_array(strtolower($needle), array_map('strtolower', $haystack)); - } -} - -/** - * Gets all the public vars for an object. Use this if you need to get all the - * public vars of $this inside an object. - * - * @return array - */ -if ( ! function_exists('get_object_public_vars')) -{ - function get_object_public_vars($obj) - { - return get_object_vars($obj); - } -} - -/** - * Renders a view and returns the output. - * - * @param string The view name/path - * @param array The data for the view - * @param bool Auto filter override - * @return string - */ -if ( ! function_exists('render')) -{ - function render($view, $data = null, $auto_filter = null) - { - return \View::forge($view, $data, $auto_filter)->render(); - } -} - -/** - * A wrapper function for Lang::get() - * - * @param mixed The string to translate - * @param array The parameters - * @return string - */ -if ( ! function_exists('__')) -{ - function __($string, $params = array(), $default = null, $language = null) - { - return \Lang::get($string, $params, $default, $language); - } -} - -/** - * Encodes the given string. This is just a wrapper function for Security::htmlentities() - * - * @param mixed The string to encode - * @return string - */ -if ( ! function_exists('e')) -{ - function e($string) - { - return \Security::htmlentities($string); - } -} - -/** - * Takes a classname and returns the actual classname for an alias or just the classname - * if it's a normal class. - * - * @param string classname to check - * @return string real classname - */ -if ( ! function_exists('get_real_class')) -{ - function get_real_class($class) - { - static $classes = array(); - - if ( ! array_key_exists($class, $classes)) - { - $reflect = new ReflectionClass($class); - $classes[$class] = $reflect->getName(); - } - - return $classes[$class]; - } -} - -/** - * Takes an associative array in the layout of parse_url, and constructs a URL from it - * - * see http://www.php.net/manual/en/function.http-build-url.php#96335 - * - * @param mixed (Part(s) of) an URL in form of a string or associative array like parse_url() returns - * @param mixed Same as the first argument - * @param int A bitmask of binary or'ed HTTP_URL constants (Optional)HTTP_URL_REPLACE is the default - * @param array If set, it will be filled with the parts of the composed url like parse_url() would return - * - * @return string constructed URL - */ -if (!function_exists('http_build_url')) -{ - define('HTTP_URL_REPLACE', 1); // Replace every part of the first URL when there's one of the second URL - define('HTTP_URL_JOIN_PATH', 2); // Join relative paths - define('HTTP_URL_JOIN_QUERY', 4); // Join query strings - define('HTTP_URL_STRIP_USER', 8); // Strip any user authentication information - define('HTTP_URL_STRIP_PASS', 16); // Strip any password authentication information - define('HTTP_URL_STRIP_AUTH', 32); // Strip any authentication information - define('HTTP_URL_STRIP_PORT', 64); // Strip explicit port numbers - define('HTTP_URL_STRIP_PATH', 128); // Strip complete path - define('HTTP_URL_STRIP_QUERY', 256); // Strip query string - define('HTTP_URL_STRIP_FRAGMENT', 512); // Strip any fragments (#identifier) - define('HTTP_URL_STRIP_ALL', 1024); // Strip anything but scheme and host - - function http_build_url($url, $parts = array(), $flags = HTTP_URL_REPLACE, &$new_url = false) - { - $keys = array('user','pass','port','path','query','fragment'); - - // HTTP_URL_STRIP_ALL becomes all the HTTP_URL_STRIP_Xs - if ($flags & HTTP_URL_STRIP_ALL) - { - $flags |= HTTP_URL_STRIP_USER; - $flags |= HTTP_URL_STRIP_PASS; - $flags |= HTTP_URL_STRIP_PORT; - $flags |= HTTP_URL_STRIP_PATH; - $flags |= HTTP_URL_STRIP_QUERY; - $flags |= HTTP_URL_STRIP_FRAGMENT; - } - // HTTP_URL_STRIP_AUTH becomes HTTP_URL_STRIP_USER and HTTP_URL_STRIP_PASS - elseif ($flags & HTTP_URL_STRIP_AUTH) - { - $flags |= HTTP_URL_STRIP_USER; - $flags |= HTTP_URL_STRIP_PASS; - } - - // parse the original URL - $parse_url = is_array($url) ? $url : parse_url($url); - - // make sure we always have a scheme, host and path - empty($parse_url['scheme']) and $parse_url['scheme'] = 'http'; - empty($parse_url['host']) and $parse_url['host'] = \Input::server('http_host'); - isset($parse_url['path']) or $parse_url['path'] = ''; - - // make the path absolute if needed - if ( ! empty($parse_url['path']) and substr($parse_url['path'], 0, 1) != '/') - { - $parse_url['path'] = '/'.$parse_url['path']; - } - - // scheme and host are always replaced - isset($parts['scheme']) and $parse_url['scheme'] = $parts['scheme']; - isset($parts['host']) and $parse_url['host'] = $parts['host']; - - // replace the original URL with it's new parts (if applicable) - if ($flags & HTTP_URL_REPLACE) - { - foreach ($keys as $key) - { - if (isset($parts[$key])) - $parse_url[$key] = $parts[$key]; - } - } - else - { - // join the original URL path with the new path - if (isset($parts['path']) && ($flags & HTTP_URL_JOIN_PATH)) - { - if (isset($parse_url['path'])) - $parse_url['path'] = rtrim(str_replace(basename($parse_url['path']), '', $parse_url['path']), '/') . '/' . ltrim($parts['path'], '/'); - else - $parse_url['path'] = $parts['path']; - } - - // join the original query string with the new query string - if (isset($parts['query']) && ($flags & HTTP_URL_JOIN_QUERY)) - { - if (isset($parse_url['query'])) - $parse_url['query'] .= '&' . $parts['query']; - else - $parse_url['query'] = $parts['query']; - } - } - - // strips all the applicable sections of the URL - // note: scheme and host are never stripped - foreach ($keys as $key) - { - if ($flags & (int) constant('HTTP_URL_STRIP_' . strtoupper($key))) - unset($parse_url[$key]); - } - - $new_url = $parse_url; - - return - ((isset($parse_url['scheme'])) ? $parse_url['scheme'] . '://' : '') - .((isset($parse_url['user'])) ? $parse_url['user'] . ((isset($parse_url['pass'])) ? ':' . $parse_url['pass'] : '') .'@' : '') - .((isset($parse_url['host'])) ? $parse_url['host'] : '') - .((isset($parse_url['port'])) ? ':' . $parse_url['port'] : '') - .((isset($parse_url['path'])) ? $parse_url['path'] : '') - .((isset($parse_url['query'])) ? '?' . $parse_url['query'] : '') - .((isset($parse_url['fragment'])) ? '#' . $parse_url['fragment'] : '') - ; - } -} - -/** - * Find the common "root" path of two given paths or FQFN's - * - * @param array array with the paths to compare - * - * @return string the determined common path section - */ -if ( ! function_exists('get_common_path')) -{ - function get_common_path($paths) - { - $lastOffset = 1; - $common = '/'; - while (($index = strpos($paths[0], '/', $lastOffset)) !== false) - { - $dirLen = $index - $lastOffset + 1; // include / - $dir = substr($paths[0], $lastOffset, $dirLen); - foreach ($paths as $path) - { - if (substr($path, $lastOffset, $dirLen) != $dir) - { - return $common; - } - } - $common .= $dir; - $lastOffset = $index + 1; - } - return $common; - } -} - -/** - * Faster equivalent of call_user_func_array - */ -if ( ! function_exists('call_fuel_func_array')) -{ - function call_fuel_func_array($callback, array $args) - { - // deal with "class::method" syntax - if (is_string($callback) and strpos($callback, '::') !== false) - { - $callback = explode('::', $callback); - } - - // if an array is passed, extract the object and method to call - if (is_array($callback) and isset($callback[1]) and is_object($callback[0])) - { - // make sure our arguments array is indexed - if ($count = count($args)) - { - $args = array_values($args); - } - - list($instance, $method) = $callback; - - // calling the method directly is faster then call_user_func_array() ! - switch ($count) - { - case 0: - return $instance->$method(); - - case 1: - return $instance->$method($args[0]); - - case 2: - return $instance->$method($args[0], $args[1]); - - case 3: - return $instance->$method($args[0], $args[1], $args[2]); - - case 4: - return $instance->$method($args[0], $args[1], $args[2], $args[3]); - } - } - - elseif (is_array($callback) and isset($callback[1]) and is_string($callback[0])) - { - list($class, $method) = $callback; - $class = '\\'.ltrim($class, '\\'); - - // calling the method directly is faster then call_user_func_array() ! - switch (count($args)) - { - case 0: - return $class::$method(); - - case 1: - return $class::$method($args[0]); - - case 2: - return $class::$method($args[0], $args[1]); - - case 3: - return $class::$method($args[0], $args[1], $args[2]); - - case 4: - return $class::$method($args[0], $args[1], $args[2], $args[3]); - } - } - - // if it's a string, it's a native function or a static method call - elseif (is_string($callback) or $callback instanceOf \Closure) - { - is_string($callback) and $callback = ltrim($callback, '\\'); - - // calling the method directly is faster then call_user_func_array() ! - switch (count($args)) - { - case 0: - return $callback(); - - case 1: - return $callback($args[0]); - - case 2: - return $callback($args[0], $args[1]); - - case 3: - return $callback($args[0], $args[1], $args[2]); - - case 4: - return $callback($args[0], $args[1], $args[2], $args[3]); - } - } - - // fallback, handle the old way - return call_user_func_array($callback, $args); - } -} - -/** - * hash_pbkdf2() implementation for PHP < 5.5.0 - */ -if ( ! function_exists('hash_pbkdf2')) -{ - /* PBKDF2 Implementation (described in RFC 2898) - * - * @param string a hash algorithm to use - * @param string p password - * @param string s salt - * @param int c iteration count (use 1000 or higher) - * @param int kl derived key length - * @param bool r when set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits. - * - * @return string derived key - */ - function hash_pbkdf2($a, $p, $s, $c, $kl = 0, $r = false) - { - $hl = strlen(hash($a, null, true)); # Hash length - $kb = ceil($kl / $hl); # Key blocks to compute - $dk = ''; # Derived key - - # Create key - for ( $block = 1; $block <= $kb; $block ++ ) - { - # Initial hash for this block - $ib = $b = hash_hmac($a, $s . pack('N', $block), $p, true); - - # Perform block iterations - for ( $i = 1; $i < $c; $i ++ ) - { - # XOR each iterate - $ib ^= ($b = hash_hmac($a, $b, $p, true)); - } - $dk .= $ib; # Append iterated block - } - - # Return derived key of correct length - return substr($r ? $dk : bin2hex($dk), 0, $kl); - } -} diff --git a/fuel/core/base56.php b/fuel/core/base56.php deleted file mode 100755 index 29116ba..0000000 --- a/fuel/core/base56.php +++ /dev/null @@ -1,57 +0,0 @@ -{$method}(...$args); - } - - // static call? - elseif (is_array($callback) and isset($callback[1]) and is_string($callback[0])) - { - list($class, $method) = $callback; - $class = '\\'.ltrim($class, '\\'); - - return $class::{$method}(...$args); - } - - // if it's a string, it's a native function or a static method call - elseif (is_string($callback) or $callback instanceOf \Closure) - { - is_string($callback) and $callback = ltrim($callback, '\\'); - } - - return $callback(...$args); - } -} diff --git a/fuel/core/bootstrap.php b/fuel/core/bootstrap.php deleted file mode 100755 index a678512..0000000 --- a/fuel/core/bootstrap.php +++ /dev/null @@ -1,347 +0,0 @@ -trigger('shutdown', '', 'none', true); - - // fire any framework shutdown events - \Event::instance()->trigger('fuel-shutdown', '', 'none', true); - } - catch (\Exception $e) - { - if (\Fuel::$is_cli) - { - \Cli::error("Error: ".$e->getMessage()." in ".$e->getFile()." on ".$e->getLine()); - \Cli::beep(); - exit(1); - } - else - { - logger(\Fuel::L_ERROR, 'shutdown - ' . $e->getMessage()." in ".$e->getFile()." on ".$e->getLine()); - } - } - return \Errorhandler::shutdown_handler(); -}); - -set_exception_handler(function ($e) -{ - // reset the autoloader - \Autoloader::_reset(); - - // deal with PHP bugs #42098/#54054 - if ( ! class_exists('Errorhandler')) - { - include COREPATH.'classes/errorhandler.php'; - class_alias('\Fuel\Core\Errorhandler', 'Errorhandler'); - class_alias('\Fuel\Core\PhpErrorException', 'PhpErrorException'); - } - - return \Errorhandler::exception_handler($e); -}); - -set_error_handler(function ($severity, $message, $filepath, $line) -{ - // reset the autoloader - \Autoloader::_reset(); - - // deal with PHP bugs #42098/#54054 - if ( ! class_exists('Errorhandler')) - { - include COREPATH.'classes/errorhandler.php'; - class_alias('\Fuel\Core\Errorhandler', 'Errorhandler'); - class_alias('\Fuel\Core\PhpErrorException', 'PhpErrorException'); - } - - return \Errorhandler::error_handler($severity, $message, $filepath, $line); -}); - -function setup_autoloader() -{ - \Autoloader::add_namespace('Fuel\\Core', COREPATH.'classes/'); - - \Autoloader::add_classes(array( - 'Fuel\\Core\\Agent' => COREPATH.'classes/agent.php', - - 'Fuel\\Core\\Arr' => COREPATH.'classes/arr.php', - - 'Fuel\\Core\\Asset' => COREPATH.'classes/asset.php', - 'Fuel\\Core\\Asset_Instance' => COREPATH.'classes/asset/instance.php', - - 'Fuel\\Core\\Cache' => COREPATH.'classes/cache.php', - 'Fuel\\Core\\CacheNotFoundException' => COREPATH.'classes/cache/notfound.php', - 'Fuel\\Core\\CacheExpiredException' => COREPATH.'classes/cache.php', - 'Fuel\\Core\\Cache_Handler_Driver' => COREPATH.'classes/cache/handler/driver.php', - 'Fuel\\Core\\Cache_Handler_Json' => COREPATH.'classes/cache/handler/json.php', - 'Fuel\\Core\\Cache_Handler_Serialized' => COREPATH.'classes/cache/handler/serialized.php', - 'Fuel\\Core\\Cache_Handler_String' => COREPATH.'classes/cache/handler/string.php', - 'Fuel\\Core\\Cache_Storage_Driver' => COREPATH.'classes/cache/storage/driver.php', - 'Fuel\\Core\\Cache_Storage_Apc' => COREPATH.'classes/cache/storage/apc.php', - 'Fuel\\Core\\Cache_Storage_File' => COREPATH.'classes/cache/storage/file.php', - 'Fuel\\Core\\Cache_Storage_Memcached' => COREPATH.'classes/cache/storage/memcached.php', - 'Fuel\\Core\\Cache_Storage_Redis' => COREPATH.'classes/cache/storage/redis.php', - 'Fuel\\Core\\Cache_Storage_Xcache' => COREPATH.'classes/cache/storage/xcache.php', - - 'Fuel\\Core\\Config' => COREPATH.'classes/config.php', - 'Fuel\\Core\\ConfigException' => COREPATH.'classes/config.php', - 'Fuel\\Core\\Config_Db' => COREPATH.'classes/config/db.php', - 'Fuel\\Core\\Config_File' => COREPATH.'classes/config/file.php', - 'Fuel\\Core\\Config_Ini' => COREPATH.'classes/config/ini.php', - 'Fuel\\Core\\Config_Json' => COREPATH.'classes/config/json.php', - 'Fuel\\Core\\Config_Interface' => COREPATH.'classes/config/interface.php', - 'Fuel\\Core\\Config_Php' => COREPATH.'classes/config/php.php', - 'Fuel\\Core\\Config_Yml' => COREPATH.'classes/config/yml.php', - 'Fuel\\Core\\Config_Memcached' => COREPATH.'classes/config/memcached.php', - - 'Fuel\\Core\\Controller' => COREPATH.'classes/controller.php', - 'Fuel\\Core\\Controller_Rest' => COREPATH.'classes/controller/rest.php', - 'Fuel\\Core\\Controller_Template' => COREPATH.'classes/controller/template.php', - 'Fuel\\Core\\Controller_Hybrid' => COREPATH.'classes/controller/hybrid.php', - - 'Fuel\\Core\\Cookie' => COREPATH.'classes/cookie.php', - - 'Fuel\\Core\\DB' => COREPATH.'classes/db.php', - 'Fuel\\Core\\DBUtil' => COREPATH.'classes/dbutil.php', - - 'Fuel\\Core\\Database_Connection' => COREPATH.'classes/database/connection.php', - 'Fuel\\Core\\Database_Result' => COREPATH.'classes/database/result.php', - 'Fuel\\Core\\Database_Result_Cached' => COREPATH.'classes/database/result/cached.php', - 'Fuel\\Core\\Database_Exception' => COREPATH.'classes/database/exception.php', - 'Fuel\\Core\\Database_Expression' => COREPATH.'classes/database/expression.php', - // Generic Schema builder - 'Fuel\\Core\\Database_Schema' => COREPATH.'classes/database/schema.php', - // Specific Schema builders - // Generic Query builder - 'Fuel\\Core\\Database_Query' => COREPATH.'classes/database/query.php', - 'Fuel\\Core\\Database_Query_Builder' => COREPATH.'classes/database/query/builder.php', - 'Fuel\\Core\\Database_Query_Builder_Insert' => COREPATH.'classes/database/query/builder/insert.php', - 'Fuel\\Core\\Database_Query_Builder_Delete' => COREPATH.'classes/database/query/builder/delete.php', - 'Fuel\\Core\\Database_Query_Builder_Update' => COREPATH.'classes/database/query/builder/update.php', - 'Fuel\\Core\\Database_Query_Builder_Select' => COREPATH.'classes/database/query/builder/select.php', - 'Fuel\\Core\\Database_Query_Builder_Where' => COREPATH.'classes/database/query/builder/where.php', - 'Fuel\\Core\\Database_Query_Builder_Join' => COREPATH.'classes/database/query/builder/join.php', - // Specific Query builders - 'Fuel\\Core\\Database_SQLite_Builder_Delete' => COREPATH.'classes/database/sqlite/builder/delete.php', - 'Fuel\\Core\\Database_SQLite_Builder_Update' => COREPATH.'classes/database/sqlite/builder/update.php', - // Generic PDO driver - 'Fuel\\Core\\Database_Pdo_Connection' => COREPATH.'classes/database/pdo/connection.php', - // Specific PDO drivers - 'Fuel\\Core\\Database_MySQL_Connection' => COREPATH.'classes/database/mysql/connection.php', - 'Fuel\\Core\\Database_SQLite_Connection' => COREPATH.'classes/database/sqlite/connection.php', - 'Fuel\\Core\\Database_Sqlsrv_Connection' => COREPATH.'classes/database/sqlsrv/connection.php', - 'Fuel\\Core\\Database_Dblib_Connection' => COREPATH.'classes/database/dblib/connection.php', - // Legacy drivers - 'Fuel\\Core\\Database_MySQLi_Connection' => COREPATH.'classes/database/mysqli/connection.php', - 'Fuel\\Core\\Database_MySQLi_Result' => COREPATH.'classes/database/mysqli/result.php', - - 'Fuel\\Core\\Fuel' => COREPATH.'classes/fuel.php', - 'Fuel\\Core\\FuelException' => COREPATH.'classes/fuel.php', - - 'Fuel\\Core\\Finder' => COREPATH.'classes/finder.php', - - 'Fuel\\Core\\Date' => COREPATH.'classes/date.php', - - 'Fuel\\Core\\Debug' => COREPATH.'classes/debug.php', - - 'Fuel\\Core\\Cli' => COREPATH.'classes/cli.php', - - 'Fuel\\Core\\Crypt' => COREPATH.'classes/crypt.php', - - 'Fuel\\Core\\Event' => COREPATH.'classes/event.php', - 'Fuel\\Core\\Event_Instance' => COREPATH.'classes/event/instance.php', - - 'Fuel\\Core\\Errorhandler' => COREPATH.'classes/errorhandler.php', - 'Fuel\\Core\\PhpErrorException' => COREPATH.'classes/errorhandler.php', - - 'Fuel\\Core\\Format' => COREPATH.'classes/format.php', - - 'Fuel\\Core\\Fieldset' => COREPATH.'classes/fieldset.php', - 'Fuel\\Core\\Fieldset_Field' => COREPATH.'classes/fieldset/field.php', - - 'Fuel\\Core\\File' => COREPATH.'classes/file.php', - 'Fuel\\Core\\FileAccessException' => COREPATH.'classes/file.php', - 'Fuel\\Core\\OutsideAreaException' => COREPATH.'classes/file.php', - 'Fuel\\Core\\InvalidPathException' => COREPATH.'classes/file.php', - 'Fuel\\Core\\File_Area' => COREPATH.'classes/file/area.php', - 'Fuel\\Core\\File_Handler_File' => COREPATH.'classes/file/handler/file.php', - 'Fuel\\Core\\File_Handler_Directory' => COREPATH.'classes/file/handler/directory.php', - - 'Fuel\\Core\\Form' => COREPATH.'classes/form.php', - 'Fuel\\Core\\Form_Instance' => COREPATH.'classes/form/instance.php', - - 'Fuel\\Core\\Ftp' => COREPATH.'classes/ftp.php', - 'Fuel\\Core\\FtpConnectionException' => COREPATH.'classes/ftp.php', - 'Fuel\\Core\\FtpFileAccessException' => COREPATH.'classes/ftp.php', - - 'Fuel\\Core\\HttpException' => COREPATH.'classes/httpexception.php', - 'Fuel\\Core\\HttpBadRequestException' => COREPATH.'classes/httpexceptions.php', - 'Fuel\\Core\\HttpNoAccessException' => COREPATH.'classes/httpexceptions.php', - 'Fuel\\Core\\HttpNotFoundException' => COREPATH.'classes/httpexceptions.php', - 'Fuel\\Core\\HttpServerErrorException' => COREPATH.'classes/httpexceptions.php', - - 'Fuel\\Core\\Html' => COREPATH.'classes/html.php', - - 'Fuel\\Core\\Image' => COREPATH.'classes/image.php', - 'Fuel\\Core\\Image_Driver' => COREPATH.'classes/image/driver.php', - 'Fuel\\Core\\Image_Gd' => COREPATH.'classes/image/gd.php', - 'Fuel\\Core\\Image_Imagemagick' => COREPATH.'classes/image/imagemagick.php', - 'Fuel\\Core\\Image_Imagick' => COREPATH.'classes/image/imagick.php', - - 'Fuel\\Core\\Inflector' => COREPATH.'classes/inflector.php', - - 'Fuel\\Core\\Input' => COREPATH.'classes/input.php', - - 'Fuel\\Core\\Lang' => COREPATH.'classes/lang.php', - 'Fuel\\Core\\LangException' => COREPATH.'classes/lang.php', - 'Fuel\\Core\\Lang_Db' => COREPATH.'classes/lang/db.php', - 'Fuel\\Core\\Lang_File' => COREPATH.'classes/lang/file.php', - 'Fuel\\Core\\Lang_Ini' => COREPATH.'classes/lang/ini.php', - 'Fuel\\Core\\Lang_Json' => COREPATH.'classes/lang/json.php', - 'Fuel\\Core\\Lang_Interface' => COREPATH.'classes/lang/interface.php', - 'Fuel\\Core\\Lang_Php' => COREPATH.'classes/lang/php.php', - 'Fuel\\Core\\Lang_Yml' => COREPATH.'classes/lang/yml.php', - - 'Fuel\\Core\\Log' => COREPATH.'classes/log.php', - - 'Fuel\\Core\\Markdown' => COREPATH.'classes/markdown.php', - - 'Fuel\\Core\\Migrate' => COREPATH.'classes/migrate.php', - - 'Fuel\\Core\\Model' => COREPATH.'classes/model.php', - 'Fuel\\Core\\Model_Crud' => COREPATH.'classes/model/crud.php', - - 'Fuel\\Core\\Module' => COREPATH.'classes/module.php', - 'Fuel\\Core\\ModuleNotFoundException' => COREPATH.'classes/module.php', - - 'Fuel\\Core\\Mongo_Db' => COREPATH.'classes/mongo/db.php', - 'Fuel\\Core\\Mongo_DbException' => COREPATH.'classes/mongo/db.php', - - 'Fuel\\Core\\Output' => COREPATH.'classes/output.php', - - 'Fuel\\Core\\Package' => COREPATH.'classes/package.php', - 'Fuel\\Core\\PackageNotFoundException' => COREPATH.'classes/package.php', - - 'Fuel\\Core\\Pagination' => COREPATH.'classes/pagination.php', - - 'Fuel\\Core\\Presenter' => COREPATH.'classes/presenter.php', - - 'Fuel\\Core\\Profiler' => COREPATH.'classes/profiler.php', - - 'Fuel\\Core\\Request' => COREPATH.'classes/request.php', - 'Fuel\\Core\\Request_Driver' => COREPATH.'classes/request/driver.php', - 'Fuel\\Core\\RequestException' => COREPATH.'classes/request/driver.php', - 'Fuel\\Core\\RequestStatusException' => COREPATH.'classes/request/driver.php', - 'Fuel\\Core\\Request_Curl' => COREPATH.'classes/request/curl.php', - 'Fuel\\Core\\Request_Soap' => COREPATH.'classes/request/soap.php', - - 'Fuel\\Core\\Redis_Db' => COREPATH.'classes/redis/db.php', - 'Fuel\\Core\\RedisException' => COREPATH.'classes/redis/db.php', - - 'Fuel\\Core\\Response' => COREPATH.'classes/response.php', - - 'Fuel\\Core\\Route' => COREPATH.'classes/route.php', - 'Fuel\\Core\\Router' => COREPATH.'classes/router.php', - - 'Fuel\\Core\\Sanitization' => COREPATH.'classes/sanitization.php', - - 'Fuel\\Core\\Security' => COREPATH.'classes/security.php', - 'Fuel\\Core\\SecurityException' => COREPATH.'classes/security.php', - - 'Fuel\\Core\\Session' => COREPATH.'classes/session.php', - 'Fuel\\Core\\Session_Driver' => COREPATH.'classes/session/driver.php', - 'Fuel\\Core\\Session_Db' => COREPATH.'classes/session/db.php', - 'Fuel\\Core\\Session_Cookie' => COREPATH.'classes/session/cookie.php', - 'Fuel\\Core\\Session_File' => COREPATH.'classes/session/file.php', - 'Fuel\\Core\\Session_Memcached' => COREPATH.'classes/session/memcached.php', - 'Fuel\\Core\\Session_Redis' => COREPATH.'classes/session/redis.php', - 'Fuel\\Core\\Session_Exception' => COREPATH.'classes/session/exception.php', - - 'Fuel\\Core\\Num' => COREPATH.'classes/num.php', - - 'Fuel\\Core\\Str' => COREPATH.'classes/str.php', - - 'Fuel\\Core\\TestCase' => COREPATH.'classes/testcase.php', - - 'Fuel\\Core\\Theme' => COREPATH.'classes/theme.php', - 'Fuel\\Core\\ThemeException' => COREPATH.'classes/theme.php', - - 'Fuel\\Core\\Uri' => COREPATH.'classes/uri.php', - - 'Fuel\\Core\\Unzip' => COREPATH.'classes/unzip.php', - - 'Fuel\\Core\\Upload' => COREPATH.'classes/upload.php', - - 'Fuel\\Core\\Validation' => COREPATH.'classes/validation.php', - 'Fuel\\Core\\Validation_Error' => COREPATH.'classes/validation/error.php', - - 'Fuel\\Core\\View' => COREPATH.'classes/view.php', - 'Fuel\\Core\\Viewmodel' => COREPATH.'classes/viewmodel.php', - )); -}; - -function get_composer() -{ - // storage for the composer autoloader - static $composer; - - // load composer - if ( ! $composer) - { - // load the Composer autoloader if present - defined('VENDORPATH') or define('VENDORPATH', realpath(COREPATH.'..'.DS.'vendor').DS); - if ( ! is_file(VENDORPATH.'autoload.php')) - { - die('Composer is not installed. Please run "php composer.phar update" in the root to install Composer'); - } - $composer = require(VENDORPATH.'autoload.php'); - } - - return $composer; -} diff --git a/fuel/core/bootstrap_phpunit.php b/fuel/core/bootstrap_phpunit.php deleted file mode 100755 index 181fc28..0000000 --- a/fuel/core/bootstrap_phpunit.php +++ /dev/null @@ -1,83 +0,0 @@ -init(array( - 'debug' => true, - 'appDir' => __DIR__.'/../', - 'includePaths' => array( - APPPATH, COREPATH, PKGPATH, - ), - 'excludePaths' => array( - APPPATH.'tests', COREPATH.'tests', - ), - 'cacheDir' => APPPATH.'tmp/AspectMock', - )); - - // Load in the Fuel autoloader - $kernel->loadFile(COREPATH.'classes'.DIRECTORY_SEPARATOR.'autoloader.php'); -} -else -{ - // Load in the Fuel autoloader - require COREPATH.'classes'.DIRECTORY_SEPARATOR.'autoloader.php'; -} - -class_alias('Fuel\\Core\\Autoloader', 'Autoloader'); - -// Boot the app -require_once APPPATH.'bootstrap.php'; - -// Set test mode -\Fuel::$is_test = true; - -// Ad hoc fix for AspectMock error -if (class_exists('AspectMock\Kernel')) -{ - class_exists('Errorhandler'); -} - -// Import the TestCase class -import('testcase'); diff --git a/fuel/core/classes/agent.php b/fuel/core/classes/agent.php deleted file mode 100755 index dfa9842..0000000 --- a/fuel/core/classes/agent.php +++ /dev/null @@ -1,657 +0,0 @@ - 'unknown', - 'version' => 0, - 'majorver' => 0, - 'minorver' => 0, - 'platform' => 'unknown', - 'alpha' => false, - 'beta' => false, - 'win16' => false, - 'win32' => false, - 'win64' => false, - 'frames' => false, - 'iframes' => false, - 'tables' => false, - 'cookies' => false, - 'backgroundsounds' => false, - 'javascript' => false, - 'vbscript' => false, - 'javaapplets' => false, - 'activexcontrols' => false, - 'isbanned' => false, - 'ismobiledevice' => false, - 'issyndicationreader' => false, - 'crawler' => false, - 'cssversion' => 0, - 'aolversion' => 0, - ); - - /** - * @var array property to cache key mapping - */ - protected static $keys = array( - 'browser' => 'A', - 'version' => 'B', - 'majorver' => 'C', - 'minorver' => 'D', - 'platform' => 'E', - 'alpha' => 'F', - 'beta' => 'G', - 'win16' => 'H', - 'win32' => 'I', - 'win64' => 'J', - 'frames' => 'K', - 'iframes' => 'L', - 'tables' => 'M', - 'cookies' => 'N', - 'backgroundsounds' => 'O', - 'javascript' => 'P', - 'vbscript' => 'Q', - 'javaapplets' => 'R', - 'activexcontrols' => 'S', - 'isbanned' => 'T', - 'ismobiledevice' => 'U', - 'issyndicationreader' => 'V', - 'crawler' => 'W', - 'cssversion' => 'X', - 'aolversion' => 'Y', - ); - - /** - * @var array global config defaults - */ - protected static $defaults = array( - 'browscap' => array( - 'enabled' => true, - 'url' => 'http://browscap.org/stream?q=Lite_PHP_BrowsCapINI', - 'method' => 'wrapper', - 'proxy' => array( - 'host' => null, - 'port' => null, - 'auth' => 'none', - 'username' => null, - 'password' => null, - ), - 'file' => '', - ), - 'cache' => array( - 'driver' => '', - 'expiry' => 604800, - 'identifier' => 'fuel.agent', - ), - ); - - /** - * @var array global config items - */ - protected static $config = array( - ); - - /** - * @var string detected user agent string - */ - protected static $user_agent = ''; - - // -------------------------------------------------------------------- - // public static methods - // -------------------------------------------------------------------- - - /** - * map the user agent string to browser specifications - * - * @return void - */ - public static function _init() - { - // fetch and store the user agent - static::$user_agent = \Input::server('http_user_agent', ''); - - // fetch and process the configuration - \Config::load('agent', true); - - static::$config = array_merge(static::$defaults, \Config::get('agent', array())); - - // validate the browscap configuration - if ( ! is_array(static::$config['browscap'])) - { - static::$config['browscap'] = static::$defaults['browscap']; - } - else - { - if ( ! array_key_exists('enabled', static::$config['browscap']) or ! is_bool(static::$config['browscap']['enabled'])) - { - static::$config['browscap']['enabled'] = true; - } - - if ( ! array_key_exists('url', static::$config['browscap']) or ! is_string(static::$config['browscap']['url'])) - { - static::$config['browscap']['url'] = static::$defaults['browscap']['url']; - } - - if ( ! array_key_exists('file', static::$config['browscap']) or ! is_string(static::$config['browscap']['file'])) - { - static::$config['browscap']['file'] = static::$defaults['browscap']['file']; - } - - if ( ! array_key_exists('method', static::$config['browscap']) or ! is_string(static::$config['browscap']['method'])) - { - static::$config['browscap']['method'] = static::$defaults['browscap']['method']; - } - static::$config['browscap']['method'] = strtolower(static::$config['browscap']['method']); - } - - // validate the cache configuration - if ( ! is_array(static::$config['cache'])) - { - static::$config['cache'] = static::$defaults['cache']; - } - else - { - if ( ! array_key_exists('driver', static::$config['cache']) or ! is_string(static::$config['cache']['driver'])) - { - static::$config['cache']['driver'] = static::$defaults['cache']['driver']; - } - - if ( ! array_key_exists('expiry', static::$config['cache']) or ! is_numeric(static::$config['cache']['expiry']) or static::$config['cache']['expiry'] < 7200) - { - static::$config['cache']['expiry'] = static::$defaults['cache']['expiry']; - } - - if ( ! array_key_exists('identifier', static::$config['cache']) or ! is_string(static::$config['cache']['identifier'])) - { - static::$config['cache']['identifier'] = static::$defaults['cache']['identifier']; - } - } - - // do we have a user agent? - if (static::$user_agent) - { - // try the build in get_browser() method - if (static::$config['browscap']['method'] == 'local' or ini_get('browscap') == '' or false === $browser = get_browser(static::$user_agent, true)) - { - // if it fails, emulate get_browser() - $browser = static::get_from_browscap(); - } - - if ($browser) - { - // save it for future reference - static::$properties = array_change_key_case($browser); - } - } - } - - // -------------------------------------------------------------------- - - /** - * get the normalized browser name - * - * @return string - */ - public static function browser() - { - return static::$properties['browser']; - } - - // -------------------------------------------------------------------- - - /** - * Get the browser platform - * - * @return string - */ - public static function platform() - { - return static::$properties['platform']; - } - - // -------------------------------------------------------------------- - - /** - * Get the Browser Version - * - * @return string - */ - public static function version() - { - return static::$properties['version']; - } - - // -------------------------------------------------------------------- - - /** - * Get any browser property - * - * @param string $property - * @return string|null - */ - public static function property($property = null) - { - $property = strtolower($property); - return array_key_exists($property, static::$properties) ? static::$properties[$property] : null; - } - - // -------------------------------------------------------------------- - - /** - * Get all browser properties - * - * @return array - */ - public static function properties() - { - return static::$properties; - } - - // -------------------------------------------------------------------- - - /** - * check if the current browser is a robot or crawler - * - * @return bool - */ - public static function is_robot() - { - return static::$properties['crawler']; - } - - // -------------------------------------------------------------------- - - /** - * check if the current browser is mobile device - * - * @return bool - */ - public static function is_mobiledevice() - { - return static::$properties['ismobiledevice']; - } - - // -------------------------------------------------------------------- - - /** - * check if the current browser accepts a specific language - * - * @param string $language optional ISO language code, defaults to 'en' - * @return bool - */ - public static function accepts_language($language = 'en') - { - return (in_array(strtolower($language), static::languages(), true)) ? true : false; - } - - // -------------------------------------------------------------------- - - /** - * check if the current browser accepts a specific character set - * - * @param string $charset optional character set, defaults to 'utf-8' - * @return bool - */ - public static function accepts_charset($charset = 'utf-8') - { - return (in_array(strtolower($charset), static::charsets(), true)) ? true : false; - } - - // -------------------------------------------------------------------- - - /** - * get the list of browser accepted languages - * - * @return array - */ - public static function languages() - { - return explode(',', preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim(\Input::server('http_accept_language'))))); - } - - // -------------------------------------------------------------------- - - /** - * get the list of browser accepted charactersets - * - * @return array - */ - public static function charsets() - { - return explode(',', preg_replace('/(;q=.+)/i', '', strtolower(trim(\Input::server('http_accept_charset'))))); - } - - // -------------------------------------------------------------------- - // internal static methods - // -------------------------------------------------------------------- - - /** - * use the parsed php_browscap.ini file to find a user agent match - * - * @return mixed array if a match is found, of false if not cached yet - */ - protected static function get_from_browscap() - { - $cache = \Cache::forge(static::$config['cache']['identifier'].'.browscap', static::$config['cache']['driver']); - - // load the cached browscap data - try - { - $browscap = $cache->get(); - } - // browscap not cached - catch (\Exception $e) - { - $browscap = static::$config['browscap']['enabled'] ? static::parse_browscap() : array(); - } - - $search = array('\*', '\?'); - $replace = array('.*', '.'); - - $result = false; - - // find a match for the user agent string - foreach($browscap as $browser => $properties) - { - $pattern = '@^'.str_replace($search, $replace, preg_quote($browser, '@')).'$@i'; - if (preg_match($pattern, static::$user_agent)) - { - // store the browser name - $properties['browser'] = $browser; - - // fetch possible parent info - if (array_key_exists('Parent', $properties)) - { - if ($properties['Parent'] > 0) - { - $parent = array_slice($browscap, $properties['Parent'], 1); - unset($properties['Parent']); - $properties = array_merge(current($parent), $properties); - - // store the browser name - $properties['browser'] = key($parent); - } - } - - // normalize keys - $properties = \Arr::replace_key($properties, array_flip(static::$keys)); - - // merge it with the defaults to add missing values - $result = array_merge(static::$properties, $properties); - - break; - } - } - - return $result; - } - - // -------------------------------------------------------------------- - - /** - * download and parse the browscap file - * - * @return array array with parsed download info, or empty if the download is disabled of failed - * @throws \Exception - * @throws \FuelException - */ - protected static function parse_browscap() - { - $cache = \Cache::forge(static::$config['cache']['identifier'].'.browscap_file', static::$config['cache']['driver']); - - // get the browscap.ini file - switch (static::$config['browscap']['method']) - { - case 'local': - if ( ! is_file(static::$config['browscap']['file']) or filesize(static::$config['browscap']['file']) == 0) - { - throw new \Exception('Agent class: could not open the local browscap.ini file: '.static::$config['browscap']['file']); - } - $data = @file_get_contents(static::$config['browscap']['file']); - break; - - // socket connections are not implemented yet! - case 'sockets': - $data = false; - break; - - case 'curl': - // initialize the proxy request - $curl = curl_init(); - curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($curl, CURLOPT_MAXREDIRS, 5); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_HEADER, 0); - curl_setopt($curl, CURLOPT_USERAGENT, 'Fuel PHP framework - Agent class (http://fuelphp.com)'); - curl_setopt($curl, CURLOPT_URL, static::$config['browscap']['url']); - - // add a proxy configuration if needed - if ( ! empty(static::$config['browscap']['proxy']['host']) and ! empty(static::$config['browscap']['proxy']['port'])) - { - curl_setopt($curl, CURLOPT_PROXY, static::$config['browscap']['proxy']['host']); - curl_setopt($curl, CURLOPT_PROXYPORT, static::$config['browscap']['proxy']['port']); - } - - // authentication set? - switch (static::$config['browscap']['proxy']['auth']) - { - case 'basic': - curl_setopt($curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC); - break; - - case 'ntlm': - curl_setopt($curl, CURLOPT_PROXYAUTH, CURLAUTH_NTLM); - break; - - default: - // no action - } - - // do we need to pass credentials? - switch (static::$config['browscap']['proxy']['auth']) - { - case 'basic': - case 'ntlm': - if (empty(static::$config['browscap']['proxy']['username']) or empty(static::$config['browscap']['proxy']['password'])) - { - logger(\Fuel::L_ERROR, 'Failed to set a proxy for Agent, cURL auth configured but no username or password configured'); - } - else - { - curl_setopt($curl, CURLOPT_PROXYUSERPWD, static::$config['browscap']['proxy']['username'].':'.static::$config['browscap']['proxy']['password']); - } - break; - - default: - // no action - } - - // execute the request - $data = curl_exec($curl); - - // check the response - $result = curl_getinfo($curl); - - if ($result['http_code'] !== 200) - { - logger(\Fuel::L_ERROR, 'Failed to download browscap.ini file. cURL response code was '.$result['http_code'], 'Agent::parse_browscap'); - logger(\Fuel::L_ERROR, $data); - $data = false; - } - break; - - case 'wrapper': - // set our custom user agent - ini_set('user_agent', 'Fuel PHP framework - Agent class (http://fuelphp.com)'); - - // create a stream context if needed - $context = null; - if ( ! empty(static::$config['browscap']['proxy']['host']) and ! empty(static::$config['browscap']['proxy']['port'])) - { - $context = array ( - 'http' => array ( - 'proxy' => 'tcp://'.static::$config['browscap']['proxy']['host'].':'.static::$config['browscap']['proxy']['port'], - 'request_fulluri' => true, - ), - ); - } - - // add credentials if needed - if ( ! empty(static::$config['browscap']['proxy']['auth']) and static::$config['browscap']['proxy']['auth'] == 'basic') - { - if ( ! empty(static::$config['browscap']['proxy']['username']) and ! empty(static::$config['browscap']['proxy']['password'])) - { - $context['http']['header'] = 'Proxy-Authorization: Basic '.base64_encode(static::$config['browscap']['proxy']['username'].':'.static::$config['browscap']['proxy']['password']); - } - else - { - logger(\Fuel::L_ERROR, 'Failed to set a proxy for Agent, "basic" auth configured but no username or password configured'); - $context = null; - } - } - - // attempt to download the file - try - { - if ($context) - { - $context = stream_context_create($context); - } - $data = file_get_contents(static::$config['browscap']['url'], false, $context); - } - catch (\ErrorException $e) - { - logger(\Fuel::L_ERROR, 'Failed to download browscap.ini file.', 'Agent::parse_browscap'); - logger(\Fuel::L_ERROR, $e->getMessage()); - $data = false; - } - break; - - default: - break; - } - - if ($data === false) - { - // if no data could be download, try retrieving a cached version - try - { - $data = $cache->get(false); - - // if the cached version is used, only cache the parsed result for a day - static::$config['cache']['expiry'] = 86400; - } - catch (\Exception $e) - { - logger(\Fuel::L_ERROR, 'Failed to get the cache of browscap.ini file.', 'Agent::parse_browscap'); - } - } - else - { - // store the downloaded data in the cache as a backup for future use - $cache->set($data, null); - } - - // parse the downloaded data - $browsers = @parse_ini_string($data, true, INI_SCANNER_RAW) or $browsers = array(); - - // remove the version and timestamp entry - array_shift($browsers); - - $result = array(); - - // reverse sort on key string length - uksort($browsers, function($a, $b) { return strlen($a) < strlen($b) ? 1 : -1; } ); - - $index = array(); - $count = 0; - - // reduce the array keys - foreach($browsers as $browser => $properties) - { - $index[$browser] = $count++; - - // fix any type issues - foreach ($properties as $var => $value) - { - if (is_numeric($value)) - { - $properties[$var] = $value + 0; - } - elseif ($value == 'true') - { - $properties[$var] = true; - } - elseif ($value == 'false') - { - $properties[$var] = false; - } - } - - $result[$browser] = \Arr::replace_key($properties, static::$keys); - - } - - // reduce parent links to - foreach($result as $browser => &$properties) - { - if (array_key_exists('Parent', $properties)) - { - if ($properties['Parent'] == 'DefaultProperties') - { - unset($properties['Parent']); - } - else - { - if (array_key_exists($properties['Parent'], $index)) - { - $properties['Parent'] = $index[$properties['Parent']]; - } - else - { - unset($properties['Parent']); - } - } - } - } - - // save the result to the cache - if ( ! empty($result)) - { - $cache = \Cache::forge(static::$config['cache']['identifier'].'.browscap', static::$config['cache']['driver']); - $cache->set($result, static::$config['cache']['expiry']); - } - - return $result; - } -} diff --git a/fuel/core/classes/arr.php b/fuel/core/classes/arr.php deleted file mode 100755 index de48355..0000000 --- a/fuel/core/classes/arr.php +++ /dev/null @@ -1,1288 +0,0 @@ - $v) - { - static::set($array, $k, $v); - } - } - else - { - $keys = explode('.', $key); - - while (count($keys) > 1) - { - $key = array_shift($keys); - - if ( ! isset($array[$key]) or ! is_array($array[$key])) - { - $array[$key] = array(); - } - - $array =& $array[$key]; - } - - $array[array_shift($keys)] = $value; - } - } - - /** - * Pluck an array of values from an array. - * - * @param array $array collection of arrays to pluck from - * @param string $key key of the value to pluck - * @param string $index optional return array index key, true for original index - * @return array array of plucked values - */ - public static function pluck($array, $key, $index = null) - { - $return = array(); - $get_deep = strpos($key, '.') !== false; - - if ( ! $index) - { - foreach ($array as $i => $a) - { - $return[] = (is_object($a) and ! ($a instanceof \ArrayAccess)) ? $a->{$key} : - ($get_deep ? static::get($a, $key) : $a[$key]); - } - } - else - { - foreach ($array as $i => $a) - { - $index !== true and $i = (is_object($a) and ! ($a instanceof \ArrayAccess)) ? $a->{$index} : $a[$index]; - $return[$i] = (is_object($a) and ! ($a instanceof \ArrayAccess)) ? $a->{$key} : - ($get_deep ? static::get($a, $key) : $a[$key]); - } - } - - return $return; - } - - /** - * Array_key_exists with a dot-notated key from an array. - * - * @param array $array The search array - * @param mixed $key The dot-notated key or array of keys - * @return mixed - */ - public static function key_exists($array, $key) - { - if ( ! is_array($array) and ! $array instanceof \ArrayAccess) - { - throw new \InvalidArgumentException('First parameter must be an array or ArrayAccess object.'); - } - - is_object($key) and $key = (string) $key; - - if ( ! is_string($key)) - { - return false; - } - - if (array_key_exists($key, $array)) - { - return true; - } - - foreach (explode('.', $key) as $key_part) - { - if (($array instanceof \ArrayAccess and isset($array[$key_part])) === false) - { - if ( ! is_array($array) or ! array_key_exists($key_part, $array)) - { - return false; - } - } - - $array = $array[$key_part]; - } - - return true; - } - - /** - * Unsets dot-notated key from an array - * - * @param array $array The search array - * @param mixed $key The dot-notated key or array of keys - * @return mixed - */ - public static function delete(&$array, $key) - { - if (is_null($key)) - { - return false; - } - - if (is_array($key)) - { - $return = array(); - foreach ($key as $k) - { - $return[$k] = static::delete($array, $k); - } - return $return; - } - - $key_parts = explode('.', $key); - - if ( ! is_array($array) or ! array_key_exists($key_parts[0], $array)) - { - return false; - } - - $this_key = array_shift($key_parts); - - if ( ! empty($key_parts)) - { - $key = implode('.', $key_parts); - return static::delete($array[$this_key], $key); - } - else - { - unset($array[$this_key]); - } - - return true; - } - - /** - * Converts a multi-dimensional associative array into an array of key => values with the provided field names - * - * @param array $assoc the array to convert - * @param string $key_field the field name of the key field - * @param string $val_field the field name of the value field - * @return array - * @throws \InvalidArgumentException - */ - public static function assoc_to_keyval($assoc, $key_field, $val_field) - { - if ( ! is_array($assoc) and ! $assoc instanceof \Iterator) - { - throw new \InvalidArgumentException('The first parameter must be an array.'); - } - - $output = array(); - foreach ($assoc as $row) - { - if (isset($row[$key_field]) and isset($row[$val_field])) - { - $output[$row[$key_field]] = $row[$val_field]; - } - } - - return $output; - } - - /** - * Converts an array of key => values into a multi-dimensional associative array with the provided field names - * - * @param array $array the array to convert - * @param string $key_field the field name of the key field - * @param string $val_field the field name of the value field - * @return array - * @throws \InvalidArgumentException - */ - public static function keyval_to_assoc($array, $key_field, $val_field) - { - if ( ! is_array($array) and ! $array instanceof \Iterator) - { - throw new \InvalidArgumentException('The first parameter must be an array.'); - } - - $output = array(); - foreach ($array as $key => $value) - { - $output[] = array( - $key_field => $key, - $val_field => $value, - ); - } - - return $output; - } - - /** - * Converts the given 1 dimensional non-associative array to an associative - * array. - * - * The array given must have an even number of elements or null will be returned. - * - * Arr::to_assoc(array('foo','bar')); - * - * @param string $arr the array to change - * @return array|null the new array or null - * @throws \BadMethodCallException - */ - public static function to_assoc($arr) - { - if (($count = count($arr)) % 2 > 0) - { - throw new \BadMethodCallException('Number of values in to_assoc must be even.'); - } - $keys = $vals = array(); - - for ($i = 0; $i < $count - 1; $i += 2) - { - $keys[] = array_shift($arr); - $vals[] = array_shift($arr); - } - return array_combine($keys, $vals); - } - - /** - * Checks if the given array is an assoc array. - * - * @param array $arr the array to check - * @return bool true if its an assoc array, false if not - */ - public static function is_assoc($arr) - { - if ( ! is_array($arr)) - { - throw new \InvalidArgumentException('The parameter must be an array.'); - } - - $counter = 0; - foreach ($arr as $key => $unused) - { - if ( ! is_int($key) or $key !== $counter++) - { - return true; - } - } - return false; - } - - /** - * Flattens a multi-dimensional associative array down into a 1 dimensional - * associative array. - * - * @param array $array the array to flatten - * @param string $glue what to glue the keys together with - * @param bool $reset whether to reset and start over on a new array - * @param bool $indexed whether to flatten only associative array's, or also indexed ones - * @return array - */ - public static function flatten($array, $glue = ':', $reset = true, $indexed = true) - { - static $return = array(); - static $curr_key = array(); - - if ($reset) - { - $return = array(); - $curr_key = array(); - } - - foreach ($array as $key => $val) - { - $curr_key[] = $key; - if (is_array($val) and ($indexed or array_values($val) !== $val)) - { - static::flatten($val, $glue, false, $indexed); - } - else - { - $return[implode($glue, $curr_key)] = $val; - } - array_pop($curr_key); - } - return $return; - } - - /** - * Flattens a multi-dimensional associative array down into a 1 dimensional - * associative array. - * - * @param array $array the array to flatten - * @param string $glue what to glue the keys together with - * @param bool $reset whether to reset and start over on a new array - * @return array - */ - public static function flatten_assoc($array, $glue = ':', $reset = true) - { - return static::flatten($array, $glue, $reset, false); - } - - /** - * Reverse a flattened array in its original form. - * - * @param array $array flattened array - * @param string $glue glue used in flattening - * @return array the unflattened array - */ - public static function reverse_flatten($array, $glue = ':') - { - $return = array(); - - foreach ($array as $key => $value) - { - if (stripos($key, $glue) !== false) - { - $keys = explode($glue, $key); - $temp =& $return; - while (count($keys) > 1) - { - $key = array_shift($keys); - $key = is_numeric($key) ? (int) $key : $key; - if ( ! isset($temp[$key]) or ! is_array($temp[$key])) - { - $temp[$key] = array(); - } - $temp =& $temp[$key]; - } - - $key = array_shift($keys); - $key = is_numeric($key) ? (int) $key : $key; - $temp[$key] = $value; - } - else - { - $key = is_numeric($key) ? (int) $key : $key; - $return[$key] = $value; - } - } - - return $return; - } - - /** - * Filters an array on prefixed associative keys. - * - * @param array $array the array to filter. - * @param string $prefix prefix to filter on. - * @param bool $remove_prefix whether to remove the prefix. - * @return array - */ - public static function filter_prefixed($array, $prefix, $remove_prefix = true) - { - $return = array(); - foreach ($array as $key => $val) - { - if (preg_match('/^'.$prefix.'/', $key)) - { - if ($remove_prefix === true) - { - $key = preg_replace('/^'.$prefix.'/', '', $key); - } - $return[$key] = $val; - } - } - return $return; - } - - /** - * Recursive version of PHP's array_filter() - * - * @param array $array the array to filter. - * @param callback $callback the callback that determines whether or not a value is filtered - * @return array - */ - public static function filter_recursive($array, $callback = null) - { - foreach ($array as &$value) - { - if (is_array($value)) - { - $value = $callback === null ? static::filter_recursive($value) : static::filter_recursive($value, $callback); - } - } - - return $callback === null ? array_filter($array) : array_filter($array, $callback); - } - - /** - * Removes items from an array that match a key prefix. - * - * @param array $array the array to remove from - * @param string $prefix prefix to filter on - * @return array - */ - public static function remove_prefixed($array, $prefix) - { - foreach ($array as $key => $val) - { - if (preg_match('/^'.$prefix.'/', $key)) - { - unset($array[$key]); - } - } - return $array; - } - - /** - * Filters an array on suffixed associative keys. - * - * @param array $array the array to filter. - * @param string $suffix suffix to filter on. - * @param bool $remove_suffix whether to remove the suffix. - * @return array - */ - public static function filter_suffixed($array, $suffix, $remove_suffix = true) - { - $return = array(); - foreach ($array as $key => $val) - { - if (preg_match('/'.$suffix.'$/', $key)) - { - if ($remove_suffix === true) - { - $key = preg_replace('/'.$suffix.'$/', '', $key); - } - $return[$key] = $val; - } - } - return $return; - } - - /** - * Removes items from an array that match a key suffix. - * - * @param array $array the array to remove from - * @param string $suffix suffix to filter on - * @return array - */ - public static function remove_suffixed($array, $suffix) - { - foreach ($array as $key => $val) - { - if (preg_match('/'.$suffix.'$/', $key)) - { - unset($array[$key]); - } - } - return $array; - } - - /** - * Filters an array by an array of keys - * - * @param array $array the array to filter. - * @param array $keys the keys to filter - * @param bool $remove if true, removes the matched elements. - * @return array - */ - public static function filter_keys($array, $keys, $remove = false) - { - $return = array(); - foreach ($keys as $key) - { - if (array_key_exists($key, $array)) - { - $remove or $return[$key] = $array[$key]; - if($remove) - { - unset($array[$key]); - } - } - } - return $remove ? $array : $return; - } - - /** - * Insert value(s) into an array, mostly an array_splice alias - * WARNING: original array is edited by reference, only boolean success is returned - * - * @param array $original the original array (by reference) - * @param array|mixed $value the value(s) to insert, if you want to insert an array it needs to be in an array itself - * @param int $pos the numeric position at which to insert, negative to count from the end backwards - * @return bool false when array shorter then $pos, otherwise true - */ - public static function insert(array &$original, $value, $pos) - { - if (count($original) < abs($pos)) - { - \Errorhandler::notice('Position larger than number of elements in array in which to insert.'); - return false; - } - - array_splice($original, $pos, 0, $value); - - return true; - } - - /** - * Insert value(s) into an array, mostly an array_splice alias - * WARNING: original array is edited by reference, only boolean success is returned - * - * @param array $original the original array (by reference) - * @param array|mixed $values the value(s) to insert, if you want to insert an array it needs to be in an array itself - * @param int $pos the numeric position at which to insert, negative to count from the end backwards - * @return bool false when array shorter then $pos, otherwise true - */ - public static function insert_assoc(array &$original, array $values, $pos) - { - if (count($original) < abs($pos)) - { - return false; - } - - $original = array_slice($original, 0, $pos, true) + $values + array_slice($original, $pos, null, true); - - return true; - } - - /** - * Insert value(s) into an array before a specific key - * WARNING: original array is edited by reference, only boolean success is returned - * - * @param array $original the original array (by reference) - * @param array|mixed $value the value(s) to insert, if you want to insert an array it needs to be in an array itself - * @param string|int $key the key before which to insert - * @param bool $is_assoc whether the input is an associative array - * @return bool false when key isn't found in the array, otherwise true - */ - public static function insert_before_key(array &$original, $value, $key, $is_assoc = false) - { - $pos = array_search($key, array_keys($original)); - - if ($pos === false) - { - \Errorhandler::notice('Unknown key before which to insert the new value into the array.'); - return false; - } - - return $is_assoc ? static::insert_assoc($original, $value, $pos) : static::insert($original, $value, $pos); - } - - /** - * Insert value(s) into an array after a specific key - * WARNING: original array is edited by reference, only boolean success is returned - * - * @param array $original the original array (by reference) - * @param array|mixed $value the value(s) to insert, if you want to insert an array it needs to be in an array itself - * @param string|int $key the key after which to insert - * @param bool $is_assoc whether the input is an associative array - * @return bool false when key isn't found in the array, otherwise true - */ - public static function insert_after_key(array &$original, $value, $key, $is_assoc = false) - { - $pos = array_search($key, array_keys($original)); - - if ($pos === false) - { - \Errorhandler::notice('Unknown key after which to insert the new value into the array.'); - return false; - } - - return $is_assoc ? static::insert_assoc($original, $value, $pos + 1) : static::insert($original, $value, $pos + 1); - } - - /** - * Insert value(s) into an array after a specific value (first found in array) - * - * @param array $original the original array (by reference) - * @param array|mixed $value the value(s) to insert, if you want to insert an array it needs to be in an array itself - * @param string|int $search the value after which to insert - * @param bool $is_assoc whether the input is an associative array - * @return bool false when value isn't found in the array, otherwise true - */ - public static function insert_after_value(array &$original, $value, $search, $is_assoc = false) - { - $key = array_search($search, $original); - - if ($key === false) - { - \Errorhandler::notice('Unknown value after which to insert the new value into the array.'); - return false; - } - - return static::insert_after_key($original, $value, $key, $is_assoc); - } - - /** - * Insert value(s) into an array before a specific value (first found in array) - * - * @param array $original the original array (by reference) - * @param array|mixed $value the value(s) to insert, if you want to insert an array it needs to be in an array itself - * @param string|int $search the value after which to insert - * @param bool $is_assoc whether the input is an associative array - * @return bool false when value isn't found in the array, otherwise true - */ - public static function insert_before_value(array &$original, $value, $search, $is_assoc = false) - { - $key = array_search($search, $original); - - if ($key === false) - { - \Errorhandler::notice('Unknown value before which to insert the new value into the array.'); - return false; - } - - return static::insert_before_key($original, $value, $key, $is_assoc); - } - - /** - * Sorts a multi-dimensional array by it's values. - * - * @access public - * @param array $array The array to fetch from - * @param string $key The key to sort by - * @param string $order The order (asc or desc) - * @param int $sort_flags The php sort type flag - * @return array - */ - public static function sort($array, $key, $order = 'asc', $sort_flags = SORT_REGULAR) - { - if ( ! is_array($array)) - { - throw new \InvalidArgumentException('Arr::sort() - $array must be an array.'); - } - - if (empty($array)) - { - return $array; - } - - foreach ($array as $k => $v) - { - $b[$k] = static::get($v, $key); - } - - switch ($order) - { - case 'asc': - asort($b, $sort_flags); - break; - - case 'desc': - arsort($b, $sort_flags); - break; - - default: - throw new \InvalidArgumentException('Arr::sort() - $order must be asc or desc.'); - break; - } - - foreach ($b as $key => $val) - { - $c[] = $array[$key]; - } - - return $c; - } - - /** - * Sorts an array on multiple values, with deep sorting support. - * - * @param array $array collection of arrays/objects to sort - * @param array $conditions sorting conditions - * @param bool $ignore_case whether to sort case insensitive - * @return array - */ - public static function multisort($array, $conditions, $ignore_case = false) - { - $temp = array(); - $keys = array_keys($conditions); - - foreach($keys as $key) - { - $temp[$key] = static::pluck($array, $key, true); - is_array($conditions[$key]) or $conditions[$key] = array($conditions[$key]); - } - - $args = array(); - foreach ($keys as $key) - { - $args[] = $ignore_case ? array_map('strtolower', $temp[$key]) : $temp[$key]; - foreach($conditions[$key] as $flag) - { - $args[] = $flag; - } - } - - $args[] = &$array; - - call_fuel_func_array('array_multisort', $args); - return $array; - } - - /** - * Find the average of an array - * - * @param array $array the array containing the values - * @return number the average value - */ - public static function average($array) - { - // No arguments passed, lets not divide by 0 - if ( ! ($count = count($array)) > 0) - { - return 0; - } - - return (array_sum($array) / $count); - } - - /** - * Replaces key names in an array by names in $replace - * - * @param array $source the array containing the key/value combinations - * @param array|string $replace key to replace or array containing the replacement keys - * @param string $new_key the replacement key - * @return array the array with the new keys - */ - public static function replace_key($source, $replace, $new_key = null) - { - if(is_string($replace)) - { - $replace = array($replace => $new_key); - } - - if ( ! is_array($source) or ! is_array($replace)) - { - throw new \InvalidArgumentException('Arr::replace_key() - $source must an array. $replace must be an array or string.'); - } - - $result = array(); - - foreach ($source as $key => $value) - { - if (array_key_exists($key, $replace)) - { - $result[$replace[$key]] = $value; - } - else - { - $result[$key] = $value; - } - } - - return $result; - } - - /** - * Merge 2 arrays recursively, differs in 2 important ways from array_merge_recursive() - * - When there's 2 different values and not both arrays, the latter value overwrites the earlier - * instead of merging both into an array - * - Numeric keys that don't conflict aren't changed, only when a numeric key already exists is the - * value added using array_push() - * - * @return array - * @throws \InvalidArgumentException - */ - public static function merge() - { - $array = func_get_arg(0); - $arrays = array_slice(func_get_args(), 1); - - if ( ! is_array($array)) - { - throw new \InvalidArgumentException('Arr::merge() - all arguments must be arrays.'); - } - - foreach ($arrays as $arr) - { - if ( ! is_array($arr)) - { - throw new \InvalidArgumentException('Arr::merge() - all arguments must be arrays.'); - } - - foreach ($arr as $k => $v) - { - // numeric keys are appended - if (is_int($k)) - { - array_key_exists($k, $array) ? $array[] = $v : $array[$k] = $v; - } - elseif (is_array($v) and array_key_exists($k, $array) and is_array($array[$k])) - { - $array[$k] = static::merge($array[$k], $v); - } - else - { - $array[$k] = $v; - } - } - } - - return $array; - } - - /** - * Merge 2 arrays recursively, differs in 2 important ways from array_merge_recursive() - * - When there's 2 different values and not both arrays, the latter value overwrites the earlier - * instead of merging both into an array - * - Numeric keys are never changed - * - * @return array - * @throws \InvalidArgumentException - */ - public static function merge_assoc() - { - $array = func_get_arg(0); - $arrays = array_slice(func_get_args(), 1); - - if ( ! is_array($array)) - { - throw new \InvalidArgumentException('Arr::merge_assoc() - all arguments must be arrays.'); - } - - foreach ($arrays as $arr) - { - if ( ! is_array($arr)) - { - throw new \InvalidArgumentException('Arr::merge_assoc() - all arguments must be arrays.'); - } - - foreach ($arr as $k => $v) - { - if (is_array($v) and array_key_exists($k, $array) and is_array($array[$k])) - { - $array[$k] = static::merge_assoc($array[$k], $v); - } - else - { - $array[$k] = $v; - } - } - } - - return $array; - } - - /** - * Prepends a value with an associative key to an array. - * Will overwrite if the value exists. - * - * @param array $arr the array to prepend to - * @param string|array $key the key or array of keys and values - * @param mixed $value the value to prepend - */ - public static function prepend(&$arr, $key, $value = null) - { - $arr = (is_array($key) ? $key : array($key => $value)) + $arr; - } - - /** - * Recursive in_array - * - * @param mixed $needle what to search for - * @param array $haystack array to search in - * @param bool $strict - * @return bool whether the needle is found in the haystack. - */ - public static function in_array_recursive($needle, $haystack, $strict = false) - { - foreach ($haystack as $value) - { - if ( ! $strict and $needle == $value) - { - return true; - } - elseif ($needle === $value) - { - return true; - } - elseif (is_array($value) and static::in_array_recursive($needle, $value, $strict)) - { - return true; - } - } - - return false; - } - - /** - * Checks if the given array is a multidimensional array. - * - * @param array $arr the array to check - * @param bool $all_keys if true, check that all elements are arrays - * @return bool true if its a multidimensional array, false if not - */ - public static function is_multi($arr, $all_keys = false) - { - $values = array_filter($arr, 'is_array'); - return $all_keys ? count($arr) === count($values) : count($values) > 0; - } - - /** - * Searches the array for a given value and returns the - * corresponding key or default value. - * If $recursive is set to true, then the Arr::search() - * function will return a delimiter-notated key using $delimiter. - * - * @param array $array The search array - * @param mixed $value The searched value - * @param string $default The default value - * @param bool $recursive Whether to get keys recursive - * @param string $delimiter The delimiter, when $recursive is true - * @param bool $strict If true, do a strict key comparison - * @return mixed - */ - public static function search($array, $value, $default = null, $recursive = true, $delimiter = '.', $strict = false) - { - if ( ! is_array($array) and ! $array instanceof \ArrayAccess) - { - throw new \InvalidArgumentException('First parameter must be an array or ArrayAccess object.'); - } - - if ( ! is_null($default) and ! is_int($default) and ! is_string($default)) - { - throw new \InvalidArgumentException('Expects parameter 3 to be an string or integer or null.'); - } - - if ( ! is_string($delimiter)) - { - throw new \InvalidArgumentException('Expects parameter 5 must be an string.'); - } - - $key = array_search($value, $array, $strict); - - if ($recursive and $key === false) - { - $keys = array(); - foreach ($array as $k => $v) - { - if (is_array($v)) - { - $rk = static::search($v, $value, $default, true, $delimiter, $strict); - if ($rk !== $default) - { - $keys = array($k, $rk); - break; - } - } - } - $key = count($keys) ? implode($delimiter, $keys) : false; - } - - return $key === false ? $default : $key; - } - - /** - * Returns only unique values in an array. It does not sort. First value is used. - * - * @param array $arr the array to dedup - * @return array array with only de-duped values - */ - public static function unique($arr) - { - // filter out all duplicate values - return array_filter($arr, function($item) - { - // contrary to popular belief, this is not as static as you think... - static $vars = array(); - - if (in_array($item, $vars, true)) - { - // duplicate - return false; - } - else - { - // record we've had this value - $vars[] = $item; - - // unique - return true; - } - }); - } - - /** - * Calculate the sum of an array - * - * @param array $array the array containing the values - * @param string $key key of the value to pluck - * @return number the sum value - */ - public static function sum($array, $key) - { - if ( ! is_array($array) and ! $array instanceof \ArrayAccess) - { - throw new \InvalidArgumentException('First parameter must be an array or ArrayAccess object.'); - } - - return array_sum(static::pluck($array, $key)); - } - - /** - * Returns the array with all numeric keys re-indexed, and string keys untouched - * - * @param array $arr the array to reindex - * @return array re-indexed array - */ - public static function reindex($arr) - { - // reindex this level - $arr = array_merge($arr); - - foreach ($arr as $k => &$v) - { - is_array($v) and $v = static::reindex($v); - } - - return $arr; - } - - /** - * Get the previous value or key from an array using the current array key - * - * @param array $array the array containing the values - * @param string $key key of the current entry to use as reference - * @param bool $get_value if true, return the previous value instead of the previous key - * @param bool $strict if true, do a strict key comparison - * - * @return mixed the value in the array, null if there is no previous value, or false if the key doesn't exist - */ - public static function previous_by_key($array, $key, $get_value = false, $strict = false) - { - if ( ! is_array($array) and ! $array instanceof \ArrayAccess) - { - throw new \InvalidArgumentException('First parameter must be an array or ArrayAccess object.'); - } - - // get the keys of the array - $keys = array_keys($array); - - // and do a lookup of the key passed - if (($index = array_search($key, $keys, $strict)) === false) - { - // key does not exist - return false; - } - - // check if we have a previous key - elseif ( ! isset($keys[$index-1])) - { - // there is none - return null; - } - - // return the value or the key of the array entry the previous key points to - return $get_value ? $array[$keys[$index-1]] : $keys[$index-1]; - } - - /** - * Get the next value or key from an array using the current array key - * - * @param array $array the array containing the values - * @param string $key key of the current entry to use as reference - * @param bool $get_value if true, return the next value instead of the next key - * @param bool $strict if true, do a strict key comparison - * - * @return mixed the value in the array, null if there is no next value, or false if the key doesn't exist - */ - public static function next_by_key($array, $key, $get_value = false, $strict = false) - { - if ( ! is_array($array) and ! $array instanceof \ArrayAccess) - { - throw new \InvalidArgumentException('First parameter must be an array or ArrayAccess object.'); - } - - // get the keys of the array - $keys = array_keys($array); - - // and do a lookup of the key passed - if (($index = array_search($key, $keys, $strict)) === false) - { - // key does not exist - return false; - } - - // check if we have a previous key - elseif ( ! isset($keys[$index+1])) - { - // there is none - return null; - } - - // return the value or the key of the array entry the previous key points to - return $get_value ? $array[$keys[$index+1]] : $keys[$index+1]; - } - - /** - * Get the previous value or key from an array using the current array value - * - * @param array $array the array containing the values - * @param string $value value of the current entry to use as reference - * @param bool $get_value if true, return the previous value instead of the previous key - * @param bool $strict if true, do a strict key comparison - * - * @return mixed the value in the array, null if there is no previous value, or false if the key doesn't exist - */ - public static function previous_by_value($array, $value, $get_value = true, $strict = false) - { - if ( ! is_array($array) and ! $array instanceof \ArrayAccess) - { - throw new \InvalidArgumentException('First parameter must be an array or ArrayAccess object.'); - } - - // find the current value in the array - if (($key = array_search($value, $array, $strict)) === false) - { - // bail out if not found - return false; - } - - // get the list of keys, and find our found key - $keys = array_keys($array); - $index = array_search($key, $keys); - - // if there is no previous one, bail out - if ( ! isset($keys[$index-1])) - { - return null; - } - - // return the value or the key of the array entry the previous key points to - return $get_value ? $array[$keys[$index-1]] : $keys[$index-1]; - } - - /** - * Get the next value or key from an array using the current array value - * - * @param array $array the array containing the values - * @param string $value value of the current entry to use as reference - * @param bool $get_value if true, return the next value instead of the next key - * @param bool $strict if true, do a strict key comparison - * - * @return mixed the value in the array, null if there is no next value, or false if the key doesn't exist - */ - public static function next_by_value($array, $value, $get_value = true, $strict = false) - { - if ( ! is_array($array) and ! $array instanceof \ArrayAccess) - { - throw new \InvalidArgumentException('First parameter must be an array or ArrayAccess object.'); - } - - // find the current value in the array - if (($key = array_search($value, $array, $strict)) === false) - { - // bail out if not found - return false; - } - - // get the list of keys, and find our found key - $keys = array_keys($array); - $index = array_search($key, $keys); - - // if there is no next one, bail out - if ( ! isset($keys[$index+1])) - { - return null; - } - - // return the value or the key of the array entry the next key points to - return $get_value ? $array[$keys[$index+1]] : $keys[$index+1]; - } - - /** - * Return the subset of the array defined by the supplied keys. - * - * Returns $default for missing keys, as with Arr::get() - * - * @param array $array the array containing the values - * @param array $keys list of keys (or indices) to return - * @param mixed $default value of missing keys; default null - * - * @return array An array containing the same set of keys provided. - */ - public static function subset(array $array, array $keys, $default = null) - { - $result = array(); - - foreach ($keys as $key) - { - static::set($result, $key, static::get($array, $key, $default)); - } - - return $result; - } -} diff --git a/fuel/core/classes/asset.php b/fuel/core/classes/asset.php deleted file mode 100755 index 47a9b5e..0000000 --- a/fuel/core/classes/asset.php +++ /dev/null @@ -1,254 +0,0 @@ - array('assets/'), - 'img_dir' => 'img/', - 'js_dir' => 'js/', - 'css_dir' => 'css/', - 'folders' => array( - 'css' => array(), - 'js' => array(), - 'img' => array(), - ), - 'url' => '/', - 'add_mtime' => true, - 'indent_level' => 1, - 'indent_with' => "\t", - 'auto_render' => true, - 'fail_silently' => false, - ); - - /** - * This is called automatically by the Autoloader. It loads in the config - * - * @return void - */ - public static function _init() - { - \Config::load('asset', true, false, true); - } - - /** - * Return a specific instance, or the default instance (is created if necessary) - * - * @param string $instance instance name - * @return Asset_Instance - */ - public static function instance($instance = null) - { - if ($instance !== null) - { - if ( ! array_key_exists($instance, static::$_instances)) - { - return false; - } - - return static::$_instances[$instance]; - } - - if (static::$_instance === null) - { - static::$_instance = static::forge(); - } - - return static::$_instance; - } - - /** - * Gets a new instance of the Asset class. - * - * @param string $name instance name - * @param array $config default config overrides - * @return Asset_Instance - */ - public static function forge($name = 'default', array $config = array()) - { - if ($exists = static::instance($name)) - { - \Errorhandler::notice('Asset with this name exists already, cannot be overwritten.'); - return $exists; - } - - static::$_instances[$name] = new \Asset_Instance(array_merge(static::$default_config, \Config::get('asset'), $config)); - - if ($name == 'default') - { - static::$_instance = static::$_instances[$name]; - } - - return static::$_instances[$name]; - } - - /** - * Adds the given path to the front of the asset paths array. It adds paths - * in a way so that asset paths are used First in Last Out. - * - * @param string $path the path to add - * @param string $type optional path type (js, css or img) - * @return void - */ - public static function add_path($path, $type = null) - { - static::instance()->add_path($path, $type); - } - - /** - * Removes the given path from the asset paths array - * - * @param string $path the path to remove - * @return void - */ - public static function remove_path($path, $type = null) - { - static::instance()->remove_path($path, $type); - } - - /** - * Renders the given group. Each tag will be separated by a line break. - * You can optionally tell it to render the files raw. This means that - * all CSS and JS files in the group will be read and the contents included - * in the returning value. - * - * @param mixed $group the group to render - * @param bool $raw whether to return the raw file or not - * @return string the group's output - */ - public static function render($group = null, $raw = false) - { - return static::instance()->render($group, $raw); - } - - // -------------------------------------------------------------------- - - /** - * CSS - * - * Either adds the stylesheet to the group, or returns the CSS tag. - * - * @param mixed $stylesheets The file name, or an array files. - * @param array $attr An array of extra attributes - * @param string $group The asset group name - * @param bool $raw whether to return the raw file or not when group is not set - * @return string - */ - public static function css($stylesheets = array(), $attr = array(), $group = NULL, $raw = false) - { - return static::instance()->assettype('css', $stylesheets, $attr, $group, $raw); - } - - // -------------------------------------------------------------------- - - /** - * JS - * - * Either adds the javascript to the group, or returns the script tag. - * - * @param mixed $scripts The file name, or an array files. - * @param array $attr An array of extra attributes - * @param string $group The asset group name - * @param bool $raw whether to return the raw file or not when group is not set - * @return string - */ - public static function js($scripts = array(), $attr = array(), $group = NULL, $raw = false) - { - return static::instance()->assettype('js', $scripts, $attr, $group, $raw); - } - - // -------------------------------------------------------------------- - - /** - * Img - * - * Either adds the image to the group, or returns the image tag. - * - * @access public - * @param mixed $images The file name, or an array files. - * @param array $attr An array of extra attributes - * @param string $group The asset group name - * @return string - */ - public static function img($images = array(), $attr = array(), $group = NULL) - { - return static::instance()->assettype('img', $images, $attr, $group); - } - - // -------------------------------------------------------------------- - - /** - * Get File - * - * Locates a file in all the asset paths, and return it relative to the docroot - * - * @access public - * @param string $file The filename to locate - * @param string $type The type of asset file - * @param string $folder The sub-folder to look in (optional) - * @return mixed Either the path to the file or false if not found - */ - public static function get_file($file, $type, $folder = '') - { - return static::instance()->get_file($file, $type, $folder); - } - - // -------------------------------------------------------------------- - - /** - * Find File - * - * Locates a file in all the asset paths. - * - * @access public - * @param string $file The filename to locate - * @param string $type The type of asset file to search - * @param string $folder The sub-folder to look in (optional) - * @return mixed Either the path to the file or false if not found - */ - public static function find_file($file, $type, $folder = '') - { - return static::instance()->find_file($file, $type, $folder); - } -} diff --git a/fuel/core/classes/asset/instance.php b/fuel/core/classes/asset/instance.php deleted file mode 100755 index e8f8a11..0000000 --- a/fuel/core/classes/asset/instance.php +++ /dev/null @@ -1,632 +0,0 @@ - array(), - 'js' => array(), - 'img' => array(), - ); - - /** - * @var array the sub-folders to be searched - */ - protected $_path_folders = array( - 'css' => 'css/', - 'js' => 'js/', - 'img' => 'img/', - ); - - /** - * @var array custom type renderers - */ - protected $_renderers = array( - ); - - /** - * @var string the URL to be prepended to all assets - */ - protected $_asset_url = '/'; - - /** - * @var bool whether to append the file mtime to the url - */ - protected $_add_mtime = true; - - /** - * @var array holds the groups of assets - */ - protected $_groups = array(); - - /** - * @var string prefix for generated output to provide proper indentation - */ - protected $_indent = ''; - - /** - * @var bool if true, directly renders the output of no group name is given - */ - protected $_auto_render = true; - - /** - * @var bool if true the 'not found' exception will not be thrown and the asset is ignored. - */ - protected $_fail_silently = false; - - /** - * @var bool if true, will always true to resolve assets. if false, it will only try to resolve if the asset url is relative. - */ - protected $_always_resolve = false; - - /** - * Parse the config and initialize the object instance - * - * @param array $config - */ - public function __construct(Array $config) - { - // look for global search path folders - foreach ($config as $key => $value) - { - if (\Str::ends_with($key, '_dir')) - { - $key = substr($key, 0, -4); - $this->_path_folders[$key] = $this->_unify_path($value); - } - } - - // global search paths - foreach ($config['paths'] as $path) - { - $this->add_path($path); - } - - // per-type search paths - foreach ($config['folders'] as $type => $folders) - { - is_array($folders) or $folders = array($folders); - - foreach ($folders as $path) - { - $this->add_path($path, $type); - } - } - - $this->_add_mtime = (bool) $config['add_mtime']; - $this->_asset_url = $config['url']; - $this->_indent = str_repeat($config['indent_with'], $config['indent_level']); - $this->_auto_render = (bool) $config['auto_render']; - $this->_fail_silently = (bool) $config['fail_silently']; - $this->_always_resolve = (bool) $config['always_resolve']; - } - - /** - * Provide backward compatibility for old type methods - * - * @param $method - * @param $args - * @return mixed - * @throws \ErrorException - */ - public function __call($method, $args) - { - // check if we can render this type - if ( ! isset($this->_path_folders[$method])) - { - throw new \ErrorException('Call to undefined method Fuel\Core\Asset_Instance::'.$method.'()'); - } - - // add the type to the arguments - array_unshift($args, $method); - - // call assettype to store the info - return call_user_func_array(array($this, 'assettype'), $args); - } - - /** - * Adds a new asset type to the list so we can load files of this type - * - * @param string $type new path type - * @param string $path optional default path - * @param Closure $renderer function to custom render this type - * - * @return object current instance - */ - public function add_type($type, $path = null, $renderer = null) - { - isset($this->_asset_paths[$type]) or $this->_asset_paths[$type] = array(); - isset($this->_path_folders[$type]) or $this->_path_folders[$type] = $type.'/'; - - if ( ! is_null($path)) - { - $path = $this->_unify_path($path); - $this->_asset_paths[$type][] = $path; - } - - if ( ! is_null($renderer)) - { - if ( ! $renderer instanceOf \Closure) - { - throw new \OutOfBoundsException('Asset type renderer must be passed as a Closure!'); - } - - $this->_renderers[$type] = $renderer; - } - - return $this; - } - - /** - * Adds the given path to the front of the asset paths array. It adds paths - * in a way so that asset paths are used First in Last Out. - * - * @param string $path the path to add - * @param string $type optional path type (js, css or img) - * @return object current instance - */ - public function add_path($path, $type = null) - { - is_null($type) and $type = $this->_path_folders; - empty($path) and $path = DOCROOT; - - if( is_array($type)) - { - foreach ($type as $key => $folder) - { - is_numeric($key) and $key = $folder; - $folder = $this->_unify_path($path).ltrim($this->_unify_path($folder), DS); - in_array($folder, $this->_asset_paths[$key]) or array_unshift($this->_asset_paths[$key], $folder); - } - } - else - { - // create the asset type if it doesn't exist - if ( ! isset($this->_asset_paths[$type])) - { - $this->_asset_paths[$type] = array(); - $this->_path_folders[$type] = $type.'/'; - } - - $path = $this->_unify_path($path); - in_array($path, $this->_asset_paths[$type]) or array_unshift($this->_asset_paths[$type], $path); - } - return $this; - } - - /** - * Removes the given path from the asset paths array - * - * @param string $path the path to remove - * @param string $type optional path type (js, css or img) - * @return object current instance - */ - public function remove_path($path, $type = null) - { - is_null($type) and $type = $this->_path_folders; - - if( is_array($type)) - { - foreach ($type as $key => $folder) - { - is_numeric($key) and $key = $folder; - $folder = $this->_unify_path($path).ltrim($this->_unify_path($folder), DS); - if (($found = array_search($folder, $this->_asset_paths[$key])) !== false) - { - unset($this->_asset_paths[$key][$found]); - } - } - } - else - { - $path = $this->_unify_path($path); - if (($key = array_search($path, $this->_asset_paths[$type])) !== false) - { - unset($this->_asset_paths[$type][$key]); - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Asset type store. - * - * Either adds the asset to the group, or directly return the tag. - * - * @param string $type The asset type - * @param mixed $files The file name, or an array files. - * @param array $attr An array of extra attributes - * @param string $group The asset group name - * @param boolean $raw whether to return the raw file or not when group is not set (optional) - * @return string|object Rendered asset or current instance when adding to group - */ - public function assettype($type, $files = array(), $attr = array(), $group = null, $raw = false) - { - static $temp_group = 50000000; - - if ($group === null) - { - $render = $this->_auto_render; - $group = $render ? (string) (++$temp_group) : '_default_'; - } - else - { - $render = false; - } - - $this->_parse_assets($type, $files, $attr, $group, $raw); - - if ($render) - { - return $this->render($group, $raw); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Find File - * - * Locates a file in all the asset paths. - * - * @param string $file The filename to locate - * @param string $type The type of asset file to search - * @param string $folder The sub-folder to look in (optional) - * @return mixed Either the path to the file or false if not found - */ - public function find_file($file, $type, $folder = '') - { - foreach ($this->_asset_paths[$type] as $path) - { - empty($folder) or $folder = $this->_unify_path($folder); - - if (is_file($newfile = $path.$folder.$this->_unify_path($file, null, false))) - { - // return the file found, make sure it uses forward slashes on Windows - return str_replace(DS, '/', $newfile); - } - } - - return false; - } - - // -------------------------------------------------------------------- - - /** - * Get File - * - * Locates a file in all the asset paths, and return it relative to the docroot - * - * @param string $file The filename to locate - * @param string $type The type of asset file - * @param string $folder The sub-folder to look in (optional) - * @return mixed Either the path to the file or false if not found - */ - public function get_file($file, $type, $folder = '') - { - if ($file = $this->find_file($file, $type, $folder)) - { - strpos($file, DOCROOT) === 0 and $file = substr($file, strlen(DOCROOT)); - - return $this->_asset_url.$file; - } - - return false; - } - - /** - * Renders the given group. Each tag will be separated by a line break. - * You can optionally tell it to render the files raw. This means that - * all CSS and JS files in the group will be read and the contents included - * in the returning value. - * - * @param mixed $group the group to render - * @param bool $raw whether to return the raw file or not - * @return string the group's output - * @throws \FuelException - */ - public function render($group = null, $raw = false) - { - // determine the group to render - is_null($group) and $group = '_default_'; - - if (is_string($group)) - { - isset($this->_groups[$group]) and $group = $this->_groups[$group]; - } - - is_array($group) or $group = array(); - - // storage for the result - $result = array(); - - // pre-define known types so the order is correct - foreach($this->_path_folders as $type => $unused) - { - $result[$type] = ''; - } - - // loop over the group entries - foreach ($group as $key => $item) - { - // determine file name and inline status - $type = $item['type']; - $filename = $item['file']; - $attr = $item['attr']; - $inline = $item['raw']; - - // make sure we have storage space for this result - if ( ! isset($result[$type])) - { - $result[$type] = ''; - } - - // only do a file search if the asset is not a URI - if ($this->_always_resolve or ! preg_match('|^(\w+:)?//|', $filename)) - { - // and only if the asset is local to the applications base_url - if ($this->_always_resolve or ! preg_match('|^(\w+:)?//|', $this->_asset_url) or strpos($this->_asset_url, \Config::get('base_url')) === 0) - { - if ( ! ($file = $this->find_file($filename, $type))) - { - if ($raw or $inline) - { - $file = $filename; - } - else - { - if ($this->_fail_silently) - { - continue; - } - - throw new \FuelException('Could not find asset: '.$filename); - } - } - else - { - if ($raw or $inline) - { - $file = file_get_contents($file); - $inline = true; - } - else - { - $file = $this->_asset_url.$file.($this->_add_mtime ? '?'.filemtime($file) : ''); - $file = str_replace(str_replace(DS, '/', DOCROOT), '', $file); - } - } - } - else - { - // a remote file and multiple paths? use the first one! - $path = reset($this->_asset_paths[$type]); - $file = $this->_asset_url.$path.$filename; - if ($raw or $inline) - { - $file = file_get_contents($file); - $inline = true; - } - else - { - $file = str_replace(str_replace(DS, '/', DOCROOT), '', $file); - } - } - } - else - { - $file = $filename; - } - - // deal with stray backslashes on Windows - $file = str_replace('\\', '/', $file); - - // call the renderer for this type - if (isset($this->_renderers[$type])) - { - $method = $this->_renderers[$type]; - $result[$type] .= $method($file, $attr, $inline); - } - else - { - $method = 'render_'.$type; - if (method_exists($this, $method)) - { - $result[$type] .= $this->$method($file, $attr, $inline); - } - else - { - throw new \OutOfBoundsException('Asset does not know how to render files of type "'.$type.'"!'); - } - } - } - - // return them in the correct order, as a string - return implode("", $result); - } - - // -------------------------------------------------------------------- - - /** - * CSS tag renderer - * - * @param $file - * @param $attr - * @param $inline - * @return string - */ - protected function render_css($file, $attr, $inline) - { - // storage for the result - $result = ''; - - // make sure we have a type - isset($attr['type']) or $attr['type'] = 'text/css'; - - // render inline. or not - if ($inline) - { - $result = html_tag('style', $attr, PHP_EOL.$file.PHP_EOL).PHP_EOL; - } - else - { - if ( ! isset($attr['rel']) or empty($attr['rel'])) - { - $attr['rel'] = 'stylesheet'; - } - $attr['href'] = $file; - - $result = $this->_indent.html_tag('link', $attr).PHP_EOL; - } - - // return the result - return $result; - } - - // -------------------------------------------------------------------- - - /** - * JS tag renderer - * - * @param $file - * @param $attr - * @param $inline - * @return string - */ - protected function render_js($file, $attr, $inline) - { - // storage for the result - $result = ''; - - // render inline. or not - $attr['type'] = 'text/javascript'; - if ($inline) - { - $result = html_tag('script', $attr, PHP_EOL.$file.PHP_EOL).PHP_EOL; - } - else - { - $attr['src'] = $file; - - $result = $this->_indent.html_tag('script', $attr, '').PHP_EOL; - } - - // return the result - return $result; - } - - // -------------------------------------------------------------------- - - /** - * IMG tag renderer - * - * @param $file - * @param $attr - * @param $inline - * @return string - */ - protected function render_img($file, $attr, $inline) - { - // storage for the result - $result = ''; - - // render the image - $attr['src'] = $file; - $attr['alt'] = isset($attr['alt']) ? $attr['alt'] : ''; - - $result = html_tag('img', $attr ); - - // return the result - return $result; - } - - // -------------------------------------------------------------------- - - /** - * Parse Assets - * - * Pareses the assets and adds them to the group - * - * @param string $type The asset type - * @param mixed $assets The file name, or an array files. - * @param array $attr An array of extra attributes - * @param string $group The asset group name - * @param bool $raw - * @return string - */ - protected function _parse_assets($type, $assets, $attr, $group, $raw = false) - { - if ( ! is_array($assets)) - { - $assets = array($assets); - } - - foreach ($assets as $key => $asset) - { - // Prevent duplicate files in a group. - if (\Arr::get($this->_groups, "$group.$key.file") == $asset) - { - continue; - } - - $this->_groups[$group][] = array( - 'type' => $type, - 'file' => $asset, - 'raw' => $raw, - 'attr' => (array) $attr, - ); - } - } - - // -------------------------------------------------------------------- - - /** - * Unify the path - * - * make sure the directory separator in the path is correct for the - * platform used, is terminated with a directory separator, and all - * relative path references are removed - * - * @param string $path The path - * @param mixed $ds Optional directory separator - * @param boolean $trailing Optional whether to add trailing directory separator - * @return string - */ - protected function _unify_path($path, $ds = null, $trailing = true) - { - $ds === null and $ds = DS; - - return rtrim(str_replace(array('\\', '/'), $ds, $path), $ds).($trailing ? $ds : ''); - } - -} diff --git a/fuel/core/classes/autoloader.php b/fuel/core/classes/autoloader.php deleted file mode 100755 index 801c94b..0000000 --- a/fuel/core/classes/autoloader.php +++ /dev/null @@ -1,404 +0,0 @@ - $path) - { - static::$classes[strtolower($class)] = $path; - } - } - - /** - * Aliases the given class into the given Namespace. By default it will - * add it to the global namespace. - * - * - * Autoloader::alias_to_namespace('Foo\\Bar'); - * Autoloader::alias_to_namespace('Foo\\Bar', '\\Baz'); - * - * - * @param string $class the class name - * @param string $namespace the namespace to alias to - */ - public static function alias_to_namespace($class, $namespace = '') - { - empty($namespace) or $namespace = rtrim($namespace, '\\').'\\'; - $parts = explode('\\', $class); - $root_class = $namespace.array_pop($parts); - class_alias($class, $root_class); - } - - /** - * Register's the autoloader to the SPL autoload stack. - * - * @return void - */ - public static function register() - { - spl_autoload_register('Autoloader::load', true, true); - } - - /** - * Returns the class with namespace prefix when available - * - * @param string $class - * @return bool|string - */ - protected static function find_core_class($class) - { - foreach (static::$core_namespaces as $ns) - { - if (array_key_exists(strtolower($ns_class = $ns.'\\'.$class), static::$classes)) - { - return $ns_class; - } - } - - return false; - } - - /** - * Add a namespace for which classes may be used without the namespace prefix and - * will be auto-aliased to the global namespace. - * Prefixing the classes will overwrite core classes and previously added namespaces. - * - * @param string $namespace - * @param bool $prefix - * @return void - */ - public static function add_core_namespace($namespace, $prefix = true) - { - if ($prefix) - { - array_unshift(static::$core_namespaces, $namespace); - } - else - { - static::$core_namespaces[] = $namespace; - } - } - - /** - * Loads a class. - * - * @param string $class Class to load - * @return bool If it loaded the class - */ - public static function load($class) - { - // deal with funny is_callable('static::classname') side-effect - if (strpos($class, 'static::') === 0) - { - // is called from within the class, so it's already loaded - return true; - } - - $loaded = false; - $class = ltrim($class, '\\'); - $pos = strripos($class, '\\'); - - if (empty(static::$auto_initialize)) - { - static::$auto_initialize = $class; - } - - if (isset(static::$classes[strtolower($class)])) - { - static::init_class($class, str_replace('/', DS, static::$classes[strtolower($class)])); - $loaded = true; - } - elseif ($full_class = static::find_core_class($class)) - { - if ( ! class_exists($full_class, false) and ! interface_exists($full_class, false)) - { - include static::prep_path(static::$classes[strtolower($full_class)]); - } - if ( ! class_exists($class, false)) - { - class_alias($full_class, $class); - } - static::init_class($class); - $loaded = true; - } - else - { - $full_ns = substr($class, 0, $pos); - - if ($full_ns) - { - foreach (static::$namespaces as $ns => $path) - { - $ns = ltrim($ns, '\\'); - if (stripos($full_ns, $ns) === 0) - { - $path .= static::class_to_path( - substr($class, strlen($ns) + 1), - array_key_exists($ns, static::$psr_namespaces) - ); - if (is_file($path)) - { - static::init_class($class, $path); - $loaded = true; - break; - } - } - } - } - - if ( ! $loaded) - { - $path = APPPATH.'classes'.DS.static::class_to_path($class); - - if (is_file($path)) - { - static::init_class($class, $path); - $loaded = true; - } - } - } - - // Prevent failed load from keeping other classes from initializing - if (static::$auto_initialize == $class) - { - static::$auto_initialize = null; - } - - return $loaded; - } - - /** - * Reset the auto initialize state after an autoloader exception. - * This method is called by the exception handler, and is considered an - * internal method! - * - * @access protected - */ - public static function _reset() - { - static::$auto_initialize = null; - } - - /** - * Takes a class name and turns it into a path. It follows the PSR-0 - * standard, except for makes the entire path lower case, unless you - * tell it otherwise. - * - * Note: This does not check if the file exists...just gets the path - * - * @param string $class Class name - * @param bool $psr Whether this is a PSR-0 compliant class - * @return string Path for the class - */ - protected static function class_to_path($class, $psr = false) - { - $file = ''; - if ($last_ns_pos = strripos($class, '\\')) - { - $namespace = substr($class, 0, $last_ns_pos); - $class = substr($class, $last_ns_pos + 1); - $file = str_replace('\\', DS, $namespace).DS; - } - $file .= str_replace('_', DS, $class).'.php'; - - if ( ! $psr) - { - $file = strtolower($file); - } - - return $file; - } - - /** - * Prepares a given path by making sure the directory separators are correct. - * - * @param string $path Path to prepare - * @return string Prepped path - */ - protected static function prep_path($path) - { - return str_replace(array('/', '\\'), DS, $path); - } - - /** - * Checks to see if the given class has a static _init() method. If so then - * it calls it. - * - * @param string $class the class name - * @param string $file the file containing the class to include - * @throws \Exception - * @throws \FuelException - */ - protected static function init_class($class, $file = null) - { - // include the file if needed - if ($file) - { - include $file; - } - - // if the loaded file contains a class... - if (class_exists($class, false)) - { - // call the classes static init if needed - if (static::$auto_initialize === $class) - { - static::$auto_initialize = null; - if (method_exists($class, '_init') and is_callable($class.'::_init')) - { - call_user_func($class.'::_init'); - } - } - } - - // or an interface... - elseif (interface_exists($class, false)) - { - // nothing to do here - } - - // or a trait if you're not on 5.3 anymore... - elseif (function_exists('trait_exists') and trait_exists($class, false)) - { - // nothing to do here - } - - // else something went wrong somewhere, barf and exit now - elseif ($file) - { - throw new \Exception('File "'.\Fuel::clean_path($file).'" does not contain class "'.$class.'"'); - } - else - { - throw new \FuelException('Class "'.$class.'" is not defined'); - } - } -} diff --git a/fuel/core/classes/cache.php b/fuel/core/classes/cache.php deleted file mode 100755 index 05dc079..0000000 --- a/fuel/core/classes/cache.php +++ /dev/null @@ -1,136 +0,0 @@ - $config); - } - - // Overwrite default values with given config - $config = array_merge($defaults, (array) $config); - - if (empty($config['driver'])) - { - throw new \FuelException('No cache driver given or no default cache driver set.'); - } - - $class = '\\Cache_Storage_'.ucfirst($config['driver']); - - // Convert the name to a string when necessary - $identifier = call_user_func($class.'::stringify_identifier', $identifier); - - // Return instance of the requested cache object - return new $class($identifier, $config); - } - - /** - * Front for writing the cache, ensures interchangeability of storage drivers. Actual writing - * is being done by the _set() method which needs to be extended. - * - * @param mixed $identifier The identifier of the cache, can be anything but empty - * @param mixed $contents The content to be cached - * @param bool $expiration The time in seconds until the cache will expire, =< 0 or null means no expiration - * @param array $dependencies Contains the identifiers of caches this one will depend on (not supported by all drivers!) - * @return Cache_Storage_Driver The new Cache object - */ - public static function set($identifier, $contents = null, $expiration = false, $dependencies = array()) - { - $contents = \Fuel::value($contents); - - $cache = static::forge($identifier); - return $cache->set($contents, $expiration, $dependencies); - } - - /** - * Does get() & set() in one call that takes a callback and it's arguments to generate the contents - * - * @param mixed $identifier The identifier of the cache, can be anything but empty - * @param string|array $callback Valid PHP callback - * @param array $args Arguments for the above function/method - * @param int $expiration Cache expiration in seconds - * @param array $dependencies Contains the identifiers of caches this one will depend on (not supported by all drivers!) - * @return mixed - */ - public static function call($identifier, $callback, $args = array(), $expiration = null, $dependencies = array()) - { - $cache = static::forge($identifier); - return $cache->call($callback, $args, $expiration, $dependencies); - } - - /** - * Front for reading the cache, ensures interchangeability of storage drivers. Actual reading - * is being done by the _get() method which needs to be extended. - * - * @param mixed $identifier The identifier of the cache, can be anything but empty - * @param bool $use_expiration - * @return mixed - */ - public static function get($identifier, $use_expiration = true) - { - $cache = static::forge($identifier); - return $cache->get($use_expiration); - } - - /** - * Frontend for deleting item from the cache, interchangeable storage methods. Actual operation - * handled by delete() call on storage driver class - * - * @param mixed $identifier The identifier of the cache, can be anything but empty - */ - public static function delete($identifier) - { - $cache = static::forge($identifier); - return $cache->delete(); - } - - /** - * Flushes the whole cache for a specific storage driver or just a part of it when $section is set - * (might not work with all storage drivers), defaults to the default storage driver - * - * @param null|string - * @param null|string - * @return bool - */ - public static function delete_all($section = null, $driver = null) - { - $cache = static::forge('__NOT_USED__', $driver); - return $cache->delete_all($section); - } -} diff --git a/fuel/core/classes/cache/handler/driver.php b/fuel/core/classes/cache/handler/driver.php deleted file mode 100755 index 1c7f0f0..0000000 --- a/fuel/core/classes/cache/handler/driver.php +++ /dev/null @@ -1,31 +0,0 @@ -config = isset($config['apc']) ? $config['apc'] : array(); - - // make sure we have an id - $this->config['cache_id'] = $this->_validate_config('cache_id', isset($this->config['cache_id']) - ? $this->config['cache_id'] : 'fuel'); - - // check for an expiration override - $this->expiration = $this->_validate_config('expiration', isset($this->config['expiration']) - ? $this->config['expiration'] : $this->expiration); - - // do we have the PHP APC extension available - if ( ! function_exists('apc_store') ) - { - throw new \FuelException('Your PHP installation doesn\'t have APC loaded.'); - } - } - - // --------------------------------------------------------------------- - - /** - * Check if other caches or files have been changed since cache creation - * - * @param array - * @return bool - */ - public function check_dependencies(array $dependencies) - { - foreach($dependencies as $dep) - { - // get the section name and identifier - $sections = explode('.', $dep); - if (count($sections) > 1) - { - $identifier = array_pop($sections); - $sections = '.'.implode('.', $sections); - - } - else - { - $identifier = $dep; - $sections = ''; - } - - // get the cache index - $index = apc_fetch($this->config['cache_id'].$sections); - - // get the key from the index - $key = isset($index[$identifier][0]) ? $index[$identifier] : false; - - // key found and newer? - if ($key === false or $key[1] > $this->created) - { - return false; - } - } - return true; - } - - /** - * Delete Cache - */ - public function delete() - { - // get the APC key for the cache identifier - $key = $this->_get_key(true); - - // delete the key from the apc store - $key and apc_delete($key); - - $this->reset(); - } - - /** - * Purge all caches - * - * @param string $section limit purge to subsection - * @return bool - */ - public function delete_all($section) - { - // determine the section index name - $section = $this->config['cache_id'].(empty($section) ? '' : '.'.$section); - - // get the directory index - $index = apc_fetch($this->config['cache_id'].'__DIR__'); - - if (is_array($index)) - { - // limit the delete if we have a valid section - if ( ! empty($section)) - { - $dirs = in_array($section, $index) ? array($section) : array(); - } - else - { - $dirs = $index; - } - - // loop through the indexes, delete all stored keys, then delete the indexes - foreach ($dirs as $dir) - { - $list = apc_fetch($dir); - foreach ($list as $item) - { - apc_delete($item[0]); - } - apc_delete($dir); - } - - // update the directory index - $index = array_diff($index, $dirs); - apc_store($this->config['cache_id'].'__DIR__', $index); - } - } - - // --------------------------------------------------------------------- - - /** - * Prepend the cache properties - * - * @return string - */ - protected function prep_contents() - { - $properties = array( - 'created' => $this->created, - 'expiration' => $this->expiration, - 'dependencies' => $this->dependencies, - 'content_handler' => $this->content_handler, - ); - $properties = '{{'.static::PROPS_TAG.'}}'.json_encode($properties).'{{/'.static::PROPS_TAG.'}}'; - - return $properties.$this->contents; - } - - /** - * Remove the prepended cache properties and save them in class properties - * - * @param string - * @throws UnexpectedValueException - */ - protected function unprep_contents($payload) - { - $properties_end = strpos($payload, '{{/'.static::PROPS_TAG.'}}'); - if ($properties_end === FALSE) - { - throw new \UnexpectedValueException('Cache has bad formatting'); - } - - $this->contents = substr($payload, $properties_end + strlen('{{/'.static::PROPS_TAG.'}}')); - $props = substr(substr($payload, 0, $properties_end), strlen('{{'.static::PROPS_TAG.'}}')); - $props = json_decode($props, true); - if ($props === NULL) - { - throw new \UnexpectedValueException('Cache properties retrieval failed'); - } - - $this->created = $props['created']; - $this->expiration = is_null($props['expiration']) ? null : (int) ($props['expiration'] - time()); - $this->dependencies = $props['dependencies']; - $this->content_handler = $props['content_handler']; - } - - /** - * Save a cache, this does the generic pre-processing - * - * @return bool success - */ - protected function _set() - { - // get the apc key for the cache identifier - $key = $this->_get_key(); - - $payload = $this->prep_contents(); - - // adjust the expiration, apc uses a TTL instead of a timestamp - $expiration = is_null($this->expiration) ? 0 : (int) ($this->expiration - $this->created); - - // write it to the apc store - if (apc_store($key, $payload, $expiration) === false) - { - throw new \RuntimeException('APC returned failed to write. Check your configuration.'); - } - - // update the index - $this->_update_index($key); - - return true; - } - - /** - * Load a cache, this does the generic post-processing - * - * @return bool success - */ - protected function _get() - { - // get the apc key for the cache identifier - $key = $this->_get_key(); - - // fetch the cached data from the apc store - $payload = apc_fetch($key); - - try - { - $this->unprep_contents($payload); - } - catch (\UnexpectedValueException $e) - { - return false; - } - - return true; - } - - /** - * validate a driver config value - * - * @param string name of the config variable to validate - * @param mixed value - * @return mixed - */ - private function _validate_config($name, $value) - { - switch ($name) - { - case 'cache_id': - if (empty($value) or ! is_string($value)) - { - $value = 'fuel'; - } - break; - - case 'expiration': - if (empty($value) or ! is_numeric($value)) - { - $value = null; - } - break; - - default: - break; - } - - return $value; - } - - /** - * get's the apc key belonging to the cache identifier - * - * @param bool if true, remove the key retrieved from the index - * @return string - */ - protected function _get_key($remove = false) - { - // get the current index information - list($identifier, $sections, $index) = $this->_get_index(); - - // get the key from the index - $key = isset($index[$identifier][0]) ? $index[$identifier][0] : false; - - if ($remove === true) - { - if ( $key !== false ) - { - unset($index[$identifier]); - apc_store($this->config['cache_id'].$sections, $index); - } - } - else - { - // create a new key if needed - $key === false and $key = $this->_new_key(); - } - - return $key; - } - - /** - * generate a new unique key for the current identifier - * - * @return string - */ - protected function _new_key() - { - $key = ''; - while (strlen($key) < 32) - { - $key .= mt_rand(0, mt_getrandmax()); - } - return md5($this->config['cache_id'].'_'.uniqid($key, TRUE)); - } - - /** - * Get the section index - * - * @return array containing the identifier, the sections, and the section index - */ - protected function _get_index() - { - // get the section name and identifier - $sections = explode('.', $this->identifier); - if (count($sections) > 1) - { - $identifier = array_pop($sections); - $sections = '.'.implode('.', $sections); - } - else - { - $identifier = $this->identifier; - $sections = ''; - } - - // get the cache index and return it - return array($identifier, $sections, apc_fetch($this->config['cache_id'].$sections)); - } - - /** - * Update the section index - * - * @param string cache key - */ - protected function _update_index($key) - { - // get the current index information - list($identifier, $sections, $index) = $this->_get_index(); - - // store the key in the index and write the index back - $index[$identifier] = array($key, $this->created); - apc_store($this->config['cache_id'].$sections, array_merge($index, array($identifier => array($key, $this->created))), 0); - - // get the directory index - $index = apc_fetch($this->config['cache_id'].'__DIR__'); - - if (is_array($index)) - { - if (!in_array($this->config['cache_id'].$sections, $index)) - { - $index[] = $this->config['cache_id'].$sections; - } - } - else - { - $index = array($this->config['cache_id'].$sections); - } - - // update the directory index - apc_store($this->config['cache_id'].'__DIR__', $index, 0); - } -} diff --git a/fuel/core/classes/cache/storage/driver.php b/fuel/core/classes/cache/storage/driver.php deleted file mode 100755 index d4e6f2b..0000000 --- a/fuel/core/classes/cache/storage/driver.php +++ /dev/null @@ -1,426 +0,0 @@ -identifier = $identifier; - - // fetch options from config and set them - $this->expiration = array_key_exists('expiration', $config) ? $config['expiration'] : \Config::get('cache.expiration', null); - $this->dependencies = array_key_exists('dependencies', $config) ? $config['dependencies'] : array(); - $this->content_handler = array_key_exists('content_handler', $config) ? new $config['content_handler']() : null; - $this->driver = array_key_exists('driver', $config) ? $config['driver'] : 'file'; - } - - /** - * Allows for default getting and setting - * - * @param string - * @param array - * @return void|mixed - */ - public function __call($method, $args = array()) - { - // Allow getting any properties set in static::$_gettable - if (substr($method, 0, 3) == 'get') - { - $name = substr($method, 4); - if (in_array($name, static::$_gettable)) - { - return $this->{$name}; - } - else - { - throw new \BadMethodCallException('This property doesn\'t exist or can\'t be read.'); - } - } - // Allow setting any properties set in static::$_settable - elseif (substr($method, 0, 3) == 'set') - { - $name = substr($method, 4); - if (in_array($name, static::$_settable)) - { - $this->{$name} = @$args[0]; - } - else - { - throw new \BadMethodCallException('This property doesn\'t exist or can\'t be set.'); - } - return $this; - } - else - { - throw new \BadMethodCallException('Illegal method call: ' . $method); - } - } - - /** - * Converts the identifier to a string when necessary: - * A int is just converted to a string, all others are serialized and then md5'd - * - * @param mixed $identifier - * @return string - * @throws \FuelException - */ - public static function stringify_identifier($identifier) - { - // Identifier may not be empty, but can be false or 0 - if ($identifier === '' || $identifier === null) - { - throw new \FuelException('The identifier cannot be empty, must contain a value of any kind other than null or an empty string.'); - } - - // In case of string or int just return it as a string - if (is_string($identifier) || is_int($identifier)) - { - // cleanup to only allow alphanumeric chars, dashes, dots & underscores - if (preg_match('/^([a-z0-9_\.\-]*)$/iuD', $identifier) === 0) - { - throw new \FuelException('Cache identifier can only contain alphanumeric characters, underscores, dashes & dots.'); - } - - return (string) $identifier; - } - // In case of array, bool or object return the md5 of the $identifier's serialization - else - { - return '_hashes.'.md5(serialize($identifier)); - } - } - - /** - * Resets all properties except for the identifier, should be run by default when a delete() is triggered - */ - public function reset() - { - $this->contents = null; - $this->created = null; - $this->expiration = null; - $this->dependencies = array(); - $this->content_handler = null; - $this->handler_object = null; - } - - /** - * Front for writing the cache, ensures interchangeability of storage engines. Actual writing - * is being done by the _set() method which needs to be extended. - * - * @param mixed $contents The content to be cached - * @param bool $expiration The time in seconds until the cache will expire, =< 0 or null means no expiration - * @param array $dependencies array of names on which this cache depends for - */ - final public function set($contents = null, $expiration = false, $dependencies = array()) - { - $contents = \Fuel::value($contents); - // save the current expiration - $current_expiration = $this->expiration; - - // Use either the given value or the class property - if ( ! is_null($contents)) - { - $this->set_contents($contents); - } - $this->expiration = ($expiration !== false) ? $expiration : $this->expiration; - $this->dependencies = ( ! empty($dependencies)) ? $dependencies : $this->dependencies; - - $this->created = time(); - - // Create expiration timestamp when other then null - if ( ! is_null($this->expiration)) - { - if ( ! is_numeric($this->expiration)) - { - throw new \InvalidArgumentException('Expiration must be a valid number.'); - } - $this->expiration = $this->created + intval($this->expiration); - } - - // Convert dependency identifiers to string when set - $this->dependencies = ( ! is_array($this->dependencies)) ? array($this->dependencies) : $this->dependencies; - if ( ! empty( $this->dependencies ) ) - { - foreach($this->dependencies as $key => $id) - { - $this->dependencies[$key] = $this->stringify_identifier($id); - } - } - - // Turn everything over to the storage specific method - $this->_set(); - - // restore the expiration - $this->expiration = $current_expiration; - } - - /** - * Front for reading the cache, ensures interchangeability of storage engines. Actual reading - * is being done by the _get() method which needs to be extended. - * - * @param bool $use_expiration - * @return Cache_Storage_Driver - * @throws \CacheExpiredException - * @throws \CacheNotFoundException - */ - final public function get($use_expiration = true) - { - if ( ! $this->_get()) - { - throw new \CacheNotFoundException('not found'); - } - - if ($use_expiration) - { - if ( ! is_null($this->expiration) and $this->expiration < 0) - { - $this->delete(); - throw new \CacheExpiredException('expired'); - } - - // Check dependencies and handle as expired on failure - if ( ! $this->check_dependencies($this->dependencies)) - { - $this->delete(); - throw new \CacheExpiredException('expired'); - } - } - - return $this->get_contents(); - } - - /** - * Does get() & set() in one call that takes a callback and it's arguments to generate the contents - * - * @param string|array $callback Valid PHP callback - * @param array $args Arguments for the above function/method - * @param int|null $expiration Cache expiration in seconds - * @param array $dependencies Contains the identifiers of caches this one will depend on - * @return mixed - */ - final public function call($callback, $args = array(), $expiration = null, $dependencies = array()) - { - try - { - $this->get(); - } - catch (\CacheNotFoundException $e) - { - // Create the contents - $contents = call_fuel_func_array($callback, $args); - - $this->set($contents, $expiration, $dependencies); - } - - return $this->get_contents(); - } - - /** - * Set the contents with optional handler instead of the default - * - * @param mixed - * @param string - * @return Cache_Storage_Driver - */ - public function set_contents($contents, $handler = NULL) - { - $this->contents = $contents; - $this->set_content_handler($handler); - $this->contents = $this->handle_writing($contents); - return $this; - } - - /** - * Fetches contents - * - * @return mixed - */ - public function get_contents() - { - return $this->handle_reading($this->contents); - } - - /** - * Decides a content handler that makes it possible to write non-strings to a file - * - * @param string - * @return Cache_Storage_Driver - */ - protected function set_content_handler($handler) - { - $this->handler_object = null; - $this->content_handler = (string) $handler; - return $this; - } - - /** - * Gets a specific content handler - * - * @param string - * @return Cache_Handler_Driver - */ - public function get_content_handler($handler = null) - { - if ( ! empty($this->handler_object)) - { - return $this->handler_object; - } - - // When not yet set, use $handler or detect the preferred handler (string = string, otherwise serialize) - if (empty($this->content_handler) && empty($handler)) - { - if ( ! empty($handler)) - { - $this->content_handler = $handler; - } - if (is_string($this->contents)) - { - $this->content_handler = \Config::get('cache.string_handler', 'string'); - } - else - { - $type = is_object($this->contents) ? get_class($this->contents) : gettype($this->contents); - $this->content_handler = \Config::get('cache.'.$type.'_handler', 'serialized'); - } - } - - $class = '\\Cache_Handler_'.ucfirst($this->content_handler); - $this->handler_object = new $class(); - - return $this->handler_object; - } - - /** - * Converts the contents the cachable format - * - * @param $contents - * @return string - */ - protected function handle_writing($contents) - { - return $this->get_content_handler()->writable($contents); - } - - /** - * Converts the cachable format to the original value - * - * @param $contents - * @return mixed - */ - protected function handle_reading($contents) - { - return $this->get_content_handler()->readable($contents); - } -} diff --git a/fuel/core/classes/cache/storage/file.php b/fuel/core/classes/cache/storage/file.php deleted file mode 100755 index bf744bd..0000000 --- a/fuel/core/classes/cache/storage/file.php +++ /dev/null @@ -1,389 +0,0 @@ -config = isset($config['file']) ? $config['file'] : array(); - - // check for an expiration override - $this->expiration = $this->_validate_config('expiration', isset($this->config['expiration']) - ? $this->config['expiration'] : $this->expiration); - - // determine the file cache path - static::$path = !empty($this->config['path']) - ? $this->config['path'] : \Config::get('cache_dir', APPPATH.'cache'.DS); - - if ( ! is_dir(static::$path) || ! is_writable(static::$path)) - { - throw new \FuelException('Cache directory does not exist or is not writable.'); - } - } - - /** - * Check if other caches or files have been changed since cache creation - * - * @param array - * @return bool - */ - public function check_dependencies(array $dependencies) - { - foreach($dependencies as $dep) - { - if (is_file($file = static::$path.str_replace('.', DS, $dep).'.cache')) - { - $filemtime = filemtime($file); - if ($filemtime === false || $filemtime > $this->created) - { - return false; - } - } - elseif (is_file($dep)) - { - $filemtime = filemtime($dep); - if ($filemtime === false || $filemtime > $this->created) - { - return false; - } - } - else - { - return false; - } - } - - return true; - } - - /** - * Delete Cache - */ - public function delete() - { - if (is_file($file = static::$path.$this->identifier_to_path($this->identifier).'.cache')) - { - unlink($file); - $this->reset(); - } - } - - /** - * Purge all caches - * - * @param string $section limit purge to subsection - * @return bool - */ - public function delete_all($section) - { - // get the cache root path and prep the requested section - $path = rtrim(static::$path, '\\/').DS; - $section = $section === null ? '' : static::identifier_to_path($section).DS; - - // if the path does not exist, bail out immediately - if ( ! is_dir($path.$section)) - { - return true; - } - - // get all files in this section - $files = \File::read_dir($path.$section, -1, array('\.cache$' => 'file')); - - // closure to recusively delete the files - $delete = function($folder, $files) use(&$delete, $path) - { - $folder = rtrim($folder, '\\/').DS; - - foreach ($files as $dir => $file) - { - if (is_numeric($dir)) - { - if ( ! $result = \File::delete($folder.$file)) - { - return $result; - } - } - else - { - if ( ! $result = ($delete($folder.$dir, $file))) - { - return $result; - } - } - } - - // if we're processing a sub directory - if ($folder != $path) - { - // remove the folder if no more files are left - $files = \File::read_dir($folder); - empty($files) and rmdir($folder); - } - - return true; - }; - - return $delete($path.$section, $files); - } - - // --------------------------------------------------------------------- - - /** - * Translates a given identifier to a valid path - * - * @param string - * @return string - */ - protected function identifier_to_path($identifier) - { - // replace dots with dashes - $identifier = str_replace('.', DS, $identifier); - - return $identifier; - } - - /** - * Prepend the cache properties - * - * @return string - */ - protected function prep_contents() - { - $properties = array( - 'created' => $this->created, - 'expiration' => $this->expiration, - 'dependencies' => $this->dependencies, - 'content_handler' => $this->content_handler, - ); - $properties = '{{'.self::PROPS_TAG.'}}'.json_encode($properties).'{{/'.self::PROPS_TAG.'}}'; - - return $properties.$this->contents; - } - - /** - * Remove the prepended cache properties and save them in class properties - * - * @param string - * @throws \UnexpectedValueException - */ - protected function unprep_contents($payload) - { - $properties_end = strpos($payload, '{{/'.self::PROPS_TAG.'}}'); - if ($properties_end === false) - { - throw new \UnexpectedValueException('Cache has bad formatting'); - } - - $this->contents = substr($payload, $properties_end + strlen('{{/'.self::PROPS_TAG.'}}')); - $props = substr(substr($payload, 0, $properties_end), strlen('{{'.self::PROPS_TAG.'}}')); - $props = json_decode($props, true); - if ($props === null) - { - throw new \UnexpectedValueException('Cache properties retrieval failed'); - } - - $this->created = $props['created']; - $this->expiration = is_null($props['expiration']) ? null : (int) ($props['expiration'] - time()); - $this->dependencies = $props['dependencies']; - $this->content_handler = $props['content_handler']; - } - - /** - * Save a cache, this does the generic pre-processing - * - * @return bool success - */ - protected function _set() - { - $payload = $this->prep_contents(); - $id_path = $this->identifier_to_path($this->identifier); - - // create directory if necessary - $subdirs = explode(DS, $id_path); - if (count($subdirs) > 1) - { - array_pop($subdirs); - - // check if specified subdir exists - if ( ! @is_dir(static::$path.implode(DS, $subdirs))) - { - // recursively create the directory. we can't use mkdir permissions or recursive - // due to the fact that mkdir is restricted by the current users umask - $basepath = rtrim(static::$path, DS); - $chmod = \Config::get('file.chmod.folders', 0775); - foreach ($subdirs as $dir) - { - $basepath .= DS.$dir; - if ( ! is_dir($basepath)) - { - try - { - if ( ! mkdir($basepath)) - { - return false; - } - chmod($basepath, $chmod); - } - catch (\PHPErrorException $e) - { - return false; - } - } - } - } - } - - // write the cache - $file = static::$path.$id_path.'.cache'; - - $handle = fopen($file, 'c'); - - if ( ! $handle) - { - return false; - } - - // wait for a lock - while ( ! flock($handle, LOCK_EX)); - - // truncate the file - ftruncate($handle, 0); - - // write the cache data - fwrite($handle, $payload); - - // flush any pending output - fflush($handle); - - //release the lock - flock($handle, LOCK_UN); - - // close the file - fclose($handle); - - // set the correct rights on the file - chmod($file, \Config::get('file.chmod.files', 0666)); - - return true; - } - - /** - * Load a cache, this does the generic post-processing - * - * @return bool success - */ - protected function _get() - { - $payload = false; - - $id_path = $this->identifier_to_path( $this->identifier ); - $file = static::$path.$id_path.'.cache'; - - // normalize the file - $file = realpath($file); - - // make sure it exists - if (is_file($file)) - { - $handle = fopen($file, 'r'); - if ($handle) - { - // wait for a lock - while( ! flock($handle, LOCK_SH)); - - // read the cache data - $payload = file_get_contents($file); - - //release the lock - flock($handle, LOCK_UN); - - // close the file - fclose($handle); - - } - } - - try - { - $this->unprep_contents($payload); - } - catch (\UnexpectedValueException $e) - { - return false; - } - - return true; - } - - /** - * validate a driver config value - * - * @param string $name name of the config variable to validate - * @param mixed $value - * @return mixed - */ - protected function _validate_config($name, $value) - { - switch ($name) - { - case 'cache_id': - if (empty($value) or ! is_string($value)) - { - $value = 'fuel'; - } - break; - - case 'expiration': - if (empty($value) or ! is_numeric($value)) - { - $value = null; - } - break; - } - - return $value; - } -} diff --git a/fuel/core/classes/cache/storage/memcached.php b/fuel/core/classes/cache/storage/memcached.php deleted file mode 100755 index 1ca3495..0000000 --- a/fuel/core/classes/cache/storage/memcached.php +++ /dev/null @@ -1,454 +0,0 @@ -config = isset($config['memcached']) ? $config['memcached'] : array(); - - // make sure we have a memcache id - $this->config['cache_id'] = $this->_validate_config('cache_id', isset($this->config['cache_id']) - ? $this->config['cache_id'] : 'fuel'); - - // check for an expiration override - $this->expiration = $this->_validate_config('expiration', isset($this->config['expiration']) - ? $this->config['expiration'] : $this->expiration); - - if (static::$memcached === false) - { - // make sure we have memcached servers configured - $this->config['servers'] = $this->_validate_config('servers', $this->config['servers']); - - // do we have the PHP memcached extension available - if ( ! class_exists('Memcached') ) - { - throw new \FuelException('Memcached cache are configured, but your PHP installation doesn\'t have the Memcached extension loaded.'); - } - - // instantiate the memcached object - static::$memcached = new \Memcached(); - - // add the configured servers - static::$memcached->addServers($this->config['servers']); - - // check if we can connect to all the server(s) - $added = static::$memcached->getStats(); - foreach ($this->config['servers'] as $server) - { - $server = $server['host'].':'.$server['port']; - if ( ! isset($added[$server]) or $added[$server]['pid'] == -1) - { - throw new \FuelException('Memcached cache is configured, but there is no connection possible. Check your configuration.'); - } - } - } - } - - // --------------------------------------------------------------------- - - /** - * Check if other caches or files have been changed since cache creation - * - * @param array - * @return bool - */ - public function check_dependencies(array $dependencies) - { - foreach($dependencies as $dep) - { - // get the section name and identifier - $sections = explode('.', $dep); - if (count($sections) > 1) - { - $identifier = array_pop($sections); - $sections = '.'.implode('.', $sections); - - } - else - { - $identifier = $dep; - $sections = ''; - } - - // get the cache index - $index = static::$memcached->get($this->config['cache_id'].$sections); - - // get the key from the index - $key = isset($index[$identifier][0]) ? $index[$identifier] : false; - - // key found and newer? - if ($key === false or $key[1] > $this->created) - { - return false; - } - } - - return true; - } - - /** - * Delete Cache - */ - public function delete() - { - // get the memcached key for the cache identifier - $key = $this->_get_key(true); - - // delete the key from the memcached server - if ($key and static::$memcached->delete($key) === false) - { - if (static::$memcached->getResultCode() !== \Memcached::RES_NOTFOUND) - { - throw new \FuelException('Memcached returned error code "'.static::$memcached->getResultCode().'" on delete. Check your configuration.'); - } - } - - $this->reset(); - } - - /** - * Purge all caches - * - * @param string $section limit purge to subsection - * @return bool - */ - public function delete_all($section) - { - // determine the section index name - $section = $this->config['cache_id'].(empty($section) ? '' : '.'.$section); - - // get the directory index - $index = static::$memcached->get($this->config['cache_id'].'__DIR__'); - - if (is_array($index)) - { - // limit the delete if we have a valid section - if ( ! empty($section)) - { - $dirs = in_array($section, $index) ? array($section) : array(); - } - else - { - $dirs = $index; - } - - // loop through the indexes, delete all stored keys, then delete the indexes - foreach ($dirs as $dir) - { - $list = static::$memcached->get($dir); - foreach ($list as $item) - { - static::$memcached->delete($item[0]); - } - static::$memcached->delete($dir); - } - - // update the directory index - $index = array_diff($index, $dirs); - static::$memcached->set($this->config['cache_id'].'__DIR__', $index); - } - } - - // --------------------------------------------------------------------- - - /** - * Prepend the cache properties - * - * @return string - */ - protected function prep_contents() - { - $properties = array( - 'created' => $this->created, - 'expiration' => $this->expiration, - 'dependencies' => $this->dependencies, - 'content_handler' => $this->content_handler, - ); - $properties = '{{'.static::PROPS_TAG.'}}'.json_encode($properties).'{{/'.static::PROPS_TAG.'}}'; - - return $properties.$this->contents; - } - - /** - * Remove the prepended cache properties and save them in class properties - * - * @param string - * @throws \UnexpectedValueException - */ - protected function unprep_contents($payload) - { - $properties_end = strpos($payload, '{{/'.static::PROPS_TAG.'}}'); - if ($properties_end === FALSE) - { - throw new \UnexpectedValueException('Cache has bad formatting'); - } - - $this->contents = substr($payload, $properties_end + strlen('{{/'.static::PROPS_TAG.'}}')); - $props = substr(substr($payload, 0, $properties_end), strlen('{{'.static::PROPS_TAG.'}}')); - $props = json_decode($props, true); - if ($props === NULL) - { - throw new \UnexpectedValueException('Cache properties retrieval failed'); - } - - $this->created = $props['created']; - $this->expiration = is_null($props['expiration']) ? null : (int) ($props['expiration'] - time()); - $this->dependencies = $props['dependencies']; - $this->content_handler = $props['content_handler']; - } - - /** - * Save a cache, this does the generic pre-processing - * - * @return bool success - * @throws \FuelException - */ - protected function _set() - { - // get the memcached key for the cache identifier - $key = $this->_get_key(); - - $payload = $this->prep_contents(); - - // calculate relative expiration time (eg. 60s) - $expiration = !is_null($this->expiration) ? $this->expiration - time() : 0; - - // if expiration value is less than 30 days, use relative value, otherwise use unix timestamp: - $expiration = $expiration <= 2592000 ? (int) $expiration : (int) $this->expiration; - - // write it to the memcached server - if (static::$memcached->set($key, $payload, $expiration) === false) - { - throw new \FuelException('Memcached returned error code "'.static::$memcached->getResultCode().'" on write. Check your configuration.'); - } - - // update the index - $this->_update_index($key); - - return true; - } - - /** - * Load a cache, this does the generic post-processing - * - * @return bool success - */ - protected function _get() - { - // get the memcached key for the cache identifier - $key = $this->_get_key(); - - // fetch the cached data from the Memcached server - $payload = static::$memcached->get($key); - - try - { - $this->unprep_contents($payload); - } - catch (\UnexpectedValueException $e) - { - return false; - } - - return true; - } - - /** - * validate a driver config value - * - * @param string $name name of the config variable to validate - * @param mixed $value - * @return mixed - * @throws \FuelException - */ - protected function _validate_config($name, $value) - { - switch ($name) - { - case 'cache_id': - if (empty($value) or ! is_string($value)) - { - $value = 'fuel'; - } - break; - - case 'expiration': - if (empty($value) or ! is_numeric($value)) - { - $value = null; - } - break; - - case 'servers': - // do we have a servers config - if ( empty($value) OR ! is_array($value)) - { - $value = array('default' => array('host' => '127.0.0.1', 'port' => '11211')); - } - - // validate the servers - foreach ($value as $key => $server) - { - // do we have a host? - if ( ! isset($server['host']) OR ! is_string($server['host'])) - { - throw new \FuelException('Invalid Memcached server definition in the cache configuration.'); - } - // do we have a port number? - if ( ! isset($server['port']) OR ! is_numeric($server['port']) OR $server['port'] < 1025 OR $server['port'] > 65535) - { - throw new \FuelException('Invalid Memcached server definition in the cache configuration.'); - } - // do we have a relative server weight? - if ( ! isset($server['weight']) OR ! is_numeric($server['weight']) OR $server['weight'] < 0) - { - // set a default - $value[$key]['weight'] = 0; - } - } - break; - - default: - break; - } - - return $value; - } - - /** - * Get's the memcached key belonging to the cache identifier - * - * @param bool $remove if true, remove the key retrieved from the index - * @return string - */ - protected function _get_key($remove = false) - { - // get the current index information - list($identifier, $sections, $index) = $this->_get_index(); - - // get the key from the index - $key = isset($index[$identifier][0]) ? $index[$identifier][0] : false; - - if ($remove === true) - { - if ( $key !== false ) - { - unset($index[$identifier]); - static::$memcached->set($this->config['cache_id'].$sections, $index); - } - } - else - { - // create a new key if needed - $key === false and $key = $this->_new_key(); - } - return $key; - } - - /** - * Generate a new unique key for the current identifier - * - * @return string - */ - protected function _new_key() - { - $key = ''; - while (strlen($key) < 32) - { - $key .= mt_rand(0, mt_getrandmax()); - } - return md5($this->config['cache_id'].'_'.uniqid($key, TRUE)); - } - - /** - * Get the section index - * - * @return array containing the identifier, the sections, and the section index - */ - protected function _get_index() - { - // get the section name and identifier - $sections = explode('.', $this->identifier); - if (count($sections) > 1) - { - $identifier = array_pop($sections); - $sections = '.'.implode('.', $sections); - - } - else - { - $identifier = $this->identifier; - $sections = ''; - } - - // get the cache index and return it - return array($identifier, $sections, static::$memcached->get($this->config['cache_id'].$sections)); - } - - /** - * Update the section index - * - * @param string cache key - */ - protected function _update_index($key) - { - // get the current index information - list($identifier, $sections, $index) = $this->_get_index(); - - // create a new index and store the key - is_array($index) or $index = array(); - - // store the key in the index and write the index back - $index[$identifier] = array($key, $this->created); - static::$memcached->set($this->config['cache_id'].$sections, $index, 0); - - // get the directory index - $index = static::$memcached->get($this->config['cache_id'].'__DIR__'); - - if (is_array($index)) - { - if (!in_array($this->config['cache_id'].$sections, $index)) - { - $index[] = $this->config['cache_id'].$sections; - } - } - else - { - $index = array($this->config['cache_id'].$sections); - } - - // update the directory index - static::$memcached->set($this->config['cache_id'].'__DIR__', $index, 0); - } -} diff --git a/fuel/core/classes/cache/storage/redis.php b/fuel/core/classes/cache/storage/redis.php deleted file mode 100755 index c397bd4..0000000 --- a/fuel/core/classes/cache/storage/redis.php +++ /dev/null @@ -1,509 +0,0 @@ -config = isset($config['redis']) ? $config['redis'] : array(); - - // make sure we have a redis id - $this->config['cache_id'] = $this->_validate_config('cache_id', isset($this->config['cache_id']) - ? $this->config['cache_id'] : 'fuel'); - - // check for an expiration override - $this->expiration = $this->_validate_config('expiration', isset($this->config['expiration']) - ? $this->config['expiration'] : $this->expiration); - - // make sure we have a redis database configured - $this->config['database'] = $this->_validate_config('database', isset($this->config['database']) - ? $this->config['database'] : 'default'); - - if (static::$redis === false) - { - // get the redis database instance - try - { - static::$redis = \Redis_Db::instance($this->config['database']); - } - catch (\Exception $e) - { - throw new \FuelException('Can not connect to the Redis engine. The error message says "'.$e->getMessage().'".'); - } - - // get the redis version - preg_match('/redis_version:(.*?)\n/', static::$redis->info(), $info); - if (version_compare(trim($info[1]), '1.2') < 0) - { - throw new \FuelException('Version 1.2 or higher of the Redis NoSQL engine is required to use the redis cache driver.'); - } - } - } - - // --------------------------------------------------------------------- - - /** - * Check if other caches or files have been changed since cache creation - * - * @param array - * @return bool - */ - public function check_dependencies(array $dependencies) - { - foreach($dependencies as $dep) - { - // get the section name and identifier - $sections = explode('.', $dep); - if (count($sections) > 1) - { - $identifier = array_pop($sections); - $sections = '.'.implode('.', $sections); - - } - else - { - $identifier = $dep; - $sections = ''; - } - - // get the cache index - $index = static::$redis->get($this->config['cache_id'].':index:'.$sections); - is_null($index) or $index = $this->_unserialize($index); - - // get the key from the index - $key = isset($index[$identifier][0]) ? $index[$identifier] : false; - - // key found and newer? - if ($key === false or $key[1] > $this->created) - { - return false; - } - } - return true; - } - - /** - * Delete Cache - */ - public function delete() - { - // get the key for the cache identifier - $key = $this->_get_key(true); - - // delete the key from the redis server - if ($key and static::$redis->del($key) === false) - { - // do something here? - } - - $this->reset(); - } - - /** - * Purge all caches - * - * @param string $section limit purge to subsection - * @return bool - */ - public function delete_all($section) - { - // determine the section index name - $section = empty($section) ? '' : '.'.$section; - - // get the directory index - $index = static::$redis->get($this->config['cache_id'].':dir:'); - is_null($index) or $index = $this->_unserialize($index); - - if (is_array($index)) - { - if (!empty($section)) - { - // limit the delete if we have a valid section - $dirs = array(); - foreach ($index as $entry) - { - if ($entry == $section or strpos($entry, $section.'.') === 0) - { - $dirs[] = $entry; - } - } - } - else - { - // else delete the entire contents of the cache - $dirs = $index; - } - - // loop through the selected indexes - foreach ($dirs as $dir) - { - // get the stored cache entries for this index - $list = static::$redis->get($this->config['cache_id'].':index:'.$dir); - if (is_null($list)) - { - $list = array(); - } - else - { - $list = $this->_unserialize($list); - } - - // delete all stored keys - foreach($list as $item) - { - static::$redis->del($item[0]); - } - - // and delete the index itself - static::$redis->del($this->config['cache_id'].':index:'.$dir); - } - - // update the directory index - static::$redis->set($this->config['cache_id'].':dir:', $this->_serialize(array_diff($index, $dirs))); - } - } - - // --------------------------------------------------------------------- - - /** - * Translates a given identifier to a valid redis key - * - * @param string - * @return string - */ - protected function identifier_to_key( $identifier ) - { - return $this->config['cache_id'].':'.$identifier; - } - - /** - * Prepend the cache properties - * - * @return string - */ - protected function prep_contents() - { - $properties = array( - 'created' => $this->created, - 'expiration' => $this->expiration, - 'dependencies' => $this->dependencies, - 'content_handler' => $this->content_handler, - ); - $properties = '{{'.static::PROPS_TAG.'}}'.json_encode($properties).'{{/'.static::PROPS_TAG.'}}'; - - return $properties.$this->contents; - } - - /** - * Remove the prepended cache properties and save them in class properties - * - * @param string - * @throws \UnexpectedValueException - */ - protected function unprep_contents($payload) - { - $properties_end = strpos($payload, '{{/'.static::PROPS_TAG.'}}'); - if ($properties_end === FALSE) - { - throw new \UnexpectedValueException('Cache has bad formatting'); - } - - $this->contents = substr($payload, $properties_end + strlen('{{/'.static::PROPS_TAG.'}}')); - $props = substr(substr($payload, 0, $properties_end), strlen('{{'.static::PROPS_TAG.'}}')); - $props = json_decode($props, true); - if ($props === NULL) - { - throw new \UnexpectedValueException('Cache properties retrieval failed'); - } - - $this->created = $props['created']; - $this->expiration = is_null($props['expiration']) ? null : (int) ($props['expiration'] - time()); - $this->dependencies = $props['dependencies']; - $this->content_handler = $props['content_handler']; - } - - /** - * Save a cache, this does the generic pre-processing - * - * @return bool success - */ - protected function _set() - { - // get the key for the cache identifier - $key = $this->_get_key(); - - // write the cache - static::$redis->set($key, $this->prep_contents()); - if ( ! empty($this->expiration)) - { - static::$redis->expireat($key, $this->expiration); - } - - // update the index - $this->_update_index($key); - - return true; - } - - /** - * Load a cache, this does the generic post-processing - * - * @return bool success - */ - protected function _get() - { - // get the key for the cache identifier - $key = $this->_get_key(); - - // fetch the cache data from the redis server - $payload = static::$redis->get($key); - try - { - $this->unprep_contents($payload); - } - catch (\UnexpectedValueException $e) - { - return false; - } - - return true; - } - - /** - * validate a driver config value - * - * @param string $name name of the config variable to validate - * @param mixed $value value - * @return mixed - */ - protected function _validate_config($name, $value) - { - switch ($name) - { - case 'database': - // do we have a database config - if (empty($value) or ! is_string($value)) - { - $value = 'default'; - } - break; - - case 'cache_id': - if (empty($value) or ! is_string($value)) - { - $value = 'fuel'; - } - break; - - case 'expiration': - if (empty($value) or ! is_numeric($value)) - { - $value = null; - } - break; - - default: - break; - } - - return $value; - } - - /** - * get's the redis key belonging to the cache identifier - * - * @param bool $remove if true, remove the key retrieved from the index - * @return string - */ - protected function _get_key($remove = false) - { - // get the current index information - list($identifier, $sections, $index) = $this->_get_index(); - $index = $index === null ? array() : $index = $this->_unserialize($index); - - // get the key from the index - $key = isset($index[$identifier][0]) ? $index[$identifier][0] : false; - - if ($remove === true) - { - if ( $key !== false ) - { - unset($index[$identifier]); - static::$redis->set($this->config['cache_id'].':index:'.$sections, $this->_serialize($index)); - } - } - else - { - // create a new key if needed - $key === false and $key = $this->_new_key(); - } - - return $key; - } - - /** - * generate a new unique key for the current identifier - * - * @return string - */ - protected function _new_key() - { - $key = ''; - while (strlen($key) < 32) - { - $key .= mt_rand(0, mt_getrandmax()); - } - return md5($this->config['cache_id'].'_'.uniqid($key, TRUE)); - } - - /** - * Get the section index - * - * @return array containing the identifier, the sections, and the section index - */ - protected function _get_index() - { - // get the section name and identifier - $sections = explode('.', $this->identifier); - if (count($sections) > 1) - { - $identifier = array_pop($sections); - $sections = '.'.implode('.', $sections); - } - else - { - $identifier = $this->identifier; - $sections = ''; - } - - // get the cache index and return it - return array($identifier, $sections, static::$redis->get($this->config['cache_id'].':index:'.$sections)); - } - - /** - * Update the section index - * - * @param string cache key - */ - protected function _update_index($key) - { - // get the current index information - list($identifier, $sections, $index) = $this->_get_index(); - $index = $index === null ? array() : $index = $this->_unserialize($index); - - // store the key in the index and write the index back - $index[$identifier] = array($key, $this->created); - - static::$redis->set($this->config['cache_id'].':index:'.$sections, $this->_serialize($index)); - - // get the directory index - $index = static::$redis->get($this->config['cache_id'].':dir:'); - $index = $index === null ? array() : $index = $this->_unserialize($index); - - if (is_array($index)) - { - if ( ! in_array($sections, $index)) - { - $index[] = $sections; - } - } - else - { - $index = array($sections); - } - - // update the directory index - static::$redis->set($this->config['cache_id'].':dir:', $this->_serialize($index)); - } - - /** - * Serialize an array - * - * This function first converts any slashes found in the array to a temporary - * marker, so when it gets unserialized the slashes will be preserved - * - * @param array - * @return string - */ - protected function _serialize($data) - { - if (is_array($data)) - { - foreach ($data as $key => $val) - { - if (is_string($val)) - { - $data[$key] = str_replace('\\', '{{slash}}', $val); - } - } - } - else - { - if (is_string($data)) - { - $data = str_replace('\\', '{{slash}}', $data); - } - } - - return serialize($data); - } - - /** - * Unserialize - * - * This function unserializes a data string, then converts any - * temporary slash markers back to actual slashes - * - * @param array - * @return string - */ - protected function _unserialize($data) - { - $data = @unserialize(stripslashes($data)); - - if (is_array($data)) - { - foreach ($data as $key => $val) - { - if (is_string($val)) - { - $data[$key] = str_replace('{{slash}}', '\\', $val); - } - } - - return $data; - } - - return (is_string($data)) ? str_replace('{{slash}}', '\\', $data) : $data; - } -} diff --git a/fuel/core/classes/cache/storage/xcache.php b/fuel/core/classes/cache/storage/xcache.php deleted file mode 100755 index 39edc89..0000000 --- a/fuel/core/classes/cache/storage/xcache.php +++ /dev/null @@ -1,375 +0,0 @@ -config = isset($config['xcache']) ? $config['xcache'] : array(); - - // make sure we have an id - $this->config['cache_id'] = $this->_validate_config('cache_id', isset($this->config['cache_id']) - ? $this->config['cache_id'] : 'fuel'); - - // check for an expiration override - $this->expiration = $this->_validate_config('expiration', isset($this->config['expiration']) - ? $this->config['expiration'] : $this->expiration); - - // do we have the PHP XCache extension available - if ( ! function_exists('xcache_set') ) - { - throw new \FuelException('Your PHP installation doesn\'t have XCache loaded.'); - } - } - - // --------------------------------------------------------------------- - - /** - * Check if other caches or files have been changed since cache creation - * - * @param array - * @return bool - */ - public function check_dependencies(array $dependencies) - { - foreach($dependencies as $dep) - { - // get the section name and identifier - $sections = explode('.', $dep); - if (count($sections) > 1) - { - $identifier = array_pop($sections); - $sections = '.'.implode('.', $sections); - - } - else - { - $identifier = $dep; - $sections = ''; - } - - // get the cache index - $index = xcache_get($this->config['cache_id'].$sections); - - // get the key from the index - $key = isset($index[$identifier][0]) ? $index[$identifier] : false; - - // key found and newer? - if ($key === false or $key[1] > $this->created) - { - return false; - } - } - return true; - } - - /** - * Delete Cache - */ - public function delete() - { - // get the XCache key for the cache identifier - $key = $this->_get_key(true); - - // delete the key from the xcache store - $key and xcache_unset($key); - - $this->reset(); - } - - /** - * Purge all caches - * - * @param string $section limit purge to subsection - * @return bool - */ - public function delete_all($section) - { - // determine the section index name - $section = $this->config['cache_id'].(empty($section) ? '' : '.'.$section); - - // get the directory index - $index = xcache_get($this->config['cache_id'].'__DIR__'); - - if (is_array($index)) - { - $dirs = array(); - foreach ($index as $dir) - { - if (strpos($dir, $section) === 0) - { - $dirs[] = $dir; - $list = xcache_get($dir); - foreach ($list as $item) - { - xcache_unset($item[0]); - } - xcache_unset($dir); - } - } - - // update the directory index - $dirs and xcache_set($this->config['cache_id'].'__DIR__', array_diff($index, $dirs)); - } - } - - // --------------------------------------------------------------------- - - /** - * Prepend the cache properties - * - * @return string - */ - protected function prep_contents() - { - $properties = array( - 'created' => $this->created, - 'expiration' => $this->expiration, - 'dependencies' => $this->dependencies, - 'content_handler' => $this->content_handler, - ); - $properties = '{{'.static::PROPS_TAG.'}}'.json_encode($properties).'{{/'.static::PROPS_TAG.'}}'; - - return $properties.$this->contents; - } - - /** - * Remove the prepended cache properties and save them in class properties - * - * @param string $payload - * @throws \UnexpectedValueException - */ - protected function unprep_contents($payload) - { - $properties_end = strpos($payload, '{{/'.static::PROPS_TAG.'}}'); - if ($properties_end === FALSE) - { - throw new \UnexpectedValueException('Cache has bad formatting'); - } - - $this->contents = substr($payload, $properties_end + strlen('{{/'.static::PROPS_TAG.'}}')); - $props = substr(substr($payload, 0, $properties_end), strlen('{{'.static::PROPS_TAG.'}}')); - $props = json_decode($props, true); - if ($props === NULL) - { - throw new \UnexpectedValueException('Cache properties retrieval failed'); - } - - $this->created = $props['created']; - $this->expiration = is_null($props['expiration']) ? null : (int) ($props['expiration'] - time()); - $this->dependencies = $props['dependencies']; - $this->content_handler = $props['content_handler']; - } - - /** - * Save a cache, this does the generic pre-processing - * - * @return bool success - */ - protected function _set() - { - // get the xcache key for the cache identifier - $key = $this->_get_key(); - - $payload = $this->prep_contents(); - - // adjust the expiration, xcache uses a TTL instead of a timestamp - $expiration = is_null($this->expiration) ? 0 : (int) ($this->expiration - $this->created); - - // write it to the xcache store - if (xcache_set($key, $payload, $expiration) === false) - { - throw new \RuntimeException('Xcache returned failed to write. Check your configuration.'); - } - - // update the index - $this->_update_index($key); - - return true; - } - - /** - * Load a cache, this does the generic post-processing - * - * @return bool success - */ - protected function _get() - { - // get the xcache key for the cache identifier - $key = $this->_get_key(); - - // fetch the cached data from the xcache store - $payload = xcache_get($key); - - try - { - $this->unprep_contents($payload); - } - catch (\UnexpectedValueException $e) - { - return false; - } - - return true; - } - - /** - * validate a driver config value - * - * @param string $name name of the config variable to validate - * @param mixed $value - * @return mixed - */ - private function _validate_config($name, $value) - { - switch ($name) - { - case 'cache_id': - if (empty($value) or ! is_string($value)) - { - $value = 'fuel'; - } - break; - - case 'expiration': - if (empty($value) or ! is_numeric($value)) - { - $value = null; - } - break; - - default: - break; - } - - return $value; - } - - /** - * get's the xcache key belonging to the cache identifier - * - * @param bool $remove if true, remove the key retrieved from the index - * @return string - */ - protected function _get_key($remove = false) - { - // get the current index information - list($identifier, $sections, $index) = $this->_get_index(); - - // get the key from the index - $key = isset($index[$identifier][0]) ? $index[$identifier][0] : false; - - if ($remove === true) - { - if ( $key !== false ) - { - unset($index[$identifier]); - xcache_set($this->config['cache_id'].$sections, $index); - } - } - else - { - // create a new key if needed - $key === false and $key = $this->_new_key(); - } - - return $key; - } - - /** - * generate a new unique key for the current identifier - * - * @return string - */ - protected function _new_key() - { - $key = ''; - while (strlen($key) < 32) - { - $key .= mt_rand(0, mt_getrandmax()); - } - return md5($this->config['cache_id'].'_'.uniqid($key, TRUE)); - } - - /** - * Get the section index - * - * @return array containing the identifier, the sections, and the section index - */ - protected function _get_index() - { - // get the section name and identifier - $sections = explode('.', $this->identifier); - if (count($sections) > 1) - { - $identifier = array_pop($sections); - $sections = '.'.implode('.', $sections); - } - else - { - $identifier = $this->identifier; - $sections = ''; - } - - // get the cache index and return it - return array($identifier, $sections, xcache_get($this->config['cache_id'].$sections)); - } - - /** - * Update the section index - * - * @param string cache key - */ - protected function _update_index($key) - { - // get the current index information - list($identifier, $sections, $index) = $this->_get_index(); - - // store the key in the index and write the index back - $index[$identifier] = array($key, $this->created); - xcache_set($this->config['cache_id'].$sections, array_merge($index, array($identifier => array($key, $this->created)))); - - // get the directory index - $index = xcache_get($this->config['cache_id'].'__DIR__'); - - if (is_array($index)) - { - if (!in_array($this->config['cache_id'].$sections, $index)) - { - $index[] = $this->config['cache_id'].$sections; - } - } - else - { - $index = array($this->config['cache_id'].$sections); - } - - // update the directory index - xcache_set($this->config['cache_id'].'__DIR__', $index, 0); - } -} diff --git a/fuel/core/classes/cli.php b/fuel/core/classes/cli.php deleted file mode 100755 index 185b605..0000000 --- a/fuel/core/classes/cli.php +++ /dev/null @@ -1,532 +0,0 @@ - '0;30', - 'dark_gray' => '1;30', - 'blue' => '0;34', - 'dark_blue' => '1;34', - 'light_blue' => '1;34', - 'green' => '0;32', - 'light_green' => '1;32', - 'cyan' => '0;36', - 'light_cyan' => '1;36', - 'red' => '0;31', - 'light_red' => '1;31', - 'purple' => '0;35', - 'light_purple' => '1;35', - 'light_yellow' => '0;33', - 'yellow' => '1;33', - 'light_gray' => '0;37', - 'white' => '1;37', - ); - - protected static $background_colors = array( - 'black' => '40', - 'red' => '41', - 'green' => '42', - 'yellow' => '43', - 'blue' => '44', - 'magenta' => '45', - 'cyan' => '46', - 'light_gray' => '47', - ); - - protected static $STDOUT; - protected static $STDERR; - - /** - * Static constructor. Parses all the CLI params. - */ - public static function _init() - { - if ( ! \Fuel::$is_cli) - { - throw new \Exception('Cli class cannot be used outside of the command line.'); - } - for ($i = 1; $i < $_SERVER['argc']; $i++) - { - $arg = explode('=', $_SERVER['argv'][$i]); - - static::$args[$i] = $arg[0]; - - if (count($arg) > 1 || strncmp($arg[0], '-', 1) === 0) - { - static::$args[ltrim($arg[0], '-')] = isset($arg[1]) ? $arg[1] : true; - } - } - - // Readline is an extension for PHP that makes interactive with PHP much more bash-like - // http://www.php.net/manual/en/readline.installation.php - static::$readline_support = extension_loaded('readline'); - - static::$STDERR = STDERR; - static::$STDOUT = STDOUT; - } - - /** - * Returns the option with the given name. You can also give the option - * number. - * - * Named options must be in the following formats: - * php index.php user -v --v -name=John --name=John - * - * @param string|int $name the name of the option (int if unnamed) - * @param mixed $default value to return if the option is not defined - * @return mixed - */ - public static function option($name, $default = null) - { - if ( ! isset(static::$args[$name])) - { - return \Fuel::value($default); - } - return static::$args[$name]; - } - - /** - * Allows you to set a commandline option from code - * - * @param string|int $name the name of the option (int if unnamed) - * @param mixed|null $value value to set, or null to delete the option - * @return mixed - */ - public static function set_option($name, $value = null) - { - if ($value === null) - { - if (isset(static::$args[$name])) - { - unset(static::$args[$name]); - } - } - else - { - static::$args[$name] = $value; - } - } - - /** - * Get input from the shell, using readline or the standard STDIN - * - * Named options must be in the following formats: - * php index.php user -v --v -name=John --name=John - * - * @param string|int $prefix the name of the option (int if unnamed) - * @return string - */ - public static function input($prefix = '') - { - if (static::$readline_support) - { - return readline($prefix); - } - - echo $prefix; - return fgets(STDIN); - } - - /** - * Asks the user for input. This can have either 1 or 2 arguments. - * - * Usage: - * - * // Waits for any key press - * CLI::prompt(); - * - * // Takes any input - * $color = CLI::prompt('What is your favorite color?'); - * - * // Takes any input, but offers default - * $color = CLI::prompt('What is your favourite color?', 'white'); - * - * // Will only accept the options in the array - * $ready = CLI::prompt('Are you ready?', array('y','n')); - * - * @return string the user input - */ - public static function prompt() - { - $args = func_get_args(); - - $options = array(); - $output = ''; - $default = null; - - // How many we got - $arg_count = count($args); - - // Is the last argument a boolean? True means required - $required = end($args) === true; - - // Reduce the argument count if required was passed, we don't care about that anymore - $required === true and --$arg_count; - - // This method can take a few crazy combinations of arguments, so lets work it out - switch ($arg_count) - { - case 2: - - // E.g: $ready = CLI::prompt('Are you ready?', array('y','n')); - if (is_array($args[1])) - { - list($output, $options)=$args; - } - - // E.g: $color = CLI::prompt('What is your favourite color?', 'white'); - elseif (is_string($args[1])) - { - list($output, $default)=$args; - } - - break; - - case 1: - - // No question (probably been asked already) so just show options - // E.g: $ready = CLI::prompt(array('y','n')); - if (is_array($args[0])) - { - $options = $args[0]; - } - - // Question without options - // E.g: $ready = CLI::prompt('What did you do today?'); - elseif (is_string($args[0])) - { - $output = $args[0]; - } - - break; - } - - // If a question has been asked with the read - if ($output !== '') - { - $extra_output = ''; - - if ($default !== null) - { - $extra_output = ' [ Default: "'.$default.'" ]'; - } - - elseif ($options !== array()) - { - $extra_output = ' [ '.implode(', ', $options).' ]'; - } - - fwrite(static::$STDOUT, $output.$extra_output.': '); - } - - // Read the input from keyboard. - $input = trim(static::input()) ?: $default; - - // No input provided and we require one (default will stop this being called) - if (empty($input) and $required === true) - { - static::write('This is required.'); - static::new_line(); - - $input = forward_static_call_array(array(__CLASS__, 'prompt'), $args); - } - - // If options are provided and the choice is not in the array, tell them to try again - if ( ! empty($options) and ! in_array($input, $options)) - { - static::write('This is not a valid option. Please try again.'); - static::new_line(); - - $input = forward_static_call_array(array(__CLASS__, 'prompt'), $args); - } - - return $input; - } - - /** - * Outputs a string to the cli. If you send an array it will implode them - * with a line break. - * - * @param string|array $text the text to output, or array of lines - * @param string $foreground the foreground color - * @param string $background the foreground color - * @throws \FuelException - */ - public static function write($text = '', $foreground = null, $background = null) - { - if (is_array($text)) - { - $text = implode(PHP_EOL, $text); - } - - if ($foreground or $background) - { - $text = static::color($text, $foreground, $background); - } - - fwrite(static::$STDOUT, $text.PHP_EOL); - } - - /** - * Outputs an error to the CLI using STDERR instead of STDOUT - * - * @param string|array $text the text to output, or array of errors - * @param string $foreground the foreground color - * @param string $background the foreground color - * @throws \FuelException - */ - public static function error($text = '', $foreground = 'light_red', $background = null) - { - if (is_array($text)) - { - $text = implode(PHP_EOL, $text); - } - - if ($foreground OR $background) - { - $text = static::color($text, $foreground, $background); - } - - fwrite(static::$STDERR, $text.PHP_EOL); - } - - /** - * Beeps a certain number of times. - * - * @param int $num the number of times to beep - */ - public static function beep($num = 1) - { - echo str_repeat("\x07", $num); - } - - /** - * Waits a certain number of seconds, optionally showing a wait message and - * waiting for a key press. - * - * @param int $seconds number of seconds - * @param bool $countdown show a countdown or not - */ - public static function wait($seconds = 0, $countdown = false) - { - if ($countdown === true) - { - $time = $seconds; - - while ($time > 0) - { - fwrite(static::$STDOUT, $time.'... '); - sleep(1); - $time--; - } - static::write(); - } - - else - { - if ($seconds > 0) - { - sleep($seconds); - } - else - { - static::write(static::$wait_msg); - static::input(); - } - } - } - - /** - * if operating system === windows - */ - public static function is_windows() - { - return 'win' === strtolower(substr(php_uname("s"), 0, 3)); - } - - /** - * Enter a number of empty lines - * - * @param integer Number of lines to output - * @return void - */ - public static function new_line($num = 1) - { - // Do it once or more, write with empty string gives us a new line - for($i = 0; $i < $num; $i++) - { - static::write(); - } - } - - /** - * Clears the screen of output - * - * @return void - */ - public static function clear_screen() - { - static::is_windows() - - // Windows is a bit crap at this, but their terminal is tiny so shove this in - ? static::new_line(40) - - // Anything with a flair of Unix will handle these magic characters - : fwrite(static::$STDOUT, chr(27)."[H".chr(27)."[2J"); - } - - /** - * Returns the given text with the correct color codes for a foreground and - * optionally a background color. - * - * @param string $text the text to color - * @param string $foreground the foreground color - * @param string $background the background color - * @param string $format other formatting to apply. Currently only 'underline' is understood - * @return string the color coded string - * @throws \FuelException - */ - public static function color($text, $foreground, $background = null, $format=null) - { - if (static::is_windows() and ! \Input::server('ANSICON')) - { - return $text; - } - - if (static::$nocolor) - { - return $text; - } - - if ( ! array_key_exists($foreground, static::$foreground_colors)) - { - throw new \FuelException('Invalid CLI foreground color: '.$foreground); - } - - if ( $background !== null and ! array_key_exists($background, static::$background_colors)) - { - throw new \FuelException('Invalid CLI background color: '.$background); - } - - $string = "\033[".static::$foreground_colors[$foreground]."m"; - - if ($background !== null) - { - $string .= "\033[".static::$background_colors[$background]."m"; - } - - if ($format === 'underline') - { - $string .= "\033[4m"; - } - - $string .= $text."\033[0m"; - - return $string; - } - - /** - * Spawn Background Process - * - * Launches a background process (note, provides no security itself, $call must be sanitised prior to use) - * @param string $call the system call to make - * @param string $output - * @return void - * @author raccettura - * @link http://robert.accettura.com/blog/2006/09/14/asynchronous-processing-with-php/ - */ - public static function spawn($call, $output = '/dev/null') - { - // Windows - if(static::is_windows()) - { - pclose(popen('start /b '.$call, 'r')); - } - - // Some sort of UNIX - else - { - pclose(popen($call.' > '.$output.' &', 'r')); - } - } - - /** - * Redirect STDERR writes to this file or fh - * - * Call with no argument to retrieve the current filehandle. - * - * Is not smart about opening the file if it's a string. Existing files will be truncated. - * - * @param resource|string $fh Opened filehandle or string filename. - * - * @return resource - */ - public static function stderr($fh = null) - { - $orig = static::$STDERR; - - if (! is_null($fh)) { - if (is_string($fh)) { - $fh = fopen($fh, "w"); - } - static::$STDERR = $fh; - } - - return $orig; - } - - /** - * Redirect STDOUT writes to this file or fh - * - * Call with no argument to retrieve the current filehandle. - * - * Is not smart about opening the file if it's a string. Existing files will be truncated. - * - * @param resource|string|null $fh Opened filehandle or string filename. - * - * @return resource - */ - public static function stdout($fh = null) - { - $orig = static::$STDOUT; - - if (! is_null($fh)) { - if (is_string($fh)) { - $fh = fopen($fh, "w"); - } - static::$STDOUT = $fh; - } - - return $orig; - } -} diff --git a/fuel/core/classes/config.php b/fuel/core/classes/config.php deleted file mode 100755 index 68440ab..0000000 --- a/fuel/core/classes/config.php +++ /dev/null @@ -1,231 +0,0 @@ -load($overwrite, ! $reload); - } - catch (\ConfigException $e) - { - $config = array(); - } - $group = $group === true ? $file->group() : $group; - } - - if ($group === null) - { - static::$items = $reload ? $config : ($overwrite ? array_merge(static::$items, $config) : \Arr::merge(static::$items, $config)); - static::$itemcache = array(); - } - else - { - $group = ($group === true) ? $file : $group; - if ( ! isset(static::$items[$group]) or $reload) - { - static::$items[$group] = array(); - } - static::$items[$group] = $overwrite ? array_merge(static::$items[$group], $config) : \Arr::merge(static::$items[$group], $config); - $group .= '.'; - foreach (static::$itemcache as $key => $value) - { - if (strpos($key, $group) === 0) - { - unset(static::$itemcache[$key]); - } - } - } - - return $config; - } - - /** - * Save a config array to disc. - * - * @param string $file desired file name - * @param string|array $config master config array key or config array - * @return bool false when config is empty or invalid else \File::update result - * @throws \FuelException - */ - public static function save($file, $config) - { - if ( ! is_array($config)) - { - if ( ! isset(static::$items[$config])) - { - return false; - } - $config = static::$items[$config]; - } - - $info = pathinfo($file); - $type = 'php'; - - if (isset($info['extension'])) - { - $type = $info['extension']; - // Keep extension when it's an absolute path, because the finder won't add it - if ($file[0] !== '/' and $file[1] !== ':') - { - $file = substr($file, 0, -(strlen($type) + 1)); - } - } - - $class = '\\Config_'.ucfirst($type); - - if ( ! class_exists($class)) - { - throw new \FuelException(sprintf('Invalid config type "%s".', $type)); - } - - $driver = new $class($file); - - return $driver->save($config); - } - - /** - * Returns a (dot notated) config setting - * - * @param string $item name of the config item, can be dot notated - * @param mixed $default the return value if the item isn't found - * @return mixed the config setting or default if not found - */ - public static function get($item, $default = null) - { - if (array_key_exists($item, static::$items)) - { - return static::$items[$item]; - } - elseif ( ! array_key_exists($item, static::$itemcache)) - { - // cook up something unique - $miss = new \stdClass(); - - $val = \Arr::get(static::$items, $item, $miss); - - // so we can detect a miss here... - if ($val === $miss) - { - return $default; - } - - static::$itemcache[$item] = $val; - } - - return \Fuel::value(static::$itemcache[$item]); - } - - /** - * Sets a (dot notated) config item - * - * @param string $item a (dot notated) config key - * @param mixed $value the config value - */ - public static function set($item, $value) - { - strpos($item, '.') === false or static::$itemcache[$item] = $value; - \Arr::set(static::$items, $item, $value); - } - - /** - * Deletes a (dot notated) config item - * - * @param string $item a (dot notated) config key - * @return array|bool the \Arr::delete result, success boolean or array of success booleans - */ - public static function delete($item) - { - if (isset(static::$itemcache[$item])) - { - unset(static::$itemcache[$item]); - } - return \Arr::delete(static::$items, $item); - } -} diff --git a/fuel/core/classes/config/db.php b/fuel/core/classes/config/db.php deleted file mode 100755 index beef80d..0000000 --- a/fuel/core/classes/config/db.php +++ /dev/null @@ -1,158 +0,0 @@ -identifier = $identifier; - - $this->vars = array( - 'APPPATH' => APPPATH, - 'COREPATH' => COREPATH, - 'PKGPATH' => PKGPATH, - 'DOCROOT' => DOCROOT, - ) + $vars; - - $this->database = \Config::get('config.database', null); - $this->table = \Config::get('config.table_name', 'config'); - } - - /** - * Loads the config file(s). - * - * @param bool $overwrite Whether to overwrite existing values - * @param bool $cache This parameter will ignore in this implement. - * @return array the config array - * @throws \Database_Exception - */ - public function load($overwrite = false, $cache = true) - { - $config = array(); - - // try to retrieve the config from the database - try - { - $result = \DB::select('config')->from($this->table)->where('identifier', '=', $this->identifier)->execute($this->database); - } - catch (Database_Exception $e) - { - // strip the actual query from the message - $msg = $e->getMessage(); - $msg = substr($msg, 0, strlen($msg) - strlen(strrchr($msg, ':'))); - - // and rethrow it - throw new \Database_Exception($msg); - } - - // did we succeed? - if ($result->count()) - { - empty($result[0]['config']) or $config = unserialize($this->parse_vars($result[0]['config'])); - } - - return $config; - } - - /** - * Gets the default group name. - * - * @return string - */ - public function group() - { - return $this->identifier; - } - - /** - * Parses a string using all of the previously set variables. Allows you to - * use something like %APPPATH% in non-PHP files. - * - * @param string $string String to parse - * @return string - */ - protected function parse_vars($string) - { - foreach ($this->vars as $var => $val) - { - $string = str_replace("%$var%", $val, $string); - } - - return $string; - } - - /** - * Replaces FuelPHP's path constants to their string counterparts. - * - * @param array $array array to be prepped - * @return array prepped array - */ - protected function prep_vars(&$array) - { - static $replacements = false; - - if ($replacements === false) - { - foreach ($this->vars as $i => $v) - { - $replacements['#^('.preg_quote($v).'){1}(.*)?#'] = "%".$i."%$2"; - } - } - - foreach ($array as $i => $value) - { - if (is_string($value)) - { - $array[$i] = preg_replace(array_keys($replacements), array_values($replacements), $value); - } - elseif(is_array($value)) - { - $this->prep_vars($array[$i]); - } - } - } - - /** - * Formats the output and saved it to disc. - * - * @param $contents $contents config array to save - * @return bool DB result - */ - public function save($contents) - { - // prep the contents - $this->prep_vars($contents); - $contents = serialize($contents); - - // update the config in the database - $result = \DB::update($this->table)->set(array('config' => $contents, 'hash' => uniqid()))->where('identifier', '=', $this->identifier)->execute($this->database); - - // if there wasn't an update, do an insert - if ($result === 0) - { - list($notused, $result) = \DB::insert($this->table)->set(array('identifier' => $this->identifier, 'config' => $contents, 'hash' => uniqid()))->execute($this->database); - } - - return $result === 1; - } -} diff --git a/fuel/core/classes/config/file.php b/fuel/core/classes/config/file.php deleted file mode 100755 index 5dddf1d..0000000 --- a/fuel/core/classes/config/file.php +++ /dev/null @@ -1,227 +0,0 @@ -file = $file; - - $this->vars = array( - 'APPPATH' => APPPATH, - 'COREPATH' => COREPATH, - 'PKGPATH' => PKGPATH, - 'DOCROOT' => DOCROOT, - ) + $vars; - } - - /** - * Loads the config file(s). - * - * @param bool $overwrite Whether to overwrite existing values - * @param bool $cache Whether to cache this path or not - * @return array the config array - */ - public function load($overwrite = false, $cache = true) - { - $paths = $this->find_file($cache); - $config = array(); - - foreach ($paths as $path) - { - $config = $overwrite ? - array_merge($config, $this->load_file($path)) : - \Arr::merge($config, $this->load_file($path)); - } - - return $config; - } - - /** - * Gets the default group name. - * - * @return string - */ - public function group() - { - return $this->file; - } - - /** - * Parses a string using all of the previously set variables. Allows you to - * use something like %APPPATH% in non-PHP files. - * - * @param string $string String to parse - * @return string - */ - protected function parse_vars($string) - { - foreach ($this->vars as $var => $val) - { - $string = str_replace("%$var%", $val, $string); - } - - return $string; - } - - /** - * Replaces FuelPHP's path constants to their string counterparts. - * - * @param array $array array to be prepped - * @return array prepped array - */ - protected function prep_vars(&$array) - { - static $replacements = false; - - if ($replacements === false) - { - foreach ($this->vars as $i => $v) - { - $replacements['#^('.preg_quote($v).'){1}(.*)?#'] = "%".$i."%$2"; - } - } - - foreach ($array as $i => $value) - { - if (is_string($value)) - { - $array[$i] = preg_replace(array_keys($replacements), array_values($replacements), $value); - } - elseif(is_array($value)) - { - $this->prep_vars($array[$i]); - } - } - } - - /** - * Finds the given config files - * - * @param bool $cache Whether to cache this path or not - * @return array - * @throws \ConfigException - */ - protected function find_file($cache = true) - { - if (($this->file[0] === '/' or (isset($this->file[1]) and $this->file[1] === ':')) and is_file($this->file)) - { - $paths = array($this->file); - } - else - { - $paths = array_merge( - \Finder::search('config/'.\Fuel::$env, $this->file, $this->ext, true, $cache), - \Finder::search('config', $this->file, $this->ext, true, $cache) - ); - } - - if (empty($paths)) - { - throw new \ConfigException(sprintf('File "%s" does not exist.', $this->file)); - } - - return array_reverse($paths); - } - - /** - * Formats the output and saved it to disc. - * - * @param array $contents config array to save - * @return bool \File::update result - */ - public function save($contents) - { - // get the formatted output - $output = $this->export_format($contents); - - if ( ! $output) - { - return false; - } - - if ( ! $path = \Finder::search('config', $this->file, $this->ext)) - { - if ($pos = strripos($this->file, '::')) - { - // get the namespace path - if ($path = \Autoloader::namespace_path('\\'.ucfirst(substr($this->file, 0, $pos)))) - { - // strip the namespace from the filename - $this->file = substr($this->file, $pos+2); - - // strip the classes directory as we need the module root - $path = substr($path, 0, -8).'config'.DS.$this->file.$this->ext; - } - else - { - // invalid namespace requested - return false; - } - } - } - - // absolute path requested? - if ($this->file[0] === '/' or (isset($this->file[1]) and $this->file[1] === ':')) - { - $path = $this->file; - } - - // make sure we have a fallback - $path or $path = APPPATH.'config'.DS.$this->file.$this->ext; - - $path = pathinfo($path); - if ( ! is_dir($path['dirname'])) - { - mkdir($path['dirname'], 0777, true); - } - - $return = \File::update($path['dirname'], $path['basename'], $output); - if ($return) - { - try - { - \Config::load('file', true); - chmod($path['dirname'].DS.$path['basename'], \Config::get('file.chmod.files', 0666)); - } - catch (\PhpErrorException $e) - { - // if we get something else then a chmod error, bail out - if (substr($e->getMessage(), 0, 8) !== 'chmod():') - { - throw new $e; - } - } - } - return $return; - } - - /** - * Must be implemented by child class. Gets called for each file to load. - * - * @param string $file the path to the file - */ - abstract protected function load_file($file); - - /** - * Must be implemented by child class. Gets called when saving a config file. - * - * @param array $contents config array to save - * @return string formatted output - */ - abstract protected function export_format($contents); -} diff --git a/fuel/core/classes/config/ini.php b/fuel/core/classes/config/ini.php deleted file mode 100755 index e2b1004..0000000 --- a/fuel/core/classes/config/ini.php +++ /dev/null @@ -1,38 +0,0 @@ -parse_vars(file_get_contents($file)); - return parse_ini_string($contents, true); - } - - /** - * Returns the formatted config file contents. - * - * @param array $contents config array - * @return string formatted config file contents - * @throws \ConfigException - */ - protected function export_format($contents) - { - throw new \ConfigException('Saving config to ini is not supported at this time'); - } -} diff --git a/fuel/core/classes/config/interface.php b/fuel/core/classes/config/interface.php deleted file mode 100755 index 08dd0bc..0000000 --- a/fuel/core/classes/config/interface.php +++ /dev/null @@ -1,10 +0,0 @@ -parse_vars(file_get_contents($file)); - return json_decode($contents, true); - } - - /** - * Returns the formatted config file contents. - * - * @param array $contents config array - * @return string formatted config file contents - */ - protected function export_format($contents) - { - $this->prep_vars($contents); - return \Format::forge()->to_json($contents, true); - } -} diff --git a/fuel/core/classes/config/memcached.php b/fuel/core/classes/config/memcached.php deleted file mode 100755 index 0bc8110..0000000 --- a/fuel/core/classes/config/memcached.php +++ /dev/null @@ -1,174 +0,0 @@ - 'config', - 'servers' => array( - array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100), - ), - ); - - /** - * @var \Memcached storage for the memcached object - */ - protected static $memcached = false; - - /** - * driver initialisation - * - * @throws \FuelException - */ - public static function _init() - { - static::$config = array_merge(static::$config, \Config::get('config.memcached', array())); - - if (static::$memcached === false) - { - // do we have the PHP memcached extension available - if ( ! class_exists('Memcached') ) - { - throw new \FuelException('Memcached config storage is required, but your PHP installation doesn\'t have the Memcached extension loaded.'); - } - - // instantiate the memcached object - static::$memcached = new \Memcached(); - - // add the configured servers - static::$memcached->addServers(static::$config['servers']); - - // check if we can connect to all the server(s) - $added = static::$memcached->getStats(); - foreach (static::$config['servers'] as $server) - { - $server = $server['host'].':'.$server['port']; - if ( ! isset($added[$server]) or $added[$server]['pid'] == -1) - { - throw new \FuelException('Memcached config storage is required, but there is no connection possible. Check your configuration.'); - } - } - } - } - - // -------------------------------------------------------------------- - - protected $identifier; - - protected $ext = '.mem'; - - protected $vars = array(); - - /** - * Sets up the file to be parsed and variables - * - * @param string $identifier Config identifier name - * @param array $vars Variables to parse in the data retrieved - */ - public function __construct($identifier = null, $vars = array()) - { - $this->identifier = $identifier; - - $this->vars = array( - 'APPPATH' => APPPATH, - 'COREPATH' => COREPATH, - 'PKGPATH' => PKGPATH, - 'DOCROOT' => DOCROOT, - ) + $vars; - } - - /** - * Loads the config file(s). - * - * @param bool $overwrite Whether to overwrite existing values - * @param bool $cache This parameter will ignore in this implement. - * @return array the config array - */ - public function load($overwrite = false, $cache = true) - { - // fetch the config data from the Memcached server - $result = static::$memcached->get(static::$config['identifier'].'_'.$this->identifier); - - return $result === false ? array() : $result; - } - - /** - * Gets the default group name. - * - * @return string - */ - public function group() - { - return $this->identifier; - } - - /** - * Parses a string using all of the previously set variables. Allows you to - * use something like %APPPATH% in non-PHP files. - * - * @param string $string String to parse - * @return string - */ - protected function parse_vars($string) - { - foreach ($this->vars as $var => $val) - { - $string = str_replace("%$var%", $val, $string); - } - - return $string; - } - - /** - * Replaces FuelPHP's path constants to their string counterparts. - * - * @param array $array array to be prepped - * @return array prepped array - */ - protected function prep_vars(&$array) - { - static $replacements = false; - - if ($replacements === false) - { - foreach ($this->vars as $i => $v) - { - $replacements['#^('.preg_quote($v).'){1}(.*)?#'] = "%".$i."%$2"; - } - } - - foreach ($array as $i => $value) - { - if (is_string($value)) - { - $array[$i] = preg_replace(array_keys($replacements), array_values($replacements), $value); - } - elseif(is_array($value)) - { - $this->prep_vars($array[$i]); - } - } - } - - /** - * Formats the output and saved it to disc. - * - * @param $contents $contents config array to save - * @throws \FuelException - */ - public function save($contents) - { - // write it to the memcached server - if (static::$memcached->set(static::$config['identifier'].'_'.$this->identifier, $contents, 0) === false) - { - throw new \FuelException('Memcached returned error code "'.static::$memcached->getResultCode().'" on write. Check your configuration.'); - } - } -} diff --git a/fuel/core/classes/config/php.php b/fuel/core/classes/config/php.php deleted file mode 100755 index 51c8ab0..0000000 --- a/fuel/core/classes/config/php.php +++ /dev/null @@ -1,105 +0,0 @@ -= 50500 and function_exists('opcache_invalidate')); - - // do we have APC active? - static::$uses_apc = function_exists('apc_compile_file'); - - // determine if we have an opcode cache active - static::$flush_needed = static::$uses_opcache or static::$uses_apc; - } - - /** - * @var string the extension used by this config file parser - */ - protected $ext = '.php'; - - /** - * Formats the output and saved it to disk. - * - * @param $contents $contents config array to save - * @return bool \File::update result - */ - public function save($contents) - { - // store the current filename - $file = $this->file; - - // save it - $return = parent::save($contents); - - // existing file? saved? and do we need to flush the opcode cache? - if ($file == $this->file and $return and static::$flush_needed) - { - if ($this->file[0] !== '/' and ( ! isset($this->file[1]) or $this->file[1] !== ':')) - { - // locate the file - $file = \Finder::search('config', $this->file, $this->ext); - } - - // make sure we have a fallback - $file or $file = APPPATH.'config'.DS.$this->file.$this->ext; - - // flush the opcode caches that are active - static::$uses_opcache and opcache_invalidate($file, true); - static::$uses_apc and apc_compile_file($file); - } - - return $return; - } - - /** - * Loads in the given file and parses it. - * - * @param string $file File to load - * @return array - */ - protected function load_file($file) - { - return \Fuel::load($file); - } - - /** - * Returns the formatted config file contents. - * - * @param array $contents config array - * @return string formatted config file contents - */ - protected function export_format($contents) - { - $output = <<parse_vars(file_get_contents($file)); - return \Format::forge($contents, 'yaml')->to_array(); - } - - /** - * Returns the formatted config file contents. - * - * @param array $contents config array - * @return string formatted config file contents - */ - protected function export_format($contents) - { - if ( ! function_exists('spyc_load')) - { - import('spyc/spyc', 'vendor'); - } - - $this->prep_vars($contents); - return \Spyc::YAMLDump($contents); - } -} diff --git a/fuel/core/classes/controller.php b/fuel/core/classes/controller.php deleted file mode 100755 index 3efa644..0000000 --- a/fuel/core/classes/controller.php +++ /dev/null @@ -1,80 +0,0 @@ -request = $request; - } - - /** - * This method gets called before the action is called - */ - public function before() {} - - /** - * This method gets called after the action is called - * @param \Response|string $response - * @return \Response - */ - public function after($response) - { - // Make sure the $response is a Response object - if ( ! $response instanceof Response) - { - $response = \Response::forge($response, $this->response_status); - } - - return $response; - } - - /** - * This method returns the named parameter requested, or all of them - * if no parameter is given. - * - * @param string $param The name of the parameter - * @param mixed $default Default value - * @return mixed - */ - public function param($param, $default = null) - { - return $this->request->param($param, $default); - } - - /** - * This method returns all of the named parameters. - * - * @return array - */ - public function params() - { - return $this->request->params(); - } -} diff --git a/fuel/core/classes/controller/hybrid.php b/fuel/core/classes/controller/hybrid.php deleted file mode 100755 index ed3f4b0..0000000 --- a/fuel/core/classes/controller/hybrid.php +++ /dev/null @@ -1,136 +0,0 @@ -template object if needed - */ - public function before() - { - // setup the template if this isn't a RESTful call - if ( ! $this->is_restful()) - { - if ( ! empty($this->template) and is_string($this->template)) - { - // Load the template - $this->template = \View::forge($this->template); - } - } - - return parent::before(); - } - - /** - * router - * - * this router will call action methods for normal requests, - * and REST methods for RESTful calls - * - * @param string $resource - * @param array $arguments - * @return mixed - * @throws \HttpNotFoundException - */ - public function router($resource, $arguments) - { - // if this is an ajax call - if ($this->is_restful()) - { - // have the Controller_Rest router deal with it - return parent::router($resource, $arguments); - } - - // check if a input specific method exists - $controller_method = strtolower(\Input::method()) . '_' . $resource; - - // fall back to action_ if no rest method is provided - if ( ! method_exists($this, $controller_method)) - { - $controller_method = 'action_'.$resource; - } - - // check if the action method exists - if (method_exists($this, $controller_method)) - { - return call_fuel_func_array(array($this, $controller_method), $arguments); - } - - // if not, we got ourselfs a genuine 404! - throw new \HttpNotFoundException(); - } - - /** - * After controller method has run output the template - * - * @param Response $response - */ - public function after($response) - { - // return the template if no response is present and this isn't a RESTful call - if ( ! $this->is_restful()) - { - // do we have a response passed? - if ($response === null) - { - // maybe one in the rest body? - $response = $this->response->body; - if ($response === null) - { - // fall back to the defined template - $response = $this->template; - } - } - - // deal with returned array's in non-restful calls - elseif (is_array($response)) - { - $response = \Format::forge()->to_json($response, true); - } - - // and make sure we have a valid Response object - if ( ! $response instanceof Response) - { - $response = \Response::forge($response, $this->response_status); - } - } - - return parent::after($response); - } - - /** - * Decide whether to return RESTful or templated response - * Override in subclass to introduce custom switching logic. - * - * @param boolean - */ - public function is_restful() - { - return \Input::is_ajax(); - } -} diff --git a/fuel/core/classes/controller/rest.php b/fuel/core/classes/controller/rest.php deleted file mode 100755 index 963f6e2..0000000 --- a/fuel/core/classes/controller/rest.php +++ /dev/null @@ -1,515 +0,0 @@ - 'application/xml', - 'rawxml' => 'application/xml', - 'json' => 'application/json', - 'jsonp'=> 'text/javascript', - 'serialized' => 'application/vnd.php.serialized', - 'php' => 'text/plain', - 'html' => 'text/html', - 'csv' => 'application/csv', - ); - - public function before() - { - parent::before(); - - // Some Methods cant have a body - $this->request->body = null; - - // Which format should the data be returned in? - $this->request->lang = $this->_detect_lang(); - - $this->response = \Response::forge(); - } - - public function after($response) - { - // If the response is an array - if (is_array($response)) - { - // set the response - $response = $this->response($response); - } - - // If the response is a Response object, we will use their - // instead of ours. - if ( ! $response instanceof \Response) - { - $response = $this->response; - } - - return parent::after($response); - } - - /** - * Router - * - * Requests are not made to methods directly The request will be for an "object". - * this simply maps the object and method to the correct Controller method. - * - * @param string $resource - * @param array $arguments - * @return bool|mixed - */ - public function router($resource, $arguments) - { - \Config::load('rest', true); - - // If no (or an invalid) format is given, auto detect the format - if (is_null($this->format) or ! array_key_exists($this->format, $this->_supported_formats)) - { - // auto-detect the format - $this->format = array_key_exists(\Input::extension(), $this->_supported_formats) ? \Input::extension() : $this->_detect_format(); - } - - // Get the configured auth method if none is defined - $this->auth === null and $this->auth = \Config::get('rest.auth'); - - //Check method is authorized if required, and if we're authorized - if ($this->auth == 'basic') - { - $valid_login = $this->_prepare_basic_auth(); - } - elseif ($this->auth == 'digest') - { - $valid_login = $this->_prepare_digest_auth(); - } - elseif (method_exists($this, $this->auth)) - { - if (($valid_login = $this->{$this->auth}()) instanceOf \Response) - { - return $valid_login; - } - } - else - { - $valid_login = false; - } - - //If the request passes auth then execute as normal - if(empty($this->auth) or $valid_login) - { - // If they call user, go to $this->post_user(); - $controller_method = strtolower(\Input::method()) . '_' . $resource; - - // Fall back to action_ if no rest method is provided - if ( ! method_exists($this, $controller_method)) - { - $controller_method = 'action_'.$resource; - } - - // If method is not available, set status code to 404 - if (method_exists($this, $controller_method)) - { - return call_fuel_func_array(array($this, $controller_method), $arguments); - } - else - { - $this->response->status = $this->no_method_status; - return; - } - } - else - { - $this->response(array('status'=> 0, 'error'=> 'Not Authorized'), 401); - } - } - - /** - * Response - * - * Takes pure data and optionally a status code, then creates the response - * - * @param mixed - * @param int - * @return object Response instance - */ - protected function response($data = array(), $http_status = null) - { - // set the correct response header - if (method_exists('Format', 'to_'.$this->format)) - { - $this->response->set_header('Content-Type', $this->_supported_formats[$this->format]); - } - - // no data returned? - if ((is_array($data) and empty($data)) or ($data == '')) - { - // override the http status with the NO CONTENT status - $http_status = $this->no_data_status; - } - - // make sure we have a valid return status - $http_status or $http_status = $this->http_status; - - // If the format method exists, call and return the output in that format - if (method_exists('Format', 'to_'.$this->format)) - { - // Handle XML output - if ($this->format === 'xml') - { - // Detect basenode - $xml_basenode = $this->xml_basenode; - $xml_basenode or $xml_basenode = \Config::get('rest.xml_basenode', 'xml'); - - // Set the XML response - $this->response->body(\Format::forge($data)->{'to_'.$this->format}(null, null, $xml_basenode)); - } - else - { - // Set the formatted response - $this->response->body(\Format::forge($data)->{'to_'.$this->format}()); - } - } - - // Format not supported, but the output is an array or an object that can not be cast to string - elseif (is_array($data) or (is_object($data) and ! method_exists($data, '__toString'))) - { - if (\Fuel::$env == \Fuel::PRODUCTION) - { - // not acceptable in production - if ($http_status == 200) - { $http_status = 406; - } - $this->response->body('The requested REST method returned an array or object, which is not compatible with the output format "'.$this->format.'"'); - } - else - { - // convert it to json so we can at least read it while we're developing - $this->response->body('The requested REST method returned an array or object:

'.\Format::forge($data)->to_json(null, true)); - } - } - - // Format not supported, output directly - else - { - $this->response->body($data); - } - - // Set the reponse http status - $http_status and $this->response->status = $http_status; - - return $this->response; - } - - /** - * Set the Response http status. - * - * @param integer $status response http status code - * @return void - */ - protected function http_status($status) - { - $this->http_status = $status; - } - - /** - * Detect format - * - * Detect which format should be used to output the data - * - * @return string - */ - protected function _detect_format() - { - // A format has been passed as a named parameter in the route - if ($this->param('format') and array_key_exists($this->param('format'), $this->_supported_formats)) - { - return $this->param('format'); - } - - // A format has been passed as an argument in the URL and it is supported - if (\Input::param('format') and array_key_exists(\Input::param('format'), $this->_supported_formats)) - { - return \Input::param('format'); - } - - // Otherwise, check the HTTP_ACCEPT (if it exists and we are allowed) - if ($acceptable = \Input::server('HTTP_ACCEPT') and \Config::get('rest.ignore_http_accept') !== true) - { - // If anything is accepted, and we have a default, return that - if ($acceptable == '*/*' and ! empty($this->rest_format)) - { - return $this->rest_format; - } - - // Split the Accept header and build an array of quality scores for each format - $fragments = new \CachingIterator(new \ArrayIterator(preg_split('/[,;]/', \Input::server('HTTP_ACCEPT')))); - $acceptable = array(); - $next_is_quality = false; - foreach ($fragments as $fragment) - { - $quality = 1; - // Skip the fragment if it is a quality score - if ($next_is_quality) - { - $next_is_quality = false; - continue; - } - - // If next fragment exists and is a quality score, set the quality score - elseif ($fragments->hasNext()) - { - $next = $fragments->getInnerIterator()->current(); - if (strpos($next, 'q=') === 0) - { - list($key, $quality) = explode('=', $next); - $next_is_quality = true; - } - } - - $acceptable[$fragment] = $quality; - } - - // Sort the formats by score in descending order - uasort($acceptable, function($a, $b) - { - $a = (float) $a; - $b = (float) $b; - return ($a > $b) ? -1 : 1; - }); - - // Check each of the acceptable formats against the supported formats - $find = array('\*', '/'); - $replace = array('.*', '\/'); - foreach ($acceptable as $pattern => $quality) - { - // The Accept header can contain wildcards in the format - $pattern = '/^' . str_replace($find, $replace, preg_quote($pattern)) . '$/'; - foreach ($this->_supported_formats as $format => $mime) - { - if (preg_match($pattern, $mime)) - { - return $format; - } - } - } - } // End HTTP_ACCEPT checking - - // Well, none of that has worked! Let's see if the controller has a default - if ( ! empty($this->rest_format)) - { - return $this->rest_format; - } - - // Just use the default format - return \Config::get('rest.default_format'); - } - - /** - * Detect language(s) - * - * What language do they want it in? - * - * @return null|array|string - */ - protected function _detect_lang() - { - if (!$lang = \Input::server('HTTP_ACCEPT_LANGUAGE')) - { - return null; - } - - // They might have sent a few, make it an array - if (strpos($lang, ',') !== false) - { - $langs = explode(',', $lang); - - $return_langs = array(); - - foreach ($langs as $lang) - { - // Remove weight and strip space - list($lang) = explode(';', $lang); - $return_langs[] = trim($lang); - } - - return $return_langs; - } - - // Nope, just return the string - return $lang; - } - - // SECURITY FUNCTIONS --------------------------------------------------------- - - protected function _check_login($username = '', $password = null) - { - if (empty($username)) - { - return false; - } - - $valid_logins = \Config::get('rest.valid_logins'); - - if (!array_key_exists($username, $valid_logins)) - { - return false; - } - - // If actually null (not empty string) then do not check it - if ($password !== null and $valid_logins[$username] != $password) - { - return false; - } - - return true; - } - - protected function _prepare_basic_auth() - { - $username = null; - $password = null; - - // mod_php - if (\Input::server('PHP_AUTH_USER')) - { - $username = \Input::server('PHP_AUTH_USER'); - $password = \Input::server('PHP_AUTH_PW'); - } - - // most other servers - elseif (\Input::server('HTTP_AUTHENTICATION')) - { - if (strpos(strtolower(\Input::server('HTTP_AUTHENTICATION')), 'basic') === 0) - { - list($username, $password) = explode(':', base64_decode(substr(\Input::server('HTTP_AUTHORIZATION'), 6))); - } - } - - if ( ! static::_check_login($username, $password)) - { - static::_force_login(); - return false; - } - - return true; - } - - protected function _prepare_digest_auth() - { - // Empty argument for backward compatibility - $uniqid = uniqid(""); - - // We need to test which server authentication variable to use - // because the PHP ISAPI module in IIS acts different from CGI - if (\Input::server('PHP_AUTH_DIGEST')) - { - $digest_string = \Input::server('PHP_AUTH_DIGEST'); - } - elseif (\Input::server('HTTP_AUTHORIZATION')) - { - $digest_string = \Input::server('HTTP_AUTHORIZATION'); - } - else - { - $digest_string = ''; - } - - // Prompt for authentication if we don't have a digest string - if (empty($digest_string)) - { - static::_force_login($uniqid); - return false; - } - - // We need to retrieve authentication informations from the $digest_string variable - $digest_params = explode(', ', $digest_string); - foreach ($digest_params as $digest_param) - { - $digest_param = explode('=', $digest_param, 2); - if (isset($digest_param[1])) - { - $digest[$digest_param[0]] = trim($digest_param[1], '"'); - } - } - - // if no username, or an invalid username found, re-authenticate - if ( ! array_key_exists('username', $digest) or ! static::_check_login($digest['username'])) - { - static::_force_login($uniqid); - return false; - } - - // validate the configured login/password - $valid_logins = \Config::get('rest.valid_logins'); - $valid_pass = $valid_logins[$digest['username']]; - - // This is the valid response expected - $A1 = md5($digest['username'] . ':' . \Config::get('rest.realm') . ':' . $valid_pass); - $A2 = md5(strtoupper(\Input::method()) . ':' . $digest['uri']); - $valid_response = md5($A1 . ':' . $digest['nonce'] . ':' . $digest['nc'] . ':' . $digest['cnonce'] . ':' . $digest['qop'] . ':' . $A2); - - if ($digest['response'] != $valid_response) - { - return false; - } - - return true; - } - - protected function _force_login($nonce = '') - { - // Get the configured auth method if none is defined - $this->auth === null and $this->auth = \Config::get('rest.auth'); - - if ($this->auth == 'basic') - { - $this->response->set_header('WWW-Authenticate', 'Basic realm="'. \Config::get('rest.realm') . '"'); - } - elseif ($this->auth == 'digest') - { - $this->response->set_header('WWW-Authenticate', 'Digest realm="' . \Config::get('rest.realm') . '", qop="auth", nonce="' . $nonce . '", opaque="' . md5(\Config::get('rest.realm')) . '"'); - } - } - -} diff --git a/fuel/core/classes/controller/template.php b/fuel/core/classes/controller/template.php deleted file mode 100755 index 42e7b82..0000000 --- a/fuel/core/classes/controller/template.php +++ /dev/null @@ -1,61 +0,0 @@ -template object - */ - public function before() - { - if ( ! empty($this->template) and is_string($this->template)) - { - // Load the template - $this->template = \View::forge($this->template); - } - - return parent::before(); - } - - /** - * After controller method has run output the template - * - * @param Response $response - */ - public function after($response) - { - // If nothing was returned default to the template - if ($response === null) - { - $response = $this->template; - } - - return parent::after($response); - } - -} diff --git a/fuel/core/classes/cookie.php b/fuel/core/classes/cookie.php deleted file mode 100755 index 24c9134..0000000 --- a/fuel/core/classes/cookie.php +++ /dev/null @@ -1,124 +0,0 @@ - 0, - 'path' => '/', - 'domain' => null, - 'secure' => false, - 'http_only' => false, - ); - - /* - * initialisation and auto configuration - */ - public static function _init() - { - static::$config = array_merge(static::$config, \Config::get('cookie', array())); - } - - /** - * Gets the value of a signed cookie. Cookies without signatures will not - * be returned. If the cookie signature is present, but invalid, the cookie - * will be deleted. - * - * // Get the "theme" cookie, or use "blue" if the cookie does not exist - * $theme = Cookie::get('theme', 'blue'); - * - * @param string $name cookie name - * @param mixed $default default value to return - * @return string - */ - public static function get($name = null, $default = null) - { - return \Input::cookie($name, $default); - } - - /** - * Sets a signed cookie. Note that all cookie values must be strings and no - * automatic serialization will be performed! - * - * // Set the "theme" cookie - * Cookie::set('theme', 'red'); - * - * @param string $name name of cookie - * @param string $value value of cookie - * @param integer $expiration lifetime in seconds - * @param string $path path of the cookie - * @param string $domain domain of the cookie - * @param boolean $secure if true, the cookie should only be transmitted over a secure HTTPS connection - * @param boolean $http_only if true, the cookie will be made accessible only through the HTTP protocol - * @return boolean - */ - public static function set($name, $value, $expiration = null, $path = null, $domain = null, $secure = null, $http_only = null) - { - // you can't set cookies in CLi mode - if (\Fuel::$is_cli) - { - return false; - } - - $value = \Fuel::value($value); - - // use the class defaults for the other parameters if not provided - is_null($expiration) and $expiration = static::$config['expiration']; - is_null($path) and $path = static::$config['path']; - is_null($domain) and $domain = static::$config['domain']; - is_null($secure) and $secure = static::$config['secure']; - is_null($http_only) and $http_only = static::$config['http_only']; - - // add the current time so we have an offset - $expiration = $expiration > 0 ? $expiration + time() : 0; - - return setcookie($name, $value, $expiration, $path, $domain, $secure, $http_only); - } - - /** - * Deletes a cookie by making the value null and expiring it. - * - * Cookie::delete('theme'); - * - * @param string $name cookie name - * @param string $path path of the cookie - * @param string $domain domain of the cookie - * @param boolean $secure if true, the cookie should only be transmitted over a secure HTTPS connection - * @param boolean $http_only if true, the cookie will be made accessible only through the HTTP protocol - * @return boolean - * @uses static::set - */ - public static function delete($name, $path = null, $domain = null, $secure = null, $http_only = null) - { - // Remove the cookie - unset($_COOKIE[$name]); - - // Nullify the cookie and make it expire - return static::set($name, null, -86400, $path, $domain, $secure, $http_only); - } -} diff --git a/fuel/core/classes/crypt.php b/fuel/core/classes/crypt.php deleted file mode 100755 index 4e69201..0000000 --- a/fuel/core/classes/crypt.php +++ /dev/null @@ -1,332 +0,0 @@ - static::$defaults, - )); - die(); - } - } - } - - /** - * forge - * - * create a new named instance - * - * @param string $name instance name - * @param array $config optional runtime configuration - * @return \Crypt - */ - public static function forge($name = '__default__', array $config = array()) - { - if ( ! array_key_exists($name, static::$_instances)) - { - static::$_instances[$name] = new static($config); - } - - return static::$_instances[$name]; - } - - /** - * Return a specific named instance - * - * @param string $name instance name - * @return mixed Crypt if the instance exists, false if not - */ - public static function instance($name = '__default__') - { - if ( ! array_key_exists($name, static::$_instances)) - { - return static::forge($name); - } - - return static::$_instances[$name]; - } - - /** - * capture static calls to methods - * - * @param mixed $method - * @param array $args The arguments will passed to $method. - * @return mixed return value of $method. - */ - public static function __callstatic($method, $args) - { - // static method calls are called on the default instance - return call_user_func_array(array(static::instance(), $method), $args); - } - - // -------------------------------------------------------------------- - - /** - * generate a URI safe base64 encoded string - * - * @param string $value - * @return string - */ - protected static function safe_b64encode($value) - { - $data = base64_encode($value); - $data = str_replace(array('+', '/', '='), array('-', '_', ''), $data); - return $data; - } - - /** - * decode a URI safe base64 encoded string - * - * @param string $value - * @return string - */ - protected static function safe_b64decode($value) - { - $data = str_replace(array('-', '_'), array('+', '/'), $value); - $mod4 = strlen($data) % 4; - if ($mod4) - { - $data .= substr('====', $mod4); - } - return base64_decode($data); - } - - /** - * compare two strings in a timing-insensitive way to prevent time-based attacks - * - * @param string $a - * @param string $b - * @return bool - */ - protected static function secure_compare($a, $b) - { - // make sure we're only comparing equal length strings - if (strlen($a) !== strlen($b)) - { - return false; - } - - // and that all comparisons take equal time - $result = 0; - for ($i = 0; $i < strlen($a); $i++) - { - $result |= ord($a[$i]) ^ ord($b[$i]); - } - return $result === 0; - } - - // -------------------------------------------------------------------- - - /** - * Crypto object used to encrypt/decrypt - * - * @var object - */ - protected $crypter = null; - - /** - * Hash object used to generate hashes - * - * @var object - */ - protected $hasher = null; - - /** - * Crypto configuration - * - * @var array - */ - protected $config = array(); - - /** - * Class constructor - * - * @param array $config - */ - public function __construct(array $config = array()) - { - $this->config = array_merge(static::$defaults, $config); - - $this->crypter = new AES(); - $this->hasher = new Hash('sha256'); - - $this->crypter->enableContinuousBuffer(); - $this->hasher->setKey(static::safe_b64decode($this->config['crypto_hmac'])); - } - - /** - * encrypt a string value, optionally with a custom key - * - * @param string $value value to encrypt - * @param string|bool $key optional custom key to be used for this encryption - * @param int|bool $keylength optional key length - * @return string encrypted value - */ - protected function encode($value, $key = false, $keylength = false) - { - if ( ! $key) - { - $key = static::safe_b64decode($this->config['crypto_key']); - // Used for backwards compatibility with encrypted data prior - // to FuelPHP 1.7.2, when phpseclib was updated, and became a - // bit smarter about figuring out key lengths. - $keylength = 128; - } - - if ($keylength) - { - $this->crypter->setKeyLength($keylength); - } - - $this->crypter->setKey($key); - $this->crypter->setIV(static::safe_b64decode($this->config['crypto_iv'])); - - $value = $this->crypter->encrypt($value); - return static::safe_b64encode($this->add_hmac($value)); - - } - - /** - * capture calls to normal methods - * - * @param mixed $method - * @param array $args The arguments will passed to $method. - * @return mixed return value of $method. - * @throws \ErrorException - */ - public function __call($method, $args) - { - // validate the method called - if ( ! in_array($method, array('encode', 'decode'))) - { - throw new \ErrorException('Call to undefined method '.__CLASS__.'::'.$method.'()', E_ERROR, 0, __FILE__, __LINE__); - } - - // static method calls are called on the default instance - return call_user_func_array(array($this, $method), $args); - } - - /** - * decrypt a string value, optionally with a custom key - * - * @param string $value value to decrypt - * @param string|bool $key optional custom key to be used for this encryption - * @param int|bool $keylength optional key length - * @access public - * @return string encrypted value - */ - protected function decode($value, $key = false, $keylength = false) - { - if ( ! $key) - { - $key = static::safe_b64decode($this->config['crypto_key']); - // Used for backwards compatibility with encrypted data prior - // to FuelPHP 1.7.2, when phpseclib was updated, and became a - // bit smarter about figuring out key lengths. - $keylength = 128; - } - - if ($keylength) - { - $this->crypter->setKeyLength($keylength); - } - - $this->crypter->setKey($key); - $this->crypter->setIV(static::safe_b64decode($this->config['crypto_iv'])); - - $value = static::safe_b64decode($value); - if ($value = $this->validate_hmac($value)) - { - return $this->crypter->decrypt($value); - } - else - { - return false; - } - } - - protected function add_hmac($value) - { - // calculate the hmac-sha256 hash of this value - $hmac = static::safe_b64encode($this->hasher->hash($value)); - - // append it and return the hmac protected string - return $value.$hmac; - } - - protected function validate_hmac($value) - { - // strip the hmac-sha256 hash from the value - $hmac = substr($value, strlen($value)-43); - - // and remove it from the value - $value = substr($value, 0, strlen($value)-43); - - // only return the value if it wasn't tampered with - return (static::secure_compare(static::safe_b64encode($this->hasher->hash($value)), $hmac)) ? $value : false; - } - -} diff --git a/fuel/core/classes/database/connection.php b/fuel/core/classes/database/connection.php deleted file mode 100755 index ed98941..0000000 --- a/fuel/core/classes/database/connection.php +++ /dev/null @@ -1,1004 +0,0 @@ -_instance = $name; - - // Store the config locally - $this->_config = $config; - - // Set up a generic schema processor if needed - if ( ! $this->_schema) - { - $this->_schema = new \Database_Schema($name, $this); - } - - // Store the database instance - static::$instances[$name] = $this; - } - - /** - * Disconnect from the database when the object is destroyed. - * - * // Destroy the database instance - * unset(static::instances[(string) $db], $db); - * - * [!!] Calling `unset($db)` is not enough to destroy the database, as it - * will still be stored in `static::$instances`. - * - * @return void - */ - final public function __destruct() - { - $this->disconnect(); - } - - /** - * Returns the database instance name. - * - * echo (string) $db; - * - * @return string - */ - final public function __toString() - { - return $this->_instance; - } - - /** - * Connect to the database. This is called automatically when the first - * query is executed. - * - * $db->connect(); - * - * @throws Database_Exception - * @return void - */ - abstract public function connect(); - - /** - * Disconnect from the database. This is called automatically by [static::__destruct]. - * - * $db->disconnect(); - * - * @return boolean - */ - abstract public function disconnect(); - - /** - * Set the connection character set. This is called automatically by [static::connect]. - * - * $db->set_charset('utf8'); - * - * @throws Database_Exception - * @param string $charset character set name - * @return void - */ - abstract public function set_charset($charset); - - /** - * Perform an SQL query of the given type. - * - * // Make a SELECT query and use objects for results - * $db->query(static::SELECT, 'SELECT * FROM groups', true); - * - * // Make a SELECT query and use "Model_User" for the results - * $db->query(static::SELECT, 'SELECT * FROM users LIMIT 1', 'Model_User'); - * - * @param integer $type static::SELECT, static::INSERT, etc - * @param string $sql SQL query - * @param mixed $as_object result object class, true for stdClass, false for assoc array - * - * @return object Database_Result for SELECT queries - * @return array list (insert id, row count) for INSERT queries - * @return integer number of affected rows for all other queries - */ - abstract public function query($type, $sql, $as_object); - - /** - * Create a new [Database_Query_Builder_Select]. Each argument will be - * treated as a column. To generate a `foo AS bar` alias, use an array. - * - * // SELECT id, username - * $query = $db->select('id', 'username'); - * - * // SELECT id AS user_id - * $query = $db->select(array('id', 'user_id')); - * - * @param mixed column name or array($column, $alias) or object - * @param ... - * @return Database_Query_Builder_Select - */ - public function select(array $args = null) - { - return new \Database_Query_Builder_Select($args); - } - - /** - * Create a new [Database_Query_Builder_Insert]. - * - * // INSERT INTO users (id, username) - * $query = $db->insert('users', array('id', 'username')); - * - * @param string table to insert into - * @param array list of column names or array($column, $alias) or object - * @return Database_Query_Builder_Insert - */ - public function insert($table = null, array $columns = null) - { - return new \Database_Query_Builder_Insert($table, $columns); - } - - /** - * Create a new [Database_Query_Builder_Update]. - * - * // UPDATE users - * $query = $db->update('users'); - * - * @param string table to update - * @return Database_Query_Builder_Update - */ - public function update($table = null) - { - return new \Database_Query_Builder_Update($table); - } - - /** - * Create a new [Database_Query_Builder_Delete]. - * - * // DELETE FROM users - * $query = $db->delete('users'); - * - * @param string table to delete from - * @return Database_Query_Builder_Delete - */ - public function delete($table = null) - { - return new \Database_Query_Builder_Delete($table); - } - - /** - * Database schema operations - * - * // CREATE DATABASE database CHARACTER SET utf-8 DEFAULT utf-8 - * $query = $db->schema('create_database', array('database', 'utf-8')); - - * @param string table to delete from - * @return Database_Query_Builder_Delete - */ - public function schema($operation, array $params = array()) - { - return call_user_func_array(array($this->_schema, $operation), $params); - } - - /** - * Count the number of records in the last query, without LIMIT or OFFSET applied. - * - * // Get the total number of records that match the last query - * $count = $db->count_last_query(); - * - * @return integer - */ - public function count_last_query() - { - if ($sql = $this->last_query) - { - $sql = trim($sql); - if (stripos($sql, 'SELECT') !== 0) - { - return false; - } - - if (stripos($sql, 'LIMIT') !== false) - { - // Remove LIMIT from the SQL - $sql = preg_replace('/\sLIMIT\s+[^a-z\)]+/i', ' ', $sql); - } - - if (stripos($sql, 'OFFSET') !== false) - { - // Remove OFFSET from the SQL - $sql = preg_replace('/\sOFFSET\s+\d+/i', '', $sql); - } - - if (stripos($sql, 'ORDER BY') !== false) - { - // Remove ORDER BY clauses from the SQL to improve count query performance - $sql = preg_replace('/ ORDER BY [^,\s)]*(\s|)*(?:ASC|DESC)?(?:\s*(?:ASC|DESC)?,\s*(?:ASC|DESC)?[^,\s)]+\s*(?:ASC|DESC))*/', '', $sql); - } - - // Get the total rows from the last query executed - $result = $this->query( - \DB::SELECT, - 'SELECT COUNT(*) AS '.$this->quote_identifier('total_rows').' '. - 'FROM ('.$sql.') AS '.$this->quote_table('counted_results'), - true - ); - - // Return the total number of rows from the query - return (int) $result->current()->total_rows; - } - - return false; - } - - /** - * Per connection cache controller setter/getter - * - * @param bool $bool whether to enable it [optional] - * - * @return mixed cache boolean when getting, current instance when setting. - */ - public function caching($bool = null) - { - if (is_bool($bool)) - { - $this->_config['enable_cache'] = $bool; - return $this; - } - return \Arr::get($this->_config, 'enable_cache', true); - } - - /** - * Count the number of records in a table. - * - * // Get the total number of records in the "users" table - * $count = $db->count_records('users'); - * - * @param mixed $table table name string or array(query, alias) - * - * @return integer - */ - public function count_records($table) - { - // Quote the table name - $table = $this->quote_table($table); - - return $this->query(\DB::SELECT, 'SELECT COUNT(*) AS total_row_count FROM '.$table, false) - ->get('total_row_count'); - } - - /** - * Returns a normalized array describing the SQL data type - * - * $db->datatype('char'); - * - * @param string $type SQL data type - * - * @return array - */ - public function datatype($type) - { - static $types = array( - // SQL-92 - 'bit' => array('type' => 'string', 'exact' => true), - 'bit varying' => array('type' => 'string'), - 'char' => array('type' => 'string', 'exact' => true), - 'char varying' => array('type' => 'string'), - 'character' => array('type' => 'string', 'exact' => true), - 'character varying' => array('type' => 'string'), - 'date' => array('type' => 'string'), - 'dec' => array('type' => 'float', 'exact' => true), - 'decimal' => array('type' => 'float', 'exact' => true), - 'double precision' => array('type' => 'float'), - 'float' => array('type' => 'float'), - 'int' => array('type' => 'int', 'min' => '-2147483648', 'max' => '2147483647'), - 'integer' => array('type' => 'int', 'min' => '-2147483648', 'max' => '2147483647'), - 'interval' => array('type' => 'string'), - 'national char' => array('type' => 'string', 'exact' => true), - 'national char varying' => array('type' => 'string'), - 'national character' => array('type' => 'string', 'exact' => true), - 'national character varying' => array('type' => 'string'), - 'nchar' => array('type' => 'string', 'exact' => true), - 'nchar varying' => array('type' => 'string'), - 'numeric' => array('type' => 'float', 'exact' => true), - 'real' => array('type' => 'float'), - 'smallint' => array('type' => 'int', 'min' => '-32768', 'max' => '32767'), - 'time' => array('type' => 'string'), - 'time with time zone' => array('type' => 'string'), - 'timestamp' => array('type' => 'string'), - 'timestamp with time zone' => array('type' => 'string'), - 'varchar' => array('type' => 'string'), - - // SQL:1999 - 'binary large object' => array('type' => 'string', 'binary' => true), - 'blob' => array('type' => 'string', 'binary' => true), - 'boolean' => array('type' => 'bool'), - 'char large object' => array('type' => 'string'), - 'character large object' => array('type' => 'string'), - 'clob' => array('type' => 'string'), - 'national character large object' => array('type' => 'string'), - 'nchar large object' => array('type' => 'string'), - 'nclob' => array('type' => 'string'), - 'time without time zone' => array('type' => 'string'), - 'timestamp without time zone' => array('type' => 'string'), - - // SQL:2003 - 'bigint' => array('type' => 'int', 'min' => '-9223372036854775808', 'max' => '9223372036854775807'), - - // SQL:2008 - 'binary' => array('type' => 'string', 'binary' => true, 'exact' => true), - 'binary varying' => array('type' => 'string', 'binary' => true), - 'varbinary' => array('type' => 'string', 'binary' => true), - ); - - if (isset($types[$type])) - { - return $types[$type]; - } - - return array(); - } - - /** - * List all of the tables in the database. Optionally, a LIKE string can - * be used to search for specific tables. - * - * // Get all tables in the current database - * $tables = $db->list_tables(); - * - * // Get all user-related tables - * $tables = $db->list_tables('user%'); - * - * @param string $like table to search for - * - * @return array - */ - abstract public function list_tables($like = null); - - /** - * Lists all of the columns in a table. Optionally, a LIKE string can be - * used to search for specific fields. - * - * // Get all columns from the "users" table - * $columns = $db->list_columns('users'); - * - * // Get all name-related columns - * $columns = $db->list_columns('users', '%name%'); - * - * @param string $table table to get columns from - * @param string $like column to search for - * - * @return array - */ - abstract public function list_columns($table, $like = null); - - /** - * Extracts the text between parentheses, if any. - * - * // Returns: array('CHAR', '6') - * list($type, $length) = $db->_parse_type('CHAR(6)'); - * - * @param string $type - * - * @return array list containing the type and length, if any - */ - protected function _parse_type($type) - { - if (($open = strpos($type, '(')) === false) - { - // No length specified - return array($type, null); - } - - // Closing parenthesis - $close = strpos($type, ')', $open); - - // Length without parentheses - $length = substr($type, $open + 1, $close - 1 - $open); - - // Type without the length - $type = substr($type, 0, $open).substr($type, $close + 1); - - return array($type, $length); - } - - /** - * Return the table prefix defined in the current configuration. - * - * $prefix = $db->table_prefix(); - * - * @param string $table - * - * @return string - */ - public function table_prefix($table = null) - { - if ($table !== null) - { - return $this->_config['table_prefix'] .$table; - } - - return $this->_config['table_prefix']; - } - - /** - * Quote a value for an SQL query. - * - * $db->quote(null); // 'null' - * $db->quote(10); // 10 - * $db->quote('fred'); // 'fred' - * - * Objects passed to this function will be converted to strings. - * [Database_Expression] objects will use the value of the expression. - * [Database_Query] objects will be compiled and converted to a sub-query. - * All other objects will be converted using the `__toString` method. - * - * @param mixed $value any value to quote - * - * @return string - * - * @uses static::escape - */ - public function quote($value) - { - if ($value === null) - { - return 'null'; - } - elseif ($value === true) - { - return "'1'"; - } - elseif ($value === false) - { - return "'0'"; - } - elseif (is_object($value)) - { - if ($value instanceof Database_Query) - { - // Create a sub-query - return '('.$value->compile($this).')'; - } - elseif ($value instanceof Database_Expression) - { - // Use a raw expression - return $value->value(); - } - else - { - // Convert the object to a string - return $this->quote((string) $value); - } - } - elseif (is_array($value)) - { - return '('.implode(', ', array_map(array($this, __FUNCTION__), $value)).')'; - } - elseif (is_int($value)) - { - return (int) $value; - } - elseif (is_float($value)) - { - // Convert to non-locale aware float to prevent possible commas - return sprintf('%F', $value); - } - - return $this->escape($value); - } - - /** - * Quote a database table name and adds the table prefix if needed. - * - * $table = $db->quote_table($table); - * - * @param mixed $value table name or array(table, alias) - * - * @return string - * - * @uses static::quote_identifier - * @uses static::table_prefix - */ - public function quote_table($value) - { - // Assign the table by reference from the value - if (is_array($value)) - { - $table =& $value[0]; - - // Attach table prefix to alias - $value[1] = $this->table_prefix().$value[1]; - } - else - { - $table =& $value; - } - - // deal with the sub-query objects first - if ($table instanceof Database_Query) - { - // Create a sub-query - $table = '('.$table->compile($this).')'; - } - elseif (is_string($table)) - { - if (strpos($table, '.') === false) - { - // Add the table prefix for tables - $table = $this->quote_identifier($this->table_prefix().$table); - } - else - { - // Split the identifier into the individual parts - $parts = explode('.', $table); - - if ($prefix = $this->table_prefix()) - { - // Get the offset of the table name, 2nd-to-last part - // This works for databases that can have 3 identifiers (Postgre) - if (($offset = count($parts)) == 2) - { - $offset = 1; - } - else - { - $offset = $offset - 2; - } - - // Add the table prefix to the table name - $parts[$offset] = $prefix.$parts[$offset]; - } - - // Quote each of the parts - $table = implode('.', array_map(array($this, 'quote_identifier'), $parts)); - } - } - - // process the alias if present - if (is_array($value)) - { - // Separate the column and alias - list($value, $alias) = $value; - - return $value.' AS '.$this->quote_identifier($alias); - } - else - { - // return the value - return $value; - } - } - - /** - * Quote a database identifier, such as a column name. Adds the - * table prefix to the identifier if a table name is present. - * - * $column = $db->quote_identifier($column); - * - * You can also use SQL methods within identifiers. - * - * // The value of "column" will be quoted - * $column = $db->quote_identifier('COUNT("column")'); - * - * Objects passed to this function will be converted to strings. - * [Database_Expression] objects will use the value of the expression. - * [Database_Query] objects will be compiled and converted to a sub-query. - * All other objects will be converted using the `__toString` method. - * - * @param mixed $value any identifier - * - * @return string - * - * @uses static::table_prefix - */ - public function quote_identifier($value) - { - if ($value === '*') - { - return $value; - } - elseif (is_object($value)) - { - if ($value instanceof Database_Query) - { - // Create a sub-query - return '('.$value->compile($this).')'; - } - elseif ($value instanceof Database_Expression) - { - // Use a raw expression - return $value->value(); - } - else - { - // Convert the object to a string - return $this->quote_identifier((string) $value); - } - } - elseif (is_array($value)) - { - // Separate the column and alias - list($value, $alias) = $value; - - return $this->quote_identifier($value).' AS '.$this->quote_identifier($alias); - } - - if (preg_match('/^(["\']).*\1$/m', $value)) - { - return $value; - } - - if (strpos($value, '.') !== false) - { - // Split the identifier into the individual parts - // This is slightly broken, because a table or column name - // (or user-defined alias!) might legitimately contain a period. - $parts = explode('.', $value); - - if ($prefix = $this->table_prefix()) - { - // Get the offset of the table name, 2nd-to-last part - // This works for databases that can have 3 identifiers (Postgre) - $offset = count($parts) - 2; - - // Add the table prefix to the table name - $parts[$offset] = $prefix.$parts[$offset]; - } - - // Quote each of the parts - return implode('.', array_map(array($this, __FUNCTION__), $parts)); - } - - // That you can simply escape the identifier by doubling - // it is a built-in assumption which may not be valid for - // all connection types! However, it's true for MySQL, - // SQLite, Postgres and other ANSI SQL-compliant DBs. - return $this->_identifier.str_replace($this->_identifier, $this->_identifier.$this->_identifier, $value).$this->_identifier; - } - - /** - * Sanitize a string by escaping characters that could cause an SQL - * injection attack. - * - * $value = $db->escape('any string'); - * - * @param string $value value to quote - * - * @return string - */ - abstract public function escape($value); - - /** - * Whether or not the connection is in transaction mode - * - * $db->in_transaction(); - * - * @return bool - */ - public function in_transaction() - { - return $this->_in_transaction; - } - - /** - * Begins a nested transaction on instance - * - * $db->start_transaction(); - * - * @return bool - */ - public function start_transaction() - { - $result = true; - - if ($this->_transaction_depth == 0) - { - if ($this->driver_start_transaction()) - { - $this->_in_transaction = true; - } - else - { - $result = false; - } - } - else - { - $result = $this->set_savepoint($this->_transaction_depth); - // If savepoint is not supported it is not an error - isset($result) or $result = true; - } - - $result and $this->_transaction_depth ++; - - return $result; - } - - /** - * Commits nested transaction - * - * $db->commit_transaction(); - * - * @return bool - */ - public function commit_transaction() - { - // Fake call of the commit - if ($this->_transaction_depth <= 0) - { - return false; - } - - if ($this->_transaction_depth - 1) - { - $result = $this->release_savepoint($this->_transaction_depth - 1); - // If savepoint is not supported it is not an error - ! isset($result) and $result = true; - } - else - { - $this->_in_transaction = false; - $result = $this->driver_commit(); - } - - $result and $this->_transaction_depth --; - - return $result; - } - - /** - * Rollsback nested pending transaction queries. - * Rollback to the current level uses SAVEPOINT, - * it does not work if current RDBMS does not support them. - * In this case system rollbacks all queries and closes the transaction - * - * $db->rollback_transaction(); - * - * @param bool $rollback_all: - * true - rollback everything and close transaction; - * false - rollback only current level - * - * @return bool - */ - public function rollback_transaction($rollback_all = true) - { - if ($this->_transaction_depth > 0) - { - if($rollback_all or $this->_transaction_depth == 1) - { - if($result = $this->driver_rollback()) - { - $this->_transaction_depth = 0; - $this->_in_transaction = false; - } - } - else - { - $result = $this->rollback_savepoint($this->_transaction_depth - 1); - // If savepoint is not supported it is not an error - isset($result) or $result = true; - - $result and $this->_transaction_depth -- ; - } - } - else - { - $result = false; - } - - return $result; - } - - /** - * Begins a transaction on the driver level - * - * @return bool - */ - abstract protected function driver_start_transaction(); - - /** - * Commits all pending transactional queries on the driver level - * - * @return bool - */ - abstract protected function driver_commit(); - - /** - * Rollback all pending transactional queries on the driver level - * - * @return bool - */ - abstract protected function driver_rollback(); - - /** - * Sets savepoint of the transaction - * - * @param string $name name of the savepoint - * @return boolean true - savepoint was set successfully; - * false - failed to set savepoint; - * null - RDBMS does not support savepoints - */ - protected function set_savepoint($name) - { - return null; - } - - /** - * Release savepoint of the transaction - * - * @param string $name name of the savepoint - * @return boolean true - savepoint was set successfully; - * false - failed to set savepoint; - * null - RDBMS does not support savepoints - */ - protected function release_savepoint($name) - { - return null; - } - - /** - * Rollback savepoint of the transaction - * - * @param string $name name of the savepoint - * @return boolean true - savepoint was set successfully; - * false - failed to set savepoint; - * null - RDBMS does not support savepoints - */ - protected function rollback_savepoint($name) - { - return null; - } - - /** - * Returns the raw connection object for custom method access - * - * $db->connection()->lastInsertId('id'); - * - * @return resource - */ - public function connection() - { - // Make sure the database is connected - $this->_connection or $this->connect(); - return $this->_connection; - } - - /** - * Returns whether or not we have a valid database connection object - * - * $db->has_connection() - * - * @return bool - */ - public function has_connection() - { - // return the status of the connection - return $this->_connection ? true : false; - } -} diff --git a/fuel/core/classes/database/dblib/connection.php b/fuel/core/classes/database/dblib/connection.php deleted file mode 100755 index 4898ba1..0000000 --- a/fuel/core/classes/database/dblib/connection.php +++ /dev/null @@ -1,154 +0,0 @@ -quote($like); - } - - // Find all table names - $result = $this->query(\DB::SELECT, $query, false); - - $tables = array(); - foreach ($result as $row) - { - $tables[] = reset($row); - } - - return $tables; - } - - /** - * List table columns - * - * @param string $table table name - * @param string $like column name pattern - * @return array array of column structure - */ - public function list_columns($table, $like = null) - { - $query = "SELECT * FROM Sys.Columns WHERE id = object_id('" . $this->quote_table($table) . "')"; - - if (is_string($like)) - { - // Search for column names - $query .= " AND name LIKE ".$this->quote($like); - } - - // Find all column names - $result = $this->query(\DB::SELECT, $query, false); - - $count = 0; - $columns = array(); - foreach ($result as $row) - { - list($type, $length) = $this->_parse_type($row['Type']); - $column = $this->datatype($type); - $column['name'] = $row['Field']; - $column['default'] = $row['Default']; - $column['data_type'] = $type; - $column['null'] = ($row['Null'] == 'YES'); - $column['ordinal_position'] = ++$count; - switch ($column['type']) - { - case 'float': - if (isset($length)) - { - list($column['numeric_precision'], $column['numeric_scale']) = explode(',', $length); - } - break; - case 'int': - if (isset($length)) - { - $column['display'] = $length; - } - break; - case 'string': - switch ($column['data_type']) - { - case 'binary': - case 'varbinary': - $column['character_maximum_length'] = $length; - break; - case 'char': - case 'varchar': - $column['character_maximum_length'] = $length; - case 'text': - case 'tinytext': - case 'mediumtext': - case 'longtext': - $column['collation_name'] = $row['Collation']; - break; - case 'enum': - case 'set': - $column['collation_name'] = $row['Collation']; - $column['options'] = explode('\',\'', substr($length, 1, -1)); - break; - } - break; - } - $column['comment'] = $row['Comment']; - $column['extra'] = $row['Extra']; - $column['key'] = $row['Key']; - $column['privileges'] = $row['Privileges']; - $columns[$row['Field']] = $column; - } - return $columns; - } - - /** - * Set the charset - * - * @param string $charset - */ - public function set_charset($charset) - { - // does not support charsets - } - -} diff --git a/fuel/core/classes/database/exception.php b/fuel/core/classes/database/exception.php deleted file mode 100755 index a06e12e..0000000 --- a/fuel/core/classes/database/exception.php +++ /dev/null @@ -1,16 +0,0 @@ -_value = $value; - } - - /** - * Get the expression value as a string. - * - * $sql = $expression->value(); - * - * @return string - */ - public function value() - { - return (string) $this->_value; - } - - /** - * Return the value of the expression as a string. - * - * echo $expression; - * - * @return string - * @uses Database_Expression::value - */ - public function __toString() - { - return $this->value(); - } - -} diff --git a/fuel/core/classes/database/mysql/connection.php b/fuel/core/classes/database/mysql/connection.php deleted file mode 100755 index 085acf0..0000000 --- a/fuel/core/classes/database/mysql/connection.php +++ /dev/null @@ -1,70 +0,0 @@ -quote($like); - } - - $q = $this->_connection->prepare($query); - $q->execute(); - $result = $q->fetchAll(); - - $tables = array(); - foreach ($result as $row) - { - $tables[] = reset($row); - } - - return $tables; - } - /** - * Create a new PDO instance - * - * @return PDO - */ - protected function _connect() - { - // enable compression if needed - if ($this->_config['connection']['compress']) - { - // use client compression with mysql or mysqli (doesn't work with mysqlnd) - $this->_config['attrs'][\PDO::MYSQL_ATTR_COMPRESS] = true; - } - - // add the charset to the DSN if needed - if ($this->_config['charset'] and strpos($this->_config['connection']['dsn'], ';charset=') === false) - { - $config['dsn'] .= ';charset='.$this->_config['charset']; - } - - // create the PDO instance - parent::_connect(); - } - -} diff --git a/fuel/core/classes/database/mysqli/connection.php b/fuel/core/classes/database/mysqli/connection.php deleted file mode 100755 index c9f1565..0000000 --- a/fuel/core/classes/database/mysqli/connection.php +++ /dev/null @@ -1,582 +0,0 @@ -_connection) - { - return; - } - - if (static::$_set_names === null) - { - // Determine if we can use mysqli_set_charset(), which is only - // available on PHP 5.2.3+ when compiled against MySQL 5.0+ - static::$_set_names = ! function_exists('mysqli_set_charset'); - } - - // Extract the connection parameters, adding required variables - extract($this->_config['connection'] + array( - 'database' => '', - 'hostname' => '', - 'port' => '', - 'socket' => '', - 'username' => '', - 'password' => '', - 'persistent' => false, - 'compress' => true, - )); - - try - { - if ($socket != '') - { - $port = null; - } - elseif ($port != '') - { - $socket = null; - } - else - { - $socket = null; - $port = null; - } - if ($persistent) - { - // Create a persistent connection - if ($compress) - { - $mysqli = mysqli_init(); - $mysqli->real_connect('p:'.$hostname, $username, $password, $database, $port, $socket, MYSQLI_CLIENT_COMPRESS); - - $this->_connection = $mysqli; - } - else - { - $this->_connection = new \MySQLi('p:'.$hostname, $username, $password, $database, $port, $socket); - } - } - else - { - // Create a connection and force it to be a new link - if ($compress) - { - $mysqli = mysqli_init(); - $mysqli->real_connect($hostname, $username, $password, $database, $port, $socket, MYSQLI_CLIENT_COMPRESS); - - $this->_connection = $mysqli; - } - else - { - $this->_connection = new \MySQLi($hostname, $username, $password, $database, $port, $socket); - } - } - if ($this->_connection->error) - { - // Unable to connect, select database, etc - throw new \Database_Exception(str_replace($password, str_repeat('*', 10), $this->_connection->error), $this->_connection->errno); - } - } - catch (\ErrorException $e) - { - // No connection exists - $this->_connection = null; - - $error_code = is_numeric($e->getCode()) ? $e->getCode() : 0; - throw new \Database_Exception(str_replace($password, str_repeat('*', 10), $e->getMessage()), $error_code, $e); - } - - // \xFF is a better delimiter, but the PHP driver uses underscore - $this->_connection_id = sha1($hostname.'_'.$username.'_'.$password); - - if ( ! empty($this->_config['charset'])) - { - // Set the character set - $this->set_charset($this->_config['charset']); - } - - static::$_current_databases[$this->_connection_id] = $database; - } - - /** - * Select the database - * - * @param string Database - * @return void - */ - protected function _select_db($database) - { - if ($this->_config['connection']['database'] !== static::$_current_databases[$this->_connection_id]) - { - if ($this->_connection->select_db($database) !== true) - { - // Unable to select database - throw new \Database_Exception($this->_connection->error, $this->_connection->errno); - } - } - - static::$_current_databases[$this->_connection_id] = $database; - } - - /** - * Disconnect from the database - * - * @throws \Exception when the mysql database is not disconnected properly - */ - public function disconnect() - { - try - { - // Database is assumed disconnected - $status = true; - - if ($this->_connection instanceof \MySQLi) - { - if ($status = $this->_connection->close()) - { - // clear the connection - $this->_connection = null; - - // and reset the savepoint depth - $this->_transaction_depth = 0; - } - - } - } - catch (\Exception $e) - { - // Database is probably not disconnected - $status = ! ($this->_connection instanceof \MySQLi); - } - - return $status; - } - - public function set_charset($charset) - { - // Make sure the database is connected - $this->_connection or $this->connect(); - $status = $this->_connection->set_charset($charset); - - if ($status === false) - { - throw new \Database_Exception($this->_connection->error, $this->_connection->errno); - } - } - - /** - * Execute query - * - * @param integer $type query type (\DB::SELECT, \DB::INSERT, etc.) - * @param string $sql SQL string - * @param mixed $as_object used when query type is SELECT - * - * @throws \Database_Exception - * - * @return mixed when SELECT then return an iterator of results,
- * when UPDATE then return a list of insert id and rows created,
- * in other case return the number of rows affected - */ - public function query($type, $sql, $as_object) - { - // Make sure the database is connected - if ($this->_connection) - { - // Make sure the connection is still alive - if ( ! $this->_connection->ping()) - { - throw new \Database_Exception($this->_connection->error.' [ '.$sql.' ]', $this->_connection->errno); - } - } - else - { - $this->connect(); - } - - if ( ! empty($this->_config['profiling'])) - { - // Get the paths defined in config - $paths = \Config::get('profiling_paths'); - - // Storage for the trace information - $stacktrace = array(); - - // Get the execution trace of this query - $include = false; - foreach (debug_backtrace() as $index => $page) - { - // Skip first entry and entries without a filename - if ($index > 0 and empty($page['file']) === false) - { - // Checks to see what paths you want backtrace - foreach($paths as $index => $path) - { - if (strpos($page['file'], $path) !== false) - { - $include = true; - break; - } - } - - // Only log if no paths we defined, or we have a path match - if ($include or empty($paths)) - { - $stacktrace[] = array('file' => \Fuel::clean_path($page['file']), 'line' => $page['line']); - } - } - } - - $benchmark = \Profiler::start($this->_instance, $sql, $stacktrace); - } - - if ( ! empty($this->_config['connection']['persistent']) and $this->_config['connection']['database'] !== static::$_current_databases[$this->_connection_id]) - { - // Select database on persistent connections - $this->_select_db($this->_config['connection']['database']); - } - - // Execute the query - if (($result = $this->_connection->query($sql)) === false) - { - if (isset($benchmark)) - { - // This benchmark is worthless - \Profiler::delete($benchmark); - } - - throw new \Database_Exception($this->_connection->error.' [ '.$sql.' ]', $this->_connection->errno); - } - - // check for multiresults, we don't support those at the moment - while($this->_connection->more_results() and $this->_connection->next_result()) - { - if ($more_result = $this->_connection->use_result()) - { - throw new \Database_Exception('The MySQLi driver does not support multiple resultsets', 0); - } - } - - if (isset($benchmark)) - { - \Profiler::stop($benchmark); - } - - // Set the last query - $this->last_query = $sql; - - if ($type === \DB::SELECT) - { - // Return an iterator of results - return new \Database_MySQLi_Result($result, $sql, $as_object); - } - elseif ($type === \DB::INSERT) - { - // Return a list of insert id and rows created - return array( - $this->_connection->insert_id, - $this->_connection->affected_rows, - ); - } - elseif ($type === \DB::UPDATE or $type === \DB::DELETE) - { - // Return the number of rows affected - return $this->_connection->affected_rows; - } - - return $result; - } - - public function datatype($type) - { - static $types = array( - 'blob' => array('type' => 'string', 'binary' => true, 'character_maximum_length' => '65535'), - 'bool' => array('type' => 'bool'), - 'bigint unsigned' => array('type' => 'int', 'min' => '0', 'max' => '18446744073709551615'), - 'datetime' => array('type' => 'string'), - 'decimal unsigned' => array('type' => 'float', 'exact' => true, 'min' => '0'), - 'double' => array('type' => 'float'), - 'double precision unsigned' => array('type' => 'float', 'min' => '0'), - 'double unsigned' => array('type' => 'float', 'min' => '0'), - 'enum' => array('type' => 'string'), - 'fixed' => array('type' => 'float', 'exact' => true), - 'fixed unsigned' => array('type' => 'float', 'exact' => true, 'min' => '0'), - 'float unsigned' => array('type' => 'float', 'min' => '0'), - 'int unsigned' => array('type' => 'int', 'min' => '0', 'max' => '4294967295'), - 'integer unsigned' => array('type' => 'int', 'min' => '0', 'max' => '4294967295'), - 'longblob' => array('type' => 'string', 'binary' => true, 'character_maximum_length' => '4294967295'), - 'longtext' => array('type' => 'string', 'character_maximum_length' => '4294967295'), - 'mediumblob' => array('type' => 'string', 'binary' => true, 'character_maximum_length' => '16777215'), - 'mediumint' => array('type' => 'int', 'min' => '-8388608', 'max' => '8388607'), - 'mediumint unsigned' => array('type' => 'int', 'min' => '0', 'max' => '16777215'), - 'mediumtext' => array('type' => 'string', 'character_maximum_length' => '16777215'), - 'national varchar' => array('type' => 'string'), - 'numeric unsigned' => array('type' => 'float', 'exact' => true, 'min' => '0'), - 'nvarchar' => array('type' => 'string'), - 'point' => array('type' => 'string', 'binary' => true), - 'real unsigned' => array('type' => 'float', 'min' => '0'), - 'set' => array('type' => 'string'), - 'smallint unsigned' => array('type' => 'int', 'min' => '0', 'max' => '65535'), - 'text' => array('type' => 'string', 'character_maximum_length' => '65535'), - 'tinyblob' => array('type' => 'string', 'binary' => true, 'character_maximum_length' => '255'), - 'tinyint' => array('type' => 'int', 'min' => '-128', 'max' => '127'), - 'tinyint unsigned' => array('type' => 'int', 'min' => '0', 'max' => '255'), - 'tinytext' => array('type' => 'string', 'character_maximum_length' => '255'), - 'varchar' => array('type' => 'string', 'exact' => true), - 'year' => array('type' => 'string'), - ); - - $type = str_replace(' zerofill', '', $type); - - if (isset($types[$type])) - { - return $types[$type]; - } - - return parent::datatype($type); - } - - /** - * List tables - * - * @param string $like pattern of table name - * @return array array of table names - */ - public function list_tables($like = null) - { - if (is_string($like)) - { - // Search for table names - $result = $this->query(\DB::SELECT, 'SHOW TABLES LIKE '.$this->quote($like), false); - } - else - { - // Find all table names - $result = $this->query(\DB::SELECT, 'SHOW TABLES', false); - } - - $tables = array(); - foreach ($result as $row) - { - $tables[] = reset($row); - } - - return $tables; - } - - /** - * List table columns - * - * @param string $table table name - * @param string $like column name pattern - * @return array array of column structure - */ - public function list_columns($table, $like = null) - { - // Quote the table name - $table = $this->quote_table($table); - - if (is_string($like)) - { - // Search for column names - $result = $this->query(\DB::SELECT, 'SHOW FULL COLUMNS FROM '.$table.' LIKE '.$this->quote($like), false); - } - else - { - // Find all column names - $result = $this->query(\DB::SELECT, 'SHOW FULL COLUMNS FROM '.$table, false); - } - - $count = 0; - $columns = array(); - foreach ($result as $row) - { - list($type, $length) = $this->_parse_type($row['Type']); - - $column = $this->datatype($type); - - $column['name'] = $row['Field']; - $column['default'] = $row['Default']; - $column['data_type'] = $type; - $column['null'] = ($row['Null'] == 'YES'); - $column['ordinal_position'] = ++$count; - - switch ($column['type']) - { - case 'float': - if (isset($length)) - { - list($column['numeric_precision'], $column['numeric_scale']) = explode(',', $length); - } - break; - case 'int': - if (isset($length)) - { - // MySQL attribute - $column['display'] = $length; - } - break; - case 'string': - switch ($column['data_type']) - { - case 'binary': - case 'varbinary': - $column['character_maximum_length'] = $length; - break; - - case 'char': - case 'varchar': - $column['character_maximum_length'] = $length; - case 'text': - case 'tinytext': - case 'mediumtext': - case 'longtext': - $column['collation_name'] = $row['Collation']; - break; - - case 'enum': - case 'set': - $column['collation_name'] = $row['Collation']; - $column['options'] = explode('\',\'', substr($length, 1, -1)); - break; - } - break; - } - - // MySQL attributes - $column['comment'] = $row['Comment']; - $column['extra'] = $row['Extra']; - $column['key'] = $row['Key']; - $column['privileges'] = $row['Privileges']; - - $columns[$row['Field']] = $column; - } - - return $columns; - } - - /** - * Escape query for sql - * - * @param mixed $value value of string castable - * @return string escaped sql string - */ - public function escape($value) - { - // Make sure the database is connected - $this->_connection or $this->connect(); - - if (($value = $this->_connection->real_escape_string((string) $value)) === false) - { - throw new \Database_Exception($this->_connection->error, $this->_connection->errno); - } - - // SQL standard is to use single-quotes for all values - return "'$value'"; - } - - public function error_info() - { - $errno = $this->_connection->errno; - return array($errno, empty($errno) ? null : $errno, empty($errno) ? null : $this->_connection->error); - } - - protected function driver_start_transaction() - { - $this->query(0, 'START TRANSACTION', false); - return true; - } - - protected function driver_commit() - { - $this->query(0, 'COMMIT', false); - return true; - } - - protected function driver_rollback() - { - $this->query(0, 'ROLLBACK', false); - return true; - } - - /** - * Sets savepoint of the transaction - * - * @param string $name name of the savepoint - * @return boolean true - savepoint was set successfully; - * false - failed to set savepoint; - */ - protected function set_savepoint($name) { - $this->query(0, 'SAVEPOINT LEVEL'.$name, false); - return true; - } - - /** - * Release savepoint of the transaction - * - * @param string $name name of the savepoint - * @return boolean true - savepoint was set successfully; - * false - failed to set savepoint; - */ - protected function release_savepoint($name) { - $this->query(0, 'RELEASE SAVEPOINT LEVEL'.$name, false); - return true; - } - - /** - * Rollback savepoint of the transaction - * - * @param string $name name of the savepoint - * @return boolean true - savepoint was set successfully; - * false - failed to set savepoint; - */ - protected function rollback_savepoint($name) { - $this->query(0, 'ROLLBACK TO SAVEPOINT LEVEL'.$name, false); - return true; - } - -} diff --git a/fuel/core/classes/database/mysqli/result.php b/fuel/core/classes/database/mysqli/result.php deleted file mode 100755 index 5eb8aed..0000000 --- a/fuel/core/classes/database/mysqli/result.php +++ /dev/null @@ -1,79 +0,0 @@ -_total_rows = $result->num_rows; - } - - public function __destruct() - { - if ($this->_result instanceof \MySQLi_Result) - { - $this->_result->free(); - } - } - - public function seek($offset) - { - if ($this->offsetExists($offset) and $this->_result->data_seek($offset)) - { - // Set the current row to the offset - $this->_current_row = $this->_internal_row = $offset; - - return true; - } - else - { - return false; - } - } - - public function current() - { - if ($this->_current_row !== $this->_internal_row and ! $this->seek($this->_current_row)) - { - return false; - } - - // Increment internal row for optimization assuming rows are fetched in order - $this->_internal_row++; - - if ($this->_as_object === true) - { - // Return an stdClass - return $this->_result->fetch_object(); - } - elseif (is_string($this->_as_object)) - { - // Return an object of given class name - //! TODO: add the $params parameter - return $this->_result->fetch_object($this->_as_object); - } - else - { - // Return an array of the row - return $this->_result->fetch_assoc(); - } - } - -} diff --git a/fuel/core/classes/database/pdo/connection.php b/fuel/core/classes/database/pdo/connection.php deleted file mode 100755 index 3c3e51b..0000000 --- a/fuel/core/classes/database/pdo/connection.php +++ /dev/null @@ -1,562 +0,0 @@ -_schema = new \Database_Drivername_Schema($name, $this); - - // call the parent consructor - parent::__construct($name, $config); - - if (isset($config['identifier'])) - { - // Allow the identifier to be overloaded per-connection - $this->_identifier = (string) $this->_config['identifier']; - } - } - - /** - * Connects to the database - * - * @throws \Database_Exception - */ - public function connect() - { - if ($this->_connection) - { - return; - } - - // make sure we have all connection parameters - $this->_config = array_merge(array( - 'connection' => array( - 'dsn' => '', - 'hostname' => '', - 'username' => null, - 'password' => null, - 'database' => '', - 'persistent' => false, - 'compress' => false, - ), - 'identifier' => '`', - 'table_prefix' => '', - 'charset' => 'utf8', - 'collation' => false, - 'enable_cache' => true, - 'profiling' => false, - 'readonly' => false, - 'attrs' => array(), - ), $this->_config); - - // Force PDO to use exceptions for all errors - $this->_config['attrs'] = array( - \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION - ); - - if ( ! empty($this->_config['connection']['persistent'])) - { - // Make the connection persistent - $this->_config['attrs'][\PDO::ATTR_PERSISTENT] = true; - } - - try - { - // Create a new PDO connection - $this->_connect(); - } - catch (\PDOException $e) - { - // and convert the exception in a database exception - if ( ! is_numeric($error_code = $e->getCode())) - { - if ($this->_connection) - { - $error_code = $this->_connection->errorinfo(); - $error_code = $error_code[1]; - } - else - { - $error_code = 0; - } - } - throw new \Database_Exception(str_replace($this->_config['connection']['password'], str_repeat('*', 10), $e->getMessage()), $error_code, $e); - } - } - - /** - * @return bool - */ - public function disconnect() - { - // destroy the PDO object - $this->_connection = null; - - // and reset the savepoint depth - $this->_transaction_depth = 0; - - return true; - } - - /** - * Get the current PDO Driver name - * - * @return string - */ - public function driver_name() - { - // Make sure the database is connected - $this->_connection or $this->connect(); - - // Getting driver name - return $this->_connection->getAttribute(\PDO::ATTR_DRIVER_NAME); - } - - /** - * Set the charset - * - * @param string $charset - */ - public function set_charset($charset) - { - // Make sure the database is connected - $this->_connection or $this->connect(); - - if ($charset) - { - $this->_connection->exec('SET NAMES '.$this->quote($charset)); - } - } - - /** - * Query the database - * - * @param integer $type - * @param string $sql - * @param mixed $as_object - * - * @return mixed - * - * @throws \Database_Exception - */ - public function query($type, $sql, $as_object) - { - // Make sure the database is connected - $this->_connection or $this->connect(); - - if ( ! empty($this->_config['profiling'])) - { - // Get the paths defined in config - $paths = \Config::get('profiling_paths'); - - // Storage for the trace information - $stacktrace = array(); - - // Get the execution trace of this query - $include = false; - foreach (debug_backtrace() as $index => $page) - { - // Skip first entry and entries without a filename - if ($index > 0 and empty($page['file']) === false) - { - // Checks to see what paths you want backtrace - foreach($paths as $index => $path) - { - if (strpos($page['file'], $path) !== false) - { - $include = true; - break; - } - } - - // Only log if no paths we defined, or we have a path match - if ($include or empty($paths)) - { - $stacktrace[] = array('file' => \Fuel::clean_path($page['file']), 'line' => $page['line']); - } - } - } - - $benchmark = \Profiler::start($this->_instance, $sql, $stacktrace); - } - - // run the query. if the connection is lost, try 3 times to reconnect - $attempts = 3; - - do - { - try - { - // try to run the query - $result = $this->_connection->query($sql); - break; - } - catch (\Exception $e) - { - // if failed and we have attempts left - if ($attempts > 0) - { - // try reconnecting if it was a MySQL disconnected error - if (strpos($e->getMessage(), '2006 MySQL') !== false) - { - $this->disconnect(); - $this->connect(); - } - else - { - // other database error, cleanup the profiler - isset($benchmark) and \Profiler::delete($benchmark); - - // and convert the exception in a database exception - if ( ! is_numeric($error_code = $e->getCode())) - { - if ($this->_connection) - { - $error_code = $this->_connection->errorinfo(); - $error_code = $error_code[1]; - } - else - { - $error_code = 0; - } - } - - throw new \Database_Exception($e->getMessage().' with query: "'.$sql.'"', $error_code, $e); - } - } - - // no more attempts left, bail out - else - { - // and convert the exception in a database exception - if ( ! is_numeric($error_code = $e->getCode())) - { - if ($this->_connection) - { - $error_code = $this->_connection->errorinfo(); - $error_code = $error_code[1]; - } - else - { - $error_code = 0; - } - } - throw new \Database_Exception($e->getMessage().' with query: "'.$sql.'"', $error_code, $e); - } - } - } - while ($attempts-- > 0); - - if (isset($benchmark)) - { - \Profiler::stop($benchmark); - } - - // Set the last query - $this->last_query = $sql; - - if ($type === \DB::SELECT) - { - // Convert the result into an array, as PDOStatement::rowCount is not reliable - if ($as_object === false) - { - $result = $result->fetchAll(\PDO::FETCH_ASSOC); - } - elseif (is_string($as_object)) - { - $result = $result->fetchAll(\PDO::FETCH_CLASS, $as_object); - } - else - { - $result = $result->fetchAll(\PDO::FETCH_CLASS, 'stdClass'); - } - - // Return an iterator of results - return new \Database_Result_Cached($result, $sql, $as_object); - } - elseif ($type === \DB::INSERT) - { - // Return a list of insert id and rows created - return array( - $this->_connection->lastInsertId(), - $result->rowCount(), - ); - } - elseif ($type === \DB::UPDATE or $type === \DB::DELETE) - { - // Return the number of rows affected - return $result->errorCode() === '00000' ? $result->rowCount() : -1; - } - - return $result->errorCode() === '00000' ? true : false; - } - - /** - * List tables - * - * @param string $like - * - * @throws \FuelException - */ - public function list_tables($like = null) - { - throw new \FuelException('Database method '.__METHOD__.' is not supported by '.__CLASS__); - } - - /** - * List table columns - * - * @param string $table - * @param string $like - * - * @return array - */ - public function list_columns($table, $like = null) - { - $this->_connection or $this->connect(); - $q = $this->_connection->prepare("DESCRIBE ".$table); - $q->execute(); - $result = $q->fetchAll(); - $count = 0; - $columns = array(); - ! is_null($like) and $like = str_replace('%', '.*', $like); - foreach ($result as $row) - { - if ( ! is_null($like) and ! preg_match('#'.$like.'#', $row['Field'])) - { - continue; - } - list($type, $length) = $this->_parse_type($row['Type']); - - $column = $this->datatype($type); - - $column['name'] = $row['Field']; - $column['default'] = $row['Default']; - $column['data_type'] = $type; - $column['null'] = ($row['Null'] == 'YES'); - $column['ordinal_position'] = ++$count; - switch ($column['type']) - { - case 'float': - if (isset($length)) - { - list($column['numeric_precision'], $column['numeric_scale']) = explode(',', $length); - } - break; - case 'int': - if (isset($length)) - { - // MySQL attribute - $column['display'] = $length; - } - break; - case 'string': - switch ($column['data_type']) - { - case 'binary': - case 'varbinary': - $column['character_maximum_length'] = $length; - break; - - case 'char': - case 'varchar': - $column['character_maximum_length'] = $length; - case 'text': - case 'tinytext': - case 'mediumtext': - case 'longtext': - $column['collation_name'] = isset($row['Collation']) ? $row['Collation'] : null; - break; - - case 'enum': - case 'set': - $column['collation_name'] = isset($row['Collation']) ? $row['Collation'] : null; - $column['options'] = explode('\',\'', substr($length, 1, - 1)); - break; - } - break; - } - - // MySQL attributes - $column['comment'] = isset($row['Comment']) ? $row['Comment'] : null; - $column['extra'] = $row['Extra']; - $column['key'] = $row['Key']; - $column['privileges'] = isset($row['Privileges']) ? $row['Privileges'] : null; - - $columns[$row['Field']] = $column; - } - - return $columns; - } - - /** - * Resolve a datatype - * - * @param integer $type - * - * @return array - */ - public function datatype($type) - { - // try to determine the datatype - $datatype = parent::datatype($type); - - // if not an ANSI database, assume it's string - return empty($datatype) ? array('type' => 'string') : $datatype; - } - - /** - * Escape a value - * - * @param mixed $value - * - * @return string - */ - public function escape($value) - { - // Make sure the database is connected - $this->_connection or $this->connect(); - - $result = $this->_connection->quote($value); - - // poor-mans workaround for the fact that not all drivers implement quote() - if (empty($result)) - { - if ( ! is_numeric($value)) - { - $result = "'".str_replace("'", "''", $value)."'"; - } - } - return $result; - } - - /** - * Retrieve error info - * - * @return array - */ - public function error_info() - { - return $this->_connection->errorInfo(); - } - - /** - * Create a new PDO instance - * - * @return PDO - */ - protected function _connect() - { - $this->_connection = new \PDO( - $this->_config['connection']['dsn'], - $this->_config['connection']['username'], - $this->_config['connection']['password'], - $this->_config['attrs'] - ); - - // set the DB charset if needed - $this->set_charset($this->_config['charset']); - } - - /** - * Start a transaction - * - * @return bool - */ - protected function driver_start_transaction() - { - $this->_connection or $this->connect(); - return $this->_connection->beginTransaction(); - } - - /** - * Commit a transaction - * - * @return bool - */ - protected function driver_commit() - { - return $this->_connection->commit(); - } - - /** - * Rollback a transaction - * @return bool - */ - protected function driver_rollback() - { - return $this->_connection->rollBack(); - } - - /** - * Sets savepoint of the transaction - * - * @param string $name name of the savepoint - * @return boolean true - savepoint was set successfully; - * false - failed to set savepoint; - * null - RDBMS does not support savepoints - */ - protected function set_savepoint($name) - { - $result = $this->_connection->exec('SAVEPOINT '.$name); - return $result !== false; - } - - /** - * Release savepoint of the transaction - * - * @param string $name name of the savepoint - * @return boolean true - savepoint was set successfully; - * false - failed to set savepoint; - * null - RDBMS does not support savepoints - */ - protected function release_savepoint($name) - { - $result = $this->_connection->exec('RELEASE SAVEPOINT '.$name); - return $result !== false; - } - - /** - * Rollback savepoint of the transaction - * - * @param string $name name of the savepoint - * @return boolean true - savepoint was set successfully; - * false - failed to set savepoint; - * null - RDBMS does not support savepoints - */ - protected function rollback_savepoint($name) - { - $result = $this->_connection->exec('ROLLBACK TO SAVEPOINT '.$name); - return $result !== false; - } - -} diff --git a/fuel/core/classes/database/query.php b/fuel/core/classes/database/query.php deleted file mode 100755 index b4de52a..0000000 --- a/fuel/core/classes/database/query.php +++ /dev/null @@ -1,325 +0,0 @@ -_type = $type; - $this->_sql = $sql; - } - - /** - * Return the SQL query string. - * - * @return string - */ - final public function __toString() - { - try - { - // Return the SQL string - return $this->compile(); - } - catch (\Exception $e) - { - return $e->getMessage(); - } - } - - /** - * Get the type of the query. - * - * @return integer - */ - public function type() - { - return $this->_type; - } - - /** - * Enables the query to be cached for a specified amount of time. - * - * @param integer $lifetime number of seconds to cache or null for default - * @param string $cache_key name of the cache key to be used or null for default - * @param boolean $cache_all if true, cache all results, even empty ones - * - * @return $this - */ - public function cached($lifetime = null, $cache_key = null, $cache_all = true) - { - $this->_lifetime = $lifetime; - $this->_cache_all = (bool) $cache_all; - is_string($cache_key) and $this->_cache_key = $cache_key; - - return $this; - } - - /** - * Returns results as associative arrays - * - * @return $this - */ - public function as_assoc() - { - $this->_as_object = false; - - return $this; - } - - /** - * Returns results as objects - * - * @param mixed $class classname or true for stdClass - * - * @return $this - */ - public function as_object($class = true) - { - $this->_as_object = $class; - - return $this; - } - - /** - * Set the value of a parameter in the query. - * - * @param string $param parameter key to replace - * @param mixed $value value to use - * - * @return $this - */ - public function param($param, $value) - { - // Add or overload a new parameter - $this->_parameters[$param] = $value; - - return $this; - } - - /** - * Bind a variable to a parameter in the query. - * - * @param string $param parameter key to replace - * @param mixed $var variable to use - * - * @return $this - */ - public function bind($param, & $var) - { - // Bind a value to a variable - $this->_parameters[$param] =& $var; - - return $this; - } - - /** - * Add multiple parameters to the query. - * - * @param array $params list of parameters - * - * @return $this - */ - public function parameters(array $params) - { - // Merge the new parameters in - $this->_parameters = $params + $this->_parameters; - - return $this; - } - - /** - * Set a DB connection to use when compiling the SQL - * - * @param mixed $db - * - * @return $this - */ - public function set_connection($db) - { - if ( ! $db instanceof \Database_Connection) - { - // Get the database instance - $db = \Database_Connection::instance($db); - } - $this->_connection = $db; - - return $this; - } - - /** - * Compile the SQL query and return it. Replaces any parameters with their - * given values. - * - * @param mixed $db Database instance or instance name - * - * @return string - */ - public function compile($db = null) - { - if ($this->_connection !== null and $db === null) - { - $db = $this->_connection; - } - - if ( ! $db instanceof \Database_Connection) - { - // Get the database instance - $db = $this->_connection ?: \Database_Connection::instance($db); - } - - // Import the SQL locally - $sql = $this->_sql; - - if ( ! empty($this->_parameters)) - { - // Quote all of the values - $values = array_map(array($db, 'quote'), $this->_parameters); - - // Replace the values in the SQL - $sql = \Str::tr($sql, $values); - } - - return trim($sql); - } - - /** - * Execute the current query on the given database. - * - * @param mixed $db Database instance or name of instance - * - * @return object Database_Result for SELECT queries - * @return mixed the insert id for INSERT queries - * @return integer number of affected rows for all other queries - */ - public function execute($db = null) - { - if ($this->_connection !== null and $db === null) - { - $db = $this->_connection; - } - - if ( ! is_object($db)) - { - // Get the database instance. If this query is a instance of - // Database_Query_Builder_Select then use the slave connection if configured - $db = \Database_Connection::instance($db, null, ! $this instanceof \Database_Query_Builder_Select); - } - - // Compile the SQL query - $sql = $this->compile($db); - - // make sure we have a SQL type to work with - if (is_null($this->_type)) - { - // get the SQL statement type without having to duplicate the entire statement - $stmt = preg_split("/[\s]+/", substr($sql, 0, 10), 2); - switch(strtoupper(reset($stmt))) - { - case 'DESCRIBE': - case 'EXECUTE': - case 'EXPLAIN': - case 'SELECT': - case 'SHOW': - $this->_type = \DB::SELECT; - break; - case 'INSERT': - case 'REPLACE': - $this->_type = \DB::INSERT; - break; - case 'UPDATE': - $this->_type = \DB::UPDATE; - break; - case 'DELETE': - $this->_type = \DB::DELETE; - break; - default: - $this->_type = 0; - } - } - - if ($db->caching() and ! empty($this->_lifetime) and $this->_type === \DB::SELECT) - { - $cache_key = empty($this->_cache_key) ? - 'db.'.md5('Database_Connection::query("'.$db.'", "'.$sql.'")') : $this->_cache_key; - $cache = \Cache::forge($cache_key); - try - { - $result = $cache->get(); - return new \Database_Result_Cached($result, $sql, $this->_as_object); - } - catch (\CacheNotFoundException $e) {} - } - - // Execute the query - \DB::$query_count++; - $result = $db->query($this->_type, $sql, $this->_as_object); - - // Cache the result if needed - if (isset($cache) and ($this->_cache_all or $result->count())) - { - $cache->set_expiration($this->_lifetime)->set_contents($result->as_array())->set(); - } - - return $result; - } - -} diff --git a/fuel/core/classes/database/query/builder.php b/fuel/core/classes/database/query/builder.php deleted file mode 100755 index 8d1302e..0000000 --- a/fuel/core/classes/database/query/builder.php +++ /dev/null @@ -1,217 +0,0 @@ -compile($db); - } - - return implode(' ', $statements); - } - - /** - * Compiles an array of conditions into an SQL partial. Used for WHERE - * and HAVING. - * - * @param object $db Database instance - * @param array $conditions condition statements - * - * @return string - */ - protected function _compile_conditions(\Database_Connection$db, array $conditions) - { - $last_condition = NULL; - - $sql = ''; - foreach ($conditions as $group) - { - // Process groups of conditions - foreach ($group as $logic => $condition) - { - if ($condition === '(') - { - if ( ! empty($sql) AND $last_condition !== '(') - { - // Include logic operator - $sql .= ' '.$logic.' '; - } - - $sql .= '('; - } - elseif ($condition === ')') - { - $sql .= ')'; - } - else - { - if ( ! empty($sql) AND $last_condition !== '(') - { - // Add the logic operator - $sql .= ' '.$logic.' '; - } - - // Split the condition - list($column, $op, $value) = $condition; - - // Support DB::expr() as where clause - if ($column instanceOf Database_Expression and $op === null and $value === null) - { - $sql .= (string) $column; - } - else - { - if ($value === NULL) - { - if ($op === '=') - { - // Convert "val = NULL" to "val IS NULL" - $op = 'IS'; - } - elseif ($op === '!=') - { - // Convert "val != NULL" to "valu IS NOT NULL" - $op = 'IS NOT'; - } - } - - // Database operators are always uppercase - $op = strtoupper($op); - - if (($op === 'BETWEEN' OR $op === 'NOT BETWEEN') AND is_array($value)) - { - // BETWEEN always has exactly two arguments - list($min, $max) = $value; - - if (is_string($min) AND array_key_exists($min, $this->_parameters)) - { - // Set the parameter as the minimum - $min = $this->_parameters[$min]; - } - - if (is_string($max) AND array_key_exists($max, $this->_parameters)) - { - // Set the parameter as the maximum - $max = $this->_parameters[$max]; - } - - // Quote the min and max value - $value = $db->quote($min).' AND '.$db->quote($max); - } - else - { - if (is_string($value) AND array_key_exists($value, $this->_parameters)) - { - // Set the parameter as the value - $value = $this->_parameters[$value]; - } - - // Quote the entire value normally - $value = $db->quote($value); - } - - // Append the statement to the query - $sql .= $db->quote_identifier($column).' '.$op.' '.$value; - } - } - - $last_condition = $condition; - } - } - - return $sql; - } - - /** - * Compiles an array of set values into an SQL partial. Used for UPDATE. - * - * @param object $db Database instance - * @param array $values updated values - * - * @return string - */ - protected function _compile_set(\Database_Connection$db, array $values) - { - $set = array(); - foreach ($values as $group) - { - // Split the set - list($column, $value) = $group; - - // Quote the column name - $column = $db->quote_identifier($column); - - if (is_string($value) AND array_key_exists($value, $this->_parameters)) - { - // Use the parameter value - $value = $this->_parameters[$value]; - } - - $set[$column] = $column.' = '.$db->quote($value); - } - - return implode(', ', $set); - } - - /** - * Compiles an array of ORDER BY statements into an SQL partial. - * - * @param object $db Database instance - * @param array $columns sorting columns - * - * @return string - */ - protected function _compile_order_by(\Database_Connection $db, array $columns) - { - $sort = array(); - - foreach ($columns as $group) - { - list($column, $direction) = $group; - - $direction = strtoupper($direction); - if ( ! empty($direction)) - { - // Make the direction uppercase - $direction = ' '.($direction == 'ASC' ? 'ASC' : 'DESC'); - } - - $sort[] = $db->quote_identifier($column).$direction; - } - - return 'ORDER BY '.implode(', ', $sort); - } - - /** - * Reset the current builder status. - * - * @return $this - */ - abstract public function reset(); -} diff --git a/fuel/core/classes/database/query/builder/delete.php b/fuel/core/classes/database/query/builder/delete.php deleted file mode 100755 index 3b88bd2..0000000 --- a/fuel/core/classes/database/query/builder/delete.php +++ /dev/null @@ -1,109 +0,0 @@ -_table = $table; - } - - // Start the query with no SQL - parent::__construct('', \DB::DELETE); - } - - /** - * Sets the table to delete from. - * - * @param mixed $table table name or array($table, $alias) or object - * - * @return $this - */ - public function table($table) - { - $this->_table = $table; - - return $this; - } - - /** - * Compile the SQL query and return it. - * - * @param mixed $db Database_Connection instance or instance name - * - * @return string - */ - public function compile($db = null) - { - if ( ! $db instanceof \Database_Connection) - { - // Get the database instance - $db = \Database_Connection::instance($db); - } - - // Start a deletion query - $query = 'DELETE FROM '.$db->quote_table($this->_table); - - if ( ! empty($this->_where)) - { - // Add deletion conditions - $query .= ' WHERE '.$this->_compile_conditions($db, $this->_where); - } - - if ( ! empty($this->_order_by)) - { - // Add sorting - $query .= ' '.$this->_compile_order_by($db, $this->_order_by); - } - - if ($this->_limit !== null) - { - // Add limiting - $query .= ' LIMIT '.$this->_limit; - } - - return $query; - } - - /** - * Reset the query parameters - * - * @return $this - */ - public function reset() - { - $this->_table = NULL; - - $this->_where = array(); - $this->_order_by = array(); - - $this->_parameters = array(); - - $this->_limit = NULL; - - return $this; - } -} diff --git a/fuel/core/classes/database/query/builder/insert.php b/fuel/core/classes/database/query/builder/insert.php deleted file mode 100755 index 525ea0e..0000000 --- a/fuel/core/classes/database/query/builder/insert.php +++ /dev/null @@ -1,219 +0,0 @@ -_table = $table; - } - - if ($columns) - { - // Set the column names - $this->_columns = $columns; - } - - // Start the query with no SQL - parent::__construct('', \DB::INSERT); - } - - /** - * Sets the table to insert into. - * - * @param mixed $table table name or array($table, $alias) or object - * @return $this - */ - public function table($table) - { - $this->_table = $table; - - return $this; - } - - /** - * Set the columns that will be inserted. - * - * @param array $columns column names - * @return $this - */ - public function columns(array $columns) - { - $this->_columns = array_merge($this->_columns, $columns); - - return $this; - } - - /** - * Adds values. Multiple value sets can be added. - * - * @throws \FuelException - * @param array $values - * @return $this - */ - public function values(array $values) - { - if ( ! is_array($this->_values)) - { - throw new \FuelException('INSERT INTO ... SELECT statements cannot be combined with INSERT INTO ... VALUES'); - } - - // Get all of the passed values - $values = func_get_args(); - - // And process them - foreach ($values as $value) - { - if (is_array(reset($value))) - { - $this->_values = array_merge($this->_values, $value); - } - else - { - $this->_values[] = $value; - } - } - - return $this; - } - - /** - * This is a wrapper function for calling columns() and values(). - * - * @param array $pairs column value pairs - * - * @return $this - */ - public function set(array $pairs) - { - $this->columns(array_keys($pairs)); - $this->values($pairs); - - return $this; - } - - /** - * Use a sub-query to for the inserted values. - * - * @param Database_Query $query Database_Query of SELECT type - * - * @return $this - * - * @throws \FuelException - */ - public function select(Database_Query $query) - { - if ($query->type() !== \DB::SELECT) - { - throw new \FuelException('Only SELECT queries can be combined with INSERT queries'); - } - - $this->_values = $query; - - return $this; - } - - /** - * Compile the SQL query and return it. - * - * @param mixed $db Database instance or instance name - * - * @return string - */ - public function compile($db = null) - { - if ( ! $db instanceof \Database_Connection) - { - // Get the database instance - $db = \Database_Connection::instance($db); - } - - // Start an insertion query - $query = 'INSERT INTO '.$db->quote_table($this->_table); - - // Add the column names - $query .= ' ('.implode(', ', array_map(array($db, 'quote_identifier'), $this->_columns)).') '; - - if (is_array($this->_values)) - { - // Callback for quoting values - $quote = array($db, 'quote'); - - $groups = array(); - foreach ($this->_values as $group) - { - foreach ($group as $i => $value) - { - if (is_string($value) AND isset($this->_parameters[$value])) - { - // Use the parameter value - $group[$i] = $this->_parameters[$value]; - } - } - - $groups[] = '('.implode(', ', array_map($quote, $group)).')'; - } - - // Add the values - $query .= 'VALUES '.implode(', ', $groups); - } - else - { - // Add the sub-query - $query .= (string) $this->_values; - } - - return $query; - } - - /** - * Reset the query parameters - * - * @return $this - */ - public function reset() - { - $this->_table = null; - $this->_columns = array(); - $this->_values = array(); - $this->_parameters = array(); - - return $this; - } -} diff --git a/fuel/core/classes/database/query/builder/join.php b/fuel/core/classes/database/query/builder/join.php deleted file mode 100755 index 8a963f9..0000000 --- a/fuel/core/classes/database/query/builder/join.php +++ /dev/null @@ -1,165 +0,0 @@ -_table = $table; - - if ($type !== null) - { - // Set the JOIN type - $this->_type = (string) $type; - } - } - - /** - * Adds a new OR condition for joining. - * - * @param mixed $c1 column name or array($column, $alias) or object - * @param string $op logic operator - * @param mixed $c2 column name or array($column, $alias) or object - * - * @return $this - */ - public function or_on($c1, $op, $c2) - { - $this->_on[] = array($c1, $op, $c2, 'OR'); - - return $this; - } - - /** - * Adds a new AND condition for joining. - * - * @param mixed $c1 column name or array($column, $alias) or object - * @param string $op logic operator - * @param mixed $c2 column name or array($column, $alias) or object - * - * @return $this - */ - public function on($c1, $op, $c2) - { - $this->_on[] = array($c1, $op, $c2, 'AND'); - - return $this; - } - - /** - * Adds a new AND condition for joining. - * - * @param mixed $c1 column name or array($column, $alias) or object - * @param string $op logic operator - * @param mixed $c2 column name or array($column, $alias) or object - * - * @return $this - */ - public function and_on($c1, $op, $c2) - { - return $this->on($c1, $op, $c2); - } - - /** - * Compile the SQL partial for a JOIN statement and return it. - * - * @param mixed $db Database_Connection instance or instance name - * - * @return string - */ - public function compile($db = null) - { - if ( ! $db instanceof \Database_Connection) - { - // Get the database instance - $db = \Database_Connection::instance($db); - } - - if ($this->_type) - { - $sql = strtoupper($this->_type).' JOIN'; - } - else - { - $sql = 'JOIN'; - } - - // Quote the table name that is being joined - $sql .= ' '.$db->quote_table($this->_table); - - $conditions = array(); - - foreach ($this->_on as $condition) - { - // Split the condition - list($c1, $op, $c2, $chaining) = $condition; - - // Add chain type - $conditions[] = ' '.$chaining.' '; - - if ($op) - { - // Make the operator uppercase and spaced - $op = ' '.strtoupper($op); - } - - // Quote each of the identifiers used for the condition - $conditions[] = $db->quote_identifier($c1).$op.' '.(is_null($c2) ? 'NULL' : $db->quote_identifier($c2)); - } - - // remove the first chain type - array_shift($conditions); - - // if there are conditions, concat the conditions "... AND ..." and glue them on... - empty($conditions) or $sql .= ' ON ('.implode('', $conditions).')'; - - return $sql; - } - - /** - * Resets the join values. - * - * @return $this - */ - public function reset() - { - $this->_type = - $this->_table = NULL; - $this->_on = array(); - } -} diff --git a/fuel/core/classes/database/query/builder/select.php b/fuel/core/classes/database/query/builder/select.php deleted file mode 100755 index cb37ded..0000000 --- a/fuel/core/classes/database/query/builder/select.php +++ /dev/null @@ -1,502 +0,0 @@ -_select = $columns; - } - - // Start the query with no actual SQL statement - parent::__construct('', \DB::SELECT); - } - - /** - * Enables or disables selecting only unique columns using "SELECT DISTINCT" - * - * @param boolean $value enable or disable distinct columns - * @return $this - */ - public function distinct($value = true) - { - $this->_distinct = (bool) $value; - - return $this; - } - - /** - * Choose the columns to select from. - * - * @param mixed $columns column name or array($column, $alias) or object - * @param ... - * - * @return $this - */ - public function select($columns = null) - { - $columns = func_get_args(); - - $this->_select = array_merge($this->_select, $columns); - - return $this; - } - - /** - * Choose the columns to select from, using an array. - * - * @param array $columns list of column names or aliases - * @param bool $reset if true, don't merge but overwrite - * - * @return $this - */ - public function select_array(array $columns, $reset = false) - { - $this->_select = $reset ? $columns : array_merge($this->_select, $columns); - - return $this; - } - - /** - * Choose the tables to select "FROM ..." - * - * @param mixed $tables table name or array($table, $alias) - * @param ... - * - * @return $this - */ - public function from($tables) - { - $tables = func_get_args(); - - $this->_from = array_merge($this->_from, $tables); - - return $this; - } - - /** - * Adds addition tables to "JOIN ...". - * - * @param mixed $table column name or array($column, $alias) - * @param string $type join type (LEFT, RIGHT, INNER, etc) - * - * @return $this - */ - public function join($table, $type = NULL) - { - $this->_join[] = $this->_last_join = new \Database_Query_Builder_Join($table, $type); - - return $this; - } - - /** - * Adds "ON ..." conditions for the last created JOIN statement. - * - * @param mixed $c1 column name or array($column, $alias) or object - * @param string $op logic operator - * @param mixed $c2 column name or array($column, $alias) or object - * - * @return $this - */ - public function on($c1, $op, $c2) - { - $this->_last_join->on($c1, $op, $c2); - - return $this; - } - - /** - * Adds "AND ON ..." conditions for the last created JOIN statement. - * - * @param mixed $c1 column name or array($column, $alias) or object - * @param string $op logic operator - * @param mixed $c2 column name or array($column, $alias) or object - * - * @return $this - */ - public function and_on($c1, $op, $c2) - { - $this->_last_join->and_on($c1, $op, $c2); - - return $this; - } - - /** - * Adds "OR ON ..." conditions for the last created JOIN statement. - * - * @param mixed $c1 column name or array($column, $alias) or object - * @param string $op logic operator - * @param mixed $c2 column name or array($column, $alias) or object - * - * @return $this - */ - public function or_on($c1, $op, $c2) - { - $this->_last_join->or_on($c1, $op, $c2); - - return $this; - } - - /** - * Creates a "GROUP BY ..." filter. - * - * @param mixed $columns column name or array($column, $column) or object - * @param ... - * - * @return $this - */ - public function group_by($columns) - { - $columns = func_get_args(); - - foreach($columns as $idx => $column) - { - // if an array of columns is passed, flatten it - if (is_array($column)) - { - foreach($column as $c) - { - $columns[] = $c; - } - unset($columns[$idx]); - } - } - - $this->_group_by = array_merge($this->_group_by, $columns); - - return $this; - } - - /** - * Alias of and_having() - * - * @param mixed $column column name or array($column, $alias) or object - * @param string $op logic operator - * @param mixed $value column value - * - * @return $this - */ - public function having($column, $op = null, $value = null) - { - return call_fuel_func_array(array($this, 'and_having'), func_get_args()); - } - - /** - * Creates a new "AND HAVING" condition for the query. - * - * @param mixed $column column name or array($column, $alias) or object - * @param string $op logic operator - * @param mixed $value column value - * - * @return $this - */ - public function and_having($column, $op = null, $value = null) - { - if($column instanceof \Closure) - { - $this->and_having_open(); - $column($this); - $this->and_having_close(); - return $this; - } - - if(func_num_args() === 2) - { - $value = $op; - $op = '='; - } - - $this->_having[] = array('AND' => array($column, $op, $value)); - - return $this; - } - - /** - * Creates a new "OR HAVING" condition for the query. - * - * @param mixed $column column name or array($column, $alias) or object - * @param string $op logic operator - * @param mixed $value column value - * - * @return $this - */ - public function or_having($column, $op = null, $value = null) - { - if($column instanceof \Closure) - { - $this->or_having_open(); - $column($this); - $this->or_having_close(); - return $this; - } - - if(func_num_args() === 2) - { - $value = $op; - $op = '='; - } - - $this->_having[] = array('OR' => array($column, $op, $value)); - - return $this; - } - - /** - * Alias of and_having_open() - * - * @return $this - */ - public function having_open() - { - return $this->and_having_open(); - } - - /** - * Opens a new "AND HAVING (...)" grouping. - * - * @return $this - */ - public function and_having_open() - { - $this->_having[] = array('AND' => '('); - - return $this; - } - - /** - * Opens a new "OR HAVING (...)" grouping. - * - * @return $this - */ - public function or_having_open() - { - $this->_having[] = array('OR' => '('); - - return $this; - } - - /** - * Closes an open "AND HAVING (...)" grouping. - * - * @return $this - */ - public function having_close() - { - return $this->and_having_close(); - } - - /** - * Closes an open "AND HAVING (...)" grouping. - * - * @return $this - */ - public function and_having_close() - { - $this->_having[] = array('AND' => ')'); - - return $this; - } - - /** - * Closes an open "OR HAVING (...)" grouping. - * - * @return $this - */ - public function or_having_close() - { - $this->_having[] = array('OR' => ')'); - - return $this; - } - - /** - * Start returning results after "OFFSET ..." - * - * @param integer $number starting result number - * - * @return $this - */ - public function offset($number) - { - $this->_offset = (int) $number; - - return $this; - } - - /** - * Compile the SQL query and return it. - * - * @param mixed $db Database_Connection instance or instance name - * - * @return string - */ - public function compile($db = null) - { - if ( ! $db instanceof \Database_Connection) - { - // Get the database instance - $db = $this->_connection ?: \Database_Connection::instance($db); - } - - // Callback to quote identifiers - $quote_ident = array($db, 'quote_identifier'); - - // Callback to quote tables - $quote_table = array($db, 'quote_table'); - - // Start a selection query - $query = 'SELECT '; - - if ($this->_distinct === TRUE) - { - // Select only unique results - $query .= 'DISTINCT '; - } - - if (empty($this->_select)) - { - // Select all columns - $query .= '*'; - } - else - { - // Select all columns - $query .= implode(', ', array_unique(array_map($quote_ident, $this->_select))); - } - - if ( ! empty($this->_from)) - { - // Set tables to select from - $query .= ' FROM '.implode(', ', array_unique(array_map($quote_table, $this->_from))); - } - - if ( ! empty($this->_join)) - { - // Add tables to join - $query .= ' '.$this->_compile_join($db, $this->_join); - } - - if ( ! empty($this->_where)) - { - // Add selection conditions - $query .= ' WHERE '.$this->_compile_conditions($db, $this->_where); - } - - if ( ! empty($this->_group_by)) - { - // Add sorting - $query .= ' GROUP BY '.implode(', ', array_map($quote_ident, $this->_group_by)); - } - - if ( ! empty($this->_having)) - { - // Add filtering conditions - $query .= ' HAVING '.$this->_compile_conditions($db, $this->_having); - } - - if ( ! empty($this->_order_by)) - { - // Add sorting - $query .= ' '.$this->_compile_order_by($db, $this->_order_by); - } - - if ($this->_limit !== NULL) - { - // Add limiting - $query .= ' LIMIT '.$this->_limit; - } - - if ($this->_offset !== NULL) - { - // Add offsets - $query .= ' OFFSET '.$this->_offset; - } - - return $query; - } - - /** - * Reset the query parameters - * @return $this - */ - public function reset() - { - $this->_select = array(); - $this->_from = array(); - $this->_join = array(); - $this->_where = array(); - $this->_group_by = array(); - $this->_having = array(); - $this->_order_by = array(); - $this->_distinct = false; - $this->_limit = null; - $this->_offset = null; - $this->_last_join = null; - $this->_parameters = array(); - - return $this; - } - -} diff --git a/fuel/core/classes/database/query/builder/update.php b/fuel/core/classes/database/query/builder/update.php deleted file mode 100755 index 176406d..0000000 --- a/fuel/core/classes/database/query/builder/update.php +++ /dev/null @@ -1,200 +0,0 @@ -_table = $table; - } - - // Start the query with no SQL - parent::__construct('', \DB::UPDATE); - } - - /** - * Sets the table to update. - * - * @param mixed $table table name or array($table, $alias) - * - * @return $this - */ - public function table($table) - { - $this->_table = $table; - - return $this; - } - - /** - * Set the values to update with an associative array. - * - * @param array $pairs associative (column => value) list - * - * @return $this - */ - public function set(array $pairs) - { - foreach ($pairs as $column => $value) - { - $this->_set[] = array($column, $value); - } - - return $this; - } - - /** - * Set the value of a single column. - * - * @param mixed $column table name or array($table, $alias) or object - * @param mixed $value column value - * - * @return $this - */ - public function value($column, $value) - { - $this->_set[] = array($column, $value); - - return $this; - } - - /** - * Compile the SQL query and return it. - * - * @param mixed $db Database instance or instance name - * - * @return string - */ - public function compile($db = null) - { - if ( ! $db instanceof \Database_Connection) - { - // Get the database instance - $db = \Database_Connection::instance($db); - } - - // Start an update query - $query = 'UPDATE '.$db->quote_table($this->_table); - - if ( ! empty($this->_join)) - { - // Add tables to join - $query .= ' '.$this->_compile_join($db, $this->_join); - } - - // Add the columns to update - $query .= ' SET '.$this->_compile_set($db, $this->_set); - - if ( ! empty($this->_where)) - { - // Add selection conditions - $query .= ' WHERE '.$this->_compile_conditions($db, $this->_where); - } - - if ( ! empty($this->_order_by)) - { - // Add sorting - $query .= ' '.$this->_compile_order_by($db, $this->_order_by); - } - - if ($this->_limit !== null) - { - // Add limiting - $query .= ' LIMIT '.$this->_limit; - } - - return $query; - } - - /** - * Reset the query parameters - * - * @return $this - */ - public function reset() - { - $this->_table = null; - $this->_join = array(); - $this->_set = array(); - $this->_where = array(); - $this->_order_by = array(); - $this->_limit = null; - $this->_last_join = null; - $this->_parameters = array(); - - return $this; - } - - /** - * Adds addition tables to "JOIN ...". - * - * @param mixed $table column name or array($column, $alias) or object - * @param string $type join type (LEFT, RIGHT, INNER, etc) - * - * @return $this - */ - public function join($table, $type = null) - { - $this->_join[] = $this->_last_join = new \Database_Query_Builder_Join($table, $type); - - return $this; - } - - /** - * Adds "ON ..." conditions for the last created JOIN statement. - * - * @param mixed $c1 column name or array($column, $alias) or object - * @param string $op logic operator - * @param mixed $c2 column name or array($column, $alias) or object - * - * @return $this - */ - public function on($c1, $op, $c2) - { - $this->_last_join->on($c1, $op, $c2); - - return $this; - } -} diff --git a/fuel/core/classes/database/query/builder/where.php b/fuel/core/classes/database/query/builder/where.php deleted file mode 100755 index 9f266fc..0000000 --- a/fuel/core/classes/database/query/builder/where.php +++ /dev/null @@ -1,230 +0,0 @@ -and_where_open(); - $column($this); - $this->and_where_close(); - return $this; - } - - if (is_array($column)) - { - foreach ($column as $key => $val) - { - if (is_array($val)) - { - $this->and_where($val[0], $val[1], $val[2]); - } - else - { - $this->and_where($key, '=', $val); - } - } - } - else - { - if(func_num_args() === 2) - { - $value = $op; - $op = '='; - } - $this->_where[] = array('AND' => array($column, $op, $value)); - } - - return $this; - } - - /** - * Creates a new "OR WHERE" condition for the query. - * - * @param mixed $column column name or array($column, $alias) or object - * @param string $op logic operator - * @param mixed $value column value - * - * @return $this - */ - public function or_where($column, $op = null, $value = null) - { - if($column instanceof \Closure) - { - $this->or_where_open(); - $column($this); - $this->or_where_close(); - return $this; - } - - if (is_array($column)) - { - foreach ($column as $key => $val) - { - if (is_array($val)) - { - $this->or_where($val[0], $val[1], $val[2]); - } - else - { - $this->or_where($key, '=', $val); - } - } - } - else - { - if(func_num_args() === 2) - { - $value = $op; - $op = '='; - } - $this->_where[] = array('OR' => array($column, $op, $value)); - } - return $this; - } - - /** - * Alias of and_where_open() - * - * @return $this - */ - public function where_open() - { - return $this->and_where_open(); - } - - /** - * Opens a new "AND WHERE (...)" grouping. - * - * @return $this - */ - public function and_where_open() - { - $this->_where[] = array('AND' => '('); - - return $this; - } - - /** - * Opens a new "OR WHERE (...)" grouping. - * - * @return $this - */ - public function or_where_open() - { - $this->_where[] = array('OR' => '('); - - return $this; - } - - /** - * Closes an open "AND WHERE (...)" grouping. - * - * @return $this - */ - public function where_close() - { - return $this->and_where_close(); - } - - /** - * Closes an open "AND WHERE (...)" grouping. - * - * @return $this - */ - public function and_where_close() - { - $this->_where[] = array('AND' => ')'); - - return $this; - } - - /** - * Closes an open "OR WHERE (...)" grouping. - * - * @return $this - */ - public function or_where_close() - { - $this->_where[] = array('OR' => ')'); - - return $this; - } - - /** - * Applies sorting with "ORDER BY ..." - * - * @param mixed $column column name or array($column, $alias) or object - * @param string $direction direction of sorting - * - * @return $this - */ - public function order_by($column, $direction = null) - { - $this->_order_by[] = array($column, $direction); - - return $this; - } - - /** - * Return up to "LIMIT ..." results - * - * @param integer $number maximum results to return - * - * @return $this - */ - public function limit($number) - { - $this->_limit = (int) $number; - - return $this; - } -} diff --git a/fuel/core/classes/database/result.php b/fuel/core/classes/database/result.php deleted file mode 100755 index 86f9aef..0000000 --- a/fuel/core/classes/database/result.php +++ /dev/null @@ -1,417 +0,0 @@ -_result = $result; - - // Store the SQL locally - $this->_query = $sql; - - if (is_object($as_object)) - { - // Get the object class name - $as_object = get_class($as_object); - } - - // Results as objects or associative arrays - $this->_as_object = $as_object; - } - - /** - * Result destruction cleans up all open result sets. - * - * @return void - */ - abstract public function __destruct(); - - /** - * Get a cached database result from the current result iterator. - * - * $cachable = serialize($result->cached()); - * - * @return Database_Result_Cached - * @since 3.0.5 - */ - public function cached() - { - return new \Database_Result_Cached($this->as_array(), $this->_query, $this->_as_object); - } - - /** - * Return all of the rows in the result as an array. - * - * // Indexed array of all rows - * $rows = $result->as_array(); - * - * // Associative array of rows by "id" - * $rows = $result->as_array('id'); - * - * // Associative array of rows, "id" => "name" - * $rows = $result->as_array('id', 'name'); - * - * @param string $key column for associative keys - * @param string $value column for values - * @return array - */ - public function as_array($key = null, $value = null) - { - $results = array(); - - if ($key === null and $value === null) - { - // Indexed rows - - foreach ($this as $row) - { - $results[] = $row; - } - } - elseif ($key === null) - { - // Indexed columns - - if ($this->_as_object) - { - foreach ($this as $row) - { - $results[] = $row->$value; - } - } - else - { - foreach ($this as $row) - { - $results[] = $row[$value]; - } - } - } - elseif ($value === null) - { - // Associative rows - - if ($this->_as_object) - { - foreach ($this as $row) - { - $results[$row->$key] = $row; - } - } - else - { - foreach ($this as $row) - { - $results[$row[$key]] = $row; - } - } - } - else - { - // Associative columns - - if ($this->_as_object) - { - foreach ($this as $row) - { - $results[$row->$key] = $row->$value; - } - } - else - { - foreach ($this as $row) - { - $results[$row[$key]] = $row[$value]; - } - } - } - - $this->rewind(); - - return $results; - } - - /** - * Return the named column from the current row. - * - * // Get the "id" value - * $id = $result->get('id'); - * - * @param string $name column to get - * @param mixed $default default value if the column does not exist - * - * @return mixed - */ - public function get($name, $default = null) - { - $row = $this->current(); - - if ($this->_as_object) - { - if (isset($row->$name)) - { - // sanitize the data if needed - if ( ! $this->_sanitization_enabled) - { - $result = $row->$name; - } - else - { - $result = \Security::clean($row->$name, null, 'security.output_filter'); - } - - return $result; - } - } - else - { - if (isset($row[$name])) - { - // sanitize the data if needed - if ( ! $this->_sanitization_enabled) - { - $result = $row[$name]; - } - else - { - $result = \Security::clean($row[$name], null, 'security.output_filter'); - } - - return $result; - } - } - - return \Fuel::value($default); - } - - /** - * Implements [Countable::count], returns the total number of rows. - * - * echo count($result); - * - * @return integer - */ - public function count() - { - return $this->_total_rows; - } - - /** - * Implements [ArrayAccess::offsetExists], determines if row exists. - * - * if (isset($result[10])) - * { - * // Row 10 exists - * } - * - * @param integer $offset - * - * @return boolean - */ - public function offsetExists($offset) - { - return ($offset >= 0 and $offset < $this->_total_rows); - } - - /** - * Implements [ArrayAccess::offsetGet], gets a given row. - * - * $row = $result[10]; - * - * @param integer $offset - * - * @return mixed - */ - public function offsetGet($offset) - { - if ( ! $this->seek($offset)) - { - return null; - } - - $result = $this->current(); - - // sanitize the data if needed - if ($this->_sanitization_enabled) - { - $result = \Security::clean($result, null, 'security.output_filter'); - } - - return $result; - } - - /** - * Implements [ArrayAccess::offsetSet], throws an error. - * [!!] You cannot modify a database result. - * - * @param integer $offset - * @param mixed $value - * - * @throws \FuelException - */ - final public function offsetSet($offset, $value) - { - throw new \FuelException('Database results are read-only'); - } - - /** - * Implements [ArrayAccess::offsetUnset], throws an error. - * [!!] You cannot modify a database result. - * - * @param integer $offset - * - * @throws \FuelException - */ - final public function offsetUnset($offset) - { - throw new \FuelException('Database results are read-only'); - } - - /** - * Implements [Iterator::key], returns the current row number. - * - * echo key($result); - * - * @return integer - */ - public function key() - { - return $this->_current_row; - } - - /** - * Implements [Iterator::next], moves to the next row. - * - * next($result); - * - * @return $this - */ - public function next() - { - ++$this->_current_row; - return $this; - } - - /** - * Implements [Iterator::prev], moves to the previous row. - * - * prev($result); - * - * @return $this - */ - public function prev() - { - --$this->_current_row; - return $this; - } - - /** - * Implements [Iterator::rewind], sets the current row to zero. - * - * rewind($result); - * - * @return $this - */ - public function rewind() - { - $this->_current_row = 0; - return $this; - } - - /** - * Implements [Iterator::valid], checks if the current row exists. - * - * [!!] This method is only used internally. - * - * @return boolean - */ - public function valid() - { - return $this->offsetExists($this->_current_row); - } - - /** - * Enable sanitization mode in the object - * - * @return $this - */ - public function sanitize() - { - $this->_sanitization_enabled = true; - - return $this; - } - - /** - * Disable sanitization mode in the object - * - * @return $this - */ - public function unsanitize() - { - $this->_sanitization_enabled = false; - - return $this; - } - - /** - * Returns the current sanitization state of the object - * - * @return bool - */ - public function sanitized() - { - return $this->_sanitization_enabled; - } -} diff --git a/fuel/core/classes/database/result/cached.php b/fuel/core/classes/database/result/cached.php deleted file mode 100755 index 31fc0f6..0000000 --- a/fuel/core/classes/database/result/cached.php +++ /dev/null @@ -1,81 +0,0 @@ -_total_rows = count($result); - } - - public function __destruct() - { - // Cached results do not use resources - } - - /** - * @return $this - */ - public function cached() - { - return $this; - } - - /** - * @param integer $offset - * - * @return bool - */ - public function seek($offset) - { - if ( ! $this->offsetExists($offset)) - { - return false; - } - - $this->_current_row = $offset; - return true; - } - - /** - * @return mixed - */ - public function current() - { - if ($this->valid()) - { - // sanitize the data if needed - if ( ! $this->_sanitization_enabled) - { - $result = $this->_result[$this->_current_row]; - } - else - { - $result = \Security::clean($this->_result[$this->_current_row], null, 'security.output_filter'); - } - - return $result; - } - } - -} diff --git a/fuel/core/classes/database/schema.php b/fuel/core/classes/database/schema.php deleted file mode 100755 index 74eec26..0000000 --- a/fuel/core/classes/database/schema.php +++ /dev/null @@ -1,647 +0,0 @@ -_name = $name; - - // Set the connection instance - $this->_connection = $connection; - } - - /** - * Creates a database. Will throw a Database_Exception if it cannot. - * - * @throws Fuel\Database_Exception - * @param string $database the database name - * @param string $charset the character set - * @param boolean $if_not_exists whether to add an IF NOT EXISTS statement. - * @return int the number of affected rows - */ - public function create_database($database, $charset = null, $if_not_exists = true) - { - $sql = 'CREATE DATABASE'; - $sql .= $if_not_exists ? ' IF NOT EXISTS ' : ' '; - - $sql .= $this->_connection->quote_identifier($database).$this->process_charset($charset, true); - - return $this->_connection->query(0, $sql, false); - } - - /** - * Drops a database. Will throw a Database_Exception if it cannot. - * - * @throws Fuel\Database_Exception - * @param string $database the database name - * @return int the number of affected rows - */ - public function drop_database($database) - { - $sql = 'DROP DATABASE '; - $sql .= $this->_connection->quote_identifier($database); - - return $this->_connection->query(0, $sql, false); - } - - /** - * Drops a table. Will throw a Database_Exception if it cannot. - * - * @throws Fuel\Database_Exception - * @param string $table the table name - * @return int the number of affected rows - */ - public function drop_table($table) - { - $sql = 'DROP TABLE IF EXISTS '; - $sql .= $this->_connection->quote_identifier($this->_connection->table_prefix($table)); - - return $this->_connection->query(0, $sql, false); - } - - /** - * Renames a table. Will throw a Database_Exception if it cannot. - * - * @throws \Database_Exception - * @param string $table the old table name - * @param string $new_table_name the new table name - * @return int the number of affected - */ - public function rename_table($table, $new_table_name) - { - $sql = 'RENAME TABLE '; - $sql .= $this->_connection->quote_identifier($this->_connection->table_prefix($table)); - $sql .= ' TO '; - $sql .= $this->_connection->quote_identifier($this->_connection->table_prefix($new_table_name)); - - return $this->_connection->query(0, $sql, false); - } - - /** - * Creates a table. - * - * @throws \Database_Exception - * @param string $table the table name - * @param array $fields the fields array - * @param array $primary_keys an array of primary keys - * @param boolean $if_not_exists whether to add an IF NOT EXISTS statement. - * @param string|boolean $engine storage engine overwrite - * @param string $charset default charset overwrite - * @param array $foreign_keys an array of foreign keys - * @return int number of affected rows. - */ - public function create_table($table, $fields, $primary_keys = array(), $if_not_exists = true, $engine = false, $charset = null, $foreign_keys = array()) - { - $sql = 'CREATE TABLE'; - - $sql .= $if_not_exists ? ' IF NOT EXISTS ' : ' '; - - $sql .= $this->_connection->quote_identifier($this->_connection->table_prefix($table)).' ('; - $sql .= $this->process_fields($fields, ''); - if ( ! empty($primary_keys)) - { - foreach ($primary_keys as $index => $primary_key) - { - $primary_keys[$index] = $this->_connection->quote_identifier($primary_key); - } - $sql .= ",\n\tPRIMARY KEY (".implode(', ', $primary_keys).')'; - } - - empty($foreign_keys) or $sql .= $this->process_foreign_keys($foreign_keys); - - $sql .= "\n)"; - $sql .= ($engine !== false) ? ' ENGINE = '.$engine.' ' : ''; - $sql .= $this->process_charset($charset, true).";"; - - return $this->_connection->query(0, $sql, false); - } - - /** - * Truncates a table. - * - * @throws Fuel\Database_Exception - * @param string $table the table name - * @return int the number of affected rows - */ - public function truncate_table($table) - { - $sql = 'TRUNCATE TABLE '; - $sql .= $this->_connection->quote_identifier($this->_connection->table_prefix($table)); - - return $this->_connection->query(\DB::DELETE, $sql, false); - } - - /** - * Generic check if a given table exists. - * - * @throws \Database_Exception - * @param string $table Table name - * @return bool - */ - public function table_exists($table) - { - $sql = 'SELECT * FROM '; - $sql .= $this->_connection->quote_identifier($this->_connection->table_prefix($table)); - $sql .= ' LIMIT 1'; - - try - { - $this->_connection->query(\DB::SELECT, $sql, false); - return true; - } - catch (\Database_Exception $e) - { - // check if we have a DB connection at all - if ( ! $this->_connection->has_connection()) - { - // if no connection could be made, re throw the exception - throw $e; - } - - return false; - } - } - - /** - * Checks if given field(s) in a given table exists. - * - * @throws \Database_Exception - * @param string $table Table name - * @param string|array $columns columns to check - * @return bool - */ - public function field_exists($table, $columns) - { - if ( ! is_array($columns)) - { - $columns = array($columns); - } - - $sql = 'SELECT '; - $sql .= implode(', ', array_unique(array_map(array($this->_connection, 'quote_identifier'), $columns))); - $sql .= ' FROM '; - $sql .= $this->_connection->quote_identifier($this->_connection->table_prefix($table)); - $sql .= ' LIMIT 1'; - - try - { - $this->_connection->query(\DB::SELECT, $sql, false); - return true; - } - catch (\Database_Exception $e) - { - // check if we have a DB connection at all - if ( ! $this->_connection->has_connection()) - { - // if no connection could be made, re throw the exception - throw $e; - } - - return false; - } - } - - /** - * Creates an index on that table. - * - * @access public - * @param string $table - * @param string $index_name - * @param string $index_columns - * @param string $index (should be 'unique', 'fulltext', 'spatial' or 'nonclustered') - * @return bool - * @author Thomas Edwards - */ - public function create_index($table, $index_columns, $index_name = '', $index = '') - { - static $accepted_index = array('UNIQUE', 'FULLTEXT', 'SPATIAL', 'NONCLUSTERED', 'PRIMARY'); - - // make sure the index type is uppercase - $index !== '' and $index = strtoupper($index); - - if (empty($index_name)) - { - if (is_array($index_columns)) - { - foreach ($index_columns as $key => $value) - { - if (is_numeric($key)) - { - $index_name .= ($index_name == '' ? '' : '_').$value; - } - else - { - $index_name .= ($index_name == '' ? '' : '_').str_replace(array('(', ')', ' '), '', $key); - } - } - } - else - { - $index_name = $index_columns; - } - } - - if ($index == 'PRIMARY') - { - $sql = 'ALTER TABLE '; - $sql .= $this->_connection->quote_identifier($this->_connection->table_prefix($table)); - $sql .= ' ADD PRIMARY KEY '; - if (is_array($index_columns)) - { - $columns = ''; - foreach ($index_columns as $key => $value) - { - if (is_numeric($key)) - { - $columns .= ($columns=='' ? '' : ', ').$this->_connection->quote_identifier($value); - } - else - { - $columns .= ($columns=='' ? '' : ', ').$this->_connection->quote_identifier($key).' '.strtoupper($value); - } - } - $sql .= ' ('.$columns.')'; - } - } - else - { - $sql = 'CREATE '; - - $index !== '' and $sql .= (in_array($index, $accepted_index)) ? $index.' ' : ''; - - $sql .= 'INDEX '; - $sql .= $this->_connection->quote_identifier($index_name); - $sql .= ' ON '; - $sql .= $this->_connection->quote_identifier($this->_connection->table_prefix($table)); - if (is_array($index_columns)) - { - $columns = ''; - foreach ($index_columns as $key => $value) - { - if (is_numeric($key)) - { - $columns .= ($columns=='' ? '' : ', ').$this->_connection->quote_identifier($value); - } - else - { - $columns .= ($columns=='' ? '' : ', ').$this->_connection->quote_identifier($key).' '.strtoupper($value); - } - } - $sql .= ' ('.$columns.')'; - } - else - { - $sql .= ' ('.$this->_connection->quote_identifier($index_columns).')'; - } - } - - return $this->_connection->query(0, $sql, false); - } - - /** - * Drop an index from a table. - * - * @access public - * @param string $table - * @param string $index_name - * @return bool - * @author Thomas Edwards - */ - public function drop_index($table, $index_name) - { - if (strtoupper($index_name) == 'PRIMARY') - { - $sql = 'ALTER TABLE '.$this->_connection->quote_identifier($this->_connection->table_prefix($table)); - $sql .= ' DROP PRIMARY KEY'; - } - else - { - $sql = 'DROP INDEX '.$this->_connection->quote_identifier($index_name); - $sql .= ' ON '.$this->_connection->quote_identifier($this->_connection->table_prefix($table)); - } - - return $this->_connection->query(0, $sql, false); - } - - /** - * Adds a single foreign key to a table - * - * @param string $table the table name - * @param array $foreign_key a single foreign key - * @return int number of affected rows - */ - public function add_foreign_key($table, $foreign_key) - { - if ( ! is_array($foreign_key)) - { - throw new \InvalidArgumentException('Foreign key for add_foreign_key() must be specified as an array'); - } - - $sql = 'ALTER TABLE '; - $sql .= $this->_connection->quote_identifier($this->_connection->table_prefix($table)).' '; - $sql .= 'ADD '; - $sql .= ltrim($this->process_foreign_keys(array($foreign_key), $this->_connection), ','); - - return $this->_connection->query(0, $sql, false); - } - - /** - * Drops a foreign key from a table - * - * @param string $table the table name - * @param string $fk_name the foreign key name - * @return int number of affected rows - */ - public function drop_foreign_key($table, $fk_name) - { - $sql = 'ALTER TABLE '; - $sql .= $this->_connection->quote_identifier($this->_connection->table_prefix($table)).' '; - $sql .= 'DROP FOREIGN KEY '.$this->_connection->quote_identifier($fk_name); - - return $this->_connection->query(0, $sql, false); - } - - /** - * Returns string of foreign keys - * - * @throws \Database_Exception - * @param array $foreign_keys Array of foreign key rules - * @return string the formatted foreign key string - */ - public function process_foreign_keys($foreign_keys) - { - if ( ! is_array($foreign_keys)) - { - throw new \Database_Exception('Foreign keys on create_table() must be specified as an array'); - } - - $fk_list = array(); - - foreach($foreign_keys as $definition) - { - // some sanity checks - if (empty($definition['key'])) - { - throw new \Database_Exception('Foreign keys on create_table() must specify a foreign key name'); - } - if ( empty($definition['reference'])) - { - throw new \Database_Exception('Foreign keys on create_table() must specify a foreign key reference'); - } - if (empty($definition['reference']['table']) or empty($definition['reference']['column'])) - { - throw new \Database_Exception('Foreign keys on create_table() must specify a reference table and column name'); - } - - $sql = ''; - ! empty($definition['constraint']) and $sql .= " CONSTRAINT ".$this->_connection->quote_identifier($definition['constraint']); - $sql .= " FOREIGN KEY (".$this->_connection->quote_identifier($definition['key']).')'; - $sql .= " REFERENCES ".$this->_connection->quote_identifier($this->_connection->table_prefix($definition['reference']['table'])).' ('; - if (is_array($definition['reference']['column'])) - { - $sql .= implode(', ', $this->_connection->quote_identifier($definition['reference']['column'])); - } - else - { - $sql .= $this->_connection->quote_identifier($definition['reference']['column']); - } - $sql .= ')'; - ! empty($definition['on_update']) and $sql .= " ON UPDATE ".$definition['on_update']; - ! empty($definition['on_delete']) and $sql .= " ON DELETE ".$definition['on_delete']; - - $fk_list[] = "\n\t".ltrim($sql); - } - - return ', '.implode(',', $fk_list); - } - - /** - * - */ - public function alter_fields($type, $table, $fields) - { - $sql = 'ALTER TABLE '.$this->_connection->quote_identifier($this->_connection->table_prefix($table)).' '; - - if ($type === 'DROP') - { - if ( ! is_array($fields)) - { - $fields = array($fields); - } - - $drop_fields = array(); - foreach ($fields as $field) - { - $drop_fields[] = 'DROP '.$this->_connection->quote_identifier($field); - } - $sql .= implode(', ', $drop_fields); - } - else - { - $use_brackets = ! in_array($type, array('ADD', 'CHANGE', 'MODIFY')); - $use_brackets and $sql .= $type.' '; - $use_brackets and $sql .= '('; - $sql .= $this->process_fields($fields, (( ! $use_brackets) ? $type.' ' : '')); - $use_brackets and $sql .= ')'; - } - - return $this->_connection->query(0, $sql, false); - } - - /* - * Executes table maintenance. Will throw FuelException when the operation is not supported. - * - * @throws FuelException - * @param string $table the table name - * @return bool whether the operation has succeeded - */ - public function table_maintenance($operation, $table) - { - $sql = $operation.' '.$this->_connection->quote_identifier($this->_connection->table_prefix($table)); - $result = $this->_connection->query(\DB::SELECT, $sql, false); - - $type = $result->get('Msg_type'); - $message = $result->get('Msg_text'); - $table = $result->get('Table'); - - if ($type === 'status' and in_array(strtolower($message), array('ok', 'table is already up to date'))) - { - return true; - } - - // make sure we have a type logger can handle - if (in_array($type, array('info', 'warning', 'error'))) - { - $type = strtoupper($type); - } - else - { - $type = \Fuel::L_INFO; - } - - logger($type, 'Table: '.$table.', Operation: '.$operation.', Message: '.$result->get('Msg_text'), 'DBUtil::table_maintenance'); - - return false; - } - - /** - * Formats the default charset. - * - * @param string $charset the character set - * @param bool $is_default whether to use default - * @param string $collation the collating sequence to be used - * @return string the formatted charset sql - */ - protected function process_charset($charset = null, $is_default = false, $collation = null) - { - $charset or $charset = \Config::get('db.'.$this->_name.'.charset', null); - - if (empty($charset)) - { - return ''; - } - - $collation or $collation = \Config::get('db.'.$this->_name.'.collation', null); - - if (empty($collation) and ($pos = stripos($charset, '_')) !== false) - { - $collation = $charset; - $charset = substr($charset, 0, $pos); - } - - $charset = 'CHARACTER SET '.$charset; - - if ($is_default) - { - $charset = 'DEFAULT '.$charset; - } - - if ( ! empty($collation)) - { - if ($is_default) - { - $charset .= ' DEFAULT'; - } - $charset .= ' COLLATE '.$collation; - } - - return $charset; - } - - /** - * - */ - protected function process_fields($fields, $prefix = '') - { - $sql_fields = array(); - - foreach ($fields as $field => $attr) - { - $attr = array_change_key_case($attr, CASE_UPPER); - $_prefix = $prefix; - if(array_key_exists('NAME', $attr) and $field !== $attr['NAME'] and $_prefix === 'MODIFY ') - { - $_prefix = 'CHANGE '; - } - $sql = "\n\t".$_prefix; - $sql .= $this->_connection->quote_identifier($field); - $sql .= (array_key_exists('NAME', $attr) and $attr['NAME'] !== $field) ? ' '.$this->_connection->quote_identifier($attr['NAME']).' ' : ''; - $sql .= array_key_exists('TYPE', $attr) ? ' '.$attr['TYPE'] : ''; - - if(array_key_exists('CONSTRAINT', $attr)) - { - if(is_array($attr['CONSTRAINT'])) - { - $sql .= "("; - foreach($attr['CONSTRAINT'] as $constraint) - { - $sql .= (is_string($constraint) ? "'".$constraint."'" : $constraint).", "; - } - $sql = rtrim($sql, ', '). ")"; - } - else - { - $sql .= '('.$attr['CONSTRAINT'].')'; - } - } - - $sql .= array_key_exists('CHARSET', $attr) ? $this->process_charset($attr['CHARSET'], false) : ''; - - if (array_key_exists('UNSIGNED', $attr) and $attr['UNSIGNED'] === true) - { - $sql .= ' UNSIGNED'; - } - - if(array_key_exists('DEFAULT', $attr)) - { - $sql .= ' DEFAULT '.(($attr['DEFAULT'] instanceof \Database_Expression) ? $attr['DEFAULT'] : $this->_connection->quote($attr['DEFAULT'])); - } - - if(array_key_exists('NULL', $attr) and $attr['NULL'] === true) - { - $sql .= ' NULL'; - } - else - { - $sql .= ' NOT NULL'; - } - - if (array_key_exists('AUTO_INCREMENT', $attr) and $attr['AUTO_INCREMENT'] === true) - { - $sql .= ' AUTO_INCREMENT'; - } - - if (array_key_exists('PRIMARY_KEY', $attr) and $attr['PRIMARY_KEY'] === true) - { - $sql .= ' PRIMARY KEY'; - } - - if (array_key_exists('COMMENT', $attr)) - { - $sql .= ' COMMENT '.$this->_connection->escape($attr['COMMENT']); - } - - if (array_key_exists('FIRST', $attr) and $attr['FIRST'] === true) - { - $sql .= ' FIRST'; - } - elseif (array_key_exists('AFTER', $attr) and strval($attr['AFTER'])) - { - $sql .= ' AFTER '.$this->_connection->quote_identifier($attr['AFTER']); - } - - $sql_fields[] = $sql; - } - - return implode(',', $sql_fields); - } - -} diff --git a/fuel/core/classes/database/sqlite/builder/delete.php b/fuel/core/classes/database/sqlite/builder/delete.php deleted file mode 100755 index 1075471..0000000 --- a/fuel/core/classes/database/sqlite/builder/delete.php +++ /dev/null @@ -1,50 +0,0 @@ -quote_table($this->_table); - - if ( ! empty($this->_where)) - { - // Add deletion conditions - $query .= ' WHERE '.$this->_compile_conditions($db, $this->_where); - } - - if ( ! empty($this->_order_by)) - { - // Add sorting - $query .= ' '.$this->_compile_order_by($db, $this->_order_by); - } - - return $query; - } -} diff --git a/fuel/core/classes/database/sqlite/builder/update.php b/fuel/core/classes/database/sqlite/builder/update.php deleted file mode 100755 index c36f1a3..0000000 --- a/fuel/core/classes/database/sqlite/builder/update.php +++ /dev/null @@ -1,59 +0,0 @@ -quote_table($this->_table); - - if ( ! empty($this->_join)) - { - // Add tables to join - $query .= ' '.$this->_compile_join($db, $this->_join); - } - - // Add the columns to update - $query .= ' SET '.$this->_compile_set($db, $this->_set); - - if ( ! empty($this->_where)) - { - // Add selection conditions - $query .= ' WHERE '.$this->_compile_conditions($db, $this->_where); - } - - if ( ! empty($this->_order_by)) - { - // Add sorting - $query .= ' '.$this->_compile_order_by($db, $this->_order_by); - } - - return $query; - } -} diff --git a/fuel/core/classes/database/sqlite/connection.php b/fuel/core/classes/database/sqlite/connection.php deleted file mode 100755 index 758f3e0..0000000 --- a/fuel/core/classes/database/sqlite/connection.php +++ /dev/null @@ -1,130 +0,0 @@ -update('users'); - * - * @param string table to update - * @return Database_Query_Builder_Update - */ - public function update($table = null) - { - return new Database_SQLite_Builder_Update($table); - } - - /** - * Create a new [Database_Query_Builder_Delete]. - * - * // DELETE FROM users - * $query = $db->delete('users'); - * - * @param string table to delete from - * @return Database_Query_Builder_Delete - */ - public function delete($table = null) - { - return new Database_SQLite_Builder_Delete($table); - } - - /** - * List tables - * - * @param string $like - * - * @throws \FuelException - */ - public function list_tables($like = null) - { - $query = 'SELECT name FROM sqlite_master WHERE type = "table" AND name != "sqlite_sequence" AND name != "geometry_columns" AND name != "spatial_ref_sys"' - . 'UNION ALL SELECT name FROM sqlite_temp_master ' - . 'WHERE type = "table"'; - - if (is_string($like)) - { - $query .= ' AND name LIKE ' . $this->quote($like); - } - - $query .= ' ORDER BY name'; - - $q = $this->_connection->prepare($query); - $q->execute(); - $result = $q->fetchAll(); - - $tables = array(); - foreach ($result as $row) - { - $tables[] = reset($row); - } - - return $tables; - } - - /** - * List table columns - * - * @param string $table table name - * @param string $like column name pattern - * @return array array of column structure - */ - public function list_columns($table, $like = null) - { - $query = "PRAGMA table_info('" . $this->quote_table($table) . "')"; - $q = $this->_connection->prepare($query); - $q->execute(); - $result = $q->fetchAll(); - - $count = 0; - $columns = array(); - foreach ($result as $row) - { - $column = $this->datatype($row['type']); - - $column['name'] = $row['name']; - $column['default'] = $row['dflt_value']; - $column['data_type'] = $row['type']; - $column['null'] = $row['notnull']; - $column['ordinal_position'] = ++$count; - $column['comment'] = ''; - $column['extra'] = $row['cid']; - $column['key'] = $row['pk']; - $column['privileges'] = ''; - - $columns[$row['name']] = $column; - } - - return $columns; - } - - /** - * Set the charset - * - * @param string $charset - */ - public function set_charset($charset) - { - // Make sure the database is connected - $this->_connection or $this->connect(); - - if ($charset) - { - $this->_connection->exec('PRAGMA encoding = ' . $this->quote($charset)); - } - } -} diff --git a/fuel/core/classes/database/sqlsrv/connection.php b/fuel/core/classes/database/sqlsrv/connection.php deleted file mode 100755 index 756ac21..0000000 --- a/fuel/core/classes/database/sqlsrv/connection.php +++ /dev/null @@ -1,170 +0,0 @@ -quote($like); - } - - // Find all table names - $result = $this->query(\DB::SELECT, $query, false); - - $tables = array(); - foreach ($result as $row) - { - $tables[] = reset($row); - } - - return $tables; - } - - /** - * List table columns - * - * @param string $table table name - * @param string $like column name pattern - * @return array array of column structure - */ - public function list_columns($table, $like = null) - { - $query = "SELECT * FROM Sys.Columns WHERE id = object_id('" . $this->quote_table($table) . "')"; - - if (is_string($like)) - { - // Search for column names - $query .= " AND name LIKE ".$this->quote($like); - } - - $count = 0; - $columns = array(); - foreach ($result as $row) - { - list($type, $length) = $this->_parse_type($row['Type']); - $column = $this->datatype($type); - $column['name'] = $row['Field']; - $column['default'] = $row['Default']; - $column['data_type'] = $type; - $column['null'] = ($row['Null'] == 'YES'); - $column['ordinal_position'] = ++$count; - switch ($column['type']) - { - case 'float': - if (isset($length)) - { - list($column['numeric_precision'], $column['numeric_scale']) = explode(',', $length); - } - break; - case 'int': - if (isset($length)) - { - $column['display'] = $length; - } - break; - case 'string': - switch ($column['data_type']) - { - case 'binary': - case 'varbinary': - $column['character_maximum_length'] = $length; - break; - case 'char': - case 'varchar': - $column['character_maximum_length'] = $length; - case 'text': - case 'tinytext': - case 'mediumtext': - case 'longtext': - $column['collation_name'] = $row['Collation']; - break; - case 'enum': - case 'set': - $column['collation_name'] = $row['Collation']; - $column['options'] = explode('\',\'', substr($length, 1, -1)); - break; - } - break; - } - $column['comment'] = $row['Comment']; - $column['extra'] = $row['Extra']; - $column['key'] = $row['Key']; - $column['privileges'] = $row['Privileges']; - $columns[$row['Field']] = $column; - } - return $columns; - } - - /** - * Set the charset - * - * @param string $charset - */ - public function set_charset($charset) - { - if ($charset == 'utf8' or $charset = 'utf-8') - { - // use utf8 encoding - $this->_connection->setAttribute(\PDO::SQLSRV_ATTR_ENCODING, \PDO::SQLSRV_ENCODING_UTF8); - } - elseif ($charset == 'system') - { - // use system encoding - $this->_connection->setAttribute(\PDO::SQLSRV_ATTR_ENCODING, \PDO::SQLSRV_ENCODING_SYSTEM); - } - elseif (is_numeric($charset)) - { - // charset code passed directly - $this->_connection->setAttribute(\PDO::SQLSRV_ATTR_ENCODING, $charset); - } - else - { - // unknown charset, use the default encoding - $this->_connection->setAttribute(\PDO::SQLSRV_ATTR_ENCODING, \PDO::SQLSRV_ENCODING_DEFAULT); - } - } - -} diff --git a/fuel/core/classes/date.php b/fuel/core/classes/date.php deleted file mode 100755 index 70b8725..0000000 --- a/fuel/core/classes/date.php +++ /dev/null @@ -1,429 +0,0 @@ - $parsed['year'] - 1900, - 'tm_mon' => $parsed['month'] - 1, - 'tm_mday' => $parsed['day'], - 'tm_hour' => $parsed['hour'] ?: 0, - 'tm_min' => $parsed['minute'] ?: 0, - 'tm_sec' => $parsed['second'] ?: 0, - ); - } - else - { - $masks = array( - '%d' => '(?P[0-9]{2})', - '%m' => '(?P[0-9]{2})', - '%Y' => '(?P[0-9]{4})', - '%H' => '(?P[0-9]{2})', - '%M' => '(?P[0-9]{2})', - '%S' => '(?P[0-9]{2})', - ); - - $rexep = "#" . strtr(preg_quote($format), $masks) . "#"; - - if ( ! preg_match($rexep, $input, $result)) - { - return false; - } - - return array( - "tm_sec" => isset($result['S']) ? (int) $result['S'] : 0, - "tm_min" => isset($result['M']) ? (int) $result['M'] : 0, - "tm_hour" => isset($result['H']) ? (int) $result['H'] : 0, - "tm_mday" => isset($result['d']) ? (int) $result['d'] : 0, - "tm_mon" => isset($result['m']) ? ($result['m'] ? $result['m'] - 1 : 0) : 0, - "tm_year" => isset($result['Y']) ? ($result['Y'] > 1900 ? $result['Y'] - 1900 : 0) : 0, - ); - } - } - - // This really is some fugly code, but someone at PHP HQ decided strptime should - // output this awful array instead of a timestamp LIKE EVERYONE ELSE DOES!!! - } - } - - /** - * Create Date object from timestamp, timezone is optional - * - * @param int $timestamp UNIX timestamp from current server - * @param string $timezone valid PHP timezone from www.php.net/timezones - * @return Date - */ - public static function forge($timestamp = null, $timezone = null) - { - return new static($timestamp, $timezone); - } - - /** - * Returns the current time with offset - * - * @param string $timezone valid PHP timezone from www.php.net/timezones - * @return Date - */ - public static function time($timezone = null) - { - return static::forge(null, $timezone); - } - - /** - * Returns the current time with offset - * - * @param string $timezone valid PHP timezone from www.php.net/timezones - * @return string - */ - public static function display_timezone($timezone = null) - { - is_string($timezone) and static::$display_timezone = $timezone; - - return static::$display_timezone; - } - - /** - * Uses the date config file to translate string input to timestamp - * - * @param string $input date/time input - * @param string $pattern_key key name of pattern in config file - * @return Date - */ - public static function create_from_string($input, $pattern_key = 'local') - { - \Config::load('date', 'date'); - - $pattern = \Config::get('date.patterns.'.$pattern_key, null); - empty($pattern) and $pattern = $pattern_key; - - $time = strptime($input, $pattern); - if ($time === false) - { - throw new \UnexpectedValueException('Input was not recognized by pattern.'); - } - - // convert it into a timestamp - $timestamp = mktime($time['tm_hour'], $time['tm_min'], $time['tm_sec'], - $time['tm_mon'] + 1, $time['tm_mday'], $time['tm_year'] + 1900); - - if ($timestamp === false) - { - throw new \OutOfBoundsException('Input was invalid.'.(PHP_INT_SIZE == 4 ? ' A 32-bit system only supports dates between 1901 and 2038.' : '')); - } - - return static::forge($timestamp); - } - - /** - * Fetches an array of Date objects per interval within a range - * - * @param int|Date $start start of the range - * @param int|Date $end end of the range - * @param int|string $interval Length of the interval in seconds or valid strtotime time difference - * @return array array of Date objects - */ - public static function range_to_array($start, $end, $interval = '+1 Day') - { - // make sure start and end are date objects - $start = ( ! $start instanceof Date) ? static::forge($start) : $start; - $end = ( ! $end instanceof Date) ? static::forge($end) : $end; - - $range = array(); - - // if end > start, the range is empty - if ($end->get_timestamp() >= $start->get_timestamp()) - { - $current = $start; - $increment = $interval; - - do - { - $range[] = $current; - - if ( ! is_int($interval)) - { - $increment = strtotime($interval, $current->get_timestamp()) - $current->get_timestamp(); - if ($increment <= 0) - { - throw new \UnexpectedValueException('Input was not recognized by pattern.'); - } - } - - $current = static::forge($current->get_timestamp() + $increment); - } - while ($current->get_timestamp() <= $end->get_timestamp()); - } - - return $range; - } - - /** - * Returns the number of days in the requested month - * - * @param int $month month as a number (1-12) - * @param int $year the year, leave empty for current - * @return int the number of days in the month - */ - public static function days_in_month($month, $year = null) - { - $year = ! empty($year) ? (int) $year : (int) date('Y'); - $month = (int) $month; - - if ($month < 1 or $month > 12) - { - throw new \UnexpectedValueException('Invalid input for month given.'); - } - elseif ($month == 2) - { - if ($year % 400 == 0 or ($year % 4 == 0 and $year % 100 != 0)) - { - return 29; - } - } - - $days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); - return $days_in_month[$month-1]; - } - - /** - * Returns the time ago - * - * @param int $timestamp UNIX timestamp from current server - * @param int $from_timestamp UNIX timestamp to compare against. Default to the current time - * @param string $unit Unit to return the result in - * @return string Time ago - */ - public static function time_ago($timestamp, $from_timestamp = null, $unit = null) - { - if ($timestamp === null) - { - return ''; - } - - ! is_numeric($timestamp) and $timestamp = static::create_from_string($timestamp)->get_timestamp(); - - $from_timestamp == null and $from_timestamp = time(); - - \Lang::load('date', true); - - $difference = $from_timestamp - $timestamp; - $periods = array('second', 'minute', 'hour', 'day', 'week', 'month', 'year', 'decade'); - $lengths = array(60, 60, 24, 7, 4.35, 12, 10); - - for ($j = 0; isset($lengths[$j]) and $difference >= $lengths[$j] and (empty($unit) or $unit != $periods[$j]); $j++) - { - $difference /= $lengths[$j]; - } - - $difference = round($difference); - - if ($difference != 1) - { - $periods[$j] = \Inflector::pluralize($periods[$j]); - } - - $text = \Lang::get('date.text', array( - 'time' => \Lang::get('date.'.$periods[$j], array('t' => $difference)), - )); - - return $text; - } - - /** - * @var int instance timestamp - */ - protected $timestamp; - - /** - * @var string output timezone - */ - protected $timezone; - - public function __construct($timestamp = null, $timezone = null) - { - is_null($timestamp) and $timestamp = time() + static::$server_gmt_offset; - ! $timezone and $timezone = \Fuel::$timezone; - - $this->timestamp = $timestamp; - $this->set_timezone($timezone); - } - - /** - * Returns the date formatted according to the current locale - * - * @param string $pattern_key either a named pattern from date config file or a pattern, defaults to 'local' - * @param mixed $timezone vald timezone, or if true, output the time in local time instead of system time - * @return string - */ - public function format($pattern_key = 'local', $timezone = null) - { - \Config::load('date', 'date'); - - $pattern = \Config::get('date.patterns.'.$pattern_key, $pattern_key); - - // determine the timezone to switch to - $timezone === true and $timezone = static::$display_timezone; - is_string($timezone) or $timezone = $this->timezone; - - // Temporarily change timezone when different from default - if (\Fuel::$timezone != $timezone) - { - date_default_timezone_set($timezone); - } - - // Create output - $output = strftime($pattern, $this->timestamp); - - // Change timezone back to default if changed previously - if (\Fuel::$timezone != $timezone) - { - date_default_timezone_set(\Fuel::$timezone); - } - - return $output; - } - - /** - * Returns the internal timestamp - * - * @return int - */ - public function get_timestamp() - { - return $this->timestamp; - } - - /** - * Returns the internal timezone - * - * @return string - */ - public function get_timezone() - { - return $this->timezone; - } - - /** - * Returns the internal timezone or the display timezone abbreviation - * - * @param boolean $display_timezone - * - * @return string - */ - public function get_timezone_abbr($display_timezone = false) - { - // determine the timezone to switch to - $display_timezone and $timezone = static::$display_timezone; - empty($timezone) and $timezone = $this->timezone; - - // Temporarily change timezone when different from default - if (\Fuel::$timezone != $timezone) - { - date_default_timezone_set($timezone); - } - - // Create output - $output = date('T'); - - // Change timezone back to default if changed previously - if (\Fuel::$timezone != $timezone) - { - date_default_timezone_set(\Fuel::$timezone); - } - - return $output; - } - - /** - * Change the timezone - * - * @param string $timezone timezone from www.php.net/timezones - * @return Date - */ - public function set_timezone($timezone) - { - $this->timezone = $timezone; - - return $this; - } - - /** - * Allows you to just put the object in a string and get it inserted in the default pattern - * - * @return string - */ - public function __toString() - { - return $this->format(); - } -} diff --git a/fuel/core/classes/db.php b/fuel/core/classes/db.php deleted file mode 100755 index cffc7f3..0000000 --- a/fuel/core/classes/db.php +++ /dev/null @@ -1,415 +0,0 @@ -last_query; - } - - /* - * Returns the DB drivers error info - * - * @return mixed the DB drivers error info - */ - public static function error_info($db = null) - { - return \Database_Connection::instance($db)->error_info(); - } - - /* - * Returns a database instance - * - * @return Database_Connection - */ - public static function instance($db = null) - { - return \Database_Connection::instance($db); - } - - /** - * Create a new [Database_Query_Builder_Select]. Each argument will be - * treated as a column. To generate a `foo AS bar` alias, use an array. - * - * // SELECT id, username - * $query = DB::select('id', 'username'); - * - * // SELECT id AS user_id - * $query = DB::select(array('id', 'user_id')); - * - * @param mixed column name or array($column, $alias) or object - * @param ... - * @return Database_Query_Builder_Select - */ - public static function select($args = null) - { - return \Database_Connection::instance()->select(func_get_args()); - } - - /** - * Create a new [Database_Query_Builder_Select] from an array of columns. - * - * // SELECT id, username - * $query = DB::select_array(array('id', 'username')); - * - * @param array columns to select - * @return Database_Query_Builder_Select - */ - public static function select_array(array $columns = null) - { - return \Database_Connection::instance()->select($columns); - } - - /** - * Create a new [Database_Query_Builder_Insert]. - * - * // INSERT INTO users (id, username) - * $query = DB::insert('users', array('id', 'username')); - * - * @param string table to insert into - * @param array list of column names or array($column, $alias) or object - * @return Database_Query_Builder_Insert - */ - public static function insert($table = null, array $columns = null) - { - return \Database_Connection::instance()->insert($table, $columns); - } - - /** - * Create a new [Database_Query_Builder_Update]. - * - * // UPDATE users - * $query = DB::update('users'); - * - * @param string table to update - * @return Database_Query_Builder_Update - */ - public static function update($table = null) - { - return \Database_Connection::instance()->update($table); - } - - /** - * Create a new [Database_Query_Builder_Delete]. - * - * // DELETE FROM users - * $query = DB::delete('users'); - * - * @param string table to delete from - * @return Database_Query_Builder_Delete - */ - public static function delete($table = null) - { - return \Database_Connection::instance()->delete($table); - } - - /** - * Create a new [Database_Expression] which is not escaped. An expression - * is the only way to use SQL functions within query builders. - * - * $expression = DB::expr('COUNT(users.id)'); - * - * @param string $string expression - * @return Database_Expression - */ - public static function expr($string) - { - return new \Database_Expression($string); - } - - /** - * Create a new [Database_Expression] containing a quoted identifier. An expression - * is the only way to use SQL functions within query builders. - * - * $expression = DB::identifier('users.id'); // returns `users`.`id` for MySQL - * - * @param string $string the string to quote - * @param string $db the database connection to use - * @return Database_Expression - */ - public static function identifier($string, $db = null) - { - return new \Database_Expression(static::quote_identifier($string, $db)); - } - - /** - * Quote a value for an SQL query. - * - * @param string $string the string to quote - * @param string $db the database connection to use - * @return string the quoted value - */ - public static function quote($string, $db = null) - { - if (is_array($string)) - { - foreach ($string as $k => $s) - { - $string[$k] = static::quote($s, $db); - } - return $string; - } - return \Database_Connection::instance($db)->quote($string); - } - - /** - * Quotes an identifier so it is ready to use in a query. - * - * @param string $string the string to quote - * @param string $db the database connection to use - * @return string the quoted identifier - */ - public static function quote_identifier($string, $db = null) - { - if (is_array($string)) - { - foreach ($string as $k => $s) - { - $string[$k] = static::quote_identifier($s, $db); - } - return $string; - } - return \Database_Connection::instance($db)->quote_identifier($string); - } - - /** - * Quote a database table name and adds the table prefix if needed. - * - * @param string $string the string to quote - * @param string $db the database connection to use - * @return string the quoted identifier - */ - public static function quote_table($string, $db = null) - { - if (is_array($string)) - { - foreach ($string as $k => $s) - { - $string[$k] = static::quote_table($s, $db); - } - return $string; - } - return \Database_Connection::instance($db)->quote_table($string); - } - - /** - * Escapes a string to be ready for use in a sql query - * - * @param string $string the string to escape - * @param string $db the database connection to use - * @return string the escaped string - */ - public static function escape($string, $db = null) - { - return \Database_Connection::instance($db)->escape($string); - } - - /** - * If a table name is given it will return the table name with the configured - * prefix. If not, then just the prefix is returned - * - * @param string $table the table name to prefix - * @param string $db the database connection to use - * @return string the prefixed table name or the prefix - */ - public static function table_prefix($table = null, $db = null) - { - return \Database_Connection::instance($db)->table_prefix($table); - } - - /** - * Lists all of the columns in a table. Optionally, a LIKE string can be - * used to search for specific fields. - * - * // Get all columns from the "users" table - * $columns = DB::list_columns('users'); - * - * // Get all name-related columns - * $columns = DB::list_columns('users', '%name%'); - * - * @param string table to get columns from - * @param string column to search for - * @param string the database connection to use - * @return array - */ - public static function list_columns($table = null, $like = null, $db = null) - { - return \Database_Connection::instance($db)->list_columns($table, $like); - } - - /** - * If a table name is given it will return the table name with the configured - * prefix. If not, then just the prefix is returned - * - * @param string $table the table name to prefix - * @param string $db the database connection to use - * @return string the prefixed table name or the prefix - */ - public static function list_tables($like = null, $db = null) - { - return \Database_Connection::instance($db)->list_tables($like); - } - - /** - * Returns a normalized array describing the SQL data type - * - * DB::datatype('char'); - * - * @param string SQL data type - * @param string db connection - * @return array - */ - public static function datatype($type, $db = null) - { - return \Database_Connection::instance($db)->datatype($type); - } - - /** - * Count the number of records in a table. - * - * // Get the total number of records in the "users" table - * $count = DB::count_records('users'); - * - * @param mixed table name string or array(query, alias) - * @param string db connection - * @return integer - */ - public static function count_records($table, $db = null) - { - return \Database_Connection::instance($db)->count_records($table); - } - - /** - * Count the number of records in the last query, without LIMIT or OFFSET applied. - * - * // Get the total number of records that match the last query - * $count = $db->count_last_query(); - * - * @param string db connection - * @return integer - */ - public static function count_last_query($db = null) - { - return \Database_Connection::instance($db)->count_last_query(); - } - - /** - * Set the connection character set. This is called automatically by [static::connect]. - * - * DB::set_charset('utf8'); - * - * @throws Database_Exception - * @param string character set name - * @param string db connection - * @return void - */ - public static function set_charset($charset, $db = null) - { - \Database_Connection::instance($db)->set_charset($charset); - } - - /** - * Checks whether a connection is in transaction. - * - * DB::in_transaction(); - * - * @param string db connection - * @return bool - */ - public static function in_transaction($db = null) - { - return \Database_Connection::instance($db)->in_transaction(); - } - - /** - * Begins a transaction on instance - * - * DB::start_transaction(); - * - * @param string db connection - * @return bool - */ - public static function start_transaction($db = null) - { - return \Database_Connection::instance($db)->start_transaction(); - } - - /** - * Commits all pending transactional queries - * - * DB::commit_transaction(); - * - * @param string db connection - * @return bool - */ - public static function commit_transaction($db = null) - { - return \Database_Connection::instance($db)->commit_transaction(); - } - - /** - * Rollsback pending transactional queries - * Rollback to the current level uses SAVEPOINT, - * it does not work if current RDBMS does not support them. - * In this case system rollsback all queries and closes the transaction - * - * DB::rollback_transaction(); - * - * @param string $db connection - * @param bool $rollback_all: - * true - rollback everything and close transaction; - * false - rollback only current level - * @return bool - */ - public static function rollback_transaction($db = null, $rollback_all = true) - { - return \Database_Connection::instance($db)->rollback_transaction($rollback_all); - } - -} diff --git a/fuel/core/classes/dbutil.php b/fuel/core/classes/dbutil.php deleted file mode 100755 index d4846a0..0000000 --- a/fuel/core/classes/dbutil.php +++ /dev/null @@ -1,445 +0,0 @@ -schema( - 'create_database', - array( - $database, - $charset, - $if_not_exists, - ) - ); - } - - /** - * Drops a database. Will throw a Database_Exception if it cannot. - * - * @throws Fuel\Database_Exception - * @param string $database the database name - * @param string $db the database connection to use - * @return int the number of affected rows - */ - public static function drop_database($database, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'drop_database', - array( - $database, - ) - ); - } - - /** - * Drops a table. Will throw a Database_Exception if it cannot. - * - * @throws Fuel\Database_Exception - * @param string $table the table name - * @param string $db the database connection to use - * @return int the number of affected rows - */ - public static function drop_table($table, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'drop_table', - array( - $table, - ) - ); - } - - /** - * Renames a table. Will throw a Database_Exception if it cannot. - * - * @throws \Database_Exception - * @param string $table the old table name - * @param string $new_table_name the new table name - * @param string $db the database connection to use - * @return int the number of affected - */ - public static function rename_table($table, $new_table_name, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'rename_table', - array( - $table, - $new_table_name, - ) - ); - } - - /** - * Creates a table. - * - * @throws \Database_Exception - * @param string $table the table name - * @param array $fields the fields array - * @param array $primary_keys an array of primary keys - * @param boolean $if_not_exists whether to add an IF NOT EXISTS statement. - * @param string|boolean $engine storage engine overwrite - * @param string $charset default charset overwrite - * @param array $foreign_keys an array of foreign keys - * @param string $db the database connection to use - * @return int number of affected rows. - */ - public static function create_table($table, $fields, $primary_keys = array(), $if_not_exists = true, $engine = false, $charset = null, $foreign_keys = array(), $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'create_table', - array( - $table, - $fields, - $primary_keys, - $if_not_exists, - $engine, - $charset, - $foreign_keys, - ) - ); - } - - /** - * Adds fields to a table a table. Will throw a Database_Exception if it cannot. - * - * @throws Fuel\Database_Exception - * @param string $table the table name - * @param array $fields the new fields - * @param string $db the database connection to use - * @return int the number of affected - */ - public static function add_fields($table, $fields, $db = null) - { - return static::alter_fields('ADD', $table, $fields, $db); - } - - /** - * Modifies fields in a table. Will throw a Database_Exception if it cannot. - * - * @throws Fuel\Database_Exception - * @param string $table the table name - * @param array $fields the modified fields - * @param string $db the database connection to use - * @return int the number of affected - */ - public static function modify_fields($table, $fields, $db = null) - { - return static::alter_fields('MODIFY', $table, $fields, $db); - } - - /** - * Drops fields from a table a table. Will throw a Database_Exception if it cannot. - * - * @throws Fuel\Database_Exception - * @param string $table the table name - * @param string|array $fields the fields - * @param string $db the database connection to use - * @return int the number of affected - */ - public static function drop_fields($table, $fields, $db = null) - { - return static::alter_fields('DROP', $table, $fields, $db); - } - - /** - * Creates an index on that table. - * - * @access public - * @static - * @param string $table - * @param string $index_name - * @param string $index_columns - * @param string $index (should be 'unique', 'fulltext', 'spatial' or 'nonclustered') - * @param string $db the database connection to use - * @return bool - * @author Thomas Edwards - */ - public static function create_index($table, $index_columns, $index_name = '', $index = '', $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'create_index', - array( - $table, - $index_columns, - $index_name, - $index, - ) - ); - } - - /** - * Drop an index from a table. - * - * @access public - * @static - * @param string $table - * @param string $index_name - * @param string $db the database connection to use - * @return bool - * @author Thomas Edwards - */ - public static function drop_index($table, $index_name, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'drop_index', - array( - $table, - $index_name, - ) - ); - } - - /** - * Adds a single foreign key to a table - * - * @param string $table the table name - * @param array $foreign_key a single foreign key - * @param string $db the database connection to use - * @return int number of affected rows - */ - public static function add_foreign_key($table, $foreign_key, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'add_foreign_key', - array( - $table, - $foreign_key, - ) - ); - } - - /** - * Drops a foreign key from a table - * - * @param string $table the table name - * @param string $fk_name the foreign key name - * @param string $db the database connection to use - * @return int number of affected rows - */ - public static function drop_foreign_key($table, $fk_name, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'drop_foreign_key', - array( - $table, - $fk_name, - ) - ); - } - - /** - * Returns string of foreign keys - * - * @throws \Database_Exception - * @param array $foreign_keys Array of foreign key rules - * @param string $db the database connection to use - * @return string the formatted foreign key string - */ - public static function process_foreign_keys($foreign_keys, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'process_foreign_keys', - array( - $foreign_keys, - ) - ); - } - - /** - * Truncates a table. - * - * @throws Fuel\Database_Exception - * @param string $table the table name - * @param string $db the database connection to use - * @return int the number of affected rows - */ - public static function truncate_table($table, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'truncate_table', - array( - $table, - ) - ); - } - - /** - * Analyzes a table. - * - * @param string $table the table name - * @param string $db the database connection to use - * @return bool whether the table is OK - */ - public static function analyze_table($table, $db = null) - { - return static::table_maintenance('ANALYZE TABLE', $table, $db); - } - - /** - * Checks a table. - * - * @param string $table the table name - * @param string $db the database connection to use - * @return bool whether the table is OK - */ - public static function check_table($table, $db = null) - { - return static::table_maintenance('CHECK TABLE', $table, $db); - } - - /** - * Optimizes a table. - * - * @param string $table the table name - * @param string $db the database connection to use - * @return bool whether the table has been optimized - */ - public static function optimize_table($table, $db = null) - { - return static::table_maintenance('OPTIMIZE TABLE', $table, $db); - } - - /** - * Repairs a table. - * - * @param string $table the table name - * @param string $db the database connection to use - * @return bool whether the table has been repaired - */ - public static function repair_table($table, $db = null) - { - return static::table_maintenance('REPAIR TABLE', $table, $db); - } - - /** - * Checks if a given table exists. - * - * @throws \Database_Exception - * @param string $table Table name - * @param string $db the database connection to use - * @return bool - */ - public static function table_exists($table, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'table_exists', - array( - $table, - ) - ); - } - - /** - * Checks if given field(s) in a given table exists. - * - * @throws \Database_Exception - * @param string $table Table name - * @param string|array $columns columns to check - * @param string $db the database connection to use - * @return bool - */ - public static function field_exists($table, $columns, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'field_exists', - array( - $table, - $columns, - ) - ); - } - - /** - * - */ - protected static function alter_fields($type, $table, $fields, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'alter_fields', - array( - $type, - $table, - $fields, - ) - ); - } - - /* - * Executes table maintenance. Will throw FuelException when the operation is not supported. - * - * @throws FuelException - * @param string $table the table name - * @param string $db the database connection to use - * @return bool whether the operation has succeeded - */ - protected static function table_maintenance($operation, $table, $db = null) - { - return \Database_Connection::instance($db ? $db : static::$connection)->schema( - 'table_maintenance', - array( - $operation, - $table, - ) - ); - } -} diff --git a/fuel/core/classes/debug.php b/fuel/core/classes/debug.php deleted file mode 100755 index 2fa1368..0000000 --- a/fuel/core/classes/debug.php +++ /dev/null @@ -1,551 +0,0 @@ - $trace) - { - if (isset($trace['file'])) - { - // If being called from within, show the file above in the backtrack - if (strpos($trace['file'], 'core/classes/debug.php') !== false) - { - $callee = $backtrace[$stack+1]; - $label = \Inflector::humanize($backtrace[$stack+1]['function']); - } - else - { - $callee = $trace; - $label = 'Debug'; - } - - $callee['file'] = \Fuel::clean_path($callee['file']); - - break; - } - } - - $arguments = func_get_args(); - - if ( ! static::$js_displayed) - { - echo <<function fuel_debug_toggle(a){if(document.getElementById){if(document.getElementById(a).style.display=="none"){document.getElementById(a).style.display="block"}else{document.getElementById(a).style.display="none"}}else{if(document.layers){if(document.id.display=="none"){document.id.display="block"}else{document.id.display="none"}}else{if(document.all.id.style.display=="none"){document.all.id.style.display="block"}else{document.all.id.style.display="none"}}}}; -JS; - static::$js_displayed = true; - } - echo '
'; - echo '

'.$callee['file'].' @ line: '.$callee['line'].'

'; - echo '
';
-
-			$count = count($arguments);
-			for ($i = 1; $i <= $count; $i++)
-			{
-				echo 'Variable #'.$i.':'.PHP_EOL;
-				echo static::format('', $arguments[$i - 1]);
-				echo PHP_EOL.PHP_EOL;
-			}
-
-			echo "
"; - echo "
"; - } - } - - /** - * Quick and nice way to output a mixed variable to the browser - * - * @static - * @access public - * @return string - */ - public static function inspect() - { - $backtrace = debug_backtrace(); - - // If being called from within, show the file above in the backtrack - if (strpos($backtrace[0]['file'], 'core/classes/debug.php') !== false) - { - $callee = $backtrace[1]; - $label = \Inflector::humanize($backtrace[1]['function']); - } - else - { - $callee = $backtrace[0]; - $label = 'Debug'; - } - - $arguments = func_get_args(); - $total_arguments = count($arguments); - - $callee['file'] = \Fuel::clean_path($callee['file']); - - if ( ! static::$js_displayed) - { - echo <<function fuel_debug_toggle(a){if(document.getElementById){if(document.getElementById(a).style.display=="none"){document.getElementById(a).style.display="block"}else{document.getElementById(a).style.display="none"}}else{if(document.layers){if(document.id.display=="none"){document.id.display="block"}else{document.id.display="none"}}else{if(document.all.id.style.display=="none"){document.all.id.style.display="block"}else{document.all.id.style.display="none"}}}}; -JS; - static::$js_displayed = true; - } - echo '
'; - echo '

'.$callee['file'].' @ line: '.$callee['line'].'

'; - echo '
';
-		$i = 0;
-		foreach ($arguments as $argument)
-		{
-			echo ''.$label.' #'.(++$i).' of '.$total_arguments.':
'; - echo static::format('...', $argument); - echo '
'; - } - - echo "
"; - echo "
"; - } - - /** - * Formats the given $var's output in a nice looking, Foldable interface. - * - * @param string $name the name of the var - * @param mixed $var the variable - * @param int $level the indentation level - * @param string $indent_char the indentation character - * @param string $scope - * @return string the formatted string. - */ - public static function format($name, $var, $level = 0, $indent_char = '    ', $scope = '') - { - $return = str_repeat($indent_char, $level); - if (is_array($var)) - { - $id = 'fuel_debug_'.mt_rand(); - $return .= "{$scope} ".htmlentities($name).""; - $return .= " (Array, ".count($var)." element".(count($var)!=1 ? "s" : "").")"; - if (count($var) > 0 and static::$max_nesting_level > $level) - { - $return .= " \n"; - } - else - { - $return .= "\n"; - } - - if (static::$max_nesting_level <= $level) - { - $return .= str_repeat($indent_char, $level + 1)."...\n"; - } - else - { - $sub_return = ''; - foreach ($var as $key => $val) - { - $sub_return .= static::format($key, $val, $level + 1); - } - if (count($var) > 0) - { - $return .= "$sub_return"; - } - else - { - $return .= $sub_return; - } - } - - } - elseif (is_string($var)) - { - $return .= "{$scope} ".htmlentities($name)." (String): \"".\Security::htmlentities($var)."\" (".strlen($var)." characters)\n"; - } - elseif (is_float($var)) - { - $return .= "{$scope} ".htmlentities($name)." (Float): {$var}\n"; - } - elseif (is_long($var)) - { - $return .= "{$scope} ".htmlentities($name)." (Integer): {$var}\n"; - } - elseif (is_null($var)) - { - $return .= "{$scope} ".htmlentities($name)." : null\n"; - } - elseif (is_bool($var)) - { - $return .= "{$scope} ".htmlentities($name)." (Boolean): ".($var ? 'true' : 'false')."\n"; - } - elseif (is_double($var)) - { - $return .= "{$scope} ".htmlentities($name)." (Double): {$var}\n"; - } - elseif (is_object($var)) - { - // dirty hack to get the object id - ob_start(); - var_dump($var); - $contents = ob_get_contents(); - ob_end_clean(); - - // process it based on the xdebug presence and configuration - if (extension_loaded('xdebug') and ini_get('xdebug.overload_var_dump') === '1') - { - if (ini_get('html_errors')) - { - preg_match('~(.*?)\)\[(\d+)(.*)~', $contents, $matches); - } - else - { - preg_match('~class (.*?)#(\d+)(.*)~', $contents, $matches); - } - } - else - { - preg_match('~object\((.*?)#(\d+)(.*)~', $contents, $matches); - } - - $id = 'fuel_debug_'.mt_rand(); - $rvar = new \ReflectionObject($var); - $vars = $rvar->getProperties(); - $return .= "{$scope} {$name} (Object #".$matches[2]."): ".get_class($var); - if (count($vars) > 0 and static::$max_nesting_level > $level) - { - $return .= " \n"; - } - $return .= "\n"; - - $sub_return = ''; - foreach ($rvar->getProperties() as $prop) - { - $prop->isPublic() or $prop->setAccessible(true); - if ($prop->isPrivate()) - { - $scope = 'private'; - } - elseif ($prop->isProtected()) - { - $scope = 'protected'; - } - else - { - $scope = 'public'; - } - if (static::$max_nesting_level <= $level) - { - $sub_return .= str_repeat($indent_char, $level + 1)."...\n"; - } - else - { - $sub_return .= static::format($prop->name, $prop->getValue($var), $level + 1, $indent_char, $scope); - } - } - - if (count($vars) > 0) - { - $return .= "$sub_return"; - } - else - { - $return .= $sub_return; - } - } - else - { - $return .= "{$scope} ".htmlentities($name).": {$var}\n"; - } - return $return; - } - - /** - * Returns the debug lines from the specified file - * - * @access protected - * @param string $filepath the file path - * @param int $line_num the line number - * @param bool $highlight whether to use syntax highlighting or not - * @param int $padding the amount of line padding - * @return array - */ - public static function file_lines($filepath, $line_num, $highlight = true, $padding = 5) - { - // deal with eval'd code and runtime-created function - if (strpos($filepath, 'eval()\'d code') !== false or strpos($filepath, 'runtime-created function') !== false) - { - return ''; - } - - // We cache the entire file to reduce disk IO for multiple errors - if ( ! isset(static::$files[$filepath])) - { - static::$files[$filepath] = file($filepath, FILE_IGNORE_NEW_LINES); - array_unshift(static::$files[$filepath], ''); - } - - $start = $line_num - $padding; - if ($start < 0) - { - $start = 0; - } - - $length = ($line_num - $start) + $padding + 1; - if (($start + $length) > count(static::$files[$filepath]) - 1) - { - $length = NULL; - } - - $debug_lines = array_slice(static::$files[$filepath], $start, $length, TRUE); - - if ($highlight) - { - $to_replace = array('', '', '<?php ', "\n"); - $replace_with = array('', '', '', ''); - - foreach ($debug_lines as & $line) - { - $line = str_replace($to_replace, $replace_with, highlight_string(' $frame) - { - $line = "#$i\t"; - - if ( ! isset($frame['file'])) - { - $line .= "[internal function]"; - } - else - { - $line .= $frame['file'] . ":" . $frame['line']; - } - - $line .= "\t"; - - if (isset($frame['function'])) - { - if (isset($frame['class'])) - { - $line .= $frame['class'] . '::'; - } - - $line .= $frame['function'] . "()"; - } - - $str .= $line . "\n"; - - } - - return $str; - } - else - { - return static::dump($trace); - } - } - - /** - * Prints a list of all currently declared classes. - * - * @access public - * @static - */ - public static function classes() - { - return static::dump(get_declared_classes()); - } - - /** - * Prints a list of all currently declared interfaces (PHP5 only). - * - * @access public - * @static - */ - public static function interfaces() - { - return static::dump(get_declared_interfaces()); - } - - /** - * Prints a list of all currently included (or required) files. - * - * @access public - * @static - */ - public static function includes() - { - return static::dump(get_included_files()); - } - - /** - * Prints a list of all currently declared functions. - * - * @access public - * @static - */ - public static function functions() - { - return static::dump(get_defined_functions()); - } - - /** - * Prints a list of all currently declared constants. - * - * @access public - * @static - */ - public static function constants() - { - return static::dump(get_defined_constants()); - } - - /** - * Prints a list of all currently loaded PHP extensions. - * - * @access public - * @static - */ - public static function extensions() - { - return static::dump(get_loaded_extensions()); - } - - /** - * Prints a list of all HTTP request headers. - * - * @access public - * @static - */ - public static function headers() - { - // get the current request headers and dump them - return static::dump(\Input::headers()); - } - - /** - * Prints a list of the configuration settings read from php.ini - * - * @access public - * @static - */ - public static function phpini() - { - if ( ! is_readable(get_cfg_var('cfg_file_path'))) - { - return false; - } - - // render it - return static::dump(parse_ini_file(get_cfg_var('cfg_file_path'), true)); - } - - /** - * Benchmark anything that is callable - * - * @access public - * @param callable $callable - * @param array $params - * @static - * @return array - */ - public static function benchmark($callable, array $params = array()) - { - // get the before-benchmark time - if (function_exists('getrusage')) - { - $dat = getrusage(); - $utime_before = $dat['ru_utime.tv_sec'] + round($dat['ru_utime.tv_usec']/1000000, 4); - $stime_before = $dat['ru_stime.tv_sec'] + round($dat['ru_stime.tv_usec']/1000000, 4); - } - else - { - list($usec, $sec) = explode(" ", microtime()); - $utime_before = ((float) $usec + (float) $sec); - $stime_before = 0; - } - - // call the function to be benchmarked - $result = is_callable($callable) ? call_fuel_func_array($callable, $params) : null; - - // get the after-benchmark time - if (function_exists('getrusage')) - { - $dat = getrusage(); - $utime_after = $dat['ru_utime.tv_sec'] + round($dat['ru_utime.tv_usec']/1000000, 4); - $stime_after = $dat['ru_stime.tv_sec'] + round($dat['ru_stime.tv_usec']/1000000, 4); - } - else - { - list($usec, $sec) = explode(" ", microtime()); - $utime_after = ((float) $usec + (float) $sec); - $stime_after = 0; - } - - return array( - 'user' => sprintf('%1.6f', $utime_after - $utime_before), - 'system' => sprintf('%1.6f', $stime_after - $stime_before), - 'result' => $result, - ); - } - -} diff --git a/fuel/core/classes/errorhandler.php b/fuel/core/classes/errorhandler.php deleted file mode 100755 index d4f6547..0000000 --- a/fuel/core/classes/errorhandler.php +++ /dev/null @@ -1,325 +0,0 @@ -code.' - '.$this->message.' in '.$this->file.' on line '.$this->line); - - if (\Fuel::$env != \Fuel::PRODUCTION and ($this->code & error_reporting()) == $this->code) - { - static::$count++; - \Errorhandler::exception_handler(new \ErrorException($this->message, $this->code, 0, $this->file, $this->line)); - } - } - elseif (\Fuel::$env != \Fuel::PRODUCTION - and static::$count == (\Config::get('errors.throttle', 10) + 1) - and ($this->severity & error_reporting()) == $this->severity) - { - static::$count++; - \Errorhandler::notice('Error throttling threshold was reached, no more full error reports are shown.', true); - } - } -} - -/** - * - */ -class Errorhandler -{ - public static $loglevel = \Fuel::L_ERROR; - - public static $levels = array( - 0 => 'Error', - E_ERROR => 'Fatal Error', - E_WARNING => 'Warning', - E_PARSE => 'Parsing Error', - E_NOTICE => 'Notice', - E_CORE_ERROR => 'Core Error', - E_CORE_WARNING => 'Core Warning', - E_COMPILE_ERROR => 'Compile Error', - E_COMPILE_WARNING => 'Compile Warning', - E_USER_ERROR => 'User Error', - E_USER_WARNING => 'User Warning', - E_USER_NOTICE => 'User Notice', - E_STRICT => 'Runtime Notice', - E_RECOVERABLE_ERROR => 'Runtime Recoverable error', - E_DEPRECATED => 'Runtime Deprecated code usage', - E_USER_DEPRECATED => 'User Deprecated code usage', - ); - - public static $fatal_levels = array(E_PARSE, E_ERROR, E_USER_ERROR, E_COMPILE_ERROR); - - public static $non_fatal_cache = array(); - - /** - * Native PHP shutdown handler - * - * @return string - */ - public static function shutdown_handler() - { - $last_error = error_get_last(); - - // Only show valid fatal errors - if ($last_error AND in_array($last_error['type'], static::$fatal_levels)) - { - $severity = static::$levels[$last_error['type']]; - logger(static::$loglevel, $severity.' - '.$last_error['message'].' in '.$last_error['file'].' on line '.$last_error['line']); - - $error = new \ErrorException($last_error['message'], $last_error['type'], 0, $last_error['file'], $last_error['line']); - if (\Fuel::$env != \Fuel::PRODUCTION) - { - static::show_php_error($error); - } - else - { - static::show_production_error($error); - } - - exit(1); - } - } - - /** - * PHP Exception handler - * - * @param Exception $e the exception - * @return bool - */ - public static function exception_handler($e) - { - // make sure we've got something useful passed - if ($e instanceOf \Exception or (PHP_VERSION_ID >= 70000 and $e instanceOf \Error)) - { - if (method_exists($e, 'handle')) - { - return $e->handle(); - } - - $severity = ( ! isset(static::$levels[$e->getCode()])) ? $e->getCode() : static::$levels[$e->getCode()]; - logger(static::$loglevel, $severity.' - '.$e->getMessage().' in '.$e->getFile().' on line '.$e->getLine()); - - if (\Fuel::$env != \Fuel::PRODUCTION) - { - static::show_php_error($e); - } - else - { - static::show_production_error($e); - } - } - else - { - die('Something was passed to the Exception handler that was neither an Error or an Exception !!!'); - } - - return true; - } - - /** - * PHP Error handler - * - * @param int $severity the severity code - * @param string $message the error message - * @param string $filepath the path to the file throwing the error - * @param int $line the line number of the error - * @return bool whether to continue with execution - */ - public static function error_handler($severity, $message, $filepath, $line) - { - // don't do anything if error reporting is disabled - if (error_reporting() !== 0) - { - $fatal = (bool) ( ! in_array($severity, \Config::get('errors.continue_on', array()))); - - if ($fatal) - { - throw new \PhpErrorException($message, $severity, 0, $filepath, $line); - } - else - { - // non-fatal, recover from the error - $e = new \PhpErrorException($message, $severity, 0, $filepath, $line); - $e->recover(); - } - } - - return true; - } - - /** - * Shows a small notice error, only when not in production or when forced. - * This is used by several libraries to notify the developer of certain things. - * - * @param string $msg the message to display - * @param bool $always_show whether to force display the notice or not - * @return void - */ - public static function notice($msg, $always_show = false) - { - $trace = array_merge(array('file' => '(unknown)', 'line' => '(unknown)'), \Arr::get(debug_backtrace(), 1)); - logger(\Fuel::L_DEBUG, 'Notice - '.$msg.' in '.$trace['file'].' on line '.$trace['line']); - - if (\Fuel::$is_test or ( ! $always_show and (\Fuel::$env == \Fuel::PRODUCTION or \Config::get('errors.notices', true) === false))) - { - return; - } - - $data['message'] = $msg; - $data['type'] = 'Notice'; - $data['filepath'] = \Fuel::clean_path($trace['file']); - $data['line'] = $trace['line']; - $data['function'] = $trace['function']; - - echo \View::forge('errors'.DS.'php_short', $data, false); - } - - /** - * Shows an error. It will stop script execution if the error code is not - * in the errors.continue_on whitelist. - * - * @param Exception $e the exception to show - * @return void - */ - protected static function show_php_error($e) - { - $fatal = (bool) ( ! in_array($e->getCode(), \Config::get('errors.continue_on', array()))); - $data = static::prepare_exception($e, $fatal); - - if ($fatal) - { - $data['contents'] = ob_get_contents(); - while (ob_get_level() > 0) - { - ob_end_clean(); - } - ob_start(\Config::get('ob_callback', null)); - } - else - { - static::$non_fatal_cache[] = $data; - } - - if (\Fuel::$is_cli) - { - \Cli::write(\Cli::color($data['severity'].' - '.$data['message'].' in '.\Fuel::clean_path($data['filepath']).' on line '.$data['error_line'], 'red')); - if (\Config::get('cli_backtrace')) - { - \Cli::write('Stack trace:'); - \Cli::write(\Debug::backtrace($e->getTrace())); - } - return; - } - - if ($fatal) - { - if ( ! headers_sent()) - { - $protocol = \Input::server('SERVER_PROTOCOL') ? \Input::server('SERVER_PROTOCOL') : 'HTTP/1.1'; - header($protocol.' 500 Internal Server Error'); - } - - $data['non_fatal'] = static::$non_fatal_cache; - - try - { - exit(\View::forge('errors'.DS.'php_fatal_error', $data, false)); - } - catch (\FuelException $view_exception) - { - exit($data['severity'].' - '.$data['message'].' in '.\Fuel::clean_path($data['filepath']).' on line '.$data['error_line']); - } - } - - try - { - echo \View::forge('errors'.DS.'php_error', $data, false); - } - catch (\FuelException $e) - { - echo $e->getMessage().'
'; - } - } - - /** - * Shows the errors/production view and exits. This only gets - * called when an error occurs in production mode. - * - * @return void - */ - protected static function show_production_error($e) - { - // when we're on CLI, always show the php error - if (\Fuel::$is_cli) - { - return static::show_php_error($e); - } - - if ( ! headers_sent()) - { - $protocol = \Input::server('SERVER_PROTOCOL') ? \Input::server('SERVER_PROTOCOL') : 'HTTP/1.1'; - header($protocol.' 500 Internal Server Error'); - } - exit(\View::forge('errors'.DS.'production')); - } - - protected static function prepare_exception($e, $fatal = true) - { - $data = array(); - $data['type'] = get_class($e); - $data['severity'] = $e->getCode(); - $data['message'] = $e->getMessage(); - $data['filepath'] = $e->getFile(); - $data['error_line'] = $e->getLine(); - $data['backtrace'] = $e->getTrace(); - - $data['severity'] = ( ! isset(static::$levels[$data['severity']])) ? $data['severity'] : static::$levels[$data['severity']]; - - foreach ($data['backtrace'] as $key => $trace) - { - if ( ! isset($trace['file'])) - { - unset($data['backtrace'][$key]); - } - elseif ($trace['file'] == COREPATH.'classes/error.php') - { - unset($data['backtrace'][$key]); - } - } - - $data['debug_lines'] = \Debug::file_lines($data['filepath'], $data['error_line'], $fatal); - $data['orig_filepath'] = $data['filepath']; - $data['filepath'] = \Fuel::clean_path($data['filepath']); - - $data['filepath'] = str_replace("\\", "/", $data['filepath']); - - return $data; - } - -} diff --git a/fuel/core/classes/event.php b/fuel/core/classes/event.php deleted file mode 100755 index 14ac9c3..0000000 --- a/fuel/core/classes/event.php +++ /dev/null @@ -1,87 +0,0 @@ - $callback) - { - $this->register($event, $callback); - } - } - - // -------------------------------------------------------------------- - - /** - * Register - * - * Registers a Callback for a given event - * - * @return void - */ - public function register() - { - // get any arguments passed - $callback = func_get_args(); - - // if the arguments are valid, register the event - if (isset($callback[0]) and is_string($callback[0]) and isset($callback[1]) and is_callable($callback[1])) - { - // make sure we have an array for this event - isset($this->_events[$callback[0]]) or $this->_events[$callback[0]] = array(); - - // store the callback on the call stack - if (empty($callback[2])) - { - array_unshift($this->_events[$callback[0]], $callback); - } - else - { - $this->_events[$callback[0]][] = $callback; - } - - // and report success - return true; - } - else - { - // can't register the event - return false; - } - } - - // -------------------------------------------------------------------- - - /** - * Unregister/remove one or all callbacks from event - * - * @param string $event event to remove from - * @param mixed $callback callback to remove [optional, null for all] - * @return boolean whether one or all callbacks have been removed - */ - public function unregister($event, $callback = null) - { - if (isset($this->_events[$event])) - { - if ($callback === null) - { - unset($this->_events[$event]); - return true; - } - - foreach ($this->_events[$event] as $i => $arguments) - { - if($callback === $arguments[1]) - { - unset($this->_events[$event][$i]); - return true; - } - } - } - - return false; - } - - // -------------------------------------------------------------------- - - /** - * Trigger - * - * Triggers an event and returns the results. The results can be returned - * in the following formats: - * - * 'array' - * 'json' - * 'serialized' - * 'string' - * - * @param string $event The name of the event - * @param mixed $data Any data that is to be passed to the listener - * @param string $return_type The return type - * @param boolean $reversed Whether to fire events ordered LIFO instead of FIFO - * @return mixed The return of the listeners, in the return type - */ - public function trigger($event, $data = '', $return_type = 'string', $reversed = false) - { - $calls = array(); - - // check if we have events registered - if ($this->has_events($event)) - { - $events = $reversed ? array_reverse($this->_events[$event], true) : $this->_events[$event]; - - // process them - foreach ($events as $arguments) - { - // get rid of the event name - array_shift($arguments); - - // get the callback method - $callback = array_shift($arguments); - - // call the callback event - if (is_callable($callback)) - { - $calls[] = call_user_func($callback, $data, $arguments); - } - } - } - - return $this->_format_return($calls, $return_type); - } - - // -------------------------------------------------------------------- - - /** - * Has Listeners - * - * Checks if the event has listeners - * - * @param string $event The name of the event - * @return bool Whether the event has listeners - */ - public function has_events($event) - { - if (isset($this->_events[$event]) and count($this->_events[$event]) > 0) - { - return true; - } - return false; - } - - // -------------------------------------------------------------------- - - /** - * Format Return - * - * Formats the return in the given type - * - * @param array $calls The array of returns - * @param string $return_type The return type - * @return mixed The formatted return - */ - protected function _format_return(array $calls, $return_type) - { - switch ($return_type) - { - case 'array': - return $calls; - break; - case 'json': - return json_encode($calls); - break; - case 'none': - return null; - case 'serialized': - return serialize($calls); - break; - case 'string': - $str = ''; - foreach ($calls as $call) - { - $str .= $call; - } - return $str; - break; - default: - return $calls; - break; - } - } -} diff --git a/fuel/core/classes/fieldset.php b/fuel/core/classes/fieldset.php deleted file mode 100755 index 259f2ac..0000000 --- a/fuel/core/classes/fieldset.php +++ /dev/null @@ -1,888 +0,0 @@ -validation($config['validation_instance']); - unset($config['validation_instance']); - } - if (isset($config['form_instance'])) - { - $this->form($config['form_instance']); - unset($config['form_instance']); - } - - $this->name = (string) $name; - $this->config = $config; - } - - /** - * Get related Validation instance or create it - * - * @param bool|Validation $instance - * @return Validation - */ - public function validation($instance = true) - { - if ($instance instanceof Validation) - { - $this->validation = $instance; - return $instance; - } - - if (empty($this->validation) and $instance === true) - { - $this->validation = \Validation::forge($this); - } - - return $this->validation; - } - - /** - * Get related Form instance or create it - * - * @param bool|Form $instance - * @return Form - */ - public function form($instance = true) - { - if ($instance instanceof Form) - { - $this->form = $instance; - return $instance; - } - - if (empty($this->form) and $instance === true) - { - $this->form = \Form::forge($this); - } - - return $this->form; - } - - /** - * Set the tag to be used for this fieldset - * - * @param string $tag - * @return Fieldset this, to allow chaining - */ - public function set_fieldset_tag($tag) - { - $this->fieldset_tag = $tag; - - return $this; - } - - /** - * Set the parent Fieldset instance - * - * @param Fieldset $fieldset parent fieldset to which this belongs - * @return Fieldset - */ - public function set_parent(Fieldset $fieldset) - { - if ( ! empty($this->fieldset_parent)) - { - throw new \RuntimeException('Fieldset already has a parent, belongs to "'.$this->parent()->name.'".'); - } - - $children = $fieldset->children(); - while ($child = array_shift($children)) - { - if ($child === $this) - { - throw new \RuntimeException('Circular reference detected, adding a Fieldset that\'s already a child as a parent.'); - } - $children = array_merge($child->children(), $children); - } - - $this->fieldset_parent = $fieldset; - $fieldset->add_child($this); - return $this; - } - - /** - * Add a child Fieldset instance - * - * @param Fieldset $fieldset - * @return Fieldset - */ - protected function add_child(Fieldset $fieldset) - { - if (is_null($fieldset->fieldset_tag)) - { - $fieldset->fieldset_tag = 'fieldset'; - } - - $this->fieldset_children[$fieldset->name] = $fieldset; - return $this; - } - - /** - * Factory for Fieldset_Field objects - * - * @param string - * @param string - * @param array - * @param array - * @return Fieldset_Field - */ - public function add($name, $label = '', array $attributes = array(), array $rules = array()) - { - if ($name instanceof Fieldset_Field) - { - if ($name->name == '' or $this->field($name->name) !== false) - { - throw new \RuntimeException('Fieldname empty or already exists in this Fieldset: "'.$name->name.'".'); - } - - $name->set_fieldset($this); - $this->fields[$name->name] = $name; - return $name; - } - elseif ($name instanceof Fieldset) - { - if (empty($name->name) or $this->field($name->name) !== false) - { - throw new \RuntimeException('Fieldset name empty or already exists in this Fieldset: "'.$name->name.'".'); - } - - $name->set_parent($this); - $this->fields[$name->name] = $name; - return $name; - } - - if (empty($name) || (is_array($name) and empty($name['name']))) - { - throw new \InvalidArgumentException('Cannot create field without name.'); - } - - // Allow passing the whole config in an array, will overwrite other values if that's the case - if (is_array($name)) - { - $attributes = $name; - $label = isset($name['label']) ? $name['label'] : ''; - $rules = isset($name['rules']) ? $name['rules'] : array(); - $name = $name['name']; - } - - // Check if it exists already, if so: return and give notice - if ($field = $this->field($name)) - { - \Errorhandler::notice('Field with this name exists already in this fieldset: "'.$name.'".'); - return $field; - } - - $this->fields[$name] = new \Fieldset_Field($name, $label, $attributes, $rules, $this); - - return $this->fields[$name]; - } - - /** - * Add a new Fieldset_Field before an existing field in a Fieldset - * - * @param string $name - * @param string $label - * @param array $attributes - * @param array $rules - * @param string $fieldname fieldname before which the new field is inserted in the fieldset - * @return Fieldset_Field - */ - public function add_before($name, $label = '', array $attributes = array(), array $rules = array(), $fieldname = null) - { - $field = $this->add($name, $label, $attributes, $rules); - - // Remove from tail and reinsert at correct location - unset($this->fields[$field->name]); - - if ( ! \Arr::insert_before_key($this->fields, array($field->name => $field), $fieldname, true)) - { - throw new \RuntimeException('Field "'.$fieldname.'" does not exist in this Fieldset. Field "'.$name.'" can not be added.'); - } - - return $field; - } - - /** - * Add a new Fieldset_Field after an existing field in a Fieldset - * - * @param string $name - * @param string $label - * @param array $attributes - * @param array $rules - * @param string $fieldname fieldname after which the new field is inserted in the fieldset - * @return Fieldset_Field - */ - public function add_after($name, $label = '', array $attributes = array(), array $rules = array(), $fieldname = null) - { - $field = $this->add($name, $label, $attributes, $rules); - - // Remove from tail and reinsert at correct location - unset($this->fields[$field->name]); - if ( ! \Arr::insert_after_key($this->fields, array($field->name => $field), $fieldname, true)) - { - throw new \RuntimeException('Field "'.$fieldname.'" does not exist in this Fieldset. Field "'.$name.'" can not be added.'); - } - - return $field; - } - - /** - * Delete a field instance - * - * @param string field name or null to fetch an array of all - * @return Fieldset this fieldset, for chaining - */ - public function delete($name) - { - if (isset($this->fields[$name])) - { - unset($this->fields[$name]); - } - - return $this; - } - - /** - * Get Field instance - * - * @param string|null $name field name or null to fetch an array of all - * @param bool $flatten whether to get the fields array or flattened array - * @param bool $tabular_form whether to include tabular form fields in the flattened array - * @return Fieldset_Field|false returns false when field wasn't found - */ - public function field($name = null, $flatten = false, $tabular_form = true) - { - if ($name === null) - { - $fields = $this->fields; - - if ($flatten) - { - foreach ($this->fieldset_children as $fs_name => $fieldset) - { - if ($tabular_form or ! $fieldset->get_tabular_form()) - { - \Arr::insert_after_key($fields, $fieldset->field(null, true), $fs_name); - } - unset($fields[$fs_name]); - } - } - return $fields; - } - - if ( ! array_key_exists($name, $this->fields)) - { - if ($flatten) - { - foreach ($this->fieldset_children as $fieldset) - { - if (($field = $fieldset->field($name)) !== false) - { - return $field; - } - } - } - return false; - } - - return $this->fields[$name]; - } - - /** - * Add a model's fields - * The model must have a method "set_form_fields" that takes this Fieldset instance - * and adds fields to it. - * - * @param string|Object $class either a full classname (including full namespace) or object instance - * @param array|Object $instance array or object that has the exactly same named properties to populate the fields - * @param string $method method name to call on model for field fetching - * @return Fieldset this, to allow chaining - */ - public function add_model($class, $instance = null, $method = 'set_form_fields') - { - // Add model to validation callables for validation rules - $this->validation()->add_callable($class); - - if ((is_string($class) and is_callable($callback = array('\\'.$class, $method))) - || is_callable($callback = array($class, $method))) - { - $instance ? call_user_func($callback, $this, $instance) : call_user_func($callback, $this); - } - - return $this; - } - - /** - * Sets a config value on the fieldset - * - * @param string $config - * @param mixed $value - * @return Fieldset this, to allow chaining - */ - public function set_config($config, $value = null) - { - $config = is_array($config) ? $config : array($config => $value); - foreach ($config as $key => $value) - { - if (strpos($key, '.') === false) - { - $this->config[$key] = $value; - } - else - { - \Arr::set($this->config, $key, $value); - } - } - - return $this; - } - - /** - * Get a single or multiple config values by key - * - * @param string|array $key a single key or multiple in an array, empty to fetch all - * @param mixed $default default output when config wasn't set - * @return mixed|array a single config value or multiple in an array when $key input was an array - */ - public function get_config($key = null, $default = null) - { - if ($key === null) - { - return $this->config; - } - - if (is_array($key)) - { - $output = array(); - foreach ($key as $k) - { - $output[$k] = $this->get_config($k, $default); - } - return $output; - } - - if (strpos($key, '.') === false) - { - return array_key_exists($key, $this->config) ? $this->config[$key] : $default; - } - else - { - return \Arr::get($this->config, $key, $default); - } - } - - /** - * Populate the form's values using an input array or object - * - * @param array|object $input - * @param bool $repopulate - * @return Fieldset this, to allow chaining - */ - public function populate($input, $repopulate = false) - { - $fields = $this->field(null, true, false); - foreach ($fields as $f) - { - if (is_array($input) or $input instanceof \ArrayAccess) - { - // convert form field array's to Fuel dotted notation - $name = str_replace(array('[', ']'), array('.', ''), $f->name); - - // fetch the value for this field, and set it if found - $value = \Arr::get($input, $name, null); - $value === null and $value = \Arr::get($input, $f->basename, null); - $value !== null and $f->set_value($value, true); - } - elseif (is_object($input) and property_exists($input, $f->basename)) - { - $f->set_value($input->{$f->basename}, true); - } - } - - // Optionally overwrite values using post/get - if ($repopulate) - { - $this->repopulate(); - } - - return $this; - } - - /** - * Set all fields to the input from get or post (depends on the form method attribute) - * - * @return Fieldset this, to allow chaining - */ - public function repopulate() - { - $fields = $this->field(null, true); - foreach ($fields as $f) - { - // Don't repopulate the CSRF field - if ($f->name === \Config::get('security.csrf_token_key', 'fuel_csrf_token')) - { - continue; - } - - if (($value = $f->input()) !== null) - { - $f->set_value($value, true); - } - } - - return $this; - } - - /** - * Build the fieldset HTML - * - * @param mixed $action - * @return string - */ - public function build($action = null) - { - $attributes = $this->get_config('form_attributes'); - if ($action and ($this->fieldset_tag == 'form' or empty($this->fieldset_tag))) - { - $attributes['action'] = $action; - } - - $open = ($this->fieldset_tag == 'form' or empty($this->fieldset_tag)) - ? $this->form()->open($attributes).PHP_EOL - : $this->form()->{$this->fieldset_tag.'_open'}($attributes); - - $fields_output = ''; - - // construct the tabular form table header - if ($this->tabular_form_relation) - { - $properties = call_user_func($this->tabular_form_model.'::properties'); - $primary_keys = call_user_func($this->tabular_form_model.'::primary_key'); - $fields_output .= ''.PHP_EOL; - foreach ($properties as $field => $settings) - { - if ((isset($settings['skip']) and $settings['skip']) or in_array($field, $primary_keys)) - { - continue; - } - if (isset($settings['form']['type']) and ($settings['form']['type'] === false or $settings['form']['type'] === 'hidden')) - { - continue; - } - $fields_output .= "\t".''.(isset($settings['label']) ? \Lang::get($settings['label'], array(), $settings['label']) : '').''.PHP_EOL; - } - $fields_output .= "\t".''.\Config::get('form.tabular_delete_label', 'Delete?').''.PHP_EOL; - - $fields_output .= ''.PHP_EOL; - } - - foreach ($this->field() as $f) - { - in_array($f->name, $this->disabled) or $fields_output .= $f->build().PHP_EOL; - } - - $close = ($this->fieldset_tag == 'form' or empty($this->fieldset_tag)) - ? $this->form()->close($attributes).PHP_EOL - : $this->form()->{$this->fieldset_tag.'_close'}($attributes); - - $template = $this->form()->get_config((empty($this->fieldset_tag) ? 'form' : $this->fieldset_tag).'_template', - "\n\t\t{open}\n\t\t\n{fields}\n\t\t
\n\t\t{close}\n"); - - $template = str_replace(array('{form_open}', '{open}', '{fields}', '{form_close}', '{close}'), - array($open, $open, $fields_output, $close, $close), - $template); - - return $template; - } - - /** - * Enable a disabled field from being build - * - * @param mixed $name - * @return Fieldset this, to allow chaining - */ - public function enable($name = null) - { - // Check if it exists. if not, bail out - if ( ! $this->field($name)) - { - throw new \RuntimeException('Field "'.$name.'" does not exist in this Fieldset.'); - } - - if (isset($this->disabled[$name])) - { - unset($this->disabled[$name]); - } - - return $this; - } - - /** - * Disable a field from being build - * - * @param mixed $name - * @return Fieldset this, to allow chaining - */ - public function disable($name = null) - { - // Check if it exists. if not, bail out - if ( ! $this->field($name)) - { - throw new \RuntimeException('Field "'.$name.'" does not exist in this Fieldset.'); - } - - isset($this->disabled[$name]) or $this->disabled[$name] = $name; - - return $this; - } - - /** - * Magic method toString that will build this as a form - * - * @return string - */ - public function __toString() - { - return $this->build(); - } - - /** - * Return parent Fieldset - * - * @return Fieldset - */ - public function parent() - { - return $this->fieldset_parent; - } - - /** - * Return the child fieldset instances - * - * @return array - */ - public function children() - { - return $this->fieldset_children; - } - - /** - * Alias for $this->validation()->input() - * - * @param string $field - * @return mixed - */ - public function input($field = null) - { - return $this->validation()->input($field); - } - - /** - * Alias for $this->validation()->validated() - * - * @param string $field - * @return mixed - */ - public function validated($field = null) - { - return $this->validation()->validated($field); - } - - /** - * Alias for $this->validation()->error() - * - * @param string $field - * @return Validation_Error|array - */ - public function error($field = null) - { - return $this->validation()->error($field); - } - - /** - * Alias for $this->validation()->show_errors() - * - * @param array $config - * @return string - */ - public function show_errors(array $config = array()) - { - return $this->validation()->show_errors($config); - } - - /** - * Get the fieldset name - * - * @return string - */ - public function get_name() - { - return $this->name; - } - - /** - * Enable or disable the tabular form feature of this fieldset - * - * @param string $model Model on which to define the tabular form - * @param string $relation Relation of the Model on the tabular form is modeled - * @param array $parent Collection of Model objects from a many relation - * @param int $blanks Number of empty rows to generate - * - * @return Fieldset this, to allow chaining - */ - public function set_tabular_form($model, $relation, $parent, $blanks = 1) - { - // make sure our parent is an ORM model instance - if ( ! $parent instanceOf \Orm\Model) - { - throw new \RuntimeException('Parent passed to set_tabular_form() is not an ORM model object.'); - } - - // validate the model and relation - // fetch the relations of the parent model - $relations = call_user_func(array($parent, 'relations')); - if ( ! array_key_exists($relation, $relations)) - { - throw new \RuntimeException('Relation passed to set_tabular_form() is not a valid relation of the ORM parent model object.'); - } - - // check for compound primary keys - try - { - // fetch the relations of the parent model - $primary_key = call_user_func($model.'::primary_key'); - - // we don't support compound primary keys - if (count($primary_key) !== 1) - { - throw new \RuntimeException('set_tabular_form() does not supports models with compound primary keys.'); - } - - // store the primary key name, we need that later - $primary_key = reset($primary_key); - } - catch (\Exception $e) - { - throw new \RuntimeException('Unable to fetch the models primary key information.'); - } - - // store the tabular form class name - $this->tabular_form_model = $model; - - // and the relation on which we model the rows - $this->tabular_form_relation = $relation; - - // load the form config if not loaded yet - \Config::load('form', true); - - // load the config for embedded forms - $this->set_config(array( - 'form_template' => \Config::get('form.tabular_form_template', "{fields}
\n"), - 'field_template' => \Config::get('form.tabular_field_template', "{field}"), - )); - - // add the rows to the tabular form fieldset - foreach ($parent->{$relation} as $row) - { - // add the row fieldset to the tabular form fieldset - $this->add($fieldset = \Fieldset::forge($this->tabular_form_relation.'_row_'.$row->{$primary_key})); - - // and add the model fields to the row fielset - $fieldset->add_model($model, $row)->set_fieldset_tag(false); - $fieldset->set_config(array( - 'form_template' => \Config::get('form.tabular_row_template', "{fields}
\n"), - 'field_template' => \Config::get('form.tabular_row_field_template', "{field}"), - )); - $fieldset->add($this->tabular_form_relation.'['.$row->{$primary_key}.'][_delete]', '', array('type' => 'checkbox', 'value' => 1)); - } - - // and finish with zero or more empty rows so we can add new data - if ( ! is_numeric($blanks) or $blanks < 0) - { - $blanks = 1; - } - for ($i = 0; $i < $blanks; $i++) - { - $this->add($fieldset = \Fieldset::forge($this->tabular_form_relation.'_new_'.$i)); - $fieldset->add_model($model)->set_fieldset_tag(false); - $fieldset->set_config(array( - 'form_template' => \Config::get('form.tabular_row_template', "{fields}"), - 'field_template' => \Config::get('form.tabular_row_field_template', "{field}"), - )); - $fieldset->add($this->tabular_form_relation.'_new['.$i.'][_delete]', '', array('type' => 'checkbox', 'value' => 0, 'disabled' => 'disabled')); - - // no required rules on this row - foreach ($fieldset->field() as $f) - { - $f->delete_rule('required', false)->delete_rule('required_with', false); - } - } - - return $this; - } - - /** - * return the tabular form relation of this fieldset - * - * @return bool - */ - public function get_tabular_form() - { - return $this->tabular_form_relation; - } -} diff --git a/fuel/core/classes/fieldset/field.php b/fuel/core/classes/fieldset/field.php deleted file mode 100755 index fd7bbc7..0000000 --- a/fuel/core/classes/fieldset/field.php +++ /dev/null @@ -1,666 +0,0 @@ -name = (string) $name; - - if ($this->name === "") - { - throw new \RuntimeException('Fieldset field name may not be empty.'); - } - - // determine the field's base name (for fields with array indices) - $this->basename = ($pos = strpos($this->name, '[')) ? rtrim(substr(strrchr($this->name, '['), 1), ']') : $this->name; - - $this->fieldset = $fieldset instanceof Fieldset ? $fieldset : null; - - // Don't allow name in attributes - unset($attributes['name']); - - // Take rules out of attributes - unset($attributes['rules']); - - // Use specific setter when available - foreach ($attributes as $attr => $val) - { - if (method_exists($this, $method = 'set_'.$attr)) - { - $this->{$method}($val); - unset($attributes[$attr]); - } - } - - // Add default "type" attribute if not specified - empty($attributes['type']) and $this->set_type($this->type); - - // only when non-empty, will supersede what was given in $attributes - $label and $this->set_label($label); - - $this->attributes = array_merge($this->attributes, $attributes); - - foreach ($rules as $rule) - { - call_fuel_func_array(array($this, 'add_rule'), (array) $rule); - } - } - - /** - * @param Fieldset $fieldset Fieldset to assign the field to - * @return Fieldset_Field - * @throws \RuntimeException - */ - public function set_fieldset(Fieldset $fieldset) - { - // if we currently have a fieldset - if ($this->fieldset) - { - // remove the field from the fieldset - $this->fieldset->delete($this->name); - - // reset the fieldset - $this->fieldset = null; - - // add this field to the new fieldset - $fieldset->add($this); - } - - // assign the new fieldset - $this->fieldset = $fieldset; - - return $this; - } - - /** - * Change the field label - * - * @param string $label - * @return Fieldset_Field this, to allow chaining - */ - public function set_label($label) - { - $this->label = $label; - $this->set_attribute('label', $label); - - return $this; - } - - /** - * Change the field type for form generation - * - * @param string $type - * @return Fieldset_Field this, to allow chaining - */ - public function set_type($type) - { - $this->type = $type; - $this->set_attribute('type', $type); - - return $this; - } - - /** - * Change the field's current or default value - * - * @param string $value - * @param bool $repopulate - * @return Fieldset_Field this, to allow chaining - */ - public function set_value($value, $repopulate = false) - { - // Repopulation is handled slightly different in some cases - if ($repopulate) - { - if (($this->type == 'radio' or $this->type == 'checkbox') and empty($this->options)) - { - if ($this->value == $value) - { - $this->set_attribute('checked', 'checked'); - } - - return $this; - } - } - - $this->value = $value; - $this->set_attribute('value', $value); - - return $this; - } - - /** - * Change the field description - * - * @param string $description - * @return Fieldset_Field this, to allow chaining - */ - public function set_description($description) - { - $this->description = strval($description); - - return $this; - } - - /** - * Template the output - * - * @param string $template - * @return Fieldset_Field this, to allow chaining - */ - public function set_template($template = null) - { - $this->template = $template; - - return $this; - } - - /** - * Overwrite a default error message - * - * @param string $rule - * @param string $msg - * @return Fieldset_Field - */ - public function set_error_message($rule, $msg) - { - empty($rule) and $rule = 0; - $this->error_messages[$rule] = strval($msg); - - return $this; - } - - /** - * Check if a rule has an error message overwrite - * - * @param string $rule - * @return null|string - */ - public function get_error_message($rule) - { - if (isset($this->error_messages[$rule])) - { - return $this->error_messages[$rule]; - } - elseif (isset($this->error_messages[0])) - { - return $this->error_messages[0]; - } - - return null; - } - - /** - * Add a validation rule - * any further arguements after the callback will be used as arguements for the callback - * - * @param string|Callback either a validation rule or full callback - * @return Fieldset_Field this, to allow chaining - */ - public function add_rule($callback) - { - $args = array_slice(func_get_args(), 1); - $this->rules[] = array($callback, $args); - - // Set required setting for forms when rule was applied - if ($callback === 'required') - { - $this->set_attribute('required', 'required'); - } - - return $this; - } - - /** - * Delete a validation rule - * - * @param string|Callback either a validation rule or full callback - * @param bool whether to also reset related attributes - * @return Fieldset_Field this, to allow chaining - */ - public function delete_rule($callback, $set_attr = true) - { - foreach($this->rules as $index => $rule) - { - if ($rule[0] === $callback) - { - unset($this->rules[$index]); - break; - } - } - - if ($callback === 'required' and $set_attr) - { - unset($this->attributes[$callback]); - } - - return $this; - } - - /** - * Sets an attribute on the field - * - * @param string - * @param mixed new value or null to unset - * @return Fieldset_Field this, to allow chaining - */ - public function set_attribute($attr, $value = null) - { - $attr = is_array($attr) ? $attr : array($attr => $value); - foreach ($attr as $key => $value) - { - if ($value === null) - { - unset($this->attributes[$key]); - } - else - { - $this->attributes[$key] = $value; - } - } - - return $this; - } - - /** - * Get a single or multiple attributes by key - * - * @param string|array a single key or multiple in an array, empty to fetch all - * @param mixed default output when attribute wasn't set - * @return mixed|array a single attribute or multiple in an array when $key input was an array - */ - public function get_attribute($key = null, $default = null) - { - if ($key === null) - { - return $this->attributes; - } - - if (is_array($key)) - { - $output = array(); - foreach ($key as $k) - { - $output[$k] = array_key_exists($k, $this->attributes) ? $this->attributes[$k] : $default; - } - return $output; - } - - return array_key_exists($key, $this->attributes) ? $this->attributes[$key] : $default; - } - - /** - * Add an option value with label - * - * @param string|array one option value, or multiple value=>label pairs in an array - * @param string - * @param bool Whether or not to replace the current options - * @return Fieldset_Field this, to allow chaining - */ - public function set_options($value, $label = null, $replace_options = false) - { - if ( ! is_array($value)) - { - \Arr::set($this->options, $value, $label); - return $this; - } - - $merge = function(&$array, $new, $merge) - { - foreach ($new as $k => $v) - { - if (isset($array[$k]) and is_array($array[$k]) and is_array($v)) - { - $merge($array[$k], $v); - } - else - { - $array[$k] = $v; - } - } - }; - - ($replace_options or empty($this->options)) ? $this->options = $value : $merge($this->options, $value, $merge); - - return $this; - } - - /** - * Magic get method to allow getting class properties but still having them protected - * to disallow writing. - * - * @return mixed - */ - public function __get($property) - { - return $this->$property; - } - - /** - * Build the field - * - * @return string - */ - public function __toString() - { - try - { - return $this->build(); - } - catch (\Exception $e) - { - return $e->getMessage(); - } - } - - /** - * Return the parent Fieldset object - * - * @return Fieldset - */ - public function fieldset() - { - return $this->fieldset; - } - - /** - * Alias for $this->fieldset->add() to allow chaining - * - * @return Fieldset_Field - */ - public function add($name, $label = '', array $attributes = array(), array $rules = array()) - { - return $this->fieldset()->add($name, $label, $attributes, $rules); - } - - /** - * Alias for $this->fieldset->add_before() to allow chaining - * - * @return Fieldset_Field - */ - public function add_before($name, $label = '', array $attributes = array(), array $rules = array(), $fieldname = null) - { - return $this->fieldset()->add_before($name, $label, $attributes, $rules, $fieldname); - } - - /** - * Alias for $this->fieldset->add_after() to allow chaining - * - * @return Fieldset_Field - */ - public function add_after($name, $label = '', array $attributes = array(), array $rules = array(), $fieldname = null) - { - return $this->fieldset()->add_after($name, $label, $attributes, $rules, $fieldname); - } - - /** - * Build the field - * - * @return string - */ - public function build() - { - $form = $this->fieldset()->form(); - - // Add IDs when auto-id is on - if ($form->get_config('auto_id', false) === true and $this->get_attribute('id') == '') - { - $auto_id = $form->get_config('auto_id_prefix', '') - .str_replace(array('[', ']'), array('-', ''), $this->name); - $this->set_attribute('id', $auto_id); - } - - switch( ! empty($this->attributes['tag']) ? $this->attributes['tag'] : $this->type) - { - case 'hidden': - $build_field = $form->hidden($this->name, $this->value, $this->attributes); - break; - - case 'radio': - case 'checkbox': - if ($this->options) - { - $build_field = array(); - $i = 0; - foreach ($this->options as $value => $label) - { - $attributes = $this->attributes; - $attributes['name'] = $this->name; - $this->type == 'checkbox' and $attributes['name'] .= '['.$i.']'; - - $attributes['value'] = $value; - $attributes['label'] = $label; - - if (is_array($this->value) ? in_array($value, $this->value) : $value == $this->value) - { - $attributes['checked'] = 'checked'; - } - - if( ! empty($attributes['id'])) - { - $attributes['id'] .= '_'.$i; - } - else - { - $attributes['id'] = null; - } - $build_field[$form->label($label, null, array('for' => $attributes['id']))] = $this->type == 'radio' - ? $form->radio($attributes) - : $form->checkbox($attributes); - - $i++; - } - } - else - { - $build_field = $this->type == 'radio' - ? $form->radio($this->name, $this->value, $this->attributes) - : $form->checkbox($this->name, $this->value, $this->attributes); - } - break; - - case 'select': - $attributes = $this->attributes; - $name = $this->name; - unset($attributes['type']); - array_key_exists('multiple', $attributes) and $name .= '[]'; - $build_field = $form->select($name, $this->value, $this->options, $attributes); - break; - - case 'textarea': - $attributes = $this->attributes; - unset($attributes['type']); - $build_field = $form->textarea($this->name, $this->value, $attributes); - break; - - case 'button': - $build_field = $form->button($this->name, $this->value, $this->attributes); - break; - - case false: - $build_field = ''; - break; - - default: - $build_field = $form->input($this->name, $this->value, $this->attributes); - break; - } - - if (empty($build_field) or $this->type == 'hidden') - { - return $build_field; - } - - return $this->template($build_field); - } - - protected function template($build_field) - { - $form = $this->fieldset()->form(); - - $required_mark = $this->get_attribute('required', null) ? $form->get_config('required_mark', null) : null; - $label = $this->label ? $form->label($this->label, null, array('id' => 'label_'.$this->name, 'for' => $this->get_attribute('id', null), 'class' => $form->get_config('label_class', null))) : ''; - $error_template = $form->get_config('error_template', ''); - $error_msg = ($form->get_config('inline_errors') && $this->error()) ? str_replace('{error_msg}', $this->error(), $error_template) : ''; - $error_class = $this->error() ? $form->get_config('error_class') : ''; - - if (is_array($build_field)) - { - $label = $this->label ? str_replace('{label}', $this->label, $form->get_config('group_label', '{label}')) : ''; - $template = $this->template ?: $form->get_config('multi_field_template', "\t\t\n\t\t\t{group_label}{required}\n\t\t\t{fields}\n\t\t\t\t{field} {label}
\n{fields}\t\t\t{error_msg}\n\t\t\t\n\t\t\n"); - if ($template && preg_match('#\{fields\}(.*)\{fields\}#Dus', $template, $match) > 0) - { - $build_fields = ''; - foreach ($build_field as $lbl => $bf) - { - $bf_temp = str_replace('{label}', $lbl, $match[1]); - $bf_temp = str_replace('{required}', $required_mark, $bf_temp); - $bf_temp = str_replace('{field}', $bf, $bf_temp); - $build_fields .= $bf_temp; - } - - $template = str_replace($match[0], '{fields}', $template); - $template = str_replace(array('{group_label}', '{required}', '{fields}', '{error_msg}', '{error_class}', '{description}'), array($label, $required_mark, $build_fields, $error_msg, $error_class, $this->description), $template); - - return $template; - } - - // still here? wasn't a multi field template available, try the normal one with imploded $build_field - $build_field = implode(' ', $build_field); - } - - // determine the field_id, which allows us to identify the field for CSS purposes - $field_id = 'col_'.$this->name; - if ($parent = $this->fieldset()->parent()) - { - $parent->get_tabular_form() and $field_id = $parent->get_tabular_form().'_col_'.$this->basename; - } - - $template = $this->template ?: $form->get_config('field_template', "\t\t\n\t\t\t{label}{required}\n\t\t\t{field} {description} {error_msg}\n\t\t\n"); - $template = str_replace(array('{label}', '{required}', '{field}', '{error_msg}', '{error_class}', '{description}', '{field_id}'), - array($label, $required_mark, $build_field, $error_msg, $error_class, $this->description, $field_id), - $template); - - return $template; - } - - /** - * Alias for $this->fieldset->validation->input() for this field - * - * @return mixed - */ - public function input() - { - return $this->fieldset()->validation()->input($this->name); - } - - /** - * Alias for $this->fieldset->validation->validated() for this field - * - * @return mixed - */ - public function validated() - { - return $this->fieldset()->validation()->validated($this->name); - } - - /** - * Alias for $this->fieldset->validation->error() for this field - * - * @return Validation_Error - */ - public function error() - { - return $this->fieldset()->validation()->error($this->name); - } -} diff --git a/fuel/core/classes/file.php b/fuel/core/classes/file.php deleted file mode 100755 index 8bcb963..0000000 --- a/fuel/core/classes/file.php +++ /dev/null @@ -1,922 +0,0 @@ - $config) - { - static::$areas[$name] = \File_Area::forge($config); - } - } - - public static function forge(array $config = array()) - { - return \File_Area::forge($config); - } - - /** - * Instance - * - * @param string|File_Area|null $area file area name, object or null for base area - * @return File_Area - */ - public static function instance($area = null) - { - if ($area instanceof File_Area) - { - return $area; - } - - $instance = array_key_exists($area, static::$areas) ? static::$areas[$area] : false; - - if ($instance === false) - { - throw new \InvalidArgumentException('There is no file instance named "'.$area.'".'); - } - - return $instance; - } - - /** - * File & directory objects factory - * - * @param string $path path to the file or directory - * @param array $config configuration items - * @param string|File_Area|null $area file area name, object or null for base area - * @return File_Handler_File - */ - public static function get($path, array $config = array(), $area = null) - { - return static::instance($area)->get_handler($path, $config); - } - - /** - * Get the url. - * - * @param string $path - * @param array $config - * @param null $area - * @return bool - */ - public static function get_url($path, array $config = array(), $area = null) - { - return static::get($path, $config, $area)->get_url(); - } - - /** - * Check for file existence - * - * @param string $path path to file to check - * @param string|File_Area|null $area file area name, object or null for base area - * @return bool - */ - public static function exists($path, $area = null) - { - $path = rtrim(static::instance($area)->get_path($path), '\\/'); - - // resolve symlinks - while ($path and is_link($path)) - { - $path = readlink($path); - } - - return is_file($path); - } - - /** - * Create a file - * - * @param string $basepath directory where to create file - * @param string $name filename - * @param null $contents contents of file - * @param string|File_Area|null $area file area name, object or null for base area - * @return bool - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function create($basepath, $name, $contents = null, $area = null) - { - $basepath = rtrim(static::instance($area)->get_path($basepath), '\\/').DS; - $new_file = static::instance($area)->get_path($basepath.$name); - - if ( ! is_dir($basepath) or ! is_writable($basepath)) - { - throw new \InvalidPathException('Invalid basepath: "'.$basepath.'", cannot create file at this location.'); - } - elseif (is_file($new_file)) - { - throw new \FileAccessException('File: "'.$new_file.'" already exists, cannot be created.'); - } - - $file = static::open_file(@fopen($new_file, 'c'), true, $area); - fwrite($file, $contents); - static::close_file($file, $area); - - return true; - } - - /** - * Create an empty directory - * - * @param string directory where to create new dir - * @param string dirname - * @param int (octal) file permissions - * @param string|File_Area|null file area name, object or null for non-specific - * @return bool - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function create_dir($basepath, $name, $chmod = null, $area = null) - { - $basepath = rtrim(static::instance($area)->get_path($basepath), '\\/').DS; - $new_dir = static::instance($area)->get_path($basepath.trim($name, '\\/')); - is_null($chmod) and $chmod = \Config::get('file.chmod.folders', 0777); - - if ( ! is_dir($basepath) or ! is_writable($basepath)) - { - throw new \InvalidPathException('Invalid basepath: "'.$basepath.'", cannot create directory at this location.'); - } - elseif (is_dir($new_dir)) - { - throw new \FileAccessException('Directory: "'.$new_dir.'" exists already, cannot be created.'); - } - - // unify the path separators, and get the part we need to add to the basepath - $new_dir = str_replace(array('\\', '/'), DS, $new_dir); - - // recursively create the directory. we can't use mkdir permissions or recursive - // due to the fact that mkdir is restricted by the current users umask - $path = ''; - foreach (explode(DS, $new_dir) as $dir) - { - // some security checking - if ($dir == '.' or $dir == '..') - { - throw new \FileAccessException('Directory to be created contains illegal segments.'); - } - - $path .= DS.$dir; - if ( ! is_dir($path)) - { - try - { - if ( ! mkdir($path)) - { - return false; - } - chmod($path, $chmod); - } - catch (\PHPErrorException $e) - { - return false; - } - } - } - - return true; - } - - /** - * Read file - * - * @param string $path file to read - * @param bool $as_string whether to use readfile() or file_get_contents() - * @param string|File_Area|null $area file area name, object or null for base area - * @return IO|string file contents - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function read($path, $as_string = false, $area = null) - { - $path = static::instance($area)->get_path($path); - - if ( ! is_file($path)) - { - throw new \InvalidPathException('Cannot read file: "'.$path.'", file does not exists.'); - } - - $file = static::open_file(@fopen($path, 'r'), LOCK_SH, $area); - $return = $as_string ? file_get_contents($path) : readfile($path); - static::close_file($file, $area); - - return $return; - } - - /** - * Read directory - * - * @param string $path directory to read - * @param int $depth depth to recurse directory, 1 is only current and 0 or smaller is unlimited - * @param Array|null $filter array of partial regexps or non-array for default - * @param string|File_Area|null $area file area name, object or null for base area - * @return array - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function read_dir($path, $depth = 0, $filter = null, $area = null) - { - $path = rtrim(static::instance($area)->get_path($path), '\\/').DS; - - if ( ! is_dir($path)) - { - throw new \InvalidPathException('Invalid path: "'.$path.'", directory cannot be read.'); - } - - if ( ! $fp = @opendir($path)) - { - throw new \FileAccessException('Could not open directory: "'.$path.'" for reading.'); - } - - // Use default when not set - if ( ! is_array($filter)) - { - $filter = array('!^\.'); - if ($extensions = static::instance($area)->extensions()) - { - foreach($extensions as $ext) - { - $filter[] = '\.'.$ext.'$'; - } - } - } - - $files = array(); - $dirs = array(); - $new_depth = $depth - 1; - - while (false !== ($file = readdir($fp))) - { - // Remove '.', '..' - if (in_array($file, array('.', '..'))) - { - continue; - } - // use filters when given - elseif ( ! empty($filter)) - { - $continue = false; // whether or not to continue - $matched = false; // whether any positive pattern matched - $positive = false; // whether positive filters are present - foreach($filter as $f => $type) - { - if (is_numeric($f)) - { - // generic rule - $f = $type; - } - else - { - // type specific rule - $is_file = is_file($path.$file); - if (($type === 'file' and ! $is_file) or ($type !== 'file' and $is_file)) - { - continue; - } - } - - $not = substr($f, 0, 1) === '!'; // whether it's a negative condition - $f = $not ? substr($f, 1) : $f; - // on negative condition a match leads to a continue - if (($match = preg_match('/'.$f.'/uiD', $file) > 0) and $not) - { - $continue = true; - } - - $positive = $positive ?: ! $not; // whether a positive condition was encountered - $matched = $matched ?: ($match and ! $not); // whether one of the filters has matched - } - - // continue when negative matched or when positive filters and nothing matched - if ($continue or $positive and ! $matched) - { - continue; - } - } - - if (@is_dir($path.$file)) - { - // Use recursion when depth not depleted or not limited... - if ($depth < 1 or $new_depth > 0) - { - $dirs[$file.DS] = static::read_dir($path.$file.DS, $new_depth, $filter, $area); - } - // ... or set dir to false when not read - else - { - $dirs[$file.DS] = false; - } - } - else - { - $files[] = $file; - } - } - - closedir($fp); - - // sort dirs & files naturally and return array with dirs on top and files - uksort($dirs, 'strnatcasecmp'); - natcasesort($files); - return array_merge($dirs, $files); - } - - /** - * Update a file - * - * @param string $basepath directory where to write the file - * @param string $name filename - * @param string $contents contents of file - * @param string|File_Area|null $area file area name, object or null for base area - * @return bool - * @throws \InvalidPathException - * @throws \FileAccessException - * @throws \OutsideAreaException - */ - public static function update($basepath, $name, $contents = null, $area = null) - { - $basepath = rtrim(static::instance($area)->get_path($basepath), '\\/').DS; - $new_file = static::instance($area)->get_path($basepath.$name); - - if ( ! $file = static::open_file(@fopen($new_file, 'w'), true, $area)) - { - if ( ! is_dir($basepath) or ! is_writable($basepath)) - { - throw new \InvalidPathException('Invalid basepath: "'.$basepath.'", cannot update a file at this location.'); - } - - throw new \FileAccessException('No write access to: "'.$basepath.'", cannot update a file.'); - } - - fwrite($file, $contents); - static::close_file($file, $area); - - return true; - } - - /** - * Append to a file - * - * @param string $basepath directory where to write the file - * @param string $name filename - * @param string $contents contents of file - * @param string|File_Area|null $area file area name, object or null for base area - * @return bool - * @throws \InvalidPathException - * @throws \FileAccessException - * @throws \OutsideAreaException - */ - public static function append($basepath, $name, $contents = null, $area = null) - { - $basepath = rtrim(static::instance($area)->get_path($basepath), '\\/').DS; - $new_file = static::instance($area)->get_path($basepath.$name); - - if ( ! is_file($new_file)) - { - throw new \FileAccessException('File: "'.$new_file.'" does not exist, cannot be appended.'); - } - - if ( ! $file = static::open_file(@fopen($new_file, 'a'), true, $area)) - { - if ( ! is_dir($basepath) or ! is_writable($basepath)) - { - throw new \InvalidPathException('Invalid basepath: "'.$basepath.'", cannot append to a file at this location.'); - } - - throw new \FileAccessException('No write access, cannot append to the file: "'.$file.'".'); - } - - fwrite($file, $contents); - static::close_file($file, $area); - - return true; - } - - /** - * Get the octal permissions for a file or directory - * - * @param string $path path to the file or directory - * @param string|File_Area|null $area file area name, object or null for base area - * @return string octal file permissions - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function get_permissions($path, $area = null) - { - $path = static::instance($area)->get_path($path); - - if ( ! file_exists($path)) - { - throw new \InvalidPathException('Path: "'.$path.'" is not a directory or a file, cannot get permissions.'); - } - - return substr(sprintf('%o', fileperms($path)), -4); - - } - - /** - * Get a file's or directory's created or modified timestamp. - * - * @param string $path path to the file or directory - * @param string $type modified or created - * @param string|File_Area|null $area file area name, object or null for base area - * @return int Unix Timestamp - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function get_time($path, $type = 'modified', $area = null) - { - $path = static::instance($area)->get_path($path); - - if ( ! file_exists($path)) - { - throw new \InvalidPathException('Path: "'.$path.'" is not a directory or a file, cannot get creation timestamp.'); - } - - if ($type === 'modified') - { - return filemtime($path); - } - elseif ($type === 'created') - { - return filectime($path); - } - else - { - throw new \UnexpectedValueException('File::time $type must be "modified" or "created".'); - } - } - - /** - * Get a file's size. - * - * @param string $path path to the file or directory - * @param mixed $area file area name, object or null for base area - * @return int the file's size in bytes - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function get_size($path, $area = null) - { - $path = static::instance($area)->get_path($path); - - if ( ! file_exists($path)) - { - throw new \InvalidPathException('Path: "'.$path.'" is not a directory or a file, cannot get size.'); - } - - return filesize($path); - } - - /** - * Rename directory or file - * - * @param string $path path to file or directory to rename - * @param string $new_path new path (full path, can also cause move) - * @param string|File_Area|null $source_area source path file area name, object or null for non-specific - * @param string|File_Area|null $target_area target path file area name, object or null for non-specific. Defaults to source_area if not set. - * @return bool - * @throws \FileAccessException - * @throws \OutsideAreaException - */ - public static function rename($path, $new_path, $source_area = null, $target_area = null) - { - $path = static::instance($source_area)->get_path($path); - $new_path = static::instance($target_area ?: $source_area)->get_path($new_path); - - return rename($path, $new_path); - } - - /** - * Alias for rename(), not needed but consistent with other methods - * - * @param string $path path to directory to rename - * @param string $new_path new path (full path, can also cause move) - * @param string|File_Area|null $source_area source path file area name, object or null for non-specific - * @param string|File_Area|null $target_area target path file area name, object or null for non-specific. Defaults to source_area if not set. - * @return bool - * @throws \FileAccessException - * @throws \OutsideAreaException - */ - public static function rename_dir($path, $new_path, $source_area = null, $target_area = null) - { - return static::rename($path, $new_path, $source_area, $target_area); - } - - /** - * Copy file - * - * @param string path path to file to copy - * @param string new_path new base directory (full path) - * @param string|File_Area|null source_area source path file area name, object or null for non-specific - * @param string|File_Area|null target_area target path file area name, object or null for non-specific. Defaults to source_area if not set. - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - * @return bool - */ - public static function copy($path, $new_path, $source_area = null, $target_area = null) - { - $path = static::instance($source_area)->get_path($path); - $new_path = static::instance($target_area ?: $source_area)->get_path($new_path); - - if ( ! is_file($path)) - { - throw new \InvalidPathException('Cannot copy file: given path: "'.$path.'" is not a file.'); - } - elseif (file_exists($new_path)) - { - throw new \FileAccessException('Cannot copy file: new path: "'.$new_path.'" already exists.'); - } - return copy($path, $new_path); - } - - /** - * Copy directory - * - * @param string $path path to directory which contents will be copied - * @param string $new_path new base directory (full path) - * @param string|File_Area|null $source_area source path file area name, object or null for non-specific - * @param string|File_Area|null $target_area target path file area name, object or null for non-specific. Defaults to source_area if not set. - * @throws \FileAccessException when something went wrong - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function copy_dir($path, $new_path, $source_area = null, $target_area = null) - { - $target_area = $target_area ?: $source_area; - - $path = rtrim(static::instance($source_area)->get_path($path), '\\/').DS; - $new_path = rtrim(static::instance($target_area)->get_path($new_path), '\\/').DS; - - if ( ! is_dir($path)) - { - throw new \InvalidPathException('Cannot copy directory: given path: "'.$path.'" is not a directory: '.$path); - } - elseif ( ! file_exists($new_path)) - { - $newpath_dirname = pathinfo($new_path, PATHINFO_DIRNAME); - static::create_dir($newpath_dirname, pathinfo($new_path, PATHINFO_BASENAME), fileperms($newpath_dirname) ?: 0777, $target_area); - } - - $files = static::read_dir($path, -1, array(), $source_area); - foreach ($files as $dir => $file) - { - if (is_array($file)) - { - $check = static::create_dir($new_path.DS, substr($dir, 0, -1), fileperms($path.$dir) ?: 0777, $target_area); - $check and static::copy_dir($path.$dir.DS, $new_path.$dir, $source_area, $target_area); - } - else - { - $check = static::copy($path.$file, $new_path.$file, $source_area, $target_area); - } - - // abort if something went wrong - if ( ! $check) - { - throw new \FileAccessException('Directory copy aborted prematurely, part of the operation failed during copying: '.(is_array($file) ? $dir : $file)); - } - } - } - - /** - * Create a new symlink - * - * @param string $path target of symlink - * @param string $link_path destination of symlink - * @param bool $is_file true for file, false for directory - * @param string|File_Area|null $area file area name, object or null for base area - * @return bool - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function symlink($path, $link_path, $is_file = true, $area = null) - { - $path = rtrim(static::instance($area)->get_path($path), '\\/'); - $link_path = rtrim(static::instance($area)->get_path($link_path), '\\/'); - - if ($is_file and ! is_file($path)) - { - throw new \InvalidPathException('Cannot symlink: given file: "'.$path.'" does not exist.'); - } - elseif ( ! $is_file and ! is_dir($path)) - { - throw new \InvalidPathException('Cannot symlink: given directory: "'.$path.'" does not exist.'); - } - elseif (file_exists($link_path)) - { - throw new \FileAccessException('Cannot symlink: link: "'.$link_path.'" already exists.'); - } - - return symlink($path, $link_path); - } - - /** - * Delete file - * - * @param string $path path to file to delete - * @param string|File_Area|null $area file area name, object or null for base area - * @return bool - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function delete($path, $area = null) - { - $path = rtrim(static::instance($area)->get_path($path), '\\/'); - - if ( ! is_file($path) and ! is_link($path)) - { - throw new \InvalidPathException('Cannot delete file: given path "'.$path.'" is not a file.'); - } - - return unlink($path); - } - - /** - * Delete directory - * - * @param string $path path to directory to delete - * @param bool $recursive whether to also delete contents of subdirectories - * @param bool $delete_top whether to delete the parent dir itself when empty - * @param string|File_Area|null $area file area name, object or null for base area - * @return bool - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function delete_dir($path, $recursive = true, $delete_top = true, $area = null) - { - $path = rtrim(static::instance($area)->get_path($path), '\\/').DS; - if ( ! is_dir($path)) - { - throw new \InvalidPathException('Cannot delete directory: given path: "'.$path.'" is not a directory.'); - } - - $files = static::read_dir($path, -1, array(), $area); - - $not_empty = false; - $check = true; - foreach ($files as $dir => $file) - { - if (is_array($file)) - { - if ($recursive) - { - $check = static::delete_dir($path.$dir, true, true, $area); - } - else - { - $not_empty = true; - } - } - else - { - $check = static::delete($path.$file, $area); - } - - // abort if something went wrong - if ( ! $check) - { - throw new \FileAccessException('Directory deletion aborted prematurely, part of the operation failed.'); - } - } - - if ( ! $not_empty and $delete_top) - { - return rmdir($path); - } - return true; - } - - /** - * Open and lock file - * - * @param resource|string $path file resource or path - * @param constant|bool $lock either valid lock constant or true=LOCK_EX / false=LOCK_UN - * @param string|File_Area|null $area file area name, object or null for base area - * @return bool|resource - * @throws \FileAccessException - * @throws \OutsideAreaException - */ - public static function open_file($path, $lock = true, $area = null) - { - if (is_string($path)) - { - $path = static::instance($area)->get_path($path); - $resource = fopen($path, 'r+'); - } - else - { - $resource = $path; - } - - // Make sure the parameter is a valid resource - if ( ! is_resource($resource)) - { - return false; - } - - // If locks aren't used, don't lock - if ( ! static::instance($area)->use_locks()) - { - return $resource; - } - - // Accept valid lock constant or set to LOCK_EX - $lock = in_array($lock, array(LOCK_SH, LOCK_EX, LOCK_NB)) ? $lock : LOCK_EX; - - // Try to get a lock, timeout after 5 seconds - $lock_mtime = microtime(true); - while ( ! flock($resource, $lock)) - { - if (microtime(true) - $lock_mtime > 5) - { - throw new \FileAccessException('Could not secure file lock, timed out after 5 seconds.'); - } - } - - return $resource; - } - - /** - * Close file resource & unlock - * - * @param resource $resource open file resource - * @param string|File_Area|null $area file area name, object or null for base area - */ - public static function close_file($resource, $area = null) - { - // If locks aren't used, don't unlock - if ( static::instance($area)->use_locks()) - { - flock($resource, LOCK_UN); - } - - fclose($resource); - } - - /** - * Get detailed information about a file - * - * @param string $path file path - * @param string|File_Area|null $area file area name, object or null for base area - * @return array - * @throws \FileAccessException - * @throws \InvalidPathException - * @throws \OutsideAreaException - */ - public static function file_info($path, $area = null) - { - $info = array( - 'original' => $path, - 'realpath' => '', - 'dirname' => '', - 'basename' => '', - 'filename' => '', - 'extension' => '', - 'mimetype' => '', - 'charset' => '', - 'size' => 0, - 'permissions' => '', - 'time_created' => '', - 'time_modified' => '', - ); - - if ( ! $info['realpath'] = static::instance($area)->get_path($path) or ! is_file($info['realpath'])) - { - throw new \InvalidPathException('Filename given is not a valid file.'); - } - - $info = array_merge($info, pathinfo($info['realpath'])); - - if ( ! $fileinfo = new \finfo(FILEINFO_MIME, \Config::get('file.magic_file', null))) - { - throw new \InvalidArgumentException('Can not retrieve information about this file.'); - } - - $fileinfo = explode(';', $fileinfo->file($info['realpath'])); - - $info['mimetype'] = isset($fileinfo[0]) ? $fileinfo[0] : 'application/octet-stream'; - - if (isset($fileinfo[1])) - { - $fileinfo = explode('=', $fileinfo[1]); - $info['charset'] = isset($fileinfo[1]) ? $fileinfo[1] : ''; - } - - $info['size'] = static::get_size($info['realpath'], $area); - $info['permissions'] = static::get_permissions($info['realpath'], $area); - $info['time_created'] = static::get_time($info['realpath'], 'created', $area); - $info['time_modified'] = static::get_time($info['realpath'], 'modified', $area); - - return $info; - } - - /** - * Download a file - * - * @param string $path file path - * @param string|null $name custom name for the file to be downloaded - * @param string|null $mime custom mime type or null for file mime type - * @param string|File_Area|null $area file area name, object or null for base area - * @param bool $delete delete the file after download when true - * @param string $disposition disposition, must be 'attachment' or 'inline' - */ - public static function download($path, $name = null, $mime = null, $area = null, $delete = false, $disposition = 'attachment') - { - $info = static::file_info($path, $area); - $class = get_called_class(); - empty($mime) or $info['mimetype'] = $mime; - empty($name) or $info['basename'] = $name; - in_array($disposition, array('inline', 'attachment')) or $disposition = 'attachment'; - - \Event::register('fuel-shutdown', function () use($info, $area, $class, $delete, $disposition) { - - if ( ! $file = call_user_func(array($class, 'open_file'), @fopen($info['realpath'], 'rb'), LOCK_SH, $area)) - { - throw new \FileAccessException('Filename given could not be opened for download.'); - } - - while (ob_get_level() > 0) - { - ob_end_clean(); - } - - ini_get('zlib.output_compression') and ini_set('zlib.output_compression', 0); - ! ini_get('safe_mode') and set_time_limit(0); - - header('Content-Type: '.$info['mimetype']); - header('Content-Disposition: '.$disposition.'; filename="'.$info['basename'].'"'); - $disposition === 'attachment' and header('Content-Description: File Transfer'); - header('Content-Length: '.$info['size']); - header('Content-Transfer-Encoding: binary'); - $disposition === 'attachment' and header('Expires: 0'); - $disposition === 'attachment' and header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - - while( ! feof($file)) - { - echo fread($file, 2048); - } - - call_user_func(array($class, 'close_file'), $file, $area); - - if ($delete) - { - call_user_func(array($class, 'delete'), $info['realpath'], $area); - } - }); - - exit; - } - -} diff --git a/fuel/core/classes/file/area.php b/fuel/core/classes/file/area.php deleted file mode 100755 index a04970a..0000000 --- a/fuel/core/classes/file/area.php +++ /dev/null @@ -1,277 +0,0 @@ - $value) - { - if (property_exists($this, $key)) - { - $this->{$key} = $value; - } - } - - if ( ! empty($this->basedir)) - { - $this->basedir = realpath($this->basedir) ?: $this->basedir; - } - } - - /** - * Factory for area objects - * - * @param array - * @return File_Area - */ - public static function forge(array $config = array()) - { - return new static($config); - } - - /** - * Handler factory for given path - * - * @param string $path path to file or directory - * @param array $config optional config - * @param array $content - * @return File_Handler_File - * @throws \FileAccessException when outside basedir restriction or disallowed file extension - * @throws \OutsideAreaException - */ - public function get_handler($path, array $config = array(), $content = array()) - { - $path = $this->get_path($path); - - if (is_file($path)) - { - $info = pathinfo($path); - - // deal with path names without an extension - isset($info['extension']) or $info['extension'] = ''; - - // check file extension - if ( ! empty($this->extensions) && ! in_array($info['extension'], $this->extensions)) - { - throw new \FileAccessException('File operation not allowed: disallowed file extension.'); - } - - // create specific handler when available - if (array_key_exists($info['extension'], $this->file_handlers)) - { - $class = '\\'.ltrim($this->file_handlers[$info['extension']], '\\'); - return $class::forge($path, $config, $this); - } - - return \File_Handler_File::forge($path, $config, $this); - } - elseif (is_dir($path)) - { - return \File_Handler_Directory::forge($path, $config, $this, $content); - } - - // still here? path is invalid - throw new \FileAccessException('Invalid path for file or directory.'); - } - - /** - * Does this area use file locks? - * - * @return bool - */ - public function use_locks() - { - return $this->use_locks; - } - - /** - * Are the shown extensions limited, and if so to which? - * - * @return array - */ - public function extensions() - { - return $this->extensions; - } - - /** - * Translate relative path to real path, throws error when operation is not allowed - * - * @param string $path - * @return string - * @throws \FileAccessException when outside basedir restriction or disallowed file extension - * @throws \OutsideAreaException - */ - public function get_path($path) - { - $pathinfo = is_dir($path) ? array('dirname' => $path, 'extension' => null, 'basename' => '') : pathinfo($path); - - // make sure we have a dirname to work with - isset($pathinfo['dirname']) or $pathinfo['dirname'] = ''; - - // do we have a basedir, and is the path already prefixed by the basedir? then just deal with the double dots... - if ( ! empty($this->basedir) && substr($pathinfo['dirname'], 0, strlen($this->basedir)) == $this->basedir) - { - $pathinfo['dirname'] = realpath($pathinfo['dirname']); - } - else - { - // attempt to get the realpath(), otherwise just use path with any double dots taken out when basedir is set (for security) - $pathinfo['dirname'] = ( ! empty($this->basedir) ? realpath($this->basedir.DS.$pathinfo['dirname']) : realpath($pathinfo['dirname']) ) - ?: ( ! empty($this->basedir) ? $this->basedir.DS.str_replace('..', '', $pathinfo['dirname']) : $pathinfo['dirname']); - } - - // basedir prefix is required when it is set (may cause unexpected errors when realpath doesn't work) - if ( ! empty($this->basedir) && substr($pathinfo['dirname'], 0, strlen($this->basedir)) != $this->basedir) - { - throw new \OutsideAreaException('File operation not allowed: given path is outside the basedir for this area.'); - } - - // check file extension - if ( ! empty(static::$extensions) && array_key_exists($pathinfo['extension'], static::$extensions)) - { - throw new \FileAccessException('File operation not allowed: disallowed file extension.'); - } - - return $pathinfo['dirname'].DS.$pathinfo['basename']; - } - - /** - * Translate relative path to accessible path, throws error when operation is not allowed - * - * @param string - * @return string - * @throws \LogicException when no url is set or no basedir is set and file is outside DOCROOT - */ - public function get_url($path) - { - if(empty($this->url)) - { - throw new \LogicException('File operation now allowed: cannot create a file url without an area url.'); - } - - $path = $this->get_path($path); - - $basedir = $this->basedir; - empty($basedir) and $basedir = DOCROOT; - - if(stripos($path, $basedir) !== 0) - { - throw new \LogicException('File operation not allowed: cannot create file url whithout a basedir and file outside DOCROOT.'); - } - - return rtrim($this->url, '/').'/'.ltrim(str_replace(DS, '/', substr($path, strlen($basedir))), '/'); - } - - /* ------------------------------------------------------------------------------------- - * Allow all File methods to be used from an area directly - * ------------------------------------------------------------------------------------- */ - - public function create($basepath, $name, $contents = null) - { - return \File::create($basepath, $name, $contents, $this); - } - - public function create_dir($basepath, $name, $chmod = null) - { - return \File::create_dir($basepath, $name, $chmod, $this); - } - - public function read($path, $as_string = false) - { - return \File::read($path, $as_string, $this); - } - - public function read_dir($path, $depth = 0, $filter = null) - { - $content = \File::read_dir($path, $depth, $filter, $this); - return $this->get_handler($path, array(), $content); - } - - public function rename($path, $new_path) - { - return \File::rename($path, $new_path, $this); - } - - public function rename_dir($path, $new_path) - { - return \File::rename_dir($path, $new_path, $this); - } - - public function copy($path, $new_path) - { - return \File::copy($path, $new_path, $this); - } - - public function copy_dir($path, $new_path) - { - return \File::copy_dir($path, $new_path, $this); - } - - public function delete($path) - { - return \File::delete($path, $this); - } - - public function delete_dir($path, $recursive = true, $delete_top = true) - { - return \File::delete_dir($path, $recursive, $delete_top, $this); - } - - public function update($basepath, $name, $new_content) - { - return \File::update($basepath, $name, $new_content, $this); - } - - public function get_permissions($path) - { - return \File::get_permissions($path, $this); - } - - public function get_time($path, $type) - { - return \File::get_time($path, $type, $this); - } - - public function get_size($path) - { - return \File::get_size($path, $this); - } -} diff --git a/fuel/core/classes/file/handler/directory.php b/fuel/core/classes/file/handler/directory.php deleted file mode 100755 index 7608684..0000000 --- a/fuel/core/classes/file/handler/directory.php +++ /dev/null @@ -1,191 +0,0 @@ -path = rtrim($path, '\\/').DS; - $this->area = $area; - - foreach ($content as $key => $value) - { - if ( ! is_int($key)) - { - $this->content[$key] = $value === false ? false : $area->get_handler($path.DS.$key, $config, $value); - } - else - { - $this->content[$key] = $area->get_handler($path.DS.$value, $config); - } - } - } - - public static function forge($path, array $config = array(), File_Area $area = null, $content = array()) - { - return new static($path, $config, $area, $content); - } - - /** - * Read directory - * - * @param int $depth whether or not to read recursive - * @param array $filters array of partial regexps or non-array for default - * @return array - */ - public function read($depth = 0, $filters = null) - { - return $this->area->read_dir($this->path, $depth, $filters, $this->area); - } - - /** - * Rename file, only within current directory - * - * @param string $new_name new directory name - * @return bool - */ - public function rename($new_name) - { - $info = pathinfo($this->path); - - $new_name = str_replace(array('..', '/', '\\'), array('', '', ''), $new_name); - - $new_path = $info['dirname'].DS.$new_name; - - $return = $this->area->rename_dir($this->path, $new_path); - $return and $this->path = $new_path; - - return $return; - } - - /** - * Move directory to new parent directory - * - * @param string $new_path path to new parent directory, must be valid - * @return bool - */ - public function move($new_path) - { - $info = pathinfo($this->path); - $new_path = $this->area->get_path($new_path); - - $new_path = rtrim($new_path, '\\/').DS.$info['basename']; - - $return = $this->area->rename_dir($this->path, $new_path); - $return and $this->path = $new_path; - - return $return; - } - - /** - * Copy directory - * - * @param string $new_path path to parent directory, must be valid - * @return bool - */ - public function copy($new_path) - { - $info = pathinfo($this->path); - $new_path = $this->area->get_path($new_path); - - $new_path = rtrim($new_path, '\\/').DS.$info['basename']; - - return $this->area->copy_dir($this->path, $new_path); - } - - /** - * Update contents - * - * This method is unavailable on this implement, that will surely cause exception. - * - * @throws \BadMethodCallException - */ - public function update() - { - throw new \BadMethodCallException('Update method is unavailable on directories.'); - } - - /** - * Delete directory - * - * @param bool $recursive - * @param bool $delete_top - * @return bool - */ - public function delete($recursive = true, $delete_top = true) - { - // should also destroy object but not possible in PHP right? - return $this->area->delete_dir($this->path, $recursive, $delete_top); - } - - /** - * Get the url. - * - * This method is unavailable on this implement, that will surely cause exception. - * - * @throws \BadMethodCallException - */ - public function get_url() - { - throw new \BadMethodCallException('Get_url method is unavailable on directories.'); - } - - /** - * Get the directory permissions. - * - * @return string file permissions - */ - public function get_permissions() - { - return $this->area->get_permissions($this->path); - } - - /** - * Get directory's the created or modified timestamp. - * - * @param string $type modified or created - * @return int Unix Timestamp - */ - public function get_time($type = 'modified') - { - return $this->area->get_time($this->path, $type); - } - - /** - * Get the size. - * - * This method is unavailable on this implement, that will surely cause exception. - * - * @throws \BadMethodCallException - */ - public function get_size() - { - throw new \BadMethodCallException('Get_size method is unavailable on directories.'); - } -} diff --git a/fuel/core/classes/file/handler/file.php b/fuel/core/classes/file/handler/file.php deleted file mode 100755 index 7f61245..0000000 --- a/fuel/core/classes/file/handler/file.php +++ /dev/null @@ -1,205 +0,0 @@ -path = $path; - $this->area = $area; - } - - public static function forge($path, array $config = array(), File_Area $area = null, $content = array()) - { - $obj = new static($path, $config, \File::instance($area), $content); - - $config['path'] = $path; - $config['area'] = $area; - foreach ($config as $key => $value) - { - if (property_exists($obj, $key) && empty($obj->$key)) - { - $obj->$key = $value; - } - } - - return $obj; - } - - /** - * Read file - * - * @param bool $as_string whether to use file_get_contents() or readfile() - * @return string|IO - */ - public function read($as_string = false) - { - return $this->area->read($this->path, $as_string); - } - - /** - * Rename file, only within current directory - * - * @param string $new_name new filename - * @param string|bool $new_extension new extension, false to keep current - * @return bool - */ - public function rename($new_name, $new_extension = false) - { - $info = pathinfo($this->path); - - $new_name = str_replace(array('..', '/', '\\'), array('', '', ''), $new_name); - $extension = $new_extension === false - ? $info['extension'] - : ltrim($new_extension, '.'); - $extension = ! empty($extension) ? '.'.$extension : ''; - - $new_path = $info['dirname'].DS.$new_name.$extension; - - $return = $this->area->rename($this->path, $new_path); - $return and $this->path = $new_path; - - return $return; - } - - /** - * Move file to new directory - * - * @param string $new_path path to new directory, must be valid - * @return bool - */ - public function move($new_path) - { - $info = pathinfo($this->path); - - $new_path = $this->area->get_path($new_path); - $new_path = rtrim($new_path, '\\/').DS.$info['basename']; - - $return = $this->area->rename($this->path, $new_path); - $return and $this->path = $new_path; - - return $return; - } - - /** - * Copy file - * - * @param string $new_path path to target directory, must be valid - * @return bool - */ - public function copy($new_path) - { - $info = pathinfo($this->path); - $new_path = $this->area->get_path($new_path); - - $new_path = rtrim($new_path, '\\/').DS.$info['basename']; - - return $this->area->copy($this->path, $new_path); - } - - /** - * Update contents - * - * @param mixed $new_content new file contents - * @return bool - */ - public function update($new_content) - { - $info = pathinfo($this->path); - return $this->area->update($info['dirname'], $info['basename'], $new_content, $this); - } - - /** - * Delete file - * - * @return bool - */ - public function delete() - { - // should also destroy object but not possible in PHP right? - return $this->area->delete($this->path); - } - - /** - * Get the url. - * - * @return bool - */ - public function get_url() - { - return $this->area->get_url($this->path); - } - - /** - * Get the file's permissions. - * - * @return string file permissions - */ - public function get_permissions() - { - return $this->area->get_permissions($this->path); - } - - /** - * Get the file's created or modified timestamp. - * - * @param string $type modified or created - * @return int Unix Timestamp - */ - public function get_time($type = 'modified') - { - return $this->area->get_time($this->path, $type); - } - - /** - * Get the file's size. - * - * @return int File size - */ - public function get_size() - { - return $this->area->get_size($this->path); - } - - /** - * Get the file's path. - * - * @return string File path - */ - public function get_path() - { - return $this->path; - } - -} diff --git a/fuel/core/classes/finder.php b/fuel/core/classes/finder.php deleted file mode 100755 index a6448ac..0000000 --- a/fuel/core/classes/finder.php +++ /dev/null @@ -1,559 +0,0 @@ -locate(); - * - * @param string $dir Directory to look in - * @param string $file File to find - * @param string $ext File extension - * @param bool $multiple Whether to find multiple files - * @param bool $cache Whether to cache this path or not - * @return mixed Path, or paths, or false - */ - public static function search($dir, $file, $ext = '.php', $multiple = false, $cache = true) - { - return static::instance()->locate($dir, $file, $ext, $multiple, $cache); - } - - /** - * Gets a singleton instance of Finder - * - * @return Finder - */ - public static function instance() - { - if ( ! static::$instance) - { - static::$instance = static::forge(array(APPPATH, COREPATH)); - } - - return static::$instance; - } - - /** - * Forges new Finders. - * - * @param array $paths The paths to initialize with - * @return Finder - */ - public static function forge($paths = array()) - { - return new static($paths); - } - - /** - * @var array $paths Holds all of the search paths - */ - protected $paths = array(); - - /** - * @var array $flash_paths Search paths that only last for one lookup - */ - protected $flash_paths = array(); - - /** - * @var int $cache_lifetime the amount of time to cache in seconds - */ - protected $cache_lifetime = null; - - /** - * @var string $cache_dir path to the cache file location - */ - protected $cache_dir = null; - - /** - * @var array $cached_paths Cached lookup paths - */ - protected $cached_paths = array(); - - /** - * @var bool $cache_valid Whether the path cache is valid or not - */ - protected $cache_valid = true; - - /** - * Takes in an array of paths, preps them and gets the party started. - * - * @param array $paths The paths to initialize with - */ - public function __construct($paths = array()) - { - $this->add_path($paths); - } - - /** - * Adds a path (or paths) to the search path at a given position. - * - * Possible positions: - * (null): Append to the end of the search path - * (-1): Prepend to the start of the search path - * (index): The path will get inserted AFTER the given index - * - * @param string|array $paths The path to add - * @param int $pos The position to add the path - * @return $this - * @throws \OutOfBoundsException - */ - public function add_path($paths, $pos = null) - { - if ( ! is_array($paths)) - { - $paths = array($paths); - } - - foreach ($paths as $path) - { - if ($pos === null) - { - $this->paths[] = $this->prep_path($path); - } - elseif ($pos === -1) - { - array_unshift($this->paths, $this->prep_path($path)); - } - else - { - if ($pos > count($this->paths)) - { - throw new \OutOfBoundsException(sprintf('Position "%s" is out of range.', $pos)); - } - array_splice($this->paths, $pos, 0, $this->prep_path($path)); - } - } - - return $this; - } - - /** - * Removes a path from the search path. - * - * @param string $path Path to remove - * @return $this - */ - public function remove_path($path) - { - foreach ($this->paths as $i => $p) - { - if ($p === $path) - { - unset($this->paths[$i]); - break; - } - } - - return $this; - } - - /** - * Adds multiple flash paths. - * - * @param array $paths The paths to add - * @return $this - */ - public function flash($paths) - { - if ( ! is_array($paths)) - { - $paths = array($paths); - } - - foreach ($paths as $path) - { - $this->flash_paths[] = $this->prep_path($path); - } - - return $this; - } - - /** - * Clears the flash paths. - * - * @return $this - */ - public function clear_flash() - { - $this->flash_paths = array(); - - return $this; - } - - /** - * Returns the current search paths...including flash paths. - * - * @return array Search paths - */ - public function paths() - { - return array_merge($this->flash_paths, $this->paths); - } - - /** - * Prepares a path for usage. It ensures that the path has a trailing - * Directory Separator. - * - * @param string $path The path to prepare - * @return string - */ - public function prep_path($path) - { - $path = str_replace(array('/', '\\'), DS, $path); - return rtrim($path, DS).DS; - } - - /** - * Prepares an array of paths. - * - * @param array $paths The paths to prepare - * @return array - */ - public function prep_paths(array $paths) - { - foreach ($paths as &$path) - { - $path = $this->prep_path($path); - } - return $paths; - } - - /** - * Gets a list of all the files in a given directory inside all of the - * loaded search paths (e.g. the cascading file system). This is useful - * for things like finding all the config files in all the search paths. - * - * @param string $directory The directory to look in - * @param string $filter The file filter - * @return array the array of files - */ - public function list_files($directory = null, $filter = '*.php') - { - $paths = $this->paths; - - // get extra information of the active request - if (class_exists('Request', false) and ($uri = \Uri::string()) !== null) - { - $paths = array_merge(\Request::active()->get_paths(), $paths); - } - - // Merge in the flash paths then reset the flash paths - $paths = array_merge($this->flash_paths, $paths); - $this->clear_flash(); - - $found = array(); - foreach ($paths as $path) - { - $files = new \GlobIterator(rtrim($path.$directory, DS).DS.$filter); - foreach($files as $file) - { - $found[] = $file->getPathname(); - } - } - - return $found; - } - - /** - * Locates a given file in the search paths. - * - * @param string $dir Directory to look in - * @param string $file File to find - * @param string $ext File extension - * @param bool $multiple Whether to find multiple files - * @param bool $cache Whether to cache this path or not - * @return mixed Path, or paths, or false - */ - public function locate($dir, $file, $ext = '.php', $multiple = false, $cache = true) - { - $found = $multiple ? array() : false; - - // absolute path requested? - if ($file[0] === '/' or substr($file, 1, 2) === ':\\') - { - // if the base file does not exist, stick the extension to the back of it - if ( ! is_file($file)) - { - $file .= $ext; - } - if ( ! is_file($file)) - { - // at this point, found would be either empty array or false - return $found; - } - return $multiple ? array($file) : $file; - } - - // determine the cache prefix - if ($multiple) - { - // make sure cache is not used if the loaded package and module list is changed - $cachekey = ''; - class_exists('Module', false) and $cachekey .= implode('|', \Module::loaded()); - $cachekey .= '|'; - class_exists('Package', false) and $cachekey .= implode('|', \Package::loaded()); - $cache_id = md5($cachekey).'.'; - } - else - { - $cache_id = 'S.'; - } - - $paths = array(); - - // If a filename contains a :: then it is trying to be found in a namespace. - // This is sometimes used to load a view from a non-loaded module. - if ($pos = strripos($file, '::')) - { - // get the namespace path - if ($path = \Autoloader::namespace_path('\\'.ucfirst(substr($file, 0, $pos)))) - { - $cache_id .= substr($file, 0, $pos); - - // and strip the classes directory as we need the module root - $paths = array(substr($path, 0, -8)); - - // strip the namespace from the filename - $file = substr($file, $pos + 2); - } - } - else - { - $paths = $this->paths; - - // get extra information of the active request - if (class_exists('Request', false) and ($request = \Request::active())) - { - $request->module and $cache_id .= $request->module; - $paths = array_merge($request->get_paths(), $paths); - } - } - - // Merge in the flash paths then reset the flash paths - $paths = array_merge($this->flash_paths, $paths); - $this->clear_flash(); - - $file = $this->prep_path($dir).$file.$ext; - $cache_id .= $file; - - if ($cache and $cached_path = $this->from_cache($cache_id)) - { - return $cached_path; - } - - foreach ($paths as $dir) - { - $file_path = $dir.$file; - - if (is_file($file_path)) - { - if ( ! $multiple) - { - $found = $file_path; - break; - } - - $found[] = $file_path; - } - } - - if ( ! empty($found) and $cache) - { - $this->add_to_cache($cache_id, $found); - } - - return $found; - } - - /** - * Reads in the cached paths with the given cache id. - * - * @param string $cache_id Cache id to read - * @return void - */ - public function read_cache($cache_id) - { - // make sure we have all config data - empty($this->cache_dir) and $this->cache_dir = \Config::get('cache_dir', APPPATH.'cache/'); - empty($this->cache_lifetime) and $this->cache_lifetime = \Config::get('cache_lifetime', 3600); - - if ($cached = $this->cache($cache_id)) - { - $this->cached_paths = $cached; - } - } - - /** - * Writes out the cached paths if they need to be. - * - * @param string $cache_id Cache id to read - * @return void - */ - public function write_cache($cache_id) - { - $this->cache_valid or $this->cache($cache_id, $this->cached_paths); - } - - /** - * Loads in the given cache_id from the cache if it exists. - * - * @param string $cache_id Cache id to load - * @return string|bool Path or false if not found - */ - protected function from_cache($cache_id) - { - $cache_id = md5($cache_id); - if (array_key_exists($cache_id, $this->cached_paths)) - { - return $this->cached_paths[$cache_id]; - } - - return false; - } - - /** - * Loads in the given cache_id from the cache if it exists. - * - * @param string $cache_id Cache id to load - * @return string|bool Path or false if not found - */ - protected function add_to_cache($cache_id, $path) - { - $cache_id = md5($cache_id); - $this->cached_paths[$cache_id] = $path; - $this->cache_valid = false; - } - - /** - * This method does basic filesystem caching. It is used for things like path caching. - * - * This method is from KohanaPHP's Kohana class. - * - * @param string $name the cache name - * @param array $data the data to cache (if non given it returns) - * @param int $lifetime the number of seconds for the cache too live - * @return bool|null - */ - protected function cache($name, $data = null, $lifetime = null) - { - // Cache file is a hash of the name - $file = $name.'.pathcache'; - - // Cache directories are split by keys to prevent filesystem overload - $dir = rtrim($this->cache_dir, DS).DS; - - if ($lifetime === NULL) - { - // Use the default lifetime - $lifetime = $this->cache_lifetime; - } - - if ($data === null) - { - if (is_file($dir.$file)) - { - if ((time() - filemtime($dir.$file)) < $lifetime) - { - // Return the cache - try - { - return unserialize(file_get_contents($dir.$file)); - } - catch (\Exception $e) - { - // Cache exists but could not be read, ignore it - } - } - else - { - try - { - // Cache has expired - unlink($dir.$file); - } - catch (Exception $e) - { - // Cache has mostly likely already been deleted, - // let return happen normally. - } - } - } - - // Cache not found - return null; - } - - if ( ! is_dir($dir)) - { - // Create the cache directory - mkdir($dir, \Config::get('file.chmod.folders', 0777), true); - - // Set permissions (must be manually set to fix umask issues) - chmod($dir, \Config::get('file.chmod.folders', 0777)); - } - - // Force the data to be a string - $data = serialize($data); - - try - { - // Write the cache, and set permissions - if ($result = (bool) file_put_contents($dir.$file, $data, LOCK_EX)) - { - try - { - chmod($dir.$file, \Config::get('file.chmod.files', 0666)); - } - catch (\PhpErrorException $e) - { - // if we get something else then a chmod error, bail out - if (substr($e->getMessage(), 0, 8) !== 'chmod():') - { - throw new $e; - } - } - } - - return $result; - } - catch (\Exception $e) - { - // Failed to write cache - return false; - } - } - -} diff --git a/fuel/core/classes/form.php b/fuel/core/classes/form.php deleted file mode 100755 index 51ecbc5..0000000 --- a/fuel/core/classes/form.php +++ /dev/null @@ -1,312 +0,0 @@ -form(false) != null) - { - throw new \DomainException('Form instance already exists, cannot be recreated. Use instance() instead of forge() to retrieve the existing instance.'); - } - } - - return new \Form_Instance($fieldset, $config); - } - - /** - * Returns the 'default' instance of Form - * - * @param null|string $name - * @return Form_Instance - */ - public static function instance($name = null) - { - $fieldset = \Fieldset::instance($name); - return $fieldset === false ? false : $fieldset->form(); - } - - /** - * Create a form open tag - * - * @param string|array $attributes action string or array with more tag attribute settings - * @param array $hidden - * @return string - */ - public static function open($attributes = array(), array $hidden = array()) - { - return static::$instance->open($attributes, $hidden); - } - - /** - * Create a form close tag - * - * @return string - */ - public static function close() - { - return static::$instance->close(); - } - - /** - * Create a fieldset open tag - * - * @param array $attributes array with tag attribute settings - * @param string $legend string for the fieldset legend - * @return string - */ - public static function fieldset_open($attributes = array(), $legend = null) - { - return static::$instance->fieldset_open($attributes, $legend); - } - - /** - * Create a fieldset close tag - * - * @return string - */ - public static function fieldset_close() - { - return static::$instance->fieldset_close(); - } - - /** - * Create a form input - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public static function input($field, $value = null, array $attributes = array()) - { - return static::$instance->input($field, $value, $attributes); - } - - /** - * Create a hidden field - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public static function hidden($field, $value = null, array $attributes = array()) - { - return static::$instance->hidden($field, $value, $attributes); - } - - /** - * Create a CSRF hidden field - * - * @return string - */ - public static function csrf() - { - return static::hidden(\Config::get('security.csrf_token_key', 'fuel_csrf_token'), \Security::fetch_token()); - } - - /** - * Create a password input field - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public static function password($field, $value = null, array $attributes = array()) - { - return static::$instance->password($field, $value, $attributes); - } - - /** - * Create a radio button - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param mixed $checked either attributes (array) or bool/string to set checked status - * @param array $attributes - * @return string - */ - public static function radio($field, $value = null, $checked = null, array $attributes = array()) - { - return static::$instance->radio($field, $value, $checked, $attributes); - } - - /** - * Create a checkbox - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param mixed $checked either attributes (array) or bool/string to set checked status - * @param array $attributes - * @return string - */ - public static function checkbox($field, $value = null, $checked = null, array $attributes = array()) - { - return static::$instance->checkbox($field, $value, $checked, $attributes); - } - - /** - * Create a file upload input field - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param array $attributes - * @return string - */ - public static function file($field, array $attributes = array()) - { - return static::$instance->file($field, $attributes); - } - - /** - * Create a button - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public static function button($field, $value = null, array $attributes = array()) - { - return static::$instance->button($field, $value, $attributes); - } - - /** - * Create a reset button - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public static function reset($field = 'reset', $value = 'Reset', array $attributes = array()) - { - return static::$instance->reset($field, $value, $attributes); - } - - /** - * Create a submit button - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public static function submit($field = 'submit', $value = 'Submit', array $attributes = array()) - { - return static::$instance->submit($field, $value, $attributes); - } - - /** - * Create a textarea field - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public static function textarea($field, $value = null, array $attributes = array()) - { - return static::$instance->textarea($field, $value, $attributes); - } - - /** - * Select - * - * Generates a html select element based on the given parameters - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $values selected value(s) - * @param array $options array of options and option groups - * @param array $attributes - * @return string - */ - public static function select($field, $values = null, array $options = array(), array $attributes = array()) - { - return static::$instance->select($field, $values, $options, $attributes); - } - - /** - * Create a label field - * - * @param string|array $label either fieldname or full attributes array (when array other params are ignored) - * @param string $id - * @param array $attributes - * @return string - */ - public static function label($label, $id = null, array $attributes = array()) - { - return static::$instance->label($label, $id, $attributes); - } - - /** - * Prep Value - * - * Prepares the value for display in the form - * - * @param string $value - * @return string - */ - public static function prep_value($value) - { - return static::$instance->prep_value($value); - } - - /** - * Attr to String - * - * Wraps the global attributes function and does some form specific work - * - * @param array $attr - * @return string - */ - protected static function attr_to_string($attr) - { - return static::$instance->attr_to_string($attr); - } - -} diff --git a/fuel/core/classes/form/instance.php b/fuel/core/classes/form/instance.php deleted file mode 100755 index 06e2fcc..0000000 --- a/fuel/core/classes/form/instance.php +++ /dev/null @@ -1,820 +0,0 @@ -form($this); - $this->fieldset = $fieldset; - } - else - { - $this->fieldset = \Fieldset::forge($fieldset, array('form_instance' => $this)); - } - - foreach ($config as $key => $val) - { - $this->set_config($key, $val); - } - } - - /** - * Set form attribute - * - * @param string $key - * @param mixed $value - * @return \Form_Instance - */ - public function set_attribute($key, $value) - { - $attributes = $this->get_config('form_attributes', array()); - $attributes[$key] = $value; - $this->set_config('form_attributes', $attributes); - - return $this; - } - - /** - * Get form attribute - * - * @param string $key - * @param mixed $default - * @return mixed - */ - public function get_attribute($key, $default = null) - { - $attributes = $this->get_config('form_attributes', array()); - - return array_key_exists($key, $attributes) ? $attributes[$key] : $default; - } - - /** - * Magic method toString that will build this as a form - * - * @return string - */ - public function __toString() - { - return $this->build(); - } - - /** - * Create a form open tag - * - * @param string|array $attributes action string or array with more tag attribute settings - * @param array $hidden - * @return string - */ - public function open($attributes = array(), array $hidden = array()) - { - $attributes = ! is_array($attributes) ? array('action' => $attributes) : $attributes; - - // If there is still no action set, Form-post - if( ! array_key_exists('action', $attributes) or empty($attributes['action'])) - { - $attributes['action'] = \Uri::main(); - } - - // If not a full URL, create one - elseif ( ! strpos($attributes['action'], '://')) - { - $attributes['action'] = \Uri::create($attributes['action']); - } - - if (empty($attributes['accept-charset'])) - { - $attributes['accept-charset'] = strtolower(\Fuel::$encoding); - } - - // If method is empty, use POST - ! empty($attributes['method']) || $attributes['method'] = $this->get_config('form_method', 'post'); - - $form = ' $value) - { - $form .= ' '.$prop.'="'.$value.'"'; - } - $form .= '>'; - - // Add hidden fields when given - foreach ($hidden as $field => $value) - { - $form .= PHP_EOL.$this->hidden($field, $value); - } - - // Add CSRF token automatically - if (Config::get('security.csrf_auto_token', false)) - { - $form .= PHP_EOL.\Form::csrf(); - } - - return $form; - } - - /** - * Create a form close tag - * - * @return string - */ - public function close() - { - return ''; - } - - /** - * Create a fieldset open tag - * - * @param array $attributes array with tag attribute settings - * @param string $legend string for the fieldset legend - * @return string - */ - public function fieldset_open($attributes = array(), $legend = null) - { - $fieldset_open = '
'; - - ! is_null($legend) and $attributes['legend'] = $legend; - if ( ! empty($attributes['legend'])) - { - $fieldset_open.= "\n".$attributes['legend'].""; - } - - return $fieldset_open; - } - - /** - * Create a fieldset close tag - * - * @return string - */ - public function fieldset_close() - { - return '
'; - } - - /** - * Create a form input - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public function input($field, $value = null, array $attributes = array()) - { - if (is_array($field)) - { - $attributes = $field; - ! array_key_exists('value', $attributes) and $attributes['value'] = ''; - } - else - { - $attributes['name'] = (string) $field; - $attributes['value'] = (string) $value; - } - - $attributes['type'] = empty($attributes['type']) ? 'text' : $attributes['type']; - - if ( ! in_array($attributes['type'], static::$_valid_inputs)) - { - throw new \InvalidArgumentException(sprintf('"%s" is not a valid input type.', $attributes['type'])); - } - - if ($this->get_config('prep_value', true) && empty($attributes['dont_prep'])) - { - $attributes['value'] = $this->prep_value($attributes['value']); - } - unset($attributes['dont_prep']); - - if (empty($attributes['id']) && $this->get_config('auto_id', false) == true) - { - $attributes['id'] = $this->get_config('auto_id_prefix', 'form_').$attributes['name']; - } - - $tag = ! empty($attributes['tag']) ? $attributes['tag'] : 'input'; - unset($attributes['tag']); - - return html_tag($tag, $this->attr_to_string($attributes)); - } - - /** - * Create a hidden field - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public function hidden($field, $value = null, array $attributes = array()) - { - if (is_array($field)) - { - $attributes = $field; - } - else - { - $attributes['name'] = (string) $field; - $attributes['value'] = (string) $value; - } - $attributes['type'] = 'hidden'; - - return $this->input($attributes); - } - - /** - * Create a password input field - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public function password($field, $value = null, array $attributes = array()) - { - if (is_array($field)) - { - $attributes = $field; - } - else - { - $attributes['name'] = (string) $field; - $attributes['value'] = (string) $value; - } - $attributes['type'] = 'password'; - - return $this->input($attributes); - } - - /** - * Create a radio button - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param mixed $checked either attributes (array) or bool/string to set checked status - * @param array $attributes - * @return string - */ - public function radio($field, $value = null, $checked = null, array $attributes = array()) - { - if (is_array($field)) - { - $attributes = $field; - } - else - { - is_array($checked) and $attributes = $checked; - $attributes['name'] = (string) $field; - $attributes['value'] = (string) $value; - - # Added for 1.2 to allow checked true/false. in 3rd argument, used to be attributes - if ( ! is_array($checked)) - { - // If it's true, then go for it - if (is_bool($checked)) - { - if($checked === true) - { - $attributes['checked'] = 'checked'; - } - } - - // Otherwise, if the string/number/whatever matches then do it - elseif (is_scalar($checked) and $checked == $value) - { - $attributes['checked'] = 'checked'; - } - } - } - $attributes['type'] = 'radio'; - - return $this->input($attributes); - } - - /** - * Create a checkbox - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param mixed $checked either attributes (array) or bool/string to set checked status - * @param array $attributes - * @return string - */ - public function checkbox($field, $value = null, $checked = null, array $attributes = array()) - { - if (is_array($field)) - { - $attributes = $field; - } - else - { - is_array($checked) and $attributes = $checked; - $attributes['name'] = (string) $field; - $attributes['value'] = (string) $value; - - # Added for 1.2 to allow checked true/false. in 3rd argument, used to be attributes - if ( ! is_array($checked)) - { - // If it's true, then go for it - if (is_bool($checked)) - { - if($checked === true) - { - $attributes['checked'] = 'checked'; - } - } - - // Otherwise, if the string/number/whatever matches then do it - elseif (is_scalar($checked) and $checked == $value) - { - $attributes['checked'] = 'checked'; - } - } - } - $attributes['type'] = 'checkbox'; - - return $this->input($attributes); - } - - /** - * Create a file upload input field - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param array $attributes - * @return string - */ - public function file($field, array $attributes = array()) - { - if (is_array($field)) - { - $attributes = $field; - } - else - { - $attributes['name'] = (string) $field; - } - $attributes['type'] = 'file'; - - return $this->input($attributes); - } - - /** - * Create a button - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public function button($field, $value = null, array $attributes = array()) - { - if (is_array($field)) - { - $attributes = $field; - $value = isset($attributes['value']) ? $attributes['value'] : $value; - } - else - { - $attributes['name'] = (string) $field; - $value = isset($value) ? $value : $attributes['name']; - } - - return html_tag('button', $this->attr_to_string($attributes), $value); - } - - /** - * Create a reset button - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public function reset($field = 'reset', $value = 'Reset', array $attributes = array()) - { - if (is_array($field)) - { - $attributes = $field; - } - else - { - $attributes['name'] = (string) $field; - $attributes['value'] = (string) $value; - } - $attributes['type'] = 'reset'; - - return $this->input($attributes); - } - - /** - * Create a submit button - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public function submit($field = 'submit', $value = 'Submit', array $attributes = array()) - { - if (is_array($field)) - { - $attributes = $field; - } - else - { - $attributes['name'] = (string) $field; - $attributes['value'] = (string) $value; - } - $attributes['type'] = 'submit'; - - return $this->input($attributes); - } - - /** - * Create a textarea field - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $value - * @param array $attributes - * @return string - */ - public function textarea($field, $value = null, array $attributes = array()) - { - if (is_array($field)) - { - $attributes = $field; - } - else - { - $attributes['name'] = (string) $field; - $attributes['value'] = (string) $value; - } - $value = is_scalar($attributes['value']) ? $attributes['value'] : ''; - unset($attributes['value']); - - if ($this->get_config('prep_value', true) && empty($attributes['dont_prep'])) - { - $value = $this->prep_value($value); - } - unset($attributes['dont_prep']); - - if (empty($attributes['id']) && $this->get_config('auto_id', false) == true) - { - $attributes['id'] = $this->get_config('auto_id_prefix', '').$attributes['name']; - } - - return html_tag('textarea', $this->attr_to_string($attributes), $value); - } - - /** - * Select - * - * Generates a html select element based on the given parameters - * - * @param string|array $field either fieldname or full attributes array (when array other params are ignored) - * @param string $values selected value(s) - * @param array $options array of options and option groups - * @param array $attributes - * @return string - */ - public function select($field, $values = null, array $options = array(), array $attributes = array()) - { - if (is_array($field)) - { - $attributes = $field; - - if ( ! isset($attributes['selected'])) - { - $attributes['selected'] = ! isset($attributes['value']) ? (isset($attributes['default']) ? $attributes['default'] : null) : $attributes['value']; - } - } - else - { - $attributes['name'] = (string) $field; - $attributes['selected'] = ($values === null or $values === array()) ? (isset($attributes['default']) ? $attributes['default'] : $values) : $values; - $attributes['options'] = $options; - } - unset($attributes['value']); - unset($attributes['default']); - - if ( ! isset($attributes['options']) || ! is_array($attributes['options'])) - { - throw new \InvalidArgumentException(sprintf('Select element "%s" is either missing the "options" or "options" is not array.', $attributes['name'])); - } - // Get the options then unset them from the array - $options = $attributes['options']; - unset($attributes['options']); - - // Get the selected options then unset it from the array - // and make sure they're all strings to avoid type conversions - $selected = ! isset($attributes['selected']) ? array() : array_map(function($a) { return (string) $a; }, array_values((array) $attributes['selected'])); - - unset($attributes['selected']); - - // workaround to access the current object context in the closure - $current_obj =& $this; - - // closure to recursively process the options array - $listoptions = function (array $options, $selected, $level = 1) use (&$listoptions, &$current_obj, &$attributes) - { - $input = PHP_EOL; - foreach ($options as $key => $val) - { - if (is_array($val)) - { - $optgroup = $listoptions($val, $selected, $level + 1); - $optgroup .= str_repeat("\t", $level); - $input .= str_repeat("\t", $level).html_tag('optgroup', array('label' => $key, 'style' => 'text-indent: '.(20+10*($level-1)).'px;'), $optgroup).PHP_EOL; - } - else - { - $opt_attr = array('value' => $key); - $level > 1 and $opt_attr['style'] = 'text-indent: '.(10*($level-1)).'px;'; - (in_array((string) $key, $selected, true)) && $opt_attr[] = 'selected'; - $input .= str_repeat("\t", $level); - $opt_attr['value'] = ($current_obj->get_config('prep_value', true) && empty($attributes['dont_prep'])) ? - $current_obj->prep_value($opt_attr['value']) : $opt_attr['value']; - $val = ($current_obj->get_config('prep_value', true) && empty($attributes['dont_prep'])) ? - $current_obj->prep_value($val) : $val; - $input .= html_tag('option', $opt_attr, $val).PHP_EOL; - } - } - unset($attributes['dont_prep']); - - return $input; - }; - - // generate the select options list - $input = $listoptions($options, $selected).str_repeat("\t", 0); - - if (empty($attributes['id']) && $this->get_config('auto_id', false) == true) - { - $attributes['id'] = $this->get_config('auto_id_prefix', '').$attributes['name']; - } - - // if it's a multiselect, make sure the name is an array - if (isset($attributes['multiple']) and substr($attributes['name'], -2) != '[]') - { - $attributes['name'] .= '[]'; - } - - return html_tag('select', $this->attr_to_string($attributes), $input); - } - - /** - * Create a label field - * - * @param string|array $label either fieldname or full attributes array (when array other params are ignored) - * @param string $id - * @param array $attributes - * @return string - */ - public function label($label, $id = null, array $attributes = array()) - { - if (is_array($label)) - { - $attributes = $label; - $label = $attributes['label']; - isset($attributes['id']) and $id = $attributes['id']; - } - - if (empty($attributes['for']) and ! empty($id)) - { - if ($this->get_config('auto_id', false) == true) - { - $attributes['for'] = $this->get_config('auto_id_prefix', 'form_').$id; - } - else - { - $attributes['for'] = $id; - } - } - - unset($attributes['label']); - - return html_tag('label', $attributes, \Lang::get($label, array(), false) ?: $label); - } - - /** - * Prep Value - * - * Prepares the value for display in the form - * - * @param string $value - * @return string - */ - public function prep_value($value) - { - $value = \Security::htmlentities($value, ENT_QUOTES); - - return $value; - } - - /** - * Attr to String - * - * Wraps the global attributes function and does some form specific work - * - * @param array $attr - * @return string - */ - protected function attr_to_string($attr) - { - unset($attr['label']); - return array_to_attr($attr); - } - - // fieldset related methods - - /** - * Returns the related fieldset - * - * @return Fieldset - */ - public function fieldset() - { - return $this->fieldset; - } - - /** - * Build & template individual field - * - * @param string|Fieldset_Field $field field instance or name of a field in this form's fieldset - * @return string - * @deprecated until v1.2 - */ - public function build_field($field) - { - ! $field instanceof Fieldset_Field && $field = $this->field($field); - - return $field->build(); - } - - /** - * Add a CSRF token and a validation rule to check it - */ - public function add_csrf() - { - $this->add(\Config::get('security.csrf_token_key', 'fuel_csrf_token'), 'CSRF Token') - ->set_type('hidden') - ->set_value(\Security::fetch_token()) - ->add_rule(array('Security', 'check_token')); - - return $this; - } - - /** - * Sets a config value on the fieldset - * - * @param string $config - * @param mixed $value - * @return Fieldset this, to allow chaining - */ - public function set_config($config, $value = null) - { - $this->fieldset->set_config($config, $value); - - return $this; - } - - /** - * Get a single or multiple config values by key - * - * @param string|array $key a single key or multiple in an array, empty to fetch all - * @param mixed $default default output when config wasn't set - * @return mixed|array a single config value or multiple in an array when $key input was an array - */ - public function get_config($key = null, $default = null) - { - if ($key === null) - { - return $this->fieldset->get_config(); - } - - if (is_array($key)) - { - $output = array(); - foreach ($key as $k) - { - $output[$k] = $this->fieldset->get_config($k, null) !== null - ? $this->fieldset->get_config($k, $default) - : \Config::get('form.'.$k, $default); - } - return $output; - } - - return $this->fieldset->get_config($key, null) !== null - ? $this->fieldset->get_config($key, $default) - : \Config::get('form.'.$key, $default); - } - - /** - * Alias for $this->fieldset->build() - * - * @param mixed $action - * @return string - */ - public function build($action = null) - { - return $this->fieldset()->build($action); - } - - /** - * Alias for $this->fieldset->add() - * - * @param string - * @param string - * @param array - * @param array - * @return Fieldset_Field - */ - public function add($name, $label = '', array $attributes = array(), array $rules = array()) - { - return $this->fieldset->add($name, $label, $attributes, $rules); - } - - /** - * Alias for $this->fieldset->add_model() - * - * @param string|Object $class either a full classname (including full namespace) or object instance - * @param array|Object $instance array or object that has the exactly same named properties to populate the fields - * @param string $method method name to call on model for field fetching - * @return Validation this, to allow chaining - */ - public function add_model($class, $instance = null, $method = 'set_form_fields') - { - $this->fieldset->add_model($class, $instance, $method); - - return $this; - } - - /** - * Alias for $this->fieldset->field() - * - * @param string|null $name field name or null to fetch an array of all - * @param bool $flatten whether to get the fields array or flattened array - * @return Fieldset_Field|false - */ - public function field($name = null, $flatten = false) - { - return $this->fieldset->field($name, $flatten); - } - - /** - * Alias for $this->fieldset->populate() for this fieldset - * - * @param array|object $input - * @param bool $repopulate - * @return Fieldset - */ - public function populate($input, $repopulate = false) - { - $this->fieldset->populate($input, $repopulate); - } - - /** - * Alias for $this->fieldset->repopulate() for this fieldset - * - * @return Fieldset_Field - */ - public function repopulate() - { - $this->fieldset->repopulate(); - } -} diff --git a/fuel/core/classes/format.php b/fuel/core/classes/format.php deleted file mode 100755 index 42b43d8..0000000 --- a/fuel/core/classes/format.php +++ /dev/null @@ -1,639 +0,0 @@ - 'bar'))->to_xml(); - * - * @param mixed $data general date to be converted - * @param string $from_type data format the file was provided in - * @param mixed $param additional parameter that can be passed on to a 'from' method - * @return Format - */ - public static function forge($data = null, $from_type = null, $param = null) - { - return new static($data, $from_type, $param); - } - - /** - * @var array|mixed input to convert - */ - protected $_data = array(); - - /** - * @var bool whether to ignore namespaces when parsing xml - */ - protected $ignore_namespaces = true; - - /** - * Do not use this directly, call forge() - * - * @param mixed $data general date to be converted - * @param string $from_type data format the file was provided in - * @param mixed $param additional parameter that can be passed on to a 'from' method - * @throws \FuelException - */ - public function __construct($data = null, $from_type = null, $param = null) - { - // If the provided data is already formatted we should probably convert it to an array - if ($from_type !== null) - { - - if ($from_type == 'xml:ns') - { - $this->ignore_namespaces = false; - $from_type = 'xml'; - } - - if (method_exists($this, '_from_' . $from_type)) - { - $data = call_user_func_array(array($this, '_from_' . $from_type), array($data, $param)); - } - - else - { - throw new \FuelException('Format class does not support conversion from "' . $from_type . '".'); - } - } - - $this->_data = $data; - } - - // FORMATING OUTPUT --------------------------------------------------------- - - /** - * To array conversion - * - * Goes through the input and makes sure everything is either a scalar value or array - * - * @param mixed $data - * @return array - */ - public function to_array($data = null) - { - if ($data === null) - { - $data = $this->_data; - } - - $array = array(); - - if (is_object($data) and ! $data instanceof \Iterator) - { - $data = get_object_vars($data); - } - - if (empty($data)) - { - return array(); - } - - foreach ($data as $key => $value) - { - if (is_object($value) or is_array($value)) - { - $array[$key] = $this->to_array($value); - } - else - { - $array[$key] = $value; - } - } - - return $array; - } - - /** - * To XML conversion - * - * @param mixed $data - * @param null $structure - * @param null|string $basenode - * @param null|bool $use_cdata whether to use CDATA in nodes - * @param mixed $bool_representation if true, element values are true/false. if 1, 1/0. - * @return string - */ - public function to_xml($data = null, $structure = null, $basenode = null, $use_cdata = null, $bool_representation = null) - { - if ($data == null) - { - $data = $this->_data; - } - - is_null($basenode) and $basenode = \Config::get('format.xml.basenode', 'xml'); - is_null($use_cdata) and $use_cdata = \Config::get('format.xml.use_cdata', false); - is_null($bool_representation) and $bool_representation = \Config::get('format.xml.bool_representation', null); - - // turn off compatibility mode as simple xml throws a wobbly if you don't. - if (ini_get('zend.ze1_compatibility_mode') == 1) - { - ini_set('zend.ze1_compatibility_mode', 0); - } - - if ($structure == null) - { - $structure = simplexml_load_string("<$basenode />"); - } - - // Force it to be something useful - if ( ! is_array($data) and ! is_object($data)) - { - $data = (array) $data; - } - - foreach ($data as $key => $value) - { - // replace anything not alpha numeric - $key = preg_replace('/[^a-z_\-0-9]/i', '', $key); - - // no numeric keys in our xml please! - if (is_numeric($key)) - { - // make string key... - $key = (\Inflector::singularize($basenode) != $basenode) ? \Inflector::singularize($basenode) : 'item'; - } - - // if there is another array found recrusively call this function - if (is_array($value) or is_object($value)) - { - $node = $structure->addChild($key); - - // recursive call if value is not empty - if( ! empty($value)) - { - $this->to_xml($value, $node, $key, $use_cdata, $bool_representation); - } - } - elseif ($bool_representation and is_bool($value)) - { - if ($bool_representation === true) - { - $bool = $value ? 'true' : 'false'; - } - else - { - $bool = $value ? '1' : '0'; - } - $structure->addChild($key, $bool); - } - else - { - // add single node. - $encoded = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, "UTF-8"); - - if ($use_cdata and ($encoded !== (string) $value)) - { - $dom = dom_import_simplexml($structure->addChild($key)); - $owner = $dom->ownerDocument; - $dom->appendChild($owner->createCDATASection($value)); - } - else - { - $structure->addChild($key, $encoded); - } - } - } - - // pass back as string. or simple xml object if you want! - return $structure->asXML(); - } - - /** - * To CSV conversion - * - * @param mixed $data - * @param mixed $delimiter - * @param mixed $enclose_numbers - * @param array $headings Custom headings to use - * @return string - */ - public function to_csv($data = null, $delimiter = null, $enclose_numbers = null, array $headings = array()) - { - // csv format settings - $newline = \Config::get('format.csv.newline', \Config::get('format.csv.export.newline', "\n")); - $delimiter or $delimiter = \Config::get('format.csv.delimiter', \Config::get('format.csv.export.delimiter', ',')); - $enclosure = \Config::get('format.csv.enclosure', \Config::get('format.csv.export.enclosure', '"')); - $escape = \Config::get('format.csv.escape', \Config::get('format.csv.export.escape', '\\')); - is_null($enclose_numbers) and $enclose_numbers = \Config::get('format.csv.enclose_numbers', true); - - // escape, delimit and enclose function - $escaper = function($items, $enclose_numbers) use($enclosure, $escape, $delimiter) { - return implode($delimiter, array_map(function($item) use($enclosure, $escape, $delimiter, $enclose_numbers) { - if ( ! is_numeric($item) or $enclose_numbers) - { - $item = $enclosure.str_replace($enclosure, $escape.$enclosure, $item).$enclosure; - } - return $item; - }, $items)); - }; - - if ($data === null) - { - $data = $this->_data; - } - - if (is_object($data) and ! $data instanceof \Iterator) - { - $data = $this->to_array($data); - } - - // Multi-dimensional array - if (empty($headings)) - { - if (is_array($data) and \Arr::is_multi($data)) - { - $data = array_values($data); - - if (\Arr::is_assoc($data[0])) - { - $headings = array_keys($data[0]); - } - else - { - $headings = array_shift($data); - } - } - // Single array - else - { - $headings = array_keys((array) $data); - $data = array($data); - } - } - - $output = $escaper($headings, true).$newline; - - foreach ($data as $row) - { - $output .= $escaper($row, $enclose_numbers).$newline; - } - - return rtrim($output, $newline); - } - - /** - * To JSON conversion - * - * @param mixed $data - * @param bool $pretty whether to make the json pretty - * @return string - */ - public function to_json($data = null, $pretty = false) - { - if ($data === null) - { - $data = $this->_data; - } - - // To allow exporting ArrayAccess objects like Orm\Model instances they need to be - // converted to an array first - $data = (is_array($data) or is_object($data)) ? $this->to_array($data) : $data; - return $pretty ? static::pretty_json($data) : json_encode($data, \Config::get('format.json.encode.options', JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP)); - } - - /** - * To JSONP conversion - * - * @param mixed $data - * @param bool $pretty whether to make the json pretty - * @param string $callback JSONP callback - * @return string formatted JSONP - */ - public function to_jsonp($data = null, $pretty = false, $callback = null) - { - $callback or $callback = \Input::param('callback'); - is_null($callback) and $callback = 'response'; - - return $callback.'('.$this->to_json($data, $pretty).')'; - } - - /** - * Serialize - * - * @param mixed $data - * @return string - */ - public function to_serialized($data = null) - { - if ($data === null) - { - $data = $this->_data; - } - - return serialize($data); - } - - /** - * Return as a string representing the PHP structure - * - * @param mixed $data - * @return string - */ - public function to_php($data = null) - { - if ($data === null) - { - $data = $this->_data; - } - - return var_export($data, true); - } - - /** - * Convert to YAML - * - * @param mixed $data - * @return string - */ - public function to_yaml($data = null) - { - if ($data == null) - { - $data = $this->_data; - } - - if ( ! function_exists('spyc_load')) - { - import('spyc/spyc', 'vendor'); - } - - return \Spyc::YAMLDump($data); - } - - /** - * Import XML data - * - * @param string $string - * @param bool $recursive - * @return array - */ - protected function _from_xml($string, $recursive = false) - { - // If it forged with 'xml:ns' - if ( ! $this->ignore_namespaces) - { - static $escape_keys = array(); - $recursive or $escape_keys = array('_xmlns' => 'xmlns'); - - if ( ! $recursive and strpos($string, 'xmlns') !== false and preg_match_all('/(\<.+?\>)/s', $string, $matches)) - { - foreach ($matches[1] as $tag) - { - $escaped_tag = $tag; - - strpos($tag, 'xmlns=') !== false and $escaped_tag = str_replace('xmlns=', '_xmlns=', $tag); - - if (preg_match_all('/[\s\<\/]([^\/\s\'"]*?:\S*?)[=\/\>\s]/s', $escaped_tag, $xmlns)) - { - foreach ($xmlns[1] as $ns) - { - $escaped = \Arr::search($escape_keys, $ns); - $escaped or $escape_keys[$escaped = str_replace(':', '_', $ns)] = $ns; - $string = str_replace($tag, $escaped_tag = str_replace($ns, $escaped, $escaped_tag), $string); - $tag = $escaped_tag; - } - } - } - } - } - - $_arr = is_string($string) ? simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA) : $string; - - // Convert all objects SimpleXMLElement to array recursively - $arr = array(); - foreach ((array) $_arr as $key => $val) - { - $this->ignore_namespaces or $key = \Arr::get($escape_keys, $key, $key); - if ( ! $val instanceOf \SimpleXMLElement or $val->count() or $val->attributes()) - { - $arr[$key] = (is_array($val) or is_object($val)) ? $this->_from_xml($val, true) : $val; - } - else - { - $arr[$val->getName()] = null; - } - } - - return $arr; - } - - /** - * Import YAML data - * - * @param string $string - * @return array - */ - protected function _from_yaml($string) - { - if ( ! function_exists('spyc_load')) - { - import('spyc/spyc', 'vendor'); - } - - return \Spyc::YAMLLoadString($string); - } - - /** - * Import CSV data - * - * @param string $string - * @param bool $no_headings - * @return array - */ - protected function _from_csv($string, $no_headings = false) - { - $data = array(); - - // csv config - $newline = \Config::get('format.csv.regex_newline', "\n"); - $delimiter = \Config::get('format.csv.delimiter', \Config::get('format.csv.import.delimiter', ',')); - $escape = \Config::get('format.csv.escape', \Config::get('format.csv.import.escape', '"')); - // have to do this in two steps, empty string is a valid value for enclosure! - $enclosure = \Config::get('format.csv.enclosure', \Config::get('format.csv.import.enclosure', null)); - $enclosure === null and $enclosure = '"'; - - if (empty($enclosure)) - { - $rows = preg_split('/(['.$newline.'])/m', trim($string), -1, PREG_SPLIT_NO_EMPTY); - } - else - { - $rows = preg_split('/(?<=[0-9'.preg_quote($enclosure).'])'.$newline.'/', trim($string)); - } - - // Get the headings - if ($no_headings !== false) - { - $headings = str_replace($escape.$enclosure, $enclosure, str_getcsv(array_shift($rows), $delimiter, $enclosure, $escape)); - $headcount = count($headings); - } - - // Process the rows - $incomplete = ''; - foreach ($rows as $row) - { - // process the row - $data_fields = str_replace($escape.$enclosure, $enclosure, str_getcsv($incomplete.($incomplete ? $newline : '').$row, $delimiter, $enclosure, $escape)); - - // if we didn't have headers, the first row determines the number of fields - if ( ! isset($headcount)) - { - $headcount = count($data_fields); - } - - // finish the row if the have the correct field count, otherwise add the data to the next row - if (count($data_fields) == $headcount) - { - $data[] = $no_headings === false ? $data_fields : array_combine($headings, $data_fields); - $incomplete = ''; - } - else - { - $incomplete = $row; - } - } - - return $data; - } - - /** - * Import JSON data - * - * @param string $string - * @return mixed - */ - private function _from_json($string) - { - return json_decode(trim($string)); - } - - /** - * Import Serialized data - * - * @param string $string - * @return mixed - */ - private function _from_serialize($string) - { - return unserialize(trim($string)); - } - - /** - * Makes json pretty the json output. - * Borrowed from http://www.php.net/manual/en/function.json-encode.php#80339 - * - * @param string $data json encoded array - * @return string|false pretty json output or false when the input was not valid - */ - protected static function pretty_json($data) - { - $json = json_encode($data, \Config::get('format.json.encode.options', JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP)); - - if ( ! $json) - { - return false; - } - - $tab = "\t"; - $newline = "\n"; - $new_json = ""; - $indent_level = 0; - $in_string = false; - $len = strlen($json); - - for ($c = 0; $c < $len; $c++) - { - $char = $json[$c]; - switch($char) - { - case '{': - case '[': - if ( ! $in_string) - { - $new_json .= $char.$newline.str_repeat($tab, $indent_level+1); - $indent_level++; - } - else - { - $new_json .= $char; - } - break; - case '}': - case ']': - if ( ! $in_string) - { - $indent_level--; - $new_json .= $newline.str_repeat($tab, $indent_level).$char; - } - else - { - $new_json .= $char; - } - break; - case ',': - if ( ! $in_string) - { - $new_json .= ','.$newline.str_repeat($tab, $indent_level); - } - else - { - $new_json .= $char; - } - break; - case ':': - if ( ! $in_string) - { - $new_json .= ': '; - } - else - { - $new_json .= $char; - } - break; - case '"': - if ($c > 0 and $json[$c-1] !== '\\') - { - $in_string = ! $in_string; - } - default: - $new_json .= $char; - break; - } - } - - return $new_json; - } - - /** - * Loads Format config. - */ - public static function _init() - { - \Config::load('format', true); - } -} diff --git a/fuel/core/classes/ftp.php b/fuel/core/classes/ftp.php deleted file mode 100755 index 67a627e..0000000 --- a/fuel/core/classes/ftp.php +++ /dev/null @@ -1,651 +0,0 @@ -connect(); - - return $ftp; - } - - /** - * Sets the initial Ftp filename and local data. - * - * @param string|array $config The name of the config group to use, or a configuration array. - */ - public function __construct($config = 'default') - { - \Config::load('ftp', true); - - // If it is a string we're looking at a predefined config group - if (is_string($config)) - { - $config_arr = \Config::get('ftp.'.$config); - - // Check that it exists - if ( ! is_array($config_arr) or $config_arr === array()) - { - throw new \UnexpectedValueException('You have specified an invalid ftp connection group: '.$config); - } - - $config = $config_arr; - } - - // Prep the hostname - $this->_hostname = preg_replace('|.+?://|', '', $config['hostname']); - $this->_username = $config['username']; - $this->_password = $config['password']; - $this->_timeout = ! empty($config['timeout']) ? (int) $config['timeout'] : 90; - $this->_port = ! empty($config['port']) ? (int) $config['port'] : 21; - $this->_passive = (bool) $config['passive']; - $this->_ssl_mode = (bool) $config['ssl_mode']; - $this->_debug = (bool) $config['debug']; - - static::$initialized = true; - } - - // -------------------------------------------------------------------- - - /** - * FTP Connect - * - * @return \Ftp - * @throws \FtpConnectionException - */ - public function connect() - { - if($this->_ssl_mode === true) - { - if( ! function_exists('ftp_ssl_connect')) - { - throw new \RuntimeException('ftp_ssl_connect() function is missing.'); - } - - $this->_conn_id = @ftp_ssl_connect($this->_hostname, $this->_port, $this->_timeout); - } - - else - { - $this->_conn_id = @ftp_connect($this->_hostname, $this->_port, $this->_timeout); - } - - if ($this->_conn_id === false) - { - if ($this->_debug == true) - { - throw new \FtpConnectionException('Unable to establish a connection'); - } - return false; - } - - if ( ! $this->_login()) - { - if ($this->_debug == true) - { - throw new \FtpConnectionException('Unable to login'); - } - } - - // Set passive mode if needed - if ($this->_passive == true) - { - ftp_pasv($this->_conn_id, true); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * FTP Login - * - * @return bool - */ - protected function _login() - { - return @ftp_login($this->_conn_id, $this->_username, $this->_password); - } - - // -------------------------------------------------------------------- - - /** - * Validates the connection ID - * - * @return bool - */ - protected function _is_conn() - { - if ( ! is_resource($this->_conn_id)) - { - if ($this->_debug == true) - { - throw new \InvalidArgumentException('Invalid connection'); - } - return false; - } - return true; - } - - // -------------------------------------------------------------------- - - - /** - * Change directory - * - * The second parameter lets us momentarily turn off debugging so that - * this function can be used to test for the existence of a folder - * without throwing an error. There's no FTP equivalent to is_dir() - * so we do it by trying to change to a particular directory. - * Internally, this parameter is only used by the "mirror" function below. - * - * @param string $path - * @return bool - * @throws \FtpFileAccessException - */ - public function change_dir($path = '') - { - if ($path == '' or ! $this->_is_conn()) - { - return false; - } - - $result = @ftp_chdir($this->_conn_id, $path); - - if ($result === false) - { - if ($this->_debug == true) - { - throw new \FtpFileAccessException('Unable to change the directory'); - } - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Create a directory - * - * @param string $path - * @param string $permissions - * @return bool - * @throws \FtpFileAccessException - */ - public function mkdir($path, $permissions = null) - { - if ( ! $this->_is_conn()) - { - return false; - } - - $result = ftp_mkdir($this->_conn_id, $path); - - if ($result === false) - { - if ($this->_debug == true) - { - throw new \FtpFileAccessException('Unable to create directory'); - } - return false; - } - - // Set file permissions if needed - if ($permissions !== null) - { - $this->chmod($path, (int) $permissions); - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Upload a file to the server - * - * @param string $local_path - * @param string $remote_path - * @param string $mode - * @param string $permissions - * @return bool - * @throws \FtpFileAccessException - */ - public function upload($local_path, $remote_path, $mode = 'auto', $permissions = null) - { - if ( ! $this->_is_conn()) - { - return false; - } - - if ( ! is_file($local_path)) - { - throw new \FtpFileAccessException('No source file'); - } - - // Set the mode if not specified - if ($mode == 'auto') - { - // Get the file extension so we can set the upload type - $ext = pathinfo($local_path, PATHINFO_EXTENSION); - $mode = $this->_settype($ext); - } - - $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY; - - $result = @ftp_put($this->_conn_id, $remote_path, $local_path, $mode); - - if ($result === false) - { - if ($this->_debug == true) - { - throw new \FtpFileAccessException('Unable to upload'); - } - return false; - } - - // Set file permissions if needed - if ($permissions !== null) - { - $this->chmod($remote_path, (int) $permissions); - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Download a file from a remote server to the local server - * - * @param string $remote_path - * @param string $local_path - * @param string $mode - * @return bool - * @throws \FtpFileAccessException - */ - public function download($remote_path, $local_path, $mode = 'auto') - { - if ( ! $this->_is_conn()) - { - return false; - } - - // Set the mode if not specified - if ($mode == 'auto') - { - // Get the file extension so we can set the upload type - $ext = pathinfo($remote_path, PATHINFO_BASENAME); - $mode = $this->_settype($ext); - } - - $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY; - - $result = @ftp_get($this->_conn_id, $local_path, $remote_path, $mode); - - if ($result === false) - { - if ($this->_debug === true) - { - throw new \FtpFileAccessException('Unable to download'); - } - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Rename (or move) a file - * - * @param $old_file string - * @param $new_file string - * @param $move bool - * @return bool - * @throws \FtpFileAccessException - */ - public function rename($old_file, $new_file, $move = false) - { - if ( ! $this->_is_conn()) - { - return false; - } - - $result = @ftp_rename($this->_conn_id, $old_file, $new_file); - - if ($result === false) - { - if ($this->_debug == true) - { - $msg = ($move == false) ? 'Unable to rename' : 'Unable to move'; - - throw new \FtpFileAccessException($msg); - } - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Move a file - * - * @param string $old_file - * @param string $new_file - * @return bool - */ - public function move($old_file, $new_file) - { - return $this->rename($old_file, $new_file, true); - } - - // -------------------------------------------------------------------- - - /** - * Rename (or move) a file - * - * @param string $filepath - * @return bool - * @throws \FtpFileAccessException - */ - function delete_file($filepath) - { - if ( ! $this->_is_conn()) - { - return false; - } - - $result = @ftp_delete($this->_conn_id, $filepath); - - if ($result === false) - { - if ($this->_debug == true) - { - throw new \FtpFileAccessException('Unable to delete'); - } - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Delete a folder and recursively delete everything (including sub-folders) - * contained within it. - * - * @param string $filepath - * @return bool - * @throws \FtpFileAccessException - */ - function delete_dir($filepath) - { - if ( ! $this->_is_conn()) - { - return false; - } - - // Add a trailing slash to the file path if needed - $filepath = preg_replace("/(.+?)\/*$/", "\\1/", $filepath); - - $list = $this->list_files($filepath); - - if ($list !== false and count($list) > 0) - { - foreach ($list as $item) - { - // If we can't delete the item it's probaly a folder so - // we'll recursively call delete_dir() - if ( ! @ftp_delete($this->_conn_id, $item)) - { - // don't recurse into current of parent directory - if ( ! preg_match('/\/\.\.|\/\.$/', $item)) - { - $this->delete_dir($item); - } - } - } - } - - $result = @ftp_rmdir($this->_conn_id, $filepath); - - if ($result === false) - { - if ($this->_debug == true) - { - throw new \FtpFileAccessException('Unable to delete'); - } - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Set file permissions - * - * @param string $path the file path - * @param string $permissions the permissions - * @return bool - * @throws \FtpFileAccessException - */ - public function chmod($path, $permissions) - { - if ( ! $this->_is_conn()) - { - return false; - } - - // Permissions can only be set when running PHP 5 - if ( ! function_exists('ftp_chmod')) - { - if ($this->_debug == true) - { - throw new \FtpFileAccessException('CHMOD function does not exist'); - } - return false; - } - - $result = @ftp_chmod($this->_conn_id, $permissions, $path); - - if ($result === false) - { - if ($this->_debug == true) - { - throw new \FtpFileAccessException('Unable to CHMOD'); - } - return false; - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * FTP List files in the specified directory - * - * @param string $path - * @return array - */ - public function list_files($path = '.') - { - if ( ! $this->_is_conn()) - { - return false; - } - - return ftp_nlist($this->_conn_id, $path); - } - - // ------------------------------------------------------------------------ - - /** - * Read a directory and recreate it remotely - * - * This function recursively reads a folder and everything it contains (including - * sub-folders) and creates a mirror via FTP based on it. Whatever the directory structure - * of the original file path will be recreated on the server. - * - * @param string $local_path path to source with trailing slash - * @param string $remote_path path to destination - include the base folder with trailing slash - * @return bool - */ - public function mirror($local_path, $remote_path) - { - if ( ! $this->_is_conn()) - { - return false; - } - - // Open the local file path - if ($fp = @opendir($local_path)) - { - // Attempt to open the remote file path. - if ( ! $this->change_dir($remote_path, true)) - { - // If it doesn't exist we'll attempt to create the directory - if ( ! $this->mkdir($remote_path) or ! $this->change_dir($remote_path)) - { - return false; - } - } - - // Recursively read the local directory - while (false !== ($file = readdir($fp))) - { - if (@is_dir($local_path.$file) and substr($file, 0, 1) != '.') - { - $this->mirror($local_path.$file."/", $remote_path.$file."/"); - } - elseif (substr($file, 0, 1) != ".") - { - // Get the file extension so we can se the upload type - $ext = pathinfo($file, PATHINFO_EXTENSION); - $mode = $this->_settype($ext); - - $this->upload($local_path.$file, $remote_path.$file, $mode); - } - } - return true; - } - - return false; - } - - // -------------------------------------------------------------------- - - /** - * Set the upload type - * - * @param string $ext - * @return string - */ - protected function _settype($ext) - { - $text_types = array( - 'txt', - 'text', - 'php', - 'phps', - 'php4', - 'js', - 'css', - 'htm', - 'html', - 'phtml', - 'shtml', - 'log', - 'xml', - ); - - return in_array($ext, $text_types) ? 'ascii' : 'binary'; - } - - // ------------------------------------------------------------------------ - - /** - * Close the connection - * - * @return void - */ - public function close() - { - if ( ! $this->_is_conn()) - { - return false; - } - - @ftp_close($this->_conn_id); - } - - // ------------------------------------------------------------------------ - - /** - * Close the connection when the class is unset - * - * @return void - */ - public function __destruct() - { - $this->close(); - } - -} diff --git a/fuel/core/classes/fuel.php b/fuel/core/classes/fuel.php deleted file mode 100755 index 7015a43..0000000 --- a/fuel/core/classes/fuel.php +++ /dev/null @@ -1,391 +0,0 @@ -read_cache('FuelFileFinder'); - } - - static::$profiling = \Config::get('profiling', false); - static::$profiling and \Profiler::init(); - - // set a default timezone if one is defined - try - { - static::$timezone = \Config::get('default_timezone') ?: date_default_timezone_get(); - date_default_timezone_set(static::$timezone); - } - catch (\Exception $e) - { - date_default_timezone_set('UTC'); - throw new \PHPErrorException($e->getMessage()); - } - - static::$encoding = \Config::get('encoding', static::$encoding); - MBSTRING and mb_internal_encoding(static::$encoding); - - static::$locale = \Config::get('locale', static::$locale); - - // Set locale, log warning when it fails - if (static::$locale) - { - setlocale(LC_ALL, static::$locale) or - logger(\Fuel::L_WARNING, 'The configured locale '.static::$locale.' is not installed on your system.', __METHOD__); - } - - if ( ! static::$is_cli) - { - if (\Config::get('base_url') === null) - { - \Config::set('base_url', static::generate_base_url()); - } - } - - // Run Input Filtering - \Security::clean_input(); - - \Event::register('fuel-shutdown', 'Fuel::finish'); - - // Always load classes, config & language set in always_load.php config - static::always_load(); - - // Load in the routes - \Config::load('routes', true); - \Router::add(\Config::get('routes')); - - // BC FIX FOR APPLICATIONS <= 1.6.1, makes Redis_Db available as Redis, - // like it was in versions before 1.7 - class_exists('Redis', false) or class_alias('Redis_Db', 'Redis'); - - // BC FIX FOR PHP < 7.0 to make the error class available - if (PHP_VERSION_ID < 70000) - { - // alias the error class to the new errorhandler - class_alias('\Fuel\Core\Errorhandler', '\Fuel\Core\Error'); - - // does the app have an overloaded Error class? - if (class_exists('Error')) - { - // then alias that too - class_alias('Error', 'Errorhandler'); - } - } - - static::$initialized = true; - - // fire any app created events - \Event::instance()->has_events('app_created') and \Event::instance()->trigger('app_created', '', 'none'); - - if (static::$profiling) - { - \Profiler::mark(__METHOD__.' End'); - } - } - - /** - * Cleans up Fuel execution, ends the output buffering, and outputs the - * buffer contents. - * - * @access public - * @return void - */ - public static function finish() - { - if (\Config::get('caching', false)) - { - \Finder::instance()->write_cache('FuelFileFinder'); - } - - if (static::$profiling and ! static::$is_cli and ! \Input::is_ajax()) - { - // Grab the output buffer and flush it, we will rebuffer later - $output = ob_get_clean(); - - $headers = headers_list(); - $show = true; - - foreach ($headers as $header) - { - if (stripos($header, 'content-type') === 0 and stripos($header, 'text/html') === false) - { - $show = false; - } - } - - if ($show) - { - \Profiler::mark('End of Fuel Execution'); - if (preg_match("|.*?|is", $output)) - { - $output = preg_replace("|.*?|is", '', $output); - $output .= \Profiler::output(); - $output .= ''; - } - else - { - $output .= \Profiler::output(); - } - } - // Restart the output buffer and send the new output - ob_start(\Config::get('ob_callback')); - echo $output; - } - } - - /** - * Generates a base url. - * - * @return string the base url - */ - protected static function generate_base_url() - { - $base_url = ''; - if(\Input::server('http_host')) - { - $base_url .= \Input::protocol().'://'.\Input::server('http_host'); - } - if (\Input::server('script_name')) - { - $common = get_common_path(array(\Input::server('request_uri'), \Input::server('script_name'))); - $base_url .= $common; - } - - // Add a slash if it is missing and return it - return rtrim($base_url, '/').'/'; - } - - /** - * Includes the given file and returns the results. - * - * @param string the path to the file - * @return mixed the results of the include - */ - public static function load($file) - { - return include $file; - } - - /** - * Always load packages, modules, classes, config & language files set in always_load.php config - * - * @param array what to autoload - */ - public static function always_load($array = null) - { - is_null($array) and $array = \Config::get('always_load', array()); - - isset($array['packages']) and \Package::load($array['packages']); - - isset($array['modules']) and \Module::load($array['modules']); - - if (isset($array['classes'])) - { - foreach ($array['classes'] as $class) - { - if ( ! class_exists($class = \Str::ucwords($class))) - { - throw new \FuelException('Class '.$class.' defined in your "always_load" config could not be loaded.'); - } - } - } - - /** - * Config and Lang must be either just the filename, example: array(filename) - * or the filename as key and the group as value, example: array(filename => some_group) - */ - - if (isset($array['config'])) - { - foreach ($array['config'] as $config => $config_group) - { - \Config::load((is_int($config) ? $config_group : $config), (is_int($config) ? true : $config_group)); - } - } - - if (isset($array['language'])) - { - foreach ($array['language'] as $lang => $lang_group) - { - \Lang::load((is_int($lang) ? $lang_group : $lang), (is_int($lang) ? true : $lang_group)); - } - } - } - - /** - * Takes a value and checks if it is a Closure or not, if it is it - * will return the result of the closure, if not, it will simply return the - * value. - * - * @param mixed $var The value to get - * @return mixed - */ - public static function value($var) - { - return ($var instanceof \Closure) ? $var() : $var; - } - - /** - * Cleans a file path so that it does not contain absolute file paths. - * - * @param string the filepath - * @return string the clean path - */ - public static function clean_path($path) - { - // framework default paths - static $search = array('\\', APPPATH, COREPATH, PKGPATH, DOCROOT); - static $replace = array('/', 'APPPATH/', 'COREPATH/', 'PKGPATH/', 'DOCROOT/'); - - // additional paths configured than need cleaning - $extra = \Config::get('security.clean_paths', array()); - foreach ($extra as $r => $s) - { - $search[] = $s; - $replace[] = $r.'/'; - } - - // clean up and return it - return str_ireplace($search, $replace, $path); - } -} diff --git a/fuel/core/classes/html.php b/fuel/core/classes/html.php deleted file mode 100755 index dc171e5..0000000 --- a/fuel/core/classes/html.php +++ /dev/null @@ -1,289 +0,0 @@ - $secure ? 'https' : 'http')); - - // Trim the trailing slash - $href = rtrim($href, '/'); - } - - // Create and display a URL hyperlink - is_null($text) and $text = $href; - - $attr['href'] = $href; - - return html_tag('a', $attr, $text); - } - - /** - * Creates an html image tag - * - * Sets the alt attribute to filename of it is not supplied. - * - * @param string $src the source - * @param array $attr the attributes array - * @return string the image tag - */ - public static function img($src, $attr = array()) - { - if ( ! preg_match('#^(\w+://)# i', $src)) - { - $src = \Uri::base(false).$src; - } - $attr['src'] = $src; - $attr['alt'] = (isset($attr['alt'])) ? $attr['alt'] : pathinfo($src, PATHINFO_FILENAME); - return html_tag('img', $attr); - } - - /** - * Adds the given schema to the given URL if it is not already there. - * - * @param string $url the url - * @param string $schema the schema - * @return string url with schema - */ - public static function prep_url($url, $schema = 'http') - { - if ( ! preg_match('#^(\w+://|javascript:)# i', $url)) - { - $url = $schema.'://'.$url; - } - - return $url; - } - - /** - * Creates a mailto link. - * - * @param string $email The email address - * @param string $text The text value - * @param string $subject The subject - * @param array $attr attributes for the tag - * @return string The mailto link - */ - public static function mail_to($email, $text = null, $subject = null, $attr = array()) - { - $text or $text = $email; - - $subject and $subject = '?subject='.$subject; - - return html_tag('a', array( - 'href' => 'mailto:'.$email.$subject, - ) + $attr, $text); - } - - /** - * Creates a mailto link with Javascript to prevent bots from picking up the - * email address. - * - * @param string $email the email address - * @param string $text the text value - * @param string $subject the subject - * @param array $attr attributes for the tag - * @return string the javascript code containing email - */ - public static function mail_to_safe($email, $text = null, $subject = null, $attr = array()) - { - $text or $text = str_replace('@', '[at]', $email); - - $email = explode("@", $email); - - $subject and $subject = '?subject='.$subject; - - $attr = array_to_attr($attr); - $attr = ($attr == '' ? '' : ' ').$attr; - - $output = ''; - return $output; - } - - /** - * Generates a html meta tag - * - * @param string|array $name multiple inputs or name/http-equiv value - * @param string $content content value - * @param string $type name or http-equiv - * @return string - */ - public static function meta($name = '', $content = '', $type = 'name') - { - if( ! is_array($name)) - { - $result = html_tag('meta', array($type => $name, 'content' => $content)); - } - elseif(is_array($name)) - { - $result = ""; - foreach($name as $array) - { - $meta = $array; - $result .= "\n" . html_tag('meta', $meta); - } - } - return $result; - } - - /** - * Generates a html doctype tag - * - * @param string $type doctype declaration key from doctypes config - * @return string - */ - public static function doctype($type = 'xhtml1-trans') - { - if(static::$doctypes === null) - { - \Config::load('doctypes', true); - static::$doctypes = \Config::get('doctypes', array()); - } - - if(is_array(static::$doctypes) and isset(static::$doctypes[$type])) - { - if($type == "html5") - { - static::$html5 = true; - } - return static::$doctypes[$type]; - } - else - { - return false; - } - } - - /** - * Generates a html5 audio tag - * It is required that you set html5 as the doctype to use this method - * - * @param string|array $src one or multiple audio sources - * @param array $attr tag attributes - * @return string - */ - public static function audio($src = '', $attr = false) - { - if(static::$html5) - { - if(is_array($src)) - { - $source = ''; - foreach($src as $item) - { - $source .= html_tag('source', array('src' => $item)); - } - } - else - { - $source = html_tag('source', array('src' => $src)); - } - return html_tag('audio', $attr, $source); - } - } - - /** - * Generates a html un-ordered list tag - * - * @param array $list list items, may be nested - * @param array|string $attr outer list attributes - * @return string - */ - public static function ul(array $list = array(), $attr = false) - { - return static::build_list('ul', $list, $attr); - } - - /** - * Generates a html ordered list tag - * - * @param array $list list items, may be nested - * @param array|string $attr outer list attributes - * @return string - */ - public static function ol(array $list = array(), $attr = false) - { - return static::build_list('ol', $list, $attr); - } - - /** - * Generates the html for the list methods - * - * @param string $type list type (ol or ul) - * @param array $list list items, may be nested - * @param array $attr tag attributes - * @param string $indent indentation - * @return string - */ - protected static function build_list($type = 'ul', array $list = array(), $attr = false, $indent = '') - { - if ( ! is_array($list)) - { - $result = false; - } - - $out = ''; - foreach ($list as $key => $val) - { - if ( ! is_array($val)) - { - $out .= $indent."\t".html_tag('li', array(), $val).PHP_EOL; - } - else - { - $out .= $indent."\t".html_tag('li', array(), $key.PHP_EOL.static::build_list($type, $val, '', $indent."\t\t").$indent."\t").PHP_EOL; - } - } - $result = $indent.html_tag($type, $attr, PHP_EOL.$out.$indent).PHP_EOL; - return $result; - } -} diff --git a/fuel/core/classes/httpexception.php b/fuel/core/classes/httpexception.php deleted file mode 100755 index e04cdeb..0000000 --- a/fuel/core/classes/httpexception.php +++ /dev/null @@ -1,42 +0,0 @@ -response(); - - // fire any app shutdown events - \Event::instance()->trigger('shutdown', '', 'none', true); - - // fire any framework shutdown events - \Event::instance()->trigger('fuel-shutdown', '', 'none', true); - - // send the response out - $response->send(true); - } -} diff --git a/fuel/core/classes/httpexceptions.php b/fuel/core/classes/httpexceptions.php deleted file mode 100755 index 1cda3c6..0000000 --- a/fuel/core/classes/httpexceptions.php +++ /dev/null @@ -1,45 +0,0 @@ -load($filename); - } - return $return; - } - - /** - * Used to set configuration options. - * - * Sending the config options through the static reference initializes the - * instance. If you need to send a driver config through the static reference, - * make sure its the first one sent! If errors arise, create a new instance using - * forge(). - * - * @param array $index An array of configuration settings. - * @param mixed $value - * @return Image_Driver - */ - public static function config($index = array(), $value = null) - { - if (static::$_instance === null) - { - if ($value !== null) - { - $index = array($index => $value); - } - if (is_array($index)) - { - static::$_config = array_merge(static::$_config, $index); - } - static::instance(); - return static::instance(); - } else { - return static::instance()->config($index, $value); - } - } - - /** - * Loads the image and checks if its compatible. - * - * @param string $filename The file to load - * @param string $return_data Decides if it should return the images data, or just "$this". - * @param mixed $force_extension Whether or not to force the image extension - * @return Image_Driver - */ - public static function load($filename, $return_data = false, $force_extension = false) - { - return static::instance()->load($filename, $return_data, $force_extension); - } - - /** - * Crops the image using coordinates or percentages. - * - * Absolute integer or percentages accepted for all 4. - * - * @param integer $x1 X-Coordinate based from the top-left corner. - * @param integer $y1 Y-Coordinate based from the top-left corner. - * @param integer $x2 X-Coordinate based from the bottom-right corner. - * @param integer $y2 Y-Coordinate based from the bottom-right corner. - * @return Image_Driver - */ - public static function crop($x1, $y1, $x2, $y2) - { - return static::instance()->crop($x1, $y1, $x2, $y2); - } - - /** - * Resize the image. If the width or height is null, it will resize retaining the original aspect ratio. - * - * @param integer $width The new width of the image. - * @param integer $height The new height of the image. - * @param boolean $keepar Defaults to true. If false, allows resizing without keeping AR. - * @param boolean $pad If set to true and $keepar is true, it will pad the image with the configured bgcolor - * @return Image_Driver - */ - public static function resize($width, $height, $keepar = true, $pad = false) - { - return static::instance()->resize($width, $height, $keepar, $pad); - } - - /** - * Resize the image. If the width or height is null, it will resize retaining the original aspect ratio. - * - * @param integer $width The new width of the image. - * @param integer $height The new height of the image. - * @return Image_Driver - */ - public static function crop_resize($width, $height) - { - return static::instance()->crop_resize($width, $height); - } - - /** - * Rotates the image - * - * @param integer $degrees The degrees to rotate, negatives integers allowed. - * @return Image_Driver - */ - public static function rotate($degrees) - { - return static::instance()->rotate($degrees); - } - - /** - * Creates a vertical / horizontal or both mirror image. - * - * @param string $direction 'vertical', 'horizontal', 'both' - * @return Image_Driver - */ - public static function flip($direction) - { - return static::instance()->flip($direction); - } - - /** - * Adds a watermark to the image. - * - * @param string $filename The filename of the watermark file to use. - * @param string $position The position of the watermark, ex: "bottom right", "center center", "top left" - * @param integer $padding The spacing between the edge of the image. - * @return Image_Driver - */ - public static function watermark($filename, $position, $padding = 5) - { - return static::instance()->watermark($filename, $position, $padding); - } - - /** - * Adds a border to the image. - * - * @param integer $size The side of the border, in pixels. - * @param string $color A hexadecimal color. - * @return Image_Driver - */ - public static function border($size, $color = null) - { - return static::instance()->border($size, $color); - } - - /** - * Masks the image using the alpha channel of the image input. - * - * @param string $maskimage The location of the image to use as the mask - * @return Image_Driver - */ - public static function mask($maskimage) - { - return static::instance()->mask($maskimage); - } - - /** - * Adds rounded corners to the image. - * - * @param integer $radius - * @param integer $sides Accepts any combination of "tl tr bl br" separated by spaces, or null for all sides - * @param integer $antialias Sets the anti-alias range. - * @return Image_Driver - */ - public static function rounded($radius, $sides = null, $antialias = null) - { - return static::instance()->rounded($radius, $sides, $antialias); - } - - /** - * Turns the image into a grayscale version - * - * @return Image_Driver - */ - public static function grayscale() - { - return static::instance()->grayscale(); - } - - /** - * Saves the image, and optionally attempts to set permissions - * - * @param string $filename The location where to save the image. - * @param string $permissions Allows unix style permissions - * @return Image_Driver - */ - public static function save($filename = null, $permissions = null) - { - return static::instance()->save($filename, $permissions); - } - - /** - * Saves the image, and optionally attempts to set permissions - * - * @param string $prepend The text to add to the beginning of the filename. - * @param string $append The text to add to the end of the filename. - * @param string $permissions Allows unix style permissions - * @return Image_Driver - */ - public static function save_pa($prepend, $append = null, $permissions = null) - { - return static::instance()->save_pa($prepend, $append, $permissions); - } - - /** - * Outputs the file directly to the user. - * - * @param string $filetype The extension type to use. Ex: png, jpg, bmp, gif - * @return Image_Driver - */ - public static function output($filetype = null) - { - return static::instance()->output($filetype); - } - - /** - * Returns sizes for the currently loaded image, or the image given in the $filename. - * - * @param string $filename The location of the file to get sizes for. - * @return object An object containing width and height variables. - */ - public static function sizes($filename = null) - { - return static::instance()->sizes($filename); - } - - /** - * Reloads the image. - * - * @return Image_Driver - */ - public static function reload() - { - return static::instance()->reload(); - } -} diff --git a/fuel/core/classes/image/driver.php b/fuel/core/classes/image/driver.php deleted file mode 100755 index b74b491..0000000 --- a/fuel/core/classes/image/driver.php +++ /dev/null @@ -1,912 +0,0 @@ -config = array_merge(\Config::get('image', array()), $config); - } - else - { - $this->config = \Config::get('image', array()); - } - $this->debug("Image Class was initialized using the " . $this->config['driver'] . " driver."); - } - /** - * Accepts configuration in either an array (as $index) or a pairing using $index and $value - * - * @param string $index The index to be set, or an array of configuration options. - * @param mixed $value The value to be set if $index is not an array. - * @return Image_Driver - */ - public function config($index = null, $value = null) - { - if (is_array($index)) - { - if (isset($index['driver'])) - { - throw new \RuntimeException("The driver cannot be changed after initialization!"); - } - $this->config = array_merge($this->config, $index); - } - elseif ($index != null) - { - if ($index == 'driver') - { - throw new \RuntimeException("The driver cannot be changed after initialization!"); - } - $this->config[$index] = $value; - } - - return $this; - } - - /** - * Executes the presets set in the config. Additional parameters replace the $1, $2, ect. - * - * @param string $name The name of the preset. - * @return Image_Driver - */ - public function preset($name) - { - $vars = func_get_args(); - if (isset($this->config['presets'][$name])) - { - $old_config = $this->config; - $this->config = array_merge($this->config, $this->config['presets'][$name]); - foreach ($this->config['actions'] AS $action) - { - $func = $action[0]; - array_shift($action); - for ($i = 0; $i < count($action); $i++) - { - for ($x = count($vars) - 1; $x >= 0; $x--) - { - $action[$i] = preg_replace('#\$' . $x . '#', $vars[$x], $action[$i]); - } - } - call_fuel_func_array(array($this, $func), $action); - } - $this->config = $old_config; - } - else - { - throw new \InvalidArgumentException("Could not load preset $name, you sure it exists?"); - } - return $this; - } - - /** - * Loads the image and checks if its compatible. - * - * @param string $filename The file to load - * @param string $return_data Decides if it should return the images data, or just "$this". - * @param mixed $force_extension Decides if it should force the extension with this (or false) - * @return Image_Driver - */ - public function load($filename, $return_data = false, $force_extension = false) - { - // First check if the filename exists - $filename = realpath($filename); - $return = array( - 'filename' => $filename, - 'return_data' => $return_data, - ); - if (is_file($filename)) - { - // Check the extension - $ext = $this->check_extension($filename, false, $force_extension); - if ($ext !== false) - { - $return = array_merge($return, array( - 'image_fullpath' => $filename, - 'image_directory' => dirname($filename), - 'image_filename' => basename($filename), - 'image_extension' => $ext, - )); - if ( ! $return_data) - { - $this->image_fullpath = $filename; - $this->image_directory = dirname($filename); - $this->image_filename = basename($filename); - $this->image_extension = $ext; - } - } - else - { - throw new \RuntimeException("The library does not support this filetype for $filename."); - } - } - else - { - throw new \OutOfBoundsException("Image file $filename does not exist."); - } - return $return; - } - - /** - * Crops the image using coordinates or percentages. - * - * Positive whole numbers or percentages are coordinates from the top left. - * - * Negative whole numbers or percentages are coordinates from the bottom right. - * - * @param integer $x1 X-Coordinate for first set. - * @param integer $y1 Y-Coordinate for first set. - * @param integer $x2 X-Coordinate for second set. - * @param integer $y2 Y-Coordinate for second set. - * @return Image_Driver - */ - public function crop($x1, $y1, $x2, $y2) - { - $this->queue('crop', $x1, $y1, $x2, $y2); - return $this; - } - - /** - * Executes the crop event when the queue is ran. - * - * Formats the crop method input for use with driver specific methods - * - * @param integer $x1 X-Coordinate for first set. - * @param integer $y1 Y-Coordinate for first set. - * @param integer $x2 X-Coordinate for second set. - * @param integer $y2 Y-Coordinate for second set. - * @return array An array of variables for the specific driver. - */ - protected function _crop($x1, $y1, $x2, $y2) - { - $y1 === null and $y1 = $x1; - $x2 === null and $x2 = "-" . $x1; - $y2 === null and $y2 = "-" . $y1; - - $x1 = $this->convert_number($x1, true); - $y1 = $this->convert_number($y1, false); - $x2 = $this->convert_number($x2, true); - $y2 = $this->convert_number($y2, false); - - return array( - 'x1' => $x1, - 'y1' => $y1, - 'x2' => $x2, - 'y2' => $y2, - ); - } - - /** - * Resize the image. If the width or height is null, it will resize retaining the original aspect ratio. - * - * @param integer $width The new width of the image. - * @param integer $height The new height of the image. - * @param boolean $keepar If false, allows stretching of the image. - * @param boolean $pad Adds padding to the image when resizing. - * @return Image_Driver - */ - public function resize($width, $height = null, $keepar = true, $pad = false) - { - $this->queue('resize', $width, $height, $keepar, $pad); - return $this; - } - - /** - * Creates a vertical / horizontal or both mirror image. - * - * @param mixed $direction 'vertical', 'horizontal', 'both' - * @return Image_Driver - */ - public function flip($direction) - { - $this->queue('flip', $direction); - return $this; - } - - /** - * Executes the resize event when the queue is ran. - * - * Formats the resize method input for use with driver specific methods. - * - * @param integer $width The new width of the image. - * @param integer $height The new height of the image. - * @param boolean $keepar If false, allows stretching of the image. - * @param boolean $pad Adds padding to the image when resizing. - * @return array An array of variables for the specific driver. - */ - protected function _resize($width, $height = null, $keepar = true, $pad = true) - { - if ($height == null or $width == null) - { - if ($height == null and substr($width, -1) == '%') - { - $height = $width; - } - elseif (substr($height, -1) == '%' and $width == null) - { - $width = $height; - } - else - { - $sizes = $this->sizes(); - if ($height == null and $width != null) - { - $height = $width * ($sizes->height / $sizes->width); - } - elseif ($height != null and $width == null) - { - $width = $height * ($sizes->width / $sizes->height); - } - else - { - throw new \InvalidArgumentException("Width and height cannot be null."); - } - } - } - - $origwidth = $this->convert_number($width, true); - $origheight = $this->convert_number($height, false); - $width = $origwidth; - $height = $origheight; - $sizes = $this->sizes(); - $x = 0; - $y = 0; - if ($keepar) - { - // See which is the biggest ratio - if (function_exists('bcdiv')) - { - $width_ratio = bcdiv($width, $sizes->width, 10); - $height_ratio = bcdiv($height, $sizes->height, 10); - $compare = bccomp($width_ratio, $height_ratio, 10); - if ($compare > -1) - { - $height = ceil((float) bcmul($sizes->height, $height_ratio, 10)); - $width = ceil((float) bcmul($sizes->width, $height_ratio, 10)); - } - else - { - $height = ceil((float) bcmul($sizes->height, $width_ratio, 10)); - $width = ceil((float) bcmul($sizes->width, $width_ratio, 10)); - } - } - else - { - $width_ratio = $width / $sizes->width; - $height_ratio = $height / $sizes->height; - if ($width_ratio >= $height_ratio) - { - $height = ceil($sizes->height * $height_ratio); - $width = ceil($sizes->width * $height_ratio); - } - else - { - $height = ceil($sizes->height * $width_ratio); - $width = ceil($sizes->width * $width_ratio); - } - } - } - - if ($pad) - { - $x = floor(($origwidth - $width) / 2); - $y = floor(($origheight - $height) / 2); - } - else - { - $origwidth = $width; - $origheight = $height; - } - - return array( - 'width' => $width, - 'height' => $height, - 'cwidth' => $origwidth, - 'cheight' => $origheight, - 'x' => $x, - 'y' => $y, - ); - } - - public function crop_resize($width, $height = null) - { - is_null($height) and $height = $width; - $this->queue('crop_resize', $width, $height); - return $this; - } - - protected function _crop_resize($width, $height) - { - // Determine the crop size - $sizes = $this->sizes(); - $width = $this->convert_number($width, true); - $height = $this->convert_number($height, false); - - if (function_exists('bcdiv')) - { - if (bccomp(bcdiv($sizes->width, $width, 10), bcdiv($sizes->height, $height, 10), 10) < 1) - { - $this->_resize($width, 0, true, false); - } - else - { - $this->_resize(0, $height, true, false); - } - } - else - { - if ($sizes->width / $width < $sizes->height / $height) - { - $this->_resize($width, 0, true, false); - } - else - { - $this->_resize(0, $height, true, false); - } - } - - $sizes = $this->sizes(); - $y = floor(max(0, $sizes->height - $height) / 2); - $x = floor(max(0, $sizes->width - $width) / 2); - $this->_crop($x, $y, $x + $width, $y + $height); - } - - /** - * Rotates the image - * - * @param integer $degrees The degrees to rotate, negatives integers allowed. - * @return Image_Driver - */ - public function rotate($degrees) - { - $this->queue('rotate', $degrees); - return $this; - } - - /** - * Executes the rotate event when the queue is ran. - * - * Formats the rotate method input for use with driver specific methods - * - * @param integer $degrees The degrees to rotate, negatives integers allowed. - * @return array An array of variables for the specific driver. - */ - protected function _rotate($degrees) - { - $degrees %= 360; - if ($degrees < 0) - { - $degrees = 360 + $degrees; - } - return array( - 'degrees' => $degrees, - ); - } - - /** - * Adds a watermark to the image. - * - * @param string $filename The filename of the watermark file to use. - * @param string $position The position of the watermark, ex: "bottom right", "center center", "top left" - * @param integer $padding The amount of padding (in pixels) from the position. - * @return Image_Driver - */ - public function watermark($filename, $position, $padding = 5) - { - $this->queue('watermark', $filename, $position, $padding); - return $this; - } - - /** - * Executes the watermark event when the queue is ran. - * - * Formats the watermark method input for use with driver specific methods - * - * @param string $filename The filename of the watermark file to use. - * @param string $position The position of the watermark, ex: "bottom right", "center center", "top left" - * @param integer $padding The amount of padding (in pixels) from the position. - * @return array An array of variables for the specific driver. - */ - protected function _watermark($filename, $position, $padding = 5) - { - $filename = realpath($filename); - $return = false; - if (is_file($filename) and $this->check_extension($filename, false)) - { - $x = 0; - $y = 0; - $wsizes = $this->sizes($filename); - $sizes = $this->sizes(); - // Get the x and y positions. - list($ypos, $xpos) = explode(' ', $position); - switch ($xpos) - { - case 'left': - $x = $padding; - break; - case 'middle': - case 'center': - $x = ($sizes->width / 2) - ($wsizes->width / 2); - break; - case 'right': - $x = $sizes->width - $wsizes->width - $padding; - break; - } - switch ($ypos) - { - case 'top': - $y = $padding; - break; - case 'middle': - case 'center': - $y = ($sizes->height / 2) - ($wsizes->height / 2); - break; - case 'bottom': - $y = $sizes->height - $wsizes->height - $padding; - break; - } - $this->debug("Watermark being placed at $x,$y"); - $return = array( - 'filename' => $filename, - 'x' => $x, - 'y' => $y, - 'padding' => $padding, - ); - } - return $return; - } - - /** - * Adds a border to the image. - * - * @param integer $size The side of the border, in pixels. - * @param string $color A hexadecimal color. - * @return Image_Driver - */ - public function border($size, $color = null) - { - $this->queue('border', $size, $color); - return $this; - } - - /** - * Executes the border event when the queue is ran. - * - * Formats the border method input for use with driver specific methods - * - * @param integer $size The side of the border, in pixels. - * @param string $color A hexadecimal color. - * @return array An array of variables for the specific driver. - */ - protected function _border($size, $color = null) - { - empty($color) and $color = $this->config['bgcolor']; - - return array( - 'size' => $size, - 'color' => $color, - ); - } - - /** - * Masks the image using the alpha channel of the image input. - * - * @param string $maskimage The location of the image to use as the mask - * @return Image_Driver - */ - public function mask($maskimage) - { - $this->queue('mask', $maskimage); - return $this; - } - - /** - * Executes the mask event when the queue is ran. - * - * Formats the mask method input for use with driver specific methods - * - * @param string $maskimage The location of the image to use as the mask - * @return array An array of variables for the specific driver. - */ - protected function _mask($maskimage) - { - return array( - 'maskimage' => $maskimage, - ); - } - - /** - * Adds rounded corners to the image. - * - * @param integer $radius - * @param integer $sides Accepts any combination of "tl tr bl br" separated by spaces, or null for all sides - * @param integer $antialias Sets the anti-alias range. - * @return Image_Driver - */ - public function rounded($radius, $sides = null, $antialias = null) - { - $this->queue('rounded', $radius, $sides, $antialias); - return $this; - } - - /** - * Executes the rounded event when the queue is ran. - * - * Formats the rounded method input for use with driver specific methods - * - * @param integer $radius - * @param integer $sides Accepts any combination of "tl tr bl br" separated by spaces, or null for all sides - * @param integer $antialias Sets the anti-alias range. - * @return array An array of variables for the specific driver. - */ - protected function _rounded($radius, $sides, $antialias) - { - $radius < 0 and $radius = 0; - $tl = $tr = $bl = $br = $sides == null; - - if ($sides != null) - { - $sides = explode(' ', $sides); - foreach ($sides as $side) - { - if ($side == 'tl' or $side == 'tr' or $side == 'bl' or $side == 'br') - { - $$side = true; - } - } - } - $antialias == null and $antialias = 1; - - return array( - 'radius' => $radius, - 'tl' => $tl, - 'tr' => $tr, - 'bl' => $bl, - 'br' => $br, - 'antialias' => $antialias, - ); - } - - /** - * Turns the image into a grayscale version - * - * @return Image_Driver - */ - public function grayscale() - { - $this->queue('grayscale'); - return $this; - } - - /** - * Executes the grayscale event when the queue is ran. - */ - abstract protected function _grayscale(); - - /** - * Saves the image, and optionally attempts to set permissions - * - * @param string $filename The location where to save the image. - * @param string $permissions Allows unix style permissions - * @return array - */ - public function save($filename = null, $permissions = null) - { - if (empty($filename)) - { - $filename = $this->image_filename; - } - - $directory = dirname($filename); - if ( ! is_dir($directory)) - { - throw new \OutOfBoundsException("Could not find directory \"$directory\""); - } - - if ( ! $this->check_extension($filename, true)) - { - $filename .= "." . $this->image_extension; - } - // Touch the file - if ( ! touch($filename)) - { - throw new \RuntimeException("Do not have permission to write to \"$filename\""); - } - - // Set the new permissions - if ($permissions != null and ! chmod($filename, $permissions)) - { - throw new \RuntimeException("Could not set permissions on the file."); - } - - $this->debug("", "Saving image as $filename"); - return array( - 'filename' => $filename, - ); - } - - /** - * Saves the file in the original location, adding the append and prepend to the filename. - * - * @param string $append The string to append to the filename - * @param string $prepend The string to prepend to the filename - * @param string $extension The extension to save the image as, null defaults to the loaded images extension. - * @param integer $permissions The permissions to attempt to set on the file. - * @return Image_Driver - */ - public function save_pa($append, $prepend = null, $extension = null, $permissions = null) - { - $filename = substr($this->image_filename, 0, -(strlen($this->image_extension) + 1)); - $fullpath = $this->image_directory.'/'.$append.$filename.$prepend.'.'. - ($extension !== null ? $extension : $this->image_extension); - $this->save($fullpath, $permissions); - return $this; - } - - /** - * Outputs the file directly to the user. - * - * @param string $filetype The extension type to use. Ex: png, jpg, gif - * @return array - * @throws \FuelException - */ - public function output($filetype = null) - { - if ($filetype == null) - { - $filetype = $this->config['filetype'] == null ? $this->image_extension : $this->config['filetype']; - } - - if ($this->check_extension($filetype, false)) - { - if ( ! $this->config['debug']) - { - $mimetype = $filetype === 'jpg' ? 'jpeg' : $filetype; - header('Content-Type: image/' . $mimetype); - } - $this->new_extension = $filetype; - } - else - { - throw new \FuelException("Image extension $filetype is unsupported."); - } - - $this->debug('', "Outputting image as $filetype"); - return array( - 'filetype' => $filetype, - ); - } - - /** - * Returns sizes for the currently loaded image, or the image given in the $filename. - * - * @param string $filename The location of the file to get sizes for. - * @return object An object containing width and height variables. - */ - abstract public function sizes($filename = null); - - /** - * Adds a background to the image using the 'bgcolor' config option. - */ - abstract protected function add_background(); - - /** - * Creates a new color usable by all drivers. - * - * @param string $hex The hex code of the color - * @return array rgba representation of the hex and alpha values. - */ - protected function create_hex_color($hex) - { - if ($hex == null) - { - $red = 0; - $green = 0; - $blue = 0; - $alpha = 0; - } - else - { - // Check if theres a # in front - if (substr($hex, 0, 1) == '#') - { - $hex = substr($hex, 1); - } - - // Break apart the hex - if (strlen($hex) == 6 or strlen($hex) == 8) - { - $red = hexdec(substr($hex, 0, 2)); - $green = hexdec(substr($hex, 2, 2)); - $blue = hexdec(substr($hex, 4, 2)); - $alpha = (strlen($hex) == 8) ? hexdec(substr($hex, 6, 2)) : 255; - } - else - { - $red = hexdec(substr($hex, 0, 1).substr($hex, 0, 1)); - $green = hexdec(substr($hex, 1, 1).substr($hex, 1, 1)); - $blue = hexdec(substr($hex, 2, 1).substr($hex, 2, 1)); - $alpha = (strlen($hex) > 3) ? hexdec(substr($hex, 3, 1).substr($hex, 3, 1)) : 255; - } - } - - $alpha = floor($alpha / 2.55); - - return array( - 'red' => $red, - 'green' => $green, - 'blue' => $blue, - 'alpha' => $alpha, - ); - } - - /** - * Checks if the extension is accepted by this library, and if its valid sets the $this->image_extension variable. - * - * @param string $filename - * @param boolean $writevar Decides if the extension should be written to $this->image_extension - * @param mixed $force_extension Decides if the extension should be overridden with this (or false) - * @return boolean - */ - protected function check_extension($filename, $writevar = true, $force_extension = false) - { - $return = false; - - if ($force_extension !== false and in_array($force_extension, $this->accepted_extensions)) - { - return $force_extension; - } - - foreach ($this->accepted_extensions as $ext) - { - if (strtolower(substr($filename, strlen($ext) * -1)) == strtolower($ext)) - { - $writevar and $this->image_extension = $ext; - $return = $ext; - } - } - return $return; - } - - /** - * Converts percentages, negatives, and other values to absolute integers. - * - * @param string $input - * @param boolean $x Determines if the number relates to the x-axis or y-axis. - * @return integer The converted number, usable with the image being edited. - */ - protected function convert_number($input, $x = null) - { - // Sanitize double negatives - $input = str_replace('--', '', $input); - - // Depending on php configuration, float are sometimes converted to strings - // using commas instead of points. This notation can create issues since the - // conversion from string to float will return an integer. - // For instance: "1.2" / 10 == 0.12 but "1,2" / 10 == 0.1... - $input = str_replace(',', '.', $input); - - $orig = $input; - $sizes = $this->sizes(); - $size = $x ? $sizes->width : $sizes->height; - // Convert percentages to absolutes - if (substr($input, -1) == '%') - { - $input = floor((substr($input, 0, -1) / 100) * $size); - } - // Negatives are based off the bottom right - if ($x !== null and $input < 0) - { - $input = $size + $input; - } - return $input; - } - - /** - * Queues a function to run at a later time. - * - * @param string $function The name of the function to be ran, without the leading _ - */ - protected function queue($function) - { - $func = func_get_args(); - $tmpfunc = array(); - for ($i = 0; $i < count($func); $i++) - { - $tmpfunc[$i] = var_export($func[$i], true); - } - - $this->debug("Queued " . implode(", ", $tmpfunc) . ""); - $this->queued_actions[] = $func; - } - - /** - * Runs all queued actions on the loaded image. - * - * @param boolean $clear Decides if the queue should be cleared once completed. - */ - public function run_queue($clear = null) - { - foreach ($this->queued_actions as $action) - { - $tmpfunc = array(); - for ($i = 0; $i < count($action); $i++) - { - $tmpfunc[$i] = var_export($action[$i], true); - } - $this->debug('', "Executing " . implode(", ", $tmpfunc) . ""); - call_user_func_array(array(&$this, '_' . $action[0]), array_slice($action, 1)); - } - if (($clear === null and $this->config['clear_queue']) or $clear === true) - { - $this->queued_actions = array(); - } - } - - /** - * Reloads the image. - * - * @return Image_Driver - */ - public function reload() - { - $this->debug("Reloading was called!"); - $this->load($this->image_fullpath); - return $this; - } - - /** - * Get the file extension (type) worked out on construct - * - * @return string File extension - */ - public function extension() - { - return $this->image_extension; - } - - /** - * Used for debugging image output. - */ - protected function debug() - { - if ($this->config['debug']) - { - $messages = func_get_args(); - foreach ($messages as $message) - { - echo '
' . $message . ' 
'; - } - } - } -} diff --git a/fuel/core/classes/image/gd.php b/fuel/core/classes/image/gd.php deleted file mode 100755 index 1c71bfd..0000000 --- a/fuel/core/classes/image/gd.php +++ /dev/null @@ -1,551 +0,0 @@ -image_data !== null and imagedestroy($this->image_data); - $this->image_data = null; - } - - // Check if the function exists - if (function_exists('imagecreatefrom'.$image_extension)) - { - // Create a new transparent image. - $sizes = $this->sizes($image_fullpath); - $tmpImage = call_user_func('imagecreatefrom'.$image_extension, $image_fullpath); - $image = $this->create_transparent_image($sizes->width, $sizes->height, $tmpImage); - if ( ! $return_data) - { - $this->image_data = $image; - $return = true; - } - else - { - $return = $image; - } - $this->debug('', "Loaded ".$image_fullpath." with size of ".$sizes->width."x".$sizes->height); - } - else - { - throw new \RuntimeException("Function imagecreatefrom".$image_extension."() does not exist (Missing GD?)"); - } - return $return_data ? $return : $this; - } - - protected function _crop($x1, $y1, $x2, $y2) - { - extract(parent::_crop($x1, $y1, $x2, $y2)); - $width = $x2 - $x1; - $height = $y2 - $y1; - $this->debug("Cropping image ".$width."x".$height."+$x1+$y1 based on coords ($x1, $y1), ($x2, $y2)"); - $image = $this->create_transparent_image($width, $height); - - imagecopy($image, $this->image_data, 0, 0, $x1, $y1, $width, $height); - $this->image_data = $image; - } - - protected function _resize($width, $height = null, $keepar = true, $pad = true) - { - extract(parent::_resize($width, $height, $keepar, $pad)); - $sizes = $this->sizes(); - - $this->debug("Resizing image to $width, $height with" . ($keepar ? '' : 'out') . " keeping AR and with" . ($pad ? '' : 'out') . " padding."); - - // Add the original image. - $image = $this->create_transparent_image($cwidth, $cheight); - call_user_func($this->gdresizefunc, $image, $this->image_data, $x, $y, 0, 0, $width, $height, $sizes->width, $sizes->height); - $this->image_data = $image; - } - - protected function _rotate($degrees) - { - extract(parent::_rotate($degrees)); - $degrees = 360 - $degrees; - $bgcolor = $this->config['bgcolor'] !== null ? $this->config['bgcolor'] : '#000'; - $color = $this->create_color($this->image_data, $bgcolor, 100); - $this->image_data = imagerotate($this->image_data, $degrees, $color, false); - } - - protected function _watermark($filename, $position, $padding = 5) - { - $values = parent::_watermark($filename, $position, $padding); - if ($values == false) - { - throw new \InvalidArgumentException("Watermark image not found or invalid filetype."); - } - else - { - extract($values); - $wsizes = $this->sizes($filename); - $sizes = $this->sizes(); - - // Load the watermark preserving transparency - $watermark = $this->load($filename, true); - - // Below is to prevent glitch in GD with negative $x coords - if ($x < 0 || $y < 0) - { - $this->debug("Modifying watermark to remove negative coords."); - // Generate a new width and height for the watermark. - $newwidth = ($x < 0 ? $wsizes->width + $x : $wsizes->width); - $newheight = ($y < 0 ? $wsizes->height + $y : $wsizes->height); - // Create a transparent image the size of the new watermark. - $tmpwatermark = $this->create_transparent_image($newwidth, $newheight); - $this->debug("New size is $newwidth x $newheight and coords are $x , $y"); - // Call the resize function based on image format - imagecopy( - $tmpwatermark, $watermark, // Copy the new image into the tmp watermark - 0, 0, - $x < 0 ? abs($x) : 0, - $y < 0 ? abs($y) : 0, - $newwidth, $newheight - ); - // Set the variables for the image_merge - $watermark = $tmpwatermark; - $x = $x < 0 ? 0 : $x; - $y = $y < 0 ? 0 : $y; - } - // Used as a workaround for lack of alpha support in imagecopymerge. - $this->debug("Coords for watermark are $x , $y"); - $this->image_merge($this->image_data, $watermark, $x, $y, $this->config['watermark_alpha']); - } - } - - protected function _flip($mode) - { - $sizes = (array) $this->sizes(); - $source = array_merge($sizes, array('x' => 0, 'y' => 0)); - - switch ($mode) - { - case 'vertical': - $source['y'] = $sizes['height'] - 1; - $source['height'] = -$sizes['height']; - break; - - case 'horizontal': - $source['x'] = $sizes['width'] - 1; - $source['width'] = -$sizes['width']; - break; - - case 'both': - $source['y'] = $sizes['height'] - 1; - $source['x'] = $sizes['width'] - 1; - $source['height'] = -$sizes['height']; - $source['width'] = -$sizes['width']; - break; - - default: return false; - } - - $image = imagecreatetruecolor($sizes['width'], $sizes['height']); - - imagecopyresampled( - $image, - $this->image_data, - 0, - 0, - $source['x'], - $source['y'], - $sizes['width'], - $sizes['height'], - $source['width'], - $source['height'] - ); - - $this->image_data = $image; - } - - protected function _border($size, $color = null) - { - extract(parent::_border($size, $color)); - $sizes = $this->sizes(); - $image = $this->create_transparent_image($sizes->width + ($size * 2), $sizes->height + ($size * 2)); - $color = $this->create_color($image, $color, 100); - $this->image_merge($image, $this->image_data, $size, $size, 100); - for ($s = 0; $s < $size; $s++) - { - imagerectangle($image, $s, $s, $sizes->width + ($size * 2) - $s - 1, $sizes->height + ($size * 2) - $s - 1, $color); - } - $this->image_data = $image; - } - - protected function _mask($maskimage) - { - extract(parent::_mask($maskimage)); - - // Get size and width of image - $sizes = $this->sizes(); - $masksizes = $this->sizes($maskimage); - - // Create new blank image - $image = $this->create_transparent_image($sizes->width, $sizes->height); - if (is_resource($maskimage)) - { - $maskim = $maskimage; - } - else - { - $maskim = $this->load($maskimage, true); - } - - $masksizes->width > $sizes->width and $masksizes->width = $sizes->width; - $masksizes->height > $sizes->width and $masksizes->height = $sizes->height; - - // Loop through all the pixels - for ($x = 0; $x < $masksizes->width; $x++) - { - for ($y = 0; $y < $masksizes->height; $y++) - { - $maskcolor = imagecolorat($maskim, $x, $y); - $maskcolor = imagecolorsforindex($maskim, $maskcolor); - $maskalpha = 127 - floor(($maskcolor['red'] + $maskcolor['green'] + $maskcolor['blue']) / 6); - if ($maskalpha == 127) - { - continue; - } - - if ($maskalpha == 0) - { - $ourcolor = array( - 'red' => 0, - 'green' => 0, - 'blue' => 0, - 'alpha' => 0, - ); - } - else - { - $ourcolor = imagecolorat($this->image_data, $x, $y); - $ourcolor = imagecolorsforindex($this->image_data, $ourcolor); - } - - $ouralpha = 127 - $ourcolor['alpha']; - if ($ouralpha == 0) - { - continue; - } - - $newalpha = floor($ouralpha - (($maskalpha / 127) * $ouralpha)); - $newcolor = imagecolorallocatealpha($image, $ourcolor['red'], $ourcolor['green'], $ourcolor['blue'], 127 - $newalpha); - imagesetpixel($image, $x, $y, $newcolor); - } - } - - $this->image_data = $image; - } - - protected function _rounded($radius, $sides, $antialias) - { - extract(parent::_rounded($radius, $sides, $antialias)); - - $tl and $this->round_corner($this->image_data, $radius, $antialias, true, true); - $tr and $this->round_corner($this->image_data, $radius, $antialias, true, false); - $bl and $this->round_corner($this->image_data, $radius, $antialias, false, true); - $br and $this->round_corner($this->image_data, $radius, $antialias, false, false); - } - - protected function _grayscale() - { - $sizes = $this->sizes(); - - // Create the 256 color palette - $bwpalette = array(); - for ($i = 0; $i < 256; $i++) - { - $bwpalette[$i] = imagecolorallocate($this->image_data, $i, $i, $i); - } - - for ($x = 0; $x < $sizes->width; $x++) - { - for ($y = 0; $y < $sizes->height; $y++) - { - $color = imagecolorat($this->image_data, $x, $y); - $red = ($color >> 16) & 0xFF; - $green = ($color >> 8) & 0xFF; - $blue = $color & 0xFF; - - // If its black or white, theres no use in setting the pixel - if (($red == 0 && $green == 0 && $blue == 0) || ($red == 255 && $green == 255 && $blue == 255)) - { - continue; - } - - // Now set the color - $shade = (($red*0.299)+($green*0.587)+($blue*0.114)); - imagesetpixel($this->image_data, $x, $y, $bwpalette[$shade]); - } - } - } - - public function sizes($filename = null) - { - if (empty($filename) && !empty($this->image_fullpath)) - { - $filename = $this->image_fullpath; - } - - if ($filename == $this->image_fullpath && is_resource($this->image_data)) - { - $width = imagesx($this->image_data); - $height = imagesy($this->image_data); - } - elseif (is_resource($filename)) - { - $width = imagesx($filename); - $height = imagesy($filename); - } - else - { - list($width, $height) = getimagesize($filename); - } - return (object) array('width' => $width, 'height' => $height); - } - - public function save($filename = null, $permissions = null) - { - extract(parent::save($filename, $permissions)); - - $this->run_queue(); - $this->add_background(); - - $vars = array(&$this->image_data, $filename); - $filetype = $this->image_extension; - if ($filetype == 'jpg' || $filetype == 'jpeg') - { - $vars[] = $this->config['quality']; - $filetype = 'jpeg'; - } - elseif ($filetype == 'png') - { - $vars[] = floor(($this->config['quality'] / 100) * 9); - } - - call_fuel_func_array('image'.$filetype, $vars); - if ($this->config['persistence'] === false) - { - $this->reload(); - } - - return $this; - } - - public function output($filetype = null) - { - $this->gdresizefunc = ($filetype == 'gif') ? 'imagecopyresized' : $this->gdresizefunc = 'imagecopyresampled'; - - extract(parent::output($filetype)); - - $this->run_queue(); - $this->add_background(); - - $vars = array($this->image_data, null); - if ($filetype == 'jpg' || $filetype == 'jpeg') - { - $vars[] = $this->config['quality']; - $filetype = 'jpeg'; - } - elseif ($filetype == 'png') - { - $vars[] = floor(($this->config['quality'] / 100) * 9); - } - - call_fuel_func_array('image'.$filetype, $vars); - - if ($this->config['persistence'] === false) - { - $this->reload(); - } - - return $this; - } - - /** - * Creates a new color usable by GD. - * - * @param resource $image The image to create the color from - * @param string $hex The hex code of the color - * @param integer $alpha The alpha of the color, 0 (trans) to 100 (opaque) - * @return integer The color - */ - protected function create_color(&$image, $hex, $alpha) - { - extract($this->create_hex_color($hex)); - - // Handling alpha is different among drivers - if ($hex == null) - { - $alpha = 127; - } - else - { - $alpha = 127 - floor($alpha * 1.27); - } - - // Check if the transparency is allowed - return imagecolorallocatealpha($image, $red, $green, $blue, $alpha); - } - - protected function add_background() - { - if ($this->config['bgcolor'] != null || ($this->new_extension == 'jpg' || $this->new_extension == 'jpeg')) - { - $bgcolor = $this->config['bgcolor'] == null ? '#000' : $this->config['bgcolor']; - $this->debug("Adding background color $bgcolor"); - $sizes = $this->sizes(); - $bgimg = $this->create_transparent_image($sizes->width, $sizes->height); - $color = $this->create_color($bgimg, $bgcolor, 100); - imagefill($bgimg, 0, 0, $color); - $this->image_merge($bgimg, $this->image_data, 0, 0, 100); - $this->image_data = $bgimg; - } - } - - /** - * Creates a new transparent image. - * - * @param integer $width The width of the image. - * @param integer $height The height of the image. - * @param resource $resource Optionally add an image to the new transparent image. - * @return resource Returns the image in resource form. - */ - protected function create_transparent_image($width, $height, $resource = null) - { - $image = imagecreatetruecolor($width, $height); - $bgcolor = $this->config['bgcolor'] == null ? '#000' : $this->config['bgcolor']; - $color = $this->create_color($image, $bgcolor, 0); - imagesavealpha($image, true); - if ($this->image_extension == 'gif' || $this->image_extension == 'png') - { - // Get the current transparent color if possible... - $transcolor = imagecolortransparent($image); - if ($transcolor > 0) - { - $color = $transcolor; - } - imagecolortransparent($image, $color); - } - // Set the blending mode to false, add the bgcolor, then switch it back. - imagealphablending($image, false); - imagefilledrectangle($image, 0, 0, $width, $height, $color); - imagealphablending($image, true); - - if (is_resource($resource)) - { - imagecopy($image, $resource, 0, 0, 0, 0, $width, $height); - } - return $image; - } - - /** - * Creates a rounded corner on the image. - * - * @param resource $image - * @param integer $radius - * @param integer $antialias - * @param boolean $top - * @param boolean $left - */ - protected function round_corner(&$image, $radius, $antialias, $top, $left) - { - $this->debug("Rounding ".($top ? 'top' : 'bottom')." ".($left ? 'left' : 'right')." corner with a radius of ".$radius."px."); - $sX = $left ? -$radius : 0; - $sY = $top ? -$radius : 0; - $eX = $left ? 0 : $radius; - $eY = $top ? 0 : $radius; - - // Get this images size - $sizes = $this->sizes(); - $offsetX = ($left ? $radius : $sizes->width - $radius - 1); - $offsetY = ($top ? $radius : $sizes->height - $radius - 1); - - // Set the images alpha blend to false - imagealphablending($image, false); - - // Make this color ahead time - $transparent = $this->create_color($image, null, 0); - for ($x = $sX; $x <= $eX; $x++) - { - for ($y = $sY; $y <= $eY; $y++) - { - $dist = sqrt(($x * $x) + ($y * $y)); - if ($dist <= $radius + $antialias) - { - // Decide if anything needs to be changed - // We subtract from antialias so the transparency makes sense. - $fromCirc = $dist - $radius; - if ($fromCirc > 0) - { - if ($fromCirc == 0) - { - imagesetpixel($image, $x + $offsetX, $y + $offsetY, $transparent); - } - else - { - // Get color information from this spot on the image - $rgba = imagecolorat($image, $x + $offsetX, $y + $offsetY); - $tmpColor = imagecolorallocatealpha( - $image, - ($rgba >> 16) & 0xFF, // Red - ($rgba >> 8) & 0xFF, // Green - $rgba & 0xFF, // Blue - (127 - (($rgba >> 24) & 0xFF)) * ($fromCirc / $antialias) // Alpha - ); - imagesetpixel($image, $x + $offsetX, $y + $offsetY, $tmpColor); - } - } - } - else - { - // Clear this area out... - imagesetpixel($image, $x + $offsetX, $y + $offsetY, $transparent); - } - } - } - // Reset alpha blending - imagealphablending($image, true); - } - - /** - * Merges to images together, using a fix for transparency - * - * @param resource $image The bottom image - * @param resource $watermark The image to be placed on top - * @param integer $x The position of the watermark on the X-axis - * @param integer $y The position of the watermark on the Y-axis - * @param integer $alpha The transparency of the watermark, 0 (trans) to 100 (opaque) - */ - protected function image_merge(&$image, $watermark, $x, $y, $alpha) - { - $wsizes = $this->sizes($watermark); - $tmpimage = $this->create_transparent_image($wsizes->width, $wsizes->height); - imagecopy($tmpimage, $image, 0, 0, $x, $y, $wsizes->width, $wsizes->height); - imagecopy($tmpimage, $watermark, 0, 0, 0, 0, $wsizes->width, $wsizes->height); - imagealphablending($image, false); - imagecopymerge($image, $tmpimage, $x, $y, 0, 0, $wsizes->width, $wsizes->height, $alpha); - imagealphablending($image, true); - } -} diff --git a/fuel/core/classes/image/imagemagick.php b/fuel/core/classes/image/imagemagick.php deleted file mode 100755 index cfe298c..0000000 --- a/fuel/core/classes/image/imagemagick.php +++ /dev/null @@ -1,356 +0,0 @@ -clear_sizes(); - if (empty($this->image_temp)) - { - do - { - $this->image_temp = $this->config['temp_dir'].substr($this->config['temp_append'].md5(time() * microtime()), 0, 32).'.png'; - } - while (is_file($this->image_temp)); - } - elseif (is_file($this->image_temp)) - { - $this->debug('Removing previous temporary image.'); - unlink($this->image_temp); - } - $this->debug('Temp file: '.$this->image_temp); - if ( ! is_dir($this->config['temp_dir'])) - { - throw new \RuntimeException("The temp directory that was given does not exist."); - } - elseif (!touch($this->config['temp_dir'] . $this->config['temp_append'] . '_touch')) - { - throw new \RuntimeException("Could not write in the temp directory."); - } - $this->exec('convert', '"'.$image_fullpath.'"[0] "'.$this->image_temp.'"'); - - return $this; - } - - protected function _crop($x1, $y1, $x2, $y2) - { - extract(parent::_crop($x1, $y1, $x2, $y2)); - $image = '"'.$this->image_temp.'"'; - $this->exec('convert', $image.' -crop '.($x2 - $x1).'x'.($y2 - $y1).'+'.$x1.'+'.$y1.' +repage '.$image); - $this->clear_sizes(); - } - - protected function _resize($width, $height = null, $keepar = true, $pad = true) - { - extract(parent::_resize($width, $height, $keepar, $pad)); - - $image = '"'.$this->image_temp.'"'; - $this->exec('convert', "-define png:size=".$cwidth."x".$cheight." ".$image." ". - "-background none ". - "-resize \"".($pad ? $width : $cwidth)."x".($pad ? $height : $cheight)."!\" ". - "-gravity center ". - "-extent ".$cwidth."x".$cheight." ".$image); - $this->clear_sizes(); - } - - protected function _rotate($degrees) - { - extract(parent::_rotate($degrees)); - - $image = '"'.$this->image_temp.'"'; - $this->exec('convert', $image." -background none -virtual-pixel background +distort ScaleRotateTranslate ".$degrees." +repage ".$image); - - $this->clear_sizes(); - } - - protected function _flip($direction) - { - switch ($direction) - { - case 'vertical': - $arg = '-flip'; - break; - - case 'horizontal': - $arg = '-flop'; - break; - - case 'both': - $arg = '-flip -flop'; - break; - - default: return false; - } - $image = '"'.$this->image_temp.'"'; - $this->exec('convert', $image.' '.$arg.' '.$image); - } - - protected function _watermark($filename, $position, $padding = 5) - { - $values = parent::_watermark($filename, $position, $padding); - if ($values == false) - { - throw new \InvalidArgumentException("Watermark image not found or invalid filetype."); - } - - extract($values); - $x >= 0 and $x = '+'.$x; - $y >= 0 and $y = '+'.$y; - - $image = '"'.$this->image_temp.'"'; - $this->exec( - 'composite', - '-compose atop -geometry '.$x.$y.' '. - '-dissolve '.$this->config['watermark_alpha'].'% '. - '"'.$filename.'" "'.$this->image_temp.'" '.$image - ); - } - - protected function _border($size, $color = null) - { - extract(parent::_border($size, $color)); - - $image = '"'.$this->image_temp.'"'; - $color = $this->create_color($color, 100); - $command = $image.' -compose copy -bordercolor '.$color.' -border '.$size.'x'.$size.' '.$image; - $this->exec('convert', $command); - - $this->clear_sizes(); - } - - protected function _mask($maskimage) - { - extract(parent::_mask($maskimage)); - - $mimage = '"'.$maskimage.'"'; - $image = '"'.$this->image_temp.'"'; - $command = $image.' '.$mimage.' +matte -compose copy-opacity -composite '.$image; - $this->exec('convert', $command); - } - - /** - * Credit to Leif Åstrand for the base of the round corners. - * - * Note there is a defect with this, as non-transparent corners get opaque circles of color. Maybe mask it with auto-generated corners? - * - * @link http://www.imagemagick.org/Usage/thumbnails/#rounded - */ - protected function _rounded($radius, $sides, $antialias = 0) - { - extract(parent::_rounded($radius, $sides, null)); - - $image = '"'.$this->image_temp.'"'; - $r = $radius; - $command = $image." \\( +clone -alpha extract ". - ( ! $tr ? '' : "-draw \"fill black polygon 0,0 0,$r $r,0 fill white circle $r,$r $r,0\" ")."-flip ". - ( ! $br ? '' : "-draw \"fill black polygon 0,0 0,$r $r,0 fill white circle $r,$r $r,0\" ")."-flop ". - ( ! $bl ? '' : "-draw \"fill black polygon 0,0 0,$r $r,0 fill white circle $r,$r $r,0\" ")."-flip ". - ( ! $tl ? '' : "-draw \"fill black polygon 0,0 0,$r $r,0 fill white circle $r,$r $r,0\" "). - '\\) -alpha off -compose CopyOpacity -composite '.$image; - $this->exec('convert', $command); - } - - protected function _grayscale() - { - $image = '"'.$this->image_temp.'"'; - $this->exec('convert', $image." -colorspace Gray ".$image); - } - - public function sizes($filename = null, $usecache = true) - { - $is_loaded_file = $filename == null; - if ( ! $is_loaded_file or $this->sizes_cache == null or !$usecache) - { - $reason = ($filename != null ? "filename" : ($this->sizes_cache == null ? 'cache' : 'option')); - $this->debug("Generating size of image... (triggered by $reason)"); - - if ($is_loaded_file and ! empty($this->image_temp)) - { - $filename = $this->image_temp; - } - - $output = $this->exec('identify', '-format "%w %h" "'.$filename.'"[0]'); - list($width, $height) = explode(" ", $output[0]); - $return = (object) array( - 'width' => $width, - 'height' => $height, - ); - - if ($is_loaded_file) - { - $this->sizes_cache = $return; - } - $this->debug("Sizes ".( !$is_loaded_file ? "for $filename " : "")."are now $width and $height"); - } - else - { - $return = $this->sizes_cache; - } - - return $return; - } - - public function save($filename = null, $permissions = null) - { - extract(parent::save($filename, $permissions)); - - $this->run_queue(); - $this->add_background(); - - $filetype = $this->image_extension; - $old = '"'.$this->image_temp.'"'; - $new = '"'.$filename.'"'; - - if(($filetype == 'jpeg' or $filetype == 'jpg') and $this->config['quality'] != 100) - { - $quality = '"'.$this->config['quality'].'%"'; - $this->exec('convert', $old.' -quality '.$quality.' '.$new); - } - else - { - $this->exec('convert', $old.' '.$new); - } - - if ($this->config['persistence'] === false) - { - $this->reload(); - } - - return $this; - } - - public function output($filetype = null) - { - extract(parent::output($filetype)); - - $this->run_queue(); - $this->add_background(); - - $image = '"'.$this->image_temp.'"'; - - if(($filetype == 'jpeg' or $filetype == 'jpg') and $this->config['quality'] != 100) - { - $quality = '"'.$this->config['quality'].'%"'; - $this->exec('convert', $image.' -quality '.$quality.' '.strtolower($filetype).':-', true); - } - elseif (substr($this->image_temp, -1 * strlen($filetype)) != $filetype) - { - if ( ! $this->config['debug']) - { - $this->exec('convert', $image.' '.strtolower($filetype).':-', true); - } - } - else - { - if ( ! $this->config['debug']) - { - echo file_get_contents($this->image_temp); - } - } - - if ($this->config['persistence'] === false) - { - $this->reload(); - } - - return $this; - } - - /** - * Cleared the currently loaded sizes, used to removed cached sizes. - */ - protected function clear_sizes() - { - $this->sizes_cache = null; - } - - protected function add_background() - { - if ($this->config['bgcolor'] != null) - { - $bgcolor = $this->config['bgcolor'] == null ? '#000' : $this->config['bgcolor']; - $image = '"'.$this->image_temp.'"'; - $color = $this->create_color($bgcolor, 100); - $sizes = $this->sizes(); - $command = '-size '.$sizes->width.'x'.$sizes->height.' '.'canvas:'.$color.' '. - $image.' -composite '.$image; - $this->exec('convert', $command); - } - } - - /** - * Executes the specified imagemagick executable and returns the output. - * - * @param string $program The name of the executable. - * @param string $params The parameters of the executable. - * @param boolean $passthru Returns the output if false or pass it to browser. - * @return mixed Either returns the output or returns nothing. - */ - protected function exec($program, $params, $passthru = false) - { - // Determine the path - $this->im_path = realpath($this->config['imagemagick_dir'].$program); - if ( ! $this->im_path) - { - $this->im_path = realpath($this->config['imagemagick_dir'].$program.'.exe'); - } - if ( ! $this->im_path) - { - throw new \RuntimeException("imagemagick executables not found in ".$this->config['imagemagick_dir']); - } - - $command = $this->im_path." ".$params; - $this->debug("Running command: $command"); - $code = 0; - $output = null; - - $passthru ? passthru($command) : exec($command, $output, $code); - - if ($code != 0) - { - throw new \FuelException("imagemagick failed to edit the image. Returned with $code.

Command:\n $command"); - } - - return $output; - } - - /** - * Creates a new color usable by ImageMagick. - * - * @param string $hex The hex code of the color - * @param integer $alpha The alpha of the color, 0 (trans) to 100 (opaque) - * @return string rgba representation of the hex and alpha values. - */ - protected function create_color($hex, $alpha) - { - extract($this->create_hex_color($hex)); - return "\"rgba(".$red.", ".$green.", ".$blue.", ".round($alpha / 100, 2).")\""; - } - - public function __destruct() - { - if (is_file($this->image_temp)) - { - unlink($this->image_temp); - } - } -} diff --git a/fuel/core/classes/image/imagick.php b/fuel/core/classes/image/imagick.php deleted file mode 100755 index c8232be..0000000 --- a/fuel/core/classes/image/imagick.php +++ /dev/null @@ -1,265 +0,0 @@ -imagick == null) - { - $this->imagick = new \Imagick(); - } - - $this->imagick->readImage($filename); - - return $this; - } - - protected function _crop($x1, $y1, $x2, $y2) - { - extract(parent::_crop($x1, $y1, $x2, $y2)); - - $width = $x2 - $x1; - $height = $y2 - $y1; - - $this->debug("Cropping image ".$width."x".$height."+$x1+$y1 based on coords ($x1, $y1), ($x2, $y2)"); - - $this->imagick->cropImage($width, $height, $x1, $y1); - $this->imagick->setImagePage(0, 0, 0, 0); - } - - protected function _resize($width, $height = null, $keepar = true, $pad = true) - { - extract(parent::_resize($width, $height, $keepar, $pad)); - - $this->imagick->scaleImage($width, $height, $keepar); - - if ($pad) - { - $tmpimage = new \Imagick(); - $tmpimage->newImage($cwidth, $cheight, $this->create_color('#000', 0), 'png'); - $tmpimage->compositeImage($this->imagick, \Imagick::COMPOSITE_DEFAULT, ($cwidth-$width) / 2, ($cheight-$height) / 2); - $this->imagick = $tmpimage; - } - } - - protected function _rotate($degrees) - { - extract(parent::_rotate($degrees)); - - $this->imagick->rotateImage($this->create_color('#000', 0), $degrees); - } - - protected function _watermark($filename, $position, $padding = 5) - { - extract(parent::_watermark($filename, $position, $padding)); - $wmimage = new \Imagick(); - $wmimage->readImage($filename); - $wmimage->evaluateImage(\Imagick::EVALUATE_MULTIPLY, $this->config['watermark_alpha'] / 100, \Imagick::CHANNEL_ALPHA); - $this->imagick->compositeImage($wmimage, \Imagick::COMPOSITE_DEFAULT, $x, $y); - } - - protected function _flip($direction) - { - switch ($direction) - { - case 'vertical': - $this->imagick->flipImage(); - break; - - case 'horizontal': - $this->imagick->flopImage(); - break; - - case 'both': - $this->imagick->flipImage(); - $this->imagick->flopImage(); - break; - - default: return false; - } - } - - protected function _border($size, $color = null) - { - extract(parent::_border($size, $color)); - - $this->imagick->borderImage($this->create_color($color, 100), $size, $size); - } - - protected function _mask($maskimage) - { - extract(parent::_mask($maskimage)); - $wmimage = new \Imagick(); - $wmimage->readImage($maskimage); - $wmimage->setImageMatte(false); - $this->imagick->compositeImage($wmimage, \Imagick::COMPOSITE_COPYOPACITY, 0, 0); - } - - protected function _rounded($radius, $sides, $antialias = 0) - { - extract(parent::_rounded($radius, $sides, null)); - - $sizes = $this->sizes(); - $sizes->width_half = $sizes->width / 2; - $sizes->height_half = $sizes->height / 2; - - $list = array(); - if (!$tl) { - $list = array('x' => 0, 'y' => 0); - } - if (!$tr) { - $list = array('x' => $sizes->width_half, 'y' => 0); - } - if (!$bl) { - $list = array('x' => 0, 'y' => $sizes->height_half); - } - if (!$br) { - $list = array('x' => $sizes->width_half, 'y' => $sizes->height_half); - } - - foreach($list as $index => $element) { - $image = $this->imagick->clone(); - $image->cropImage($sizes->width_half, $sizes->height_half, $element['x'], $element['y']); - $list[$index]['image'] = $image; - } - - $this->imagick->roundCorners($radius, $radius); - - foreach($list as $element) { - $this->imagick->compositeImage($element['image'], \Imagick::COMPOSITE_DEFAULT, $element['x'], $element['y']); - } - } - - protected function _grayscale() - { - $this->imagick->setImageType(\Imagick::IMGTYPE_GRAYSCALEMATTE); - } - - public function sizes($filename = null, $usecache = true) - { - if ($filename === null) - { - return (object) array( - 'width' => $this->imagick->getImageWidth(), - 'height' => $this->imagick->getImageHeight(), - ); - } - - $tmpimage = new \Imagick(); - $tmpimage->readImage($filename); - return (object) array( - 'width' => $tmpimage->getImageWidth(), - 'height' => $tmpimage->getImageHeight(), - ); - } - - public function save($filename = null, $permissions = null) - { - extract(parent::save($filename, $permissions)); - - $this->run_queue(); - $this->add_background(); - - $filetype = $this->image_extension; - - if ($filetype == 'jpg' or $filetype == 'jpeg') - { - $filetype = 'jpeg'; - } - - if ($this->imagick->getImageFormat() != $filetype) - { - $this->imagick->setImageFormat($filetype); - } - - if($this->imagick->getImageFormat() == 'jpeg' and $this->config['quality'] != 100) - { - $this->imagick->setImageCompression(\Imagick::COMPRESSION_JPEG); - $this->imagick->setImageCompressionQuality($this->config['quality']); - $this->imagick->stripImage(); - } - - file_put_contents($filename, $this->imagick->getImageBlob()); - - if ($this->config['persistence'] === false) - { - $this->reload(); - } - - return $this; - } - - public function output($filetype = null) - { - extract(parent::output($filetype)); - - $this->run_queue(); - $this->add_background(); - - if ($filetype == 'jpg' or $filetype == 'jpeg') - { - $filetype = 'jpeg'; - } - - if ($this->imagick->getImageFormat() != $filetype) - { - $this->imagick->setImageFormat($filetype); - } - - if($this->imagick->getImageFormat() == 'jpeg' and $this->config['quality'] != 100) - { - $this->imagick->setImageCompression(\Imagick::COMPRESSION_JPEG); - $this->imagick->setImageCompressionQuality($this->config['quality']); - $this->imagick->stripImage(); - } - - if ( ! $this->config['debug']) - { - echo $this->imagick->getImageBlob(); - } - - return $this; - } - - protected function add_background() - { - if($this->config['bgcolor'] != null) - { - $tmpimage = new \Imagick(); - $sizes = $this->sizes(); - $tmpimage->newImage($sizes->width, $sizes->height, $this->create_color($this->config['bgcolor'], $this->config['bgcolor'] == null ? 0 : 100), 'png'); - $tmpimage->compositeImage($this->imagick, \Imagick::COMPOSITE_DEFAULT, 0, 0); - $this->imagick = $tmpimage; - } - } - - /** - * Creates a new color usable by Imagick. - * - * @param string $hex The hex code of the color - * @param integer $alpha The alpha of the color, 0 (trans) to 100 (opaque) - * @return string rgba representation of the hex and alpha values. - */ - protected function create_color($hex, $alpha) - { - extract($this->create_hex_color($hex)); - return new \ImagickPixel('rgba('.$red.', '.$green.', '.$blue.', '.round($alpha / 100, 2).')'); - } -} diff --git a/fuel/core/classes/inflector.php b/fuel/core/classes/inflector.php deleted file mode 100755 index 251204f..0000000 --- a/fuel/core/classes/inflector.php +++ /dev/null @@ -1,461 +0,0 @@ - '\1\2en', // ox - '/([m|l])ouse$/i' => '\1ice', // mouse, louse - '/(matr|vert|ind)ix|ex$/i' => '\1ices', // matrix, vertex, index - '/(x|ch|ss|sh)$/i' => '\1es', // search, switch, fix, box, process, address - '/([^aeiouy]|qu)y$/i' => '\1ies', // query, ability, agency - '/(hive)$/i' => '\1s', // archive, hive - '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', // half, safe, wife - '/sis$/i' => 'ses', // basis, diagnosis - '/([ti])um$/i' => '\1a', // datum, medium - '/(p)erson$/i' => '\1eople', // person, salesperson - '/(m)an$/i' => '\1en', // man, woman, spokesman - '/(c)hild$/i' => '\1hildren', // child - '/(buffal|tomat)o$/i' => '\1\2oes', // buffalo, tomato - '/(bu|campu)s$/i' => '\1\2ses', // bus, campus - '/(alias|status|virus)$/i' => '\1es', // alias - '/(octop)us$/i' => '\1i', // octopus - '/(ax|cris|test)is$/i' => '\1es', // axis, crisis - '/s$/' => 's', // no change (compatibility) - '/$/' => 's', - ); - - /** - * @var array default list of iregular singular words, in English - */ - protected static $singular_rules = array( - '/(matr)ices$/i' => '\1ix', - '/(vert|ind)ices$/i' => '\1ex', - '/^(ox)en/i' => '\1', - '/(alias)es$/i' => '\1', - '/([octop|vir])i$/i' => '\1us', - '/(cris|ax|test)es$/i' => '\1is', - '/(shoe)s$/i' => '\1', - '/(o)es$/i' => '\1', - '/(bus|campus)es$/i' => '\1', - '/([m|l])ice$/i' => '\1ouse', - '/(x|ch|ss|sh)es$/i' => '\1', - '/(m)ovies$/i' => '\1\2ovie', - '/(s)eries$/i' => '\1\2eries', - '/([^aeiouy]|qu)ies$/i' => '\1y', - '/([lr])ves$/i' => '\1f', - '/(tive)s$/i' => '\1', - '/(hive)s$/i' => '\1', - '/([^f])ves$/i' => '\1fe', - '/(^analy)ses$/i' => '\1sis', - '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', - '/([ti])a$/i' => '\1um', - '/(p)eople$/i' => '\1\2erson', - '/(m)en$/i' => '\1an', - '/(s)tatuses$/i' => '\1\2tatus', - '/(c)hildren$/i' => '\1\2hild', - '/(n)ews$/i' => '\1\2ews', - '/([^us])s$/i' => '\1', - ); - - /** - * Load any localized rules on first load - */ - public static function _init() - { - static::load_rules(); - } - - /** - * Load any localized rulesets based on the current language configuration - * If not exists, the current rules remain active - */ - public static function load_rules() - { - \Lang::load('inflector', true, false, true); - - if ($rules = \Lang::get('inflector.uncountable_words', array())) - { - static::$uncountable_words = $rules; - } - if ($rules = \Lang::get('inflector.singular_rules', array())) - { - static::$singular_rules = $rules; - } - if ($rules = \Lang::get('inflector.plural_rules', array())) - { - static::$plural_rules = $rules; - } - } - - /** - * Add order suffix to numbers ex. 1st 2nd 3rd 4th 5th - * - * @param int $number the number to ordinalize - * @return string the ordinalized version of $number - * @link http://snipplr.com/view/4627/a-function-to-add-a-prefix-to-numbers-ex-1st-2nd-3rd-4th-5th/ - */ - public static function ordinalize($number) - { - if ( ! is_numeric($number)) - { - return $number; - } - - if (in_array(($number % 100), range(11, 13))) - { - return $number . 'th'; - } - else - { - switch ($number % 10) - { - case 1: - return $number . 'st'; - break; - case 2: - return $number . 'nd'; - break; - case 3: - return $number . 'rd'; - break; - default: - return $number . 'th'; - break; - } - } - } - - /** - * Gets the plural version of the given word - * - * @param string $word the word to pluralize - * @param int $count number of instances - * @return string the plural version of $word - */ - public static function pluralize($word, $count = 0) - { - $result = strval($word); - - // If a counter is provided, and that equals 1 - // return as singular. - if ($count === 1) - { - return $result; - } - - if ( ! static::is_countable($result)) - { - return $result; - } - - foreach (static::$plural_rules as $rule => $replacement) - { - if (preg_match($rule, $result)) - { - $result = preg_replace($rule, $replacement, $result); - break; - } - } - - return $result; - } - - /** - * Gets the singular version of the given word - * - * @param string $word the word to singularize - * @return string the singular version of $word - */ - public static function singularize($word) - { - $result = strval($word); - - if ( ! static::is_countable($result)) - { - return $result; - } - - foreach (static::$singular_rules as $rule => $replacement) - { - if (preg_match($rule, $result)) - { - $result = preg_replace($rule, $replacement, $result); - break; - } - } - - return $result; - } - - /** - * Takes a string that has words separated by underscores and turns it into - * a CamelCased string. - * - * @param string $underscored_word the underscored word - * @return string the CamelCased version of $underscored_word - */ - public static function camelize($underscored_word) - { - return preg_replace_callback( - '/(^|_)(.)/', - function ($parm) - { - return strtoupper($parm[2]); - }, - strval($underscored_word) - ); - } - - /** - * Takes a CamelCased string and returns an underscore separated version. - * - * @param string $camel_cased_word the CamelCased word - * @return string an underscore separated version of $camel_cased_word - */ - public static function underscore($camel_cased_word) - { - return \Str::lower(preg_replace('/([A-Z]+)([A-Z])/', '\1_\2', preg_replace('/([a-z\d])([A-Z])/', '\1_\2', strval($camel_cased_word)))); - } - - /** - * Translate string to 7-bit ASCII - * Only works with UTF-8. - * - * @param string $str string to translate - * @param bool $allow_non_ascii whether to remove non ascii - * @return string translated string - */ - public static function ascii($str, $allow_non_ascii = false) - { - // Translate unicode characters to their simpler counterparts - \Config::load('ascii', true); - $foreign_characters = \Config::get('ascii'); - - $str = preg_replace(array_keys($foreign_characters), array_values($foreign_characters), $str); - - if ( ! $allow_non_ascii) - { - return preg_replace('/[^\x09\x0A\x0D\x20-\x7E]/', '', $str); - } - - return $str; - } - - /** - * Converts your text to a URL-friendly title so it can be used in the URL. - * Only works with UTF8 input and and only outputs 7 bit ASCII characters. - * - * @param string $str the text - * @param string $sep the separator - * @param bool $lowercase whether to convert to lowercase - * @param bool $allow_non_ascii whether to allow non ascii - * @return string the new title - */ - public static function friendly_title($str, $sep = '-', $lowercase = false, $allow_non_ascii = false) - { - // Remove tags - $str = \Security::strip_tags($str); - - // Decode all entities to their simpler forms - $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8'); - - // Only allow 7bit characters - $str = static::ascii($str, $allow_non_ascii); - - if ($allow_non_ascii) - { - // Strip regular special chars - $str = preg_replace("#[\.;:\]\}\[\{\+\)\(\*&\^\$\#@\!±`%~']#iu", '', $str); - } - else - { - // Strip unwanted characters - $str = preg_replace("#[^a-z0-9]#i", $sep, $str); - } - - // Remove all quotes - $str = preg_replace("#[\"\']#", '', $str); - - // Replace apostrophes by separators - $str = preg_replace("#[\’]#", '-', $str); - - // Replace repeating characters - $str = preg_replace("#[/_|+ -]+#u", $sep, $str); - - // Remove separators from both ends - $str = trim($str, $sep); - - // And convert to lowercase if needed - if ($lowercase === true) - { - $str = \Str::lower($str); - } - - return $str; - } - - /** - * Turns an underscore or dash separated word and turns it into a human looking string. - * - * @param string $str the word - * @param string $sep the separator (either _ or -) - * @param bool $lowercase lowercase string and upper case first - * @return string the human version of given string - */ - public static function humanize($str, $sep = '_', $lowercase = true) - { - // Allow dash, otherwise default to underscore - $sep = $sep != '-' ? '_' : $sep; - - if ($lowercase === true) - { - $str = \Str::ucfirst($str); - } - - return str_replace($sep, " ", strval($str)); - } - - /** - * Takes the class name out of a modulized string. - * - * @param string $class_name_in_module the modulized class - * @return string the string without the class name - */ - public static function demodulize($class_name_in_module) - { - return preg_replace('/^.*::/', '', strval($class_name_in_module)); - } - - /** - * Takes the namespace off the given class name. - * - * @param string $class_name the class name - * @return string the string without the namespace - */ - public static function denamespace($class_name) - { - $class_name = trim($class_name, '\\'); - if ($last_separator = strrpos($class_name, '\\')) - { - $class_name = substr($class_name, $last_separator + 1); - } - return $class_name; - } - - /** - * Returns the namespace of the given class name. - * - * @param string $class_name the class name - * @return string the string without the namespace - */ - public static function get_namespace($class_name) - { - $class_name = trim($class_name, '\\'); - if ($last_separator = strrpos($class_name, '\\')) - { - return substr($class_name, 0, $last_separator + 1); - } - return ''; - } - - /** - * Takes a class name and determines the table name. The table name is a - * pluralized version of the class name. - * - * @param string $class_name the table name - * @return string the table name - */ - public static function tableize($class_name) - { - $class_name = static::denamespace($class_name); - if (strncasecmp($class_name, 'Model_', 6) === 0) - { - $class_name = substr($class_name, 6); - } - return \Str::lower(static::pluralize(static::underscore($class_name))); - } - - /** - * Takes an underscored classname and uppercases all letters after the underscores. - * - * @param string $class classname - * @param string $sep separator - * @return string - */ - public static function words_to_upper($class, $sep = '_') - { - return str_replace(' ', $sep, ucwords(str_replace($sep, ' ', $class))); - } - - /** - * Takes a table name and creates the class name. - * - * @param string $name the table name - * @param bool $force_singular whether to singularize the table name or not - * @return string the class name - */ - public static function classify($name, $force_singular = true) - { - $class = ($force_singular) ? static::singularize($name) : $name; - return static::words_to_upper($class); - } - - /** - * Gets the foreign key for a given class. - * - * @param string $class_name the class name - * @param bool $use_underscore whether to use an underscore or not - * @return string the foreign key - */ - public static function foreign_key($class_name, $use_underscore = true) - { - $class_name = static::denamespace(\Str::lower($class_name)); - if (strncasecmp($class_name, 'Model_', 6) === 0) - { - $class_name = substr($class_name, 6); - } - return static::underscore(static::demodulize($class_name)).($use_underscore ? "_id" : "id"); - } - - /** - * Checks if the given word has a plural version. - * - * @param string $word the word to check - * @return bool if the word is countable - */ - public static function is_countable($word) - { - return ! (\in_array(\Str::lower(\strval($word)), static::$uncountable_words)); - } -} diff --git a/fuel/core/classes/input.php b/fuel/core/classes/input.php deleted file mode 100755 index 4048a65..0000000 --- a/fuel/core/classes/input.php +++ /dev/null @@ -1,565 +0,0 @@ -to_array()); - } - - /** - * Detects and returns the current URI based on a number of different server - * variables. - * - * @throws \FuelException - * @return string - */ - public static function uri() - { - if (static::$detected_uri !== null) - { - return static::$detected_uri; - } - - if (\Fuel::$is_cli) - { - if (($uri = \Cli::option('uri')) !== null) - { - static::$detected_uri = $uri; - } - else - { - static::$detected_uri = \Cli::option(1); - } - - return static::$detected_uri; - } - - // We want to use PATH_INFO if we can. - if ( ! empty($_SERVER['PATH_INFO'])) - { - $uri = $_SERVER['PATH_INFO']; - } - // Only use ORIG_PATH_INFO if it contains the path - elseif ( ! empty($_SERVER['ORIG_PATH_INFO']) and ($path = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['ORIG_PATH_INFO'])) != '') - { - $uri = $path; - } - else - { - // Fall back to parsing the REQUEST URI - if (isset($_SERVER['REQUEST_URI'])) - { - $uri = strpos($_SERVER['SCRIPT_NAME'], $_SERVER['REQUEST_URI']) !== 0 ? $_SERVER['REQUEST_URI'] : ''; - } - else - { - throw new \FuelException('Unable to detect the URI.'); - } - - // Remove the base URL from the URI - $base_url = parse_url(\Config::get('base_url'), PHP_URL_PATH); - if ($uri != '' and strncmp($uri, $base_url, strlen($base_url)) === 0) - { - $uri = substr($uri, strlen($base_url) - 1); - } - - // If we are using an index file (not mod_rewrite) then remove it - $index_file = \Config::get('index_file'); - if ($index_file and strncmp($uri, $index_file, strlen($index_file)) === 0) - { - $uri = substr($uri, strlen($index_file)); - } - - // When index.php? is used and the config is set wrong, lets just - // be nice and help them out. - if ($index_file and strncmp($uri, '?/', 2) === 0) - { - $uri = substr($uri, 1); - } - - // decode the uri, and put any + back (does not mean a space in the url path) - $uri = str_replace("\r", '+', urldecode(str_replace('+', "\r", $uri))); - - // Lets split the URI up in case it contains a ?. This would - // indicate the server requires 'index.php?' and that mod_rewrite - // is not being used. - preg_match('#(.*?)\?(.*)#i', $uri, $matches); - - // If there are matches then lets set set everything correctly - if ( ! empty($matches)) - { - $uri = $matches[1]; - - // only reconstruct $_GET if we didn't have a query string - if (empty($_SERVER['QUERY_STRING'])) - { - $_SERVER['QUERY_STRING'] = $matches[2]; - parse_str($matches[2], $_GET); - $_GET = \Security::clean($_GET); - } - } - } - - // Deal with any trailing dots - $uri = rtrim($uri, '.'); - - // Do we have a URI and does it not end on a slash? - if ($uri and substr($uri, -1) !== '/') - { - // Strip the defined url suffix from the uri if needed - $ext = strrchr($uri, '.'); - $path = $ext === false ? $uri : substr($uri, 0, -strlen($ext)); - - // Did we detect something that looks like an extension? - if ( ! empty($ext)) - { - // if it has a slash in it, it's a URI segment with a dot in it - if (strpos($ext, '/') === false) - { - static::$detected_ext = ltrim($ext, '.'); - - if (\Config::get('routing.strip_extension', true)) - { - $uri = $path; - } - } - } - } - - // Do some final clean up of the uri - static::$detected_uri = \Security::clean_uri($uri, true); - - return static::$detected_uri; - } - - /** - * Detects and returns the current URI extension - * - * @return string - */ - public static function extension() - { - static::$detected_ext === null and static::uri(); - - return static::$detected_ext; - } - - /** - * Get the public ip address of the user. - * - * @param string $default - * @return array|string - */ - public static function ip($default = '0.0.0.0') - { - return static::server('REMOTE_ADDR', $default); - } - - /** - * Get the real ip address of the user. Even if they are using a proxy. - * - * @param string $default the default to return on failure - * @param bool $exclude_reserved exclude private and reserved IPs - * @return string the real ip address of the user - */ - public static function real_ip($default = '0.0.0.0', $exclude_reserved = false) - { - static $server_keys = null; - - if (empty($server_keys)) - { - $server_keys = array('HTTP_CLIENT_IP', 'REMOTE_ADDR'); - if (\Config::get('security.allow_x_headers', false)) - { - $server_keys = array_merge(array('HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_X_FORWARDED_FOR'), $server_keys); - } - } - - foreach ($server_keys as $key) - { - if ( ! static::server($key)) - { - continue; - } - - $ips = explode(',', static::server($key)); - array_walk($ips, function (&$ip) { - $ip = trim($ip); - }); - - $ips = array_filter($ips, function($ip) use($exclude_reserved) { - return filter_var($ip, FILTER_VALIDATE_IP, $exclude_reserved ? FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE : null); - }); - - if ($ips) - { - return reset($ips); - } - } - - return \Fuel::value($default); - } - - /** - * Return's the protocol that the request was made with - * - * @return string - */ - public static function protocol() - { - if (static::server('HTTPS') == 'on' or - static::server('HTTPS') == 1 or - static::server('SERVER_PORT') == 443 or - (\Config::get('security.allow_x_headers', false) and static::server('HTTP_X_FORWARDED_PROTO') == 'https') or - (\Config::get('security.allow_x_headers', false) and static::server('HTTP_X_FORWARDED_PORT') == 443)) - { - return 'https'; - } - - return 'http'; - } - - /** - * Return's whether this is an AJAX request or not - * - * @return bool - */ - public static function is_ajax() - { - return (static::server('HTTP_X_REQUESTED_WITH') !== null) and strtolower(static::server('HTTP_X_REQUESTED_WITH')) === 'xmlhttprequest'; - } - - /** - * Return's the referrer - * - * @param string $default - * @return string - */ - public static function referrer($default = '') - { - return static::server('HTTP_REFERER', $default); - } - - /** - * Return's the input method used (GET, POST, DELETE, etc.) - * - * @param string $default - * @return string - */ - public static function method($default = 'GET') - { - // get the method from the current active request - if ($request = \Request::active() and $method = $request->get_method()) - { - return $method; - } - - // if called before a request is active, fall back to the global server setting - if (\Config::get('security.allow_x_headers', false)) - { - return static::server('HTTP_X_HTTP_METHOD_OVERRIDE', static::server('REQUEST_METHOD', $default)); - } - else - { - return static::server('REQUEST_METHOD', $default); - } - } - - /** - * Return's the user agent - * - * @param $default - * @return string - */ - public static function user_agent($default = '') - { - return static::server('HTTP_USER_AGENT', $default); - } - - /** - * Returns all of the GET, POST, PUT and DELETE variables. - * - * @return array - */ - public static function all() - { - static::$input === null and static::hydrate(); - return static::$input; - } - - /** - * Gets the specified GET variable. - * - * @param string $index The index to get - * @param string $default The default value - * @return string|array - */ - public static function get($index = null, $default = null) - { - return (func_num_args() === 0) ? $_GET : \Arr::get($_GET, $index, $default); - } - - /** - * Fetch an item from the POST array - * - * @param string $index The index key - * @param mixed $default The default value - * @return string|array - */ - public static function post($index = null, $default = null) - { - return (func_num_args() === 0) ? $_POST : \Arr::get($_POST, $index, $default); - } - - /** - * Fetch an item from the php://input for put arguments - * - * @param string $index The index key - * @param mixed $default The default value - * @return string|array - */ - public static function put($index = null, $default = null) - { - static::$put_patch_delete === null and static::hydrate(); - return (func_num_args() === 0) ? static::$put_patch_delete : \Arr::get(static::$put_patch_delete, $index, $default); - } - - /** - * Fetch an item from the php://input for patch arguments - * - * @param string $index The index key - * @param mixed $default The default value - * @return string|array - */ - public static function patch($index = null, $default = null) - { - static::$put_patch_delete === null and static::hydrate(); - return (func_num_args() === 0) ? static::$put_patch_delete : \Arr::get(static::$put_patch_delete, $index, $default); - } - - /** - * Fetch an item from the php://input for delete arguments - * - * @param string $index The index key - * @param mixed $default The default value - * @return string|array - */ - public static function delete($index = null, $default = null) - { - static::$put_patch_delete === null and static::hydrate(); - return (is_null($index) and func_num_args() === 0) ? static::$put_patch_delete : \Arr::get(static::$put_patch_delete, $index, $default); - } - - /** - * Fetch an item from the FILE array - * - * @param string $index The index key - * @param mixed $default The default value - * @return string|array - */ - public static function file($index = null, $default = null) - { - return (func_num_args() === 0) ? $_FILES : \Arr::get($_FILES, $index, $default); - } - - /** - * Fetch an item from either the GET, POST, PUT, PATCH or DELETE array - * - * @param string $index The index key - * @param mixed $default The default value - * @return string|array - */ - public static function param($index = null, $default = null) - { - static::$input === null and static::hydrate(); - return \Arr::get(static::$input, $index, $default); - } - - /** - * Fetch an item from the COOKIE array - * - * @param string $index The index key - * @param mixed $default The default value - * @return string|array - */ - public static function cookie($index = null, $default = null) - { - return (func_num_args() === 0) ? $_COOKIE : \Arr::get($_COOKIE, $index, $default); - } - - /** - * Fetch an item from the SERVER array - * - * @param string $index The index key - * @param mixed $default The default value - * @return string|array - */ - public static function server($index = null, $default = null) - { - return (func_num_args() === 0) ? $_SERVER : \Arr::get($_SERVER, strtoupper($index), $default); - } - - /** - * Fetch a item from the HTTP request headers - * - * @param mixed $index - * @param mixed $default - * @return array - */ - public static function headers($index = null, $default = null) - { - static $headers = null; - - // do we need to fetch the headers? - if ($headers === null) - { - // deal with fcgi or nginx installs - if ( ! function_exists('getallheaders')) - { - $server = \Arr::filter_prefixed(static::server(), 'HTTP_', true); - - foreach ($server as $key => $value) - { - $key = join('-', array_map('ucfirst', explode('_', strtolower($key)))); - - $headers[$key] = $value; - } - - $value = static::server('Content_Type', static::server('Content-Type')) and $headers['Content-Type'] = $value; - $value = static::server('Content_Length', static::server('Content-Length')) and $headers['Content-Length'] = $value; - } - else - { - $headers = getallheaders(); - } - } - - return empty($headers) ? $default : ((func_num_args() === 0) ? $headers : \Arr::get(array_change_key_case($headers), strtolower($index), $default)); - } - - /** - * Hydrates the input array - * - * @return void - */ - protected static function hydrate() - { - static::$input = array_merge($_GET, $_POST); - - if (static::method() == 'PUT' or static::method() == 'PATCH' or static::method() == 'DELETE') - { - static::$php_input === null and static::$php_input = file_get_contents('php://input'); - if (strpos(static::headers('Content-Type'), 'www-form-urlencoded') > 0 and \Config::get('security.form-double-urlencoded', false)) - { - static::$php_input = urldecode(static::$php_input); - } - parse_str(static::$php_input, static::$put_patch_delete); - static::$input = array_merge(static::$input, static::$put_patch_delete); - } - else - { - static::$put_patch_delete = array(); - } - } - - /** - * Return's the query string - * - * @param string $default - * @return string - */ - public static function query_string($default = '') - { - return static::server('QUERY_STRING', $default); - } -} diff --git a/fuel/core/classes/lang.php b/fuel/core/classes/lang.php deleted file mode 100755 index cda276b..0000000 --- a/fuel/core/classes/lang.php +++ /dev/null @@ -1,292 +0,0 @@ -load($overwrite); - } - catch (\LangException $e) - { - $lang = array(); - } - $group = $group === true ? $file->group() : $group; - } - - isset(static::$lines[$language]) or static::$lines[$language] = array(); - if ($group === null) - { - static::$lines[$language] = $overwrite ? array_merge(static::$lines[$language], $lang) : \Arr::merge(static::$lines[$language], $lang); - } - else - { - $group = ($group === true) ? $file : $group; - if ($overwrite) - { - \Arr::set(static::$lines[$language], $group, array_merge(\Arr::get(static::$lines[$language], $group, array()), $lang)); - } - else - { - \Arr::set(static::$lines[$language], $group, \Arr::merge(\Arr::get(static::$lines[$language], $group, array()), $lang)); - } - } - - return $lang; - } - - /** - * Save a language array to disk. - * - * @param string $file desired file name - * @param string|array $lang master language array key or language array - * @param string|null $language name of the language to load, null for the configured language - * @return bool false when language is empty or invalid else \File::update result - * @throws \LangException - */ - public static function save($file, $lang, $language = null) - { - ($language === null) and $language = static::get_lang(); - - // prefix the file with the language - if ( ! is_null($language)) - { - $file = explode('::', $file); - end($file); - $file[key($file)] = $language.DS.end($file); - $file = implode('::', $file); - } - - if ( ! is_array($lang)) - { - if ( ! isset(static::$lines[$language][$lang])) - { - return false; - } - $lang = static::$lines[$language][$lang]; - } - - $type = pathinfo($file, PATHINFO_EXTENSION); - if( ! $type) - { - $type = 'php'; - $file .= '.'.$type; - } - - $class = '\\Lang_'.ucfirst($type); - - if( ! class_exists($class, true)) - { - throw new \LangException('Cannot save a language file of type: '.$type); - } - - $driver = new $class; - return $driver->save($file, $lang); - } - - /** - * Returns a (dot notated) language string - * - * @param string $line key for the line - * @param array $params array of params to str_replace - * @param mixed $default default value to return - * @param string|null $language name of the language to get, null for the configured language - * @return mixed either the line or default when not found - */ - public static function get($line, array $params = array(), $default = null, $language = null) - { - ($language === null) and $language = static::get_lang(); - - return isset(static::$lines[$language]) ? \Str::tr(\Fuel::value(\Arr::get(static::$lines[$language], $line, $default)), $params) : $default; - } - - /** - * Sets a (dot notated) language string - * - * @param string $line a (dot notated) language key - * @param mixed $value the language string - * @param string $group group - * @param string|null $language name of the language to set, null for the configured language - * @return void the \Arr::set result - */ - public static function set($line, $value, $group = null, $language = null) - { - $group === null or $line = $group.'.'.$line; - - ($language === null) and $language = static::get_lang(); - - isset(static::$lines[$language]) or static::$lines[$language] = array(); - - \Arr::set(static::$lines[$language], $line, \Fuel::value($value)); - } - - /** - * Deletes a (dot notated) language string - * - * @param string $item a (dot notated) language key - * @param string $group group - * @param string|null $language name of the language to set, null for the configured language - * @return array|bool the \Arr::delete result, success boolean or array of success booleans - */ - public static function delete($item, $group = null, $language = null) - { - $group === null or $item = $group.'.'.$item; - - ($language === null) and $language = static::get_lang(); - - return isset(static::$lines[$language]) ? \Arr::delete(static::$lines[$language], $item) : false; - } - - /** - * Sets the current language, and optionally reloads all language files loaded in another language - * - * @param string $language name of the language to activate - * @param bool $reload true to force a reload of already loaded language files - * @return bool success boolean, false if no language or the current was passed, true otherwise - */ - public static function set_lang($language, $reload = false) - { - // check if a language was passedd - if ( ! empty($language) and $language != static::get_lang()) - { - // set it - \Config::set('language', $language); - - // do we need to reload? - if ($reload) - { - foreach (static::$loaded_files as $file => $args) - { - // reload with exactly the same arguments - if (strpos($file, $language.'/') !== 0) - { - call_user_func_array('Lang::load', $args); - } - } - } - - // return success - return true; - } - - // no language or the current language was passed - return false; - } -} diff --git a/fuel/core/classes/lang/db.php b/fuel/core/classes/lang/db.php deleted file mode 100755 index dba773e..0000000 --- a/fuel/core/classes/lang/db.php +++ /dev/null @@ -1,173 +0,0 @@ -identifier = $identifier; - - // we need the highest priority language last in the list - $this->languages = array_reverse($languages); - - $this->vars = array( - 'APPPATH' => APPPATH, - 'COREPATH' => COREPATH, - 'PKGPATH' => PKGPATH, - 'DOCROOT' => DOCROOT, - ) + $vars; - - $this->table = \Config::get('lang.table_name', 'lang'); - } - - /** - * Loads the language file(s). - * - * @param bool $overwrite Whether to overwrite existing values - * @return array the language array - * @throws \Database_Exception - */ - public function load($overwrite = false) - { - $lang = array(); - - foreach ($this->languages as $language) - { - // try to retrieve the config from the database - try - { - $result = \DB::select('lang')->from($this->table)->where('identifier', '=', $this->identifier)->where('language', '=', $language)->execute(); - } - catch (Database_Exception $e) - { - // strip the actual query from the message - $msg = $e->getMessage(); - $msg = substr($msg, 0, strlen($msg) - strlen(strrchr($msg, ':'))); - - // and rethrow it - throw new \Database_Exception($msg); - } - - // did we succeed? - if ($result->count()) - { - if ( ! empty($result[0]['lang'])) - { - $lang = $overwrite ? - array_merge($lang, unserialize($this->parse_vars($result[0]['lang']))) : - \Arr::merge($lang, unserialize($this->parse_vars($result[0]['lang']))); - } - } - } - - return $lang; - } - - /** - * Gets the default group name. - * - * @return string - */ - public function group() - { - return $this->identifier; - } - - /** - * Parses a string using all of the previously set variables. Allows you to - * use something like %APPPATH% in non-PHP files. - * - * @param string $string String to parse - * @return string - */ - protected function parse_vars($string) - { - foreach ($this->vars as $var => $val) - { - $string = str_replace("%$var%", $val, $string); - } - - return $string; - } - - /** - * Replaces FuelPHP's path constants to their string counterparts. - * - * @param array $array array to be prepped - * @return array prepped array - */ - protected function prep_vars(&$array) - { - static $replacements = false; - - if ($replacements === false) - { - foreach ($this->vars as $i => $v) - { - $replacements['#^('.preg_quote($v).'){1}(.*)?#'] = "%".$i."%$2"; - } - } - - foreach ($array as $i => $value) - { - if (is_string($value)) - { - $array[$i] = preg_replace(array_keys($replacements), array_values($replacements), $value); - } - elseif(is_array($value)) - { - $this->prep_vars($array[$i]); - } - } - } - - /** - * Formats the output and saved it to the database. - * - * @param string $identifier filename - * @param $contents $contents language array to save - * @return bool DB result - */ - public function save($identifier, $contents) - { - // get the language and the identifier - list($language, $identifier) = explode(DS, $identifier, 2); - $identifier = basename($identifier, '.db'); - - // prep the contents - $this->prep_vars($contents); - $contents = serialize($contents); - - // update the config in the database - $result = \DB::update($this->table)->set(array('lang' => $contents, 'hash' => uniqid()))->where('identifier', '=', $identifier)->where('language', '=', $language)->execute(); - - // if there wasn't an update, do an insert - if ($result === 0) - { - list($notused, $result) = \DB::insert($this->table)->set(array('identifier' => $identifier, 'language' => $language, 'lang' => $contents, 'hash' => uniqid()))->execute(); - } - - return $result === 1; - } -} diff --git a/fuel/core/classes/lang/file.php b/fuel/core/classes/lang/file.php deleted file mode 100755 index e1e59a1..0000000 --- a/fuel/core/classes/lang/file.php +++ /dev/null @@ -1,210 +0,0 @@ -file = $file; - - $this->languages = $languages; - - $this->vars = array( - 'APPPATH' => APPPATH, - 'COREPATH' => COREPATH, - 'PKGPATH' => PKGPATH, - 'DOCROOT' => DOCROOT, - ) + $vars; - } - - /** - * Loads the language file(s). - * - * @param bool $overwrite Whether to overwrite existing values - * @return array the language array - */ - public function load($overwrite = false) - { - $paths = $this->find_file(); - - $lang = array(); - - foreach ($paths as $path) - { - $lang = $overwrite ? - array_merge($lang, $this->load_file($path)) : - \Arr::merge($lang, $this->load_file($path)); - } - - return $lang; - } - - /** - * Gets the default group name. - * - * @return string - */ - public function group() - { - return $this->file; - } - - /** - * Parses a string using all of the previously set variables. Allows you to - * use something like %APPPATH% in non-PHP files. - * - * @param string $string String to parse - * @return string - */ - protected function parse_vars($string) - { - foreach ($this->vars as $var => $val) - { - $string = str_replace("%$var%", $val, $string); - } - - return $string; - } - - /** - * Replaces FuelPHP's path constants to their string counterparts. - * - * @param array $array array to be prepped - * @return array prepped array - */ - protected function prep_vars(&$array) - { - static $replacements = false; - - if ($replacements === false) - { - foreach ($this->vars as $i => $v) - { - $replacements['#^('.preg_quote($v).'){1}(.*)?#'] = "%".$i."%$2"; - } - } - - foreach ($array as $i => $value) - { - if (is_string($value)) - { - $array[$i] = preg_replace(array_keys($replacements), array_values($replacements), $value); - } - elseif(is_array($value)) - { - $this->prep_vars($array[$i]); - } - } - } - - /** - * Finds the given language files - * - * @return array - * @throws \LangException - */ - protected function find_file() - { - $paths = array(); - foreach ($this->languages as $lang) - { - $paths = array_merge($paths, \Finder::search('lang'.DS.$lang, $this->file, $this->ext, true)); - } - - if (empty($paths)) - { - throw new \LangException(sprintf('File "%s" does not exist.', $this->file)); - } - - return array_reverse($paths); - } - - /** - * Formats the output and saved it to disc. - * - * @param string $identifier filename - * @param $contents $contents language array to save - * @return bool \File::update result - */ - public function save($identifier, $contents) - { - // get the formatted output - $output = $this->export_format($contents); - - if ( ! $output) - { - return false; - } - - if ( ! $path = \Finder::search('lang', $identifier)) - { - if ($pos = strripos($identifier, '::')) - { - // get the namespace path - if ($path = \Autoloader::namespace_path('\\'.ucfirst(substr($identifier, 0, $pos)))) - { - // strip the namespace from the filename - $identifier = substr($identifier, $pos+2); - - // strip the classes directory as we need the module root - $path = substr($path, 0, -8).'lang'.DS.$identifier; - } - else - { - // invalid namespace requested - return false; - } - } - } - - // absolute path requested? - if ($identifier[0] === '/' or (isset($identifier[1]) and $identifier[1] === ':')) - { - $path = $identifier; - } - - // make sure we have a fallback - $path or $path = APPPATH.'lang'.DS.$identifier; - - $path = pathinfo($path); - if ( ! is_dir($path['dirname'])) - { - mkdir($path['dirname'], 0777, true); - } - - return \File::update($path['dirname'], $path['basename'], $output); - } - - /** - * Must be implemented by child class. Gets called for each file to load. - * - * @param string $file File to load - * @return array - */ - abstract protected function load_file($file); - - /** - * Must be impletmented by child class. Gets called when saving a language file. - * - * @param array $contents language array to save - * @return string formatted output - */ - abstract protected function export_format($contents); -} diff --git a/fuel/core/classes/lang/ini.php b/fuel/core/classes/lang/ini.php deleted file mode 100755 index a3daf2b..0000000 --- a/fuel/core/classes/lang/ini.php +++ /dev/null @@ -1,35 +0,0 @@ -parse_vars(file_get_contents($file)); - return parse_ini_string($contents, true); - } - - /** - * Returns the formatted language file contents. - * - * @param array $contents language array - * @return string formatted language file contents - * @throws \LangException - */ - protected function export_format($contents) - { - throw new \LangException('Saving lang to ini is not supported at this time'); - } -} diff --git a/fuel/core/classes/lang/interface.php b/fuel/core/classes/lang/interface.php deleted file mode 100755 index 5e31689..0000000 --- a/fuel/core/classes/lang/interface.php +++ /dev/null @@ -1,10 +0,0 @@ -parse_vars(file_get_contents($file)); - return json_decode($contents, true); - } - - /** - * Returns the formatted language file contents. - * - * @param array $contents config array - * @return string formatted config file contents - */ - protected function export_format($contents) - { - $this->prep_vars($contents); - return \Format::forge()->to_json($contents, true); - } -} diff --git a/fuel/core/classes/lang/php.php b/fuel/core/classes/lang/php.php deleted file mode 100755 index cb5e60c..0000000 --- a/fuel/core/classes/lang/php.php +++ /dev/null @@ -1,126 +0,0 @@ -= 50500 and function_exists('opcache_invalidate')); - - // do we have APC active? - static::$uses_apc = function_exists('apc_compile_file'); - - // determine if we have an opcode cache active - static::$flush_needed = static::$uses_opcache or static::$uses_apc; - } - - /** - * @var string the extension used by this config file parser - */ - protected $ext = '.php'; - - /** - * Formats the output and saved it to disc. - * - * @param string $identifier filename - * @param $contents $contents language array to save - * @return bool \File::update result - */ - public function save($identifier, $contents) - { - // store the current filename - $file = $this->file; - - // save it - $return = parent::save($identifier, $contents); - - // existing file? saved? and do we need to flush the opcode cache? - if ($file == $this->file and $return and static::$flush_needed) - { - if ($this->file[0] !== '/' and ( ! isset($this->file[1]) or $this->file[1] !== ':')) - { - // locate the file - if ($pos = strripos($identifier, '::')) - { - // get the namespace path - if ($file = \Autoloader::namespace_path('\\'.ucfirst(substr($identifier, 0, $pos)))) - { - // strip the namespace from the filename - $identifier = substr($identifier, $pos+2); - - // strip the classes directory as we need the module root - $file = substr($file, 0, -8).'lang'.DS.$identifier; - } - else - { - // invalid namespace requested - return false; - } - } - else - { - $file = \Finder::search('lang', $identifier); - } - } - - // make sure we have a fallback - $file or $file = APPPATH.'lang'.DS.$identifier; - - // flush the opcode caches that are active - static::$uses_opcache and opcache_invalidate($file, true); - static::$uses_apc and apc_compile_file($file); - } - - return $return; - } - - /** - * Loads in the given file and parses it. - * - * @param string $file File to load - * @return array - */ - protected function load_file($file) - { - return \Fuel::load($file); - } - - /** - * Returns the formatted language file contents. - * - * @param array $contents config array - * @return string formatted config file contents - */ - protected function export_format($contents) - { - $output = <<parse_vars(file_get_contents($file)); - return \Format::forge($contents, 'yaml')->to_array(); - } - - /** - * Returns the formatted language file contents. - * - * @param array $contents config array - * @return string formatted config file contents - */ - protected function export_format($contents) - { - if ( ! function_exists('spyc_load')) - { - import('spyc/spyc', 'vendor'); - } - - $this->prep_vars($contents); - return \Spyc::YAMLDump($contents); - } -} diff --git a/fuel/core/classes/log.php b/fuel/core/classes/log.php deleted file mode 100755 index f627a75..0000000 --- a/fuel/core/classes/log.php +++ /dev/null @@ -1,249 +0,0 @@ - 'DEBUG', - 200 => 'INFO', - 250 => 'NOTICE', - 300 => 'WARNING', - 400 => 'ERROR', - 500 => 'CRITICAL', - 550 => 'ALERT', - 600 => 'EMERGENCY', - ); - - /** - * create the monolog instance - */ - public static function _init() - { - static::$monolog = new \Monolog\Logger('fuelphp'); - static::initialize(); - } - - /** - * return the monolog instance - */ - public static function instance() - { - return static::$monolog; - } - - /** - * initialize the created the monolog instance - */ - public static function initialize() - { - // load the file config - \Config::load('file', true); - - // make sure the log directories exist - try - { - // determine the name and location of the logfile - $path = \Config::get('log_path', APPPATH.'logs'.DS); - $filename = \Config::get('log_file', null); - - if(empty($filename)) - { - $rootpath = $path.date('Y').DS; - $filepath = $path.date('Y/m').DS; - $filename = $filepath.date('d').'.php'; - } - else - { - $rootpath = $path; - $filepath = $path; - $filename = $path.$filename; - } - - // get the required folder permissions - $permission = \Config::get('file.chmod.folders', 0777); - - if ( ! is_dir($rootpath)) - { - mkdir($rootpath, 0777, true); - chmod($rootpath, $permission); - } - if ( ! is_dir($filepath)) - { - mkdir($filepath, 0777, true); - chmod($filepath, $permission); - } - - $handle = fopen($filename, 'a'); - } - catch (\Exception $e) - { - \Config::set('log_threshold', \Fuel::L_NONE); - throw new \FuelException('Unable to create or write to the log file. Please check the permissions on '.\Config::get('log_path').'. ('.$e->getMessage().')'); - } - - if ( ! filesize($filename)) - { - fwrite($handle, "".PHP_EOL.PHP_EOL); - chmod($filename, \Config::get('file.chmod.files', 0666)); - } - fclose($handle); - - // create the streamhandler, and activate the handler - $stream = new \Monolog\Handler\StreamHandler($filename, \Monolog\Logger::DEBUG); - $formatter = new \Monolog\Formatter\LineFormatter("%level_name% - %datetime% --> %message%".PHP_EOL, "Y-m-d H:i:s"); - $stream->setFormatter($formatter); - static::$monolog->pushHandler($stream); - } - - /** - * Logs a message with the Info Log Level - * - * @param string $msg The log message - * @param string $method The method that logged - * @return bool If it was successfully logged - */ - public static function info($msg, $method = null) - { - return static::write(\Fuel::L_INFO, $msg, $method); - } - - /** - * Logs a message with the Debug Log Level - * - * @param string $msg The log message - * @param string $method The method that logged - * @return bool If it was successfully logged - */ - public static function debug($msg, $method = null) - { - return static::write(\Fuel::L_DEBUG, $msg, $method); - } - - /** - * Logs a message with the Warning Log Level - * - * @param string $msg The log message - * @param string $method The method that logged - * @return bool If it was successfully logged - */ - public static function warning($msg, $method = null) - { - return static::write(\Fuel::L_WARNING, $msg, $method); - } - - /** - * Logs a message with the Error Log Level - * - * @param string $msg The log message - * @param string $method The method that logged - * @return bool If it was successfully logged - */ - public static function error($msg, $method = null) - { - return static::write(\Fuel::L_ERROR, $msg, $method); - } - - /** - * Write Log File - * - * Generally this function will be called using the global log_message() function - * - * @param int|string $level the error level - * @param string $msg the error message - * @param string $method information about the method - * @return bool - * @throws \FuelException - */ - public static function write($level, $msg, $method = null) - { - // defined default error labels - static $oldlabels = array( - 1 => 'Error', - 2 => 'Warning', - 3 => 'Debug', - 4 => 'Info', - ); - - // get the levels defined to be logged - $loglabels = \Config::get('log_threshold'); - - // bail out if we don't need logging at all - if ($loglabels == \Fuel::L_NONE) - { - return false; - } - - // if it's not an array, assume it's an "up to" level - if ( ! is_array($loglabels)) - { - $a = array(); - foreach (static::$levels as $l => $label) - { - $l >= $loglabels and $a[] = $l; - } - $loglabels = $a; - } - - // if profiling is active log the message to the profile - if (\Config::get('profiling')) - { - \Console::log($method.' - '.$msg); - } - - // convert the level to monolog standards if needed - if (is_int($level) and isset($oldlabels[$level])) - { - $level = strtoupper($oldlabels[$level]); - } - if (is_string($level)) - { - if ( ! $level = array_search($level, static::$levels)) - { - $level = 250; // can't map it, convert it to a NOTICE - } - } - - // make sure $level has the correct value - if ((is_int($level) and ! isset(static::$levels[$level])) or (is_string($level) and ! array_search(strtoupper($level), static::$levels))) - { - throw new \FuelException('Invalid level "'.$level.'" passed to logger()'); - } - - // do we need to log the message with this level? - if ( ! in_array($level, $loglabels)) - { - return false; - } - - // log the message - static::instance()->log($level, (empty($method) ? '' : $method.' - ').$msg); - - return true; - } - -} diff --git a/fuel/core/classes/markdown.php b/fuel/core/classes/markdown.php deleted file mode 100755 index 810f601..0000000 --- a/fuel/core/classes/markdown.php +++ /dev/null @@ -1,61 +0,0 @@ -transform($text); - } -} diff --git a/fuel/core/classes/migrate.php b/fuel/core/classes/migrate.php deleted file mode 100755 index 9e78513..0000000 --- a/fuel/core/classes/migrate.php +++ /dev/null @@ -1,738 +0,0 @@ - array('type' => 'varchar', 'constraint' => 25), - 'name' => array('type' => 'varchar', 'constraint' => 50), - 'migration' => array('type' => 'varchar', 'constraint' => 100, 'null' => false, 'default' => ''), - ); - - /** - * loads in the migrations config file, checks to see if the migrations - * table is set in the database (if not, create it), and reads in all of - * the versions from the DB. - * - * @return void - */ - public static function _init() - { - logger(\Fuel::L_DEBUG, 'Migrate class initialized'); - - // load the migrations config - \Config::load('migrations', true); - - // set the name of the table containing the installed migrations - static::$table = \Config::get('migrations.table', static::$table); - - // set the name of the connection group to use - static::$connection = \Config::get('migrations.connection', static::$connection); - - // installs or upgrades the migration table to the current schema - static::table_version_check(); - - //get all installed migrations from db - $migrations = \DB::select() - ->from(static::$table) - ->order_by('type', 'ASC') - ->order_by('name', 'ASC') - ->order_by('migration', 'ASC') - ->execute(static::$connection) - ->as_array(); - - foreach($migrations as $migration) - { - // convert the db migrations to match the config file structure - isset(static::$migrations[$migration['type']]) or static::$migrations[$migration['type']] = array(); - static::$migrations[$migration['type']][$migration['name']][] = $migration['migration']; - - // make sure we have this in the config too - $config = \Config::get('migrations.version.'.$migration['type'].'.'.$migration['name'], array()); - is_array($config) or $config = array(); - if ( ! in_array($migration['migration'], $config)) - { - $config[] = $migration['migration']; - sort($config); - \Config::set('migrations.version.'.$migration['type'].'.'.$migration['name'], $config); - } - } - // write the updated config - \Config::save(\Fuel::$env.DS.'migrations', 'migrations'); - } - - /** - * migrate to a specific version, range of versions, or all - * - * @param mixed $version version to migrate to (up or down!) - * @param string $name name of the package, module or app - * @param string $type type of migration (package, module or app) - * @param bool $all if true, also run out-of-sequence migrations - * - * @throws \UnexpectedValueException - * @return array - */ - public static function version($version = null, $name = 'default', $type = 'app', $all = false) - { - // get the current version from the config - $all or $current = \Config::get('migrations.version.'.$type.'.'.$name); - - // any migrations defined? - if ( ! empty($current)) - { - // get the timestamp of the last installed migration - if (preg_match('/^(.*?)_(.*)$/', end($current), $match)) - { - // determine the direction - $direction = (is_null($version) or $match[1] < $version) ? 'up' : 'down'; - - // fetch the migrations - if ($direction == 'up') - { - $migrations = static::find_migrations($name, $type, $match[1], $version); - } - else - { - $migrations = static::find_migrations($name, $type, $version, $match[1], $direction); - - // we're going down, so reverse the order of mygrations - $migrations = array_reverse($migrations, true); - } - - // run migrations from current version to given version - return static::run($migrations, $name, $type, $direction); - } - else - { - throw new \UnexpectedValueException('Could not determine a valid version from '.$current.'.'); - } - } - - // run migrations from the beginning to given version - return static::run(static::find_migrations($name, $type, null, $version), $name, $type, 'up'); - } - - /** - * migrate to a latest version - * - * @param string $name name of the package, module or app - * @param string $type type of migration (package, module or app) - * @param bool $all if true, also run out-of-sequence migrations - * - * @return array - */ - public static function latest($name = 'default', $type = 'app', $all = false) - { - // equivalent to from current version (or all) to latest - return static::version(null, $name, $type, $all); - } - - /** - * migrate to the version defined in the config file - * - * @param string $name name of the package, module or app - * @param string $type type of migration (package, module or app) - * - * @return array - */ - public static function current($name = 'default', $type = 'app') - { - // get the current version from the config - $current = \Config::get('migrations.version.'.$type.'.'.$name); - - // any migrations defined? - if ( ! empty($current)) - { - // get the timestamp of the last installed migration - if (preg_match('/^(.*?)_(.*)$/', end($current), $match)) - { - // run migrations from start to current version - return static::run(static::find_migrations($name, $type, null, $match[1]), $name, $type, 'up'); - } - } - - // nothing to migrate - return array(); - } - - /** - * migrate up to the next version - * - * @param mixed $version version to migrate up to - * @param string $name name of the package, module or app - * @param string $type type of migration (package, module or app) - * - * @return array - */ - public static function up($version = null, $name = 'default', $type = 'app') - { - // get the current version info from the config - $current = \Config::get('migrations.version.'.$type.'.'.$name); - - // get the last migration installed - $current = empty($current) ? null : end($current); - - // get the available migrations after the current one - $migrations = static::find_migrations($name, $type, $current, $version); - - // found any? - if ( ! empty($migrations)) - { - // if no version was given, only install the next migration - is_null($version) and $migrations = array(reset($migrations)); - - // install migrations found - return static::run($migrations, $name, $type, 'up'); - } - - // nothing to migrate - return array(); - } - - /** - * migrate down to the previous version - * - * @param mixed $version version to migrate down to - * @param string $name name of the package, module or app - * @param string $type type of migration (package, module or app) - * - * @return array - */ - public static function down($version = null, $name = 'default', $type = 'app') - { - // get the current version info from the config - $current = \Config::get('migrations.version.'.$type.'.'.$name); - - // any migrations defined? - if ( ! empty($current)) - { - // get the last entry - $current = end($current); - - // get the available migrations before the last current one - $migrations = static::find_migrations($name, $type, $version, $current, 'down'); - - // found any? - if ( ! empty($migrations)) - { - // if no version was given, only revert the last migration - if (is_null($version)) - { - $migrations = array_slice($migrations, -1, 1, true); - } - else - { - // we're going down, so reverse the order of migrations - $migrations = array_reverse($migrations, true); - } - - // revert the installed migrations - return static::run($migrations, $name, $type, 'down'); - } - } - - // nothing to migrate - return array(); - } - - /** - * run the action migrations found - * - * @param array $migrations list of files to migrate - * @param string $name name of the package, module or app - * @param string $type type of migration (package, module or app) - * @param string $method method to call on the migration - * - * @return array - */ - protected static function run($migrations, $name, $type, $method = 'up') - { - // storage for installed migrations - $done = array(); - - static::$connection === null or \DBUtil::set_connection(static::$connection); - - // Make sure we have class access - switch ($type) - { - case 'package': - \Package::load($name); - break; - - case 'module': - \Module::load($name); - break; - - default: - } - - // Loop through the runnable migrations and run them - foreach ($migrations as $ver => $migration) - { - logger(\Fuel::L_INFO, 'Migrating to version: '.$ver); - $result = static::_run($migration['class'], $method); - if ($result === false) - { - logger(\Fuel::L_INFO, 'Skipped migration to '.$ver.'.'); - $done[] = false; - return $done; - } - - $file = basename($migration['path'], '.php'); - $method == 'up' ? static::write_install($name, $type, $file) : static::write_revert($name, $type, $file); - $done[] = $file; - } - - static::$connection === null or \DBUtil::set_connection(null); - - empty($done) or logger(\Fuel::L_INFO, 'Migrated to '.$ver.' successfully.'); - - return $done; - } - - /** - * add an installed migration to the database - * - * @param string $name name of the package, module or app - * @param string $type type of migration (package, module or app) - * @param string $file name of the migration file just run - * - * @return void - */ - protected static function write_install($name, $type, $file) - { - // add the migration just run - \DB::insert(static::$table)->set(array( - 'name' => $name, - 'type' => $type, - 'migration' => $file, - ))->execute(static::$connection); - - // add the file to the list of run migrations - static::$migrations[$type][$name][] = $file; - - // make sure the migrations are in the correct order - sort(static::$migrations[$type][$name]); - - // and save the update to the environment config file - \Config::set('migrations.version.'.$type.'.'.$name, static::$migrations[$type][$name]); - \Config::save(\Fuel::$env.DS.'migrations', 'migrations'); - } - - /** - * remove a reverted migration from the database - * - * @param string $name name of the package, module or app - * @param string $type type of migration (package, module or app) - * @param string $file name of the migration file just run - * - * @return void - */ - protected static function write_revert($name, $type, $file) - { - // remove the migration just run - \DB::delete(static::$table) - ->where('name', $name) - ->where('type', $type) - ->where('migration', $file) - ->execute(static::$connection); - - // remove the file from the list of run migrations - if (($key = array_search($file, static::$migrations[$type][$name])) !== false) - { - unset(static::$migrations[$type][$name][$key]); - } - - // make sure the migrations are in the correct order - sort(static::$migrations[$type][$name]); - - // and save the update to the config file - \Config::set('migrations.version.'.$type.'.'.$name, static::$migrations[$type][$name]); - \Config::save(\Fuel::$env.DS.'migrations', 'migrations'); - } - - /** - * migrate down to the previous version - * - * @param string $name name of the package, module or app - * @param string $type type of migration (package, module or app) - * @param mixed $start version to start migrations from, or null to start at the beginning - * @param mixed $end version to end migrations by, or null to migrate to the end - * @param string $direction - * - * @return array - * @throws \FuelException - */ - protected static function find_migrations($name, $type, $start = null, $end = null, $direction = 'up') - { - // Load all *_*.php files in the migrations path - $method = '_find_'.$type; - if ( ! $files = static::$method($name)) - { - return array(); - } - - // get the currently installed migrations from the DB - $current = \Arr::get(static::$migrations, $type.'.'.$name, array()); - - // storage for the result - $migrations = array(); - - // normalize start and end values - if ( ! is_null($start)) - { - // if we have a prefix, use that - ($pos = strpos($start, '_')) === false or $start = ltrim(substr($start, 0, $pos), '0'); - is_numeric($start) and $start = (int) $start; - } - if ( ! is_null($end)) - { - // if we have a prefix, use that - ($pos = strpos($end, '_')) === false or $end = ltrim(substr($end, 0, $pos), '0'); - is_numeric($end) and $end = (int) $end; - } - - // filter the migrations out of bounds - foreach ($files as $file) - { - // get the version for this migration and normalize it - $migration = basename($file); - ($pos = strpos($migration, '_')) === false or $migration = ltrim(substr($migration, 0, $pos), '0'); - is_numeric($migration) and $migration = (int) $migration; - - // add the file to the migrations list if it's in between version bounds - if ((is_null($start) or $migration > $start) and (is_null($end) or $migration <= $end)) - { - // see if it is already installed - if ( in_array(basename($file, '.php'), $current)) - { - // already installed. store it only if we're going down - $direction == 'down' and $migrations[$migration] = array('path' => $file); - } - else - { - // not installed yet. store it only if we're going up - $direction == 'up' and $migrations[$migration] = array('path' => $file); - } - } - } - - // We now prepare to actually DO the migrations - // But first let's make sure that everything is the way it should be - foreach ($migrations as $ver => $migration) - { - // get the migration filename from the path - $migration['file'] = basename($migration['path']); - - // make sure the migration filename has a valid format - if (preg_match('/^.*?_(.*).php$/', $migration['file'], $match)) - { - // determine the classname for this migration - $class_name = ucfirst(strtolower($match[1])); - - // load the file and determine the classname - include_once $migration['path']; - $class = static::$prefix.$class_name; - - // make sure it exists in the migration file loaded - if ( ! class_exists($class, false)) - { - throw new \FuelException(sprintf('Migration "%s" does not contain expected class "%s"', $migration['path'], $class)); - } - - // and that it contains an "up" and "down" method - if ( ! is_callable(array($class, 'up')) or ! is_callable(array($class, 'down'))) - { - throw new \FuelException(sprintf('Migration class "%s" must include public methods "up" and "down"', $name)); - } - - $migrations[$ver]['class'] = $class; - } - else - { - throw new \FuelException(sprintf('Invalid Migration filename "%s"', $migration['path'])); - } - } - - // make sure the result is sorted properly with all version types - uksort($migrations, 'strnatcasecmp'); - - return $migrations; - } - - /** - * run the actual migration, and it's before and after methods if present - * - */ - protected static function _run($class, $method) - { - // create an instance of the migration class - $class = new $class; - - // if it has a before method, call that first - if (method_exists($class, 'before')) - { - if (false === call_user_func(array($class, 'before'))) - { - return false; - } - } - - // run the actual migration - $result = call_user_func(array($class, $method)); - - // if it has a after method, call that if the migration has run - if ($result !== false and method_exists($class, 'after')) - { - if (false === call_user_func(array($class, 'after'))) - { - // revert the migration - logger(\Fuel::L_INFO, 'Migration is reverted due to failure of the after method.'); - - if ($method == 'up') - { - call_user_func(array($class, 'down')); - } - else - { - call_user_func(array($class, 'up')); - } - return false; - } - } - - return $result; - } - - /** - * finds migrations for the given app - * - * @param string $name name of the app (not used at the moment) - * - * @return array - */ - protected static function _find_app($name = null) - { - $found = array(); - - $files = new \GlobIterator(APPPATH.\Config::get('migrations.folder').'*_*.php'); - foreach($files as $file) - { - $found[] = $file->getPathname(); - } - - return $found; - } - - /** - * finds migrations for the given module (or all if name is not given) - * - * @param string $name name of the module - * - * @return array - */ - protected static function _find_module($name = null) - { - $files = array(); - - if ($name) - { - // find a module - foreach (\Config::get('module_paths') as $m) - { - $found = new \GlobIterator($m.$name.DS.\Config::get('migrations.folder').'*_*.php'); - if (count($found)) - { - foreach($found as $file) - { - $files[] = $file->getPathname(); - } - break; - } - } - } - else - { - // find all modules - foreach (\Config::get('module_paths') as $m) - { - $found = new \GlobIterator($m.'*'.DS.\Config::get('migrations.folder').'*_*.php'); - foreach($found as $file) - { - $files[] = $file->getPathname(); - } - } - } - - return $files; - } - - /** - * finds migrations for the given package (or all if name is not given) - * - * @param string $name name of the package - * - * @return array - */ - protected static function _find_package($name = null) - { - $files = array(); - - if ($name) - { - // find a package - foreach (\Config::get('package_paths', array(PKGPATH)) as $p) - { - $found = new \GlobIterator($p.$name.DS.\Config::get('migrations.folder').'*_*.php'); - if (count($found)) - { - foreach($found as $file) - { - $files[] = $file->getPathname(); - } - break; - } - } - } - else - { - // find all packages - foreach (\Config::get('package_paths', array(PKGPATH)) as $p) - { - $found = new \GlobIterator($p.'*'.DS.\Config::get('migrations.folder').'*_*.php'); - foreach($found as $file) - { - $files[] = $file->getPathname(); - } - } - } - - return $files; - } - - /** - * installs or upgrades the migration table to the current schema - * - * @return void - * - * @deprecated Remove upgrade check in 1.4 - */ - protected static function table_version_check() - { - // set connection - static::$connection === null or \DBUtil::set_connection(static::$connection); - - // if table does not exist - if ( ! \DBUtil::table_exists(static::$table)) - { - // create table - \DBUtil::create_table(static::$table, static::$table_definition); - } - - // check if a table upgrade is needed - elseif ( ! \DBUtil::field_exists(static::$table, array('migration'))) - { - // get the current migration status - $current = \DB::select()->from(static::$table)->order_by('type', 'ASC')->order_by('name', 'ASC')->execute(static::$connection)->as_array(); - - // drop the existing table, and recreate it in the new layout - \DBUtil::drop_table(static::$table); - \DBUtil::create_table(static::$table, static::$table_definition); - - // check if we had a current migration status - if ( ! empty($current)) - { - // do we need to migrate from a v1.0 migration environment? - if (isset($current[0]['current'])) - { - // convert the current result into a v1.1. migration environment structure - $current = array(0 => array('name' => 'default', 'type' => 'app', 'version' => $current[0]['current'])); - } - - // build a new config structure - $configs = array(); - - // convert the v1.1 structure to the v1.2 structure - foreach ($current as $migration) - { - // find the migrations for this entry - $migrations = static::find_migrations($migration['name'], $migration['type'], null, $migration['version']); - - // array to keep track of the migrations already run - $config = array(); - - // add the individual migrations found - foreach ($migrations as $file) - { - $file = pathinfo($file['path']); - - // add this migration to the table - \DB::insert(static::$table)->set(array( - 'name' => $migration['name'], - 'type' => $migration['type'], - 'migration' => $file['filename'], - ))->execute(static::$connection); - - // and to the config - $config[] = $file['filename']; - } - - // create a config entry for this name and type if needed - isset($configs[$migration['type']]) or $configs[$migration['type']] = array(); - $configs[$migration['type']][$migration['name']] = $config; - } - - // write the updated migrations config back - \Config::set('migrations.version', $configs); - \Config::save(\Fuel::$env.DS.'migrations', 'migrations'); - } - - // delete any old migration config file that may exist - is_file(APPPATH.'config'.DS.'migrations.php') and unlink(APPPATH.'config'.DS.'migrations.php'); - } - - // set connection to default - static::$connection === null or \DBUtil::set_connection(null); - } -} diff --git a/fuel/core/classes/model.php b/fuel/core/classes/model.php deleted file mode 100755 index 519f709..0000000 --- a/fuel/core/classes/model.php +++ /dev/null @@ -1,17 +0,0 @@ -set($data) - */ - // protected static $_mass_whitelist = array(); - - /** - * @var array $_mass_blacklist The table column names which will not be set while using mass assignment like ->set($data) - */ - // protected static $_mass_blacklist = array(); - - /** - * @var array $_labels Field labels (must set this in your Model to use) - */ - // protected static $_labels = array(); - - /** - * @var array $_defaults Field defaults (must set this in your Model to use) - */ - // protected static $_defaults = array(); - - /** - * @var bool set true to use MySQL timestamp instead of UNIX timestamp - */ - //protected static $_mysql_timestamp = false; - - /** - * @var string fieldname of created_at field, uncomment to use. - */ - //protected static $_created_at = 'created_at'; - - /** - * @var string fieldname of updated_at field, uncomment to use. - */ - //protected static $_updated_at = 'updated_at'; - - /** - * Forges new Model_Crud objects. - * - * @param array $data Model data - * @return Model_Crud - */ - public static function forge(array $data = array()) - { - return new static($data); - } - - /** - * Finds a row with the given primary key value. - * - * @param mixed $value The primary key value to find - * @return null|object Either null or a new Model object - */ - public static function find_by_pk($value) - { - return static::find_one_by(static::primary_key(), $value); - } - - /** - * Finds a row with the given column value. - * - * @param mixed $column The column to search - * @param mixed $value The value to find - * @param string $operator - * @return null|object Either null or a new Model object - */ - public static function find_one_by($column, $value = null, $operator = '=') - { - $config = array( - 'limit' => 1, - ); - - if (is_array($column) or ($column instanceof \Closure)) - { - $config['where'] = $column; - } - else - { - $config['where'] = array(array($column, $operator, $value)); - } - - $result = static::find($config); - - if ($result !== null) - { - return reset($result); - } - - return null; - } - - /** - * Finds all records where the given column matches the given value using - * the given operator ('=' by default). Optionally limited and offset. - * - * @param string $column The column to search - * @param mixed $value The value to find - * @param string $operator The operator to search with - * @param int $limit Number of records to return - * @param int $offset What record to start at - * @return null|object Null if not found or an array of Model object - */ - public static function find_by($column = null, $value = null, $operator = '=', $limit = null, $offset = 0) - { - $config = array( - 'limit' => $limit, - 'offset' => $offset, - ); - - if ($column !== null) - { - if (is_array($column) or ($column instanceof \Closure)) - { - $config['where'] = $column; - } - else - { - $config['where'] = array(array($column, $operator, $value)); - } - } - - return static::find($config); - } - - /** - * Finds all records in the table. Optionally limited and offset. - * - * @param int $limit Number of records to return - * @param int $offset What record to start at - * @return null|object Null if not found or an array of Model object - */ - public static function find_all($limit = null, $offset = 0) - { - return static::find(array( - 'limit' => $limit, - 'offset' => $offset, - )); - } - - /** - * Finds all records. - * - * @param array $config array containing query settings - * @param string $key optional array index key - * @return array|null an array containing models or null if none are found - */ - public static function find($config = array(), $key = null) - { - $query = \DB::select() - ->from(static::$_table_name) - ->as_object(get_called_class()); - - if ($config instanceof \Closure) - { - $config($query); - } - else - { - $config = $config + array( - 'select' => array(static::$_table_name.'.*'), - 'where' => array(), - 'order_by' => array(), - 'limit' => null, - 'offset' => 0, - ); - - extract($config); - - is_string($select) and $select = array($select); - $query->select_array($select); - - if ( ! empty($where)) - { - $query->where($where); - } - - if (is_array($order_by)) - { - foreach ($order_by as $_field => $_direction) - { - $query->order_by($_field, $_direction); - } - } - else - { - $query->order_by($order_by); - } - - if ($limit !== null) - { - $query = $query->limit($limit)->offset($offset); - } - } - - static::pre_find($query); - - $result = $query->execute(static::get_connection()); - $result = ($result->count() === 0) ? null : $result->as_array($key); - - return static::post_find($result); - } - - /** - * Count all of the rows in the table. - * - * @param string $column Column to count by - * @param bool $distinct Whether to count only distinct rows (by column) - * @param array $where Query where clause(s) - * @param string $group_by Column to group by - * @return int The number of rows OR false - * @throws \FuelException - */ - public static function count($column = null, $distinct = true, $where = array(), $group_by = null) - { - $select = $column ?: static::primary_key(); - - // Get the database group / connection - $connection = static::get_connection(); - - // Get the columns - $columns = \DB::expr('COUNT('.($distinct ? 'DISTINCT ' : ''). - \Database_Connection::instance($connection)->quote_identifier($select). - ') AS count_result'); - - // Remove the current select and - $query = \DB::select($columns); - - // Set from table - $query = $query->from(static::$_table_name); - - if ( ! empty($where)) - { - //is_array($where) or $where = array($where); - if ( ! is_array($where) and ($where instanceof \Closure) === false) - { - throw new \FuelException(get_called_class().'::count where statement must be an array or a closure.'); - } - $query = $query->where($where); - } - - if ( ! empty($group_by)) - { - $result = $query->select($group_by)->group_by($group_by)->execute($connection)->as_array(); - $counts = array(); - foreach ($result as $res) - { - $counts[$res[$group_by]] = $res['count_result']; - } - - return $counts; - } - - $count = $query->execute($connection)->get('count_result'); - - if ($count === null) - { - return false; - } - - return (int) $count; - } - - /** - * Implements dynamic Model_Crud::find_by_{column} and Model_Crud::find_one_by_{column} - * methods. - * - * @param string $name The method name - * @param string $args The method args - * @return mixed Based on static::$return_type - * @throws \BadMethodCallException - */ - public static function __callStatic($name, $args) - { - if (strncmp($name, 'find_by_', 8) === 0) - { - return static::find_by(substr($name, 8), reset($args)); - } - elseif (strncmp($name, 'find_one_by_', 12) === 0) - { - return static::find_one_by(substr($name, 12), reset($args)); - } - throw new \BadMethodCallException('Method "'.$name.'" does not exist.'); - } - - /** - * Get the connection to use for reading or writing - * - * @param boolean $writable Get a writable connection - * @return Database_Connection - */ - protected static function get_connection($writable = false) - { - if ($writable and isset(static::$_write_connection)) - { - return static::$_write_connection; - } - - return isset(static::$_connection) ? static::$_connection : null; - } - - /** - * Get the primary key for the current Model - * - * @return string - */ - protected static function primary_key() - { - return isset(static::$_primary_key) ? static::$_primary_key : 'id'; - } - - /** - * Gets called before the query is executed. Must return the query object. - * - * @param Database_Query $query The query object - * @return void - */ - protected static function pre_find(&$query){} - - /** - * Gets called after the query is executed and right before it is returned. - * $result will be null if 0 rows are returned. - * - * @param array|null $result the result array or null when there was no result - * @return array|null - */ - protected static function post_find($result) - { - return $result; - } - - /** - * @var array $_data Data container for this object - */ - protected $_data = array(); - - /** - * @var bool $_is_new If this is a new record - */ - protected $_is_new = true; - - /** - * @var bool $_is_frozen If this is a record is frozen - */ - protected $_is_frozen = false; - - /** - * @var bool $_sanitization_enabled If this is a records data will be sanitized on get - */ - protected $_sanitization_enabled = false; - - /** - * @var object $_validation The validation instance - */ - protected $_validation = null; - - /** - * Sets up the object. - * - * @param array $data The data array - */ - public function __construct(array $data = array()) - { - $this->set($data); - - if (isset($this->_data[static::primary_key()])) - { - $this->is_new(false); - } - } - - /** - * Magic setter so new objects can be assigned values - * - * @param string $property The property name - * @param mixed $value The property value - * @return void - */ - public function __set($property, $value) - { - $this->_data[$property] = $value; - } - - /** - * Magic getter to fetch data from the data container - * - * @param string $property The property name - * @return mixed - */ - public function __get($property) - { - if (array_key_exists($property, $this->_data)) - { - return $this->_sanitization_enabled ? \Security::clean($this->_data[$property], null, 'security.output_filter') : $this->_data[$property]; - } - - throw new \OutOfBoundsException('Property "'.$property.'" not found for '.get_called_class().'.'); - } - - /** - * Magic isset to check if values exist - * - * @param string $property The property name - * @return bool whether or not the property exists - */ - public function __isset($property) - { - return isset($this->_data[$property]); - } - - /** - * Magic unset to remove existing properties - * - * @param string $property The property name - */ - public function __unset($property) - { - unset($this->_data[$property]); - } - - /** - * Sets an array of values to class properties - * - * @param array $data The data - * @return $this - */ - public function set(array $data) - { - foreach ($data as $key => $value) - { - if (isset(static::$_mass_whitelist)) - { - in_array($key, static::$_mass_whitelist) and $this->_data[$key] = $value; - } - elseif (isset(static::$_mass_blacklist)) - { - ( ! in_array($key, static::$_mass_blacklist)) and $this->_data[$key] = $value; - } - else - { - // no static::$_mass_whitelist or static::$_mass_blacklist set, proceed with default behavior - $this->_data[$key] = $value; - } - } - return $this; - } - - /** - * Saves the object to the database by either creating a new record - * or updating an existing record. Sets the default values if set. - * - * @param bool $validate whether to validate the input - * @return array|int Rows affected and or insert ID - * @throws \Exception - */ - public function save($validate = true) - { - if ($this->frozen()) - { - throw new \Exception('Cannot modify a frozen row.'); - } - - $vars = $this->_data; - - // Set default if there are any - isset(static::$_defaults) and $vars = $vars + static::$_defaults; - - if ($validate and isset(static::$_rules) and ! empty(static::$_rules)) - { - $vars = $this->pre_validate($vars); - $validated = $this->post_validate($this->run_validation($vars)); - - if ($validated) - { - $validated = array_filter($this->validation()->validated(), function($val){ - return ($val !== null); - }); - - $vars = $validated + $vars; - } - else - { - return false; - } - } - - $vars = $this->prep_values($vars); - - if (isset(static::$_properties)) - { - $vars = \Arr::filter_keys($vars, static::$_properties); - } - - if(isset(static::$_updated_at)) - { - if(isset(static::$_mysql_timestamp) and static::$_mysql_timestamp === true) - { - $vars[static::$_updated_at] = \Date::forge()->format('mysql'); - } - else - { - $vars[static::$_updated_at] = \Date::forge()->get_timestamp(); - } - } - - if ($this->is_new()) - { - if(isset(static::$_created_at)) - { - if(isset(static::$_mysql_timestamp) and static::$_mysql_timestamp === true) - { - $vars[static::$_created_at] = \Date::forge()->format('mysql'); - } - else - { - $vars[static::$_created_at] = \Date::forge()->get_timestamp(); - } - } - - $query = \DB::insert(static::$_table_name) - ->set($vars); - - $this->pre_save($query); - $result = $query->execute(static::get_connection(true)); - - if ($result[1] > 0) - { - // workaround for PDO connections not returning the insert_id - if ($result[0] === false and isset($vars[static::primary_key()])) - { - $result[0] = $vars[static::primary_key()]; - } - $this->set($vars); - empty($result[0]) or $this->{static::primary_key()} = $result[0]; - $this->is_new(false); - } - - return $this->post_save($result); - } - - $query = \DB::update(static::$_table_name) - ->set($vars) - ->where(static::primary_key(), '=', $this->{static::primary_key()}); - - $this->pre_update($query); - $result = $query->execute(static::get_connection(true)); - $result > 0 and $this->set($vars); - - return $this->post_update($result); - } - - /** - * Deletes this record and freezes the object - * - * @return mixed Rows affected - */ - public function delete() - { - $this->frozen(true); - $query = \DB::delete(static::$_table_name) - ->where(static::primary_key(), '=', $this->{static::primary_key()}); - - $this->pre_delete($query); - $result = $query->execute(static::get_connection(true)); - - return $this->post_delete($result); - } - - /** - * Either checks if the record is new or sets whether it is new or not. - * - * @param bool|null $new Whether this is a new record - * @return bool|$this - */ - public function is_new($new = null) - { - if ($new === null) - { - return $this->_is_new; - } - - $this->_is_new = (bool) $new; - - return $this; - } - - /** - * Either checks if the record is frozen or sets whether it is frozen or not. - * - * @param bool|null $frozen Whether this is a frozen record - * @return bool|$this - */ - public function frozen($frozen = null) - { - if ($frozen === null) - { - return $this->_is_frozen; - } - - $this->_is_frozen = (bool) $frozen; - - return $this; - } - - /** - * Enable sanitization mode in the object - * - * @return $this - */ - public function sanitize() - { - $this->_sanitization_enabled = true; - - return $this; - } - - /** - * Disable sanitization mode in the object - * - * @return $this - */ - public function unsanitize() - { - $this->_sanitization_enabled = false; - - return $this; - } - - /** - * Returns the current sanitization state of the object - * - * @return bool - */ - public function sanitized() - { - return $this->_sanitization_enabled; - } - - /** - * Returns the a validation object for the model. - * - * @return object Validation object - */ - public function validation() - { - if( ! $this->_validation) - { - $this->_validation = \Validation::forge(\Str::random('alnum', 32)); - - if (isset(static::$_rules) and count(static::$_rules)) - { - foreach (static::$_rules as $field => $rules) - { - $label = (isset(static::$_labels) and array_key_exists($field, static::$_labels)) ? static::$_labels[$field] : $field; - $this->_validation->add_field($field, $label, $rules); - } - } - } - - return $this->_validation; - } - - /** - * Returns all of $this object's public properties as an associative array. - * - * @return array - */ - public function to_array() - { - return $this->_data; - } - - /** - * Implementation of the Iterator interface - */ - - public function rewind() - { - reset($this->_data); - } - - public function current() - { - return current($this->_data); - } - - public function key() - { - return key($this->_data); - } - - public function next() - { - return next($this->_data); - } - - public function valid() - { - return key($this->_data) !== null; - } - - /** - * Sets the value of the given offset (class property). - * - * @param string $offset class property - * @param string $value value - * @return void - */ - public function offsetSet($offset, $value) - { - $this->_data[$offset] = $value; - } - - /** - * Checks if the given offset (class property) exists. - * - * @param string $offset class property - * @return bool - */ - public function offsetExists($offset) - { - return array_key_exists($offset, $this->_data); - } - - /** - * Unsets the given offset (class property). - * - * @param string $offset class property - * @return void - */ - public function offsetUnset($offset) - { - unset($this->_data[$offset]); - } - - /** - * Gets the value of the given offset (class property). - * - * @param string $offset class property - * @return mixed - */ - public function offsetGet($offset) - { - if (array_key_exists($offset, $this->_data)) - { - return $this->_data[$offset]; - } - - throw new \OutOfBoundsException('Property "'.$offset.'" not found for '.get_called_class().'.'); - } - - /** - * Returns whether the instance will pass validation. - * - * @return bool whether the instance passed validation - */ - public function validates() - { - if ( ! isset(static::$_rules) or count(static::$_rules) < 0) - { - return true; - } - - $vars = $this->_data; - - // Set default if there are any - isset(static::$_defaults) and $vars = $vars + static::$_defaults; - $vars = $this->pre_validate($vars); - - return $this->run_validation($vars); - } - - /** - * Run validation - * - * @param array $vars array to validate - * @return bool validation result - */ - protected function run_validation($vars) - { - if ( ! isset(static::$_rules) or count(static::$_rules) < 0) - { - return true; - } - - $this->_validation = $this->validation(); - - return $this->_validation->run($vars); - } - - /** - * Gets called before the insert query is executed. Must return - * the query object. - * - * @param Database_Query $query The query object - * @return void - */ - protected function pre_save(&$query){} - - /** - * Gets called after the insert query is executed and right before - * it is returned. - * - * @param array $result insert id and number of affected rows - * @return array - */ - protected function post_save($result) - { - return $result; - } - - /** - * Gets called before the update query is executed. Must return the query object. - * - * @param Database_Query $query The query object - * @return void - */ - protected function pre_update(&$query){} - - /** - * Gets called after the update query is executed and right before - * it is returned. - * - * @param int $result Number of affected rows - * @return int - */ - protected function post_update($result) - { - return $result; - } - - /** - * Gets called before the delete query is executed. Must return the query object. - * - * @param Database_Query $query The query object - * @return void - */ - protected function pre_delete(&$query){} - - /** - * Gets called after the delete query is executed and right before - * it is returned. - * - * @param int $result Number of affected rows - * @return int - */ - protected function post_delete($result) - { - return $result; - } - - /** - * Gets called before the validation is ran. - * - * @param array $data The validation data - * @return array - */ - protected function pre_validate($data) - { - return $data; - } - - /** - * Called right after the validation is ran. - * - * @param bool $result Validation result - * @return bool - */ - protected function post_validate($result) - { - return $result; - } - - /** - * Called right after values retrieval, before save, - * update, setting defaults and validation. - * - * @param array $values input array - * @return array - */ - protected function prep_values($values) - { - return $values; - } - - /** - * Serializable implementation: serialize - * - * @return array model data - */ - public function serialize() - { - $data = $this->_data; - - $data['_is_new'] = $this->_is_new; - $data['_is_frozen'] = $this->_is_frozen; - - return serialize($data); - } - - /** - * Serializable implementation: unserialize - * - * @param string $data - * @return array model data - */ - public function unserialize($data) - { - $data = unserialize($data); - - foreach ($data as $key => $value) - { - $this->__set($key, $value); - } - } -} diff --git a/fuel/core/classes/module.php b/fuel/core/classes/module.php deleted file mode 100755 index a9318a9..0000000 --- a/fuel/core/classes/module.php +++ /dev/null @@ -1,194 +0,0 @@ - $path) - { - if (is_numeric($mod)) - { - $mod = $path; - $path = null; - } - $result = $result and static::load($mod, $path); - } - return $result; - } - - if (static::loaded($module)) - { - return false; - } - - // if no path is given, try to locate the module - if ($path === null) - { - $paths = \Config::get('module_paths', array()); - - if ( ! empty($paths)) - { - foreach ($paths as $modpath) - { - if (is_dir($path = $modpath.strtolower($module).DS)) - { - break; - } - } - } - - } - else - { - // make sure it's terminated properly - $path = rtrim($path, DS).DS; - } - - // make sure the path exists - if ( ! is_dir($path)) - { - throw new \ModuleNotFoundException("Module '$module' could not be found at '".\Fuel::clean_path($path)."'"); - } - - // determine the module namespace - $ns = '\\'.ucfirst($module); - - // add the namespace to the autoloader - \Autoloader::add_namespaces(array( - $ns => $path.'classes'.DS, - ), true); - - static::$modules[$module] = $path; - - return true; - } - - /** - * Unloads a module from the stack. - * - * @param string $module The module name - * @return void - */ - public static function unload($module) - { - // we can only unload a loaded module - if (isset(static::$modules[$module])) - { - $path = static::$modules[$module]; - - if (is_file($path .= 'config/routes.php')) - { - // load and add the module routes - $module_routes = \Fuel::load($path); - - $route_names = array(); - foreach($module_routes as $name => $_route) - { - if ($name === '_root_') - { - $name = $module; - } - elseif (strpos($name, $module.'/') !== 0 and $name != $module and $name !== '_404_') - { - $name = $module.'/'.$name; - } - - $route_names[] = $name; - }; - - // delete the defined module routes - \Router::delete($route_names); - } - } - - // delete this module - unset(static::$modules[$module]); - } - - /** - * Checks if the given module is loaded, if no module is given then - * all loaded modules are returned. - * - * @param string|null $module The module name or null - * @return bool|array Whether the module is loaded, or all modules - */ - public static function loaded($module = null) - { - if ($module === null) - { - return static::$modules; - } - - return array_key_exists($module, static::$modules); - } - - /** - * Checks if the given module exists. - * - * @param string $module The module name - * @return bool|string Path to the module found, or false if not found - */ - public static function exists($module) - { - if (array_key_exists($module, static::$modules)) - { - return static::$modules[$module]; - } - else - { - $paths = \Config::get('module_paths', array()); - $module = strtolower($module); - - foreach ($paths as $path) - { - if (is_dir($path.$module)) - { - return $path.$module.DS; - } - } - } - - return false; - } -} diff --git a/fuel/core/classes/mongo/db.php b/fuel/core/classes/mongo/db.php deleted file mode 100755 index 36f54d5..0000000 --- a/fuel/core/classes/mongo/db.php +++ /dev/null @@ -1,1304 +0,0 @@ - - * @copyright 2009 Justin Poliey - * @modified Alex Bilbie - * @modified Phil Sturgeon - * @license http://www.opensource.org/licenses/mit-license.php The MIT License - */ - -class Mongo_DbException extends \FuelException {} - -class Mongo_Db -{ - /** - * Holds the current Mongo connection object - * - * @var Mongo - */ - protected $connection = false; - - /** - * Holds the current DB reference on the connection object - * - * @var Object - */ - protected $db; - - /** - * Whether to use a persistent connection - * - * @var bool - */ - protected $persist = false; - - /** - * Whether to use the profiler - * - * @var bool - */ - protected $profiling = false; - - /** - * Holds all the select options - * - * @var array - */ - protected $selects = array(); - - /** - * Holds all the where options. - * - * @var array - */ - public $wheres = array(); - - /** - * Holds the sorting options - * - * @var array - */ - protected $sorts = array(); - - /** - * Holds the limit of the number of results to return - * - * @var int - */ - protected $limit = 999999; - - /** - * The offset to start from. - * - * @var int - */ - protected $offset = 0; - - /** - * All the Mongo_Db instances - * - * @var array - */ - protected static $instances = array(); - - /** - * Acts as a Multiton. Will return the requested instance, or will create - * a new one if it does not exist. - * - * @param string $name The instance name - * @return Mongo_Db - * @throws \Mongo_DbException - */ - public static function instance($name = 'default') - { - if (\array_key_exists($name, static::$instances)) - { - return static::$instances[$name]; - } - - if (empty(static::$instances)) - { - \Config::load('db', true); - } - - if ( ! ($config = \Config::get('db.mongo.'.$name))) - { - throw new \Mongo_DbException('Invalid instance name given.'); - } - - static::$instances[$name] = new static($config); - - return static::$instances[$name]; - } - - /** - * The class constructor - * Automatically check if the Mongo PECL extension has been installed/enabled. - * Generate the connection string and establish a connection to the MongoDB. - * - * @param array $config an array of config values - * @throws \Mongo_DbException - */ - public function __construct(array $config = array()) - { - if ( ! class_exists('Mongo')) - { - throw new \Mongo_DbException("The MongoDB PECL extension has not been installed or enabled"); - } - - // Build up a connect options array for mongo - $options = array("connect" => true); - - if ( ! empty($config['persistent'])) - { - $options['persist'] = 'fuel_mongo_persist'; - } - - if ( ! empty($config['replicaset'])) - { - $options['replicaSet'] = $config['replicaset']; - } - - $connection_string = "mongodb://"; - - if (empty($config['hostname'])) - { - throw new \Mongo_DbException("The host must be set to connect to MongoDB"); - } - - if (empty($config['database'])) - { - throw new \Mongo_DbException("The database must be set to connect to MongoDB"); - } - - if ( ! empty($config['username']) and ! empty($config['password'])) - { - $connection_string .= "{$config['username']}:{$config['password']}@"; - } - - if (isset($config['port']) and ! empty($config['port'])) - { - $connection_string .= "{$config['hostname']}:{$config['port']}"; - } - else - { - $connection_string .= "{$config['hostname']}"; - } - - if (\Arr::get($config, 'profiling') === true) - { - $this->profiling = true; - } - - $connection_string .= "/{$config['database']}"; - - // Let's give this a go - try - { - $this->connection = new \MongoClient(trim($connection_string), $options); - $this->db = $this->connection->{$config['database']}; - return $this; - } - catch (\MongoConnectionException $e) - { - throw new \Mongo_DbException("Unable to connect to MongoDB: {$e->getMessage()}", $e->getCode()); - } - } - - /** - * Drop a Mongo database - * - * @param string $database the database name - * @return bool - * @throws \Mongo_DbException - * @usage $mongodb->drop_db("foobar"); - */ - public static function drop_db($database = null) - { - if (empty($database)) - { - throw new \Mongo_DbException('Failed to drop MongoDB database because name is empty'); - } - - else - { - try - { - static::instance()->connection->{$database}->drop(); - return true; - } - catch (\Exception $e) - { - throw new \Mongo_DbException("Unable to drop Mongo database `{$database}`: {$e->getMessage()}", $e->getCode()); - } - - } - } - - /** - * Drop a Mongo collection - * - * @param string $db the database name - * @param string $col the collection name - * @return bool - * @throws \Mongo_DbException - * @usage $mongodb->drop_collection('foo', 'bar'); - */ - public static function drop_collection($db = '', $col = '') - { - if (empty($db)) - { - throw new \Mongo_DbException('Failed to drop MongoDB collection because database name is empty'); - } - - if (empty($col)) - { - throw new \Mongo_DbException('Failed to drop MongoDB collection because collection name is empty'); - } - - else - { - try - { - static::instance($db)->db->{$col}->drop(); - return true; - } - catch (\Exception $e) - { - throw new \Mongo_DbException("Unable to drop Mongo collection `{$col}`: {$e->getMessage()}", $e->getCode()); - } - } - } - - /** - * Determine which fields to include OR which to exclude during the query process. - * Currently, including and excluding at the same time is not available, so the - * $includes array will take precedence over the $excludes array. If you want to - * only choose fields to exclude, leave $includes an empty array(). - * - * @param array $includes which fields to include - * @param array $excludes which fields to exclude - * @return $this - * @usage $mongodb->select(array('foo', 'bar'))->get('foobar'); - */ - public function select($includes = array(), $excludes = array()) - { - if ( ! is_array($includes)) - { - $includes = array($includes); - } - - if ( ! is_array($excludes)) - { - $excludes = array($excludes); - } - - if ( ! empty($includes)) - { - foreach ($includes as $col) - { - $this->selects[$col] = 1; - } - } - else - { - foreach ($excludes as $col) - { - $this->selects[$col] = 0; - } - } - return $this; - } - - /** - * Get the documents based on these search parameters. The $wheres array should - * be an associative array with the field as the key and the value as the search - * criteria. - * - * @param array $wheres an associative array with conditions, array(field => value) - * @return $this - * @usage $mongodb->where(array('foo' => 'bar'))->get('foobar'); - */ - public function where($wheres = array()) - { - foreach ($wheres as $wh => $val) - { - $this->wheres[$wh] = $val; - } - return $this; - } - - /** - * Get the documents where the value of a $field may be something else - * - * @param array $wheres an associative array with conditions, array(field => value) - * @return $this - * @usage $mongodb->or_where(array( array('foo'=>'bar', 'bar'=>'foo' ))->get('foobar'); - */ - public function or_where($wheres = array()) - { - if (count($wheres) > 0) - { - if ( ! isset($this->wheres['$or']) or ! is_array($this->wheres['$or'])) - { - $this->wheres['$or'] = array(); - } - - foreach ($wheres as $wh => $val) - { - $this->wheres['$or'][] = array($wh => $val); - } - } - return $this; - } - - /** - * Get the documents where the value of a $field is in a given $in array(). - * - * @param string $field the field name - * @param array $in an array of values to compare to - * @return $this - * @usage $mongodb->where_in('foo', array('bar', 'zoo', 'blah'))->get('foobar'); - */ - public function where_in($field = '', $in = array()) - { - $this->_where_init($field); - $this->wheres[$field]['$in'] = $in; - return $this; - } - - /** - * Get the documents where the value of a $field is in all of a given $in array(). - * - * @param string $field the field name - * @param array $in an array of values to compare to - * @return $this - * @usage $mongodb->where_in('foo', array('bar', 'zoo', 'blah'))->get('foobar'); - */ - public function where_in_all($field = '', $in = array()) - { - $this->_where_init($field); - $this->wheres[$field]['$all'] = $in; - return $this; - } - - /** - * Get the documents where the value of a $field is not in a given $in array(). - * - * @param string $field the field name - * @param array $in an array of values to compare to - * @return $this - * @usage $mongodb->where_not_in('foo', array('bar', 'zoo', 'blah'))->get('foobar'); - */ - public function where_not_in($field = '', $in = array()) - { - $this->_where_init($field); - $this->wheres[$field]['$nin'] = $in; - return $this; - } - - /** - * Get the documents where the value of a $field is greater than $x - * - * @param string $field the field name - * @param mixed $x the value to compare to - * @return $this - * @usage $mongodb->where_gt('foo', 20); - */ - public function where_gt($field = '', $x) - { - $this->_where_init($field); - $this->wheres[$field]['$gt'] = $x; - return $this; - } - - /** - * Get the documents where the value of a $field is greater than or equal to $x - * - * @param string $field the field name - * @param mixed $x the value to compare to - * @return Mongo_Db - * @usage $mongodb->where_gte('foo', 20); - */ - public function where_gte($field = '', $x) - { - $this->_where_init($field); - $this->wheres[$field]['$gte'] = $x; - return($this); - } - - /** - * Get the documents where the value of a $field is less than $x - * - * @param string $field the field name - * @param mixed $x the value to compare to - * @return Mongo_Db - * @usage $mongodb->where_lt('foo', 20); - */ - public function where_lt($field = '', $x) - { - $this->_where_init($field); - $this->wheres[$field]['$lt'] = $x; - return($this); - } - - /** - * Get the documents where the value of a $field is less than or equal to $x - * - * @param string $field the field name - * @param mixed $x the value to compare to - * @return $this - * @usage $mongodb->where_lte('foo', 20); - */ - public function where_lte($field = '', $x) - { - $this->_where_init($field); - $this->wheres[$field]['$lte'] = $x; - return $this; - } - - /** - * Get the documents where the value of a $field is between $x and $y - * - * @param string $field the field name - * @param mixed $x the value to compare to - * @param mixed $y the high value to compare to - * @return $this - * @usage $mongodb->where_between('foo', 20, 30); - */ - public function where_between($field = '', $x, $y) - { - $this->_where_init($field); - $this->wheres[$field]['$gte'] = $x; - $this->wheres[$field]['$lte'] = $y; - return $this; - } - - /** - * Get the documents where the value of a $field is between but not equal to $x and $y - * - * @param string $field the field name - * @param mixed $x the low value to compare to - * @param mixed $y the high value to compare to - * @return $this - * @usage $mongodb->where_between_ne('foo', 20, 30); - */ - public function where_between_ne($field = '', $x, $y) - { - $this->_where_init($field); - $this->wheres[$field]['$gt'] = $x; - $this->wheres[$field]['$lt'] = $y; - return $this; - } - - /** - * Get the documents where the value of a $field is not equal to $x - * - * @param string $field the field name - * @param mixed $x the value to compare to - * @return $this - * @usage $mongodb->where_not_equal('foo', 1)->get('foobar'); - */ - public function where_ne($field = '', $x) - { - $this->_where_init($field); - $this->wheres[$field]['$ne'] = $x; - return $this; - } - - /** - * Get the documents nearest to an array of coordinates (your collection must have a geospatial index) - * - * @param string $field the field name - * @param array $co array of 2 coordinates - * @return $this - * @usage $mongodb->where_near('foo', array('50','50'))->get('foobar'); - */ - public function where_near($field = '', $co = array()) - { - $this->_where_init($field); - $this->where[$field]['$near'] = $co; - return $this; - } - - /** - * -------------------------------------------------------------------------------- - * LIKE PARAMETERS - * -------------------------------------------------------------------------------- - * - * Get the documents where the (string) value of a $field is like a value. The defaults - * allow for a case-insensitive search. - * - * @param string $field - * @param string $value - * @param string $flags - * Allows for the typical regular expression flags: - * i = case insensitive - * m = multiline - * x = can contain comments - * l = locale - * s = dotall, "." matches everything, including newlines - * u = match unicode - * - * @param bool $disable_start_wildcard - * If this value evaluates to false, no starting line character "^" will be prepended - * to the search value, representing only searching for a value at the start of - * a new line. - * - * @param bool $disable_end_wildcard - * If this value evaluates to false, no ending line character "$" will be appended - * to the search value, representing only searching for a value at the end of - * a line. - * - * @return $this - * @usage $mongodb->like('foo', 'bar', 'im', false, true); - */ - public function like($field = '', $value = '', $flags = 'i', $disable_start_wildcard = false, $disable_end_wildcard = false) - { - $field = (string) trim($field); - $this->_where_init($field); - - $value = (string) trim($value); - $value = quotemeta($value); - - (bool) $disable_start_wildcard === false and $value = '^'.$value; - (bool) $disable_end_wildcard === false and $value .= '$'; - - $regex = "/$value/$flags"; - $this->wheres[$field] = new \MongoRegex($regex); - - return $this; - } - - /** - * Sort the documents based on the parameters passed. To set values to descending order, - * you must pass values of either -1, false, 'desc', or 'DESC', else they will be - * set to 1 (ASC). - * - * @param array $fields an associative array, array(field => direction) - * @return $this - * @usage $mongodb->where_between('foo', 20, 30); - */ - public function order_by($fields = array()) - { - foreach ($fields as $col => $val) - { - if ($val == -1 or $val === false or strtolower($val) == 'desc') - { - $this->sorts[$col] = -1; - } - else - { - $this->sorts[$col] = 1; - } - } - return $this; - } - - /** - * Limit the result set to $x number of documents - * - * @param integer $x the max amount of documents to fetch - * @return $this - * @usage $mongodb->limit($x); - */ - public function limit($x = 99999) - { - if ($x !== null and is_numeric($x) and $x >= 1) - { - $this->limit = (int) $x; - } - return $this; - } - - /** - * -------------------------------------------------------------------------------- - * OFFSET DOCUMENTS - * -------------------------------------------------------------------------------- - * - * Offset the result set to skip $x number of documents - * - * @param integer $x the number of documents to skip - * @return $this - * @usage $mongodb->offset($x); - */ - public function offset($x = 0) - { - if ($x !== null and is_numeric($x) and $x >= 1) - { - $this->offset = (int) $x; - } - return $this; - } - - /** - * Get the documents based upon the passed parameters - * - * @param string $collection the collection name - * @param array $where an array of conditions, array(field => value) - * @param integer $limit the max amount of documents to fetch - * @return array - * @usage $mongodb->get_where('foo', array('bar' => 'something')); - */ - public function get_where($collection = '', $where = array(), $limit = 99999) - { - return ($this->where($where)->limit($limit)->get($collection)); - } - - /** - * Get the document cursor from mongodb based upon the passed parameters - * - * @param string $collection the collection name - * @usage $mongodb->get_cursor('foo', array('bar' => 'something')); - * @throws \Mongo_DbException - */ - public function get_cursor($collection = "") - { - if (empty($collection)) - { - throw new \Mongo_DbException("In order to retrieve documents from MongoDB you must provide a collection name."); - } - - $documents = $this->db->{$collection}->find($this->wheres, $this->selects)->limit((int) $this->limit)->skip((int) $this->offset)->sort($this->sorts); - - $this->_clear(); - - return $documents; - } - - /** - * Get the documents based upon the passed parameters - * - * @param string $collection the collection name - * @usage $mongodb->get('foo', array('bar' => 'something')); - * @return array - * @throws \Mongo_DbException - */ - public function get($collection = "") - { - if ($this->profiling) - { - $query = json_encode(array( - 'type' => 'find', - 'collection' => $collection, - 'select' => $this->selects, - 'where' => $this->wheres, - 'limit' => $this->limit, - 'offset' => $this->offset, - 'sort' => $this->sorts, - )); - - $benchmark = \Profiler::start((string) $this->db, $query); - } - - $documents = $this->get_cursor($collection); - - if (isset($benchmark)) - { - \Profiler::stop($benchmark); - } - - $returns = array(); - - if ($documents and ! empty($documents)) - { - foreach ($documents as $doc) - { - $returns[] = $doc; - } - } - - return $returns; - } - - /** - * Get one document based upon the passed parameters - * - * @param string $collection the collection name - * @return mixed - * @throws \Mongo_DbException - * @usage $mongodb->get_one('foo'); - */ - public function get_one($collection = "") - { - if (empty($collection)) - { - throw new \Mongo_DbException("In order to retrieve documents from MongoDB you must provide a collection name."); - } - - if ($this->profiling) - { - $query = json_encode(array( - 'type' => 'findOne', - 'collection' => $collection, - 'select' => $this->selects, - 'where' => $this->wheres, - )); - - $benchmark = \Profiler::start((string) $this->db, $query); - } - - $returns = $this->db->{$collection}->findOne($this->wheres, $this->selects); - - if (isset($benchmark)) - { - \Profiler::stop($benchmark); - } - - $this->_clear(); - - return $returns; - } - - /** - * Count the documents based upon the passed parameters - * - * @param string $collection the collection name - * @param boolean $foundonly send cursor limit and skip information to the count function, if applicable. - * @return mixed - * @throws \Mongo_DbException - * @usage $mongodb->count('foo'); - */ - public function count($collection = '', $foundonly = false) - { - if (empty($collection)) - { - throw new \Mongo_DbException("In order to retrieve a count of documents from MongoDB you must provide a collection name."); - } - - if ($this->profiling) - { - $query = json_encode(array( - 'type' => 'count', - 'collection' => $collection, - 'where' => $this->wheres, - 'limit' => $this->limit, - 'offset' => $this->offset, - )); - - $benchmark = \Profiler::start((string) $this->db, $query); - } - - $count = $this->db->{$collection}->find($this->wheres)->limit((int) $this->limit)->skip((int) $this->offset)->count($foundonly); - - if (isset($benchmark)) - { - \Profiler::stop($benchmark); - } - - $this->_clear(); - return ($count); - } - - /** - * -------------------------------------------------------------------------------- - * INSERT - * -------------------------------------------------------------------------------- - * - * Insert a new document into the passed collection - * - * @param string $collection the collection name - * @param array $insert an array of values to insert, array(field => value) - * @return bool - * @throws \Mongo_DbException - * @usage $mongodb->insert('foo', $data = array()); - */ - public function insert($collection = '', $insert = array()) - { - if (empty($collection)) - { - throw new \Mongo_DbException("No Mongo collection selected to insert"); - } - - if (empty($insert) or ! is_array($insert)) - { - throw new \Mongo_DbException("Nothing to insert into Mongo collection or insert value is not an array"); - } - - try - { - if ($this->profiling) - { - $query = json_encode(array( - 'type' => 'insert', - 'collection' => $collection, - 'payload' => $insert, - )); - - $benchmark = \Profiler::start((string) $this->db, $query); - } - - $this->db->{$collection}->insert($insert, array('fsync' => true)); - - if (isset($benchmark)) - { - \Profiler::stop($benchmark); - } - - if (isset($insert['_id'])) - { - return $insert['_id']; - } - else - { - return false; - } - } - catch (\MongoCursorException $e) - { - throw new \Mongo_DbException("Insert of data into MongoDB failed: {$e->getMessage()}", $e->getCode()); - } - } - - /** - * Updates a single document - * - * @param string $collection the collection name - * @param array $data an associative array of values, array(field => value) - * @param array $options an associative array of options - * @param bool $literal - * @return bool - * @throws \Mongo_DbException - * @usage $mongodb->update('foo', $data = array()); - */ - public function update($collection = '', $data = array(), $options = array(), $literal = false) - { - if (empty($collection)) - { - throw new \Mongo_DbException("No Mongo collection selected to update"); - } - - if (empty($data) or ! is_array($data)) - { - throw new \Mongo_DbException("Nothing to update in Mongo collection or update value is not an array"); - } - - try - { - $options = array_merge($options, array('fsync' => true, 'multiple' => false)); - - if ($this->profiling) - { - $query = json_encode(array( - 'type' => 'update', - 'collection' => $collection, - 'where' => $this->wheres, - 'payload' => $data, - 'options' => $options, - )); - - $benchmark = \Profiler::start((string) $this->db, $query); - } - - $this->db->{$collection}->update($this->wheres, (($literal) ? $data : array('$set' => $data)), $options); - - if (isset($benchmark)) - { - \Profiler::stop($benchmark); - } - - $this->_clear(); - return true; - } - catch (\MongoCursorException $e) - { - throw new \Mongo_DbException("Update of data into MongoDB failed: {$e->getMessage()}", $e->getCode()); - } - } - - /** - * Updates a collection of documents - * - * @param string $collection the collection name - * @param array $data an associative array of values, array(field => value) - * @param bool $literal - * @return bool - * @throws \Mongo_DbException - * @usage $mongodb->update_all('foo', $data = array()); - */ - public function update_all($collection = "", $data = array(), $literal = false) - { - if (empty($collection)) - { - throw new \Mongo_DbException("No Mongo collection selected to update"); - } - - if (empty($data) or ! is_array($data)) - { - throw new \Mongo_DbException("Nothing to update in Mongo collection or update value is not an array"); - } - - try - { - if ($this->profiling) - { - $query = json_encode(array( - 'type' => 'updateAll', - 'collection' => $collection, - 'where' => $this->wheres, - 'payload' => $data, - 'literal' => $literal, - )); - - $benchmark = \Profiler::start((string) $this->db, $query); - } - - $this->db->{$collection}->update($this->wheres, (($literal) ? $data : array('$set' => $data)), array('fsync' => true, 'multiple' => true)); - - if (isset($benchmark)) - { - \Profiler::stop($benchmark); - } - - $this->_clear(); - return true; - } - catch (\MongoCursorException $e) - { - throw new \Mongo_DbException("Update of data into MongoDB failed: {$e->getMessage()}", $e->getCode()); - } - } - - /** - * Delete a document from the passed collection based upon certain criteria - * - * @param string $collection the collection name - * @return bool - * @throws \Mongo_DbException - * @usage $mongodb->delete('foo'); - */ - public function delete($collection = '') - { - if (empty($collection)) - { - throw new \Mongo_DbException("No Mongo collection selected to delete from"); - } - - try - { - if ($this->profiling) - { - $query = json_encode(array( - 'type' => 'delete', - 'collection' => $collection, - 'where' => $this->wheres, - )); - - $benchmark = \Profiler::start((string) $this->db, $query); - } - - $this->db->{$collection}->remove($this->wheres, array('fsync' => true, 'justOne' => true)); - - if (isset($benchmark)) - { - \Profiler::stop($benchmark); - } - - $this->_clear(); - return true; - } - catch (\MongoCursorException $e) - { - throw new \Mongo_DbException("Delete of data into MongoDB failed: {$e->getMessage()}", $e->getCode()); - } - } - - /** - * Delete all documents from the passed collection based upon certain criteria. - * - * @param string $collection the collection name - * @return bool - * @throws \Mongo_DbException - * @usage $mongodb->delete_all('foo'); - */ - public function delete_all($collection = '') - { - if (empty($collection)) - { - throw new \Mongo_DbException("No Mongo collection selected to delete from"); - } - - try - { - if ($this->profiling) - { - $query = json_encode(array( - 'type' => 'deleteAll', - 'collection' => $collection, - 'where' => $this->wheres, - )); - - $benchmark = \Profiler::start((string) $this->db, $query); - } - - $this->db->{$collection}->remove($this->wheres, array('fsync' => true, 'justOne' => false)); - - if (isset($benchmark)) - { - \Profiler::stop($benchmark); - } - - $this->_clear(); - return true; - } - catch (\MongoCursorException $e) - { - throw new \Mongo_DbException("Delete of data from MongoDB failed: {$e->getMessage()}", $e->getCode()); - } - } - - /** - * Runs a MongoDB command (such as GeoNear). See the MongoDB documentation for more usage scenarios: - * http://dochub.mongodb.org/core/commands - * - * @param array $query a query array - * @return mixed - * @throws \Mongo_DbException - * @usage $mongodb->command(array('geoNear'=>'buildings', 'near'=>array(53.228482, -0.547847), 'num' => 10, 'nearSphere'=>TRUE)); - */ - public function command($query = array()) - { - try - { - $run = $this->db->command($query); - return $run; - } - - catch (\MongoCursorException $e) - { - throw new \Mongo_DbException("MongoDB command failed to execute: {$e->getMessage()}", $e->getCode()); - } - } - - /** - * Ensure an index of the keys in a collection with optional parameters. To set values to descending order, - * you must pass values of either -1, false, 'desc', or 'DESC', else they will be - * set to 1 (ASC). - * - * @param string $collection the collection name - * @param array $keys an associative array of keys, array(field => direction) - * @param array $options an associative array of options - * @return $this - * @throws \Mongo_DbException - * @usage $mongodb->add_index($collection, array('first_name' => 'ASC', 'last_name' => -1), array('unique' => TRUE)); - */ - public function add_index($collection = '', $keys = array(), $options = array()) - { - if (empty($collection)) - { - throw new \Mongo_DbException("No Mongo collection specified to add an index to"); - } - - if (empty($keys) or ! is_array($keys)) - { - throw new \Mongo_DbException("Index could not be created to MongoDB Collection because no keys were specified"); - } - - foreach ($keys as $col => $val) - { - if($val == -1 or $val === false or strtolower($val) == 'desc') - { - $keys[$col] = -1; - } - else - { - $keys[$col] = 1; - } - } - - if ($this->db->{$collection}->ensureIndex($keys, $options) == true) - { - $this->_clear(); - return $this; - } - else - { - throw new \Mongo_DbException("An error occurred when trying to add an index to MongoDB Collection"); - } - } - - /** - * Remove an index of the keys in a collection. To set values to descending order, - * you must pass values of either -1, false, 'desc', or 'DESC', else they will be - * set to 1 (ASC). - * - * @param string $collection the collection name - * @param array $keys an associative array of keys, array(field => direction) - * @return $this - * @throws \Mongo_DbException - * @usage $mongodb->remove_index($collection, array('first_name' => 'ASC', 'last_name' => -1)); - */ - public function remove_index($collection = '', $keys = array()) - { - if (empty($collection)) - { - throw new \Mongo_DbException("No Mongo collection specified to remove an index from"); - } - - if (empty($keys) or ! is_array($keys)) - { - throw new \Mongo_DbException("Index could not be removed from MongoDB Collection because no keys were specified"); - } - - if ($this->db->{$collection}->deleteIndex($keys) == true) - { - $this->_clear(); - return $this; - } - else - { - throw new \Mongo_DbException("An error occurred when trying to remove an index from MongoDB Collection"); - } - } - - /** - * Remove all indexes from a collection. - * - * @param string $collection the collection name - * @return $this - * @throws \Mongo_DbException - * @usage $mongodb->remove_all_index($collection); - */ - public function remove_all_indexes($collection = '') - { - if (empty($collection)) - { - throw new \Mongo_DbException("No Mongo collection specified to remove all indexes from"); - } - $this->db->{$collection}->deleteIndexes(); - $this->_clear(); - return $this; - } - - /** - * Lists all indexes in a collection. - * - * @param string $collection the collection name - * @return mixed - * @throws \Mongo_DbException - * @usage $mongodb->list_indexes($collection); - */ - public function list_indexes($collection = '') - { - if (empty($collection)) - { - throw new \Mongo_DbException("No Mongo collection specified to remove all indexes from"); - } - - return ($this->db->{$collection}->getIndexInfo()); - } - - /** - * Returns a collection object so you can perform advanced queries, upserts, pushes and addtosets - * - * @param string $collection the collection name - * @usage $collection_name = $mongodb->get_collection('collection_name'); - */ - public function get_collection($collection) - { - return ($this->db->{$collection}); - } - - /** - * Returns all collection objects - * - * @param bool $system_collections whether or not to include system collections - * @usage $collections = $mongodb->list_collections(); - */ - public function list_collections($system_collections = false) - { - return ($this->db->listCollections($system_collections)); - } - - /** - * Dump database or collection - * - * @param mixed $collection_name The collection name - * @param string $path Path to write the dump do - * - * @usage $mongodb->dump(); - * @usage $mongodb->dump(test, APPPATH . "tmp"); - * @usage $mongodb->dump(["test", "test2"], APPPATH . "tmp"); - * - * @return bool - */ - public function dump($collection_name = null, $path = null) - { - // set the default dump path if none given - if (empty($path)) - { - $path = APPPATH.'tmp'.DS.'mongo-'.date("/Y/m/d"); - } - - // backup full database - if ($collection_name == null) - { - //get all collection in current database - $mongo_collections = $this->list_collections(); - foreach ($mongo_collections as $mongo_collection) - { - $this->_write_dump($path, $mongo_collection); - } - } - // Backup given collection`s - else - { - $collection_name = (array) $collection_name; - foreach ($collection_name as $name) - { - $mongo_collection = $this->get_collection($name); - $this->_write_dump($path, $mongo_collection); - } - } - - return true; - } - - /** - * Collect and write dump - * - * @param string $path - * @param MongoCollection $mongo_collection - */ - protected function _write_dump($path, $mongo_collection) - { - if ( ! is_dir($path)) - { - \Config::load('file', true); - mkdir($path, \Config::get('file.chmod.folders', 0777), true); - } - - $collection_name = $mongo_collection->getName(); - - // get all documents in current collection - $documents = $mongo_collection->find(); - - // collect data - $array_data = iterator_to_array($documents); - $json_data = \Format::forge($array_data)->to_json(); - - return \File::update($path, $collection_name, $json_data); - } - - /** - * Resets the class variables to default settings - */ - protected function _clear() - { - $this->selects = array(); - $this->wheres = array(); - $this->limit = 999999; - $this->offset = 0; - $this->sorts = array(); - } - - /** - * Prepares parameters for insertion in $wheres array(). - * - * @param string $param the field name - */ - protected function _where_init($param) - { - if ( ! isset($this->wheres[$param])) - { - $this->wheres[ $param ] = array(); - } - } -} diff --git a/fuel/core/classes/num.php b/fuel/core/classes/num.php deleted file mode 100755 index d0a29e5..0000000 --- a/fuel/core/classes/num.php +++ /dev/null @@ -1,337 +0,0 @@ - - * echo Num::bytes('200K'); // 204800 - * echo static::bytes('5MiB'); // 5242880 - * echo static::bytes('1000'); // 1000 - * echo static::bytes('2.5GB'); // 2684354560 - * - * - * @author Kohana Team - * @copyright (c) 2009-2011 Kohana Team - * @license http://kohanaframework.org/license - * @param string file size in SB format - * @return float - */ - public static function bytes($size = 0) - { - // Prepare the size - $size = trim((string) $size); - - // Construct an OR list of byte units for the regex - $accepted = implode('|', array_keys(static::$byte_units)); - - // Construct the regex pattern for verifying the size format - $pattern = '/^([0-9]+(?:\.[0-9]+)?)('.$accepted.')?$/Di'; - - // Verify the size format and store the matching parts - if (!preg_match($pattern, $size, $matches)) - { - throw new \Exception('The byte unit size, "'.$size.'", is improperly formatted.'); - } - - // Find the float value of the size - $size = (float) $matches[1]; - - // Find the actual unit, assume B if no unit specified - $unit = \Arr::get($matches, 2, 'B'); - - // Convert the size into bytes - $bytes = $size * pow(2, static::$byte_units[$unit]); - - return $bytes; - } - - /** - * Converts a number of bytes to a human readable number by taking the - * number of that unit that the bytes will go into it. Supports TB value. - * - * Note: Integers in PHP are limited to 32 bits, unless they are on 64 bit - * architectures, then they have 64 bit size. If you need to place the - * larger size then what the PHP integer type will hold, then use a string. - * It will be converted to a double, which should always have 64 bit length. - * - * @param integer - * @param integer - * @return boolean|string - */ - public static function format_bytes($bytes = 0, $decimals = 0) - { - $quant = array( - 'TB' => 1099511627776, // pow( 1024, 4) - 'GB' => 1073741824, // pow( 1024, 3) - 'MB' => 1048576, // pow( 1024, 2) - 'KB' => 1024, // pow( 1024, 1) - 'B ' => 1, // pow( 1024, 0) - ); - - foreach ($quant as $unit => $mag ) - { - if (doubleval($bytes) >= $mag) - { - return sprintf('%01.'.$decimals.'f', ($bytes / $mag)).' '.$unit; - } - } - - return false; - } - - /** - * Converts a number into a more readable human-type number. - * - * Usage: - * - * echo Num::quantity(7000); // 7K - * echo Num::quantity(7500); // 8K - * echo Num::quantity(7500, 1); // 7.5K - * - * - * @param integer - * @param integer - * @return string - */ - public static function quantity($num, $decimals = 0) - { - if ($num >= 1000 && $num < 1000000) - { - return sprintf('%01.'.$decimals.'f', (sprintf('%01.0f', $num) / 1000)).'K'; - } - elseif ($num >= 1000000 && $num < 1000000000) - { - return sprintf('%01.'.$decimals.'f', (sprintf('%01.0f', $num) / 1000000)).'M'; - } - elseif ($num >= 1000000000) - { - return sprintf('%01.'.$decimals.'f', (sprintf('%01.0f', $num) / 1000000000)).'B'; - } - - return $num; - } - - /** - * Formats a number by injecting non-numeric characters in a specified - * format into the string in the positions they appear in the format. - * - * Usage: - * - * echo Num::format('1234567890', '(000) 000-0000'); // (123) 456-7890 - * echo Num::format('1234567890', '000.000.0000'); // 123.456.7890 - * - * - * @link http://snippets.symfony-project.org/snippet/157 - * @param string the string to format - * @param string the format to apply - * @return string - */ - public static function format($string = '', $format = '') - { - if(empty($format) or empty($string)) - { - return $string; - } - - $result = ''; - $fpos = 0; - $spos = 0; - - while ((strlen($format) - 1) >= $fpos) - { - if (ctype_alnum(substr($format, $fpos, 1))) - { - $result .= substr($string, $spos, 1); - $spos++; - } - else - { - $result .= substr($format, $fpos, 1); - } - - $fpos++; - } - - return $result; - } - - /** - * Transforms a number by masking characters in a specified mask format, and - * ignoring characters that should be injected into the string without - * matching a character from the original string (defaults to space). - * - * Usage: - * - * echo Num::mask_string('1234567812345678', '************0000'); ************5678 - * echo Num::mask_string('1234567812345678', '**** **** **** 0000'); // **** **** **** 5678 - * echo Num::mask_string('1234567812345678', '**** - **** - **** - 0000', ' -'); // **** - **** - **** - 5678 - * - * - * @link http://snippets.symfony-project.org/snippet/157 - * @param string the string to transform - * @param string the mask format - * @param string a string (defaults to a single space) containing characters to ignore in the format - * @return string the masked string - */ - public static function mask_string($string = '', $format = '', $ignore = ' ') - { - if(empty($format) or empty($string)) - { - return $string; - } - - $result = ''; - $fpos = 0; - $spos = 0; - - while ((strlen($format) - 1) >= $fpos) - { - if (ctype_alnum(substr($format, $fpos, 1))) - { - $result .= substr($string, $spos, 1); - $spos++; - } - else - { - $result .= substr($format, $fpos, 1); - - if (strpos($ignore, substr($format, $fpos, 1)) === false) - { - ++$spos; - } - } - - ++$fpos; - } - - return $result; - } - - /** - * Formats a phone number. - * - * @link http://snippets.symfony-project.org/snippet/157 - * @param string the unformatted phone number to format - * @param string the format to use, defaults to '(000) 000-0000' - * @return string the formatted string - * @see format - */ - public static function format_phone($string = '', $format = null) - { - is_null($format) and $format = static::$config['formatting']['phone']; - return static::format($string, $format); - } - - /** - * Formats a variable length phone number, using a standard format. - * - * Usage: - * - * echo Num::smart_format_phone('1234567'); // 123-4567 - * echo Num::smart_format_phone('1234567890'); // (123) 456-7890 - * echo Num::smart_format_phone('91234567890'); // 9 (123) 456-7890 - * echo Num::smart_format_phone('123456'); // => 123456 - * - * - * @param string the unformatted phone number to format - * @see format - */ - public static function smart_format_phone($string) - { - $formats = static::$config['formatting']['smart_phone']; - - if(is_array($formats) and isset($formats[strlen($string)])) - { - return static::format($string, $formats[strlen($string)]); - } - - return $string; - } - - /** - * Formats a credit card expiration string. Expects 4-digit string (MMYY). - * - * @param string the unformatted expiration string to format - * @param string the format to use, defaults to '00-00' - * @see format - */ - public static function format_exp($string, $format = null) - { - is_null($format) and $format = static::$config['formatting']['exp']; - return static::format($string, $format); - } - - /** - * Formats (masks) a credit card. - * - * @param string the unformatted credit card number to format - * @param string the format to use, defaults to '**** **** **** 0000' - * @see mask_string - */ - public static function mask_credit_card($string, $format = null) - { - is_null($format) and $format = static::$config['formatting']['credit_card']; - return static::mask_string($string, $format); - } -} - -/* End of file num.php */ diff --git a/fuel/core/classes/package.php b/fuel/core/classes/package.php deleted file mode 100755 index 699b587..0000000 --- a/fuel/core/classes/package.php +++ /dev/null @@ -1,157 +0,0 @@ - $path) - { - if (is_numeric($pkg)) - { - $pkg = $path; - $path = null; - } - $result = $result and static::load($pkg, $path); - } - return $result; - } - - if (static::loaded($package)) - { - return false; - } - - // if no path is given, try to locate the package - if ($path === null) - { - $paths = \Config::get('package_paths', array()); - empty($paths) and $paths = array(PKGPATH); - - if ( ! empty($paths)) - { - foreach ($paths as $modpath) - { - if (is_dir($path = $modpath.strtolower($package).DS)) - { - break; - } - } - } - - } - - if ( ! is_dir($path)) - { - throw new \PackageNotFoundException("Package '$package' could not be found at '".\Fuel::clean_path($path)."'"); - } - - \Finder::instance()->add_path($path, 1); - \Fuel::load($path.'bootstrap.php'); - static::$packages[$package] = $path; - - return true; - } - - /** - * Unloads a package from the stack. - * - * @param string $package The package name - * @return void - */ - public static function unload($package) - { - \Finder::instance()->remove_path(static::$packages[$package]); - unset(static::$packages[$package]); - } - - /** - * Checks if the given package is loaded, if no package is given then - * all loaded packages are returned. - * - * @param string|null $package The package name or null - * @return bool|array Whether the package is loaded, or all packages - */ - public static function loaded($package = null) - { - if ($package === null) - { - return static::$packages; - } - - return array_key_exists($package, static::$packages); - } - - /** - * Checks if the given package exists. - * - * @param string $package The package name - * @return bool|string Path to the package found, or false if not found - */ - public static function exists($package) - { - if (array_key_exists($package, static::$packages)) - { - return static::$packages[$package]; - } - else - { - $paths = \Config::get('package_paths', array()); - empty($paths) and $paths = array(PKGPATH); - $package = strtolower($package); - - foreach ($paths as $path) - { - if (is_dir($path.$package)) - { - return $path.$package.DS; - } - } - } - - return false; - } -} diff --git a/fuel/core/classes/pagination.php b/fuel/core/classes/pagination.php deleted file mode 100755 index eb1a75c..0000000 --- a/fuel/core/classes/pagination.php +++ /dev/null @@ -1,707 +0,0 @@ - '__get', - 'set' => '__set', - 'set_config' => '__set', - 'create_links' => 'render', - 'page_links' => 'pages_render', - 'prev_link' => 'previous', - 'next_link' => 'next', - ); - - array_key_exists($name, $mapping) and $name = $mapping[$name]; - - // call the method on the default instance - if ($instance = static::instance() and method_exists($instance, $name)) - { - return call_fuel_func_array(array($instance, $name), $arguments); - } - - throw new \BadMethodCallException('The pagination class doesn\'t have a method called "'.$name.'"'); - } - - /** - * forge a new pagination instance - * - * @param string $name - * @param array $config - * @return \Pagination a new pagination instance - */ - public static function forge($name = 'default', $config = array()) - { - if ($exists = static::instance($name)) - { - \Errorhandler::notice('Pagination with this name exists already, cannot be overwritten.'); - return $exists; - } - - static::$_instances[$name] = new static($config); - - if ($name == 'default') - { - static::$_instance = static::$_instances[$name]; - } - - return static::$_instances[$name]; - } - - /** - * retrieve an existing pagination instance - * - * @param string $name - * @return \Pagination a existing pagination instance - */ - public static function instance($name = null) - { - if ($name !== null) - { - if ( ! array_key_exists($name, static::$_instances)) - { - return false; - } - - return static::$_instances[$name]; - } - - if (static::$_instance === null) - { - static::$_instance = static::forge(); - } - - return static::$_instance; - } - - // -------------------------------------------------------------------- - - /** - * instance configuration values - */ - protected $config = array( - 'current_page' => null, - 'offset' => 0, - 'per_page' => 10, - 'total_pages' => 0, - 'total_items' => 0, - 'num_links' => 5, - 'uri_segment' => 3, - 'show_first' => false, - 'show_last' => false, - 'pagination_url' => null, - 'link_offset' => 0.5, - ); - - /** - * instance template values - */ - protected $template = array( - 'wrapper' => "
\n\t{pagination}\n
\n", - 'first' => "\n\t{link}\n\n", - 'first-marker' => "««", - 'first-link' => "\t\t{page}\n", - 'first-inactive' => "", - 'first-inactive-link' => "", - 'previous' => "\n\t{link}\n\n", - 'previous-marker' => "«", - 'previous-link' => "\t\t{page}\n", - 'previous-inactive' => "\n\t{link}\n\n", - 'previous-inactive-link' => "\t\t{page}\n", - 'regular' => "\n\t{link}\n\n", - 'regular-link' => "\t\t{page}\n", - 'active' => "\n\t{link}\n\n", - 'active-link' => "\t\t{page}\n", - 'next' => "\n\t{link}\n\n", - 'next-marker' => "»", - 'next-link' => "\t\t{page}\n", - 'next-inactive' => "\n\t{link}\n\n", - 'next-inactive-link' => "\t\t{page}\n", - 'last' => "\n\t{link}\n\n", - 'last-marker' => "»»", - 'last-link' => "\t\t{page}\n", - 'last-inactive' => "", - 'last-inactive-link' => "", - ); - - /** - * raw pagination results - */ - protected $raw_results = array(); - - /** - * @param array $config - */ - public function __construct($config = array()) - { - // make sure config is an array - is_array($config) or $config = array('name' => $config); - - // and we have a template name - array_key_exists('name', $config) or $config['name'] = \Config::get('pagination.active', 'default'); - - // merge the config passed with the defined configuration - $config = array_merge(\Config::get('pagination.'.$config['name'], array()), $config); - - // don't need the template name anymore - unset($config['name']); - - // update the instance default config with the data passed - foreach ($config as $key => $value) - { - $this->__set($key, $value); - } - } - - /** - * configuration value getter - * @param $name - * @return mixed - */ - public function __get($name) - { - // use the calculated page if no current_page is passed - if ($name === 'current_page' and $this->config[$name] === null) - { - $name = 'calculated_page'; - } - - if (array_key_exists($name, $this->config)) - { - return $this->config[$name]; - } - elseif (array_key_exists($name, $this->template)) - { - return $this->template[$name]; - } - else - { - return null; - } - } - - /** - * configuration value setter - * - * @param $name - * @param mixed $value - */ - public function __set($name, $value = null) - { - if (is_array($name)) - { - foreach($name as $key => $value) - { - $this->__set($key, $value); - } - } - else - { - $value = $this->_validate($name, $value); - - if (array_key_exists($name, $this->config)) - { - $this->config[$name] = $value; - } - elseif (array_key_exists($name, $this->template)) - { - $this->template[$name] = $value; - } - } - - // update the page counters - $this->_recalculate(); - } - - /** - * Render the pagination when the object is cast to string - */ - public function __toString() - { - return $this->render(); - } - - /** - * Creates the pagination markup - * - * @param mixed $raw - * @return mixed HTML Markup for page number links, or an array of raw pagination data - */ - public function render($raw = false) - { - // no links if we only have one page - if ($this->config['total_pages'] == 1) - { - return $raw ? array() : ''; - } - - $this->raw_results = array(); - - $html = str_replace( - '{pagination}', - $this->first().$this->previous().$this->pages_render().$this->next().$this->last(), - $this->template['wrapper'] - ); - - return $raw ? $this->raw_results : $html; - } - - /** - * generate the HTML for the page links only - * - * @return string Markup for the pagination block - */ - public function pages_render() - { - // no links if we only have one page - if ($this->config['total_pages'] == 1) - { - return ''; - } - - $html = ''; - - // calculate start- and end page numbers - $start = $this->config['calculated_page'] - floor($this->config['num_links'] * $this->config['link_offset']); - $end = $this->config['calculated_page'] + floor($this->config['num_links'] * ( 1 - $this->config['link_offset'])); - - // adjust for the first few pages - if ($start < 1) - { - $end -= $start - 1; - $start = 1; - } - - // make sure we don't overshoot the current page due to rounding issues - if ($end < $this->config['calculated_page']) - { - $start++; - $end++; - } - - // make sure we don't overshoot the total - if ($end > $this->config['total_pages']) - { - $start = max(1, $start - $end + $this->config['total_pages']); - $end = $this->config['total_pages']; - } - - for($i = intval($start); $i <= intval($end); $i++) - { - if ($this->config['calculated_page'] == $i) - { - $html .= str_replace( - '{link}', - str_replace(array('{uri}', '{page}'), array('#', $i), $this->template['active-link']), - $this->template['active'] - ); - $this->raw_results[] = array('uri' => '#', 'title' => $i, 'type' => 'active'); - } - else - { - $html .= str_replace( - '{link}', - str_replace(array('{uri}', '{page}'), array($this->_make_link($i), $i), $this->template['regular-link']), - $this->template['regular'] - ); - $this->raw_results[] = array('uri' => $this->_make_link($i), 'title' => $i, 'type' => 'regular'); - } - } - - return $html; - } - - /** - * Pagination "First" link - * - * @param string $marker optional text to display in the link - * @return string Markup for the 'first' page number link - */ - public function first($marker = null) - { - $html = ''; - - $marker === null and $marker = $this->template['first-marker']; - - if ($this->config['show_first']) - { - if ($this->config['total_pages'] > 1 and $this->config['calculated_page'] > 1) - { - $html = str_replace( - '{link}', - str_replace(array('{uri}', '{page}'), array($this->_make_link(1), $marker), $this->template['first-link']), - $this->template['first'] - ); - $this->raw_results['first'] = array('uri' => $this->_make_link(1), 'title' => $marker, 'type' => 'first'); - } - else - { - $html = str_replace( - '{link}', - str_replace(array('{uri}', '{page}'), array('#', $marker), $this->template['first-inactive-link']), - $this->template['first-inactive'] - ); - $this->raw_results['first'] = array('uri' => '#', 'title' => $marker, 'type' => 'first-inactive'); - } - } - - return $html; - } - - /** - * Pagination "Previous" link - * - * @param string $marker optional text to display in the link - * @return string Markup for the 'previous' page number link - */ - public function previous($marker = null) - { - $html = ''; - - $marker === null and $marker = $this->template['previous-marker']; - - if ($this->config['total_pages'] > 1) - { - if ($this->config['calculated_page'] == 1) - { - $html = str_replace( - '{link}', - str_replace(array('{uri}', '{page}'), array('#', $marker), $this->template['previous-inactive-link']), - $this->template['previous-inactive'] - ); - $this->raw_results['previous'] = array('uri' => '#', 'title' => $marker, 'type' => 'previous-inactive'); - } - else - { - $previous_page = $this->config['calculated_page'] - 1; - $previous_page = ($previous_page == 1) ? '' : $previous_page; - - $html = str_replace( - '{link}', - str_replace(array('{uri}', '{page}'), array($this->_make_link($previous_page), $marker), $this->template['previous-link']), - $this->template['previous'] - ); - $this->raw_results['previous'] = array('uri' => $this->_make_link($previous_page), 'title' => $marker, 'type' => 'previous'); - } - } - - return $html; - } - - /** - * Pagination "Next" link - * - * @param string $marker optional text to display in the link - * @return string Markup for the 'next' page number link - */ - public function next($marker = null) - { - $html = ''; - - $marker === null and $marker = $this->template['next-marker']; - - if ($this->config['total_pages'] > 1) - { - if ($this->config['calculated_page'] == $this->config['total_pages']) - { - $html = str_replace( - '{link}', - str_replace(array('{uri}', '{page}'), array('#', $marker), $this->template['next-inactive-link']), - $this->template['next-inactive'] - ); - $this->raw_results['next'] = array('uri' => '#', 'title' => $marker, 'type' => 'next-inactive'); - } - else - { - $next_page = $this->config['calculated_page'] + 1; - - $html = str_replace( - '{link}', - str_replace(array('{uri}', '{page}'), array($this->_make_link($next_page), $marker), $this->template['next-link']), - $this->template['next'] - ); - $this->raw_results['next'] = array('uri' => $this->_make_link($next_page), 'title' => $marker, 'type' => 'next'); - } - } - - return $html; - } - - /** - * Pagination "Last" link - * - * @param string $marker optional text to display in the link - * @return string Markup for the 'last' page number link - */ - public function last($marker = null) - { - $html = ''; - - $marker === null and $marker = $this->template['last-marker']; - - if ($this->config['show_last']) - { - if ($this->config['total_pages'] > 1 and $this->config['calculated_page'] != $this->config['total_pages']) - { - $html = str_replace( - '{link}', - str_replace(array('{uri}', '{page}'), array($this->_make_link($this->config['total_pages']), $marker), $this->template['last-link']), - $this->template['last'] - ); - $this->raw_results['last'] = array('uri' => $this->_make_link($this->config['total_pages']), 'title' => $marker, 'type' => 'last'); - } - else - { - $html = str_replace( - '{link}', - str_replace(array('{uri}', '{page}'), array('#', $marker), $this->template['last-inactive-link']), - $this->template['last-inactive'] - ); - $this->raw_results['last'] = array('uri' => '#', 'title' => $marker, 'type' => 'last-inactive'); - } - } - - return $html; - } - - /** - * Prepares vars for creating links - */ - protected function _recalculate() - { - // get the current page number, either from the one set, or from the URI or the query string - if ($this->config['current_page']) - { - $this->config['calculated_page'] = $this->config['current_page']; - } - else - { - if (is_string($this->config['uri_segment'])) - { - $this->config['calculated_page'] = \Input::get($this->config['uri_segment'], 1); - } - else - { - $this->config['calculated_page'] = (int) \Request::main()->uri->get_segment($this->config['uri_segment'], 1); - } - } - - // do we have the total number of items? - if ($this->config['total_items'] > 0) - { - // calculate the number of pages - $this->config['total_pages'] = (int) ceil($this->config['total_items'] / $this->config['per_page']) ?: 1; - - // make sure the current page is within bounds - if ($this->config['calculated_page'] > $this->config['total_pages']) - { - $this->config['calculated_page'] = $this->config['total_pages']; - } - elseif ($this->config['calculated_page'] < 1) - { - $this->config['calculated_page'] = 1; - } - } - - // the current page must be zero based so that the offset for page 1 is 0. - $this->config['offset'] = ($this->config['calculated_page'] - 1) * $this->config['per_page']; - } - - /** - * Generate a pagination link - */ - protected function _make_link($page) - { - // make sure we have a valid page number - empty($page) and $page = 1; - - // construct a pagination url if we don't have one - if (is_null($this->config['pagination_url'])) - { - // start with the main uri - $this->config['pagination_url'] = \Uri::main(); - \Input::get() and $this->config['pagination_url'] .= '?'.http_build_query(\Input::get()); - } - - // was a placeholder defined in the url? - if (strpos($this->config['pagination_url'], '{page}') === false) - { - // break the url in bits so we can insert it - $url = parse_url($this->config['pagination_url']); - - // parse the query string - if (isset($url['query'])) - { - parse_str($url['query'], $url['query']); - } - else - { - $url['query'] = array(); - } - - // make sure we don't destroy any fragments - if (isset($url['fragment'])) - { - $url['fragment'] = '#'.$url['fragment']; - } - - // do we have a segment offset due to the base_url containing segments? - $seg_offset = parse_url(rtrim(\Uri::base(), '/')); - $seg_offset = empty($seg_offset['path']) ? 0 : count(explode('/', trim($seg_offset['path'], '/'))); - - // is the page number a URI segment? - if (is_numeric($this->config['uri_segment'])) - { - // get the URL segments - $segs = isset($url['path']) ? explode('/', trim($url['path'], '/')) : array(); - - // do we have enough segments to insert? we can't fill in any blanks... - if (count($segs) < $this->config['uri_segment'] - 1) - { - throw new \RuntimeException("Not enough segments in the URI, impossible to insert the page number"); - } - - // replace the selected segment with the page placeholder - $segs[$this->config['uri_segment'] - 1 + $seg_offset] = '{page}'; - $url['path'] = '/'.implode('/', $segs); - } - else - { - // add our placeholder - $url['query'][$this->config['uri_segment']] = '{page}'; - } - - // re-assemble the url - $query = empty($url['query']) ? '' : '?'.preg_replace('/%7Bpage%7D/', '{page}', http_build_query($url['query'], '', '&')); - unset($url['query']); - empty($url['scheme']) or $url['scheme'] .= '://'; - empty($url['port']) or $url['host'] .= ':'; - $this->config['pagination_url'] = implode($url).$query; - } - - // return the page link - return str_replace('{page}', $page, $this->config['pagination_url']); - } - - /** - * Validate the input configuration - * - * @param $name - * @param $value - * @return int|mixed - */ - protected function _validate($name, $value) - { - switch ($name) - { - case 'offset': - case 'total_items': - // make sure it's an integer - if ($value != intval($value)) - { - $value = 0; - } - // and that it's within bounds - $value = max(0, $value); - break; - - // integer or string - case 'uri_segment': - if (is_numeric($value)) - { - // make sure it's an integer - if ($value != intval($value)) - { - $value = 1; - } - // and that it's within bounds - $value = max(1, $value); - } - break; - - // validate integer values - case 'current_page': - case 'per_page': - case 'limit': - case 'total_pages': - case 'num_links': - // make sure it's an integer - if ($value != intval($value)) - { - $value = 1; - } - // and that it's within bounds - $value = max(1, $value); - break; - - // validate booleans - case 'show_first': - case 'show_last': - if ( ! is_bool($value)) - { - $value = (bool) $value; - } - break; - - // validate the link offset, and adjust if needed - case 'link_offset': - // make sure we have a fraction between 0 and 1 - if ($value > 1) - { - $value = $value / 100; - } - - // and that it's within bounds - $value = max(0.01, min($value, 0.99)); - break; - } - - return $value; - } -} diff --git a/fuel/core/classes/presenter.php b/fuel/core/classes/presenter.php deleted file mode 100755 index cec74b0..0000000 --- a/fuel/core/classes/presenter.php +++ /dev/null @@ -1,350 +0,0 @@ -module) : ''; - - // create the list of possible class prefixes - $prefixes = array(static::$ns_prefix, $namespace.'\\'); - - /** - * Add non prefixed classnames to the list as well, for BC reasons - * - * @deprecated 1.6 - */ - if ( ! empty($namespace)) - { - array_unshift($prefixes, $namespace.'\\'.static::$ns_prefix); - $prefixes[] = ''; - } - - // loading from a specific namespace? - if (strpos($presenter, '::') !== false) - { - $split = explode('::', $presenter, 2); - if (isset($split[1])) - { - array_unshift($prefixes, ucfirst($split[0]).'\\'.static::$ns_prefix); - $presenter = $split[1]; - } - } - - // if no custom view is given, make it equal to the presenter name - is_null($view) and $view = $presenter; - - // strip any extensions from the view name to determine the presenter to load - $presenter = \Inflector::words_to_upper(str_replace( - array('/', DS), - '_', - strpos($presenter, '.') === false ? $presenter : substr($presenter, 0, -strlen(strrchr($presenter, '.'))) - )); - - // create the list of possible presenter classnames, start with the namespaced one - $classes = array(); - foreach ($prefixes as $prefix) - { - $classes[] = $prefix.$presenter; - } - - // check if we can find one - foreach ($classes as $class) - { - if (class_exists($class)) - { - return new $class($method, $auto_filter, $view); - } - } - - throw new \OutOfBoundsException('Presenter "'.reset($classes).'" could not be found.'); - } - - /** - * @var string method to execute when rendering - */ - protected $_method; - - /** - * @var string|View view name, after instantiation a View object - */ - protected $_view; - - /** - * @var bool whether or not to use auto filtering - */ - protected $_auto_filter; - - /** - * @var Request active request during Presenter creation for proper context - */ - protected $_active_request; - - protected function __construct($method, $auto_filter = null, $view = null) - { - $this->_auto_filter = $auto_filter; - $this->_view === null and $this->_view = $view; - class_exists('Request', false) and $this->_active_request = \Request::active(); - - if (empty($this->_view)) - { - // Take the class name and guess the view name - $class = get_class($this); - $this->_view = strtolower(str_replace('_', DS, preg_replace('#^([a-z0-9_]*\\\\)?(View_)?#i', '', $class))); - } - - $this->set_view(); - - $this->_method = $method; - } - - /** - * Returns the View object associated with this Presenter - * - * @return View - */ - public function get_view() - { - return $this->_view; - } - - /** - * Construct the View object - */ - protected function set_view() - { - $this->_view instanceOf View or $this->_view = \View::forge($this->_view); - } - - /** - * Returns the active request object. - * - * @return Request - */ - protected function request() - { - return $this->_active_request; - } - - /** - * Executed before the view method - */ - public function before() {} - - /** - * The default view method - * Should set all expected variables upon itself - */ - public function view() {} - - /** - * Executed after the view method - */ - public function after() {} - - /** - * Fetches an existing value from the template - * - * @param mixed $name - * @return mixed - */ - public function & __get($name) - { - return $this->get($name); - } - - /** - * Gets a variable from the template - * - * @param null $key - * @param null $default - * @return string - */ - public function & get($key = null, $default = null) - { - if (is_null($default) and func_num_args() === 1) - { - return $this->_view->get($key); - } - return $this->_view->get($key, $default); - } - - /** - * Sets and sanitizes a variable on the template - * - * @param string $key - * @param mixed $value - * @return Presenter - */ - public function __set($key, $value) - { - return $this->set($key, $value); - } - - /** - * Sets a variable on the template - * - * @param string $key - * @param mixed $value - * @param bool|null $filter - * @return $this - */ - public function set($key, $value = null, $filter = null) - { - is_null($filter) and $filter = $this->_auto_filter; - $this->_view->set($key, $value, $filter); - - return $this; - } - - /** - * The same as set(), except this defaults to not-encoding the variable - * on output. - * - * $view->set_safe('foo', 'bar'); - * - * @param string $key variable name or an array of variables - * @param mixed $value value - * @return $this - */ - public function set_safe($key, $value = null) - { - return $this->set($key, $value, false); - } - - /** - * Magic method, determines if a variable is set. - * - * isset($view->foo); - * - * @param string $key variable name - * @return boolean - */ - public function __isset($key) - { - return isset($this->_view->$key); - } - - /** - * Magic method, unsets a given variable. - * - * unset($view->foo); - * - * @param string $key variable name - * @return void - */ - public function __unset($key) - { - unset($this->_view->$key); - } - - /** - * Assigns a value by reference. The benefit of binding is that values can - * be altered without re-setting them. It is also possible to bind variables - * before they have values. Assigned values will be available as a - * variable within the view file: - * - * $this->bind('ref', $bar); - * - * @param string $key variable name - * @param mixed $value referenced variable - * @param bool $filter Whether to filter the var on output - * @return $this - */ - public function bind($key, &$value, $filter = null) - { - $this->_view->bind($key, $value, $filter); - - return $this; - } - - /** - * Change auto filter setting - * - * @param null|bool change setting (bool) or get the current setting (null) - * @return void|bool returns current setting or nothing when it is changed - */ - public function auto_filter($setting = null) - { - if (func_num_args() == 0) - { - return $this->_view->auto_filter(); - } - - return $this->_view->auto_filter($setting); - } - - /** - * Add variables through method and after() and create template as a string - */ - public function render() - { - if (class_exists('Request', false)) - { - $current_request = \Request::active(); - \Request::active($this->_active_request); - } - - $this->before(); - $this->{$this->_method}(); - $this->after(); - - $return = $this->_view->render(); - - if (class_exists('Request', false)) - { - \Request::active($current_request); - } - - return $return; - } - - /** - * Auto-render on toString - */ - public function __toString() - { - try - { - return $this->render(); - } - catch (\Exception $e) - { - \Errorhandler::exception_handler($e); - - return ''; - } - } -} diff --git a/fuel/core/classes/profiler.php b/fuel/core/classes/profiler.php deleted file mode 100755 index 7365d98..0000000 --- a/fuel/core/classes/profiler.php +++ /dev/null @@ -1,82 +0,0 @@ -queries = array(); - static::$profiler->queryCount = 0; - static::mark(__METHOD__.' Start'); - \Fuel::$profiling = true; - } - } - - public static function mark($label) - { - static::$profiler and \Console::logSpeed($label); - } - - public static function mark_memory($var = false, $name = 'PHP') - { - static::$profiler and \Console::logMemory($var, $name); - } - - public static function console($text) - { - static::$profiler and \Console::log($text); - } - - public static function output() - { - return static::$profiler ? static::$profiler->display(static::$profiler) : ''; - } - - public static function start($dbname, $sql, $stacktrace = array()) - { - if (static::$profiler) - { - static::$query = array( - 'sql' => \Security::htmlentities($sql), - 'time' => static::$profiler->getMicroTime(), - 'stacktrace' => $stacktrace, - 'dbname' => $dbname, - ); - return true; - } - } - - public static function stop($text) - { - if (static::$profiler) - { - static::$query['time'] = (static::$profiler->getMicroTime() - static::$query['time']) *1000; - static::$profiler->queries[] = static::$query; - static::$profiler->queryCount++; - } - } - - public static function delete($text) - { - static::$query = null; - } - - public static function app_total() - { - return array( - microtime(true) - FUEL_START_TIME, - memory_get_peak_usage() - FUEL_START_MEM, - ); - } -} diff --git a/fuel/core/classes/redis/db.php b/fuel/core/classes/redis/db.php deleted file mode 100755 index d07202a..0000000 --- a/fuel/core/classes/redis/db.php +++ /dev/null @@ -1,335 +0,0 @@ - - * @copyright 2009-2012 Justin Poliey - * @license http://www.opensource.org/licenses/ISC The ISC License - */ - -namespace Fuel\Core; - -class RedisException extends \FuelException {} - -/** - * Redisent, a Redis interface for the modest among us - */ -class Redis_Db -{ - /** - * Multiton pattern, keep track of all created instances - */ - protected static $instances = array(); - - /** - * Get an instance of the Redis class - * - * @param string $name - * @return mixed - * @throws \RedisException - */ - public static function instance($name = 'default') - { - if ( ! array_key_exists($name, static::$instances)) - { - // @deprecated since 1.4 - // call forge() if a new instance needs to be created, this should throw an error - return static::forge($name); - } - - return static::$instances[$name]; - } - - /** - * create an instance of the Redis class - * - * @param string $name - * @param array $config - * @return mixed - * @throws \RedisException - */ - public static function forge($name = 'default', $config = array()) - { - empty(static::$instances) and \Config::load('db', true); - - if ( ! ($conf = \Config::get('db.redis.'.$name))) - { - throw new \RedisException('Invalid instance name given.'); - } - $config = \Arr::merge($conf, $config); - - static::$instances[$name] = new static($config); - - return static::$instances[$name]; - } - - /** - * @var resource - */ - protected $connection = false; - - /** - * Flag indicating whether or not commands are being pipelined - * - * @var boolean - */ - protected $pipelined = false; - - /** - * The queue of commands to be sent to the Redis server - * - * @var array - */ - protected $queue = array(); - - /** - * Create a new Redis instance using the configuration values supplied - * - * @param array $config - * @throws \RedisException - */ - public function __construct(array $config = array()) - { - empty($config['timeout']) and $config['timeout'] = ini_get("default_socket_timeout"); - - $this->connection = @fsockopen($config['hostname'], $config['port'], $errno, $errstr, $config['timeout']); - - if ( ! $this->connection) - { - throw new \RedisException($errstr, $errno); - } - else - { - // execute the auth command if a password is present in config - empty($config['password']) or $this->auth($config['password']); - - // Select database using zero-based numeric index - empty($config['database']) or $this->select($config['database']); - } - } - - /** - * Close the open connection on class destruction - */ - public function __destruct() - { - $this->connection and fclose($this->connection); - } - - /** - * Returns the Redisent instance ready for pipelining. - * - * Redis commands can now be chained, and the array of the responses will be - * returned when {@link execute} is called. - * @see execute - * - */ - public function pipeline() - { - $this->pipelined = true; - - return $this; - } - - /** - * Flushes the commands in the pipeline queue to Redis and returns the responses. - * @see pipeline - */ - public function execute() - { - // open a Redis connection and execute the queued commands - foreach ($this->queue as $command) - { - for ($written = 0; $written < strlen($command); $written += $fwrite) - { - $fwrite = fwrite($this->connection, substr($command, $written)); - if ($fwrite === false) - { - throw new \RedisException('Failed to write entire command to stream'); - } - } - } - - // Read in the results from the pipelined commands - $responses = array(); - for ($i = 0; $i < count($this->queue); $i++) - { - $responses[] = $this->readResponse(); - } - - // Clear the queue and return the response - $this->queue = array(); - - if ($this->pipelined) - { - $this->pipelined = false; - return $responses; - } - else - { - return $responses[0]; - } - } - - /** - * Alias for the redis PSUBSCRIBE command. It allows you to listen, and - * have the callback called for every response. - * - * @param string $pattern pattern to subscribe to - * @param callable $callback callback, to process the responses - * @throws \RedisException if writing the command failed - */ - public function psubscribe($pattern, $callback) - { - $args = array('PSUBSCRIBE', $pattern); - - $command = sprintf('*%d%s%s%s', 2, CRLF, implode(array_map(function($arg) { - return sprintf('$%d%s%s', strlen($arg), CRLF, $arg); - }, $args), CRLF), CRLF); - - for ($written = 0; $written < strlen($command); $written += $fwrite) - { - $fwrite = fwrite($this->connection, substr($command, $written)); - if ($fwrite === false) - { - throw new \RedisException('Failed to write entire command to stream'); - } - } - - while ( ! feof($this->connection)) - { - try - { - $response = $this->readResponse(); - $callback($response); - } - catch(\RedisException $e) - { - \Log::warning($e->getMessage(), 'Redis_Db::readResponse'); - } - } - } - - /** - * @param $name - * @param $args - * @return $this|array - * @throws \RedisException - */ - public function __call($name, $args) - { - // build the Redis unified protocol command - array_unshift($args, strtoupper($name)); - - $command = sprintf('*%d%s%s%s', count($args), CRLF, implode(array_map(function($arg) { - return sprintf('$%d%s%s', strlen($arg), CRLF, $arg); - }, $args), CRLF), CRLF); - - // add it to the pipeline queue - $this->queue[] = $command; - - if ($this->pipelined) - { - return $this; - } - else - { - return $this->execute(); - } - } - - protected function readResponse() - { - // parse the response based on the reply identifier - $reply = trim(fgets($this->connection, 512)); - - switch (substr($reply, 0, 1)) - { - // error reply - case '-': - throw new \RedisException(trim(substr($reply, 1))); - break; - - // inline reply - case '+': - $response = substr(trim($reply), 1); - if ($response === 'OK') - { - $response = true; - } - break; - - // bulk reply - case '$': - $response = null; - if ($reply == '$-1') - { - break; - } - $read = 0; - $size = intval(substr($reply, 1)); - if ($size > 0) - { - do - { - $block_size = ($size - $read) > 1024 ? 1024 : ($size - $read); - $r = fread($this->connection, $block_size); - if ($r === false) - { - throw new \RedisException('Failed to read response from stream'); - } - else - { - $read += strlen($r); - $response .= $r; - } - } - while ($read < $size); - } - - // discard the crlf - fread($this->connection, 2); - break; - - // multi-bulk reply - case '*': - $count = intval(substr($reply, 1)); - if ($count == '-1') - { - return null; - } - $response = array(); - for ($i = 0; $i < $count; $i++) - { - $response[] = $this->readResponse(); - } - break; - - // integer reply - case ':': - $response = intval(substr(trim($reply), 1)); - break; - - default: - throw new \RedisException("Unknown response: {$reply}"); - break; - } - - // party on... - return $response; - } - -} diff --git a/fuel/core/classes/request.php b/fuel/core/classes/request.php deleted file mode 100755 index 8f1a2c2..0000000 --- a/fuel/core/classes/request.php +++ /dev/null @@ -1,631 +0,0 @@ -execute(); - * echo $request->response(); - * - * @package Fuel - * @subpackage Core - */ -class Request -{ - /** - * Holds the main request instance - * - * @var Request - */ - protected static $main = false; - - /** - * Holds the global active request instance - * - * @var Request - */ - protected static $active = false; - - /** - * Generates a new request. The request is then set to be the active - * request. If this is the first request, then save that as the main - * request for the app. - * - * Usage: - * - * Request::forge('hello/world'); - * - * @param string $uri The URI of the request - * @param mixed $options Internal: whether to use the routes; external: driver type or array with settings (driver key must be set) - * @param string $method request method - * @return Request The new request object - */ - public static function forge($uri = null, $options = true, $method = null) - { - is_bool($options) and $options = array('route' => $options); - is_string($options) and $options = array('driver' => $options); - - if ( ! empty($options['driver'])) - { - $class = \Inflector::words_to_upper('Request_'.$options['driver']); - return $class::forge($uri, $options, $method); - } - - $request = new static($uri, isset($options['route']) ? $options['route'] : true, $method); - if (static::$active) - { - $request->parent = static::$active; - static::$active->children[] = $request; - } - - // fire any request created events - \Event::instance()->has_events('request_created') and \Event::instance()->trigger('request_created', '', 'none'); - - return $request; - } - - /** - * Returns the main request instance (the one from the browser or CLI). - * This is the first executed Request, not necessarily the root parent of the current request. - * - * Usage: - * - * Request::main(); - * - * @return Request - */ - public static function main() - { - return static::$main; - } - - /** - * Returns the active request currently being used. - * - * Usage: - * - * Request::active(); - * - * @param Request|null|false $request overwrite current request before returning, false prevents overwrite - * @return Request - */ - public static function active($request = false) - { - if ($request !== false) - { - static::$active = $request; - } - - return static::$active; - } - - /** - * Returns the current request is an HMVC request - * - * Usage: - * - * if (Request::is_hmvc()) - * { - * // Do something special... - * return; - * } - * - * @return bool - */ - public static function is_hmvc() - { - return ((\Fuel::$is_cli and static::main()) or static::active() !== static::main()); - } - - /** - * Reset's the active request with the previous one. This is needed after - * the active request is finished. - * - * Usage: - * - * Request::reset_request(); - * - * @return void - */ - public static function reset_request($full = false) - { - // Let's make the previous Request active since we are done executing this one. - static::$active and static::$active = static::$active->parent(); - - if ($full) - { - static::$main = null; - } - } - - /** - * Holds the response object of the request. - * - * @var Response - */ - public $response = null; - - /** - * The Request's URI object. - * - * @var Uri - */ - public $uri = null; - - /** - * The request's route object - * - * @var Route - */ - public $route = null; - - /** - * @var string $method request method - */ - protected $method = null; - - /** - * The current module - * - * @var string - */ - public $module = ''; - - /** - * The current controller directory - * - * @var string - */ - public $directory = ''; - - /** - * The request's controller - * - * @var string - */ - public $controller = ''; - - /** - * The request's controller action - * - * @var string - */ - public $action = ''; - - /** - * The request's method params - * - * @var array - */ - public $method_params = array(); - - /** - * The request's named params - * - * @var array - */ - public $named_params = array(); - - /** - * Controller instance once instantiated - * - * @var Controller - */ - public $controller_instance; - - /** - * Search paths for the current active request - * - * @var array - */ - public $paths = array(); - - /** - * Request that created this one - * - * @var Request - */ - protected $parent = null; - - /** - * Requests created by this request - * - * @var array - */ - protected $children = array(); - - /** - * Creates the new Request object by getting a new URI object, then parsing - * the uri with the Route class. - * - * Usage: - * - * $request = new Request('foo/bar'); - * - * @param string $uri the uri string - * @param bool $route whether or not to route the URI - * @param string $method request method - * @throws \FuelException - */ - public function __construct($uri, $route = true, $method = null) - { - $this->uri = new \Uri($uri); - $this->method = $method ?: \Input::method(); - - logger(\Fuel::L_INFO, 'Creating a new '.(static::$main==null ? 'main' : 'HMVC').' Request with URI = "'.$this->uri->get().'"', __METHOD__); - - // check if a module was requested - if (count($this->uri->get_segments()) and $module_path = \Module::exists($this->uri->get_segment(1))) - { - // check if the module has routes - if (is_file($module_path .= 'config/routes.php')) - { - $module = $this->uri->get_segment(1); - - // load and add the module routes - $module_routes = \Fuel::load($module_path); - - $reserve_routes = array( - '_root_' => $module, - '_403_' => '_403_', - '_404_' => '_404_', - '_500_' => '_500_', - $module => $module, - ); - - $prepped_routes = array(); - foreach($module_routes as $name => $_route) - { - if (isset($reserve_routes[$name])) - { - $name = $reserve_routes[$name]; - } - elseif (strpos($name, $module.'/') !== 0) - { - $name = $module.'/'.$name; - } - - $prepped_routes[$name] = $_route; - }; - - // update the loaded list of routes - \Router::add($prepped_routes, null, true); - } - } - - $this->route = \Router::process($this, $route); - - if ( ! $this->route) - { - return; - } - - $this->module = $this->route->module; - $this->controller = $this->route->controller; - $this->action = $this->route->action; - $this->method_params = $this->route->method_params; - $this->named_params = $this->route->named_params; - - if ($this->route->module !== null) - { - $this->add_path(\Module::exists($this->module)); - } - } - - /** - * This executes the request and sets the output to be used later. - * - * Usage: - * - * $request = Request::forge('hello/world')->execute(); - * - * @param array|null $method_params An array of parameters to pass to the method being executed - * @return Request This request object - * @throws \Exception - * @throws \FuelException - * @throws \HttpNotFoundException - */ - public function execute($method_params = null) - { - // fire any request started events - \Event::instance()->has_events('request_started') and \Event::instance()->trigger('request_started', '', 'none'); - - if (\Fuel::$profiling) - { - \Profiler::mark(__METHOD__.': Start of '.$this->uri->get()); - } - - logger(\Fuel::L_INFO, 'Called', __METHOD__); - - // Make the current request active - static::$active = $this; - - // First request called is also the main request - if ( ! static::$main) - { - logger(\Fuel::L_INFO, 'Setting main Request', __METHOD__); - static::$main = $this; - } - - if ( ! $this->route) - { - static::reset_request(); - throw new \HttpNotFoundException(); - } - - // save the current language so we can restore it after the call - $current_language = \Config::get('language', 'en'); - - try - { - if ($this->route->callable !== null) - { - $response = call_fuel_func_array($this->route->callable, array($this)); - - if ( ! $response instanceof Response) - { - $response = new \Response($response); - } - } - else - { - $method_prefix = $this->method.'_'; - $class = $this->controller; - - // Allow override of method params from execute - if (is_array($method_params)) - { - $this->method_params = array_merge($this->method_params, $method_params); - } - - // If the class doesn't exist then 404 - if ( ! class_exists($class)) - { - throw new \HttpNotFoundException(); - } - - // Load the controller using reflection - $class = new \ReflectionClass($class); - - if ($class->isAbstract()) - { - throw new \HttpNotFoundException(); - } - - // Create a new instance of the controller - $this->controller_instance = $class->newInstance($this); - - $this->action = $this->action ?: ($class->hasProperty('default_action') ? $class->getProperty('default_action')->getValue($this->controller_instance) : 'index'); - $method = $method_prefix.$this->action; - - // Allow to do in controller routing if method router(action, params) exists - if ($class->hasMethod('router')) - { - $method = 'router'; - $this->method_params = array($this->action, $this->method_params); - } - - if ( ! $class->hasMethod($method)) - { - // If they call user, go to $this->post_user(); - $method = strtolower(\Input::method()) . '_' . $this->action; - - // Fall back to action_ if no HTTP request method based method exists - if ( ! $class->hasMethod($method)) - { - $method = 'action_'.$this->action; - } - } - - if ($class->hasMethod($method)) - { - $action = $class->getMethod($method); - - if ( ! $action->isPublic()) - { - throw new \HttpNotFoundException(); - } - - if (count($this->method_params) < $action->getNumberOfRequiredParameters()) - { - throw new \HttpNotFoundException(); - } - - // fire any controller started events - \Event::instance()->has_events('controller_started') and \Event::instance()->trigger('controller_started', '', 'none'); - - $class->hasMethod('before') and $class->getMethod('before')->invoke($this->controller_instance); - - $response = $action->invokeArgs($this->controller_instance, $this->method_params); - - $class->hasMethod('after') and $response = $class->getMethod('after')->invoke($this->controller_instance, $response); - - // fire any controller finished events - \Event::instance()->has_events('controller_finished') and \Event::instance()->trigger('controller_finished', '', 'none'); - } - else - { - throw new \HttpNotFoundException(); - } - } - - // restore the language setting - \Config::set('language', $current_language); - } - catch (\Exception $e) - { - static::reset_request(); - - // restore the language setting - \Config::set('language', $current_language); - - throw $e; - } - - // Get the controller's output - if ($response instanceof Response) - { - $this->response = $response; - } - else - { - throw new \FuelException(get_class($this->controller_instance).'::'.$method.'() or the controller after() method must return a Response object.'); - } - - // fire any request finished events - \Event::instance()->has_events('request_finished') and \Event::instance()->trigger('request_finished', '', 'none'); - - if (\Fuel::$profiling) - { - \Profiler::mark(__METHOD__.': End of '.$this->uri->get()); - } - - static::reset_request(); - - return $this; - } - - /** - * Sets the request method. - * - * @param string $method request method - * @return object current instance - */ - public function set_method($method) - { - $this->method = strtoupper($method); - return $this; - } - - /** - * Returns the request method. - * - * @return string request method - */ - public function get_method() - { - return $this->method; - } - - /** - * Gets this Request's Response object; - * - * Usage: - * - * $response = Request::forge('foo/bar')->execute()->response(); - * - * @return Response This Request's Response object - */ - public function response() - { - return $this->response; - } - - /** - * Returns the Request that created this one - * - * @return Request|null - */ - public function parent() - { - return $this->parent; - } - - /** - * Returns an array of Requests created by this one - * - * @return array - */ - public function children() - { - return $this->children; - } - - /** - * Add to paths which are used by Finder::search() - * - * @param string the new path - * @param bool whether to add to the front or the back of the array - * @return void - */ - public function add_path($path, $prefix = false) - { - if ($prefix) - { - // prefix the path to the paths array - array_unshift($this->paths, $path); - } - else - { - // add the new path - $this->paths[] = $path; - } - } - - /** - * Returns the array of currently loaded search paths. - * - * @return array the array of paths - */ - public function get_paths() - { - return $this->paths; - } - - /** - * Gets a specific named parameter - * - * @param string $param Name of the parameter - * @param mixed $default Default value - * @return mixed - */ - public function param($param, $default = null) - { - if ( ! isset($this->named_params[$param])) - { - return \Fuel::value($default); - } - - return $this->named_params[$param]; - } - - /** - * Gets all of the named parameters - * - * @return array - */ - public function params() - { - return $this->named_params; - } - - /** - * PHP magic function returns the Output of the request. - * - * Usage: - * - * $request = Request::forge('hello/world')->execute(); - * echo $request; - * - * @return string the response - */ - public function __toString() - { - return (string) $this->response; - } -} diff --git a/fuel/core/classes/request/curl.php b/fuel/core/classes/request/curl.php deleted file mode 100755 index 18a2d28..0000000 --- a/fuel/core/classes/request/curl.php +++ /dev/null @@ -1,353 +0,0 @@ -http_login($options['user'], $options['pass'], $options['auth']); - } - - parent::__construct($resource, $options, $method); - } - - /** - * Fetch the connection, create if necessary - * - * @return \resource - */ - protected function connection() - { - // If no a protocol in URL, assume its a local link - ! preg_match('!^\w+://! i', $this->resource) and $this->resource = \Uri::create($this->resource); - - return curl_init($this->resource); - } - - /** - * Authenticate to an http server - * - * @param string $username - * @param string $password - * @param string $type - * @return Request_Curl - */ - public function http_login($username = '', $password = '', $type = 'any') - { - $this->set_option(CURLOPT_HTTPAUTH, constant('CURLAUTH_' . strtoupper($type))); - $this->set_option(CURLOPT_USERPWD, $username . ':' . $password); - - return $this; - } - - /** - * Overwrites driver method to set options driver specifically - * - * @param array $options - * @return Request_Curl - */ - public function set_options(array $options) - { - foreach ($options as $key => $val) - { - if (is_string($key) and ! is_numeric($key)) - { - $key = constant(defined($key) ? $key : 'CURLOPT_' . strtoupper($key)); - } - - $this->options[$key] = $val; - } - - return $this; - } - - public function execute(array $additional_params = array()) - { - // Reset response - $this->response = null; - $this->response_info = array(); - - // Set two default options, and merge any extra ones in - if ( ! isset($this->options[CURLOPT_TIMEOUT])) - { - $this->options[CURLOPT_TIMEOUT] = 30; - } - if ( ! isset($this->options[CURLOPT_RETURNTRANSFER])) - { - $this->options[CURLOPT_RETURNTRANSFER] = true; - } - if ( ! isset($this->options[CURLOPT_FAILONERROR])) - { - $this->options[CURLOPT_FAILONERROR] = false; - } - - // Only set follow location if not running securely - if ( ! ini_get('safe_mode') && ! ini_get('open_basedir')) - { - // Ok, follow location is not set already so lets set it to true - if ( ! isset($this->options[CURLOPT_FOLLOWLOCATION])) - { - $this->options[CURLOPT_FOLLOWLOCATION] = true; - } - } - - if ( ! empty($this->headers)) - { - $this->set_option(CURLOPT_HTTPHEADER, $this->get_headers()); - } - - $additional_params and $this->params = \Arr::merge($this->params, $additional_params); - $this->method and $this->options[CURLOPT_CUSTOMREQUEST] = $this->method; - - if ( ! empty($this->method)) - { - $this->options[CURLOPT_CUSTOMREQUEST] = $this->method; - $this->{'method_'.strtolower($this->method)}(); - } - else - { - $this->method_get(); - } - - $connection = $this->connection(); - - curl_setopt_array($connection, $this->options); - - // Execute the request & and hide all output - $body = curl_exec($connection); - $this->response_info = curl_getinfo($connection); - $this->response_info['response'] = $body; - $mime = $this->response_info('content_type', 'text/plain'); - - // Was header data requested? - $headers = array(); - if (isset($this->options[CURLOPT_HEADER]) and $this->options[CURLOPT_HEADER]) - { - // Split the headers from the body - $raw_headers = explode("\n", str_replace("\r", "", substr($body, 0, $this->response_info['header_size']))); - $body = $this->response_info['header_size'] >= strlen($body) ? '' : substr($body, $this->response_info['header_size']); - - // Convert the header data - foreach ($raw_headers as $header) - { - $header = explode(':', $header, 2); - if (isset($header[1])) - { - $headers[trim($header[0])] = trim($header[1]); - } - } - } - - $this->set_response($body, $this->response_info('http_code', 200), $mime, $headers, isset($this->headers['Accept']) ? $this->headers['Accept'] : null); - - // Request failed - if ($body === false) - { - $this->set_defaults(); - throw new \RequestException(curl_error($connection), curl_errno($connection)); - } - elseif ($this->response->status >= 400) - { - $this->set_defaults(); - throw new \RequestStatusException($body, $this->response->status); - } - else - { - // Request successful - curl_close($connection); - $this->set_defaults(); - - return $this; - } - } - - /** - * Extends parent to reset headers as well - * - * @return Request_Curl - */ - protected function set_defaults() - { - parent::set_defaults(); - $this->headers = array(); - - if ( ! empty($this->preserve_resource)) - { - $this->resource = $this->preserve_resource; - $this->preserve_resource = null; - } - - return $this; - } - - /** - * GET request - * - * @return void - */ - protected function method_get() - { - $this->preserve_resource = $this->resource; - $this->resource = \Uri::create($this->resource, array(), $this->params); - } - - /** - * HEAD request - * - * @return void - */ - protected function method_head() - { - $this->method_get(); - - $this->set_option(CURLOPT_NOBODY, true); - $this->set_option(CURLOPT_HEADER, true); - - } - - /** - * POST request - * - * @return void - */ - protected function method_post() - { - $params = is_array($this->params) ? $this->encode($this->params) : $this->params; - - $this->set_option(CURLOPT_POST, true); - $this->set_option(CURLOPT_POSTFIELDS, $params); - } - - /** - * PUT request - * - * @return void - */ - protected function method_put() - { - $params = is_array($this->params) ? $this->encode($this->params) : $this->params; - - $this->set_option(CURLOPT_POSTFIELDS, $params); - - // Override method, I think this makes $_POST DELETE data but... we'll see eh? - $this->set_header('X-HTTP-Method-Override', 'PUT'); - } - - /** - * DELETE request - * - * @return void - */ - protected function method_delete() - { - $params = is_array($this->params) ? $this->encode($this->params) : $this->params; - - $this->set_option(CURLOPT_POSTFIELDS, $params); - - // Override method, I think this makes $_POST DELETE data but... we'll see eh? - $this->set_header('X-HTTP-Method-Override', 'DELETE'); - } - - /** - * Function to encode input array depending on the content type - * - * @param array $input - * @return mixed encoded output - */ - protected function encode(array $input) - { - // Detect the request content type, default to 'text/plain' - $content_type = isset($this->headers['Content-Type']) ? $this->headers['Content-Type'] : $this->response_info('content_type', 'text/plain'); - - // Get the correct format for the current content type - $format = \Arr::key_exists(static::$auto_detect_formats, $content_type) ? static::$auto_detect_formats[$content_type] : null; - - switch($format) - { - // Format as XML - case 'xml': - /** - * If the input array has one item in the top level - * then use that item as the root XML element. - */ - if(count($input) === 1) - { - $base_node = key($input); - return \Format::forge($input[$base_node])->to_xml(null, null, $base_node); - } - else - { - return \Format::forge($input)->to_xml(); - } - break; - - // Format as JSON - case 'json': - return \Format::forge($input)->to_json(); - break; - - // Format as PHP Serialized Array - case 'serialize': - return \Format::forge($input)->to_serialize(); - break; - - // Format as PHP Array - case 'php': - return \Format::forge($input)->to_php(); - break; - - // Format as CSV - case 'csv': - return \Format::forge($input)->to_csv(); - break; - - default: - if (count($input) === 1 and key($input) === 'form-data') - { - // multipart/form-data - return $input['form-data']; - } - else - { - //application/x-www-form-urlencoded - return http_build_query($input, null, '&'); - } - break; - } - } -} diff --git a/fuel/core/classes/request/driver.php b/fuel/core/classes/request/driver.php deleted file mode 100755 index 983e570..0000000 --- a/fuel/core/classes/request/driver.php +++ /dev/null @@ -1,411 +0,0 @@ - 'application/xml', - 'json' => 'application/json', - 'serialize' => 'application/vnd.php.serialized', - 'php' => 'text/plain', - 'csv' => 'text/csv', - ); - - /** - * @var array mimetype format autodetection - */ - protected static $auto_detect_formats = array( - 'application/xml' => 'xml', - 'application/soap+xml' => 'xml', - 'text/xml' => 'xml', - 'application/json' => 'json', - 'text/json' => 'json', - 'text/csv' => 'csv', - 'application/csv' => 'csv', - 'application/vnd.php.serialized' => 'serialize', - ); - - public function __construct($resource, array $options, $method = null) - { - $this->resource = $resource; - $method and $this->set_method($method); - - foreach ($options as $key => $value) - { - if (method_exists($this, 'set_'.$key)) - { - $this->{'set_'.$key}($value); - } - } - - $this->default_options = $this->options; - $this->default_params = $this->params; - } - - /** - * Sets the request method. - * - * @param string $method request method - * @return object current instance - */ - public function set_method($method) - { - $this->method = strtoupper($method); - return $this; - } - - /** - * Returns the request method. - * - * @return string request method - */ - public function get_method() - { - return $this->method; - } - - /** - * Set the parameters to pass with the request - * - * @param array $params - * @return Request_Driver - */ - public function set_params($params) - { - $this->params = $params; - return $this; - } - - /** - * Sets options on the driver - * - * @param array $options - * @return Request_Driver - */ - public function set_options(array $options) - { - foreach ($options as $key => $val) - { - $this->options[$key] = $val; - } - - return $this; - } - - /** - * Sets a single option/value - * - * @param int|string $option - * @param mixed $value - * @return Request_Driver - */ - public function set_option($option, $value) - { - return $this->set_options(array($option => $value)); - } - - /** - * Add a single parameter/value or an array of parameters - * - * @param string|array $param - * @param mixed $value - * @return Request_Driver - */ - public function add_param($param, $value = null) - { - if ( ! is_array($param)) - { - $param = array($param => $value); - } - - foreach ($param as $key => $val) - { - \Arr::set($this->params, $key, $val); - } - return $this; - } - - /** - * set a request http header - * - * @param string $header - * @param string $content - * @return Request_Driver - */ - public function set_header($header, $content = null) - { - if (is_null($content)) - { - $this->headers[] = $header; - } - else - { - $this->headers[$header] = $content; - } - - return $this; - } - - /** - * Collect all headers and parse into consistent string - * - * @return array - */ - public function get_headers() - { - $headers = array(); - foreach ($this->headers as $key => $value) - { - $headers[] = is_int($key) ? $value : $key.': '.$value; - } - - return $headers; - } - - /** - * Set mime-type accept header - * - * @param string $mime - * @return string Request_Driver - */ - public function set_mime_type($mime) - { - if (array_key_exists($mime, static::$supported_formats)) - { - $mime = static::$supported_formats[$mime]; - } - - $this->set_header('Accept', $mime); - return $this; - } - - /** - * Switch auto formatting on or off - * - * @param bool $auto_format - * @return Request_Driver - */ - public function set_auto_format($auto_format) - { - $this->auto_format = (bool) $auto_format; - return $this; - } - - /** - * Executes the request upon the URL - * - * @param array $additional_params - * @return Response - */ - abstract public function execute(array $additional_params = array()); - - /** - * Reset before doing another request - * - * @return Request_Driver - */ - protected function set_defaults() - { - $this->options = $this->default_options; - $this->params = $this->default_params; - return $this; - } - - /** - * Validate if a given mime type is accepted according to an accept header - * - * @param string $mime - * @param string $accept_header - * @return bool - */ - protected function mime_in_header($mime, $accept_header) - { - // make sure we have input - if (empty($mime) or empty($accept_header)) - { - // no header or no mime to check - return true; - } - - // process the accept header and get a list of accepted mimes - $accept_mimes = array(); - $accept_header = explode(',', $accept_header); - foreach ($accept_header as $accept_def) - { - $accept_def = explode(';', $accept_def); - $accept_def = trim($accept_def[0]); - if ( ! in_array($accept_def, $accept_mimes)) - { - $accept_mimes[] = $accept_def; - } - } - - // match on generic mime type - if (in_array('*/*', $accept_mimes)) - { - return true; - } - - // match on full mime type - if (in_array($mime, $accept_mimes)) - { - return true; - } - - // match on generic mime type - $mime = substr($mime, 0, strpos($mime, '/')).'/*'; - if (in_array($mime, $accept_mimes)) - { - return true; - } - - // no match - return false; - } - - /** - * Creates the Response and optionally attempts to auto-format the output - * - * @param string $body - * @param int $status - * @param string $mime - * @param array $headers - * @param string $accept_header - * @return Response - * - * @throws \OutOfRangeException if an accept header was specified, but the mime type isn't in it - */ - public function set_response($body, $status, $mime = null, $headers = array(), $accept_header = null) - { - // did we use an accept header? If so, validate the returned mimetype - if ( ! $this->mime_in_header($mime, $accept_header)) - { - throw new \OutOfRangeException('The mimetype "'.$mime.'" of the returned response is not acceptable according to the accept header send.'); - } - - // do we have auto formatting enabled and can we format this mime type? - if ($this->auto_format and array_key_exists($mime, static::$auto_detect_formats)) - { - $body = \Format::forge($body, static::$auto_detect_formats[$mime])->to_array(); - } - - $this->response = \Response::forge($body, $status, $headers); - - return $this->response; - } - - /** - * Fetch the response - * - * @return Response - */ - public function response() - { - return $this->response; - } - - /** - * Fetch the response info or a key from it - * - * @param string $key - * @param string $default - * @return mixed - */ - public function response_info($key = null, $default = null) - { - if (func_num_args() == 0) - { - return $this->response_info; - } - - return \Arr::get($this->response_info, $key, $default); - } - - /** - * Returns the body as a string. - * - * @return string - */ - public function __toString() - { - return (string) $this->response(); - } -} diff --git a/fuel/core/classes/request/soap.php b/fuel/core/classes/request/soap.php deleted file mode 100755 index fad31b2..0000000 --- a/fuel/core/classes/request/soap.php +++ /dev/null @@ -1,276 +0,0 @@ -set_option('login', $options['user']); - $this->set_option('password', $options['pass']); - } - - // WSDL-mode only options - if ( ! empty($resource)) - { - foreach (static::$wsdl_settings as $setting) - { - isset($options[$setting]) and $this->set_option($setting, $options[$setting]); - } - } - // non-WSDL-mode only options - else - { - $resource = null; - - if ( ! isset($options['location']) or ! isset($options['uri'])) - { - throw new \RequestException('The keys "location" and "uri" are required in non-WSDL mode.'); - } - - foreach (static::$non_wsdl_settings as $setting) - { - isset($options[$setting]) and $this->set_option($setting, $options[$setting]); - } - } - - foreach (static::$generic_settings as $setting) - { - isset($options[$setting]) and $this->set_option($setting, $options[$setting]); - } - - // make it always throw exceptions - $this->set_option('exceptions', true); - - parent::__construct($resource, $options); - } - - /** - * Set the function to execute on the SoapClient - * - * @param string $function - * @return Request_Soap - */ - public function set_function($function) - { - $this->function = $function; - return $this; - } - - /** - * Fetch the connection, create if necessary - * - * @return \SoapClient - */ - protected function connection() - { - if (empty($this->connection)) - { - $this->connection = new \SoapClient($this->resource, $this->options); - } - - return $this->connection; - } - - public function execute(array $additional_params = array()) - { - if (empty($this->function)) - { - throw new \RequestException('No function set to execute on the Soap request.'); - } - - $additional_params and $this->params = \Arr::merge($this->params, $additional_params); - - // Execute the request & and hide all output - try - { - $body = $this->connection()->__soapCall($this->function, $this->params, array(), $this->get_headers(), $headers); - $this->response_info = $headers; - - $mime = $this->response_info('content_type', 'application/soap+xml'); - $this->set_response($body, $this->response_info('http_code', 200), $mime, $headers, isset($this->headers['Accept']) ? $this->headers['Accept'] : null); - - $this->set_defaults(); - return $this; - } - catch (\SoapFault $e) - { - $this->set_defaults(); - throw new \RequestException($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * Extends parent to reset headers as well - * - * @return Request_Soap - */ - protected function set_defaults() - { - parent::set_defaults(); - $this->function = ''; - - return $this; - } - - /** - * Get functions defined in WSDL - * - * @return array - * @throws \RequestException - */ - public function get_functions() - { - if ( ! $this->resource) - { - throw new \RequestException('SOAP get functions not available in non-WSDL mode.'); - } - return $this->connection()->__getFunctions(); - } - - /** - * Get last request XML - * - * @return string - * @throws \RequestException - */ - public function get_request_xml() - { - if (empty($this->options['trace'])) - { - throw new \RequestException('The "trace" option must be true to be able to get the last request.'); - } - return $this->connection()->__getLastRequest(); - } - - /** - * Get last request headers - * - * @return string - * @throws \RequestException - */ - public function get_request_headers() - { - if (empty($this->options['trace'])) - { - throw new \RequestException('The "trace" option must be true to be able to get the last request headers.'); - } - return $this->connection()->__getLastRequestHeaders(); - } - - /** - * Get last response XML - * - * @return string - * @throws \RequestException - */ - public function get_response_xml() - { - if (empty($this->options['trace'])) - { - throw new \RequestException('The "trace" option must be true to be able to get the last response.'); - } - return $this->connection()->__getLastResponse(); - } - - /** - * Get last response headers - * - * @return string - * @throws \RequestException - */ - public function get_response_headers() - { - if (empty($this->options['trace'])) - { - throw new \RequestException('The "trace" option must be true to be able to get the last response headers.'); - } - return $this->connection()->__getLastResponseHeaders(); - } - - /** - * Get last response headers - * - * @return array - * @throws \RequestException - */ - public function get_types() - { - if ( ! $this->resource) - { - throw new \RequestException('SOAP get types not available in non-WSDL mode.'); - } - return $this->connection()->__getTypes(); - } - - /** - * Set cookie for subsequent requests - * - * @param string $name - * @param string $value - * @return void - * @throws \RequestException - */ - public function set_cookie($name, $value = null) - { - is_null($value) - ? $this->connection()->__setCookie($name) - : $this->connection()->__setCookie($name, $value); - } - - /** - * Change the endpoint location - * - * @param string $location - * @return string the old endpoint - */ - public function set_location($location) - { - $this->connection()->__setLocation($location); - } -} diff --git a/fuel/core/classes/response.php b/fuel/core/classes/response.php deleted file mode 100755 index 8bfe588..0000000 --- a/fuel/core/classes/response.php +++ /dev/null @@ -1,384 +0,0 @@ - 'Continue', - 101 => 'Switching Protocols', - 102 => 'Processing', - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - 207 => 'Multi-Status', - 208 => 'Already Reported', - 226 => 'IM Used', - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 307 => 'Temporary Redirect', - 308 => 'Permanent Redirect', - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - 418 => 'I\'m a Teapot', - 422 => 'Unprocessable Entity', - 423 => 'Locked', - 424 => 'Failed Dependency', - 426 => 'Upgrade Required', - 428 => 'Precondition Required', - 429 => 'Too Many Requests', - 431 => 'Request Header Fields Too Large', - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported', - 506 => 'Variant Also Negotiates', - 507 => 'Insufficient Storage', - 508 => 'Loop Detected', - 509 => 'Bandwidth Limit Exceeded', - 510 => 'Not Extended', - 511 => 'Network Authentication Required', - ); - - /** - * Creates an instance of the Response class - * - * @param string $body The response body - * @param int $status The HTTP response status for this response - * @param array $headers Array of HTTP headers for this response - * - * @return Response - */ - public static function forge($body = null, $status = 200, array $headers = array()) - { - $response = new static($body, $status, $headers); - - // fire any response created events - \Event::instance()->has_events('response_created') and \Event::instance()->trigger('response_created', '', 'none'); - - return $response; - } - - /** - * Redirects to another uri/url. Sets the redirect header, - * sends the headers and exits. Can redirect via a Location header - * or using a refresh header. - * - * The refresh header works better on certain servers like IIS. - * - * @param string $url The url - * @param string $method The redirect method - * @param int $code The redirect status code - * - * @return void - */ - public static function redirect($url = '', $method = 'location', $code = 302) - { - $response = new static; - - $response->set_status($code); - - if (strpos($url, '://') === false) - { - $url = $url !== '' ? \Uri::create($url) : \Uri::base(); - } - - if (\Config::get('response.redirect_with_wildcards', true)) - { - strpos($url, '*') !== false and $url = \Uri::segment_replace($url); - } - - if ($method == 'location') - { - $response->set_header('Location', $url); - } - elseif ($method == 'refresh') - { - $response->set_header('Refresh', '0;url='.$url); - } - else - { - return; - } - - $response->send(true); - exit; - } - - /** - * Redirects back to the previous page, if that page is within the current - * application. If not, it will redirect to the given url, and if none is - * given, back to the application root. If the current page is the application - * root, an exception is thrown - * - * @param string $url The url - * @param string $method The redirect method - * @param int $code The redirect status code - * - * @return void - * - * @throws \RuntimeException If it would redirect back to itself - */ - public static function redirect_back($url = '', $method = 'location', $code = 302) - { - // do we have a referrer? - if ($referrer = \Input::referrer()) - { - // is it within our website? And not equal to the current url? - if (strpos($referrer, \Uri::base()) === 0 and $referrer != \Uri::current()) - { - // redirect back to where we came from - static::redirect($referrer, $method, $code); - } - } - - // make sure we're not redirecting back to ourself - if (\Uri::create($url) == \Uri::current()) - { - throw new \RuntimeException('You can not redirect back here, it would result in a redirect loop!'); - } - - // no referrer or an external link, do a normal redirect - static::redirect($url, $method, $code); - } - - /** - * @var int The HTTP status code - */ - public $status = 200; - - /** - * @var array An array of HTTP headers - */ - public $headers = array(); - - /** - * @var string The content of the response - */ - public $body = null; - - /** - * Sets up the response with a body and a status code. - * - * @param string $body The response body - * @param int $status The response status - * @param array $headers - */ - public function __construct($body = null, $status = 200, array $headers = array()) - { - foreach ($headers as $k => $v) - { - $this->set_header($k, $v); - } - $this->body = $body; - $this->status = $status; - } - - /** - * Sets the response status code - * - * @param int $status The status code - * - * @return Response - */ - public function set_status($status = 200) - { - $this->status = $status; - return $this; - } - - /** - * Adds a header to the queue - * - * @param string $name The header name - * @param string $value The header value - * @param string|bool $replace Whether to replace existing value for the header, will never overwrite/be overwritten when false - * - * @return Response - */ - public function set_header($name, $value, $replace = true) - { - if ($replace) - { - $this->headers[$name] = $value; - } - else - { - $this->headers[] = array($name, $value); - } - - return $this; - } - - /** - * Adds multiple headers to the queue - * - * @param array $headers Assoc array with header name / value combinations - * @param string|bool $replace Whether to replace existing value for the header, will never overwrite/be overwritten when false - * - * @return Response - */ - public function set_headers($headers, $replace = true) - { - foreach ($headers as $key => $value) - { - $this->set_header($key, $value, $replace); - } - - return $this; - } - - - /** - * Gets header information from the queue - * - * @param string $name The header name, or null for all headers - * - * @return mixed - */ - public function get_header($name = null) - { - if (func_num_args()) - { - return isset($this->headers[$name]) ? $this->headers[$name] : null; - } - else - { - return $this->headers; - } - } - - /** - * Sets (or returns) the body for the response - * - * @param string|bool $value The response content - * - * @return Response|string - */ - public function body($value = false) - { - if (func_num_args()) - { - $this->body = $value; - return $this; - } - - return $this->body; - } - - /** - * Sends the headers if they haven't already been sent. Returns whether - * they were sent or not. - * - * @return bool - */ - public function send_headers() - { - if ( ! headers_sent()) - { - // Send the protocol/status line first, FCGI servers need different status header - if ( ! empty($_SERVER['FCGI_SERVER_VERSION'])) - { - header('Status: '.$this->status.' '.static::$statuses[$this->status]); - } - else - { - $protocol = \Input::server('SERVER_PROTOCOL') ? \Input::server('SERVER_PROTOCOL') : 'HTTP/1.1'; - header($protocol.' '.$this->status.' '.static::$statuses[$this->status]); - } - - foreach ($this->headers as $name => $value) - { - // Parse non-replace headers - if (is_int($name) and is_array($value)) - { - isset($value[0]) and $name = $value[0]; - isset($value[1]) and $value = $value[1]; - } - - // Create the header - is_string($name) and $value = "{$name}: {$value}"; - - // Send it - header($value, true); - } - return true; - } - return false; - } - - /** - * Sends the response to the output buffer. Optionally will send the - * headers. - * - * @param bool $send_headers Whether or not to send the defined HTTP headers - * - * @return void - */ - public function send($send_headers = false) - { - $body = $this->__toString(); - - if ($send_headers) - { - $this->send_headers(); - } - - if ($this->body != null) - { - echo $body; - } - } - - /** - * Returns the body as a string. - * - * @return string - */ - public function __toString() - { - return (string) $this->body; - } -} diff --git a/fuel/core/classes/route.php b/fuel/core/classes/route.php deleted file mode 100755 index 27ec812..0000000 --- a/fuel/core/classes/route.php +++ /dev/null @@ -1,266 +0,0 @@ -path = $path; - $this->translation = ($translation === null) ? $path : $translation; - $this->search = ($translation == stripslashes($path)) ? $path : $this->compile(); - $this->case_sensitive = ($case_sensitive === null) ? \Config::get('routing.case_sensitive', true) : $case_sensitive; - $this->strip_extension = ($strip_extension === null) ? \Config::get('routing.strip_extension', true) : $strip_extension; - $this->name = $name; - } - - /** - * Compiles a route. Replaces named params and regex shortcuts. - * - * @return string compiled route. - */ - protected function compile() - { - if ($this->path === '_root_') - { - return ''; - } - - $search = str_replace(array( - ':any', - ':everything', - ':alnum', - ':num', - ':alpha', - ':segment', - ), array( - '.+', - '.*', - '[[:alnum:]]+', - '[[:digit:]]+', - '[[:alpha:]]+', - '[^/]*', - ), $this->path); - - return preg_replace('#(?.+?)', $search); - } - - /** - * Attempts to find the correct route for the given URI - * - * @param \Request $request The URI object - * @return array - */ - public function parse(\Request $request) - { - $uri = $request->uri->get(); - $method = $request->get_method(); - - if ($uri === '' and $this->path === '_root_') - { - return $this->matched(); - } - - $result = $this->_parse_search($uri, null, $method); - - if ($result) - { - return $result; - } - - return false; - } - - /** - * Parses a route match and returns the controller, action and params. - * - * @param string $uri The matched route - * @param array $named_params Named parameters - * @return object $this - */ - public function matched($uri = '', $named_params = array()) - { - // Clean out all the non-named stuff out of $named_params - foreach($named_params as $key => $val) - { - if (is_numeric($key)) - { - unset($named_params[$key]); - } - } - - $this->named_params = $named_params; - - if ($this->translation instanceof \Closure) - { - $this->callable = $this->translation; - } - else - { - $path = $this->translation; - - if ($uri != '') - { - // strip the extension if needed and there is something to strip - if ($this->strip_extension and strrchr($uri, '.') == $ext = '.'.\Input::extension()) - { - $uri = substr($uri, 0, -(strlen($ext))); - } - - if ($this->case_sensitive) - { - $path = preg_replace('#^'.$this->search.'$#uD', $this->translation, $uri); - } - else - { - $path = preg_replace('#^'.$this->search.'$#uiD', $this->translation, $uri); - } - } - - $this->segments = explode('/', trim($path, '/')); - } - - return $this; - } - - /** - * Parses an actual route - extracted out of parse() to make it recursive. - * - * @param string $uri The URI object - * @param object $route route object - * @param string $method request method - * @return array|boolean - */ - protected function _parse_search($uri, $route = null, $method = null) - { - if ($route === null) - { - $route = $this; - } - - if (is_array($route->translation)) - { - foreach ($route->translation as $r) - { - $verb = $r[0]; - - $protocol = isset($r[2]) ? ($r[2] ? 'https' : 'http') : false; - - if (($protocol === false or $protocol == \Input::protocol()) and $method == strtoupper($verb)) - { - $r[1]->search = $route->search; - $result = $route->_parse_search($uri, $r[1], $method); - - if ($result) - { - return $result; - } - } - } - - return false; - } - - if ($this->case_sensitive) - { - $result = preg_match('#^'.$route->search.'$#uD', $uri, $params); - } - else - { - $result = preg_match('#^'.$route->search.'$#uiD', $uri, $params); - } - - if ($result === 1) - { - return $route->matched($uri, $params); - } - else - { - return false; - } - } -} diff --git a/fuel/core/classes/router.php b/fuel/core/classes/router.php deleted file mode 100755 index 1cf18ee..0000000 --- a/fuel/core/classes/router.php +++ /dev/null @@ -1,354 +0,0 @@ - $t) - { - static::add($p, $t, $prepend); - } - return; - } - elseif ($options instanceof Route) - { - static::$routes[$path] = $options; - return; - } - - $name = $path; - if (is_array($options) and array_key_exists('name', $options)) - { - $name = $options['name']; - unset($options['name']); - if (count($options) == 1 and ! is_array($options[0])) - { - $options = $options[0]; - } - } - - if ($prepend) - { - \Arr::prepend(static::$routes, $name, new \Route($path, $options, $case_sensitive, null, $name)); - return; - } - - static::$routes[$name] = new \Route($path, $options, $case_sensitive, null, $name); - } - - /** - * Does reverse routing for a named route. This will return the FULL url - * (including the base url and index.php). - * - * WARNING: Reverse routing with routes that contains a regex is still - * experimental. The simple ones work, but complex ones might fail! - * - * Usage: - * - * Foo - * - * @param string $name the name of the route - * @param array $named_params the array of named parameters - * @return string the full url for the named route - */ - public static function get($name, $named_params = array()) - { - // check if we have this named route - if (array_key_exists($name, static::$routes)) - { - // fetch the url this route defines - $url = static::$routes[$name]->path; - - // get named parameters regex's out of the way first - foreach($named_params as $name => $value) - { - if (is_string($name) and ($pos = strpos($url, '(:'.$name.')')) !== false) - { - $url = substr_replace($url, $value, $pos, strlen($name)+3); - } - } - - // deal with regex's groups - if (preg_match_all('#\((?:\?P<(\w+?)>)?.*?\)#', $url, $matches) !== false) - { - if (count($matches) == 2) - { - $indexed_group_count = 0; - foreach($matches[0] as $index => $target) - { - $replace = ''; - if (array_key_exists($key = $matches[1][$index], $named_params) || - array_key_exists($key = '$'.($index + 1), $named_params) || - array_key_exists($key = $indexed_group_count++, $named_params)) - { - $replace = $named_params[$key]; - } - - if (($pos = strpos($url, $target)) !== false) - { - $url = substr_replace($url, $replace, $pos, strlen($target)); - } - } - } - } - - // return the created URI, replace any named parameters not in a regex - return \Uri::create($url, $named_params); - } - } - - /** - * Delete one or multiple routes - * - * @param string|array $path route path, or array of route paths - * @param bool $case_sensitive whether to check case sensitive - */ - public static function delete($path, $case_sensitive = null) - { - // if multiple paths are passed, recurse - if (is_array($path)) - { - foreach($path as $p) - { - static::delete($p, $case_sensitive); - } - } - else - { - $case_sensitive ?: \Config::get('routing.case_sensitive', true); - - // support the usual route path placeholders - $path = str_replace(array( - ':any', - ':everything', - ':alnum', - ':num', - ':alpha', - ':segment', - ), array( - '.+', - '.*', - '[[:alnum:]]+', - '[[:digit:]]+', - '[[:alpha:]]+', - '[^/]*', - ), $path); - - foreach (static::$routes as $name => $route) - { - if ($case_sensitive) - { - if (preg_match('#^'.$path.'$#uD', $name)) - { - unset(static::$routes[$name]); - } - } - else - { - if (preg_match('#^'.$path.'$#uiD', $name)) - { - unset(static::$routes[$name]); - } - } - } - } - } - - /** - * Processes the given request using the defined routes - * - * @param \Request $request the given Request object - * @param bool $route whether to use the defined routes or not - * @return mixed the match array or false - */ - public static function process(\Request $request, $route = true) - { - $match = false; - - if ($route) - { - foreach (static::$routes as $route) - { - if ($match = $route->parse($request)) - { - break; - } - } - } - - if ( ! $match) - { - // Since we didn't find a match, we will create a new route. - $match = new \Route(preg_quote($request->uri->get(), '#'), $request->uri->get()); - $match->parse($request); - } - - if ($match->callable !== null) - { - return $match; - } - - return static::parse_match($match); - } - - /** - * Find the controller that matches the route requested - * - * @param Route $match the given Route object - * @return mixed the match array or false - */ - protected static function parse_match($match) - { - $namespace = ''; - $segments = $match->segments; - $module = false; - - // First port of call: request for a module? - if (\Module::exists($segments[0])) - { - // make the module known to the autoloader - \Module::load($segments[0]); - $match->module = array_shift($segments); - $namespace .= ucfirst($match->module).'\\'; - $module = $match->module; - } - - if ($info = static::parse_segments($segments, $namespace, $module)) - { - $match->controller = $info['controller']; - $match->controller_path = $info['controller_path']; - $match->action = $info['action']; - $match->method_params = $info['method_params']; - return $match; - } - else - { - return null; - } - } - - protected static function parse_segments($segments, $namespace = '', $module = false) - { - $temp_segments = $segments; - $prefix = static::get_prefix(); - - foreach (array_reverse($segments, true) as $key => $segment) - { - // determine which classes to check. First, all underscores, or all namespaced - $classes = array( - $namespace.$prefix.\Inflector::words_to_upper(implode(substr($prefix, -1, 1), $temp_segments), substr($prefix, -1, 1)), - ); - - // if we're namespacing, check a hybrid version too - $classes[] = $namespace.$prefix.\Inflector::words_to_upper(implode('_', $temp_segments)); - - array_pop($temp_segments); - - foreach ($classes as $class) - { - if (static::check_class($class)) - { - return array( - 'controller' => $class, - 'controller_path' => implode('/', array_slice($segments, 0, $key + 1)), - 'action' => isset($segments[$key + 1]) ? $segments[$key + 1] : null, - 'method_params' => array_slice($segments, $key + 2), - ); - } - } - } - - // Fall back for default module controllers - if ($module) - { - $class = $namespace.$prefix.ucfirst($module); - if (static::check_class($class)) - { - return array( - 'controller' => $class, - 'controller_path' => isset($key) ? implode('/', array_slice($segments, 0, $key + 1)) : '', - 'action' => isset($segments[0]) ? $segments[0] : null, - 'method_params' => array_slice($segments, 1), - ); - } - } - - return false; - } - - /** - * Checks whether class exists. - * - * @param string $class The class name to check. - * @return bool True if $class exists, false otherwise. - * @throws \Exception - */ - protected static function check_class($class) - { - try - { - return class_exists($class); - } - catch (\Exception $e) - { - // capture autoloader failures - if (strpos($e->getFile(),'/core/classes/autoloader.php') !== false) - { - return false; - } - throw $e; - } - } - - /** - * Get prefix. - * - * @return string Prefix as defined in config controller_prefix. - */ - protected static function get_prefix() - { - return static::$prefix; - } -} diff --git a/fuel/core/classes/sanitization.php b/fuel/core/classes/sanitization.php deleted file mode 100755 index 318fe6c..0000000 --- a/fuel/core/classes/sanitization.php +++ /dev/null @@ -1,37 +0,0 @@ -sanitize(); - } - - // deal with array's or array emulating objects - elseif (is_array($var) or ($var instanceOf \Traversable and $var instanceOf \ArrayAccess)) - { - // recurse on array values - foreach($var as $key => $value) - { - $var[$key] = static::clean($value, $filters, $type); - } - } - - // deal with all other variable types - else - { - is_null($filters) and $filters = \Config::get($type, array()); - $filters = is_array($filters) ? $filters : array($filters); - - foreach ($filters as $filter) - { - // is this filter a callable local function? - if (is_string($filter) and is_callable('static::'.$filter)) - { - $var = static::$filter($var); - } - - // is this filter a callable function? - elseif (is_callable($filter)) - { - $var = call_user_func($filter, $var); - } - - // assume it's a regex of characters to filter - else - { - $var = preg_replace('#['.$filter.']#ui', '', $var); - } - } - } - - return $var; - } - - public static function xss_clean($value, array $options = array()) - { - if ( ! is_array($value)) - { - if ( ! function_exists('htmLawed')) - { - import('htmlawed/htmlawed', 'vendor'); - } - - return htmLawed($value, array_merge(array('safe' => 1, 'balanced' => 0), $options)); - } - - foreach ($value as $k => $v) - { - $value[$k] = static::xss_clean($v); - } - - return $value; - } - - public static function strip_tags($value) - { - if ( ! is_array($value)) - { - $value = filter_var($value, FILTER_SANITIZE_STRING); - } - else - { - foreach ($value as $k => $v) - { - $value[$k] = static::strip_tags($v); - } - } - - return $value; - } - - public static function htmlentities($value, $flags = null, $encoding = null, $double_encode = null) - { - static $already_cleaned = array(); - - is_null($flags) and $flags = \Config::get('security.htmlentities_flags', ENT_QUOTES); - is_null($encoding) and $encoding = \Fuel::$encoding; - is_null($double_encode) and $double_encode = \Config::get('security.htmlentities_double_encode', false); - - // Nothing to escape for non-string scalars, or for already processed values - if (is_bool($value) or is_int($value) or is_float($value) or in_array($value, $already_cleaned, true)) - { - return $value; - } - - if (is_string($value)) - { - $value = htmlentities($value, $flags, $encoding, $double_encode); - } - elseif (is_object($value) and $value instanceOf \Sanitization) - { - $value->sanitize(); - return $value; - - } - elseif (is_array($value) or ($value instanceof \Iterator and $value instanceof \ArrayAccess)) - { - // Add to $already_cleaned variable when object - is_object($value) and $already_cleaned[] = $value; - - foreach ($value as $k => $v) - { - $value[$k] = static::htmlentities($v, $flags, $encoding, $double_encode); - } - } - elseif ($value instanceof \Iterator or get_class($value) == 'stdClass') - { - // Add to $already_cleaned variable - $already_cleaned[] = $value; - - foreach ($value as $k => $v) - { - $value->{$k} = static::htmlentities($v, $flags, $encoding, $double_encode); - } - } - elseif (is_object($value)) - { - // Check if the object is whitelisted and return when that's the case - foreach (\Config::get('security.whitelisted_classes', array()) as $class) - { - if (is_a($value, $class)) - { - // Add to $already_cleaned variable - $already_cleaned[] = $value; - - return $value; - } - } - - // Throw exception when it wasn't whitelisted and can't be converted to String - if ( ! method_exists($value, '__toString')) - { - throw new \RuntimeException('Object class "'.get_class($value).'" could not be converted to string or '. - 'sanitized as ArrayAccess. Whitelist it in security.whitelisted_classes in app/config/config.php '. - 'to allow it to be passed unchecked.'); - } - - $value = static::htmlentities((string) $value, $flags, $encoding, $double_encode); - } - - return $value; - } - - /** - * Check CSRF Token - * - * @param string $value CSRF token to be checked, checks post when empty - * @return bool - */ - public static function check_token($value = null) - { - $value = $value ?: \Input::param(static::$csrf_token_key, \Input::json(static::$csrf_token_key, 'fail')); - - // always reset token once it's been checked and still the same - if (static::fetch_token() == static::$csrf_old_token and ! empty($value)) - { - static::set_token(true); - } - - return $value === static::$csrf_old_token; - } - - /** - * Fetch CSRF Token for the next request - * - * @return string - */ - public static function fetch_token() - { - if (static::$csrf_token !== false) - { - return static::$csrf_token; - } - - static::set_token(); - - return static::$csrf_token; - } - - /** - * Generate new token. Based on an example from OWASP - * - * @return string - */ - public static function generate_token() - { - // generate a random token base - if (function_exists('random_bytes')) - { - $token_base = \Config::get('security.token_salt', '') .random_bytes(64); - } - elseif (function_exists('openssl_random_pseudo_bytes')) - { - $token_base = \Config::get('security.token_salt', '') . openssl_random_pseudo_bytes(64); - } - else - { - $token_base = time() . uniqid() . \Config::get('security.token_salt', '') . mt_rand(0, mt_getrandmax()); - } - - // return the hashed token - if (function_exists('hash_algos')) - { - foreach (array('sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5') as $hash) - { - if (in_array($hash, hash_algos())) - { - return hash($hash, $token_base); - } - } - } - - // if all else fails - return md5($token_base); - } - - protected static function set_token($reset = false) - { - // re-use old token when found (= not expired) and expiration is used (otherwise always reset) - if ( ! $reset and static::$csrf_old_token and \Config::get('security.csrf_expiration', 0) > 0) - { - static::$csrf_token = static::$csrf_old_token; - } - // set new token for next session when necessary - else - { - static::$csrf_token = static::generate_token(); - - $expiration = \Config::get('security.csrf_expiration', 0); - \Cookie::set(static::$csrf_token_key, static::$csrf_token, $expiration); - } - } - - /** - * JS fetch token - * - * Produces JavaScript fuel_csrf_token() function that will return the current - * CSRF token when called. Use to fill right field on form submit for AJAX operations. - * - * @return string - */ - public static function js_fetch_token() - { - $output = ''.PHP_EOL; - - return $output; - } - - /** - * JS set token - * - * Produces JavaScript fuel_set_csrf_token() function that will update the current - * CSRF token in the form when called, based on the value of the csrf cookie - * - * @return string - */ - public static function js_set_token() - { - $output = ''.PHP_EOL; - - return $output; - } -} diff --git a/fuel/core/classes/session.php b/fuel/core/classes/session.php deleted file mode 100755 index 505d7b9..0000000 --- a/fuel/core/classes/session.php +++ /dev/null @@ -1,380 +0,0 @@ - 'cookie', - 'match_ip' => false, - 'match_ua' => true, - 'cookie_domain' => '', - 'cookie_path' => '/', - 'cookie_http_only' => null, - 'encrypt_cookie' => true, - 'expire_on_close' => false, - 'expiration_time' => 7200, - 'rotation_time' => 300, - 'flash_id' => 'flash', - 'flash_auto_expire' => true, - 'flash_expire_after_get' => true, - 'post_cookie_name' => '', - ); - - // -------------------------------------------------------------------- - - /** - * Initialize by loading config & starting default session - */ - public static function _init() - { - \Config::load('session', true); - - if (\Config::get('session.auto_initialize', true)) - { - static::instance(); - } - - if (\Config::get('session.native_emulation', false)) - { - // emulate native PHP sessions - session_set_save_handler( - // open - function ($savePath, $sessionName) { - }, - // close - function () { - }, - // read - function ($sessionId) { - // copy all existing session vars into the PHP session store - $_SESSION = \Session::get(); - $_SESSION['__org'] = $_SESSION; - }, - // write - function ($sessionId, $data) { - // get the original data - $org = isset($_SESSION['__org']) ? $_SESSION['__org'] : array(); - unset($_SESSION['__org']); - - // do we need to remove stuff? - if ($remove = array_diff_key($org, $_SESSION)) - { - \Session::delete(array_keys($remove)); - } - - // add or update the remainder - empty($_SESSION) or \Session::set($_SESSION); - }, - // destroy - function ($sessionId) { - \Session::destroy(); - }, - // gc - function ($lifetime) { - } - ); - } - } - - // -------------------------------------------------------------------- - - /** - * Factory - * - * Produces fully configured session driver instances - * - * @param array|string $custom full driver config or just driver type - * @return mixed - * @throws \FuelException - * @throws \Session_Exception - */ - public static function forge($custom = array()) - { - $config = \Config::get('session', array()); - - // When a string was passed it's just the driver type - if ( ! empty($custom) and ! is_array($custom)) - { - $custom = array('driver' => $custom); - } - - $config = array_merge(static::$_defaults, $config, $custom); - - if (empty($config['driver'])) - { - throw new \Session_Exception('No session driver given or no default session driver set.'); - } - - // determine the driver to load - $class = '\\Session_'.ucfirst($config['driver']); - - $driver = new $class($config); - - // get the driver's cookie name - $cookie = $driver->get_config('cookie_name'); - - // do we already have a driver instance for this cookie? - if (isset(static::$_instances[$cookie])) - { - // if so, they must be using the same driver class! - $class_instance = 'Fuel\\Core\\'.$class; - if (static::$_instances[$cookie] instanceof $class_instance) - { - throw new \FuelException('You can not instantiate two different sessions using the same cookie name "'.$cookie.'"'); - } - } - else - { - // register a shutdown event to update the session - \Event::register('fuel-shutdown', array($driver, 'write')); - - // init the session - $driver->init(); - $driver->read(); - - // store this instance - static::$_instances[$cookie] =& $driver; - } - - return static::$_instances[$cookie]; - } - - // -------------------------------------------------------------------- - - /** - * class constructor - * - * @param void - */ - final private function __construct() {} - - // -------------------------------------------------------------------- - - /** - * create or return the driver instance - * - * @param void - * @return \Session_Driver object - */ - public static function instance($instance = null) - { - if ($instance !== null) - { - if ( ! array_key_exists($instance, static::$_instances)) - { - return false; - } - - return static::$_instances[$instance]; - } - - if (static::$_instance === null) - { - static::$_instance = static::forge(); - } - - return static::$_instance; - } - - // -------------------------------------------------------------------- - - /** - * set session variables - * - * @param string|array $name name of the variable to set or array of values, array(name => value) - * @param mixed $value value - * @return \Session_Driver - */ - public static function set($name, $value = null) - { - return static::instance()->set($name, $value); - } - - // -------------------------------------------------------------------- - - /** - * get session variables - * - * @param string $name name of the variable to get - * @param mixed $default default value to return if the variable does not exist - * @return mixed - */ - public static function get($name = null, $default = null) - { - return static::instance()->get($name, $default); - } - - // -------------------------------------------------------------------- - - /** - * delete a session variable - * - * @param string $name name of the variable to delete - * @return Session_Driver - */ - public static function delete($name) - { - return static::instance()->delete($name); - } - - // -------------------------------------------------------------------- - - /** - * get session key variables - * - * @param string $name name of the variable to get, default is 'session_id' - * @return mixed - */ - public static function key($name = 'session_id') - { - return static::$_instance ? static::instance()->key($name) : null; - } - - // -------------------------------------------------------------------- - - /** - * set session flash variables - * - * @param string $name name of the variable to set - * @param mixed $value value - * @return void - */ - public static function set_flash($name, $value = null) - { - return static::instance()->set_flash($name, $value); - } - - // -------------------------------------------------------------------- - - /** - * get session flash variables - * - * @param string $name name of the variable to get - * @param mixed $default default value to return if the variable does not exist - * @param bool $expire true if the flash variable needs to expire immediately - * @return mixed - */ - public static function get_flash($name = null, $default = null, $expire = null) - { - return static::instance()->get_flash($name, $default, $expire); - } - - // -------------------------------------------------------------------- - - /** - * keep session flash variables - * - * @param string $name name of the variable to keep - * @return \Session_Driver - */ - public static function keep_flash($name = null) - { - return static::instance()->keep_flash($name); - } - - // -------------------------------------------------------------------- - - /** - * delete session flash variables - * - * @param string $name name of the variable to delete - * @return \Session_Driver - */ - public static function delete_flash($name = null) - { - return static::instance()->delete_flash($name); - } - - // -------------------------------------------------------------------- - - /** - * create a new session - * - * @return void - */ - public static function create() - { - return static::instance()->create(); - } - - // -------------------------------------------------------------------- - - /** - * read the session - * - * @return \Session_Driver - */ - public static function read() - { - return static::instance()->read(); - } - - // -------------------------------------------------------------------- - - /** - * write the session - * - * @return \Session_Driver - */ - public static function write() - { - return static::instance()->write(); - } - - // -------------------------------------------------------------------- - - /** - * rotate the session id - * - * @return \Session_Driver - */ - public static function rotate() - { - return static::instance()->rotate(); - } - - // -------------------------------------------------------------------- - - /** - * destroy the current session - * - * @return \Session_Driver - */ - public static function destroy() - { - return static::instance()->destroy(); - } - -} diff --git a/fuel/core/classes/session/cookie.php b/fuel/core/classes/session/cookie.php deleted file mode 100755 index 161fdd9..0000000 --- a/fuel/core/classes/session/cookie.php +++ /dev/null @@ -1,185 +0,0 @@ - 'fuelcid', - ); - - // -------------------------------------------------------------------- - - public function __construct($config = array()) - { - // merge the driver config with the global config - $this->config = array_merge($config, (isset($config['cookie']) and is_array($config['cookie'])) ? $config['cookie'] : static::$_defaults); - - $this->config = $this->_validate_config($this->config); - } - - // -------------------------------------------------------------------- - - /** - * create a new session - * - * @return \Session_Cookie - */ - public function create() - { - // create a new session - $this->keys['session_id'] = $this->_new_session_id(); - $this->keys['ip_hash'] = md5(\Input::ip().\Input::real_ip()); - $this->keys['user_agent'] = \Input::user_agent(); - $this->keys['created'] = $this->time->get_timestamp(); - $this->keys['updated'] = $this->keys['created']; - $this->keys['payload'] = ''; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * read the session - * - * @param boolean, set to true if we want to force a new session to be created - * @return \Session_Driver - */ - public function read($force = false) - { - // initialize the session - $this->data = array(); - $this->keys = array(); - $this->flash = array(); - - // get the session cookie - $payload = $this->_get_cookie(); - - // validate it - if ($force) - { - // a forced session reset - } - elseif ($payload === false) - { - // no cookie found - } - elseif ( ! isset($payload[0]) or ! is_array($payload[0])) - { - logger('DEBUG', 'Error: not a valid cookie payload!'); - } - elseif ($payload[0]['updated'] + $this->config['expiration_time'] <= $this->time->get_timestamp()) - { - logger('DEBUG', 'Error: session id has expired!'); - } - elseif ($this->config['match_ip'] and $payload[0]['ip_hash'] !== md5(\Input::ip().\Input::real_ip())) - { - logger('DEBUG', 'Error: IP address in the session doesn\'t match this requests source IP!'); - } - elseif ($this->config['match_ua'] and $payload[0]['user_agent'] !== \Input::user_agent()) - { - logger('DEBUG', 'Error: User agent in the session doesn\'t match the browsers user agent string!'); - } - else - { - // session is valid, retrieve the payload - if (isset($payload[0]) and is_array($payload[0])) - { - $this->keys = $payload[0]; - } - if (isset($payload[1]) and is_array($payload[1])) - { - $this->data = $payload[1]; - } - if (isset($payload[2]) and is_array($payload[2])) - { - $this->flash = $payload[2]; - } - } - - return parent::read(); - } - - // -------------------------------------------------------------------- - - /** - * write the current session - * - * @return \Session_Cookie - */ - public function write() - { - // do we have something to write? - if ( ! empty($this->keys) or ! empty($this->data) or ! empty($this->flash)) - { - parent::write(); - - // rotate the session id if needed - $this->rotate(false); - - // record the last update time of the session - $this->keys['updated'] = $this->time->get_timestamp(); - - // then update the cookie - $this->_set_cookie(array($this->keys, $this->data, $this->flash)); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * validate a driver config value - * - * @param array array with configuration values - * @return array validated and consolidated config - */ - public function _validate_config($config) - { - $validated = array(); - - foreach ($config as $name => $item) - { - // filter out any driver config - if (!is_array($item)) - { - switch ($name) - { - case 'cookie_name': - if ( empty($item) or ! is_string($item)) - { - $item = 'fuelcid'; - } - break; - - default: - // no config item for this driver - break; - } - - // global config, was validated in the driver - $validated[$name] = $item; - } - } - - // validate all global settings as well - return parent::_validate_config($validated); - } -} diff --git a/fuel/core/classes/session/db.php b/fuel/core/classes/session/db.php deleted file mode 100755 index 920fecc..0000000 --- a/fuel/core/classes/session/db.php +++ /dev/null @@ -1,357 +0,0 @@ - 'fueldid', // name of the session cookie for database based sessions - 'table' => 'sessions', // name of the sessions table - 'gc_probability' => 5, // probability % (between 0 and 100) for garbage collection - ); - - // -------------------------------------------------------------------- - - public function __construct($config = array()) - { - // merge the driver config with the global config - $this->config = array_merge($config, is_array($config['db']) ? $config['db'] : static::$_defaults); - - $this->config = $this->_validate_config($this->config); - } - - // -------------------------------------------------------------------- - - /** - * create a new session - * - * @return \Session_Db - */ - public function create($payload = '') - { - // create a new session - $this->keys['session_id'] = $this->_new_session_id(); - $this->keys['previous_id'] = $this->keys['session_id']; // prevents errors if previous_id has a unique index - $this->keys['ip_hash'] = md5(\Input::ip().\Input::real_ip()); - $this->keys['user_agent'] = \Input::user_agent(); - $this->keys['created'] = $this->time->get_timestamp(); - $this->keys['updated'] = $this->keys['created']; - - // add the payload - $this->keys['payload'] = $payload; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * read the session - * - * @param boolean, set to true if we want to force a new session to be created - * @return \Session_Driver - */ - public function read($force = false) - { - // initialize the session - $this->data = array(); - $this->keys = array(); - $this->flash = array(); - $this->record = null; - - // get the session cookie - $cookie = $this->_get_cookie(); - - // if a cookie was present, find the session record - if ($cookie and ! $force and isset($cookie[0])) - { - // read the session record - $this->record = \DB::select()->where('session_id', '=', $cookie[0])->from($this->config['table'])->execute($this->config['database']); - - // record found? - if ($this->record->count()) - { - $payload = $this->_unserialize($this->record->get('payload')); - } - else - { - // try to find the session on previous id - $this->record = \DB::select()->where('previous_id', '=', $cookie[0])->from($this->config['table'])->execute($this->config['database']); - - // record found? - if ($this->record->count()) - { - $payload = $this->_unserialize($this->record->get('payload')); - } - else - { - // cookie present, but session record missing. force creation of a new session - logger('DEBUG', 'Error: Session cookie with ID "'.$cookie[0].'" present but corresponding record is missing'); - return $this->read(true); - } - } - - if ( ! isset($payload[0]) or ! is_array($payload[0])) - { - logger('DEBUG', 'Error: not a valid db session payload!'); - } - elseif ($payload[0]['updated'] + $this->config['expiration_time'] <= $this->time->get_timestamp()) - { - logger('DEBUG', 'Error: session id has expired!'); - } - elseif ($this->config['match_ip'] and $payload[0]['ip_hash'] !== md5(\Input::ip().\Input::real_ip())) - { - logger('DEBUG', 'Error: IP address in the session doesn\'t match this requests source IP!'); - } - elseif ($this->config['match_ua'] and $payload[0]['user_agent'] !== \Input::user_agent()) - { - logger('DEBUG', 'Error: User agent in the session doesn\'t match the browsers user agent string!'); - } - else - { - // session is valid, retrieve the payload - if (isset($payload[0]) and is_array($payload[0])) - { - $this->keys = $payload[0]; - } - if (isset($payload[1]) and is_array($payload[1])) - { - $this->data = $payload[1]; - } - if (isset($payload[2]) and is_array($payload[2])) - { - $this->flash = $payload[2]; - } - } - } - - return parent::read(); - } - - // -------------------------------------------------------------------- - - /** - * write the current session - * - * @return $this - * @throws \Database_Exception - * @throws \FuelException - */ - public function write() - { - // do we have something to write? - if ( ! empty($this->keys) or ! empty($this->data) or ! empty($this->flash)) - { - parent::write(); - - // rotate the session id if needed - $this->rotate(false); - - // record the last update time of the session - $this->keys['updated'] = $this->time->get_timestamp(); - - // add a random identifier, we need the payload to be absolutely unique - $this->flash[$this->config['flash_id'].'::__session_identifier__'] = array('state' => 'expire', 'value' => sha1(uniqid(rand(), true))); - - // create the session record, and add the session payload - $session = $this->keys; - $session['payload'] = $this->_serialize(array($this->keys, $this->data, $this->flash)); - - try - { - // do we need to create a new session? - if (is_null($this->record)) - { - // create the new session record - list($notused, $result) = \DB::insert($this->config['table'], array_keys($session))->values($session)->execute($this->config['database']); - } - else - { - // update the database - $result = \DB::update($this->config['table'])->set($session)->where('session_id', '=', $this->record->get('session_id'))->execute($this->config['database']); - - // if it failed, perhaps we have lost a session id due to rotation? - if ($result === 0) - { - // if so, there must be a session record with our session_id as previous_id - $result = \DB::select()->where('previous_id', '=', $this->record->get('session_id'))->from($this->config['table'])->execute($this->config['database']); - if ($result->count()) - { - logger(\Fuel::L_WARNING, 'Session update failed, session record recovered using previous id. Lost rotation data?'); - - // update the session data - $this->keys['session_id'] = $result->get('session_id'); - $this->keys['previous_id'] = $result->get('previous_id'); - - // and recreate the payload - $session = $this->keys; - $session['payload'] = $this->_serialize(array($this->keys, $this->data, $this->flash)); - - // and update the database - $result = \DB::update($this->config['table'])->set($session)->where('session_id', '=', $this->keys['session_id'])->execute($this->config['database']); - } - else - { - logger(\Fuel::L_ERROR, 'Session update failed, session record could not be recovered using the previous id'); - $result = false; - } - } - } - - // update went well? - if ($result !== 0) - { - // then update the cookie - $this->_set_cookie(array($this->keys['session_id'])); - } - - // Run garbage collector - $this->gc(); - } - catch (Database_Exception $e) - { - // strip the actual query from the message - $msg = $e->getMessage(); - $msg = substr($msg, 0, strlen($msg) - strlen(strrchr($msg, ':'))); - - // and rethrow it - throw new \Database_Exception($msg); - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Garbage Collector - * - * @return bool - */ - public function gc() - { - if (mt_rand(0, 100) < $this->config['gc_probability']) - { - $expired = $this->time->get_timestamp() - $this->config['expiration_time']; - $result = \DB::delete($this->config['table'])->where('updated', '<', $expired)->execute($this->config['database']); - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * destroy the current session - * - * @return \Session_Db - */ - public function destroy() - { - // do we have something to destroy? - if ( ! empty($this->keys) and ! empty($this->record)) - { - // delete the session record - $result = \DB::delete($this->config['table'])->where('session_id', '=', $this->keys['session_id'])->execute($this->config['database']); - } - - // reset the stored session data - $this->record = null; - - parent::destroy(); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * validate a driver config value - * - * @param array $config array with configuration values - * @return array validated and consolidated config - * @throws \FuelException - */ - public function _validate_config($config) - { - $validated = array(); - - foreach ($config as $name => $item) - { - // filter out any driver config - if (!is_array($item)) - { - switch ($name) - { - case 'cookie_name': - if ( empty($item) or ! is_string($item)) - { - $item = 'fueldid'; - } - break; - - case 'database': - // do we have a database? - if ( empty($item) or ! is_string($item)) - { - \Config::load('db', true); - $item = \Config::get('db.active', false); - } - if ($item === false) - { - throw new \FuelException('You have specify a database to use database backed sessions.'); - } - break; - - case 'table': - // and a table name? - if ( empty($item) or ! is_string($item)) - { - throw new \FuelException('You have specify a database table name to use database backed sessions.'); - } - break; - - case 'gc_probability': - // do we have a path? - if ( ! is_numeric($item) or $item < 0 or $item > 100) - { - // default value: 5% - $item = 5; - } - break; - - default: - break; - } - - // global config, was validated in the driver - $validated[$name] = $item; - } - } - - // validate all global settings as well - return parent::_validate_config($validated); - } - -} diff --git a/fuel/core/classes/session/driver.php b/fuel/core/classes/session/driver.php deleted file mode 100755 index d9f61e7..0000000 --- a/fuel/core/classes/session/driver.php +++ /dev/null @@ -1,712 +0,0 @@ -config['cookie_name'], $this->config['cookie_path'], $this->config['cookie_domain'], null, $this->config['cookie_http_only']); - - // reset the stored session data - $this->keys = $this->flash = $this->data = array(); - - return $this; - } - - /** - * read the session - * - * @return \Session_Driver - */ - public function read() - { - // do we need to create a new session? - empty($this->keys) and $this->create(); - - // mark the loaded flash data, auto-expire if configured - foreach($this->flash as $key => $value) - { - if ($this->config['flash_auto_expire'] === true) - { - $this->flash[$key]['state'] = 'expire'; - } - else - { - $this->flash[$key]['state'] = 'loaded'; - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * write the session - * - * @return \Session_Driver - */ - public function write() - { - // create the session if it doesn't exist - empty($this->keys) and $this->create(); - - $this->_cleanup_flash(); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * generic driver initialisation - * - * @return void - */ - public function init() - { - // get a time object - $this->time = \Date::time(); - } - - // -------------------------------------------------------------------- - - /** - * set session variables - * - * @param string|array $name name of the variable to set or array of values, array(name => value) - * @param mixed $value value - * @return \Session_Driver - */ - public function set($name, $value = null) - { - is_null($name) or \Arr::set($this->data, $name, $value); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * get session variables - * - * @param string $name name of the variable to get - * @param mixed $default default value to return if the variable does not exist - * @return mixed - */ - public function get($name, $default = null) - { - if (is_null($name)) - { - return $this->data; - } - return \Arr::get($this->data, $name, $default); - } - - // -------------------------------------------------------------------- - - /** - * get session key variables - * - * @param string $name name of the variable to get, default is 'session_id' - * @return mixed contents of the requested variable, or false if not found - */ - public function key($name = 'session_id') - { - return isset($this->keys[$name]) ? $this->keys[$name] : false; - } - - // -------------------------------------------------------------------- - - /** - * delete session variables - * - * @param string $name name of the variable to delete - * @return \Session_Driver - */ - public function delete($name) - { - \Arr::delete($this->data, $name); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * force a session_id rotation - * - * @param bool $force if true, force a session id rotation - * @return \Session_Driver - */ - public function rotate($force = true) - { - // do we have a session? - if ( ! empty($this->keys)) - { - // existing session. need to rotate the session id? - if ($force or ($this->config['rotation_time'] and $this->keys['created'] + $this->config['rotation_time'] <= $this->time->get_timestamp())) - { - // generate a new session id, and update the create timestamp - $this->keys['previous_id'] = $this->keys['session_id']; - $this->keys['session_id'] = $this->_new_session_id(); - $this->keys['created'] = $this->time->get_timestamp(); - $this->keys['updated'] = $this->keys['created']; - } - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * set session flash variables - * - * @param string $name name of the variable to set - * @param mixed $value value - * @return \Session_Driver - */ - public function set_flash($name, $value) - { - if (strpos($name, '.') !== false) - { - $keys = explode('.', $name, 2); - $name = array_shift($keys); - } - else - { - $keys = false; - } - - if ($keys) - { - if (isset($this->flash[$this->config['flash_id'].'::'.$name]['value'])) - { - $this->flash[$this->config['flash_id'].'::'.$name]['state'] = 'new'; - } - else - { - $this->flash[$this->config['flash_id'].'::'.$name] = array('state' => 'new', 'value' => array()); - } - \Arr::set($this->flash[$this->config['flash_id'].'::'.$name]['value'], $keys[0], $value); - } - else - { - $this->flash[$this->config['flash_id'].'::'.$name] = array('state' => 'new', 'value' => $value); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * get session flash variables - * - * @param string $name name of the variable to get - * @param mixed $default default value to return if the variable does not exist - * @param bool $expire true if the flash variable needs to expire immediately, false to use "flash_auto_expire" - * @return mixed - */ - public function get_flash($name, $default = null, $expire = null) - { - // if no expiration is given, use the config default - is_bool($expire) or $expire = $this->config['flash_expire_after_get']; - - if (is_null($name)) - { - $default = array(); - foreach($this->flash as $key => $value) - { - $key = substr($key, strpos($key, '::')+2); - $default[$key] = $value; - } - } - else - { - // check if we need to run an Arr:get() - if (strpos($name, '.') !== false) - { - $keys = explode('.', $name, 2); - $name = array_shift($keys); - } - else - { - $keys = false; - } - - if (isset($this->flash[$this->config['flash_id'].'::'.$name])) - { - // if it's not a var set in this request, mark it for expiration - if ($this->flash[$this->config['flash_id'].'::'.$name]['state'] !== 'new' or $expire) - { - $this->flash[$this->config['flash_id'].'::'.$name]['state'] = 'expire'; - } - - if ($keys) - { - $default = \Arr::get($this->flash[$this->config['flash_id'].'::'.$name]['value'], $keys[0], $default); - } - else - { - $default = $this->flash[$this->config['flash_id'].'::'.$name]['value']; - } - } - } - - return ($default instanceof \Closure) ? $default() : $default; - } - - // -------------------------------------------------------------------- - - /** - * keep session flash variables - * - * @param string $name name of the variable to keep - * @return \Session_Driver - */ - public function keep_flash($name) - { - if (is_null($name)) - { - foreach($this->flash as $key => $value) - { - $this->flash[$key]['state'] = 'new'; - } - } - elseif (isset($this->flash[$this->config['flash_id'].'::'.$name])) - { - $this->flash[$this->config['flash_id'].'::'.$name]['state'] = 'new'; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * delete session flash variables - * - * @param string $name name of the variable to delete - * @return \Session_Driver - */ - public function delete_flash($name) - { - if (is_null($name)) - { - $this->flash = array(); - } - elseif (isset($this->flash[$this->config['flash_id'].'::'.$name])) - { - unset($this->flash[$this->config['flash_id'].'::'.$name]); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * set the session flash id - * - * @param string $name name of the id to set - * @return \Session_Driver - */ - public function set_flash_id($name) - { - $this->config['flash_id'] = (string) $name; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * get the current session flash id - * - * @return string name of the flash id - */ - public function get_flash_id() - { - return $this->config['flash_id']; - } - - // -------------------------------------------------------------------- - - /** - * get a runtime config value - * - * @param string $name name of the config variable to get - * @return mixed - */ - public function get_config($name) - { - return isset($this->config[$name]) ? $this->config[$name] : null; - } - - // -------------------------------------------------------------------- - - /** - * set a runtime config value - * - * @param string $name name of the config variable to set - * @param mixed $value - * @return \Session_Driver - */ - public function set_config($name, $value = null) - { - if (isset($this->config[$name])) - { - $this->config[$name] = $value; - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * removes flash variables marked as old - * - * @return void - */ - protected function _cleanup_flash() - { - foreach($this->flash as $key => $value) - { - if ($value['state'] === 'expire') - { - unset($this->flash[$key]); - } - } - } - - // -------------------------------------------------------------------- - - /** - * generate a new session id - * - * @return string - */ - protected function _new_session_id() - { - return substr(\Security::generate_token(), 0, 32); - } - - // -------------------------------------------------------------------- - - /** - * write a cookie - * - * @param array $payload cookie payload - * @return mixed - * @throws \FuelException - */ - protected function _set_cookie($payload = array()) - { - if ($this->config['enable_cookie']) - { - $payload = $this->_serialize($payload); - - // encrypt the payload if needed - $this->config['encrypt_cookie'] and $payload = \Crypt::encode($payload); - - // make sure it doesn't exceed the cookie size specification - if (strlen($payload) > 4000) - { - throw new \FuelException('The session data stored by the application in the cookie exceeds 4Kb. Select a different session storage driver.'); - } - - // write the session cookie - if ($this->config['expire_on_close']) - { - return \Cookie::set($this->config['cookie_name'], $payload, 0, $this->config['cookie_path'], $this->config['cookie_domain'], null, $this->config['cookie_http_only']); - } - else - { - return \Cookie::set($this->config['cookie_name'], $payload, $this->config['expiration_time'], $this->config['cookie_path'], $this->config['cookie_domain'], null, $this->config['cookie_http_only']); - } - } - } - - // -------------------------------------------------------------------- - - /** - * read a cookie - * - * @return mixed - */ - protected function _get_cookie() - { - // was the cookie value posted? - $cookie = \Input::post($this->config['post_cookie_name'], false); - - // if not found, fetch the regular cookie - if ($cookie === false) - { - $cookie = \Cookie::get($this->config['cookie_name'], false); - } - - // if not found, was a session-id present in the HTTP header? - if ($cookie === false) - { - $cookie = \Input::headers($this->config['http_header_name'], false); - } - - // if not found, check the URL for a cookie - if ($cookie === false) - { - $cookie = \Input::get($this->config['cookie_name'], false); - } - - if ($cookie !== false) - { - // fetch the payload - $this->config['encrypt_cookie'] and $cookie = \Crypt::decode($cookie); - $cookie = $this->_unserialize($cookie); - - // validate the cookie format: must be an array - if (is_array($cookie)) - { - // cookies use nested arrays, other drivers have a string value - if (($this->config['driver'] === 'cookie' and ! is_array($cookie[0])) or - ($this->config['driver'] !== 'cookie' and ! is_string($cookie[0]))) - { - // invalid specific format - logger('DEBUG', 'Error: Invalid session cookie specific format'); - $cookie = false; - } - } - - // or a string containing the session id - elseif (is_string($cookie) and strlen($cookie) == 32) - { - $cookie = array($cookie); - } - - // invalid general format - else - { - logger('DEBUG', 'Error: Invalid session cookie general format'); - $cookie = false; - } - } - - // and the result - return $cookie; - } - - // -------------------------------------------------------------------- - - /** - * Serialize an array - * - * This function first converts any slashes found in the array to a temporary - * marker, so when it gets unserialized the slashes will be preserved - * - * @param array $data - * @return string - */ - protected function _serialize($data) - { - if (is_array($data)) - { - foreach ($data as $key => $val) - { - if (is_string($val)) - { - $data[$key] = str_replace('\\', '{{slash}}', $val); - } - } - } - else - { - if (is_string($data)) - { - $data = str_replace('\\', '{{slash}}', $data); - } - } - - return serialize($data); - } - - // -------------------------------------------------------------------- - - /** - * Unserialize - * - * This function unserializes a data string, then converts any - * temporary slash markers back to actual slashes - * - * @param array $input - * @return string - */ - protected function _unserialize($input) - { - $data = @unserialize($input); - - if (is_array($data)) - { - foreach ($data as $key => $val) - { - if (is_string($val)) - { - $data[$key] = str_replace('{{slash}}', '\\', $val); - } - } - - return $data; - } - - elseif ($data === false) - { - is_string($input) and $data = array($input); - } - - return (is_string($data)) ? str_replace('{{slash}}', '\\', $data) : $data; - } - - // -------------------------------------------------------------------- - - /** - * validate__config - * - * This function validates all global (driver independent) configuration values - * - * @param array $config - * @return array - */ - protected function _validate_config($config) - { - $validated = array(); - - foreach ($config as $name => $item) - { - switch($name) - { - case 'driver': - // if we get here, this one was ok... ;-) - break; - - case 'match_ip': - case 'match_ua': - case 'enable_cookie': - case 'cookie_http_only': - case 'encrypt_cookie': - case 'expire_on_close': - case 'flash_expire_after_get': - case 'flash_auto_expire': - case 'native_emulation': - // make sure it's a boolean - $item = (bool) $item; - break; - - case 'post_cookie_name': - case 'http_header_name': - case 'cookie_domain': - // make sure it's a string - $item = (string) $item; - break; - - case 'cookie_path': - // make sure it's a string - $item = (string) $item; - empty($item) and $item = '/'; - break; - - case 'expiration_time': - // make sure it's an integer - $item = (int) $item; - // invalid? set it to two years from now - $item <= 0 and $item = 86400 * 365 * 2; - break; - - case 'rotation_time': - if ($item !== false) - { - // make sure it's an integer - $item = (int) $item; - // invalid? set it to 5 minutes - $item <= 0 and $item = 300; - } - break; - - case 'flash_id': - // make sure it's a string - $item = (string) $item; - empty($item) and $item = 'flash'; - break; - - default: - // ignore this setting - break; - - } - - // store the validated result - $validated[$name] = $item; - } - - return $validated; - } - -} diff --git a/fuel/core/classes/session/exception.php b/fuel/core/classes/session/exception.php deleted file mode 100755 index 553eeb0..0000000 --- a/fuel/core/classes/session/exception.php +++ /dev/null @@ -1,15 +0,0 @@ - 'fuelfid', // name of the session cookie for file based sessions - 'path' => '/tmp', // path where the session files should be stored - 'gc_probability' => 5, // probability % (between 0 and 100) for garbage collection - ); - - // -------------------------------------------------------------------- - - public function __construct($config = array()) - { - // merge the driver config with the global config - $this->config = array_merge($config, is_array($config['file']) ? $config['file'] : static::$_defaults); - - $this->config = $this->_validate_config($this->config); - } - - // -------------------------------------------------------------------- - - /** - * create a new session - * - * @return \Session_File - */ - public function create() - { - // create a new session - $this->keys['session_id'] = $this->_new_session_id(); - $this->keys['previous_id'] = $this->keys['session_id']; // prevents errors if previous_id has a unique index - $this->keys['ip_hash'] = md5(\Input::ip().\Input::real_ip()); - $this->keys['user_agent'] = \Input::user_agent(); - $this->keys['created'] = $this->time->get_timestamp(); - $this->keys['updated'] = $this->keys['created']; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * read the session - * - * @param boolean, set to true if we want to force a new session to be created - * @return \Session_Driver - */ - public function read($force = false) - { - // initialize the session - $this->data = array(); - $this->keys = array(); - $this->flash = array(); - - // get the session cookie - $cookie = $this->_get_cookie(); - - // if a cookie was present, find the session record - if ($cookie and ! $force and isset($cookie[0])) - { - // read the session file - $payload = $this->_read_file($cookie[0]); - - if ($payload === false) - { - // cookie present, but session record missing. force creation of a new session - return $this->read(true); - } - - // unpack the payload - $payload = $this->_unserialize($payload); - - // session referral? - if (isset($payload['rotated_session_id'])) - { - $payload = $this->_read_file($payload['rotated_session_id']); - if ($payload === false) - { - // cookie present, but session record missing. force creation of a new session - return $this->read(true); - } - else - { - // unpack the payload - $payload = $this->_unserialize($payload); - } - } - - if ( ! isset($payload[0]) or ! is_array($payload[0])) - { - logger('DEBUG', 'Error: not a valid session file payload!'); - } - elseif ($payload[0]['updated'] + $this->config['expiration_time'] <= $this->time->get_timestamp()) - { - logger('DEBUG', 'Error: session id has expired!'); - } - elseif ($this->config['match_ip'] and $payload[0]['ip_hash'] !== md5(\Input::ip().\Input::real_ip())) - { - logger('DEBUG', 'Error: IP address in the session doesn\'t match this requests source IP!'); - } - elseif ($this->config['match_ua'] and $payload[0]['user_agent'] !== \Input::user_agent()) - { - logger('DEBUG', 'Error: User agent in the session doesn\'t match the browsers user agent string!'); - } - else - { - // session is valid, retrieve the payload - if (isset($payload[0]) and is_array($payload[0])) - { - $this->keys = $payload[0]; - } - if (isset($payload[1]) and is_array($payload[1])) - { - $this->data = $payload[1]; - } - if (isset($payload[2]) and is_array($payload[2])) - { - $this->flash = $payload[2]; - } - } - } - - return parent::read(); - } - - // -------------------------------------------------------------------- - - /** - * write the session - * - * @return \Session_File - */ - public function write() - { - // do we have something to write? - if ( ! empty($this->keys) or ! empty($this->data) or ! empty($this->flash)) - { - parent::write(); - - // rotate the session id if needed - $this->rotate(false); - - // record the last update time of the session - $this->keys['updated'] = $this->time->get_timestamp(); - - // session payload - $payload = $this->_serialize(array($this->keys, $this->data, $this->flash)); - - // create the session file - $this->_write_file($this->keys['session_id'], $payload); - - // was the session id rotated? - if ( isset($this->keys['previous_id']) and $this->keys['previous_id'] != $this->keys['session_id']) - { - // point the old session file to the new one, we don't want to lose the session - $payload = $this->_serialize(array('rotated_session_id' => $this->keys['session_id'])); - $this->_write_file($this->keys['previous_id'], $payload); - } - - // then update the cookie - $this->_set_cookie(array($this->keys['session_id'])); - - // Run garbage collector - $this->gc(); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * destroy the current session - * - * @return \Session_File - */ - public function destroy() - { - // do we have something to destroy? - if ( ! empty($this->keys)) - { - // delete the session file - $file = $this->config['path'].$this->config['cookie_name'].'_'.$this->keys['session_id']; - if (is_file($file)) - { - unlink($file); - } - } - - parent::destroy(); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Garbage Collector - * - * @return bool - */ - public function gc() - { - // do some garbage collection - if (mt_rand(0, 100) < $this->config['gc_probability']) - { - if ($handle = opendir($this->config['path'])) - { - $expire = $this->time->get_timestamp() - $this->config['expiration_time']; - - while (($file = readdir($handle)) !== false) - { - if (filetype($this->config['path'] . $file) == 'file' and - strpos($file, $this->config['cookie_name'].'_') === 0 and - filemtime($this->config['path'] . $file) < $expire) - { - @unlink($this->config['path'] . $file); - } - } - - closedir($handle); - } - } - - return true; - } - - // -------------------------------------------------------------------- - - /** - * Writes the session file - * - * @param $session_id - * @param $payload - * @return boolean, true if it was an existing session, false if not - * @throws \FuelException - */ - protected function _write_file($session_id, $payload) - { - // create the session file - $file = $this->config['path'].$this->config['cookie_name'].'_'.$session_id; - $exists = is_file($file); - $handle = fopen($file, 'c'); - if ($handle) - { - // wait for a lock - while( ! flock($handle, LOCK_EX)); - - // erase existing contents - ftruncate($handle, 0); - - // write the session data - fwrite($handle, $payload); - - // flush any pending output - fflush($handle); - - // release the lock - flock($handle, LOCK_UN); - - // close the file - fclose($handle); - } - else - { - throw new \FuelException('Could not open the session file in "'.$this->config['path']." for write access"); - } - - return $exists; - } - - // -------------------------------------------------------------------- - - /** - * Reads the session file - * - * @param $session_id - * @return mixed, the payload if the file exists, or false if not - */ - protected function _read_file($session_id) - { - $payload = false; - - $file = $this->config['path'].$this->config['cookie_name'].'_'.$session_id; - - // normalize the file - $file = realpath($file); - - // make sure it exists and is in the config path - if (is_file($file) and strpos($file, $this->config['path']) === 0) - { - $handle = fopen($file, 'r'); - if ($handle) - { - // wait for a lock - while( ! flock($handle, LOCK_SH)); - - // read the session data - $payload = file_get_contents($file); - - //release the lock - flock($handle, LOCK_UN); - - // close the file - fclose($handle); - - } - } - - // only return the payload if it looks like a serialized array - return strpos($payload, 'a:') === 0 ? $payload : false; - } - - // -------------------------------------------------------------------- - - /** - * validate a driver config value - * - * @param array $config array with configuration values - * @return array validated and consolidated config - * @throws \FuelException - */ - public function _validate_config($config) - { - $validated = array(); - - foreach ($config as $name => $item) - { - // filter out any driver config - if (!is_array($item)) - { - switch ($name) - { - case 'cookie_name': - if ( empty($item) OR ! is_string($item)) - { - $item = 'fuelfid'; - } - break; - - case 'path': - // do we have a path? - if ( empty($item) OR ! is_dir($item)) - { - throw new \FuelException('You have specify a valid path to store the session data files.'); - } - // and can we write to it? - if ( ! is_writable($item)) - { - throw new \FuelException('The webserver doesn\'t have write access to the path to store the session data files.'); - } - // update the path, and add the trailing slash - $item = realpath($item).'/'; - break; - - case 'gc_probability': - // do we have a path? - if ( ! is_numeric($item) OR $item < 0 OR $item > 100) - { - // default value: 5% - $item = 5; - } - break; - - default: - // no config item for this driver - break; - } - - // global config, was validated in the driver - $validated[$name] = $item; - } - } - - // validate all global settings as well - return parent::_validate_config($validated); - } -} diff --git a/fuel/core/classes/session/memcached.php b/fuel/core/classes/session/memcached.php deleted file mode 100755 index 6a7c1eb..0000000 --- a/fuel/core/classes/session/memcached.php +++ /dev/null @@ -1,372 +0,0 @@ - 'fuelmid', // name of the session cookie for memcached based sessions - 'servers' => array( // array of servers and portnumbers that run the memcached service - array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100), - ), - ); - - /* - * @var storage for the memcached object - */ - protected $memcached = false; - - // -------------------------------------------------------------------- - - public function __construct($config = array()) - { - // merge the driver config with the global config - $this->config = array_merge($config, is_array($config['memcached']) ? $config['memcached'] : static::$_defaults); - - $this->config = $this->_validate_config($this->config); - - // adjust the expiration time to the maximum possible for memcached - $this->config['expiration_time'] = min($this->config['expiration_time'], 2592000); - } - - // -------------------------------------------------------------------- - - /** - * driver initialisation - * - * @throws \FuelException - */ - public function init() - { - // generic driver initialisation - parent::init(); - - if ($this->memcached === false) - { - // do we have the PHP memcached extension available - if ( ! class_exists('Memcached') ) - { - throw new \FuelException('Memcached sessions are configured, but your PHP installation doesn\'t have the Memcached extension loaded.'); - } - - // instantiate the memcached object - $this->memcached = new \Memcached(); - - // add the configured servers - $this->memcached->addServers($this->config['servers']); - - // check if we can connect to all the server(s) - $added = $this->memcached->getStats(); - foreach ($this->config['servers'] as $server) - { - $server = $server['host'].':'.$server['port']; - if ( ! isset($added[$server]) or $added[$server]['pid'] == -1) - { - throw new \FuelException('Memcached sessions are configured, but there is no connection possible. Check your configuration.'); - } - } - } - } - - // -------------------------------------------------------------------- - - /** - * create a new session - * - * @return \Session_Memcached - */ - public function create() - { - // create a new session - $this->keys['session_id'] = $this->_new_session_id(); - $this->keys['previous_id'] = $this->keys['session_id']; // prevents errors if previous_id has a unique index - $this->keys['ip_hash'] = md5(\Input::ip().\Input::real_ip()); - $this->keys['user_agent'] = \Input::user_agent(); - $this->keys['created'] = $this->time->get_timestamp(); - $this->keys['updated'] = $this->keys['created']; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * read the session - * - * @param bool $force set to true if we want to force a new session to be created - * @return \Session_Driver - */ - public function read($force = false) - { - // initialize the session - $this->data = array(); - $this->keys = array(); - $this->flash = array(); - - // get the session cookie - $cookie = $this->_get_cookie(); - - // if a cookie was present, find the session record - if ($cookie and ! $force and isset($cookie[0])) - { - // read the session file - $payload = $this->_read_memcached($cookie[0]); - - if ($payload === false) - { - // cookie present, but session record missing. force creation of a new session - return $this->read(true); - } - - // unpack the payload - $payload = $this->_unserialize($payload); - - // session referral? - if (isset($payload['rotated_session_id'])) - { - $payload = $this->_read_memcached($payload['rotated_session_id']); - if ($payload === false) - { - // cookie present, but session record missing. force creation of a new session - return $this->read(true); - } - else - { - // unpack the payload - $payload = $this->_unserialize($payload); - } - } - - if ( ! isset($payload[0]) or ! is_array($payload[0])) - { - logger('DEBUG', 'Error: not a valid memcached payload!'); - } - elseif ($payload[0]['updated'] + $this->config['expiration_time'] <= $this->time->get_timestamp()) - { - logger('DEBUG', 'Error: session id has expired!'); - } - elseif ($this->config['match_ip'] and $payload[0]['ip_hash'] !== md5(\Input::ip().\Input::real_ip())) - { - logger('DEBUG', 'Error: IP address in the session doesn\'t match this requests source IP!'); - } - elseif ($this->config['match_ua'] and $payload[0]['user_agent'] !== \Input::user_agent()) - { - logger('DEBUG', 'Error: User agent in the session doesn\'t match the browsers user agent string!'); - } - else - { - // session is valid, retrieve the rest of the payload - if (isset($payload[0]) and is_array($payload[0])) - { - $this->keys = $payload[0]; - } - if (isset($payload[1]) and is_array($payload[1])) - { - $this->data = $payload[1]; - } - if (isset($payload[2]) and is_array($payload[2])) - { - $this->flash = $payload[2]; - } - } - } - - return parent::read(); - } - - // -------------------------------------------------------------------- - - /** - * write the session - * - * @return \Session_Memcached - */ - public function write() - { - // do we have something to write? - if ( ! empty($this->keys) or ! empty($this->data) or ! empty($this->flash)) - { - parent::write(); - - // rotate the session id if needed - $this->rotate(false); - - // record the last update time of the session - $this->keys['updated'] = $this->time->get_timestamp(); - - // session payload - $payload = $this->_serialize(array($this->keys, $this->data, $this->flash)); - - // create the session file - $this->_write_memcached($this->keys['session_id'], $payload); - - // was the session id rotated? - if ( isset($this->keys['previous_id']) and $this->keys['previous_id'] != $this->keys['session_id']) - { - // point the old session file to the new one, we don't want to lose the session - $payload = $this->_serialize(array('rotated_session_id' => $this->keys['session_id'])); - $this->_write_memcached($this->keys['previous_id'], $payload); - } - - $this->_set_cookie(array($this->keys['session_id'])); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * destroy the current session - * - * @return $this - * @throws \FuelException - */ - public function destroy() - { - // do we have something to destroy? - if ( ! empty($this->keys)) - { - // delete the key from the memcached server - if ($this->memcached->delete($this->config['cookie_name'].'_'.$this->keys['session_id']) === false) - { - throw new \FuelException('Memcached returned error code "'.$this->memcached->getResultCode().'" on delete. Check your configuration.'); - } - } - - parent::destroy(); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Writes the memcached entry - * - * @param $session_id - * @param $payload - * @throws \FuelException - */ - protected function _write_memcached($session_id, $payload) - { - // write it to the memcached server - if ($this->memcached->set($this->config['cookie_name'].'_'.$session_id, $payload, $this->config['expiration_time']) === false) - { - throw new \FuelException('Memcached returned error code "'.$this->memcached->getResultCode().'" on write. Check your configuration.'); - } - } - - // -------------------------------------------------------------------- - - /** - * Reads the memcached entry - * - * @param $session_id - * @return mixed the payload if the file exists, or false if not - */ - protected function _read_memcached($session_id) - { - // fetch the session data from the Memcached server - return $this->memcached->get($this->config['cookie_name'].'_'.$session_id); - } - - // -------------------------------------------------------------------- - - /** - * validate a driver config value - * - * @param array $config array with configuration values - * @return array validated and consolidated config - * @throws \FuelException - */ - public function _validate_config($config) - { - $validated = array(); - - foreach ($config as $name => $item) - { - if ($name == 'memcached' and is_array($item)) - { - foreach ($item as $name => $value) - { - switch ($name) - { - case 'cookie_name': - if ( empty($value) or ! is_string($value)) - { - $value = 'fuelmid'; - } - break; - - case 'servers': - // do we have a servers config - if ( empty($value) or ! is_array($value)) - { - $value = array('default' => array('host' => '127.0.0.1', 'port' => '11211')); - } - - // validate the servers - foreach ($value as $key => $server) - { - // do we have a host? - if ( ! isset($server['host']) or ! is_string($server['host'])) - { - throw new \FuelException('Invalid Memcached server definition in the session configuration.'); - } - // do we have a port number? - if ( ! isset($server['port']) or ! is_numeric($server['port']) or $server['port'] < 1025 or $server['port'] > 65535) - { - throw new \FuelException('Invalid Memcached server definition in the session configuration.'); - } - // do we have a relative server weight? - if ( ! isset($server['weight']) or ! is_numeric($server['weight']) or $server['weight'] < 0) - { - // set a default - $value[$key]['weight'] = 0; - } - } - break; - - default: - // unknown property - continue; - } - - $validated[$name] = $value; - } - } - else - { - // skip all config array properties - if (is_array($item)) - { - continue; - } - - // global config, was validated in the driver - $validated[$name] = $item; - } - - } - - // validate all global settings as well - return parent::_validate_config($validated); - } - -} diff --git a/fuel/core/classes/session/redis.php b/fuel/core/classes/session/redis.php deleted file mode 100755 index 46094fc..0000000 --- a/fuel/core/classes/session/redis.php +++ /dev/null @@ -1,303 +0,0 @@ - 'fuelrid', // name of the session cookie for redis based sessions - 'database' => 'default', // name of the redis database to use (as configured in config/db.php) - ); - - /* - * @var storage for the redis object - */ - protected $redis = false; - - // -------------------------------------------------------------------- - - public function __construct($config = array()) - { - // merge the driver config with the global config - $this->config = array_merge($config, is_array($config['redis']) ? $config['redis'] : static::$_defaults); - - $this->config = $this->_validate_config($this->config); - } - - // -------------------------------------------------------------------- - - /** - * driver initialisation - * - * @return void - */ - public function init() - { - // generic driver initialisation - parent::init(); - - if ($this->redis === false) - { - // get the redis database instance - $this->redis = \Redis_Db::instance($this->config['database']); - } - } - - // -------------------------------------------------------------------- - - /** - * create a new session - * - * @return $this - */ - public function create() - { - // create a new session - $this->keys['session_id'] = $this->_new_session_id(); - $this->keys['previous_id'] = $this->keys['session_id']; // prevents errors if previous_id has a unique index - $this->keys['ip_hash'] = md5(\Input::ip().\Input::real_ip()); - $this->keys['user_agent'] = \Input::user_agent(); - $this->keys['created'] = $this->time->get_timestamp(); - $this->keys['updated'] = $this->keys['created']; - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * read the session - * - * @param bool $force set to true if we want to force a new session to be created - * @return \Session_Driver - * @throws \FuelException - */ - public function read($force = false) - { - // initialize the session - $this->data = array(); - $this->keys = array(); - $this->flash = array(); - - // get the session cookie - $cookie = $this->_get_cookie(); - - // if a cookie was present, find the session record - if ($cookie and ! $force and isset($cookie[0])) - { - // read the session file - $payload = $this->_read_redis($cookie[0]); - - if ($payload === false) - { - // cookie present, but session record missing. force creation of a new session - return $this->read(true); - } - - // unpack the payload - $payload = $this->_unserialize($payload); - - // session referral? - if (isset($payload['rotated_session_id'])) - { - $payload = $this->_read_redis($payload['rotated_session_id']); - if ($payload === false) - { - // cookie present, but session record missing. force creation of a new session - return $this->read(true); - } - - // unpack the payload - $payload = $this->_unserialize($payload); - } - - if ( ! isset($payload[0]) or ! is_array($payload[0])) - { - logger('DEBUG', 'Error: not a valid redis session payload!'); - } - elseif ($payload[0]['updated'] + $this->config['expiration_time'] <= $this->time->get_timestamp()) - { - logger('DEBUG', 'Error: session id has expired!'); - } - elseif ($this->config['match_ip'] and $payload[0]['ip_hash'] !== md5(\Input::ip().\Input::real_ip())) - { - logger('DEBUG', 'Error: IP address in the session doesn\'t match this requests source IP!'); - } - elseif ($this->config['match_ua'] and $payload[0]['user_agent'] !== \Input::user_agent()) - { - logger('DEBUG', 'Error: User agent in the session doesn\'t match the browsers user agent string!'); - } - else - { - // session is valid, retrieve the rest of the payload - if (isset($payload[0]) and is_array($payload[0])) - { - $this->keys = $payload[0]; - } - if (isset($payload[1]) and is_array($payload[1])) - { - $this->data = $payload[1]; - } - if (isset($payload[2]) and is_array($payload[2])){ - $this->flash = $payload[2]; - } - } - } - - return parent::read(); - } - - // -------------------------------------------------------------------- - - /** - * write the session - * - * @return \Session_Redis - */ - public function write() - { - // do we have something to write? - if ( ! empty($this->keys) or ! empty($this->data) or ! empty($this->flash)) - { - parent::write(); - - // rotate the session id if needed - $this->rotate(false); - - // record the last update time of the session - $this->keys['updated'] = $this->time->get_timestamp(); - - // session payload - $payload = $this->_serialize(array($this->keys, $this->data, $this->flash)); - - // create the session file - $this->_write_redis($this->keys['session_id'], $payload); - - // was the session id rotated? - if ( isset($this->keys['previous_id']) and $this->keys['previous_id'] != $this->keys['session_id']) - { - // point the old session file to the new one, we don't want to lose the session - $payload = $this->_serialize(array('rotated_session_id' => $this->keys['session_id'])); - $this->_write_redis($this->keys['previous_id'], $payload); - } - - $this->_set_cookie(array($this->keys['session_id'])); - } - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * destroy the current session - * - * @return \Session_Redis - */ - public function destroy() - { - // do we have something to destroy? - if ( ! empty($this->keys)) - { - // delete the key from the redis server - $this->redis->del($this->keys['session_id']); - } - - parent::destroy(); - - return $this; - } - - // -------------------------------------------------------------------- - - /** - * Writes the redis entry - * - * @param $session_id - * @param $payload - * @return boolean, true if it was an existing session, false if not - */ - protected function _write_redis($session_id, $payload) - { - // write it to the redis server - $this->redis->set($session_id, $payload); - $this->redis->expire($session_id, $this->config['expiration_time']); - } - - // -------------------------------------------------------------------- - - /** - * Reads the redis entry - * - * @param $session_id - * @return mixed, the payload if the file exists, or false if not - */ - protected function _read_redis($session_id) - { - // fetch the session data from the redis server - return $this->redis->get($session_id); - } - - // -------------------------------------------------------------------- - - /** - * validate a driver config value - * - * @param array array with configuration values - * @return array validated and consolidated config - */ - public function _validate_config($config) - { - $validated = array(); - - foreach ($config as $name => $item) - { - // filter out any driver config - if (!is_array($item)) - { - switch ($item) - { - case 'cookie_name': - if ( empty($item) or ! is_string($item)) - { - $item = 'fuelrid'; - } - break; - - case 'database': - // do we have a servers config - if ( empty($item) or ! is_array($item)) - { - $item = 'default'; - } - break; - - default: - break; - } - - // global config, was validated in the driver - $validated[$name] = $item; - } - } - - // validate all global settings as well - return parent::_validate_config($validated); - } - -} diff --git a/fuel/core/classes/str.php b/fuel/core/classes/str.php deleted file mode 100755 index 71961b8..0000000 --- a/fuel/core/classes/str.php +++ /dev/null @@ -1,448 +0,0 @@ - $match) - { - $matches[$index][0][1] -= $correction; - $correction += (strlen($match[0][0]) - mb_strlen($match[0][0])); - } - } - foreach ($matches as $match) - { - if ($match[0][1] >= $limit) - { - break; - } - $limit += (static::length($match[0][0]) - 1); - } - - // Handle all the html tags. - preg_match_all('/<[^>]+>([^<]*)/', $string, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); - // fix preg_match_all broken multibyte support - if (MBSTRING and strlen($string !== mb_strlen($string))) - { - $correction = 0; - foreach ($matches as $index => $match) - { - $matches[$index][0][1] -= $correction; - $matches[$index][1][1] -= $correction; - $correction += (strlen($match[0][0]) - mb_strlen($match[0][0])); - } - } - foreach ($matches as $match) - { - if($match[0][1] - $offset >= $limit) - { - break; - } - $tag = static::sub(strtok($match[0][0], " \t\n\r\0\x0B>"), 1); - if($tag[0] != '/') - { - $tags[] = $tag; - } - elseif (end($tags) == static::sub($tag, 1)) - { - array_pop($tags); - } - $offset += $match[1][1] - $match[0][1]; - } - } - $new_string = static::sub($string, 0, $limit = min(static::length($string), $limit + $offset)); - $new_string .= (static::length($string) > $limit ? $continuation : ''); - $new_string .= (count($tags = array_reverse($tags)) ? '' : ''); - return $new_string; - } - - /** - * Add's _1 to a string or increment the ending number to allow _2, _3, etc - * - * @param string $str required - * @param int $first number that is used to mean first - * @param string $separator separtor between the name and the number - * @return string - */ - public static function increment($str, $first = 1, $separator = '_') - { - preg_match('/(.+)'.$separator.'([0-9]+)$/', $str, $match); - - return isset($match[2]) ? $match[1].$separator.($match[2] + 1) : $str.$separator.$first; - } - - /** - * Checks whether a string has a precific beginning. - * - * @param string $str string to check - * @param string $start beginning to check for - * @param boolean $ignore_case whether to ignore the case - * @return boolean whether a string starts with a specified beginning - */ - public static function starts_with($str, $start, $ignore_case = false) - { - return (bool) preg_match('/^'.preg_quote($start, '/').'/m'.($ignore_case ? 'i' : ''), $str); - } - - /** - * Checks whether a string has a precific ending. - * - * @param string $str string to check - * @param string $end ending to check for - * @param boolean $ignore_case whether to ignore the case - * @return boolean whether a string ends with a specified ending - */ - public static function ends_with($str, $end, $ignore_case = false) - { - return (bool) preg_match('/'.preg_quote($end, '/').'$/m'.($ignore_case ? 'i' : ''), $str); - } - - /** - * substr - * - * @param string $str required - * @param int $start required - * @param int|null $length - * @param string $encoding default UTF-8 - * @return string - */ - public static function sub($str, $start, $length = null, $encoding = null) - { - $encoding or $encoding = \Fuel::$encoding; - - // substr functions don't parse null correctly - $length = is_null($length) ? (MBSTRING ? mb_strlen($str, $encoding) : strlen($str)) - $start : $length; - - return MBSTRING - ? mb_substr($str, $start, $length, $encoding) - : substr($str, $start, $length); - } - - /** - * strlen - * - * @param string $str required - * @param string $encoding default UTF-8 - * @return int - */ - public static function length($str, $encoding = null) - { - $encoding or $encoding = \Fuel::$encoding; - - return MBSTRING - ? mb_strlen($str, $encoding) - : strlen($str); - } - - /** - * lower - * - * @param string $str required - * @param string $encoding default UTF-8 - * @return string - */ - public static function lower($str, $encoding = null) - { - $encoding or $encoding = \Fuel::$encoding; - - return MBSTRING - ? mb_strtolower($str, $encoding) - : strtolower($str); - } - - /** - * upper - * - * @param string $str required - * @param string $encoding default UTF-8 - * @return string - */ - public static function upper($str, $encoding = null) - { - $encoding or $encoding = \Fuel::$encoding; - - return MBSTRING - ? mb_strtoupper($str, $encoding) - : strtoupper($str); - } - - /** - * lcfirst - * - * Does not strtoupper first - * - * @param string $str required - * @param string $encoding default UTF-8 - * @return string - */ - public static function lcfirst($str, $encoding = null) - { - $encoding or $encoding = \Fuel::$encoding; - - return MBSTRING - ? mb_strtolower(mb_substr($str, 0, 1, $encoding), $encoding). - mb_substr($str, 1, mb_strlen($str, $encoding), $encoding) - : lcfirst($str); - } - - /** - * ucfirst - * - * Does not strtolower first - * - * @param string $str required - * @param string $encoding default UTF-8 - * @return string - */ - public static function ucfirst($str, $encoding = null) - { - $encoding or $encoding = \Fuel::$encoding; - - return MBSTRING - ? mb_strtoupper(mb_substr($str, 0, 1, $encoding), $encoding). - mb_substr($str, 1, mb_strlen($str, $encoding), $encoding) - : ucfirst($str); - } - - /** - * ucwords - * - * First strtolower then ucwords - * - * ucwords normally doesn't strtolower first - * but MB_CASE_TITLE does, so ucwords now too - * - * @param string $str required - * @param string $encoding default UTF-8 - * @return string - */ - public static function ucwords($str, $encoding = null) - { - $encoding or $encoding = \Fuel::$encoding; - - return MBSTRING - ? mb_convert_case($str, MB_CASE_TITLE, $encoding) - : ucwords(strtolower($str)); - } - - /** - * Creates a random string of characters - * - * @param string $type the type of string - * @param int $length the number of characters - * @return string the random string - */ - public static function random($type = 'alnum', $length = 16) - { - switch($type) - { - case 'basic': - return mt_rand(); - break; - - default: - case 'alnum': - case 'numeric': - case 'nozero': - case 'alpha': - case 'distinct': - case 'hexdec': - switch ($type) - { - case 'alpha': - $pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - break; - - default: - case 'alnum': - $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - break; - - case 'numeric': - $pool = '0123456789'; - break; - - case 'nozero': - $pool = '123456789'; - break; - - case 'distinct': - $pool = '2345679ACDEFHJKLMNPRSTUVWXYZ'; - break; - - case 'hexdec': - $pool = '0123456789abcdef'; - break; - } - - $str = ''; - for ($i=0; $i < $length; $i++) - { - $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1); - } - return $str; - break; - - case 'unique': - return md5(uniqid(mt_rand())); - break; - - case 'sha1' : - return sha1(uniqid(mt_rand(), true)); - break; - - case 'uuid': - $pool = array('8', '9', 'a', 'b'); - return sprintf('%s-%s-4%s-%s%s-%s', - static::random('hexdec', 8), - static::random('hexdec', 4), - static::random('hexdec', 3), - $pool[array_rand($pool)], - static::random('hexdec', 3), - static::random('hexdec', 12)); - break; - } - } - - /** - * Returns a closure that will alternate between the args which to return. - * If you call the closure with false as the arg it will return the value without - * alternating the next time. - * - * @return Closure - */ - public static function alternator() - { - // the args are the values to alternate - $args = func_get_args(); - - return function ($next = true) use ($args) - { - static $i = 0; - return $args[($next ? $i++ : $i) % count($args)]; - }; - } - - /** - * Parse the params from a string using strtr() - * - * @param string $string string to parse - * @param array $array params to str_replace - * @return string - */ - public static function tr($string, $array = array()) - { - if (is_string($string)) - { - $tr_arr = array(); - - foreach ($array as $from => $to) - { - substr($from, 0, 1) !== ':' and $from = ':'.$from; - $tr_arr[$from] = $to; - } - unset($array); - - return strtr($string, $tr_arr); - } - else - { - return $string; - } - } - - /** - * Check if a string is json encoded - * - * @param string $string string to check - * @return bool - */ - public static function is_json($string) - { - json_decode($string); - return json_last_error() === JSON_ERROR_NONE; - } - - /** - * Check if a string is a valid XML - * - * @param string $string string to check - * @return bool - * @throws \FuelException - */ - public static function is_xml($string) - { - if ( ! defined('LIBXML_COMPACT')) - { - throw new \FuelException('libxml is required to use Str::is_xml()'); - } - - $internal_errors = libxml_use_internal_errors(); - libxml_use_internal_errors(true); - $result = simplexml_load_string($string) !== false; - libxml_use_internal_errors($internal_errors); - - return $result; - } - - /** - * Check if a string is serialized - * - * @param string $string string to check - * @return bool - */ - public static function is_serialized($string) - { - $array = @unserialize($string); - return ! ($array === false and $string !== 'b:0;'); - } - - /** - * Check if a string is html - * - * @param string $string string to check - * @return bool - */ - public static function is_html($string) - { - return strlen(strip_tags($string)) < strlen($string); - } -} diff --git a/fuel/core/classes/testcase.php b/fuel/core/classes/testcase.php deleted file mode 100755 index 5af0c2e..0000000 --- a/fuel/core/classes/testcase.php +++ /dev/null @@ -1,19 +0,0 @@ - null, - 'path' => null, - 'asset_base' => false, - 'asset_path' => false, - 'info' => array(), - ); - - /** - * @var array $fallback Fallback theme - */ - protected $fallback = array( - 'name' => null, - 'path' => null, - 'asset_base' => false, - 'asset_path' => false, - 'info' => array(), - ); - - /** - * @var array $config Theme config - */ - protected $config = array( - 'active' => 'default', - 'fallback' => 'default', - 'paths' => array(), - 'assets_folder' => 'themes', - 'view_ext' => '.html', - 'require_info_file' => false, - 'info_file_name' => 'themeinfo.php', - 'use_modules' => false, - ); - - /** - * @var array $partials Storage for defined template partials - */ - protected $partials = array(); - - /** - * @var array $chrome Storage for defined partial chrome - */ - protected $chrome = array(); - - /** - * @var array $order Order in which partial sections should be rendered - */ - protected $order = array(); - - /** - * Sets up the theme object. If a config is given, it will not use the config - * file. - * - * @param array $config Optional config override - */ - public function __construct(array $config = array()) - { - if (empty($config)) - { - \Config::load('theme', true, false, true); - $config = \Config::get('theme', array()); - } - - // Order of this addition is important, do not change this. - $this->config = $config + $this->config; - - // define the default theme paths... - $this->add_paths($this->config['paths']); - - // create a unique asset instance for this theme instance... - $this->asset = \Asset::forge('theme_'.spl_object_hash($this), array('paths' => array())); - - // and set the active and the fallback theme - $this->active($this->config['active']); - $this->fallback($this->config['fallback']); - } - - /** - * Magic method, returns the output of [static::render]. - * - * @return string - * @uses Theme::render - */ - public function __toString() - { - try - { - return (string) $this->render(); - } - catch (\Exception $e) - { - \Errorhandler::exception_handler($e); - - return ''; - } - } - - /** - * Sets the currently active theme. Will return the currently active - * theme. It will throw a \ThemeException if it cannot locate the theme. - * - * @param string $theme Theme name to set active - * @return array The theme array - * @throws \ThemeException - */ - public function active($theme = null) - { - return $this->set_theme($theme, 'active'); - } - - /** - * Sets the fallback theme. This theme will be used if a view or asset - * cannot be found in the active theme. Will return the fallback - * theme. It will throw a \ThemeException if it cannot locate the theme. - * - * @param string $theme Theme name to set active - * @return array The theme array - * @throws \ThemeException - */ - public function fallback($theme = null) - { - return $this->set_theme($theme, 'fallback'); - } - - /** - * Loads a view from the currently active theme, the fallback theme, or - * via the standard FuelPHP cascading file system for views - * - * @param string $view View name - * @param array $data View data - * @param bool $auto_filter Auto filter the view data - * @return View New View object - * @throws \ThemeException - */ - public function view($view, $data = array(), $auto_filter = null) - { - if ($this->active['path'] === null) - { - throw new \ThemeException('You must set an active theme.'); - } - - return \View::forge($this->find_file($view), $data, $auto_filter); - } - - /** - * Loads a viewmodel, and have it use the view from the currently active theme, - * the fallback theme, or the standard FuelPHP cascading file system - * - * @param string $view ViewModel classname without View_ prefix or full classname - * @param string $method Method to execute - * @param bool $auto_filter Auto filter the view data - * @return View New View object - * - * @deprecated 1.8 - */ - public function viewmodel($view, $method = 'view', $auto_filter = null) - { - return \Viewmodel::forge($view, $method, $auto_filter, $this->find_file($view)); - } - - /** - * Loads a presenter, and have it use the view from the currently active theme, - * the fallback theme, or the standard FuelPHP cascading file system - * - * @param string $presenter Presenter classname without View_ prefix or full classname - * @param string $method Method to execute - * @param bool $auto_filter Auto filter the view data - * @param string $view Custom View to associate with this persenter - * @return Presenter - */ - public function presenter($presenter, $method = 'view', $auto_filter = null, $view = null) - { - // if no custom view is given, make it equal to the presenter name - if (is_null($view)) - { - // loading from a specific namespace? - if (strpos($presenter, '::') !== false) - { - $split = explode('::', $presenter, 2); - if (isset($split[1])) - { - // remove the namespace from the view name - $view = $split[1]; - } - } - else - { - $view = $presenter; - } - } - - return \Presenter::forge($presenter, $method, $auto_filter, $this->find_file($view)); - } - - /** - * Loads an asset from the currently loaded theme. - * - * @param string $path Relative path to the asset - * @return string Full asset URL or path if outside docroot - * @throws \ThemeException - */ - public function asset_path($path) - { - if ($this->active['path'] === null) - { - throw new \ThemeException('You must set an active theme.'); - } - - if ($this->active['asset_base']) - { - return $this->active['asset_base'].$path; - } - else - { - return $this->active['path'].$path; - } - } - - /** - * Sets a template for a theme - * - * @param string $template Name of the template view - * @return View - */ - public function set_template($template) - { - // make sure the template is a View - if (is_string($template)) - { - $this->template = $this->view($template); - } - else - { - $this->template = $template; - } - - // return the template view for chaining - return $this->template; - } - - /** - * Get the template view so it can be manipulated - * - * @return string|View - * @throws \ThemeException - */ - public function get_template() - { - // make sure the partial entry exists - if (empty($this->template)) - { - throw new \ThemeException('No valid template could be found. Use set_template() to define a page template.'); - } - - // return the template - return $this->template; - } - - /** - * Define a custom order for a partial section - * - * @param string $section name of the partial section - * @param mixed $order - * @throws \ThemeException - */ - public function set_order($section, $order) - { - $this->order[$section] = $order; - } - - /** - * Render the partials and the theme template - * - * @return string|View - * @throws \ThemeException - */ - public function render() - { - // make sure the template to be rendered is defined - if (empty($this->template)) - { - throw new \ThemeException('No valid template could be found. Use set_template() to define a page template.'); - } - - // storage for rendered results - $rendered = array(); - - // make sure we have a render ordering for all defined partials - foreach ($this->partials as $key => $partials) - { - if ( ! isset($this->order[$key])) - { - $this->order[$key] = 0; - } - } - - // determine the rendering sequence - asort($this->order, SORT_NUMERIC); - - // pre-process all defined partials in defined order - foreach ($this->order as $key => $order) - { - $output = ''; - if (isset($this->partials[$key])) - { - foreach ($this->partials[$key] as $index => $partial) - { - // render the partial - if (is_callable(array($partial, 'render'))) - { - $output .= $partial->render(); - } - else - { - $output .= $partial; - } - } - } - - // store the rendered output - if ( ! empty($output) and array_key_exists($key, $this->chrome)) - { - // encapsulate the partial in the chrome template - $rendered[$key] = $this->chrome[$key]['view']->set($this->chrome[$key]['var'], $output, false); - } - else - { - // store the partial output - $rendered[$key] = $output; - } - } - - // assign the partials to the template - $this->template->set('partials', $rendered, false); - - // return the template - return $this->template; - } - - /** - * Sets a partial for the current template - * - * @param string $section Name of the partial section in the template - * @param string|View|ViewModel|Presenter $view View, or name of the view - * @param bool $overwrite If true overwrite any already defined partials for this section - * @return View - */ - public function set_partial($section, $view, $overwrite = false) - { - // make sure the partial entry exists - array_key_exists($section, $this->partials) or $this->partials[$section] = array(); - - // make sure the partial is a view - if (is_string($view)) - { - $name = $view; - $view = $this->view($view); - } - else - { - $name = 'partial_'.count($this->partials[$section]); - } - - // store the partial - if ($overwrite) - { - $this->partials[$section] = array($name => $view); - } - else - { - $this->partials[$section][$name] = $view; - } - - // return the partial view object for chaining - return $this->partials[$section][$name]; - } - - /** - * Get a partial so it can be manipulated - * - * @param string $section Name of the partial section in the template - * @param string $view name of the view - * @return View - * @throws \ThemeException - */ - public function get_partial($section, $view) - { - // make sure the partial entry exists - if ( ! array_key_exists($section, $this->partials) or ! array_key_exists($view, $this->partials[$section])) - { - throw new \ThemeException(sprintf('No partial named "%s" can be found in the "%s" section.', $view, $section)); - } - - return $this->partials[$section][$view]; - } - - /** - * Returns whether or not a section has partials defined - * - * @param string $section Name of the partial section in the template - * @return bool - */ - public function has_partials($section) - { - return $this->partial_count($section) > 0; - } - - /** - * Returns the number of partials defined for a section - * - * @param string $section Name of the partial section in the template - * @return int - */ - public function partial_count($section) - { - // return the defined partial count - return array_key_exists($section, $this->partials) ? count($this->partials[$section]) : 0; - } - - /** - * Sets a chrome for a partial - * - * @param string $section Name of the partial section in the template - * @param string|View|ViewModel|Presenter $view chrome View, or name of the view - * @param string $var Name of the variable in the chrome that will output the partial - * - * @return View|ViewModel|Presenter, the view partial - */ - public function set_chrome($section, $view, $var = 'content') - { - // make sure the chrome is a view - if (is_string($view)) - { - $view = $this->view($view); - } - - $this->chrome[$section] = array('var' => $var, 'view' => $view); - - return $view; - } - - /** - * Get a set chrome view - * - * @param string $section Name of the partial section in the template - * @return mixed - * @throws \ThemeException - */ - public function get_chrome($section) - { - // make sure the partial entry exists - if ( ! array_key_exists($section, $this->chrome)) - { - throw new \ThemeException(sprintf('No chrome for a partial named "%s" can be found.', $section)); - } - - return $this->chrome[$section]['view']; - } - - /** - * Adds the given path to the theme search path. - * - * @param string $path Path to add - * @return void - */ - public function add_path($path) - { - $this->paths[] = rtrim($path, DS).DS; - } - - /** - * Adds the given paths to the theme search path. - * - * @param array $paths Paths to add - * @return void - */ - public function add_paths(array $paths) - { - array_walk($paths, array($this, 'add_path')); - } - - /** - * Finds the given theme by searching through all of the theme paths. If - * found it will return the path, else it will return `false`. - * - * @param string $theme Theme to find - * @return string|false Path or false if not found - */ - public function find($theme) - { - foreach ($this->paths as $path) - { - if (is_dir($path.$theme)) - { - return $path.$theme.DS; - } - } - - return false; - } - - /** - * Gets an array of all themes in all theme paths, sorted alphabetically. - * - * @return array - */ - public function all() - { - $themes = array(); - foreach ($this->paths as $path) - { - $iterator = new \GlobIterator($path.'*'); - foreach($iterator as $theme) - { - $themes[] = $theme->getFilename(); - } - } - sort($themes); - - return $themes; - } - - /** - * Get a value from the info array - * - * @param mixed $var - * @param mixed $default - * @param mixed $theme - * @return mixed - * @throws \ThemeException - */ - public function get_info($var = null, $default = null, $theme = null) - { - // if no theme is given - if ($theme === null) - { - // if no var to search is given return the entire active info array - if ($var === null) - { - return $this->active['info']; - } - - // find the value in the active theme info - if (($value = \Arr::get($this->active['info'], $var, null)) !== null) - { - return $value; - } - - // and if not found, check the fallback - elseif (($value = \Arr::get($this->fallback['info'], $var, null)) !== null) - { - return $value; - } - } - - // or if we have a specific theme - else - { - // fetch the info from that theme - $info = $this->load_info($theme); - - // and return the requested value - return $var === null ? $info : \Arr::get($info, $var, $default); - } - - // not found, return the given default value - return $default; - } - - /** - * Set a value in the info array - * - * @return Theme - */ - public function set_info($var, $value = null, $type = 'active') - { - if ($type == 'active') - { - \Arr::set($this->active['info'], $var, $value); - } - elseif ($type == 'fallback') - { - \Arr::set($this->fallback['info'], $var, $value); - } - - // return for chaining - return $this; - } - - /** - * Load in the theme.info file for the given (or active) theme. - * - * @param string $theme Name of the theme (null for active) - * @return array Theme info array - * @throws \ThemeException - */ - public function load_info($theme = null) - { - if ($theme === null) - { - $theme = $this->active; - } - - if (is_array($theme)) - { - $path = $theme['path']; - $name = $theme['name']; - } - else - { - $path = $this->find($theme); - $name = $theme; - $theme = array( - 'name' => $name, - 'path' => $path, - ); - } - - if ( ! $path) - { - throw new \ThemeException(sprintf('Could not find theme "%s".', $theme)); - } - - if (($file = $this->find_file($this->config['info_file_name'], array($theme))) == $this->config['info_file_name']) - { - if ($this->config['require_info_file']) - { - throw new \ThemeException(sprintf('Theme "%s" is missing "%s".', $name, $this->config['info_file_name'])); - } - else - { - return array(); - } - } - - return \Config::load($file, false, true); - } - - /** - * Save the theme.info file for the active (or fallback) theme. - * - * @param string $type Name of the theme (null for active) - * @return array Theme info array - * @throws \ThemeException - */ - public function save_info($type = 'active') - { - if ($type == 'active') - { - $theme = $this->active; - } - elseif ($type == 'fallback') - { - $theme = $this->fallback; - } - else - { - throw new \ThemeException('No location found to save the info file to.'); - } - - if ( ! $theme['path']) - { - throw new \ThemeException(sprintf('Could not find theme "%s".', $theme['name'])); - } - - if ( ! ($file = $this->find_file($this->config['info_file_name'], array($theme)))) - { - throw new \ThemeException(sprintf('Theme "%s" is missing "%s".', $theme['name'], $this->config['info_file_name'])); - } - - return \Config::save($file, $theme['info']); - } - - /** - * Enable or disable the use of modules. If enabled, every theme view loaded - * will be prefixed with the module name, so you don't have to hardcode the - * module name as a view file prefix - * - * @param bool|string $enable enable if true or string, disable if false - * @return Theme - */ - public function use_modules($enable = true) - { - $this->config['use_modules'] = $enable; - - // return for chaining - return $this; - } - - /** - * Find the absolute path to a file in a set of Themes. You can optionally - * send an array of themes to search. If you do not, it will search active - * then fallback (in that order). - * - * @param string $view name of the view to find - * @param array $themes optional array of themes to search - * @return string absolute path to the view - * @throws \ThemeException when not found - */ - protected function find_file($view, $themes = null) - { - if ($themes === null) - { - $themes = array($this->active, $this->fallback); - } - - // determine the path prefix and optionally the module path - $path_prefix = ''; - $module_path = null; - if ($this->config['use_modules'] and class_exists('Request', false) and $request = \Request::active() and $module = $request->module) - { - // we're using module name prefixing - $path_prefix = $module.DS; - - // and modules are in a separate path - is_string($this->config['use_modules']) and $path_prefix = trim($this->config['use_modules'], '\\/').DS.$path_prefix; - - // do we need to check the module too? - $this->config['use_modules'] === true and $module_path = \Module::exists($module).'themes'.DS; - } - - foreach ($themes as $theme) - { - $ext = pathinfo($view, PATHINFO_EXTENSION) - ? ('.'.pathinfo($view, PATHINFO_EXTENSION)) - : $this->config['view_ext']; - - $file = pathinfo($view, PATHINFO_DIRNAME) - ? (str_replace(array('/', DS), DS, pathinfo($view, PATHINFO_DIRNAME)).DS) - : ''; - $file .= pathinfo($view, PATHINFO_FILENAME); - - if (empty($theme['find_file'])) - { - if ($module_path and ! empty($theme['name']) and is_file($path = $module_path.$theme['name'].DS.$file.$ext)) - { - return $path; - } - elseif (is_file($path = $theme['path'].$path_prefix.$file.$ext)) - { - return $path; - } - elseif (is_file($path = $theme['path'].$file.$ext)) - { - return $path; - } - } - else - { - if ($path = \Finder::search($theme['path'].$path_prefix, $file, $ext)) - { - return $path; - } - } - } - - // not found, return the viewname to fall back to the standard View processing - return $view; - } - - /** - * Sets a theme. - * - * @param string $theme Theme name to set active - * @param string $type name of the internal theme array to set - * @return array The theme array - * @throws \ThemeException - */ - protected function set_theme($theme = null, $type = 'active') - { - // set the theme if given - if ($theme !== null) - { - // remove the defined theme asset paths from the asset instance - empty($this->active['asset_path']) or $this->asset->remove_path($this->active['asset_path']); - empty($this->fallback['asset_path']) or $this->asset->remove_path($this->fallback['asset_path']); - - $this->{$type} = $this->create_theme_array($theme); - - // add the asset paths to the asset instance - empty($this->fallback['asset_path']) or $this->asset->add_path($this->fallback['asset_path']); - empty($this->active['asset_path']) or $this->asset->add_path($this->active['asset_path']); - } - - // and return the theme config - return $this->{$type}; - } - - /** - * Creates a theme array by locating the given theme and setting all of the - * option. It will throw a \ThemeException if it cannot locate the theme. - * - * @param string $theme Theme name to set active - * @return array The theme array - * @throws \ThemeException - */ - protected function create_theme_array($theme) - { - if ( ! is_array($theme)) - { - if ( ! $path = $this->find($theme)) - { - throw new \ThemeException(sprintf('Theme "%s" could not be found.', $theme)); - } - - $theme = array( - 'name' => $theme, - 'path' => $path, - ); - } - else - { - if ( ! isset($theme['name']) or ! isset($theme['path'])) - { - throw new \ThemeException('Theme name and path must be given in array config.'); - } - } - - // load the theme info file - if ( ! isset($theme['info'])) - { - $theme['info'] = $this->load_info($theme); - } - - if ( ! isset($theme['asset_base'])) - { - // determine the asset location and base URL - $assets_folder = rtrim($this->config['assets_folder'], DS).'/'; - - // all theme files are inside the docroot - if (strpos($path, DOCROOT) === 0 and is_dir($path.$assets_folder)) - { - $theme['asset_path'] = $path.$assets_folder; - $theme['asset_base'] = str_replace(DOCROOT, '', $theme['asset_path']); - } - - // theme views and templates are outside the docroot - else - { - $theme['asset_base'] = $assets_folder.$theme['name'].'/'; - } - } - - if ( ! isset($theme['asset_path']) and strpos($theme['asset_base'], '://') === false) - { - $theme['asset_path'] = DOCROOT.$theme['asset_base']; - } - - // always uses forward slashes for the asset base and path - $theme['asset_base'] = str_replace(DS, '/', $theme['asset_base']); - $theme['asset_path'] = str_replace(DS, '/', $theme['asset_path']); - - // but if on windows, file paths require a backslash - if (strpos($theme['asset_base'], '://') === false and DS !== '/') - { - $theme['asset_path'] = str_replace('/', DS, $theme['asset_path']); - } - - return $theme; - } -} diff --git a/fuel/core/classes/unzip.php b/fuel/core/classes/unzip.php deleted file mode 100755 index d0ae679..0000000 --- a/fuel/core/classes/unzip.php +++ /dev/null @@ -1,597 +0,0 @@ -_zip_file = $zip_file; - $this->_target_dir = $target_dir ? $target_dir : dirname($this->_zip_file); - - if ( ! $files = $this->_list_files()) - { - throw new \FuelException('ZIP folder was empty.'); - } - - $file_locations = array(); - foreach ($files as $file => $trash) - { - $dirname = pathinfo($file, PATHINFO_DIRNAME); - $extension = pathinfo($file, PATHINFO_EXTENSION); - - $folders = explode('/', $dirname); - $out_dn = $this->_target_dir . '/' . $dirname; - - // Skip stuff in stupid folders - if (in_array(current($folders), $this->_skip_dirs)) - { - continue; - } - - // Skip any files that are not allowed - if (is_array($this->_allow_extensions) AND $extension AND ! in_array($extension, $this->_allow_extensions)) - { - continue; - } - - if ( ! is_dir($out_dn) AND $preserve_filepath) - { - $str = ""; - foreach ($folders as $folder) - { - $str = $str ? $str . '/' . $folder : $folder; - if ( ! is_dir($this->_target_dir . '/' . $str)) - { - $this->set_debug('Creating folder: ' . $this->_target_dir . '/' . $str); - - if ( ! @mkdir($this->_target_dir . '/' . $str)) - { - throw new \FuelException('Desitnation path is not writable.'); - } - - // Apply chmod if configured to do so - $this->apply_chmod AND chmod($this->_target_dir . '/' . $str, $this->apply_chmod); - } - } - } - - if (substr($file, -1, 1) == '/') - { - continue; - } - - $file_locations[] = $file_location = $this->_target_dir . '/' . ($preserve_filepath ? $file : basename($file)); - - $this->_extract_file($file, $file_location); - } - - return $file_locations; - } - - // -------------------------------------------------------------------- - - /** - * What extensions do we want out of this ZIP - * - * @param string $ext - */ - public function allow($ext = NULL) - { - $this->_allow_extensions = $ext; - } - - // -------------------------------------------------------------------- - - /** - * Show error messages - * - * @param string $open - * @param string $close - * @return string - */ - public function error_string($open = '

', $close = '

') - { - return $open . implode($close . $open, $this->error) . $close; - } - - // -------------------------------------------------------------------- - - /** - * Show debug messages - * - * @param string $open - * @param string $close - * @return string - */ - public function debug_string($open = '

', $close = '

') - { - return $open . implode($close . $open, $this->info) . $close; - } - - // -------------------------------------------------------------------- - - /** - * Save errors - * - * @param $string - */ - function set_error($string) - { - $this->error[] = $string; - } - - // -------------------------------------------------------------------- - - /** - * Save debug data - * - * @param $string - */ - function set_debug($string) - { - $this->info[] = $string; - } - - // -------------------------------------------------------------------- - - /** - * List all files in archive. - * - * @param bool $stop_on_file - * @return array - * @throws \FuelException - */ - private function _list_files($stop_on_file = false) - { - if (sizeof($this->compressed_list)) - { - $this->set_debug('Returning already loaded file list.'); - return $this->compressed_list; - } - - // Open file, and set file handler - $fh = fopen($this->_zip_file, 'r'); - $this->fh = &$fh; - - if ( ! $fh) - { - throw new \FuelException('Failed to load file: ' . $this->_zip_file); - } - - $this->set_debug('Loading list from "End of Central Dir" index list...'); - - if ( ! $this->_load_file_list_by_eof($fh, $stop_on_file)) - { - $this->set_debug('Failed! Trying to load list looking for signatures...'); - - if ( ! $this->_load_files_by_signatures($fh, $stop_on_file)) - { - $this->set_debug('Failed! Could not find any valid header.'); - throw new \FuelException('ZIP File is corrupted or empty'); - } - } - - return $this->compressed_list; - } - - // -------------------------------------------------------------------- - - /** - * Unzip file in archive. - * - * @param string $compressed_file_name - * @param string $target_file_name - * @return int|string|bool - * @throws \FuelException - */ - private function _extract_file($compressed_file_name, $target_file_name = false) - { - if ( ! sizeof($this->compressed_list)) - { - $this->set_debug('Trying to unzip before loading file list... Loading it!'); - $this->_list_files(false, $compressed_file_name); - } - - $fdetails = &$this->compressed_list[$compressed_file_name]; - - if ( ! isset($this->compressed_list[$compressed_file_name])) - { - throw new \FuelException('File "' . $compressed_file_name . '" is not compressed in the zip.'); - } - - if (substr($compressed_file_name, -1) == '/') - { - throw new \FuelException('Trying to unzip a folder name "' . $compressed_file_name . '".'); - } - - if ( ! $fdetails['uncompressed_size']) - { - $this->set_debug('File "' . $compressed_file_name . '" is empty.'); - - return $target_file_name ? file_put_contents($target_file_name, '') : ''; - } - - fseek($this->fh, $fdetails['contents_start_offset']); - $ret = $this->_uncompress( - fread($this->fh, $fdetails['compressed_size']), - $fdetails['compression_method'], - $fdetails['uncompressed_size'], - $target_file_name - ); - - if ($this->apply_chmod AND $target_file_name) - { - chmod($target_file_name, 0644); - } - - return $ret; - } - - // -------------------------------------------------------------------- - - /** - * Free the file resource. - */ - public function close() - { - // Free the file resource - if ($this->fh) - { - fclose($this->fh); - } - } - - // -------------------------------------------------------------------- - - /** - * Free the file resource Automatic destroy. - */ - public function __destroy() - { - $this->close(); - } - - // -------------------------------------------------------------------- - - /** - * Uncompress file. And save it to the targetFile. - * - * @param mixed $content - * @param int $mode - * @param int $uncompressed_size - * @param string $target_file_name - * @return int|string|bool - * @throws \FuelException - */ - private function _uncompress($content, $mode, $uncompressed_size, $target_file_name = false) - { - switch ($mode) - { - case 0: - return $target_file_name ? file_put_contents($target_file_name, $content) : $content; - case 1: - throw new \FuelException('Shrunk mode is not supported... yet?'); - case 2: - case 3: - case 4: - case 5: - throw new \FuelException('Compression factor ' . ($mode - 1) . ' is not supported... yet?'); - case 6: - throw new \FuelException('Implode is not supported... yet?'); - case 7: - throw new \FuelException('Tokenizing compression algorithm is not supported... yet?'); - case 8: - // Deflate - return $target_file_name ? - file_put_contents($target_file_name, gzinflate($content, $uncompressed_size)) : - gzinflate($content, $uncompressed_size); - case 9: - throw new \FuelException('Enhanced Deflating is not supported... yet?'); - case 10: - throw new \FuelException('PKWARE Date Compression Library Impoloding is not supported... yet?'); - case 12: - // Bzip2 - return $target_file_name ? - file_put_contents($target_file_name, bzdecompress($content)) : - bzdecompress($content); - case 18: - throw new \FuelException('IBM TERSE is not supported... yet?'); - default: - throw new \FuelException('Unknown uncompress method: $mode'); - } - } - - private function _load_file_list_by_eof(&$fh, $stop_on_file = false) - { - // Check if there's a valid Central Dir signature. - // Let's consider a file comment smaller than 1024 characters... - // Actually, it length can be 65536.. But we're not going to support it. - - for ($x = 0; $x < 1024; $x++) - { - fseek($fh, -22 - $x, SEEK_END); - - $signature = fread($fh, 4); - - if ($signature == $this->central_signature_end) - { - // If found EOF Central Dir - $eodir['disk_number_this'] = unpack("v", fread($fh, 2)); // number of this disk - $eodir['disk_number'] = unpack("v", fread($fh, 2)); // number of the disk with the start of the central directory - $eodir['total_entries_this'] = unpack("v", fread($fh, 2)); // total number of entries in the central dir on this disk - $eodir['total_entries'] = unpack("v", fread($fh, 2)); // total number of entries in - $eodir['size_of_cd'] = unpack("V", fread($fh, 4)); // size of the central directory - $eodir['offset_start_cd'] = unpack("V", fread($fh, 4)); // offset of start of central directory with respect to the starting disk number - $zip_comment_lenght = unpack("v", fread($fh, 2)); // zipfile comment length - $eodir['zipfile_comment'] = $zip_comment_lenght[1] ? fread($fh, $zip_comment_lenght[1]) : ''; // zipfile comment - - $this->end_of_central = array( - 'disk_number_this' => $eodir['disk_number_this'][1], - 'disk_number' => $eodir['disk_number'][1], - 'total_entries_this' => $eodir['total_entries_this'][1], - 'total_entries' => $eodir['total_entries'][1], - 'size_of_cd' => $eodir['size_of_cd'][1], - 'offset_start_cd' => $eodir['offset_start_cd'][1], - 'zipfile_comment' => $eodir['zipfile_comment'], - ); - - // Then, load file list - fseek($fh, $this->end_of_central['offset_start_cd']); - $signature = fread($fh, 4); - - while ($signature == $this->dir_signature) - { - $dir['version_madeby'] = unpack("v", fread($fh, 2)); // version made by - $dir['version_needed'] = unpack("v", fread($fh, 2)); // version needed to extract - $dir['general_bit_flag'] = unpack("v", fread($fh, 2)); // general purpose bit flag - $dir['compression_method'] = unpack("v", fread($fh, 2)); // compression method - $dir['lastmod_time'] = unpack("v", fread($fh, 2)); // last mod file time - $dir['lastmod_date'] = unpack("v", fread($fh, 2)); // last mod file date - $dir['crc-32'] = fread($fh, 4); // crc-32 - $dir['compressed_size'] = unpack("V", fread($fh, 4)); // compressed size - $dir['uncompressed_size'] = unpack("V", fread($fh, 4)); // uncompressed size - $zip_file_length = unpack("v", fread($fh, 2)); // filename length - $extra_field_length = unpack("v", fread($fh, 2)); // extra field length - $fileCommentLength = unpack("v", fread($fh, 2)); // file comment length - $dir['disk_number_start'] = unpack("v", fread($fh, 2)); // disk number start - $dir['internal_attributes'] = unpack("v", fread($fh, 2)); // internal file attributes-byte1 - $dir['external_attributes1'] = unpack("v", fread($fh, 2)); // external file attributes-byte2 - $dir['external_attributes2'] = unpack("v", fread($fh, 2)); // external file attributes - $dir['relative_offset'] = unpack("V", fread($fh, 4)); // relative offset of local header - $dir['file_name'] = fread($fh, $zip_file_length[1]); // filename - $dir['extra_field'] = $extra_field_length[1] ? fread($fh, $extra_field_length[1]) : ''; // extra field - $dir['file_comment'] = $fileCommentLength[1] ? fread($fh, $fileCommentLength[1]) : ''; // file comment - - // Convert the date and time, from MS-DOS format to UNIX Timestamp - $binary_mod_date = str_pad(decbin($dir['lastmod_date'][1]), 16, '0', STR_PAD_LEFT); - $binary_mod_time = str_pad(decbin($dir['lastmod_time'][1]), 16, '0', STR_PAD_LEFT); - $last_mod_year = bindec(substr($binary_mod_date, 0, 7)) + 1980; - $last_mod_month = bindec(substr($binary_mod_date, 7, 4)); - $last_mod_day = bindec(substr($binary_mod_date, 11, 5)); - $last_mod_hour = bindec(substr($binary_mod_time, 0, 5)); - $last_mod_minute = bindec(substr($binary_mod_time, 5, 6)); - $last_mod_second = bindec(substr($binary_mod_time, 11, 5)); - - $this->central_dir_list[$dir['file_name']] = array( - 'version_madeby' => $dir['version_madeby'][1], - 'version_needed' => $dir['version_needed'][1], - 'general_bit_flag' => str_pad(decbin($dir['general_bit_flag'][1]), 8, '0', STR_PAD_LEFT), - 'compression_method' => $dir['compression_method'][1], - 'lastmod_datetime' => mktime($last_mod_hour, $last_mod_minute, $last_mod_second, $last_mod_month, $last_mod_day, $last_mod_year), - 'crc-32' => str_pad(dechex(ord($dir['crc-32'][3])), 2, '0', STR_PAD_LEFT) . - str_pad(dechex(ord($dir['crc-32'][2])), 2, '0', STR_PAD_LEFT) . - str_pad(dechex(ord($dir['crc-32'][1])), 2, '0', STR_PAD_LEFT) . - str_pad(dechex(ord($dir['crc-32'][0])), 2, '0', STR_PAD_LEFT), - 'compressed_size' => $dir['compressed_size'][1], - 'uncompressed_size' => $dir['uncompressed_size'][1], - 'disk_number_start' => $dir['disk_number_start'][1], - 'internal_attributes' => $dir['internal_attributes'][1], - 'external_attributes1' => $dir['external_attributes1'][1], - 'external_attributes2' => $dir['external_attributes2'][1], - 'relative_offset' => $dir['relative_offset'][1], - 'file_name' => $dir['file_name'], - 'extra_field' => $dir['extra_field'], - 'file_comment' => $dir['file_comment'], - ); - - $signature = fread($fh, 4); - } - - // If loaded centralDirs, then try to identify the offsetPosition of the compressed data. - if ($this->central_dir_list) - { - foreach ($this->central_dir_list as $filename => $details) - { - $i = $this->_get_file_header($fh, $details['relative_offset']); - - $this->compressed_list[$filename]['file_name'] = $filename; - $this->compressed_list[$filename]['compression_method'] = $details['compression_method']; - $this->compressed_list[$filename]['version_needed'] = $details['version_needed']; - $this->compressed_list[$filename]['lastmod_datetime'] = $details['lastmod_datetime']; - $this->compressed_list[$filename]['crc-32'] = $details['crc-32']; - $this->compressed_list[$filename]['compressed_size'] = $details['compressed_size']; - $this->compressed_list[$filename]['uncompressed_size'] = $details['uncompressed_size']; - $this->compressed_list[$filename]['lastmod_datetime'] = $details['lastmod_datetime']; - $this->compressed_list[$filename]['extra_field'] = $i['extra_field']; - $this->compressed_list[$filename]['contents_start_offset'] = $i['contents_start_offset']; - - if (strtolower($stop_on_file) == strtolower($filename)) - { - break; - } - } - } - - return TRUE; - } - } - return false; - } - - private function _load_files_by_signatures(&$fh, $stop_on_file = false) - { - fseek($fh, 0); - - $return = false; - for (;;) - { - $details = $this->_get_file_header($fh); - - if ( ! $details) - { - $this->set_debug('Invalid signature. Trying to verify if is old style Data Descriptor...'); - fseek($fh, 12 - 4, SEEK_CUR); // 12: Data descriptor - 4: Signature (that will be read again) - $details = $this->_get_file_header($fh); - } - - if ( ! $details) - { - $this->set_debug('Still invalid signature. Probably reached the end of the file.'); - break; - } - - $filename = $details['file_name']; - $this->compressed_list[$filename] = $details; - $return = true; - - if (strtolower($stop_on_file) == strtolower($filename)) - { - break; - } - } - - return $return; - } - - private function _get_file_header(&$fh, $start_offset = false) - { - if ($start_offset !== false) - { - fseek($fh, $start_offset); - } - - $signature = fread($fh, 4); - - if ($signature == $this->zip_signature) - { - // Get information about the zipped file - $file['version_needed'] = unpack("v", fread($fh, 2)); // version needed to extract - $file['general_bit_flag'] = unpack("v", fread($fh, 2)); // general purpose bit flag - $file['compression_method'] = unpack("v", fread($fh, 2)); // compression method - $file['lastmod_time'] = unpack("v", fread($fh, 2)); // last mod file time - $file['lastmod_date'] = unpack("v", fread($fh, 2)); // last mod file date - $file['crc-32'] = fread($fh, 4); // crc-32 - $file['compressed_size'] = unpack("V", fread($fh, 4)); // compressed size - $file['uncompressed_size'] = unpack("V", fread($fh, 4)); // uncompressed size - $zip_file_length = unpack("v", fread($fh, 2)); // filename length - $extra_field_length = unpack("v", fread($fh, 2)); // extra field length - $file['file_name'] = fread($fh, $zip_file_length[1]); // filename - $file['extra_field'] = $extra_field_length[1] ? fread($fh, $extra_field_length[1]) : ''; // extra field - $file['contents_start_offset'] = ftell($fh); - - // Bypass the whole compressed contents, and look for the next file - fseek($fh, $file['compressed_size'][1], SEEK_CUR); - - // Convert the date and time, from MS-DOS format to UNIX Timestamp - $binary_mod_date = str_pad(decbin($file['lastmod_date'][1]), 16, '0', STR_PAD_LEFT); - $binary_mod_time = str_pad(decbin($file['lastmod_time'][1]), 16, '0', STR_PAD_LEFT); - - $last_mod_year = bindec(substr($binary_mod_date, 0, 7)) + 1980; - $last_mod_month = bindec(substr($binary_mod_date, 7, 4)); - $last_mod_day = bindec(substr($binary_mod_date, 11, 5)); - $last_mod_hour = bindec(substr($binary_mod_time, 0, 5)); - $last_mod_minute = bindec(substr($binary_mod_time, 5, 6)); - $last_mod_second = bindec(substr($binary_mod_time, 11, 5)); - - // Mount file table - $i = array( - 'file_name' => $file['file_name'], - 'compression_method' => $file['compression_method'][1], - 'version_needed' => $file['version_needed'][1], - 'lastmod_datetime' => mktime($last_mod_hour, $last_mod_minute, $last_mod_second, $last_mod_month, $last_mod_day, $last_mod_year), - 'crc-32' => str_pad(dechex(ord($file['crc-32'][3])), 2, '0', STR_PAD_LEFT) . - str_pad(dechex(ord($file['crc-32'][2])), 2, '0', STR_PAD_LEFT) . - str_pad(dechex(ord($file['crc-32'][1])), 2, '0', STR_PAD_LEFT) . - str_pad(dechex(ord($file['crc-32'][0])), 2, '0', STR_PAD_LEFT), - 'compressed_size' => $file['compressed_size'][1], - 'uncompressed_size' => $file['uncompressed_size'][1], - 'extra_field' => $file['extra_field'], - 'general_bit_flag' => str_pad(decbin($file['general_bit_flag'][1]), 8, '0', STR_PAD_LEFT), - 'contents_start_offset' => $file['contents_start_offset'], - ); - - return $i; - } - - return false; - } -} diff --git a/fuel/core/classes/upload.php b/fuel/core/classes/upload.php deleted file mode 100755 index bacb141..0000000 --- a/fuel/core/classes/upload.php +++ /dev/null @@ -1,377 +0,0 @@ -processFiles(); - } - } - - // --------------------------------------------------------------------------- - - /** - * return the Upload instance - * - * @return \Upload - */ - public static function instance() - { - return static::$upload; - } - - // --------------------------------------------------------------------------- - - /** - * Lang callback function, translates Upload error messages - * - * @param int $error Number of the error message we want the language string for - * - * @return string Language string retrieved - */ - public static function lang_callback($error) - { - return \Lang::get('upload.error_'.$error, array(), ''); - } - - // --------------------------------------------------------------------------- - - /** - * Move callback function, custom method to move an uploaded file. In Fuel 1.x - * this method is used for FTP uploads only - * - * @param string $from The FQFN of the file to move - * @param string $to The FQFN of the file destination - * - * @return bool Result of the move operation - */ - public static function move_callback($from, $to) - { - if (static::$with_ftp) - { - return static::$with_ftp->upload($from, $to, \Config::get('upload.ftp_mode'), \Config::get('upload.ftp_permissions')); - } - - return false; - } - - // --------------------------------------------------------------------------- - - /** - * Check if we have valid files - * - * @return bool true if static:$files contains uploaded files that are valid - */ - public static function is_valid() - { - return static::$upload->getValidFiles() == array() ? false : true; - } - - // --------------------------------------------------------------------------- - - /** - * Get the list of validated files - * - * @param mixed $index - * @return array list of uploaded files that are validated - */ - public static function get_files($index = null) - { - // convert element name formats - is_string($index) and $index = str_replace(':', '.', $index); - - $files = static::$upload->getValidFiles($index); - - // convert the file object to 1.x compatible data - $result = array(); - - foreach ($files as $file) - { - $data = array(); - foreach ($file as $item => $value) - { - $item == 'element' and $item = 'field'; - $item == 'tmp_name' and $item = 'file'; - $item == 'filename' and $item = 'saved_as'; - $item == 'path' and $item = 'saved_to'; - $data[$item] = $value; - } - $data['field'] = str_replace('.', ':', $data['field']); - $data['error'] = ! $file->isValid(); - $data['errors'] = array(); - $result[] = $data; - } - - // compatibility with < 1.5, return the single entry if only one was found - if (func_num_args() and count($result) == 1) - { - return reset($result); - } - else - { - return $result; - } - } - - // --------------------------------------------------------------------------- - - /** - * Get the list of non-validated files - * - * @param mixed $index - * @return array list of uploaded files that failed to validate - */ - public static function get_errors($index = null) - { - // convert element name formats - is_string($index) and $index = str_replace(':', '.', $index); - - $files = static::$upload->getInvalidFiles($index); - - // convert the file object to 1.x compatible data - $result = array(); - - foreach ($files as $file) - { - $data = array(); - foreach ($file as $item => $value) - { - // swap item names for BC - $item == 'element' and $item = 'field'; - $item == 'tmp_name' and $item = 'file'; - $item == 'filename' and $item = 'saved_as'; - $item == 'path' and $item = 'saved_to'; - $data[$item] = $value; - } - $data['field'] = str_replace('.', ':', $data['field']); - $data['error'] = ! $file->isValid(); - $data['errors'] = array(); - foreach ($file->getErrors() as $error) - { - $data['errors'][] = array('error' => $error->getError(), 'message' => $error->getMessage()); - } - $result[] = $data; - } - - // compatibility with < 1.5, return the single entry if only one was found - if (func_num_args() and count($result) == 1) - { - return reset($result); - } - else - { - return $result; - } - } - - // -------------------------------------------------------------------- - - /** - * Register - * - * Registers a Callback for a given event - * - * @param string $event The name of the event - * @param mixed $callback callback information - * - * @return void - */ - public static function register($event, $callback) - { - // make sure we're setting the correct events - $event = str_replace(array('before', 'after', 'validate'), array('before_save', 'after_save', 'after_validation'), $event); - - static::$upload->register($event, $callback); - } - - // --------------------------------------------------------------------------- - - /** - * Process the uploaded files, and run the validation - * - * @param array $config - * @return void - */ - public static function process($config = array()) - { - foreach (static::$upload->getAllFiles() as $file) - { - $file->setConfig($config); - $file->validate(); - } - } - - // --------------------------------------------------------------------------- - - /** - * Upload files with FTP - * - * @param string|array $config The name of the config group to use, or a configuration array. - * @param bool $connect Automatically connect to this server. - */ - public static function with_ftp($config = 'default', $connect = true) - { - if (static::$with_ftp = \Ftp::forge($config, $connect)) - { - // if we have an ftp object, activate the move callback - static::$upload->setConfig('moveCallback', '\\Upload\\move_callback'); - } - else - { - // creating the ftp object failed, disable the callback - static::$upload->setConfig('moveCallback', null); - } - } - - // --------------------------------------------------------------------------- - - /** - * save uploaded file(s) - * - * @return void - */ - public static function save() - { - // storage for arguments - $path = null; - $ids = array(); - - // do we have any arguments - if (func_num_args()) - { - // process them - foreach (func_get_args() as $arg) - { - if (is_string($arg)) - { - $path = $arg; - } - elseif(is_numeric($arg)) - { - in_array($arg, $ids) or $ids[] = $arg; - } - elseif(is_array($arg)) - { - $ids = array_merge($ids, $arg); - } - } - } - - // now process the files - $counter = 0; - foreach (static::$upload->getValidFiles() as $file) - { - // do we want to process this file? - if ( ! empty($ids) and ! in_array($counter++, $ids)) - { - // nope - continue; - } - - // was a custom path defined? - $path and $file->setConfig('path', $path); - - // save the file - $file->save(); - } - } -} diff --git a/fuel/core/classes/uri.php b/fuel/core/classes/uri.php deleted file mode 100755 index 23ac05b..0000000 --- a/fuel/core/classes/uri.php +++ /dev/null @@ -1,389 +0,0 @@ -uri->get_segment($segment, $default); - } - - return null; - } - - /** - * Returns all segments in an array - * - * @return array - */ - public static function segments() - { - if ($request = \Request::active()) - { - return $request->uri->get_segments(); - } - - return null; - } - - /** - * Replace all * wildcards in a URI by the current segment in that location - * - * @param string $url The url containing the wildcards - * @param bool $secure To force a particular HTTP scheme - * @return string - */ - public static function segment_replace($url, $secure = null) - { - // get the path from the url - $parts = parse_url($url); - - // explode it in it's segments - $segments = explode('/', trim($parts['path'], '/')); - - // fetch any segments needed - $wildcards = 0; - foreach ($segments as $index => &$segment) - { - if (strpos($segment, '*') !== false) - { - $wildcards++; - if (($new = static::segment($index+1)) === null) - { - throw new \OutofBoundsException('Segment replace on "'.$url.'" failed. No segment exists for wildcard '.$wildcards.'.'); - } - $segment = str_replace('*', $new, $segment); - } - } - - // re-assemble the path - $parts['path'] = '/'.implode('/', $segments); - - // do we need to force a scheme? - if (is_bool($secure)) - { - $parts['scheme'] = $secure ? 'https' : 'http'; - } - - // and rebuild the url with the new path - if (empty($parts['host'])) - { - // if a relative url was given, fake a host so we can remove it after building - $url = substr(http_build_url('http://__removethis__/', $parts), 22); - } - else - { - // a hostname was present, just rebuild it - $url = http_build_url('', $parts); - } - - // return the newly constructed url - return $url; - } - - /** - * Converts the current URI segments to an associative array. If - * the URI has an odd number of segments, an empty value will be added. - * - * @param int $start segment number to start from. default value is the first segment - * @return array the assoc array - */ - public static function to_assoc($start = 1) - { - $segments = array_slice(static::segments(), ($start - 1)); - count($segments) % 2 and $segments[] = null; - - return \Arr::to_assoc($segments); - } - - /** - * Returns the full uri as a string - * - * @return string - */ - public static function string() - { - if ($request = \Request::active()) - { - return $request->uri->get(); - } - - return null; - } - - /** - * Creates a url with the given uri, including the base url - * - * @param string $uri The uri to create the URL for - * @param array $variables Some variables for the URL - * @param array $get_variables Any GET urls to append via a query string - * @param bool $secure If false, force http. If true, force https - * @return string - */ - public static function create($uri = null, $variables = array(), $get_variables = array(), $secure = null) - { - $url = ''; - is_null($uri) and $uri = static::string(); - - // If the given uri is not a full URL - if( ! preg_match("#^(http|https|ftp)://#i", $uri)) - { - $url .= \Config::get('base_url'); - - if ($index_file = \Config::get('index_file')) - { - $url .= $index_file.'/'; - } - } - $url .= ltrim($uri, '/'); - - // stick a url suffix onto it if defined and needed - if ($url_suffix = \Config::get('url_suffix', false) and substr($url, -1) != '/') - { - $current_suffix = strrchr($url, '.'); - if ( ! $current_suffix or strpos($current_suffix, '/') !== false) - { - $url .= $url_suffix; - } - } - - if ( ! empty($get_variables)) - { - $char = strpos($url, '?') === false ? '?' : '&'; - if (is_string($get_variables)) - { - $url .= $char.str_replace('%3A', ':', $get_variables); - } - else - { - $url .= $char.str_replace('%3A', ':', http_build_query($get_variables)); - } - } - - array_walk( - $variables, - function ($val, $key) use (&$url) - { - $url = str_replace(':'.$key, $val, $url); - } - ); - - is_bool($secure) and $url = http_build_url($url, array('scheme' => $secure ? 'https' : 'http')); - - return $url; - } - - /** - * Gets the main request's URI - * - * @return string - */ - public static function main() - { - return static::create(\Request::main()->uri->get()); - } - - /** - * Gets the current URL, including the BASE_URL - * - * @return string - */ - public static function current() - { - return static::create(); - } - - /** - * Gets the base URL, including the index_file if wanted. - * - * @param bool $include_index Whether to include index.php in the URL - * @return string - */ - public static function base($include_index = true) - { - $url = \Config::get('base_url'); - - if ($include_index and \Config::get('index_file')) - { - $url .= \Config::get('index_file').'/'; - } - - return $url; - } - - /** - * Builds a query string by merging all array and string values passed. If - * a string is passed, it will be assumed to be a switch, and converted - * to "string=1". - * - * @param array|string Array or string to merge - * @param array|string ... - * - * @return string - */ - public static function build_query_string() - { - $params = array(); - - foreach (func_get_args() as $arg) - { - $arg = is_array($arg) ? $arg : array($arg => '1'); - - $params = array_merge($params, $arg); - } - - return http_build_query($params); - } - - /** - * Updates the query string of the current or passed URL with the data passed - * - * @param array|string $vars Assoc array of GET variables, or a get variable name - * @param string|mixed $uri Optional URI to use if $vars is an array, otherwise the get variable name - * @param bool $secure If false, force http. If true, force https - * - * @return string - */ - public static function update_query_string($vars = array(), $uri = null, $secure = null) - { - // unify the input data - if ( ! is_array($vars)) - { - $vars = array($vars => $uri); - $uri = null; - } - - // if we have a custom URI, use that - if ($uri === null) - { - // use the current URI if not is passed - $uri = static::current(); - - // merge them with the existing query string data - $vars = array_merge(\Input::get(), $vars); - } - - // return the updated uri - return static::create($uri, array(), $vars, $secure); - } - - /** - * @var string The URI string - */ - protected $uri = ''; - - /** - * @var array The URI segments - */ - protected $segments = ''; - - /** - * Construct takes a URI or detects it if none is given and generates - * the segments. - * - * @param string $uri The URI - */ - public function __construct($uri = null) - { - if (\Fuel::$profiling) - { - \Profiler::mark(__METHOD__.' Start'); - } - - // if the route is a closure, an object will be passed here - is_object($uri) and $uri = null; - - $this->uri = trim($uri ?: \Input::uri(), '/'); - - if (empty($this->uri)) - { - $this->segments = array(); - } - else - { - $this->segments = explode('/', $this->uri); - } - - if (\Fuel::$profiling) - { - \Profiler::mark(__METHOD__.' End'); - } - } - - /** - * Returns the full URI string - * - * @return string The URI string - */ - public function get() - { - return $this->uri; - } - - /** - * Returns all of the URI segments - * - * @return array The URI segments - */ - public function get_segments() - { - return $this->segments; - } - - /** - * Get the specified URI segment, return default if it doesn't exist. - * - * Segment index is 1 based, not 0 based - * - * @param string $segment The 1-based segment index - * @param mixed $default The default value - * @return mixed - */ - public function get_segment($segment, $default = null) - { - if (isset($this->segments[$segment - 1])) - { - return $this->segments[$segment - 1]; - } - - return \Fuel::value($default); - } - - /** - * Returns the URI string - * - * @return string - */ - public function __toString() - { - return $this->get(); - } -} diff --git a/fuel/core/classes/validation.php b/fuel/core/classes/validation.php deleted file mode 100755 index 1680edd..0000000 --- a/fuel/core/classes/validation.php +++ /dev/null @@ -1,1072 +0,0 @@ -validation(false) != null) - { - throw new \DomainException('Form instance already exists, cannot be recreated. Use instance() instead of forge() to retrieve the existing instance.'); - } - } - - return new static($fieldset); - } - - public static function instance($name = null) - { - $fieldset = \Fieldset::instance($name); - return $fieldset === false ? false : $fieldset->validation(); - } - - /** - * Fetch the currently active validation instance - * - * @return Validation - */ - public static function active() - { - return static::$active; - } - - /** - * Set or unset the currently active validation instance - */ - protected static function set_active($instance = null) - { - static::$active = $instance; - } - - /** - * Fetch the field currently being validated - */ - public static function active_field() - { - return static::$active_field; - } - - /** - * Set or unset the current field being validated - */ - protected static function set_active_field($instance = null) - { - static::$active_field = $instance; - } - - /** - * @var Fieldset the fieldset this instance validates - */ - protected $fieldset; - - /** - * @var array available after validation started running: contains given input values - */ - protected $input = array(); - - /** - * @var array contains values of fields that validated successfully - */ - protected $validated = array(); - - /** - * @var array contains Validation_Error instances of encountered errors - */ - protected $errors = array(); - - /** - * @var array contains a list of classnames and objects that may contain validation methods - */ - protected $callables = array(); - - /** - * @var bool $global_input_fallback whether to fall back to Input::param - */ - protected $global_input_fallback = true; - - /** - * @var array contains validation error messages, will overwrite those from lang files - */ - protected $error_messages = array(); - - protected function __construct($fieldset) - { - if ($fieldset instanceof Fieldset) - { - $fieldset->validation($this); - $this->fieldset = $fieldset; - } - else - { - $this->fieldset = \Fieldset::forge($fieldset, array('validation_instance' => $this)); - } - - $this->callables = array($this); - $this->global_input_fallback = \Config::get('validation.global_input_fallback', true); - } - - /** - * Returns the related fieldset - * - * @return Fieldset - */ - public function fieldset() - { - return $this->fieldset; - } - - /** - * Simpler alias for Validation->add() - * - * @param string $name Field name - * @param string $label Field label - * @param string $rules Rules as a piped string - * @return Fieldset_Field $this to allow chaining - * @depricated Remove in v2.0, passing rules as string is to be removed use add() instead - */ - public function add_field($name, $label, $rules) - { - $field = $this->add($name, $label); - - is_array($rules) or $rules = explode('|', $rules); - - foreach ($rules as $rule) - { - if (($pos = strpos($rule, '[')) !== false) - { - preg_match('#\[(.*)\]#', $rule, $param); - $rule = substr($rule, 0, $pos); - - // deal with rules that have comma's in the rule parameter - if (in_array($rule, array('match_pattern'))) - { - call_fuel_func_array(array($field, 'add_rule'), array_merge(array($rule), array($param[1]))); - } - elseif (in_array($rule, array('valid_string'))) - { - call_fuel_func_array(array($field, 'add_rule'), array_merge(array($rule), array(explode(',', $param[1])))); - } - else - { - call_fuel_func_array(array($field, 'add_rule'), array_merge(array($rule), explode(',', $param[1]))); - } - } - else - { - $field->add_rule($rule); - } - } - - return $field; - - } - - /** - * This will overwrite lang file messages for this validation instance - * - * @param string - * @param string - * @return Validation this, to allow chaining - */ - public function set_message($rule, $message) - { - if ($message !== null) - { - $this->error_messages[$rule] = $message; - } - else - { - unset($this->error_messages[$rule]); - } - - return $this; - } - - /** - * Fetches a specific error message for this validation instance - * - * @param string - * @return string - */ - public function get_message($rule) - { - if ( ! array_key_exists($rule, $this->error_messages)) - { - return false; - } - - return $this->error_messages[$rule]; - } - - /** - * Add Callable - * - * Adds an object for which you don't need to write a full callback, just - * the method as a string will do. This also allows for overwriting functionality - * from this object because the new class is prepended. - * - * @param string|Object $class Classname or object - * @return Validation this, to allow chaining - */ - public function add_callable($class) - { - if ( ! (is_object($class) || class_exists($class))) - { - throw new \InvalidArgumentException('Input for add_callable is not a valid object or class.'); - } - - // Prevent having the same class twice in the array, remove to re-add on top if... - foreach ($this->callables as $key => $c) - { - // ...it already exists in callables - if ($c === $class) - { - unset($this->callables[$key]); - } - // ...new object/class extends it or an instance of it - elseif (is_string($c) and (is_subclass_of($class, $c) or (is_object($class) and is_a($class, $c)))) - { - unset($this->callables[$key]); - } - // but if there's a subclass in there to the new one, put the subclass on top and forget the new - elseif (is_string($class) and (is_subclass_of($c, $class) or (is_object($c) and is_a($c, $class)))) - { - unset($this->callables[$key]); - $class = $c; - } - } - - array_unshift($this->callables, $class); - - return $this; - } - - /* - * Remove Callable - * - * Removes an object from the callables array - * - * @param string|Object $class Classname or object - * @return Validation this, to allow chaining - */ - public function remove_callable($class) - { - if (($key = array_search($class, $this->callables, true))) - { - unset($this->callables[$key]); - } - - return $this; - } - - /** - * Fetch the objects for which you don't need to add a full callback but - * just the method name - * - * @return array - */ - public function callables() - { - return $this->callables; - } - - /** - * Run validation - * - * Performs validation with current fieldset and on given input, will try POST - * when input wasn't given. - * - * @param array $input input that overwrites POST values - * @param bool $allow_partial will skip validation of values it can't find or are null - * @return bool $temp_callables whether validation succeeded - */ - public function run($input = null, $allow_partial = false, $temp_callables = array()) - { - if (is_null($input) and \Input::method() != 'POST') - { - return false; - } - - // Backup current state of callables so they can be restored after adding temp callables - $callable_backup = $this->callables; - - // Add temporary callables, reversed so first ends on top - foreach (array_reverse($temp_callables) as $temp_callable) - { - $this->add_callable($temp_callable); - } - - static::set_active($this); - - $this->validated = array(); - $this->errors = array(); - $this->input = $input ?: array(); - $fields = $this->field(null, true); - foreach($fields as $field) - { - static::set_active_field($field); - - // convert form field array's to Fuel dotted notation - $name = str_replace(array('[', ']'), array('.', ''), $field->name); - - $value = $this->input($name); - if (($allow_partial === true and $value === null) - or (is_array($allow_partial) and ! in_array($field->name, $allow_partial))) - { - continue; - } - try - { - foreach ($field->rules as $rule) - { - $callback = $rule[0]; - $params = $rule[1]; - $this->_run_rule($callback, $value, $params, $field); - } - if (strpos($name, '.') !== false) - { - \Arr::set($this->validated, $name, $value); - } - else - { - $this->validated[$name] = $value; - } - } - catch (Validation_Error $v) - { - $this->errors[$field->name] = $v; - - if($field->fieldset()) - { - $field->fieldset()->Validation()->add_error($field->name, $v); - } - } - } - - static::set_active(); - static::set_active_field(); - - // Restore callables - $this->callables = $callable_backup; - - return empty($this->errors); - } - - /** - * Takes the rule input and formats it into a name & callback - * - * @param string|array $callback short rule to be called on Validation callables array or full callback - * @return array|bool rule array or false when it fails to find something callable - */ - protected function _find_rule($callback) - { - // Rules are validated and only accepted when given as an array consisting of - // array(callback, params) or just callbacks in an array. - if (is_string($callback)) - { - $callback_method = '_validation_'.$callback; - foreach ($this->callables as $callback_class) - { - if (method_exists($callback_class, $callback_method)) - { - return array($callback => array($callback_class, $callback_method)); - } - } - } - - // when no callable function was found, try regular callbacks - if (is_callable($callback)) - { - if ($callback instanceof \Closure) - { - $callback_name = 'closure'; - } - elseif (is_array($callback)) - { - $callback_name = preg_replace('#^([a-z_]*\\\\)*#i', '', - is_object($callback[0]) ? get_class($callback[0]) : $callback[0]).':'.$callback[1]; - } - else - { - $callback_name = preg_replace('#^([a-z_]*\\\\)*#i', '', str_replace('::', ':', $callback)); - } - return array($callback_name => $callback); - } - elseif (is_array($callback) and is_callable(reset($callback))) - { - return $callback; - } - else - { - $string = ! is_array($callback) - ? $callback - : (is_object(@$callback[0]) - ? get_class(@$callback[0]).'->'.@$callback[1] - : @$callback[0].'::'.@$callback[1]); - \Errorhandler::notice('Invalid rule "'.$string.'" passed to Validation, not used.'); - return false; - } - } - - /** - * Run rule - * - * Performs a single rule on a field and its value - * - * @param callback $rule - * @param mixed $value Value by reference, will be edited - * @param array $params Extra parameters - * @param array $field Validation field description - * @throws \Validation_Error - */ - protected function _run_rule($rule, &$value, $params, $field) - { - if (($rule = $this->_find_rule($rule)) === false) - { - return; - } - - $output = call_fuel_func_array(reset($rule), array_merge(array($value), $params)); - - if ($output === false and ($value !== false or key($rule) == 'required')) - { - throw new \Validation_Error($field, $value, $rule, $params); - } - elseif ($output !== true) - { - $value = $output; - } - } - - /** - * Fetches the input value from either post or given input - * - * @param string $key - * @param mixed $default - * @return mixed|array the input value or full input values array - */ - public function input($key = null, $default = null) - { - if ($key === null) - { - return $this->input; - } - - // key transformation from form array to dot notation - if (strpos($key, '[') !== false) - { - $key = str_replace(array('[', ']'), array('.', ''), $key); - } - - // if we don't have this key - if ( ! array_key_exists($key, $this->input)) - { - // it might be in dot-notation - if (strpos($key, '.') !== false) - { - // check the input first - if (($result = \Arr::get($this->input, $key, null)) !== null) - { - $this->input[$key] = $result; - } - else - { - $this->input[$key] = $this->global_input_fallback ? \Arr::get(\Input::param(), $key, $default) : $default; - } - } - else - { - // do a fallback to global input if needed, or use the provided default - $this->input[$key] = $this->global_input_fallback ? \Input::param($key, $default) : $default; - } - } - - return $this->input[$key]; - } - - /** - * Validated - * - * Returns specific validated value or all validated field=>value pairs - * - * @param string $field fieldname - * @param mixed $default value to return when not validated - * @return mixed|array the validated value or full validated values array - */ - public function validated($field = null, $default = false) - { - if ($field === null) - { - return $this->validated; - } - - return array_key_exists($field, $this->validated) ? $this->validated[$field] : $default; - } - - /** - * Error - * - * Return specific error or all errors thrown during validation - * - * @param string $field fieldname - * @param mixed $default value to return when not validated - * @return Validation_Error|array the validation error object or full array of error objects - */ - public function error($field = null, $default = false) - { - if ($field === null) - { - return $this->errors; - } - - return array_key_exists($field, $this->errors) ? $this->errors[$field] : $default; - } - - /** - * Return error message - * - * Return specific error message or all error messages thrown during validation - * - * @param string $field fieldname - * @param mixed $default value to return when not validated - * @return string|array the error message or full array of error messages - */ - public function error_message($field = null, $default = false) - { - if ($field === null) - { - $messages = array(); - foreach ($this->error() as $field => $e) - { - $messages[$field] = $e->get_message(); - } - return $messages; - } - - return array_key_exists($field, $this->errors) ? $this->errors[$field]->get_message() : $default; - } - - /** - * Show errors - * - * Returns all errors in a list or with set markup from $options param - * - * @param array $options uses keys open_list, close_list, open_error, close_error & no_errors - * @return string - */ - public function show_errors($options = array()) - { - $default = array( - 'open_list' => \Config::get('validation.open_list', '
    '), - 'close_list' => \Config::get('validation.close_list', '
'), - 'open_error' => \Config::get('validation.open_error', '
  • '), - 'close_error' => \Config::get('validation.close_error', '
  • '), - 'no_errors' => \Config::get('validation.no_errors', ''), - ); - $options = array_merge($default, $options); - - if (empty($this->errors)) - { - return $options['no_errors']; - } - - $output = $options['open_list']; - foreach($this->errors as $e) - { - $output .= $options['open_error'].$e->get_message().$options['close_error']; - } - $output .= $options['close_list']; - - return $output; - } - - /** - * Add error - * - * Adds an error for a given field. - * - * @param string $name field name for which to set the error - * @param Validation_Error $error error for the field - * @return Validation this, to allow chaining - */ - protected function add_error($name = null, $error = null) - { - if($name !== null and $error !== null) - { - $this->errors[$name] = $error; - } - - return $this; - } - - /** - * Alias for $this->fieldset->add() - * - * @param string $name - * @param string $label - * @param array $attributes - * @param array $rules - * @return Fieldset_Field - */ - public function add($name, $label = '', array $attributes = array(), array $rules = array()) - { - return $this->fieldset->add($name, $label, $attributes, $rules); - } - - /** - * Alias for $this->fieldset->add_model() - * - * @param string|Object $class - * @param array|Object $instance - * @param string $method - * @return Validation - */ - public function add_model($class, $instance = null, $method = 'set_form_fields') - { - $this->fieldset->add_model($class, $instance, $method); - - return $this; - } - - /** - * Alias for $this->fieldset->field() - * - * @param string|null $name - * @param bool $flatten - * @return Fieldset_Field|false - */ - public function field($name = null, $flatten = false) - { - return $this->fieldset->field($name, $flatten); - } - - /* ------------------------------------------------------------------------------- - * The validation methods - * ------------------------------------------------------------------------------- */ - - /** - * Required - * - * Value may not be empty - * - * @param mixed $val - * @return bool - */ - public function _validation_required($val) - { - return ! $this->_empty($val); - } - - /** - * Special empty method because 0 and '0' are non-empty values - * - * @param mixed $val - * @return bool - */ - public static function _empty($val) - { - return ($val === false or $val === null or $val === '' or $val === array()); - } - - /** - * Match value against comparison input - * - * @param mixed $val - * @param mixed $compare - * @param bool $strict whether to do type comparison - * @return bool - */ - public function _validation_match_value($val, $compare, $strict = false) - { - // first try direct match - if ($this->_empty($val) || $val === $compare || ( ! $strict && $val == $compare)) - { - return true; - } - - // allow multiple input for comparison - if (is_array($compare)) - { - foreach($compare as $c) - { - if ($val === $c || ( ! $strict && $val == $c)) - { - return true; - } - } - } - - // all is lost, return failure - return false; - } - - /** - * Match PRCE pattern - * - * @param string $val - * @param string $pattern a PRCE regex pattern - * @return bool - */ - public function _validation_match_pattern($val, $pattern) - { - return $this->_empty($val) || preg_match($pattern, $val) > 0; - } - - /** - * Match specific other submitted field string value - * (must be both strings, check is type sensitive) - * - * @param string $val - * @param string $field - * @return bool - * @throws \Validation_Error - */ - public function _validation_match_field($val, $field) - { - if ($this->input($field) !== $val) - { - $validating = $this->active_field(); - throw new \Validation_Error($validating, $val, array('match_field' => array($field)), array($this->field($field)->label)); - } - - return true; - } - - /** - * Match against an array of values - * - * @param string $val - * @param array $collection - * @param bool $strict whether to do type comparison - * @return bool - */ - public function _validation_match_collection($val, $collection = array(), $strict = false) - { - if ( ! is_array($collection)) - { - $collection = func_get_args(); - array_shift($collection); - } - - return $this->_empty($val) || in_array($val, $collection, $strict); - } - - /** - * Minimum string length - * - * @param string $val - * @param int $length - * @return bool - */ - public function _validation_min_length($val, $length) - { - return $this->_empty($val) || \Str::length($val) >= $length; - } - - /** - * Maximum string length - * - * @param string $val - * @param int $length - * @return bool - */ - public function _validation_max_length($val, $length) - { - return $this->_empty($val) || \Str::length($val) <= $length; - } - - /** - * Exact string length - * - * @param string $val - * @param int $length - * @return bool - */ - public function _validation_exact_length($val, $length) - { - return $this->_empty($val) || \Str::length($val) == $length; - } - - /** - * Validate email using PHP's filter_var() - * - * @param string $val - * @return bool - */ - public function _validation_valid_email($val) - { - return $this->_empty($val) || filter_var($val, FILTER_VALIDATE_EMAIL); - } - - /** - * Validate email using PHP's filter_var() - * - * @param string $val - * @param string $separator - * @return bool - */ - public function _validation_valid_emails($val, $separator = ',') - { - if ($this->_empty($val)) - { - return true; - } - - $emails = explode($separator, $val); - - foreach ($emails as $e) - { - if ( ! filter_var(trim($e), FILTER_VALIDATE_EMAIL)) - { - return false; - } - } - return true; - } - - /** - * Validate URL using PHP's filter_var() - * - * @param string $val - * @return bool - */ - public function _validation_valid_url($val) - { - return $this->_empty($val) || filter_var($val, FILTER_VALIDATE_URL); - } - - /** - * Validate IP using PHP's filter_var() - * - * @param string $val - * @return bool - */ - public function _validation_valid_ip($val) - { - return $this->_empty($val) || filter_var($val, FILTER_VALIDATE_IP); - } - - /** - * Validate input string with many options - * - * @param string $val - * @param string|array $flags either a named filter or combination of flags - * @return bool - */ - public function _validation_valid_string($val, $flags = array('alpha', 'utf8')) - { - if ($this->_empty($val)) - { - return true; - } - - if ( ! is_array($flags)) - { - if ($flags == 'alpha') - { - $flags = array('alpha', 'utf8'); - } - elseif ($flags == 'alpha_numeric') - { - $flags = array('alpha', 'utf8', 'numeric'); - } - elseif ($flags == 'specials') - { - $flags = array('specials', 'utf8'); - } - elseif ($flags == 'url_safe') - { - $flags = array('alpha', 'numeric', 'dashes'); - } - elseif ($flags == 'integer' or $flags == 'numeric') - { - $flags = array('numeric'); - } - elseif ($flags == 'float') - { - $flags = array('numeric', 'dots'); - } - elseif ($flags == 'quotes') - { - $flags = array('singlequotes', 'doublequotes'); - } - elseif ($flags == 'slashes') - { - $flags = array('forwardslashes', 'backslashes'); - } - elseif ($flags == 'all') - { - $flags = array('alpha', 'utf8', 'numeric', 'specials', 'spaces', 'newlines', 'tabs', 'punctuation', 'singlequotes', 'doublequotes', 'dashes', 'forwardslashes', 'backslashes', 'brackets', 'braces'); - } - else - { - return false; - } - } - - $pattern = ! in_array('uppercase', $flags) && in_array('alpha', $flags) ? 'a-z' : ''; - $pattern .= ! in_array('lowercase', $flags) && in_array('alpha', $flags) ? 'A-Z' : ''; - $pattern .= in_array('numeric', $flags) ? '0-9' : ''; - $pattern .= in_array('specials', $flags) ? '[:alpha:]' : ''; - $pattern .= in_array('spaces', $flags) ? ' ' : ''; - $pattern .= in_array('newlines', $flags) ? "\r\n" : ''; - $pattern .= in_array('tabs', $flags) ? "\t" : ''; - $pattern .= in_array('dots', $flags) && ! in_array('punctuation', $flags) ? '\.' : ''; - $pattern .= in_array('commas', $flags) && ! in_array('punctuation', $flags) ? ',' : ''; - $pattern .= in_array('punctuation', $flags) ? "\.,\!\?:;\&" : ''; - $pattern .= in_array('dashes', $flags) ? '_\-' : ''; - $pattern .= in_array('forwardslashes', $flags) ? '\/' : ''; - $pattern .= in_array('backslashes', $flags) ? '\\\\' : ''; - $pattern .= in_array('singlequotes', $flags) ? "'" : ''; - $pattern .= in_array('doublequotes', $flags) ? "\"" : ''; - $pattern .= in_array('brackets', $flags) ? "\(\)" : ''; - $pattern .= in_array('braces', $flags) ? "\{\}" : ''; - $pattern = empty($pattern) ? '/^(.*)$/' : ('/^(['.$pattern.'])+$/'); - $pattern .= in_array('utf8', $flags) || in_array('specials', $flags) ? 'u' : ''; - - return preg_match($pattern, $val) > 0; - } - - /** - * Checks whether numeric input has a minimum value - * - * @param string|float|int $val - * @param float|int $min_val - * @return bool - */ - public function _validation_numeric_min($val, $min_val) - { - return $this->_empty($val) || floatval($val) >= floatval($min_val); - } - - /** - * Checks whether numeric input has a maximum value - * - * @param string|float|int $val - * @param float|int $max_val - * @return bool - */ - public function _validation_numeric_max($val, $max_val) - { - return $this->_empty($val) || floatval($val) <= floatval($max_val); - } - - /** - * Checks whether numeric input is between a minimum and a maximum value - * - * @param string|float|int $val - * @param float|int $min_val - * @param float|int $max_val - * @return bool - */ - public function _validation_numeric_between($val, $min_val, $max_val) - { - return $this->_empty($val) or (floatval($val) >= floatval($min_val) and floatval($val) <= floatval($max_val)); - } - - /** - * Conditionally requires completion of current field based on completion of another field - * - * @param mixed $val - * @param string $field - * @return bool - * @throws \Validation_Error - */ - public function _validation_required_with($val, $field) - { - if ( ! $this->_empty($this->input($field)) and $this->_empty($val)) - { - $validating = $this->active_field(); - throw new \Validation_Error($validating, $val, array('required_with' => array($this->field($field))), array($this->field($field)->label)); - } - - return true; - } - - /** - * Checks whether string input is valid date format. When a format is passed - * it will make sure the date will be in that specific format if validated - * - * @param string $val - * @param string $format The format used at the time of a validation - * @param bool $strict Whether validation checks strict - * @return bool - */ - public function _validation_valid_date($val, $format = null, $strict = true) - { - if ($this->_empty($val)) - { - return true; - } - - if ($format) - { - $parsed = date_parse_from_format($format, $val); - } - else - { - $parsed = date_parse($val); - } - - if (\Arr::get($parsed, 'error_count', 1) + ($strict ? \Arr::get($parsed, 'warning_count', 1) : 0) === 0) - { - if ($format) - { - return date($format, mktime($parsed['hour'] ?: 0, $parsed['minute'] ?: 0, $parsed['second'] ?: 0, $parsed['month'] ?: 1, $parsed['day'] ?: 1, $parsed['year'] ?: 1970)); - } - else - { - return true; - } - } - else - { - return false; - } - } -} diff --git a/fuel/core/classes/validation/error.php b/fuel/core/classes/validation/error.php deleted file mode 100755 index 5fbeb6e..0000000 --- a/fuel/core/classes/validation/error.php +++ /dev/null @@ -1,177 +0,0 @@ -field = $field; - $this->value = $value; - $this->params = $params; - $this->rule = key($callback); - } - - /** - * Get Message - * - * Shows the error message which can be taken from loaded language file. - * - * @param string $msg HTML to prefix error message - * @param string $open HTML to postfix error message - * @param string $close Message to use, or false to try and load it from Lang class - * @return string - */ - public function get_message($msg = false, $open = '', $close = '') - { - $open = empty($open) ? \Config::get('validation.open_single_error', '') : $open; - $close = empty($close) ? \Config::get('validation.close_single_error', '') : $close; - - if ($msg === false and ! ($msg = $this->field->get_error_message($this->rule))) - { - if (is_null($msg)) - { - $msg = $this->field->fieldset()->validation()->get_message($this->rule); - } - if ($msg === false) - { - $msg = \Lang::get('validation.'.$this->rule) ?: \Lang::get('validation.'.\Arr::get(explode(':', $this->rule), 0)); - } - } - if ($msg == false) - { - return $open.'Validation rule '.$this->rule.' failed for '.$this->field->label.$close; - } - - // only parse when there's tags in the message - return $open.(strpos($msg, ':') === false ? $msg : $this->_replace_tags($msg)).$close; - } - - /** - * Replace templating tags with values - * - * @param mixed $msg error message to parse - * @return string - */ - protected function _replace_tags($msg) - { - // prepare label & value - $label = is_array($this->field->label) ? $this->field->label['label'] : $this->field->label; - $value = is_array($this->value) ? implode(', ', $this->value) : $this->value; - if (\Config::get('validation.quote_labels', false) and strpos($label, ' ') !== false) - { - // put the label in quotes if it contains spaces - $label = '"'.$label.'"'; - } - - // setup find & replace arrays - $find = array(':field', ':label', ':value', ':rule'); - $replace = array($this->field->name, $label, $value, $this->rule); - - // add the params to the find & replace arrays - foreach($this->params as $key => $val) - { - // Convert array (as far as possible) - if (is_array($val)) - { - $result = ''; - foreach ($val as $v) - { - if (is_array($v)) - { - $v = '(array)'; - } - elseif (is_object($v)) - { - $v = '(object)'; - } - elseif (is_bool($v)) - { - $v = $v ? 'true' : 'false'; - } - $result .= empty($result) ? $v : (', '.$v); - } - $val = $result; - } - elseif (is_bool($val)) - { - $val = $val ? 'true' : 'false'; - } - // Convert object with __toString or just the classname - elseif (is_object($val)) - { - $val = method_exists($val, '__toString') ? (string) $val : get_class($val); - } - - $find[] = ':param:'.($key + 1); - $replace[] = $val; - } - - // execute find & replace and return - return str_replace($find, $replace, $msg); - } - - /** - * Generate the error message - * - * @return string - */ - public function __toString() - { - return $this->get_message(); - } -} diff --git a/fuel/core/classes/view.php b/fuel/core/classes/view.php deleted file mode 100755 index 9d15db3..0000000 --- a/fuel/core/classes/view.php +++ /dev/null @@ -1,645 +0,0 @@ -auto_filter = is_null($filter) ? \Config::get('security.auto_filter_output', true) : $filter; - - $this->filter_closures = \Config::get('filter_closures', true); - - if ($file !== null) - { - $this->set_filename($file); - } - - if ($data !== null) - { - // Add the values to the current data - $this->data = $data; - } - - // store the current request search paths to deal with out-of-context rendering - if (class_exists('Request', false) and $active = \Request::active() and \Request::main() !== $active) - { - $this->request_paths = $active->get_paths(); - } - isset($active) and $this->active_request = $active; - - // store the active language, so we can render the view in the correct language later - $this->active_language = \Config::get('language', 'en'); - } - - /** - * Magic method, searches for the given variable and returns its value. - * Local variables will be returned before global variables. - * - * $value = $view->foo; - * - * @param string $key variable name - * @return mixed - * @throws \OutOfBoundsException - */ - public function & __get($key) - { - return $this->get($key); - } - - /** - * Magic method, calls [static::set] with the same parameters. - * - * $view->foo = 'something'; - * - * @param string $key variable name - * @param mixed $value value - * @return void - */ - public function __set($key, $value) - { - $this->set($key, $value); - } - - /** - * Magic method, determines if a variable is set. - * - * isset($view->foo); - * - * [!!] `null` variables are not considered to be set by [isset](http://php.net/isset). - * - * @param string $key variable name - * @return boolean - */ - public function __isset($key) - { - return (isset($this->data[$key]) or isset(static::$global_data[$key])); - } - - /** - * Magic method, unsets a given variable. - * - * unset($view->foo); - * - * @param string $key variable name - * @return void - */ - public function __unset($key) - { - unset($this->data[$key], static::$global_data[$key]); - } - - /** - * Magic method, returns the output of [static::render]. - * - * @return string - * @uses View::render - */ - public function __toString() - { - try - { - return $this->render(); - } - catch (\Exception $e) - { - \Errorhandler::exception_handler($e); - - return ''; - } - } - - /** - * Captures the output that is generated when a view is included. - * The view data will be extracted to make local variables. - * - * $output = $this->process_file(); - * - * @param bool $file_override File override - * @return string - */ - protected function process_file($file_override = false) - { - $clean_room = function($__file_name, array $__data) - { - extract($__data, EXTR_REFS); - - // Capture the view output - ob_start(); - - try - { - // Load the view within the current scope - include $__file_name; - } - catch (\Exception $e) - { - // Delete the output buffer - ob_end_clean(); - - // Re-throw the exception - throw $e; - } - - // Get the captured output and close the buffer - return ob_get_clean(); - }; - - // import and process the view file - $result = $clean_room($file_override ?: $this->file_name, $data = $this->get_data()); - - // disable sanitization on objects that support it - $this->unsanitize($data); - - // return the result - return $result; - } - - /** - * Retrieves all the data, both local and global. It filters the data if - * necessary. - * - * $data = $this->get_data(); - * - * @param string $scope local/glocal/all - * @return array view data - */ - protected function get_data($scope = 'all') - { - $filter_closures = $this->filter_closures; - $clean_it = function ($data, $rules, $auto_filter) use ($filter_closures) - { - foreach ($data as $key => &$value) - { - $filter = array_key_exists($key, $rules) ? $rules[$key] : null; - $filter = is_null($filter) ? $auto_filter : $filter; - - if ($filter) - { - if ($filter_closures and $value instanceOf \Closure) - { - $value = $value(); - } - $value = \Security::clean($value, null, 'security.output_filter'); - } - } - - return $data; - }; - - $data = array(); - - if ( ! empty($this->data) and ($scope === 'all' or $scope === 'local')) - { - $data += $clean_it($this->data, $this->local_filter, $this->auto_filter); - } - - if ( ! empty(static::$global_data) and ($scope === 'all' or $scope === 'global')) - { - $data += $clean_it(static::$global_data, static::$global_filter, $this->auto_filter); - } - - return $data; - } - - /** - * disable sanitation on any objects in the data that support it - * - * @param mixed - * @return mixed - */ - protected function unsanitize($var) - { - // deal with objects that can be sanitized - if ($var instanceOf \Sanitization) - { - $var->unsanitize(); - } - - // deal with array's or array emulating objects - elseif (is_array($var) or ($var instanceOf \Traversable and $var instanceOf \ArrayAccess)) - { - // recurse on array values - foreach($var as $key => $value) - { - $var[$key] = $this->unsanitize($value); - } - } - } - - /** - * Sets a global variable, similar to [static::set], except that the - * variable will be accessible to all views. - * - * View::set_global($name, $value); - * - * @param string $key variable name or an array of variables - * @param mixed $value value - * @param bool $filter whether to filter the data or not - * @return void - */ - public static function set_global($key, $value = null, $filter = null) - { - if (is_array($key)) - { - foreach ($key as $name => $value) - { - if ($filter !== null) - { - static::$global_filter[$name] = $filter; - } - static::$global_data[$name] = $value; - } - } - else - { - if ($filter !== null) - { - static::$global_filter[$key] = $filter; - } - static::$global_data[$key] = $value; - } - } - - /** - * Assigns a global variable by reference, similar to [static::bind], except - * that the variable will be accessible to all views. - * - * View::bind_global($key, $value); - * - * @param string $key variable name - * @param mixed $value referenced variable - * @param bool $filter whether to filter the data or not - * @return void - */ - public static function bind_global($key, &$value, $filter = null) - { - if ($filter !== null) - { - static::$global_filter[$key] = $filter; - } - static::$global_data[$key] =& $value; - } - - /** - * Sets whether to filter the data or not. - * - * $view->auto_filter(false); - * - * @param bool $filter whether to auto filter or not - * @return View - */ - public function auto_filter($filter = true) - { - if (func_num_args() == 0) - { - return $this->auto_filter; - } - - $this->auto_filter = $filter; - - return $this; - } - - /** - * Sets the view filename. - * - * $view->set_filename($file); - * - * @param string $file view filename - * @return View - * @throws \FuelException - */ - public function set_filename($file) - { - // strip the extension from it - $pathinfo = pathinfo($file); - if ( ! empty($pathinfo['extension'])) - { - $this->extension = $pathinfo['extension']; - $file = substr($file, 0, strlen($this->extension)*-1 - 1); - } - - // set find_file's one-time-only search paths - \Finder::instance()->flash($this->request_paths); - - // locate the view file - if (($path = \Finder::search('views', $file, '.'.$this->extension, false, false)) === false) - { - throw new \FuelException('The requested view could not be found: '.\Fuel::clean_path($file).'.'.$this->extension); - } - - // Store the file path locally - $this->file_name = $path; - - return $this; - } - - /** - * Searches for the given variable and returns its value. - * Local variables will be returned before global variables. - * - * $value = $view->get('foo', 'bar'); - * - * If the key is not given or null, the entire data array is returned. - * - * If a default parameter is not given and the variable does not - * exist, it will throw an OutOfBoundsException. - * - * @param string $key The variable name - * @param mixed $default The default value to return - * @return mixed - * @throws \OutOfBoundsException - */ - public function &get($key = null, $default = null) - { - if (func_num_args() === 0 or $key === null) - { - return $this->data; - } - elseif (strpos($key, '.') === false) - { - if (array_key_exists($key, $this->data)) - { - return $this->data[$key]; - } - elseif (array_key_exists($key, static::$global_data)) - { - return static::$global_data[$key]; - } - } - else - { - if (($result = \Arr::get($this->data, $key, \Arr::get(static::$global_data, $key, '__KEY__LOOKUP__MISS__'))) !== '__KEY__LOOKUP__MISS__') - { - return $result; - } - } - - if (is_null($default) and func_num_args() === 1) - { - throw new \OutOfBoundsException('View variable is not set: '.$key); - } - else - { - // assign it first, you can't return a return value by reference directly! - $default = \Fuel::value($default); - return $default; - } - } - - /** - * Assigns a variable by name. Assigned values will be available as a - * variable within the view file: - * - * // This value can be accessed as $foo within the view - * $view->set('foo', 'my value'); - * - * You can also use an array to set several values at once: - * - * // Create the values $food and $beverage in the view - * $view->set(array('food' => 'bread', 'beverage' => 'water')); - * - * @param string $key variable name or an array of variables - * @param mixed $value value - * @param bool $filter whether to filter the data or not - * @return $this - */ - public function set($key, $value = null, $filter = null) - { - if (is_array($key)) - { - foreach ($key as $name => $value) - { - $this->set($name, $value, $filter); - } - } - else - { - if ($filter !== null) - { - $this->local_filter[$key] = $filter; - } - - if (strpos($key, '.') === false) - { - $this->data[$key] = $value; - } - else - { - \Arr::set($this->data, $key, $value); - } - } - - return $this; - } - - /** - * The same as set(), except this defaults to not-encoding the variable - * on output. - * - * $view->set_safe('foo', 'bar'); - * - * @param string $key variable name or an array of variables - * @param mixed $value value - * @return $this - */ - public function set_safe($key, $value = null) - { - return $this->set($key, $value, false); - } - - /** - * Assigns a value by reference. The benefit of binding is that values can - * be altered without re-setting them. It is also possible to bind variables - * before they have values. Assigned values will be available as a - * variable within the view file: - * - * // This reference can be accessed as $ref within the view - * $view->bind('ref', $bar); - * - * @param string $key variable name - * @param mixed $value referenced variable - * @param bool $filter Whether to filter the var on output - * @return $this - */ - public function bind($key, &$value, $filter = null) - { - if ($filter !== null) - { - $this->local_filter[$key] = $filter; - } - $this->data[$key] =& $value; - - return $this; - } - - /** - * Renders the view object to a string. Global and local data are merged - * and extracted to create local variables within the view file. - * - * $output = $view->render(); - * - * [!!] Global variables with the same key name as local variables will be - * overwritten by the local variable. - * - * @param $file string view filename - * @return string - * @throws \FuelException - * @uses static::capture - */ - public function render($file = null) - { - // reactivate the correct request - if (class_exists('Request', false)) - { - $current_request = \Request::active(); - \Request::active($this->active_request); - } - - // store the current language, and set the correct render language - if ($this->active_language) - { - $current_language = \Config::get('language', 'en'); - \Config::set('language', $this->active_language); - } - - // override the view filename if needed - if ($file !== null) - { - $this->set_filename($file); - } - - // and make sure we have one - if (empty($this->file_name)) - { - throw new \FuelException('You must set the file to use within your view before rendering'); - } - - // combine local and global data and capture the output - $return = $this->process_file(); - - // restore the current language setting - $this->active_language and \Config::set('language', $current_language); - - // and the active request class - if (isset($current_request)) - { - \Request::active($current_request); - } - - return $return; - } - -} diff --git a/fuel/core/classes/viewmodel.php b/fuel/core/classes/viewmodel.php deleted file mode 100755 index d5dd419..0000000 --- a/fuel/core/classes/viewmodel.php +++ /dev/null @@ -1,26 +0,0 @@ - array( - - /** - * Whether of not manual parsing is enabled. - * - * set to false to disable this functionality. - */ - 'enabled' => true, - - /** - * Location from where the updated browscap file can be downloaded. - */ - 'url' => 'http://browscap.org/stream?q=Lite_PHP_BrowsCapINI', // only major browsers and search engines - //'url' => 'http://browscap.org/stream?q=Full_PHP_BrowsCapINI', // complete file, approx. 3 times the lite version - - /** - * Method used to download the updated browscap file - * - * Default: 'wrapper' - * - * possible values are: 'local', 'wrapper', 'curl' - */ - 'method' => 'wrapper', - - /** - * Optional http proxy configuration, will be used for both the 'wrapper' and 'curl' methods - */ - 'proxy' => array( - - /** - * hostname or IP address of your proxy - * - * Note: so "proxy.example.org" or "1.2.3.4", and not "http://proxy.example.org" !!! - */ - 'host' => null, - - /** - * TCP port number the proxy listens at - */ - 'port' => null, - - /** - * Authentication type to use - * - * Default: 'none' - * - * possible values are: 'none', 'basic', 'ntlm' - * - * Note that the 'wrapper' method only supports 'basic', all others are evaluated as 'none'! - */ - 'auth' => 'none', - - /** - * If your proxy requires authentication, specify a username and password - */ - 'username' => null, - 'password' => null, - ), - - /** - * Filename for the local browscap.ini file (for method 'local'). - * - * Default: '' - */ - 'file' => '/tmp/php_browscap.ini', - ), - - /** - * Cache configuration. - * - * The agent class caches all matched agent strings for future reference - * so the browscap file doesn't need to be loaded, as it's quite large. - * - * Also, the parsed and condensed browscap ini file is stored in cache as - * well, so when a new user agent string needs to be looked up, no further - * parsing is needed. - */ - 'cache' => array( - - /** - * Storage driver to use to cache agent class entries. If not defined, - * the default driver defined in config/cache.php will be used. - * - * Default: '' - */ - 'driver' => '', - - /** - * Cache expiry. - * - * Number of seconds after which a cached agent result expires. - * - * Default: 604800 (every 7 days) - * - * Note that to prevent abuse of the site publishing the browsecap files, - * you can not set the expiry time lower than 7200 (2 hours) - */ - 'expiry' => 604800, - - /** - * Identifier used to store agent class cache elements - * - * Default: 'fuel.agent' - * - */ - 'identifier' => 'fuel.agent', - ), - -); diff --git a/fuel/core/config/ascii.php b/fuel/core/config/ascii.php deleted file mode 100755 index ebd19da..0000000 --- a/fuel/core/config/ascii.php +++ /dev/null @@ -1,90 +0,0 @@ - 'ae', - '/œ/' => 'oe', - '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|А/' => 'A', - '/à|á|â|ã|ä|å|ǻ|ā|ă|ą|ǎ|ª|а/' => 'a', - '/Б/' => 'B', - '/б/' => 'b', - '/Ç|Ć|Ĉ|Ċ|Č|Ц/' => 'C', - '/ç|ć|ĉ|ċ|č|ц/' => 'c', - '/Ð|Ď|Đ|Д/' => 'D', - '/ð|ď|đ|д/' => 'd', - '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Е|Ё|Э/' => 'E', - '/è|é|ê|ë|ē|ĕ|ė|ę|ě|е|ё|э/' => 'e', - '/Ф/' => 'F', - '/ƒ|ф/' => 'f', - '/Ĝ|Ğ|Ġ|Ģ|Г/' => 'G', - '/ĝ|ğ|ġ|ģ|г/' => 'g', - '/Ĥ|Ħ|Х/' => 'H', - '/ĥ|ħ|х/' => 'h', - '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|И/' => 'I', - '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|и/' => 'i', - '/Ĵ|Й/' => 'J', - '/ĵ|й/' => 'j', - '/Ķ|К/' => 'K', - '/ķ|к/' => 'k', - '/Ĺ|Ļ|Ľ|Ŀ|Ł|Л/' => 'L', - '/ĺ|ļ|ľ|ŀ|ł|л/' => 'l', - '/М/' => 'M', - '/м/' => 'm', - '/Ñ|Ń|Ņ|Ň|Н/' => 'N', - '/ñ|ń|ņ|ň|ʼn|н/' => 'n', - '/Ò|Ó|Ö|Ő|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|О/' => 'O', - '/ò|ó|ö|ő|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|о/' => 'o', - '/П/' => 'P', - '/п/' => 'p', - '/Ŕ|Ŗ|Ř|Р/' => 'R', - '/ŕ|ŗ|ř|р/' => 'r', - '/Ś|Ŝ|Ş|Š|С/' => 'S', - '/ś|ŝ|ş|š|ſ|с/' => 's', - '/Ţ|Ť|Ŧ|Т/' => 'T', - '/ţ|ť|ŧ|т/' => 't', - '/Ù|Ú|Ü|Ű|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|У/' => 'U', - '/ù|ú|ü|ű|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|у/' => 'u', - '/В/' => 'V', - '/в/' => 'v', - '/Ý|Ÿ|Ŷ|Ы/' => 'Y', - '/ý|ÿ|ŷ|ы/' => 'y', - '/Ŵ/' => 'W', - '/ŵ/' => 'w', - '/Ź|Ż|Ž|З/' => 'Z', - '/ź|ż|ž|з/' => 'z', - '/Æ|Ǽ/' => 'AE', - '/ß/'=> 'ss', - '/IJ/' => 'IJ', - '/ij/' => 'ij', - '/Œ/' => 'OE', - '/Ч/' => 'Ch', - '/ч/' => 'ch', - '/Ю/' => 'Ju', - '/ю/' => 'ju', - '/Я/' => 'Ja', - '/я/' => 'ja', - '/Ш/' => 'Sh', - '/ш/' => 'sh', - '/Щ/' => 'Shch', - '/щ/' => 'shch', - '/Ж/' => 'Zh', - '/ж/' => 'zh', -); diff --git a/fuel/core/config/asset.php b/fuel/core/config/asset.php deleted file mode 100755 index 82e70be..0000000 --- a/fuel/core/config/asset.php +++ /dev/null @@ -1,117 +0,0 @@ - array('assets/'), - - /** - * Asset Sub-folders - * - * Names for the img, js and css folders (inside the asset search path). - * - * Examples: - * - * img/ - * js/ - * css/ - * - * This MUST include the trailing slash ('/') - */ - 'img_dir' => 'img/', - 'js_dir' => 'js/', - 'css_dir' => 'css/', - - /** - * You can also specify one or more per asset-type folders. You don't have - * to specify all of them. * Each folder is a RELATIVE path from the url - * speficied below: - * - * array('css' => 'assets/css/') - * - * These MUST include the trailing slash ('/') - * - * Paths specified here are expected to contain the assets they point to - */ - 'folders' => array( - 'css' => array(), - 'js' => array(), - 'img' => array(), - ), - - /** - * URL to your Fuel root. Typically this will be your base URL: - * - * \Config::get('base_url') - * - * These MUST include the trailing slash ('/') - */ - 'url' => \Config::get('base_url'), - - /** - * Whether to append the assets last modified timestamp to the url. - * This will aid in asset caching, and is recommended. It will create - * tags like this: - * - * - */ - 'add_mtime' => true, - - /** - * The amount of indents to prefix to the generated asset tag(s). - */ - 'indent_level' => 1, - - /** - * What to use for indenting. - */ - 'indent_with' => "\t", - - /** - * What to do when an asset method is called without a group name. If true, it will - * return the generated asset tag. If false, it will add it to the default group. - */ - 'auto_render' => true, - - /** - * Set to true to prevent an exception from being throw when a file is not found. - * The asset will then be skipped. - */ - 'fail_silently' => false, - - /** - * When set to true, the Asset class will always true to resolve an asset URI - * to a local asset, even if the asset URL is an absolute URL, for example - * one that points to another hostname. - */ - 'always_resolve' => false, - -); diff --git a/fuel/core/config/cache.php b/fuel/core/config/cache.php deleted file mode 100755 index 65b909d..0000000 --- a/fuel/core/config/cache.php +++ /dev/null @@ -1,77 +0,0 @@ - 'file', - - // default expiration (null = no expiration) - 'expiration' => null, - - /** - * Default content handlers: convert values to strings to be stored - * You can set them per primitive type or object class like this: - * - 'string_handler' => 'string' - * - 'array_handler' => 'json' - * - 'Some_Object_handler' => 'serialize' - */ - - /** - * ---------------------------------------------------------------------- - * storage driver settings - * ---------------------------------------------------------------------- - */ - - // specific configuration settings for the file driver - 'file' => array( - 'path' => '', // if empty the default will be application/cache/ - ), - - // specific configuration settings for the memcached driver - 'memcached' => array( - 'cache_id' => 'fuel', // unique id to distinquish fuel cache items from others stored on the same server(s) - 'servers' => array( // array of servers and portnumbers that run the memcached service - 'default' => array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100), - ), - ), - - // specific configuration settings for the apc driver - 'apc' => array( - 'cache_id' => 'fuel', // unique id to distinquish fuel cache items from others stored on the same server(s) - ), - - // specific configuration settings for the redis driver - 'redis' => array( - 'database' => 'default', // name of the redis database to use (as configured in config/db.php) - ), - - // specific configuration settings for the xcache driver - 'xcache' => array( - 'cache_id' => 'fuel', // unique id to distinquish fuel cache items from others stored on the same server(s) - ), -); diff --git a/fuel/core/config/config.php b/fuel/core/config/config.php deleted file mode 100755 index c0276e8..0000000 --- a/fuel/core/config/config.php +++ /dev/null @@ -1,436 +0,0 @@ - '/foo/', - * 'base_url' => 'http://foo.com/' - * - * Set this to null to have it automatically detected. - */ - 'base_url' => null, - - /** - * url_suffix - Any suffix that needs to be added to - * URL's generated by Fuel. If the suffix is an extension, - * make sure to include the dot - * - * 'url_suffix' => '.html', - * - * Set this to an empty string if no suffix is used - */ - 'url_suffix' => '', - - /** - * index_file - The name of the main bootstrap file. - * - * Set this to 'index.php if you don't use URL rewriting - */ - 'index_file' => false, - - 'profiling' => false, - - /** - * profiling_paths - The paths to show in profiler. - * - * If you do not wish to see path set to 'NULL' - * You can also add other paths that you wish not to see - */ - 'profiling_paths' => array( - 'APPPATH' => APPPATH, - 'COREPATH' => COREPATH, - 'PKGPATH' => PKGPATH, - ), - - /** - * Default location for the file cache - */ - 'cache_dir' => APPPATH.'cache/', - - /** - * Settings for the file finder cache (the Cache class has it's own config!) - */ - 'caching' => false, - 'cache_lifetime' => 3600, // In Seconds - - /** - * Callback to use with ob_start(), set this to 'ob_gzhandler' for gzip encoding of output - */ - 'ob_callback' => null, - - 'errors' => array( - // Which errors should we show, but continue execution? You can add the following: - // E_NOTICE, E_WARNING, E_DEPRECATED, E_STRICT to mimic PHP's default behaviour - // (which is to continue on non-fatal errors). We consider this bad practice. - 'continue_on' => array(), - // How many errors should we show before we stop showing them? (prevents out-of-memory errors) - 'throttle' => 10, - // Should notices from Errorhandler::notice() be shown? - 'notices' => true, - // Render previous contents or show it as HTML? - 'render_prior' => false, - ), - - /** - * Localization & internationalization settings - */ - 'language' => 'en', // Default language - 'language_fallback' => 'en', // Fallback language when file isn't available for default language - 'locale' => 'en_US', // PHP set_locale() setting, null to not set - - /** - * Internal string encoding charset - */ - 'encoding' => 'UTF-8', - - /** - * DateTime settings - * - * server_gmt_offset in seconds the server offset from gmt timestamp when time() is used - * default_timezone optional, if you want to change the server's default timezone - */ - 'server_gmt_offset' => 0, - 'default_timezone' => null, - - /** - * Logging Threshold. Can be set to any of the following: - * - * \Fuel::L_NONE - * \Fuel::L_ERROR - * \Fuel::L_WARNING - * \Fuel::L_DEBUG - * \Fuel::L_INFO - * \Fuel::L_ALL - */ - 'log_threshold' => \Fuel::L_WARNING, - - /** - * Log file and path. If no filename is given, it will be generated. - */ - 'log_file' => null, - 'log_path' => APPPATH.'logs/', - - 'log_date_format' => 'Y-m-d H:i:s', - - /** - * If true, a backtrace is printed when a PHP fatal error is encountered in CLI mode - */ - 'cli_backtrace' => false, - - /** - * Security settings - */ - 'security' => array( - /** - * If true, every HTTP request of the type speficied in autoload_methods - * will be checked for a CSRF token. If not present or not valid, a - * security exception will be thrown. - */ - 'csrf_autoload' => false, - 'csrf_autoload_methods' => array('post', 'put', 'delete'), - - /** - * If true, a HttpBadRequestException will be thrown. If false, a generic - * SecurityException will be thrown. It is false by default for B/C reasons - */ - 'csrf_bad_request_on_fail' => false, - - /** - * If true, Form::open() adds CSRF token hidden field automatically. - */ - 'csrf_auto_token' => false, - - /** - * Name of the form field that holds the CSRF token. - */ - 'csrf_token_key' => 'fuel_csrf_token', - - /** - * Expiry of the token in seconds. If zero, the token remains the same - * for the entire user session. - */ - 'csrf_expiration' => 0, - - /** - * A salt to make sure the generated security tokens are not predictable - */ - 'token_salt' => 'put your salt value here to make the token more secure', - - /** - * Allow the Input class to use X headers when present - * - * Examples of these are HTTP_X_FORWARDED_FOR and HTTP_X_FORWARDED_PROTO, which - * can be faked which could have security implications - */ - 'allow_x_headers' => false, - - /** - * This input filter can be any normal PHP function as well as 'xss_clean' - * - * WARNING: Using xss_clean will cause a performance hit. - * How much is dependant on how much input data there is. - * - * Note: MUST BE DEFINED IN THE APP CONFIG FILE! - */ - //'uri_filter' => array(), - - /** - * This input filter can be any normal PHP function as well as 'xss_clean' - * - * WARNING: Using xss_clean will cause a performance hit. - * How much is dependant on how much input data there is. - * - * Note: MUST BE DEFINED IN THE APP CONFIG FILE! - */ - //'input_filter' => array(), - - /** - * This output filter can be any normal PHP function as well as 'xss_clean' - * - * WARNING: Using xss_clean will cause a performance hit. - * How much is dependant on how much input data there is. - * - * Note: MUST BE DEFINED IN THE APP CONFIG FILE! - */ - //'output_filter' => array(), - - /** - * Encoding mechanism to use on htmlentities() - */ - 'htmlentities_flags' => ENT_QUOTES, - - /** - * Whether to encode HTML entities as well - */ - 'htmlentities_double_encode' => false, - - /** - * Whether to automatically filter view data - */ - 'auto_filter_output' => true, - - /** - * Whether to filter closures as well - */ - 'filter_closures' => true, - - /** - * With output encoding switched on all objects passed will be converted to strings or - * throw exceptions unless they are instances of the classes in this array. - */ - 'whitelisted_classes' => array(), - - /** - * Set this to true of your client sends data using the HTTP PUT, DELETE or PATCH methods - * using the www-form-urlencoded content-type, and it's contents is urlencoded locally - * before submitting - */ - 'form-double-urlencoded' => false, - - /** - * clean_paths - paths to clean before outputting FQFN or paths - * - * If you do not wish to see path set to 'NULL' - * You can also add other paths that you wish not to see - */ - 'clean_paths' => array( - ), - ), - - /** - * Cookie settings - */ - 'cookie' => array( - // Number of seconds before the cookie expires - 'expiration' => 0, - // Restrict the path that the cookie is available to - 'path' => '/', - // Restrict the domain that the cookie is available to - 'domain' => null, - // Only transmit cookies over secure connections - 'secure' => false, - // Only transmit cookies over HTTP, disabling Javascript access - 'http_only' => false, - ), - - /** - * Validation settings - */ - 'validation' => array( - /** - * Whether to fallback to global when a value is not found in the input array. - */ - 'global_input_fallback' => true, - ), - - /** - * Controller class prefix - */ - 'controller_prefix' => 'Controller_', - - /** - * Routing settings - */ - 'routing' => array( - /** - * Whether URI routing is case sensitive or not - */ - 'case_sensitive' => true, - - /** - * Whether to strip the extension - */ - 'strip_extension' => true, - ), - - /** - * Response settings - */ - 'response' => array( - /** - * Whether to support URI wildcards when redirecting - */ - 'redirect_with_wildcards' => true, - ), - - /** - * Config settings - */ - 'config' => array( - /* - * Name of the table used by the Config_Db driver - */ - 'table_name' => 'config', - - /* - * Database that holds the config table - */ - 'database' => null, - - /* - * Array of servers and portnumbers that run the memcached service for config data - */ - 'memcached' => array( - 'identifier' => 'config', - 'servers' => array( - array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100), - ), - ), - ), - - /** - * Lang settings - */ - 'lang' => array( - /* - * Name of the table used by the Lang_Db driver - */ - 'table_name' => 'lang', - ), - - /** - * To enable you to split up your application into modules which can be - * routed by the first uri segment you have to define their basepaths - * here. By default empty, but to use them you can add something - * like this: - * array(APPPATH.'modules'.DS) - * - * Paths MUST end with a directory separator (the DS constant)! - */ - 'module_paths' => array( - //APPPATH.'modules'.DS - ), - - /** - * To enable you to split up your additions to the framework, packages are - * used. You can define the basepaths for your packages here. By default - * empty, but to use them you can add something like this: - * array(APPPATH.'modules'.DS) - * - * Paths MUST end with a directory separator (the DS constant)! - */ - 'package_paths' => array( - //PKGPATH - ), - - /**************************************************************************/ - /* Always Load */ - /**************************************************************************/ - 'always_load' => array( - - /** - * These packages are loaded on Fuel's startup. - * You can specify them in the following manner: - * - * array('auth'); // This will assume the packages are in PKGPATH - * - * // Use this format to specify the path to the package explicitly - * array( - * array('auth' => PKGPATH.'auth/') - * ); - */ - 'packages' => array( - //'orm', - ), - - /** - * These modules are always loaded on Fuel's startup. You can specify them - * in the following manner: - * - * array('module_name'); - * - * A path must be set in module_paths for this to work. - */ - 'modules' => array(), - - /** - * Classes to autoload & initialize even when not used - */ - 'classes' => array(), - - /** - * Configs to autoload - * - * Examples: if you want to load 'session' config into a group 'session' you only have to - * add 'session'. If you want to add it to another group (example: 'auth') you have to - * add it like 'session' => 'auth'. - * If you don't want the config in a group use null as groupname. - */ - 'config' => array(), - - /** - * Language files to autoload - * - * Examples: if you want to load 'validation' lang into a group 'validation' you only have to - * add 'validation'. If you want to add it to another group (example: 'forms') you have to - * add it like 'validation' => 'forms'. - * If you don't want the lang in a group use null as groupname. - */ - 'language' => array(), - ), - -); diff --git a/fuel/core/config/date.php b/fuel/core/config/date.php deleted file mode 100755 index b4b798e..0000000 --- a/fuel/core/config/date.php +++ /dev/null @@ -1,45 +0,0 @@ - array( - 'local' => '%c', - - 'mysql' => '%Y-%m-%d %H:%M:%S', - 'mysql_date' => '%Y-%m-%d', - - 'us' => '%m/%d/%Y', - 'us_short' => '%m/%d', - 'us_named' => '%B %d %Y', - 'us_full' => '%I:%M %p, %B %d %Y', - 'eu' => '%d/%m/%Y', - 'eu_short' => '%d/%m', - 'eu_named' => '%d %B %Y', - 'eu_full' => '%H:%M, %d %B %Y', - - '24h' => '%H:%M', - '12h' => '%I:%M %p', - ), -); diff --git a/fuel/core/config/db.php b/fuel/core/config/db.php deleted file mode 100755 index 248112c..0000000 --- a/fuel/core/config/db.php +++ /dev/null @@ -1,82 +0,0 @@ - 'default', - /** - * Base PDO config - */ - 'default' => array( - 'type' => 'pdo', - 'connection' => array( - 'dsn' => '', - 'hostname' => '', - 'username' => null, - 'password' => null, - 'database' => '', - 'persistent' => false, - 'compress' => false, - ), - 'identifier' => '`', - 'table_prefix' => '', - 'charset' => 'utf8', - 'collation' => false, - 'enable_cache' => true, - 'profiling' => false, - 'readonly' => false, - ), - /** - * Base MySQLi config - * - 'default' => array( - 'type' => 'mysqli', - 'connection' => array( - 'dsn' => '', - 'hostname' => '', - 'username' => null, - 'password' => null, - 'database' => '', - 'persistent' => false, - 'compress' => false, - ), - 'identifier' => '`', - 'table_prefix' => '', - 'charset' => 'utf8', - 'collation' => false, - 'enable_cache' => false, - 'profiling' => false, - 'readonly' => false, - ), - */ - /** - * Base Redis config - */ - 'redis' => array( - 'default' => array( - 'hostname' => '127.0.0.1', - 'port' => 6379, - 'timeout' => null, - 'database' => 0, - ), - ), -); \ No newline at end of file diff --git a/fuel/core/config/doctypes.php b/fuel/core/config/doctypes.php deleted file mode 100755 index 43db02c..0000000 --- a/fuel/core/config/doctypes.php +++ /dev/null @@ -1,32 +0,0 @@ -'', - 'xhtml1-strict'=>'', - 'xhtml1-trans'=>'', - 'xhtml1-frame'=>'', - 'html5'=>'', - 'html4-strict'=>'', - 'html4-trans'=>'', - 'html4-frame'=>'', -); -/*end of file: core/config/doctype.php*/ diff --git a/fuel/core/config/file.php b/fuel/core/config/file.php deleted file mode 100755 index 17e955e..0000000 --- a/fuel/core/config/file.php +++ /dev/null @@ -1,81 +0,0 @@ - array( - - /** - * Path to basedir restriction, null for no restriction - */ - 'basedir' => null, - - /** - * array of allowed extensions, null for all - */ - 'extensions' => null, - - /** - * Base url for files, null for not available - */ - 'url' => null, - - /** - * Whether or not to use file locks when doing file operations - */ - 'use_locks' => null, - - /** - * array containing file driver per file extension - */ - 'file_handlers' => array(), - ), - - // Pre configure some areas - 'areas' => array( - /* 'area_name' => array( - 'basedir' => null, - 'extensions' => null, - 'url' => null, - 'use_locks' => null, - 'file_handlers' => array(), - ), */ - ), - - // fileinfo() magic filename - 'magic_file' => null, - - // default file and directory permissions - 'chmod' => array( - - /** - * Permissions for newly created files - */ - 'files' => 0666, - - /** - * Permissions for newly created directories - */ - 'folders' => 0777, - ), - -); diff --git a/fuel/core/config/form.php b/fuel/core/config/form.php deleted file mode 100755 index 367901b..0000000 --- a/fuel/core/config/form.php +++ /dev/null @@ -1,45 +0,0 @@ - true, - 'auto_id' => true, - 'auto_id_prefix' => 'form_', - 'form_method' => 'post', - 'form_template' => "\n\t\t{open}\n\t\t\n{fields}\n\t\t
    \n\t\t{close}\n", - 'fieldset_template' => "\n\t\t{open}\n{fields}
    \n\t\t{close}\n", - 'field_template' => "\t\t\n\t\t\t{label}{required}\n\t\t\t{field} {description} {error_msg}\n\t\t\n", - 'multi_field_template' => "\t\t\n\t\t\t{group_label}{required}\n\t\t\t{fields}\n\t\t\t\t{field} {label}
    \n{fields}{description}\t\t\t{error_msg}\n\t\t\t\n\t\t\n", - 'error_template' => '{error_msg}', - 'group_label' => '{label}', - 'required_mark' => '*', - 'inline_errors' => false, - 'error_class' => null, - 'label_class' => null, - - // tabular form definitions - 'tabular_form_template' => "{fields}
    \n", - 'tabular_field_template' => "{field}", - 'tabular_row_template' => "{fields}\n", - 'tabular_row_field_template' => "\t\t\t{label}{required} {field} {error_msg}\n", - 'tabular_delete_label' => "Delete?", -); diff --git a/fuel/core/config/format.php b/fuel/core/config/format.php deleted file mode 100755 index 92391aa..0000000 --- a/fuel/core/config/format.php +++ /dev/null @@ -1,49 +0,0 @@ - array( - 'import' => array( - 'delimiter' => ',', - 'enclosure' => '"', - 'newline' => "\n", - 'escape' => '\\', - ), - 'export' => array( - 'delimiter' => ',', - 'enclosure' => '"', - 'newline' => "\n", - 'escape' => '\\', - ), - 'regex_newline' => "\n", - 'enclose_numbers' => true, - ), - 'xml' => array( - 'basenode' => 'xml', - 'use_cdata' => false, - 'bool_representation' => null, - ), - 'json' => array( - 'encode' => array( - 'options' => JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP, - ), - ), -); diff --git a/fuel/core/config/ftp.php b/fuel/core/config/ftp.php deleted file mode 100755 index a03248b..0000000 --- a/fuel/core/config/ftp.php +++ /dev/null @@ -1,33 +0,0 @@ - array( - 'hostname' => 'localhost', - 'username' => '', - 'password' => '', - 'port' => 21, - 'passive' => true, - 'ssl_mode' => false, - 'debug' => false, - ), -); diff --git a/fuel/core/config/image.php b/fuel/core/config/image.php deleted file mode 100755 index 1400d12..0000000 --- a/fuel/core/config/image.php +++ /dev/null @@ -1,107 +0,0 @@ - 'gd', - - /** - * Sets the background color of the image. - * - * Set to null for a transparent background. - */ - 'bgcolor' => null, - - /** - * Sets the transparency of any watermark added to the image. - */ - 'watermark_alpha' => 75, - - /** - * The quality of the image being saved or output, if the format supports it. - */ - 'quality' => 100, - - /** - * Lets you use a default container for images. Override by Image::output('png') or Image::save('file.png') - * - * Examples: png, bmp, jpeg, ... - */ - 'filetype' => null, - - /** - * The install location of the imagemagick executables. - */ - 'imagemagick_dir' => '/usr/bin/', - - /** - * Temporary directory to store image files in that are being edited. - */ - 'temp_dir' => APPPATH.'tmp'.DS, - - /** - * The string of text to append to the image. - */ - 'temp_append' => 'fuelimage_', - - /** - * Sets if the queue should be cleared after a save(), save_pa(), or output(). - */ - 'clear_queue' => true, - - /** - * Determines whether to automatically reload the image (false) or keep the changes (true) when saving or outputting. - */ - 'persistence' => false, - - /** - * Used to debug the class, defaults to false. - */ - 'debug' => false, - - /** - * These presets allow you to call controlled manipulations. - */ - 'presets' => array( - - /** - * This shows an example of how to add preset manipulations - * to an image. - * - * Note that config values here override the current configuration. - * - * Driver cannot be changed in here. - - 'example' => array( - 'quality' => 100, - 'bgcolor' => null, - 'actions' => array( - array('crop_resize', 200, 200), - array('border', 20, "#f00"), - array('rounded', 10), - array('output', 'png') - ) - ) - */ - ), -); diff --git a/fuel/core/config/index.html b/fuel/core/config/index.html deleted file mode 100755 index e69de29..0000000 diff --git a/fuel/core/config/migrations.php b/fuel/core/config/migrations.php deleted file mode 100755 index 5d79b9a..0000000 --- a/fuel/core/config/migrations.php +++ /dev/null @@ -1,54 +0,0 @@ - array( - 'app' => array( - 'default' => 0, - ), - 'module' => array(), - 'package' => array(), - ), - - /* - | Folder name where migrations are stored relative to App, Module and Package Paths? - | - | Default: 'migrations/' - | - */ - 'folder' => 'migrations/', - - /* - | Table name - | - | Default: 'migration' - | - */ - 'table' => 'migration', - -); diff --git a/fuel/core/config/mimes.php b/fuel/core/config/mimes.php deleted file mode 100755 index 8ac5897..0000000 --- a/fuel/core/config/mimes.php +++ /dev/null @@ -1,106 +0,0 @@ - - */ -/* -| ------------------------------------------------------------------- -| MIME TYPES -| ------------------------------------------------------------------- -| This file contains an array of mime types. It is used by the -| Upload class to help identify allowed file types. -| -*/ - -return array( 'hqx' => 'application/mac-binhex40', - 'cpt' => 'application/mac-compactpro', - 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'), - 'bin' => 'application/macbinary', - 'dms' => 'application/octet-stream', - 'lha' => 'application/octet-stream', - 'lzh' => 'application/octet-stream', - 'exe' => array('application/octet-stream', 'application/x-msdownload'), - 'class' => 'application/octet-stream', - 'psd' => 'application/x-photoshop', - 'so' => 'application/octet-stream', - 'sea' => 'application/octet-stream', - 'dll' => 'application/octet-stream', - 'oda' => 'application/oda', - 'pdf' => array('application/pdf', 'application/x-download'), - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'mif' => 'application/vnd.mif', - 'xls' => array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'), - 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint'), - 'wbxml' => 'application/wbxml', - 'wmlc' => 'application/wmlc', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dxr' => 'application/x-director', - 'dvi' => 'application/x-dvi', - 'gtar' => 'application/x-gtar', - 'gz' => 'application/x-gzip', - 'php' => 'application/x-httpd-php', - 'php4' => 'application/x-httpd-php', - 'php3' => 'application/x-httpd-php', - 'phtml' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'js' => 'application/x-javascript', - 'swf' => 'application/x-shockwave-flash', - 'sit' => 'application/x-stuffit', - 'tar' => 'application/x-tar', - 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), - 'xhtml' => 'application/xhtml+xml', - 'xht' => 'application/xhtml+xml', - 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'), - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mpga' => 'audio/mpeg', - 'mp2' => 'audio/mpeg', - 'mp3' => array('audio/mpeg', 'audio/mpg'), - 'aif' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'ram' => 'audio/x-pn-realaudio', - 'rm' => 'audio/x-pn-realaudio', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'ra' => 'audio/x-realaudio', - 'rv' => 'video/vnd.rn-realvideo', - 'wav' => 'audio/x-wav', - 'bmp' => 'image/bmp', - 'gif' => 'image/gif', - 'jpeg' => array('image/jpeg', 'image/pjpeg'), - 'jpg' => array('image/jpeg', 'image/pjpeg'), - 'jpe' => array('image/jpeg', 'image/pjpeg'), - 'png' => array('image/png', 'image/x-png'), - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'css' => 'text/css', - 'html' => 'text/html', - 'htm' => 'text/html', - 'shtml' => 'text/html', - 'txt' => 'text/plain', - 'text' => 'text/plain', - 'log' => array('text/plain', 'text/x-log'), - 'rtx' => 'text/richtext', - 'rtf' => 'text/rtf', - 'xml' => 'text/xml', - 'xsl' => 'text/xml', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpe' => 'video/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'avi' => 'video/x-msvideo', - 'movie' => 'video/x-sgi-movie', - 'doc' => 'application/msword', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'word' => array('application/msword', 'application/octet-stream'), - 'xl' => 'application/excel', - 'eml' => 'message/rfc822', - ); - -/* Location: ./application/config/mimes.php */ diff --git a/fuel/core/config/num.php b/fuel/core/config/num.php deleted file mode 100755 index 3c67930..0000000 --- a/fuel/core/config/num.php +++ /dev/null @@ -1,46 +0,0 @@ - array( - // Num::format_phone() - 'phone' => '(000) 000-0000', - // Num::smart_format_phone() - 'smart_phone' => array( - 7 => '000-0000', - 10 => '(000) 000-0000', - 11 => '0 (000) 000-0000', - ), - // Num::format_exp() - 'exp' => '00-00', - // Num::mask_credit_card() - 'credit_card' => '**** **** **** 0000', - ), - -); - -/* End of file config/num.php */ diff --git a/fuel/core/config/package.php b/fuel/core/config/package.php deleted file mode 100755 index 17df705..0000000 --- a/fuel/core/config/package.php +++ /dev/null @@ -1,33 +0,0 @@ - array( - 'github.com/fuel-packages', - ), - -); diff --git a/fuel/core/config/pagination.php b/fuel/core/config/pagination.php deleted file mode 100755 index b27f2ae..0000000 --- a/fuel/core/config/pagination.php +++ /dev/null @@ -1,144 +0,0 @@ - 'default', - - // default FuelPHP pagination template, compatible with pre-1.4 applications - 'default' => array( - 'wrapper' => "
    \n\t{pagination}\n
    \n", - - 'first' => "\n\t{link}\n\n", - 'first-marker' => "««", - 'first-link' => "\t\t{page}\n", - - 'first-inactive' => "", - 'first-inactive-link' => "", - - 'previous' => "\n\t{link}\n\n", - 'previous-marker' => "«", - 'previous-link' => "\t\t{page}\n", - - 'previous-inactive' => "\n\t{link}\n\n", - 'previous-inactive-link' => "\t\t{page}\n", - - 'regular' => "\n\t{link}\n\n", - 'regular-link' => "\t\t{page}\n", - - 'active' => "\n\t{link}\n\n", - 'active-link' => "\t\t{page}\n", - - 'next' => "\n\t{link}\n\n", - 'next-marker' => "»", - 'next-link' => "\t\t{page}\n", - - 'next-inactive' => "\n\t{link}\n\n", - 'next-inactive-link' => "\t\t{page}\n", - - 'last' => "\n\t{link}\n\n", - 'last-marker' => "»»", - 'last-link' => "\t\t{page}\n", - - 'last-inactive' => "", - 'last-inactive-link' => "", - ), - - // Twitter bootstrap 3.x template - 'bootstrap3' => array( - 'wrapper' => "
      \n\t{pagination}\n\t
    \n", - - 'first' => "\n\t\t
  • {link}
  • ", - 'first-marker' => "««", - 'first-link' => "{page}", - - 'first-inactive' => "", - 'first-inactive-link' => "", - - 'previous' => "\n\t\t
  • {link}
  • ", - 'previous-marker' => "«", - 'previous-link' => "{page}", - - 'previous-inactive' => "\n\t\t
  • {link}
  • ", - 'previous-inactive-link' => "{page}", - - 'regular' => "\n\t\t
  • {link}
  • ", - 'regular-link' => "{page}", - - 'active' => "\n\t\t
  • {link}
  • ", - 'active-link' => "{page} ", - - 'next' => "\n\t\t
  • {link}
  • ", - 'next-marker' => "»", - 'next-link' => "{page}", - - 'next-inactive' => "\n\t\t
  • {link}
  • ", - 'next-inactive-link' => "{page}", - - 'last' => "\n\t\t
  • {link}
  • ", - 'last-marker' => "»»", - 'last-link' => "{page}", - - 'last-inactive' => "", - 'last-inactive-link' => "", - ), - - // Twitter bootstrap 2.x template - 'bootstrap' => array( - 'wrapper' => "
    \n\t
      {pagination}\n\t
    \n
    \n", - - 'first' => "\n\t\t
  • {link}
  • ", - 'first-marker' => "««", - 'first-link' => "{page}", - - 'first-inactive' => "", - 'first-inactive-link' => "", - - 'previous' => "\n\t\t
  • {link}
  • ", - 'previous-marker' => "«", - 'previous-link' => "{page}", - - 'previous-inactive' => "\n\t\t
  • {link}
  • ", - 'previous-inactive-link' => "{page}", - - 'regular' => "\n\t\t
  • {link}
  • ", - 'regular-link' => "{page}", - - 'active' => "\n\t\t
  • {link}
  • ", - 'active-link' => "{page}", - - 'next' => "\n\t\t
  • {link}
  • ", - 'next-marker' => "»", - 'next-link' => "{page}", - - 'next-inactive' => "\n\t\t
  • {link}
  • ", - 'next-inactive-link' => "{page}", - - 'last' => "\n\t\t
  • {link}
  • ", - 'last-marker' => "»»", - 'last-link' => "{page}", - - 'last-inactive' => "", - 'last-inactive-link' => "", - ), - -); diff --git a/fuel/core/config/rest.php b/fuel/core/config/rest.php deleted file mode 100755 index 9a2c526..0000000 --- a/fuel/core/config/rest.php +++ /dev/null @@ -1,76 +0,0 @@ - 'xml', - - /* - | XML Basenode name - | - | Default: xml - | - */ - 'xml_basenode' => 'xml', - - /* - | Name for the password protected REST API displayed on login dialogs - | - | E.g: My Secret REST API - | - */ - 'realm' => 'REST API', - - /* - | Is login required and if so, which type of login? - | - | '' = no login required, - | 'basic' = unsecure login, - | 'digest' = more secure login - | or define a method name in your REST controller that handles authorization - | - */ - 'auth' => '', - - /* - | array of usernames and passwords for login - | - | array('admin' => '1234') - | - */ - 'valid_logins' => array('admin' => '1234'), - - /* - | Ignore HTTP_ACCEPT - | - | A lot of work can go into detecting incoming data, - | disabling this will speed up your requests if you do not use a ACCEPT header. - | - */ - 'ignore_http_accept' => false, - -); diff --git a/fuel/core/config/session.php b/fuel/core/config/session.php deleted file mode 100755 index d97117f..0000000 --- a/fuel/core/config/session.php +++ /dev/null @@ -1,119 +0,0 @@ - true, - - // if no session type is requested, use the default - 'driver' => 'cookie', - - // check for an IP address match after loading the cookie (optional, default = false) - 'match_ip' => false, - - // check for a user agent match after loading the cookie (optional, default = true) - 'match_ua' => true, - - // cookie domain (optional, default = '') - 'cookie_domain' => '', - - // cookie path (optional, default = '/') - 'cookie_path' => '/', - - // cookie http_only flag (optional, default = use the cookie class default) - 'cookie_http_only' => null, - - // whether or not to encrypt the session cookie (optional, default is true) - 'encrypt_cookie' => true, - - // if true, the session expires when the browser is closed (optional, default = false) - 'expire_on_close' => false, - - // session expiration time, <= 0 means 2 years! (optional, default = 2 hours) - 'expiration_time' => 7200, - - // session ID rotation time (optional, default = 300) Set to false to disable rotation - 'rotation_time' => 300, - - // default ID for flash variables (optional, default = 'flash') - 'flash_id' => 'flash', - - // if false, expire flash values only after it's used (optional, default = true) - 'flash_auto_expire' => true, - - // if true, a get_flash() automatically expires the flash data - 'flash_expire_after_get' => true, - - // for requests that don't support cookies (i.e. flash), use this POST variable to pass the cookie to the session driver - 'post_cookie_name' => '', - - // for requests in which you don't want to use cookies, use an HTTP header by this name to pass the cookie to the session driver - 'http_header_name' => 'Session-Id', - - // if false, no cookie will be added to the response send back to the client - 'enable_cookie' => true, - - // if true, session data will be synced with PHP's native $_SESSION, to allow easier integration of third-party components - 'native_emulation' => false, - - /** - * specific driver configurations. to override a global setting, just add it to the driver config with a different value - */ - - // special configuration settings for cookie based sessions - 'cookie' => array( - 'cookie_name' => 'fuelcid', // name of the session cookie for cookie based sessions - ), - - // specific configuration settings for file based sessions - 'file' => array( - 'cookie_name' => 'fuelfid', // name of the session cookie for file based sessions - 'path' => '/tmp', // path where the session files should be stored - 'gc_probability' => 5, // probability % (between 0 and 100) for garbage collection - ), - - // specific configuration settings for memcached based sessions - 'memcached' => array( - 'cookie_name' => 'fuelmid', // name of the session cookie for memcached based sessions - 'servers' => array( // array of servers and portnumbers that run the memcached service - 'default' => array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100), - ), - ), - - // specific configuration settings for database based sessions - 'db' => array( - 'cookie_name' => 'fueldid', // name of the session cookie for database based sessions - 'database' => null, // name of the database name (as configured in config/db.php) - 'table' => 'sessions', // name of the sessions table - 'gc_probability' => 5, // probability % (between 0 and 100) for garbage collection - ), - - // specific configuration settings for redis based sessions - 'redis' => array( - 'cookie_name' => 'fuelrid', // name of the session cookie for redis based sessions - 'database' => 'default', // name of the redis database to use (as configured in config/db.php) - ), -); diff --git a/fuel/core/config/test/agent.php b/fuel/core/config/test/agent.php deleted file mode 100755 index 331c156..0000000 --- a/fuel/core/config/test/agent.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - 'enabled' => true, - 'url' => '', - 'method' => 'local', - 'file' => __DIR__.DS.'..'.DS.'..'.DS.'tests'.DS.'agent'.DS.'browscap.ini', - ), - 'cache' => array( - 'driver' => '', - 'expiry' => 1, - 'identifier' => 'fuel.agent-test', - ), -); diff --git a/fuel/core/config/theme.php b/fuel/core/config/theme.php deleted file mode 100755 index a1c7b4e..0000000 --- a/fuel/core/config/theme.php +++ /dev/null @@ -1,71 +0,0 @@ - 'default', - - /** - * The fallback theme to use. If a view is not found in the active theme, this theme - * is used as a fallback. This can also be set in code using Theme::fallback('foo'); - */ - 'fallback' => 'default', - - /** - * The theme search paths. They are searched in the order given. You can add paths - * on the fly via Theme::add_path($path) or Theme::add_paths(array($path1, $path2)); - */ - 'paths' => array( - APPPATH.'themes', - ), - - /** - * The folder inside the theme to be used to store assets. This is relative to the - * theme's path. - */ - 'assets_folder' => 'assets', - - /** - * The extension for theme view files. - */ - 'view_ext' => '.html', - - /** - * Whether to require a theme info file - */ - 'require_info_file' => false, - - /** - * The theme info file name - */ - 'info_file_name' => 'themeinfo.php', - - /** - * Auto prefixing for modules - * - * If true, the view to be loaded will be prefixed by the name of the current module (if any) - * If a string, it will be prefixed too, allowing you to store all modules in a subfolder - * if false, module prefixing is not used - */ - 'use_modules' => false, -); diff --git a/fuel/core/config/upload.php b/fuel/core/config/upload.php deleted file mode 100755 index e2cdd19..0000000 --- a/fuel/core/config/upload.php +++ /dev/null @@ -1,98 +0,0 @@ - true, - - /** - * file validation settings - */ - - // maximum size of the uploaded file in bytes. 0 = no maximum - 'max_size' => 0, - - // list of file extensions that a user is allowed to upload - 'ext_whitelist' => array(), - - // list of file extensions that a user is NOT allowed to upload - 'ext_blacklist' => array(), - - // list of file types that a user is allowed to upload - // ( type is the part of the mime-type, before the slash ) - 'type_whitelist' => array(), - - // list of file types that a user is NOT allowed to upload - 'type_blacklist' => array(), - - // list of file mime-types that a user is allowed to upload - 'mime_whitelist' => array(), - - // list of file mime-types that a user is NOT allowed to upload - 'mime_blacklist' => array(), - - /** - * file save settings - */ - - // prefix given to every file when saved - 'prefix' => '', - - // suffix given to every file when saved - 'suffix' => '', - - // replace the extension of the uploaded file by this extension - 'extension' => '', - - // default path the uploaded files will be saved to - 'path' => '', - - // create the path if it doesn't exist - 'create_path' => true, - - // permissions to be set on the path after creation - 'path_chmod' => 0777, - - // permissions to be set on the uploaded file after being saved - 'file_chmod' => 0666, - - // if true, add a number suffix to the file if the file already exists - 'auto_rename' => true, - - // if true, overwrite the file if it already exists (only if auto_rename = false) - 'overwrite' => false, - - // if true, generate a random filename for the file being saved - 'randomize' => false, - - // if true, normalize the filename (convert to ASCII, replace spaces by underscores) - 'normalize' => false, - - // valid values are 'upper', 'lower', and false. case will be changed after all other transformations - 'change_case' => false, - - // maximum lengh of the filename, after all name modifications have been made. 0 = no maximum - 'max_length' => 0, -); diff --git a/fuel/core/lang/.gitkeep b/fuel/core/lang/.gitkeep deleted file mode 100755 index e69de29..0000000 diff --git a/fuel/core/lang/en/.gitkeep b/fuel/core/lang/en/.gitkeep deleted file mode 100755 index e69de29..0000000 diff --git a/fuel/core/lang/en/byte_units.php b/fuel/core/lang/en/byte_units.php deleted file mode 100755 index 300968a..0000000 --- a/fuel/core/lang/en/byte_units.php +++ /dev/null @@ -1,44 +0,0 @@ - power of 2 that defines the unit's size - * - * @var array - */ -return array( - 'B' => 0, - 'K' => 10, - 'Ki' => 10, - 'KB' => 10, - 'KiB' => 10, - 'M' => 20, - 'Mi' => 20, - 'MB' => 20, - 'MiB' => 20, - 'G' => 30, - 'Gi' => 30, - 'GB' => 30, - 'GiB' => 30, - 'T' => 40, - 'Ti' => 40, - 'TB' => 40, - 'TiB' => 40, - 'P' => 50, - 'Pi' => 50, - 'PB' => 50, - 'PiB' => 50, - 'E' => 60, - 'Ei' => 60, - 'EB' => 60, - 'EiB' => 60, - 'Z' => 70, - 'Zi' => 70, - 'ZB' => 70, - 'ZiB' => 70, - 'Y' => 80, - 'Yi' => 80, - 'YB' => 80, - 'YiB' => 80, -); - -/* End of file lang/en/byte_units.php */ diff --git a/fuel/core/lang/en/date.php b/fuel/core/lang/en/date.php deleted file mode 100755 index 99da0ec..0000000 --- a/fuel/core/lang/en/date.php +++ /dev/null @@ -1,29 +0,0 @@ - ':time ago', - - 'second' => ':t second', - 'seconds' => ':t seconds', - - 'minute' => ':t minute', - 'minutes' => ':t minutes', - - 'hour' => ':t hour', - 'hours' => ':t hours', - - 'day' => ':t day', - 'days' => ':t days', - - 'week' => ':t week', - 'weeks' => ':t weeks', - - 'month' => ':t month', - 'months' => ':t months', - - 'year' => ':t year', - 'years' => ':t years', - - 'decade' => ':t decade', - 'decades' => ':t decades', -); diff --git a/fuel/core/lang/en/inflector.php b/fuel/core/lang/en/inflector.php deleted file mode 100755 index 01e6178..0000000 --- a/fuel/core/lang/en/inflector.php +++ /dev/null @@ -1,68 +0,0 @@ - array( - 'equipment', - 'information', - 'rice', - 'money', - 'species', - 'series', - 'fish', - 'meta', - ), - - 'singular_rules' => array( - '/(matr)ices$/i' => '\1ix', - '/(vert|ind)ices$/i' => '\1ex', - '/^(ox)en/i' => '\1', - '/(alias)es$/i' => '\1', - '/([octop|vir])i$/i' => '\1us', - '/(cris|ax|test)es$/i' => '\1is', - '/(shoe)s$/i' => '\1', - '/(o)es$/i' => '\1', - '/(bus|campus)es$/i' => '\1', - '/([m|l])ice$/i' => '\1ouse', - '/(x|ch|ss|sh)es$/i' => '\1', - '/(m)ovies$/i' => '\1\2ovie', - '/(s)eries$/i' => '\1\2eries', - '/([^aeiouy]|qu)ies$/i' => '\1y', - '/([lr])ves$/i' => '\1f', - '/(tive)s$/i' => '\1', - '/(hive)s$/i' => '\1', - '/([^f])ves$/i' => '\1fe', - '/(^analy)ses$/i' => '\1sis', - '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', - '/([ti])a$/i' => '\1um', - '/(p)eople$/i' => '\1\2erson', - '/(m)en$/i' => '\1an', - '/(s)tatuses$/i' => '\1\2tatus', - '/(c)hildren$/i' => '\1\2hild', - '/(n)ews$/i' => '\1\2ews', - '/([^us])s$/i' => '\1', - ), - - 'plural_rules' => array( - '/^(ox)$/i' => '\1\2en', // ox - '/([m|l])ouse$/i' => '\1ice', // mouse, louse - '/(matr|vert|ind)ix|ex$/i' => '\1ices', // matrix, vertex, index - '/(x|ch|ss|sh)$/i' => '\1es', // search, switch, fix, box, process, address - '/([^aeiouy]|qu)y$/i' => '\1ies', // query, ability, agency - '/(hive)$/i' => '\1s', // archive, hive - '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', // half, safe, wife - '/sis$/i' => 'ses', // basis, diagnosis - '/([ti])um$/i' => '\1a', // datum, medium - '/(p)erson$/i' => '\1eople', // person, salesperson - '/(m)an$/i' => '\1en', // man, woman, spokesman - '/(c)hild$/i' => '\1hildren', // child - '/(buffal|tomat)o$/i' => '\1\2oes', // buffalo, tomato - '/(bu|campu)s$/i' => '\1\2ses', // bus, campus - '/(alias|status|virus)$/i' => '\1es', // alias - '/(octop)us$/i' => '\1i', // octopus - '/(ax|cris|test)is$/i' => '\1es', // axis, crisis - '/s$/' => 's', // no change (compatibility) - '/$/' => 's', - ), - -); diff --git a/fuel/core/lang/en/pagination.php b/fuel/core/lang/en/pagination.php deleted file mode 100755 index 58d512f..0000000 --- a/fuel/core/lang/en/pagination.php +++ /dev/null @@ -1,6 +0,0 @@ - 'Previous', - 'next' => 'Next', -); diff --git a/fuel/core/lang/en/test.php b/fuel/core/lang/en/test.php deleted file mode 100755 index ec126bc..0000000 --- a/fuel/core/lang/en/test.php +++ /dev/null @@ -1,15 +0,0 @@ - 'Hello there :name!', -); diff --git a/fuel/core/lang/en/upload.php b/fuel/core/lang/en/upload.php deleted file mode 100755 index 9dc320f..0000000 --- a/fuel/core/lang/en/upload.php +++ /dev/null @@ -1,23 +0,0 @@ - 'The file uploaded with success', - 'error_'.\Upload::UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini', - 'error_'.\Upload::UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form', - 'error_'.\Upload::UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded', - 'error_'.\Upload::UPLOAD_ERR_NO_FILE => 'No file was uploaded', - 'error_'.\Upload::UPLOAD_ERR_NO_TMP_DIR => 'Configured temporary upload folder is missing', - 'error_'.\Upload::UPLOAD_ERR_CANT_WRITE => 'Failed to write uploaded file to disk', - 'error_'.\Upload::UPLOAD_ERR_EXTENSION => 'Upload blocked by an installed PHP extension', - 'error_'.\Upload::UPLOAD_ERR_MAX_SIZE => 'The uploaded file exceeds the defined maximum size', - 'error_'.\Upload::UPLOAD_ERR_EXT_BLACKLISTED => 'Upload of files with this extension is not allowed', - 'error_'.\Upload::UPLOAD_ERR_EXT_NOT_WHITELISTED => 'Upload of files with this extension is not allowed', - 'error_'.\Upload::UPLOAD_ERR_TYPE_BLACKLISTED => 'Upload of files of this file type is not allowed', - 'error_'.\Upload::UPLOAD_ERR_TYPE_NOT_WHITELISTED => 'Upload of files of this file type is not allowed', - 'error_'.\Upload::UPLOAD_ERR_MIME_BLACKLISTED => 'Upload of files of this mime type is not allowed', - 'error_'.\Upload::UPLOAD_ERR_MIME_NOT_WHITELISTED => 'Upload of files of this mime type is not allowed', - 'error_'.\Upload::UPLOAD_ERR_MAX_FILENAME_LENGTH => 'The uploaded file name exceeds the defined maximum length', - 'error_'.\Upload::UPLOAD_ERR_MOVE_FAILED => 'Unable to move the uploaded file to it\'s final destination', - 'error_'.\Upload::UPLOAD_ERR_DUPLICATE_FILE => 'A file with the name of the uploaded file already exists', - 'error_'.\Upload::UPLOAD_ERR_MKDIR_FAILED => 'Unable to create the file\'s destination directory', -); diff --git a/fuel/core/lang/en/validation.php b/fuel/core/lang/en/validation.php deleted file mode 100755 index 78ad035..0000000 --- a/fuel/core/lang/en/validation.php +++ /dev/null @@ -1,21 +0,0 @@ - 'The field :label is required and must contain a value.', - 'min_length' => 'The field :label has to contain at least :param:1 characters.', - 'max_length' => 'The field :label may not contain more than :param:1 characters.', - 'exact_length' => 'The field :label must contain exactly :param:1 characters.', - 'match_value' => 'The field :label must contain the value :param:1.', - 'match_pattern' => 'The field :label must match the pattern :param:1.', - 'match_field' => 'The field :label must match the field :param:1.', - 'valid_email' => 'The field :label must contain a valid email address.', - 'valid_emails' => 'The field :label must contain a list of valid email addresses.', - 'valid_url' => 'The field :label must contain a valid URL.', - 'valid_ip' => 'The field :label must contain a valid IP address.', - 'numeric_min' => 'The minimum numeric value of :label must be :param:1', - 'numeric_max' => 'The maximum numeric value of :label must be :param:1', - 'numeric_between' => 'The field :label must contain a numeric value between :param:1 and :param:2', - 'valid_string' => 'The valid string rule :rule(:param:1) failed for field :label', - 'required_with' => 'The field :label must contain a value if :param:1 contains a value.', - 'valid_date' => 'The field :label must contain a valid formatted date.', -); diff --git a/fuel/core/phpunit.xml b/fuel/core/phpunit.xml deleted file mode 100755 index e5a8341..0000000 --- a/fuel/core/phpunit.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - ../core/tests - - - ../packages/*/tests - - - ../app/tests - - - ../app/modules/*/tests - - - diff --git a/fuel/core/tasks/install.php b/fuel/core/tasks/install.php deleted file mode 100755 index cddf771..0000000 --- a/fuel/core/tasks/install.php +++ /dev/null @@ -1,44 +0,0 @@ - $package) - { - $packages[] = is_numeric($name) ? $package : $name; - } - $packages = implode(',', array_unique($packages)); - } - - // if modules option set - if ( ! empty($modules)) - { - // if true - get all modules - if ($modules === true) - { - // loop through module paths - foreach (\Config::get('module_paths') as $path) - { - // get all modules that have files in the migration folder - foreach(new \GlobIterator(realpath($path).DS.'*') as $m) - { - if (count(new \GlobIterator($m->getPathname().rtrim(DS.\Config::get('migrations.folder'), '\\/').DS.'*.php'))) - { - static::$modules[] = $m->getBasename(); - } - } - } - } - // else do selected modules - else - { - static::$modules = explode(',', $modules); - } - } - - // if packages option set - if ( ! empty($packages)) - { - // if true - get all packages - if ($packages === true) - { - // get all packages that have files in the migration folder - foreach (\Config::get('package_paths', array(PKGPATH)) as $path) - { - // get all modules that have files in the migration folder - foreach(new \GlobIterator(realpath($path).DS.'*') as $p) - { - if (count(new \GlobIterator($p->getPathname().rtrim(DS.\Config::get('migrations.folder'), '\\/').DS.'*.php'))) - { - static::$packages[] = $p->getBasename(); - } - } - } - } - // else do selected packages - else - { - static::$packages = explode(',', $packages); - } - } - - // if packages or modules are specified, and the app isn't, disable app migrations - if ( ( ! empty($packages) or ! empty($modules)) and empty($default)) - { - static::$default = false; - } - - // set the module and package count - static::$module_count = count(static::$modules); - static::$package_count = count(static::$packages); - } - - /** - * catches requested method call and runs as needed - * - * @param string name of the method to run - * @param string any additional method arguments (not used here!) - */ - public function __call($name, $args) - { - // set method name - $name = '_'.$name; - - // make sure the called name exists - if ( ! method_exists(get_called_class(), $name)) - { - return static::help(); - } - - do - { - // reset the rerun flag - static::$rerun = false; - - // store and reset the current execution state - $state = static::$executed; - static::$executed = array(); - - // run app (default) migrations if default is true - if (static::$default) - { - static::$name('default', 'app'); - } - - // run migrations on all specified modules - foreach (static::$modules as $module) - { - // check if the module exists - if ( ! \Module::exists($module)) - { - \Cli::write('Requested module "'.$module.'" does not exist!', 'light_red'); - } - else - { - // run the migration - static::$name($module, 'module'); - } - } - - // run migrations on all specified packages - foreach (static::$packages as $package) - { - // check if the module exists - if ( ! \Package::exists($package)) - { - \Cli::write('Requested package "'.$package.'" does not exist!', 'light_red'); - } - else - { - static::$name($package, 'package'); - } - } - - // do we need to re-run? - if (static::$rerun) - { - // check for any progress on this run - if ($state == static::$executed) - { - // there wasn't any, bail out - static::$rerun = false; - \Cli::write('Migration loop detected! Check if there is a dependency that can\'t be fulfilled by the current selection!', 'light_red'); - } - } - } - while (static::$rerun); - } - - /** - * migrates to the latest version unless -version is specified - * - * @param string name of the type (in case of app, it's 'default') - * @param string type (app, module or package) - * @param string direction of migration (up or down) - */ - protected static function _run($name, $type) - { - // -v or --version - $version = \Cli::option('v', \Cli::option('version', '')); - - // version is used as a flag, so show it - if ($version === true) - { - \Cli::write('Currently installed migrations for '.$type.':'.$name.':', 'green'); - - foreach (\Config::get('migrations.version.'.$type.'.'.$name, array()) as $version) - { - \Cli::write('- '.$version); - } - return; - } - - // version contains a timestamp of sorts - elseif ($version !== '') - { - // if version has a value, make sure only 1 item was passed - if (static::$default + static::$module_count + static::$package_count > 1) - { - \Cli::write('Migration: version only accepts 1 item.'); - return; - } - $migrations = \Migrate::version($version, $name, $type, \Cli::option('catchup', false)); - } - - // migrate to the latest version - else - { - $migrations = \Migrate::latest($name, $type, \Cli::option('catchup', false)); - } - - // were there any migrations at all? - if (empty($migrations)) - { - if ($version !== '') - { - \Cli::write('No migrations were found for '.$type.':'.$name.'.'); - } - else - { - \Cli::write('Already on the latest migration for '.$type.':'.$name.'.'); - } - } - - // did we run all migrations? - elseif ($last = end($migrations)) - { - \Cli::write('Performed migrations for '.$type.':'.$name.':', 'green'); - - foreach ($migrations as $migration) - { - \Cli::write($migration); - } - } - else - { - \Cli::write('Some migrations for '.$type.':'.$name.' are postponed due to dependencies.', 'cyan'); - - // store the ones we've executed - static::$executed[$type.'-'.$name] = $migrations; - - // set the rerun flag - static::$rerun = true; - } - } - - /** - * migrates item to current config version - * - * @param string name of the type (in case of app, it's 'default') - * @param string type (app, module or package) - */ - protected static function _current($name, $type) - { - // -v or --version - if (\Cli::option('v', \Cli::option('version', '')) !== '') - { - \Cli::write('You can not define a version when using the "current" command.', 'red'); - } - - $migrations = \Migrate::current($name, $type); - - if ($migrations) - { - \Cli::write('Newly installed migrations for '.$type.':'.$name.':', 'green'); - foreach ($migrations as $migration) - { - \Cli::write('- '.$migration); - } - } - else - { - // migration is already on current version - \Cli::write('Already on the current migration version for '.$type.':'.$name.'.'); - } - } - - /** - * migrates item up to the given version - * - * @param string - * @param string - */ - protected static function _up($name, $type) - { - // -v or --version - $version = \Cli::option('v', \Cli::option('version', null)); - - // if version has a value, make sure only 1 item was passed - if ($version and (static::$default + static::$module_count + static::$package_count > 1)) - { - \Cli::write('Migration: version only accepts 1 item.'); - return; - } - - $migrations = \Migrate::up($version, $name, $type); - - if ($migrations) - { - \Cli::write('Newly installed migrations for '.$type.':'.$name.':', 'green'); - foreach ($migrations as $migration) - { - \Cli::write('- '.$migration); - } - } - else - { - // there is no 'up'... - \Cli::write('You are already on the latest migration version for '.$type.':'.$name.'.'); - } - } - - /** - * migrates item down to the given version - * - * @param string - * @param string - */ - protected static function _down($name, $type) - { - // -v or --version - $version = \Cli::option('v', \Cli::option('version', null)); - - // if version has a value, make sure only 1 item was passed - if ($version and (static::$default + static::$module_count + static::$package_count > 1)) - { - \Cli::write('Migration: version only accepts 1 item.'); - return; - } - - $migrations = \Migrate::down($version, $name, $type); - - if ($migrations) - { - \Cli::write('Reverted migrations for '.$type.':'.$name.':', 'green'); - foreach ($migrations as $migration) - { - \Cli::write('- '.$migration); - } - } - else - { - // there is no 'down'... - \Cli::write('There are no migrations installed to revert for '.$type.':'.$name.'.'); - } - } - - /** - * Shows basic help instructions for using migrate in oil - */ - public static function help() - { - echo << --packages= --default, it will use - your applications' "always_load" configuration to determine what to migrate - --all # shortcut for --modules --packages --default - - # The following disable default migrations unless you add --default to the command - --default # re-enables default migration - --modules -m # Migrates all modules - --modules=item1,item2 -m=item1,item2 # Migrates specific modules - --packages -p # Migrates all packages - --packages=item1,item2 -p=item1,item2 # Migrates specific modules - -Description: - The migrate task can run migrations. You can go up, down or by default go to the current migration marked in the config file. - -Examples: - php oil r migrate - php oil r migrate:current - php oil r migrate:up -v=6 - php oil r migrate:down - php oil r migrate --version=201203171206 - php oil r migrate --modules --packages --default - php oil r migrate:up --modules=module1,module2 --packages=package1 - php oil r migrate --modules=module1 -v=3 - php oil r migrate --all - php oil r migrate --installed - php oil r migrate --installed --modules=extramodule --packages=extrapackage - php oil r migrate --all -v - -HELP; - - } - -} diff --git a/fuel/core/tasks/session.php b/fuel/core/tasks/session.php deleted file mode 100755 index 965e19c..0000000 --- a/fuel/core/tasks/session.php +++ /dev/null @@ -1,180 +0,0 @@ - array('constraint' => 40, 'type' => 'varchar'), - 'previous_id' => array('constraint' => 40, 'type' => 'varchar'), - 'user_agent' => array('type' => 'text', 'null' => false), - 'ip_hash' => array('constraint' => 32, 'type' => 'char'), - 'created' => array('constraint' => 10, 'type' => 'int', 'unsigned' => true), - 'updated' => array('constraint' => 10, 'type' => 'int', 'unsigned' => true), - 'payload' => array('type' => 'longtext'), - ), array('session_id'), false, 'InnoDB', \Config::get('db.default.charset')); - - // make previous_id a unique_key. speeds up query and prevents duplicate id's - \DBUtil::create_index(\Config::get('session.db.table'), 'previous_id', 'previous_id', 'unique'); - - if (\Config::get('session.driver') === 'db') - { - // return success message. - return \Cli::color('Success! Your session table has been created!', 'green'); - } - else - { - // return success message notifying that the driver is not db. - return \Cli::color('Success! Your session table has been created! Your current session driver type is set to '.\Config::get('session.driver').'. In order to use the table you just created to manage your sessions, you will need to set your driver type to "db" in your session config file.', 'green'); - } - } - - /** - * remove the sessions table - * php oil r session:remove - */ - public static function remove() - { - // load session config - \Config::load('session', true); - - // prompt the user to confirm they want to remove the table. - $iamsure = \Cli::prompt('Are you sure you want to delete the sessions table?', array('y', 'n')); - - // if they are sure, then let's drop it - if ($iamsure === 'y') - { - \DBUtil::drop_table(\Config::get('session.db.table')); - return \Cli::color('Session database table deleted.', 'green'); - } - - // if we made it to here, than that means the user said no. - return \Cli::color('Session database table was not deleted.', 'red'); - } - - /** - * clear the sessions table - * php oil r session:clear - */ - public static function clear() - { - // load session config - \Config::load('session', true); - - // prompt the user to confirm they want to clear the table. - $iamsure = \Cli::prompt('Are you sure you want to clear the sessions table?', array('y', 'n')); - - // if they are sure, then let's drop it - if ($iamsure === 'y') - { - \DBUtil::truncate_table(\Config::get('session.db.table')); - return \Cli::color('Session database table successfully truncated.', 'green'); - } - - // if we made it to here, than that means the user said no. - return \Cli::color('Session database table was not cleared.', 'red'); - } - - /** - * Shows basic help instructions for using migrate in oil - */ - public static function help() - { - echo <<assertEquals($expected, $output); - } - - /** - * Tests Agent::platform() - * - * @test - */ - public function test_platform() - { - $expected = "Linux"; - $output = Agent::platform(); - $this->assertEquals($expected, $output); - } - - /** - * Tests Agent::version() - * - * @test - */ - public function test_version() - { - $expected = 3.6; - $output = Agent::version(); - $this->assertInternalType('float', $output); - $this->assertEquals($expected, $output); - } - - public function property_provider() - { - return array( - array( - 'Browser','Firefox', - ), - array( - 'Version',3.6, - ), - array( - 'MajorVer',3, - ), - array( - 'MinorVer',6, - ), - array( - 'Platform','Linux', - ), - array( - 'Alpha',false, - ), - array( - 'Beta',false, - ), - array( - 'Win16',false, - ), - array( - 'Win32',false, - ), - array( - 'Win64',false, - ), - array( - 'Frames',true, - ), - array( - 'IFrames',true, - ), - array( - 'Tables',true, - ), - array( - 'Cookies',true, - ), - array( - 'BackgroundSounds',false, - ), - array( - 'JavaScript',true, - ), - array( - 'VBScript',false, - ), - array( - 'JavaApplets',true, - ), - array( - 'ActiveXControls',false, - ), - array( - 'isBanned',false, - ), - array( - 'isMobile',false, - ), - array( - 'isSyndicationReader',false, - ), - array( - 'Crawler',false, - ), - array( - 'CssVersion',3, - ), - array( - 'AolVersion',0, - ), - ); - } - - /** - * Tests Agent::property() - * - * @test - * @dataProvider property_provider - */ - public function test_property($property, $expected) - { - $output = Agent::property($property); - $this->assertEquals($expected, $output); - } - - /** - * Tests Agent::is_robot() - * - * @test - */ - public function test_is_robot() - { - $output = Agent::is_robot(); - $this->assertFalse($output); - } - - /** - * Tests Agent::is_mobiledevice() - * - * @test - */ - public function test_is_mobiledevice() - { - $output = Agent::is_mobiledevice(); - $this->assertFalse($output); - } - - /** - * Tests Agent::languages() - * - * @test - */ - public function test_languages() - { - $expected = array("en-us", "en", "nl-be", "nl"); - $output = Agent::languages(); - $this->assertEquals($expected, $output); - } - - /** - * Tests Agent::accepts_language() - * - * @test - */ - public function test_accepts_language_success() - { - $output = Agent::accepts_language('en-us'); - $this->assertTrue($output); - } - - public function test_accepts_language_fail() - { - $output = Agent::accepts_language('pt-br'); - $this->assertFalse($output); - } - - /** - * Tests Agent::charsets() - * - * @test - */ - public function test_charsets() - { - $expected = array("utf-8", "iso-8859-1", "*"); - $output = Agent::charsets(); - $this->assertEquals($expected, $output); - } - - /** - * Tests Agent::accepts_charset() - * - * @test - */ - public function test_accepts_charset_success() - { - $output = Agent::accepts_charset('utf-8'); - $this->assertTrue($output); - } - - public function test_accepts_charset_fail() - { - $output = Agent::accepts_charset('cp2'); - $this->assertFalse($output); - } -} diff --git a/fuel/core/tests/agent/browscap.ini b/fuel/core/tests/agent/browscap.ini deleted file mode 100755 index fae8ff2..0000000 --- a/fuel/core/tests/agent/browscap.ini +++ /dev/null @@ -1,563 +0,0 @@ -;;; Provided courtesy of http://browscap.org/ -;;; Created on Thursday, May 8, 2014 at 07:17 AM UTC -;;; Keep up with the latest goings-on with the project: -;;; Follow us on Twitter , or... -;;; Like us on Facebook , or... -;;; Collaborate on GitHub , or... -;;; Discuss on Google Groups . - -;;; Stripped version, for FuelPHP unit tests only ! - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Browscap Version - -[GJK_Browscap_Version] -Version=0000 -Released=Thu, 08 May 2014 07:17:44 +0000 -Format=php -Type=lite - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DefaultProperties - -[DefaultProperties] -Comment="DefaultProperties" -Browser="DefaultProperties" -Version=0.0 -MajorVer=0 -MinorVer=0 -Platform="unknown" -Platform_Version=unknown -Alpha=false -Beta=false -Win16=false -Win32=false -Win64=false -Frames=false -IFrames=false -Tables=false -Cookies=false -BackgroundSounds=false -JavaScript=false -VBScript=false -JavaApplets=false -ActiveXControls=false -isMobileDevice=false -isTablet=false -isSyndicationReader=false -Crawler=false -CssVersion=0 -AolVersion=0 - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Firefox 3.6 - -[Firefox 3.6] -Parent="DefaultProperties" -Comment="Firefox 3.6" -Browser="Firefox" -Version=3.6 -MajorVer=3 -MinorVer=6 -Win32=true -Frames=true -IFrames=true -Tables=true -Cookies=true -JavaScript=true -JavaApplets=true -CssVersion=3 - -[Mozilla/5.0 (*FreeBSD*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="FreeBSD" -Win32=false - -[Mozilla/5.0 (*HP-UX*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="HP-UX" -Win32=false - -[Mozilla/5.0 (*IRIX64*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="IRIX64" -Win32=false - -[Mozilla/5.0 (*Linux*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Linux" -Win32=false - -[Mozilla/5.0 (*Linux x86_64*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Linux" -Win32=false - -[Mozilla/5.0 (*Mac OS X*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_4*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.4 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.4*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.4 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_5*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.5 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.5*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.5 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_6*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.6 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.6*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.6 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_7*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.7 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.7*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.7 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_8*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.8 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.8*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.8 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_9*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.9 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.9*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.9 -Win32=false - -[Mozilla/5.0 (*OpenBSD*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="OpenBSD" -Win32=false - -[Mozilla/5.0 (*SunOS*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="SunOS" -Win32=false - -[Mozilla/5.0 (*Win98*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win98" -Platform_Version=98 - -[Mozilla/5.0 (*WinNT4.0*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinNT" -Platform_Version=4.0 - -[Mozilla/5.0 (*Windows NT 5.0*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win2000" -Platform_Version=5.0 - -[Mozilla/5.0 (*Windows NT 5.1*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinXP" -Platform_Version=5.1 - -[Mozilla/5.0 (*Windows NT 5.1 x64*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinXP" -Platform_Version=5.1 -Win32=false -Win64=true - -[Mozilla/5.0 (*Windows NT 5.2*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinXP" -Platform_Version=5.2 - -[Mozilla/5.0 (*Windows NT 5.2 x64*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinXP" -Platform_Version=5.2 -Win32=false -Win64=true - -[Mozilla/5.0 (*Windows NT 6.0*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinVista" -Platform_Version=6.0 - -[Mozilla/5.0 (*Windows NT 6.0 x64*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinVista" -Platform_Version=6.0 -Win32=false -Win64=true - -[Mozilla/5.0 (*Windows NT 6.1*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win7" -Platform_Version=6.1 - -[Mozilla/5.0 (*Windows NT 6.1*WOW64*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win7" -Platform_Version=6.1 -Win32=false -Win64=true - -[Mozilla/5.0 (*Windows NT 6.1 x64*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win7" -Platform_Version=6.1 -Win32=false -Win64=true - -[Mozilla/5.0 (*Windows NT 6.2*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win8" -Platform_Version=6.2 - -[Mozilla/5.0 (*Windows NT 6.2*WOW64*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win8" -Platform_Version=6.2 -Win32=false -Win64=true - -[Mozilla/5.0 (*Windows NT 6.3*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win8.1" -Platform_Version=6.3 - -[Mozilla/5.0 (*Windows NT 6.3*WOW64*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win8.1" -Platform_Version=6.3 -Win32=false -Win64=true - -[Mozilla/5.0 (*OS/2*) Gecko/* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="OS/2" -Win32=false - -[Mozilla/5.0 (*FreeBSD*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="FreeBSD" -Win32=false - -[Mozilla/5.0 (*HP-UX*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="HP-UX" -Win32=false - -[Mozilla/5.0 (*IRIX64*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="IRIX64" -Win32=false - -[Mozilla/5.0 (*Linux*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Linux" -Win32=false - -[Mozilla/5.0 (*Linux x86_64*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Linux" -Win32=false - -[Mozilla/5.0 (*Mac OS X*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_4*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.4 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.4*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.4 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_5*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.5 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.5*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.5 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_6*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.6 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.6*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.6 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_7*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.7 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.7*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.7 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_8*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.8 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.8*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.8 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10_9*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.9 -Win32=false - -[Mozilla/5.0 (*Mac OS X 10.9*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="MacOSX" -Platform_Version=10.9 -Win32=false - -[Mozilla/5.0 (*OpenBSD*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="OpenBSD" -Win32=false - -[Mozilla/5.0 (*SunOS*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="SunOS" -Win32=false - -[Mozilla/5.0 (*WinNT4.0*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinNT" -Platform_Version=4.0 - -[Mozilla/5.0 (*Windows NT 5.0*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win2000" -Platform_Version=5.0 - -[Mozilla/5.0 (*Windows NT 5.1*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinXP" -Platform_Version=5.1 - -[Mozilla/5.0 (*Windows NT 5.1 x64*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinXP" -Platform_Version=5.1 -Win32=false -Win64=true - -[Mozilla/5.0 (*Windows NT 5.2*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinXP" -Platform_Version=5.2 - -[Mozilla/5.0 (*Windows NT 5.2 x64*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinXP" -Platform_Version=5.2 -Win32=false -Win64=true - -[Mozilla/5.0 (*Windows NT 6.0*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinVista" -Platform_Version=6.0 - -[Mozilla/5.0 (*Windows NT 6.0 x64*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="WinVista" -Platform_Version=6.0 -Win32=false -Win64=true - -[Mozilla/5.0 (*Windows NT 6.1*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win7" -Platform_Version=6.1 - -[Mozilla/5.0 (*Windows NT 6.1 x64*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win7" -Platform_Version=6.1 -Win32=false -Win64=true - -[Mozilla/5.0 (*Windows NT 6.2*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win8" -Platform_Version=6.2 - -[Mozilla/5.0 (*Windows NT 6.2*WOW64*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win8" -Platform_Version=6.2 -Win32=false -Win64=true - -[Mozilla/5.0 (*Windows NT 6.3*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win8.1" -Platform_Version=6.3 - -[Mozilla/5.0 (*Windows NT 6.3*WOW64*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="Win8.1" -Platform_Version=6.3 -Win32=false -Win64=true - -[Mozilla/5.0 (*OS/2*) Gecko* Firefox/3.6*] -Parent="Firefox 3.6" -Platform="OS/2" -Win32=false - -[Mozilla/5.0 (*Darwin*) Gecko/* Namoroka/3.6*] -Parent="Firefox 3.6" -Platform="Darwin" -Win32=false - -[Mozilla/5.0 (*Linux*) Gecko/* Namoroka/3.6*] -Parent="Firefox 3.6" -Platform="Linux" -Win32=false - -[Mozilla/5.0 (*Windows NT 6.1*; rv:1.9.2*) Gecko/* Firefox anonymized *] -Parent="Firefox 3.6" -Platform="Win7" -Platform_Version=6.1 - -[Mozilla/5.0 (*Windows NT 6.2*; rv:1.9.2*) Gecko/* Firefox anonymized *] -Parent="Firefox 3.6" -Platform="Win8" -Platform_Version=6.2 - -[Mozilla/5.0 (*Windows NT 5.1*; rv:1.9.2*) Gecko/* Firefox *] -Parent="Firefox 3.6" -Platform="WinXP" -Platform_Version=5.1 - -[Mozilla/5.0 (*Windows NT 6.0*; rv:1.9.2*) Gecko/* Firefox *] -Parent="Firefox 3.6" -Platform="WinVista" -Platform_Version=6.0 - -[Mozilla/5.0 (*Windows NT 6.1*; rv:1.9.2*) Gecko/* Firefox *] -Parent="Firefox 3.6" -Platform="Win7" -Platform_Version=6.1 - -[Mozilla/5.0 (*Windows NT 6.2*; rv:1.9.2*) Gecko/* Firefox *] -Parent="Firefox 3.6" -Platform="Win8" -Platform_Version=6.2 - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Others - -[Others] -Parent="DefaultProperties" -Browser="Bot" -Frames=true -IFrames=true -Tables=true -Crawler=true - -[Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)] -Parent="Others" - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Default Browser - -[*] -Comment="Default Browser" -Browser="Default Browser" -Version=0.0 -MajorVer=0 -MinorVer=0 -Platform="unknown" -Platform_Version=unknown -Alpha=false -Beta=false -Win16=false -Win32=false -Win64=false -Frames=false -IFrames=false -Tables=false -Cookies=false -BackgroundSounds=false -JavaScript=false -VBScript=false -JavaApplets=false -ActiveXControls=false -isMobileDevice=false -isTablet=false -isSyndicationReader=false -Crawler=false -CssVersion=0 -AolVersion=0 - diff --git a/fuel/core/tests/arr.php b/fuel/core/tests/arr.php deleted file mode 100755 index 3d4b6a8..0000000 --- a/fuel/core/tests/arr.php +++ /dev/null @@ -1,1133 +0,0 @@ - "Jack", - "age" => "21", - "weight" => 200, - "location" => array( - "city" => "Pittsburgh", - "state" => "PA", - "country" => "US", - ), - ), - ), - ); - } - - public static function collection_provider() - { - $object = new \stdClass; - $object->id = 7; - $object->name = 'Bert'; - $object->surname = 'Visser'; - - return array( - array( - array( - array( - 'id' => 2, - 'name' => 'Bill', - 'surname' => 'Cosby', - ), - array( - 'id' => 5, - 'name' => 'Chris', - 'surname' => 'Rock', - ), - $object, - ), - ), - ); - } - - /** - * Test Arr::pluck() - * - * @test - * @dataProvider collection_provider - */ - public function test_pluck($collection) - { - $output = \Arr::pluck($collection, 'id'); - $expected = array(2, 5, 7); - $this->assertEquals($expected, $output); - } - - /** - * Test Arr::pluck() - * - * @test - * @dataProvider collection_provider - */ - public function test_pluck_with_index($collection) - { - $output = \Arr::pluck($collection, 'name', 'id'); - $expected = array(2 => 'Bill', 5 => 'Chris', 7 => 'Bert'); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::assoc_to_keyval() - * - * @test - */ - public function test_assoc_to_keyval() - { - $assoc = array( - array( - 'color' => 'red', - 'rank' => 4, - 'name' => 'Apple', - ), - array( - 'color' => 'yellow', - 'rank' => 3, - 'name' => 'Banana', - ), - array( - 'color' => 'purple', - 'rank' => 2, - 'name' => 'Grape', - ), - ); - - $expected = array( - 'red' => 'Apple', - 'yellow' => 'Banana', - 'purple' => 'Grape', - ); - $output = Arr::assoc_to_keyval($assoc, 'color', 'name'); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::keyval_to_assoc() - * - * @test - */ - public function test_keyval_to_assoc() - { - $keyval = array( - 'red' => 'Apple', - 'yellow' => 'Banana', - 'purple' => 'Grape', - ); - - $expected = array( - array( - 'color' => 'red', - 'name' => 'Apple', - ), - array( - 'color' => 'yellow', - 'name' => 'Banana', - ), - array( - 'color' => 'purple', - 'name' => 'Grape', - ), - ); - - $output = Arr::keyval_to_assoc($keyval, 'color', 'name'); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::key_exists() - * - * @test - * @dataProvider person_provider - */ - public function test_key_exists_with_key_found($person) - { - $expected = true; - $output = Arr::key_exists($person, "name"); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::key_exists() - * - * @test - * @dataProvider person_provider - */ - public function test_key_exists_with_key_not_found($person) - { - $expected = false; - $output = Arr::key_exists($person, "unknown"); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::key_exists() - * - * @test - * @dataProvider person_provider - */ - public function test_key_exists_with_dot_separated_key($person) - { - $expected = true; - $output = Arr::key_exists($person, "location.city"); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::get() - * - * @test - * @dataProvider person_provider - */ - public function test_get_with_element_found($person) - { - $expected = "Jack"; - $output = Arr::get($person, "name", "Unknown Name"); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::get() - * - * @test - * @dataProvider person_provider - */ - public function test_get_with_element_not_found($person) - { - $expected = "Unknown job"; - $output = Arr::get($person, "job", "Unknown job"); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::get() - * - * @test - * @dataProvider person_provider - */ - public function test_get_with_dot_separated_key($person) - { - $expected = "Pittsburgh"; - $output = Arr::get($person, "location.city", "Unknown City"); - $this->assertEquals($expected, $output); - - } - - /** - * Tests Arr::get() - * - * @test - * @expectedException InvalidArgumentException - */ - public function test_get_throws_exception_when_array_is_not_an_array() - { - $output = Arr::get('Jack', 'name', 'Unknown Name'); - } - - /** - * Tests Arr::get() - * - * @test - * @dataProvider person_provider - */ - public function test_get_when_dot_notated_key_is_not_array($person) - { - $expected = "Unknown Name"; - $output = Arr::get($person, 'foo.first', 'Unknown Name'); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::get() - * - * @test - * @dataProvider person_provider - */ - public function test_get_with_all_elements_found($person) - { - $expected = array( - 'name' => 'Jack', - 'weight' => 200, - ); - $output = Arr::get($person, array('name', 'weight'), 'Unknown'); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::get() - * - * @test - * @dataProvider person_provider - */ - public function test_get_with_all_elements_not_found($person) - { - $expected = array( - 'name' => 'Jack', - 'height' => 'Unknown', - ); - $output = Arr::get($person, array('name', 'height'), 'Unknown'); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::get() - * - * @test - * @dataProvider person_provider - */ - public function test_get_when_keys_is_not_an_array($person) - { - $expected = 'Jack'; - $output = Arr::get($person, 'name', 'Unknown'); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::flatten() - * - * @test - */ - public function test_flatten() - { - $indexed = array( array('a'), array('b'), array('c') ); - - $expected = array( - "0_0" => "a", - "1_0" => "b", - "2_0" => "c", - ); - - $output = Arr::flatten($indexed, '_'); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::flatten_assoc() - * - * @test - */ - public function test_flatten_assoc() - { - $people = array( - array( - "name" => "Jack", - "age" => 21, - ), - array( - "name" => "Jill", - "age" => 23, - ), - ); - - $expected = array( - "0:name" => "Jack", - "0:age" => 21, - "1:name" => "Jill", - "1:age" => 23, - ); - - $output = Arr::flatten_assoc($people); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::flatten_assoc() with recursive arrays - * - * @test - */ - public function test_flatten_recursive_index() - { - $people = array( - array( - "name" => "Jack", - "age" => 21, - "children" => array( - array( - "name" => "Johnny", - "age" => 4, - ), - array( - "name" => "Jimmy", - "age" => 3, - ) - ) - ), - array( - "name" => "Jill", - "age" => 23 - ) - ); - - $expected = array( - "0:name" => "Jack", - "0:age" => 21, - "0:children:0:name" => "Johnny", - "0:children:0:age" => 4, - "0:children:1:name" => "Jimmy", - "0:children:1:age" => 3, - "1:name" => "Jill", - "1:age" => 23 - ); - - $output = Arr::flatten($people, ':'); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::merge_assoc() - * - * @test - */ - public function test_merge_assoc() - { - $arr1 = array( - 'one' => 1, - 2 => 2, - 3 => 3, - 4 => array( - 56, - ), - 5=> 87, - ); - - $arr2 = array( - 1 => 27, - 2 => 90, - 4 => array( - 'give_me' => 'bandwidth', - ), - 6 => '90', - 7 => 'php', - ); - - $expected = array( - 'one' => 1, - 2 => 90, - 3 => 3, - 4 => array( - 56, - 'give_me' => 'bandwidth', - ), - 5=> 87, - 1 => 27, - 6 => '90', - 7 => 'php', - ); - - $output = Arr::merge_assoc($arr1, $arr2); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::insert() - * - * @test - */ - public function test_insert() - { - $people = array("Jack", "Jill"); - - $expected = array("Humpty", "Jack", "Jill"); - $output = Arr::insert($people, "Humpty", 0); - - $this->assertEquals(true, $output); - $this->assertEquals($expected, $people); - } - - /** - * Tests Arr::insert() - * - * @test - */ - public function test_insert_with_index_out_of_range() - { - $people = array("Jack", "Jill"); - - $output = Arr::insert($people, "Humpty", 4); - - $this->assertFalse($output); - } - - /** - * Tests Arr::insert_after_key() - * - * @test - */ - public function test_insert_after_key_that_exists() - { - $people = array("Jack", "Jill"); - - $expected = array("Jack", "Jill", "Humpty"); - $output = Arr::insert_after_key($people, "Humpty", 1); - - $this->assertTrue($output); - $this->assertEquals($expected, $people); - } - - /** - * Tests Arr::insert_after_key() - * - * @test - */ - public function test_insert_after_key_that_does_not_exist() - { - $people = array("Jack", "Jill"); - $output = Arr::insert_after_key($people, "Humpty", 6); - $this->assertFalse($output); - } - - /** - * Tests Arr::insert_after_value() - * - * @test - */ - public function test_insert_after_value_that_exists() - { - $people = array("Jack", "Jill"); - $expected = array("Jack", "Humpty", "Jill"); - $output = Arr::insert_after_value($people, "Humpty", "Jack"); - $this->assertTrue($output); - $this->assertEquals($expected, $people); - } - - /** - * Tests Arr::insert_after_value() - * - * @test - */ - public function test_insert_after_value_that_does_not_exists() - { - $people = array("Jack", "Jill"); - $output = Arr::insert_after_value($people, "Humpty", "Joe"); - $this->assertFalse($output); - } - - /** - * Tests Arr::average() - * - * @test - */ - public function test_average() - { - $arr = array(13, 8, 6); - $this->assertEquals(9, Arr::average($arr)); - } - - /** - * Tests Arr::average() - * - * @test - */ - public function test_average_of_empty_array() - { - $arr = array(); - $this->assertEquals(0, Arr::average($arr)); - } - - /** - * Tests Arr::filter_prefixed() - * - * @test - */ - public function test_filter_prefixed() - { - $arr = array('foo' => 'baz', 'prefix_bar' => 'yay'); - - $output = Arr::filter_prefixed($arr, 'prefix_'); - $this->assertEquals(array('bar' => 'yay'), $output); - } - - /** - * Tests Arr::sort() - * - * @test - * @expectedException InvalidArgumentException - */ - public function test_sort_of_non_array() - { - $sorted = Arr::sort('not an array', 'foo.key'); - } - - public function sort_provider() - { - return array( - array( - // Unsorted Array - array( - array( - 'info' => array( - 'pet' => array( - 'type' => 'dog', - ), - ), - ), - array( - 'info' => array( - 'pet' => array( - 'type' => 'fish', - ), - ), - ), - array( - 'info' => array( - 'pet' => array( - 'type' => 'cat', - ), - ), - ), - ), - - // Sorted Array - array( - array( - 'info' => array( - 'pet' => array( - 'type' => 'cat', - ), - ), - ), - array( - 'info' => array( - 'pet' => array( - 'type' => 'dog', - ), - ), - ), - array( - 'info' => array( - 'pet' => array( - 'type' => 'fish', - ), - ), - ), - ), - ), - ); - } - - /** - * Tests Arr::sort() - * - * @test - * @dataProvider sort_provider - */ - public function test_sort_asc($data, $expected) - { - $this->assertEquals($expected, Arr::sort($data, 'info.pet.type', 'asc')); - } - - /** - * Tests Arr::sort() - * - * @test - * @dataProvider sort_provider - */ - public function test_sort_desc($data, $expected) - { - $expected = array_reverse($expected); - $this->assertEquals($expected, Arr::sort($data, 'info.pet.type', 'desc')); - } - - /** - * Tests Arr::sort() - * - * @test - * @dataProvider sort_provider - * @expectedException InvalidArgumentException - */ - public function test_sort_invalid_direction($data, $expected) - { - $this->assertEquals($expected, Arr::sort($data, 'info.pet.type', 'downer')); - } - - public function test_sort_empty() - { - $expected = array(); - $output = Arr::sort(array(), 'test', 'test'); - $this->assertEquals($expected, $output); - } - - /** - * Tests Arr::filter_keys() - * - * @test - */ - public function test_filter_keys() - { - $data = array( - 'epic' => 'win', - 'weak' => 'sauce', - 'foo' => 'bar', - ); - $expected = array( - 'epic' => 'win', - 'foo' => 'bar', - ); - $expected_remove = array( - 'weak' => 'sauce', - ); - $keys = array('epic', 'foo'); - $this->assertEquals($expected, Arr::filter_keys($data, $keys)); - $this->assertEquals($expected_remove, Arr::filter_keys($data, $keys, true)); - } - - /** - * Tests Arr::to_assoc() - * - * @test - */ - public function test_to_assoc_with_even_number_of_elements() - { - $arr = array('foo', 'bar', 'baz', 'yay'); - $expected = array('foo' => 'bar', 'baz' => 'yay'); - $this->assertEquals($expected, Arr::to_assoc($arr)); - } - - /** - * Tests Arr::to_assoc() - * - * @test - * @expectedException BadMethodCallException - */ - public function test_to_assoc_with_odd_number_of_elements() - { - $arr = array('foo', 'bar', 'baz'); - Arr::to_assoc($arr); - } - - /** - * Tests Arr::prepend() - * - * @test - */ - public function test_prepend() - { - $arr = array( - 'two' => 2, - 'three' => 3, - ); - $expected = array( - 'one' => 1, - 'two' => 2, - 'three' => 3, - ); - Arr::prepend($arr, 'one', 1); - $this->assertEquals($expected, $arr); - } - - /** - * Tests Arr::prepend() - * - * @test - */ - public function test_prepend_array() - { - $arr = array( - 'two' => 2, - 'three' => 3, - ); - $expected = array( - 'one' => 1, - 'two' => 2, - 'three' => 3, - ); - Arr::prepend($arr, array('one' => 1)); - $this->assertEquals($expected, $arr); - } - - /** - * Tests Arr::is_multi() - * - * @test - */ - public function test_multidimensional_array() - { - // Single array - $arr_single = array('one' => 1, 'two' => 2); - $this->assertFalse(Arr::is_multi($arr_single)); - - // Multi-dimensional array - $arr_multi = array('one' => array('test' => 1), 'two' => array('test' => 2), 'three' => array('test' => 3)); - $this->assertTrue(Arr::is_multi($arr_multi)); - - // Multi-dimensional array (not all elements are arrays) - $arr_multi_strange = array('one' => array('test' => 1), 'two' => array('test' => 2), 'three' => 3); - $this->assertTrue(Arr::is_multi($arr_multi_strange, false)); - $this->assertFalse(Arr::is_multi($arr_multi_strange, true)); - } - - /** - * Tests Arr::search() - * - * @test - */ - public function test_search_single_array() - { - // Single array - $arr_single = array('one' => 1, 'two' => 2); - $expected = 'one'; - $this->assertEquals($expected, Arr::search($arr_single, 1)); - - // Default - $expected = null; - $this->assertEquals($expected, Arr::search($arr_single, 3)); - $expected = 'three'; - $this->assertEquals($expected, Arr::search($arr_single, 3, 'three')); - - // Single array (int key) - $arr_single = array(0 => 'zero', 'one' => 1, 'two' => 2); - $expected = 0; - $this->assertEquals($expected, Arr::search($arr_single, 0)); - } - - /** - * Tests Arr::search() - * - * @test - */ - public function test_search_multi_array() - { - // Multi-dimensional array - $arr_multi = array('one' => array('test' => 1), 'two' => array('test' => 2), 'three' => array('test' => array('a' => 'a', 'b' => 'b'))); - $expected = 'one'; - $this->assertEquals($expected, Arr::search($arr_multi, array('test' => 1), null, false)); - $expected = null; - $this->assertEquals($expected, Arr::search($arr_multi, 1, null, false)); - - // Multi-dimensional array (recursive) - $expected = 'one.test'; - $this->assertEquals($expected, Arr::search($arr_multi, 1)); - - $expected = 'three.test.b'; - $this->assertEquals($expected, Arr::search($arr_multi, 'b', null, true)); - } - - /** - * Tests Arr::sum() - * - * @test - */ - public function test_sum_multi_array() - { - $arr_multi = array( - array( - 'name' => 'foo', - 'scores' => array( - 'sports' => 5, - 'math' => 20, - ), - ), - array( - 'name' => 'bar', - 'scores' => array( - 'sports' => 7, - 'math' => 15, - ), - ), - array( - 'name' => 'fuel', - 'scores' => array( - 'sports' => 8, - 'math' => 5, - ), - ), - array( - 'name' => 'php', - 'scores' => array( - 'math' => 10, - ), - ), - ); - - $expected = 50; - $test = \Arr::sum($arr_multi, 'scores.math'); - $this->assertEquals($expected, $test); - - $expected = 20; - $test = \Arr::sum($arr_multi, 'scores.sports'); - $this->assertEquals($expected, $test); - } - - /** - * Tests Arr::previous_by_key() - * - * @test - */ - public function test_previous_by_key() - { - // our test array - $arr = array(2 => 'A', 4 => 'B', 6 => 'C'); - - // test: key not found in array - $expected = false; - $test = \Arr::previous_by_key($arr, 1); - $this->assertTrue($expected === $test); - - // test: no previous key - $expected = null; - $test = \Arr::previous_by_key($arr, 2); - $this->assertTrue($expected === $test); - - // test: strict key comparison - $expected = false; - $test = \Arr::previous_by_key($arr, '2', false, true); - $this->assertTrue($expected === $test); - - // test: get previous key - $expected = 2; - $test = \Arr::previous_by_key($arr, 4); - $this->assertTrue($expected === $test); - - // test: get previous value - $expected = 'A'; - $test = \Arr::previous_by_key($arr, 4, true); - $this->assertTrue($expected === $test); - } - - /** - * Tests Arr::next_by_key() - * - * @test - */ - public function test_next_by_key() - { - // our test array - $arr = array(2 => 'A', 4 => 'B', 6 => 'C'); - - // test: key not found in array - $expected = false; - $test = \Arr::next_by_key($arr, 1); - $this->assertTrue($expected === $test); - - // test: no next key - $expected = null; - $test = \Arr::next_by_key($arr, 6); - $this->assertTrue($expected === $test); - - // test: strict key comparison - $expected = false; - $test = \Arr::next_by_key($arr, '6', false, true); - $this->assertTrue($expected === $test); - - // test: get next key - $expected = 6; - $test = \Arr::next_by_key($arr, 4); - $this->assertTrue($expected === $test); - - // test: get next value - $expected = 'C'; - $test = \Arr::next_by_key($arr, 4, true); - $this->assertTrue($expected === $test); - } - - /** - * Tests Arr::previous_by_value() - * - * @test - */ - public function test_previous_by_value() - { - // our test array - $arr = array(2 => 'A', 4 => '2', 6 => 'C'); - - // test: value not found in array - $expected = false; - $test = \Arr::previous_by_value($arr, 'Z'); - $this->assertTrue($expected === $test); - - // test: no previous value - $expected = null; - $test = \Arr::previous_by_value($arr, 'A'); - $this->assertTrue($expected === $test); - - // test: strict value comparison - $expected = false; - $test = \Arr::previous_by_value($arr, 2, true, true); - $this->assertTrue($expected === $test); - - // test: get previous value - $expected = 'A'; - $test = \Arr::previous_by_value($arr, '2'); - $this->assertTrue($expected === $test); - - // test: get previous key - $expected = 4; - $test = \Arr::previous_by_value($arr, 'C', false); - $this->assertTrue($expected === $test); - } - - /** - * Tests Arr::next_by_value() - * - * @test - */ - public function test_next_by_value() - { - // our test array - $arr = array(2 => 'A', 4 => '2', 6 => 'C'); - - // test: value not found in array - $expected = false; - $test = \Arr::next_by_value($arr, 'Z'); - $this->assertTrue($expected === $test); - - // test: no next value - $expected = null; - $test = \Arr::next_by_value($arr, 'C'); - $this->assertTrue($expected === $test); - - // test: strict value comparison - $expected = false; - $test = \Arr::next_by_value($arr, 2, true, true); - $this->assertTrue($expected === $test); - - // test: get next value - $expected = 'C'; - $test = \Arr::next_by_value($arr, '2'); - $this->assertTrue($expected === $test); - - // test: get next key - $expected = 4; - $test = \Arr::next_by_value($arr, 'A', false); - $this->assertTrue($expected === $test); - } - - /** - * Tests Arr::subset() - * - * @test - * @dataProvider person_provider - */ - public function test_subset_basic_usage($person) - { - $expected = array( - "name" => "Jack", - "location" => array( - "city" => "Pittsburgh", - "state" => "PA", - "country" => "US", - ), - ); - - $got = \Arr::subset($person, array("name", "location")); - $this->assertEquals($expected, $got); - - $expected = array( - "name" => "Jack", - "location" => array( - "country" => "US", - ), - ); - - $got = \Arr::subset($person, array("name", "location.country")); - $this->assertEquals($expected, $got); - } - - /** - * Tests Arr::subset() - * - * @test - * @dataProvider person_provider - */ - public function test_subset_missing_items($person) - { - $expected = array( - "name" => "Jack", - "location" => array( - "street" => null, - "country" => "US", - ), - "occupation" => null, - ); - - $got = \Arr::subset($person, array("name", "location.street", "location.country", "occupation")); - $this->assertEquals($expected, $got); - - $expected = array( - "name" => "Jack", - "location" => array( - "street" => "Unknown", - "country" => "US", - ), - "occupation" => "Unknown", - ); - - $got = \Arr::subset($person, array("name", "location.street", "location.country", "occupation"), "Unknown"); - $this->assertEquals($expected, $got); - } - - /** - * Tests Arr::filter_recursive() - */ - public function test_filter_recursive() - { - $arr = array( - "user_name" => "John", - "user_surname" => "Lastname", - "info" => array( - 0 => array( - "data" => "a value", - ), - 1 => array( - "data" => "", - ), - 2 => array( - "data" => 0, - ), - ), - ); - - $expected = array( - "user_name" => "John", - "user_surname" => "Lastname", - "info" => array( - 0 => array( - "data" => "a value", - ), - ), - ); - $got = \Arr::filter_recursive($arr); - $this->assertEquals($expected, $got); - - $expected = array( - "user_name" => "John", - "user_surname" => "Lastname", - "info" => array( - 0 => array( - "data" => "a value", - ), - 1 => array( - ), - 2 => array( - "data" => 0, - ), - ), - ); - $got = \Arr::filter_recursive( - $arr, function($item){ return $item !== ""; } - ); - $this->assertEquals($expected, $got); - } -} diff --git a/fuel/core/tests/asset.php b/fuel/core/tests/asset.php deleted file mode 100755 index 64a2dae..0000000 --- a/fuel/core/tests/asset.php +++ /dev/null @@ -1,24 +0,0 @@ - $val) - { - \Config::set($key, $val); - } - \Crypt::_init(); - } - - public function test_encode_decode() - { - $encoded = 'LmdFdwMgA9QB8FFCmEQx1094YVRUa3JxXzl6OWxDUUN1d3RLcHB1Ykp6MGp1T21wNVNJUS1ZM3J3MDA'; - $clear_text = 'some string'; - $test = \Crypt::encode($clear_text); - $this->assertEquals($encoded, $test); - - $test = \Crypt::decode($encoded); - $this->assertEquals($clear_text, $test); - } - - public function test_encode_decode_with_key() - { - $encoded = 'QE4AhW52POclh6PgPIVW5Xk3azVreHFfQjVmLXdVamNjbkZyZlE4YVQwQ1Fmc0Z3NE1fZlM0WDR4X00'; - $clear_text = 'some string'; - $test = \Crypt::encode($clear_text, 'this_is_key'); - $this->assertEquals($encoded, $test); - - $test = \Crypt::decode($encoded, 'this_is_key'); - $this->assertEquals($clear_text, $test); - } - - public function test_encode_decode_large_data() - { - $bigstr = str_repeat("this is a crypto test of 200k or so of data", 5000); - $bigstrhash = '391828747971d26de68550d935abaffa25f043795359417199ca39c09095dd11'; - $this->assertEquals($bigstrhash, hash('sha256', $bigstr)); - - // Encrypt it without a key - $test = \Crypt::encode($bigstr); - $testhash = '26c14e2093adb93798bb1eabcae1c5bb0d1e3dca800bf7c546d1e79317979996'; - $this->assertEquals($testhash, hash('sha256', $test)); - - // Decode it - $output= \Crypt::decode($test); - $this->assertEquals($bigstr, $output); - } -} diff --git a/fuel/core/tests/database/connection.php b/fuel/core/tests/database/connection.php deleted file mode 100755 index 2343fad..0000000 --- a/fuel/core/tests/database/connection.php +++ /dev/null @@ -1,24 +0,0 @@ -assertEquals($expected, $output); - - $output = Date::days_in_month(2, 2001); - $expected = 28; - $this->assertEquals($expected, $output); - - $output = Date::days_in_month(2, 2000); - $expected = 29; - $this->assertEquals($expected, $output); - } - - /** - * Test for Date::days_in_month(0) - * @expectedException UnexpectedValueException - * @test - */ - public function test_days_in_month_0_exception() - { - $output = Date::days_in_month(0); - } - - /** - * Test for Date::days_in_month(13) - * @expectedException UnexpectedValueException - * @test - */ - public function test_days_in_month_13_exception() - { - $output = Date::days_in_month(13); - } - - /** - * Test for Date::format() - * - * @test - */ - public function test_format() - { - $default_timezone = date_default_timezone_get(); - date_default_timezone_set('UTC'); - - $output = Date::forge( 1294176140 )->format("%m/%d/%Y"); - $expected = "01/04/2011"; - - date_default_timezone_set($default_timezone); - - $this->assertEquals($expected, $output); - } - - /** - * Test for Date::get_timestamp() - * - * @test - */ - public function test_get_timestamp() - { - $output = Date::forge( 1294176140 )->get_timestamp(); - $expected = 1294176140; - - $this->assertEquals($expected, $output); - } - - /** - * Test for Date::get_timezone() - * - * @test - */ - public function test_get_timezone() - { - $output = Date::forge( 1294176140, "Europe/London" )->get_timezone(); - $expected = "Europe/London"; - - $this->assertEquals($expected, $output); - } - - /** - * Test for Date::set_timezone() - * - * @test - */ - public function test_set_timezone() - { - $output = Date::forge( 1294176140 )->set_timezone("America/Chicago")->get_timezone(); - $expected = "America/Chicago"; - - $this->assertEquals($expected, $output); - } - - /** - * Test for Date::time_ago() - * - * @test - */ - public function test_time_ago_null_timestamp() - { - $output = Date::time_ago(null); - - $this->assertEquals(null, $output); - } - - /** - * Test for Date::time_ago() - * - * @test - */ - public function test_time_ago_one_month() - { - $march_30_2011 = 1301461200; - $april_30_2011 = 1304139600; - $output = Date::time_ago($march_30_2011, $april_30_2011); - - $this->assertEquals('1 month ago', $output); - } - - /** - * Test for Date::time_ago() - * - * @test - */ - public function test_time_ago_two_months() - { - $march_30_2011 = 1301461200; - $may_30_2011 = 1306731600; - - $output = Date::time_ago($march_30_2011, $may_30_2011); - - $this->assertEquals('2 months ago', $output); - } - - /** - * Test for Date::range_to_array() - * - * @test - */ - public function test_range_to_array() - { - $start = Date::create_from_string('2015-10-01', '%Y-%m-%d'); - $end = Date::create_from_string('2016-03-01', '%Y-%m-%d'); - $range = Date::range_to_array($start, $end, "+1 month"); - - $expected = array('2015-10-01', '2015-11-01', '2015-12-01', '2016-01-01', '2016-02-01', '2016-03-01'); - $output = array(); - foreach ($range as $r) - { - $output[] = $r->format('%Y-%m-%d'); - } - - $this->assertEquals($expected, $output); - } - - /** - * Test for Date::range_to_array() - * - * @test - */ - public function test_range_to_array_empty() - { - $start = Date::create_from_string('2016-03-01', '%Y-%m-%d'); - $end = Date::create_from_string('2015-10-01', '%Y-%m-%d'); - $range = Date::range_to_array($start, $end, "+1 month"); - - $expected = array(); - $output = array(); - foreach ($range as $r) - { - $output[] = $r->format('%Y-%m-%d'); - } - - $this->assertEquals($expected, $output); - } - - /** - * Test for Date::range_to_array() - * - * @test - */ - public function test_range_to_array_days() - { - $start = Date::create_from_string('2015-10-01', '%Y-%m-%d'); - $end = Date::create_from_string('2015-10-05', '%Y-%m-%d'); - $range = Date::range_to_array($start, $end, "+4 days"); - - $expected = array('2015-10-01', '2015-10-05'); - $output = array(); - foreach ($range as $r) - { - $output[] = $r->format('%Y-%m-%d'); - } - - $this->assertEquals($expected, $output); - } - - /** - * Test for Date::range_to_array() - * @expectedException UnexpectedValueException - * - * @test - */ - public function test_range_to_array_invalid() - { - $start = Date::create_from_string('2015-10-01', '%Y-%m-%d'); - $end = Date::create_from_string('2015-10-02', '%Y-%m-%d'); - $range = Date::range_to_array($start, $end, "-2 days"); - } -} diff --git a/fuel/core/tests/db.php b/fuel/core/tests/db.php deleted file mode 100755 index f611030..0000000 --- a/fuel/core/tests/db.php +++ /dev/null @@ -1,24 +0,0 @@ -old_is_cli = \Fuel::$is_cli; - \Fuel::$is_cli = false; - } - - public function tearDown() - { - // Restore original value - \Fuel::$is_cli = $this->old_is_cli; - } - - public function test_debug_dump_normally() - { - $expected = '

    COREPATH/tests/debug.php @ line: 41

    Variable #1:'."\n".'  (Integer): 1'."\n\n\n".'Variable #2:'."\n".'  (Integer): 2'."\n\n\n".'Variable #3:'."\n".'  (Integer): 3'."\n\n\n".'
    '; - - ob_start(); - \Debug::dump(1, 2, 3); - $output = ob_get_contents(); - ob_end_clean(); - - $this->assertEquals($expected, $output); - } - - public function test_debug_dump_by_call_user_func_array() - { - $expected = '

    COREPATH/tests/debug.php @ line: 53

    Variable #1:'."\n".'  (Integer): 1'."\n\n\n".'Variable #2:'."\n".'  (Integer): 2'."\n\n\n".'Variable #3:'."\n".'  (Integer): 3'."\n\n\n".'
    '; - - ob_start(); - call_user_func_array('\\Debug::dump', array(1, 2, 3)); - $output = ob_get_contents(); - ob_end_clean(); - - $this->assertEquals($expected, $output); - } - - public function test_debug_dump_by_call_fuel_func_array() - { - $expected = '

    COREPATH/base.php @ line: %d

    Variable #1:
    -  (Integer): 1
    -
    -
    -Variable #2:
    -  (Integer): 2
    -
    -
    -Variable #3:
    -  (Integer): 3
    -
    -
    -
    '; - - if (PHP_VERSION_ID >= 50600) - { - $expected = str_replace('base.php', 'base56.php', $expected); - } - - ob_start(); - call_fuel_func_array('\\Debug::dump', array(1, 2, 3)); - $output = ob_get_contents(); - ob_end_clean(); - - $this->assertStringMatchesFormat($expected, $output); - } -} diff --git a/fuel/core/tests/email.php b/fuel/core/tests/email.php deleted file mode 100755 index 212007a..0000000 --- a/fuel/core/tests/email.php +++ /dev/null @@ -1,24 +0,0 @@ -assertTrue($output); - } - - /** - * Test for Event::has_events() - * - * @test - */ - public function test_hasevents_valid() - { - $output = Event::has_events('test_register_valid'); - $this->assertTrue($output); - } - - /** - * Test for Event::trigger() - * - * @test - */ - public function test_trigger_valid() - { - $output = Event::trigger('test_register_valid', 'text to upper'); - $this->assertEquals('TEXT TO UPPER', $output); - } - - /** - * Test for Event::register() - * - * @test - */ - public function test_register_invalid() - { - $output = Event::register('test_register_invalid', 'Imaginary::callback'); - $this->assertFalse($output); - } - - /** - * Test for Event::has_events() - * - * @test - */ - public function test_hasevents_invalid() - { - $output = Event::has_events('test_register_invalid'); - $this->assertFalse($output); - } - - /** - * Test for Event::trigger() - * - * @test - */ - public function test_trigger_invalid() - { - $output = Event::trigger('test_register_invalid', 'text to upper'); - $this->assertEquals('', $output); - } -} diff --git a/fuel/core/tests/fieldset.php b/fuel/core/tests/fieldset.php deleted file mode 100755 index 63dea0f..0000000 --- a/fuel/core/tests/fieldset.php +++ /dev/null @@ -1,94 +0,0 @@ -pathinfo = $_SERVER['PATH_INFO']; - $_SERVER['PATH_INFO'] = '/welcome/index'; - - // set Request::$main - $request = \Request::forge('welcome/index'); - $rp = new \ReflectionProperty($request, 'main'); - $rp->setAccessible(true); - $rp->setValue($request, $request); - \Request::active($request); - } - - public function tearDown() - { - // remove the fake uri - if (property_exists($this, 'pathinfo')) - { - $_SERVER['PATH_INFO'] = $this->pathinfo; - } - else - { - unset($_SERVER['PATH_INFO']); - } - - // reset Request::$main - $request = \Request::forge(); - $rp = new \ReflectionProperty($request, 'main'); - $rp->setAccessible(true); - $rp->setValue($request, false); - } - - /** - * Test of "for" attribute in label tag - */ - public function test_for_in_label() - { - $form = Fieldset::forge(__METHOD__)->set_config(array( - // regular form definitions - 'prep_value' => true, - 'auto_id' => true, - 'auto_id_prefix' => 'form_', - 'form_method' => 'post', - 'form_template' => "\n\t\t{open}\n\t\t\n{fields}\n\t\t
    \n\t\t{close}\n", - 'fieldset_template' => "\n\t\t{open}\n{fields}
    \n\t\t{close}\n", - 'field_template' => "\t\t\n\t\t\t{label}{required}\n\t\t\t{field} {description} {error_msg}\n\t\t\n", - 'multi_field_template' => "\t\t\n\t\t\t{group_label}{required}\n\t\t\t{fields}\n\t\t\t\t{field} {label}
    \n{fields}{description}\t\t\t{error_msg}\n\t\t\t\n\t\t\n", - 'error_template' => '{error_msg}', - 'group_label' => '{label}', - 'required_mark' => '*', - 'inline_errors' => false, - 'error_class' => 'validation_error', - - // tabular form definitions - 'tabular_form_template' => "{fields}
    \n", - 'tabular_field_template' => "{field}", - 'tabular_row_template' => "{fields}\n", - 'tabular_row_field_template' => "\t\t\t{label}{required} {field} {icon} {error_msg}\n", - 'tabular_delete_label' => "Delete?", - )); - $ops = array('male', 'female'); - $form->add('gender', '', array( - 'options' => $ops, 'type' => 'radio', 'value' => 1, - )); - - $output = $form->build(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = '


    '; - $this->assertEquals($expected, $output); - } -} diff --git a/fuel/core/tests/fieldset/field.php b/fuel/core/tests/fieldset/field.php deleted file mode 100755 index 096a20b..0000000 --- a/fuel/core/tests/fieldset/field.php +++ /dev/null @@ -1,24 +0,0 @@ - true, - 'auto_id' => true, - 'auto_id_prefix' => 'form_', - 'form_method' => 'post', - 'form_template' => "\n\t\t{open}\n\t\t\n{fields}\n\t\t
    \n\t\t{close}\n", - 'fieldset_template' => "\n\t\t{open}\n{fields}
    \n\t\t{close}\n", - 'field_template' => "\t\t\n\t\t\t{label}{required}\n\t\t\t{field} {description} {error_msg}\n\t\t\n", - 'multi_field_template' => "\t\t\n\t\t\t{group_label}{required}\n\t\t\t{fields}\n\t\t\t\t{field} {label}
    \n{fields}{description}\t\t\t{error_msg}\n\t\t\t\n\t\t\n", - 'error_template' => '{error_msg}', - 'required_mark' => '*', - 'inline_errors' => false, - 'error_class' => 'validation_error', - )); - - Config::set('security.csrf_auto_token', false); - Config::set('security.csrf_token_key', 'fuel_csrf_token'); - } - - /** - * Tests Form::input() - * - * test for data prepping - * - * @test - */ - public function test_input_prep() - { - $output = Form::input('name', '"H&M"'); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', ''); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', "0"); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', 0); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', 1); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', 10); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', true); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', false); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', null); - $expected = ''; - $this->assertEquals($expected, $output); - } - - /** - * Tests Form::input() - * - * test for dont_prep - * - * @test - */ - public function test_input_dont_prep() - { - $output = Form::input('name', '"'H&M'"', array('dont_prep' => true)); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', '', array('dont_prep' => true)); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', "0", array('dont_prep' => true)); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', 0, array('dont_prep' => true)); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', 1, array('dont_prep' => true)); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', 10, array('dont_prep' => true)); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', true, array('dont_prep' => true)); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', false, array('dont_prep' => true)); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Form::input('name', null, array('dont_prep' => true)); - $expected = ''; - $this->assertEquals($expected, $output); - } - - /** - * Tests Form::textarea() - * - * test for data prepping - * - * @test - */ - public function test_textarea_prep() - { - $output = Form::textarea('name', '"H&M"'); - $expected = ''; - $this->assertEquals($expected, $output); - } - - /** - * Tests Form::textarea() - * - * test for dont_prep - * - * @test - */ - public function test_textarea_dont_prep() - { - $output = Form::textarea('name', '"'H&M'"', array('dont_prep' => true)); - $expected = ''; - $this->assertEquals($expected, $output); - } - - /** - * Tests Form::select() - * - * test for data prepping - * - * @test - */ - public function test_select_prep() - { - $output = Form::select('fieldname', null, - array( - 'key_H&M' => 'val_H&M', - 'key_""' => 'val_""', - ) - ); - $expected = ''; - $this->assertEquals($expected, $output); - } - - /** - * Tests Form::prep_value() - * - * @test - */ - public function test_prep_value() - { - $output = Form::prep_value('<"H&M">'); - $expected = '<"H&M">'; - $this->assertEquals($expected, $output); - } - - /** - * Tests Form::select() - * - * test for dont_prep - * - * @test - */ - public function test_select_dont_prep() - { - $output = Form::select('fieldname', null, - array( - 'key_H&M' => 'val_H&M', - 'key_"'"' => 'val_"'"', - ), - array( - 'dont_prep' => true, - ) - ); - $expected = ''; - $this->assertEquals($expected, $output); - } - - /** - * Tests Form::prep_value() - * - * test of invalid string - * - * @test - */ - public function test_prep_value_invalid_utf8() - { - // 6 byte UTF-8 string, which is invalid now - $utf8_string = "\xFC\x84\x80\x80\x80\x80"; - $output = Form::prep_value($utf8_string); - $expected = ''; - $this->assertEquals($expected, $output); - } - - /** - * Tests Form::label() - * - * @test - */ - public function test_label_auto_id_true() - { - $config = \Config::get('form.auto_id'); - \Config::set('form.auto_id', true); - - $form = \Form::forge(__METHOD__); - - $label = 'label'; - $id = 'id'; - $output = $form->label($label, $id); - $expected = ''; - $this->assertEquals($expected, $output); - - \Config::set('form.auto_id', $config); - } - - /** - * Tests Form::label() - * - * @test - */ - public function test_label_auto_id_false() - { - $config = \Config::get('form.auto_id'); - \Config::set('form.auto_id', false); - - $form = \Form::forge(__METHOD__); - - $label = 'label'; - $id = 'id'; - $output = $form->label($label, $id); - $expected = ''; - $this->assertEquals($expected, $output); - - \Config::set('form.auto_id', $config); - } - - /** - * Tests Form::open() - * - * @test - */ - public function test_open() - { - $form = \Form::forge(__METHOD__); - - $output = $form->open('uri/to/form'); - $expected = '
    '; - $this->assertEquals($expected, $output); - } - - /** - * Tests Form::open() - * - * @test - */ - public function test_open_auto_csrf_token() - { - \Config::set('security.csrf_auto_token', true); - - $form = \Form::forge(__METHOD__); - - $output = $form->open('uri/to/form'); - $expected = ''.PHP_EOL.''; - $this->assertStringMatchesFormat($expected, $output); - } - - /** - * Tests Form::open() - * - * @test - */ - public function test_open_static() - { - $output = Form::open('uri/to/form'); - $expected = ''; - $this->assertEquals($expected, $output); - } - - /** - * Tests Form::open() - * - * @test - */ - public function test_open_auto_csrf_token_static() - { - \Config::set('security.csrf_auto_token', true); - - $output = Form::open('uri/to/form'); - $expected = ''.PHP_EOL.''; - $this->assertStringMatchesFormat($expected, $output); - } -} diff --git a/fuel/core/tests/format.php b/fuel/core/tests/format.php deleted file mode 100755 index 15324a0..0000000 --- a/fuel/core/tests/format.php +++ /dev/null @@ -1,574 +0,0 @@ - array( - 'import' => array( - 'delimiter' => ',', - 'enclosure' => '"', - 'newline' => "\n", - 'escape' => '\\', - ), - 'export' => array( - 'delimiter' => ',', - 'enclosure' => '"', - 'newline' => "\n", - 'escape' => '\\', - ), - 'regex_newline' => "\n", - 'enclose_numbers' => true, - ), - 'xml' => array( - 'basenode' => 'xml', - 'use_cdata' => false, - 'bool_representation' => null, - ), - 'json' => array( - 'encode' => array( - 'options' => JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP, - ), - ), - )); - } - - public static function array_provider() - { - return array( - array( - array( - array('field1' => 'Value 1', 'field2' => 35, 'field3' => 123123), - array('field1' => 'Value 1', 'field2' => "Value\nline 2", 'field3' => 'Value 3'), - ), - '"field1","field2","field3" -"Value 1","35","123123" -"Value 1","Value -line 2","Value 3"', - ), - ); - } - - public static function array_provider2() - { - return array( - array( - array( - array('First' => 'Jane','Last' => 'Doe','Email' => 'jane@doe.com','Nr1' => 3434534,'Nr2' => 1,'Remark' => "asdfasdf\nasdfasdf",'Nr3' => 23432), - array('First' => 'John','Last' => 'Doe','Email' => 'john@doe.com','Nr1' => 52939494,'Nr2' => 1,'Remark' => 'dfdfdf','Nr3' => 35353), - ), - '"First","Last","Email","Nr1","Nr2","Remark","Nr3" -"Jane","Doe","jane@doe.com",3434534,1,"asdfasdf'."\n".'asdfasdf",23432 -"John","Doe","john@doe.com",52939494,1,"dfdfdf",35353', - ), - ); - } - - public static function array_provider3() - { - return array( - array( - array( - array('First' => 'Jane','Last' => 'Doe','Email' => 'jane@doe.com','Nr1' => 3434534,'Nr2' => 1,'Remark' => "asdfasdf\nasdfasdf",'Nr3' => 23432), - array('First' => 'John','Last' => 'Doe','Email' => 'john@doe.com','Nr1' => 52939494,'Nr2' => 1,'Remark' => 'dfdfdf','Nr3' => 35353), - ), - 'First;Last;Email;Nr1;Nr2;Remark;Nr3 -Jane;Doe;jane@doe.com;3434534;1;asdfasdf'."\n".'asdfasdf;23432 -John;Doe;john@doe.com;52939494;1;dfdfdf;35353', - ), - ); - } - - public static function array_provider4() - { - return array( - array( - array( - array(0 => 'Value 1', 1 => 35, 2 => 123123), - array(0 => 'Value 1', 1 => "Value\nline 2", 2 => 'Value 3'), - ), - '"Value 1","35","123123" -"Value 1","Value -line 2","Value 3"', - ), - ); - } - - public static function array_provider5() - { - return array( - array( - array( - array('field1' => 'Value 1', 'field2' => 35, 'field3' => true, 'field4' => false), - ), - ' -Value 1351 -', - ' -Value 1351 -', - ' -Value 135truefalse -', - ' -Value 13510 -', - ), - ); - } - - /** - * Test for Format::forge($foo, 'csv')->to_array() - * - * @test - * @dataProvider array_provider - */ - public function test_from_csv($array, $csv) - { - $this->assertEquals($array, Format::forge($csv, 'csv')->to_array()); - } - - /** - * Test for Format::forge($foo, 'csv')->to_array() - * - * @test - * @dataProvider array_provider2 - */ - public function test_from_csv2($array, $csv) - { - $this->assertEquals($array, Format::forge($csv, 'csv')->to_array()); - } - - /** - * Test for Format::forge($foo, 'csv')->to_array() with different delimiter and no enclosures - * - * @test - * @dataProvider array_provider3 - */ - public function test_from_csv3($array, $csv) - { - \Config::set('format.csv.import.enclosure', ''); - \Config::set('format.csv.import.delimiter', ';'); - \Config::set('format.csv.export.enclosure', ''); - \Config::set('format.csv.export.delimiter', ';'); - - $this->assertEquals($array, Format::forge($csv, 'csv')->to_array()); - - \Config::set('format.csv.import.enclosure', '"'); - \Config::set('format.csv.import.delimiter', ','); - \Config::set('format.csv.export.enclosure', '"'); - \Config::set('format.csv.export.delimiter', ','); - } - - /** - * Test for Format::forge($foo, 'csv')->to_array() without CSV headers - * - * @test - * @dataProvider array_provider4 - */ - public function test_from_csv4($array, $csv) - { - $this->assertEquals($array, Format::forge($csv, 'csv', false)->to_array()); - } - - /** - * Test for Format::forge($foo)->to_csv() - * - * @test - * @dataProvider array_provider - */ - public function test_to_csv($array, $csv) - { - $this->assertEquals($csv, Format::forge($array)->to_csv()); - } - - /** - * Test for Format::forge($foo)->to_csv() without enclosuring numbers - * - * @test - * @dataProvider array_provider2 - */ - public function test_to_csv2($array, $csv) - { - $this->assertEquals($csv, Format::forge($array)->to_csv(null, null, false)); - } - - /** - * Test for Format::forge($foo)->to_csv() with different delimiter and no enclosures - * - * @test - * @dataProvider array_provider3 - */ - public function test_to_csv3($array, $csv) - { - \Config::set('format.csv.import.enclosure', ''); - \Config::set('format.csv.import.delimiter', ';'); - \Config::set('format.csv.export.enclosure', ''); - \Config::set('format.csv.export.delimiter', ';'); - - $this->assertEquals($csv, Format::forge($array)->to_csv()); - - \Config::set('format.csv.import.enclosure', '"'); - \Config::set('format.csv.import.delimiter', ','); - \Config::set('format.csv.export.enclosure', '"'); - \Config::set('format.csv.export.delimiter', ','); - } - - /** - * Test for Format::forge($foo)->_from_xml() - * - * @test - */ - public function test__from_xml() - { - $xml = ' - - - - - - - - - - - ../core/tests - - - ../packages/*/tests - - - ../app/tests - - -'; - - $expected = array( - '@attributes' => array( - 'colors' => 'true', - 'stopOnFailure' => 'false', - 'bootstrap' => 'bootstrap_phpunit.php', - ), - 'php' => array( - 'server' => array( - 0 => array( - '@attributes' => array( - 'name' => 'doc_root', - 'value' => '../../', - ), - ), - 1 => array( - '@attributes' => array( - 'name' => 'app_path', - 'value' => 'fuel/app', - ), - ), - 2 => array( - '@attributes' => array( - 'name' => 'core_path', - 'value' => 'fuel/core', - ), - ), - 3 => array( - '@attributes' => array( - 'name' => 'package_path', - 'value' => 'fuel/packages', - ), - ), - ), - ), - 'testsuites' => array( - 'testsuite' => array( - 0 => array( - '@attributes' => array( - 'name' => 'core', - ), - 'directory' => '../core/tests', - ), - 1 => array( - '@attributes' => array( - 'name' => 'packages', - ), - 'directory' => '../packages/*/tests', - ), - 2 => array( - '@attributes' => array( - 'name' => 'app', - ), - 'directory' => '../app/tests', - ), - ), - ), - ); - - $this->assertEquals(Format::forge($expected)->to_php(), Format::forge($xml, 'xml')->to_php()); - } - - /** - * Test for Format::forge(null)->to_array() - * - * @test - */ - public function test_to_array_empty() - { - $array = null; - $expected = array(); - $this->assertEquals($expected, Format::forge($array)->to_array()); - } - - /** - * Test for Format::forge($foo)->to_xml() - * - * @test - */ - public function test_to_xml() - { - $array = array( - 'articles' => array( - array( - 'title' => 'test', - 'author' => 'foo', - ), - ), - ); - - $expected = ' -
    testfoo
    -'; - - $this->assertEquals($expected, Format::forge($array)->to_xml()); - } - - /** - * Test for Format::forge($foo)->to_xml(null, null, 'root') - * - * @test - */ - public function test_to_xml_basenode() - { - $array = array( - 'articles' => array( - array( - 'title' => 'test', - 'author' => 'foo', - ), - ), - ); - - $expected = ' -
    testfoo
    -'; - - $this->assertEquals($expected, Format::forge($array)->to_xml(null, null, 'root')); - } - - /** - * Test for Format::forge($foo)->to_xml() espace tags - * - * @test - */ - public function test_to_xml_escape_tags() - { - $array = array( - 'articles' => array( - array( - 'title' => 'test', - 'author' => '

    hero

    ', - ), - ), - ); - - $expected = ' -
    test<h1>hero</h1>
    -'; - - $this->assertEquals($expected, Format::forge($array)->to_xml()); - } - - /** - * Test for Format::forge($foo)->to_xml(null, null, null, null, true) - * - * @test - * @dataProvider array_provider5 - */ - public function test_to_xml_boolean($array, $default, $default_libxml277, $true, $number) - { - // default - if (LIBXML_VERSION >= 20708) - { - // libxml v2.7.8 and later - $this->assertEquals($default, Format::forge($array)->to_xml()); - } - else - { - // libxml v2.7.7 and before - $this->assertEquals($default_libxml277, Format::forge($array)->to_xml()); - } - - // true/false - $this->assertEquals($true, Format::forge($array)->to_xml(null, null, null, null, true)); - // 1/0 - $this->assertEquals($number, Format::forge($array)->to_xml(null, null, null, null, 1)); - } - - /** - * Test for Format::forge($foo)->to_xml(null, null, 'xml', true) - * - * @test - */ - public function test_to_xml_cdata() - { - $array = array( - 'articles' => array( - array( - 'title' => 'test', - 'author' => '

    hero

    ', - ), - ), - ); - - $expected = ' -
    testhero]]>
    -'; - - $this->assertEquals($expected, Format::forge($array)->to_xml(null, null, 'xml', true)); - } - - /** - * Test for Format::forge($namespaced_xml, 'xml')->to_array() - * - * @test - */ - public function test_namespaced_xml() - { - $xml = ' -
    testapp test
    '; - - $data = Format::forge($xml, 'xml')->to_array(); - - $expected = array( - 'article' => array( - 'title' => 'test', - ), - ); - - $this->assertEquals($expected, $data); - } - - /** - * Test for Format::forge($namespaced_xml, 'xml:ns')->to_array() - * - * @test - */ - public function test_namespaced_xml_and_include_xmlns() - { - $xml = ' -
    testapp test
    '; - - $data = Format::forge($xml, 'xml:ns')->to_array(); - - $expected = array( - '@attributes' => array( - 'xmlns' => 'http://www.w3.org/2005/Atom', - 'xmlns:media' => 'http://search.yahoo.com/mrss/', - 'xmlns:app' => 'http://www.w3.org/2007/app', - ), - 'article' => array( - 'title' => 'test', - 'app:title' => 'app test', - ), - ); - - $this->assertEquals($expected, $data); - } - - /** - * Test for Format::forge($foo)->to_json() - * - * @test - */ - public function test_to_json() - { - $array = array( - 'articles' => array( - array( - 'title' => 'test', - 'author' => 'foo', - 'tag' => '', - 'apos' => 'McDonald\'s', - 'quot' => '"test"', - 'amp' => 'M&M', - - ), - ), - ); - - $expected = '{"articles":[{"title":"test","author":"foo","tag":"\u003Ctag\u003E","apos":"McDonald\u0027s","quot":"\u0022test\u0022","amp":"M\u0026M"}]}'; - - $this->assertEquals($expected, Format::forge($array)->to_json()); - - // pretty json - $expected = '{ - "articles": [ - { - "title": "test", - "author": "foo", - "tag": "\u003Ctag\u003E", - "apos": "McDonald\u0027s", - "quot": "\u0022test\u0022", - "amp": "M\u0026M" - } - ] -}'; - $this->assertEquals($expected, Format::forge($array)->to_json(null, true)); - - // change config options - $config = \Config::get('format.json.encode.options'); - \Config::set('format.json.encode.options', 0); - - $expected = <<","apos":"McDonald's","quot":"\"test\"","amp":"M&M"}]} -EOD; - $this->assertEquals($expected, Format::forge($array)->to_json()); - - // pretty json - $expected = <<", - "apos": "McDonald's", - "quot": "\"test\"", - "amp": "M&M" - } - ] -} -EOD; - $this->assertEquals($expected, Format::forge($array)->to_json(null, true)); - - // restore config options - \Config::set('format.json.encode.options', $config); - } -} diff --git a/fuel/core/tests/ftp.php b/fuel/core/tests/ftp.php deleted file mode 100755 index 50a9bf4..0000000 --- a/fuel/core/tests/ftp.php +++ /dev/null @@ -1,24 +0,0 @@ -old_url_suffix = Config::get('url_suffix'); - $this->old_index_file = Config::get('index_file'); - $this->old_base_url = Config::get('base_url'); - } - - public function tearDown() - { - Config::set('url_suffix', $this->old_url_suffix); - Config::set('index_file', $this->old_index_file); - Config::set('base_url', $this->old_base_url); - } - - /** - * Tests Html::meta() - * - * @test - */ - public function test_meta() - { - $output = Html::meta('description', 'Meta Example!'); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Html::meta('robots', 'no-cache'); - $expected = ''; - $this->assertEquals($expected, $output); - - $meta = array( - array('name' => 'robots', 'content' => 'no-cache'), - array('name' => 'description', 'content' => 'Meta Example'), - array('name' => 'keywords', 'content' => 'fuel, rocks'), - ); - - $output = Html::meta($meta); - $expected = ' - - -'; - $this->assertEquals($expected, $output); - } - - /** - * Tests Html::anchor() - * - * @test - */ - public function test_anchor() - { - // Query string tests - Config::set('url_suffix', null); - Config::set('index_file', null); - Config::set('base_url', null); - - // External uri - $output = Html::anchor('http://google.com', 'Go to Google'); - $expected = 'Go to Google'; - $this->assertEquals($expected, $output); - - $output = Html::anchor('javascript:do();', 'Do()'); - $expected = 'Do()'; - $this->assertEquals($expected, $output); - - $output = Html::anchor('http://google.com', 'Go to Google', array('rel' => 'example', 'class' => 'sample', 'style' => 'color:red;')); - $expected = 'Go to Google'; - $this->assertEquals($expected, $output); - - // External secure uri - $output = Html::anchor('http://google.com', 'Go to Google', array('rel' => 'example', 'class' => 'sample', 'style' => 'color:red;'), true); - $expected = 'Go to Google'; - $this->assertEquals($expected, $output); - - // Internal uri - $output = Html::anchor('controller/method', 'Method'); - $expected = 'Method'; - $this->assertEquals($expected, $output); - - // Internal secure uri - $host = \Input::server('http_host'); - $_SERVER['HTTP_HOST'] = 'fuelphp.com'; - $output = Html::anchor('controller/method', 'Method', array(), true); - $expected = 'Method'; - $this->assertEquals($expected, $output); - $_SERVER['HTTP_HOST'] = $host; - - $output = Html::anchor('search?q=query', 'Search'); - $expected = 'Search'; - $this->assertEquals($expected, $output); - - Config::set('url_suffix', '.html'); - - $output = Html::anchor('search?q=query', 'Search'); - $expected = 'Search'; - $this->assertEquals($expected, $output); - } - - /** - * Tests Html::img() - * - * This test does not account for the image file existing in - * the filesystem. There are no images bundled with the framework - * by default, so no reliable test can be run on an actual image. - * - * @test - */ - public function test_img() - { - $image_path = 'image.png'; - - // Internal uri - $output = Html::img('image.png'); - $expected = 'image'; - $this->assertEquals($expected, $output); - - $output = Html::img('image.png', array('alt' => 'Image')); - $expected = 'Image'; - $this->assertEquals($expected, $output); - - // External uri - $output = Html::img('http://google.com/image.png'); - $expected = ''; - } - - /** - * Tests Html::prep_url() - * - * @test - */ - public function test_prep_url() - { - $output = Html::prep_url('google.com'); - $expected = 'http://google.com'; - $this->assertEquals($expected, $output); - - $output = Html::prep_url('google.com', 'https'); - $expected = 'https://google.com'; - $this->assertEquals($expected, $output); - } - - /** - * Tests Html::mail_to() - * - * @test - */ - public function test_mail_to() - { - $output = Html::mail_to('test@test.com'); - $expected = 'test@test.com'; - $this->assertEquals($expected, $output); - - $output = Html::mail_to('test@test.com', 'Email'); - $expected = 'Email'; - $this->assertEquals($expected, $output); - - $output = Html::mail_to('test@test.com', NULL, 'Test'); - $expected = 'test@test.com'; - $this->assertEquals($expected, $output); - - $output = Html::mail_to('test@test.com', 'Test', 'Test'); - $expected = 'Test'; - $this->assertEquals($expected, $output); - } - - /** - * Tests Html::doctype() - * - * @test - */ - public function test_doctype() - { - $output = Html::doctype(); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = Html::doctype('html5'); - $expected = ''; - $this->assertEquals($expected, $output); - - // Ensure static::$html5 is set - $doctype = Html::doctype('html5'); - $this->assertTrue(Html::$html5); - - // Ensure === false if doctype is invalid - $this->assertFalse(Html::doctype('shouldfail')); - } - - /** - * Tests Html::ul() & Html::ol() - * - * @test - */ - public function test_lists() - { - $list = array('one', 'two'); - - $output = Html::ul($list); - $expected = '
      '.PHP_EOL - .'
    • one
    • '.PHP_EOL - .'
    • two
    • '.PHP_EOL - .'
    '.PHP_EOL; - $this->assertEquals($expected, $output); - - $output = Html::ol($list); - $expected = '
      '.PHP_EOL - .'
    1. one
    2. '.PHP_EOL - .'
    3. two
    4. '.PHP_EOL - .'
    '.PHP_EOL; - $this->assertEquals($expected, $output); - } -} diff --git a/fuel/core/tests/image.php b/fuel/core/tests/image.php deleted file mode 100755 index d905761..0000000 --- a/fuel/core/tests/image.php +++ /dev/null @@ -1,24 +0,0 @@ -assertEquals($number.$ending, Inflector::ordinalize($number)); - } - - /** - * Test for Inflector::ordinalize() - * - * @test - */ - public function test_ordinalize_of_string() - { - $this->assertEquals('Foo', Inflector::ordinalize('Foo')); - } - - /** - * Test for Inflector::ascii() - * - * @test - */ - public function test_ascii() - { - $output = Inflector::ascii('Inglés'); - $expected = "Ingles"; - $this->assertEquals($expected, $output); - } - - /** - * Test for Inflector::camelize() - * - * @test - */ - public function test_camelize() - { - $output = Inflector::camelize('apples_and_oranges'); - $expected = 'ApplesAndOranges'; - $this->assertEquals($expected, $output); - } - - /** - * Test for Inflector::classify() - * - * @test - */ - public function test_classify() - { - $output = Inflector::classify('fuel_users'); - $expected = 'Fuel_User'; - $this->assertEquals($expected, $output); - } - - /** - * Test for Inflector::demodulize() - * - * @test - */ - public function test_demodulize() - { - $output = Inflector::demodulize('Uri::main()'); - $expected = 'main()'; - $this->assertEquals($expected, $output); - } - - /** - * Test for Inflector::denamespace() - * - * @test - */ - public function test_denamespace() - { - $this->assertEquals(Inflector::denamespace('Fuel\\SomeClass'), 'SomeClass'); - $this->assertEquals(Inflector::denamespace('\\SomeClass'), 'SomeClass'); - $this->assertEquals(Inflector::denamespace('SomeClass'), 'SomeClass'); - $this->assertEquals(Inflector::denamespace('SomeClass\\'), 'SomeClass'); - } - - /** - * Test for Inflector::foreign_key() - * - * @test - */ - public function test_foreign_key() - { - $output = Inflector::foreign_key('Inflector'); - $expected = 'inflector_id'; - $this->assertEquals($expected, $output); - - $output = Inflector::foreign_key('Inflector', false); - $expected = 'inflectorid'; - $this->assertEquals($expected, $output); - } - - /** - * Test for Inflector::foreign_key() - * - * @test - */ - public function test_foreign_key_with_model_prefx() - { - $this->assertEquals('inflector_id', Inflector::foreign_key('Model_Inflector')); - } - - /** - * Test for Inflector::friendly_title() - * - * @test - */ - public function test_friendly_title() - { - $output = Inflector::friendly_title('Fuel is a community driven PHP 5 web framework.'); - $expected = 'Fuel-is-a-community-driven-PHP-5-web-framework'; - $this->assertEquals($expected, $output); - } - - public function test_friendly_title_sep() - { - $output = Inflector::friendly_title('Fuel is a community driven PHP 5 web framework.', '_'); - $expected = 'Fuel_is_a_community_driven_PHP_5_web_framework'; - $this->assertEquals($expected, $output); - } - - public function test_friendly_title_lowercase() - { - $output = Inflector::friendly_title('Fuel is a community driven PHP 5 web framework.', '-', true); - $expected = 'fuel-is-a-community-driven-php-5-web-framework'; - $this->assertEquals($expected, $output); - } - - public function test_friendly_title_non_ascii() - { - $output = Inflector::friendly_title('وقود هو مجتمع مدفوعة إطار شبكة الإنترنت'); - $expected = ''; - $this->assertEquals($expected, $output); - } - - public function test_friendly_title_allow_non_ascii() - { - $output = Inflector::friendly_title('وقود هو مجتمع مدفوعة إطار شبكة الإنترنت', '-', false, true); - $expected = 'وقود-هو-مجتمع-مدفوعة-إطار-شبكة-الإنترنت'; - $this->assertEquals($expected, $output); - } - - /** - * Test for Inflector::humanize() - * - * @test - */ - public function test_humanize() - { - $output = Inflector::humanize('apples_and_oranges'); - $expected = 'Apples and oranges'; - $this->assertEquals($expected, $output); - } - - /** - * Test for Inflector::is_countable() - * - * @test - */ - public function test_is_countable() - { - $output = Inflector::is_countable('fish'); - $this->assertFalse($output); - - $output = Inflector::is_countable('apple'); - $this->assertTrue($output); - } - - /** - * Test for Inflector::pluralize() - * - * @test - */ - public function test_pluralize() - { - $output = Inflector::pluralize('apple'); - $expected = "apples"; - $this->assertEquals($expected, $output); - - $output = Inflector::pluralize('apple', 1); - $expected = "apple"; - $this->assertEquals($expected, $output); - } - - /** - * Test for Inflector::pluralize() - * - * @test - */ - public function test_pluralize_uncountable() - { - $this->assertEquals('equipment', Inflector::pluralize('equipment')); - } - - /** - * Test for Inflector::singularize() - * - * @test - */ - public function test_singularize() - { - $output = Inflector::singularize('apples'); - $expected = "apple"; - $this->assertEquals($expected, $output); - } - - /** - * Test for Inflector::singularize() - * - * @test - */ - public function test_singularize_uncountable() - { - $this->assertEquals('equipment', Inflector::singularize('equipment')); - } - - public function tableize_provider() - { - return array( - array('\\Model\\User', 'users'), - array('\\Model\\Person', 'people'), - array('\\Model\\Mouse', 'mice'), - array('\\Model\\Ox', 'oxen'), - array('\\Model\\Matrix', 'matrices'), - array('Model_User', 'users'), - ); - } - - /** - * Test for Inflector::tableize() - * - * @test - * @dataProvider tableize_provider - */ - public function test_tableize($class, $table) - { - $this->assertEquals(Inflector::tableize($class), $table); - } - - public function get_namespace_provider() - { - return array( - array('\\Model\\User', 'Model\\'), - array('\\Fuel\\Core\\Inflector', 'Fuel\\Core\\'), - array('Model_User', ''), - ); - } - - /** - * Test for Inflector::get_namespace() - * - * @test - * @dataProvider get_namespace_provider - */ - public function test_get_namespace($class, $namespace) - { - $this->assertEquals(Inflector::get_namespace($class), $namespace); - } - - /** - * Test for Inflector::underscore() - * - * @test - */ - public function test_underscore() - { - $output = Inflector::underscore('ApplesAndOranges'); - $expected = "apples_and_oranges"; - $this->assertEquals($expected, $output); - } -} diff --git a/fuel/core/tests/input.php b/fuel/core/tests/input.php deleted file mode 100755 index 456a3ad..0000000 --- a/fuel/core/tests/input.php +++ /dev/null @@ -1,24 +0,0 @@ - 'Bob')); - $expected = 'Hello there Bob!'; - $this->assertEquals($expected, $output); - } - - /** - * Test for Lang::get() - * - * @test - */ - public function test_line_invalid() - { - Lang::load('test'); - $output = Lang::get('non_existant_hello', array('name' => 'Bob')); - $expected = false; - $this->assertEquals($expected, $output); - } - - /** - * Test for Lang::set() - * - * @test - */ - public function test_set_return_true() - { - $output = Lang::set('testing_set_valid', 'Ahoy :name!'); - $this->assertNull($output); - } - - /** - * Test for Lang::set() - * - * @test - */ - public function test_set() - { - Lang::set('testing_set_valid', 'Ahoy :name!'); - $output = Lang::get('testing_set_valid', array('name' => 'Bob')); - $expected = 'Ahoy Bob!'; - $this->assertEquals($expected, $output); - } -} diff --git a/fuel/core/tests/migrate.php b/fuel/core/tests/migrate.php deleted file mode 100755 index b055d2f..0000000 --- a/fuel/core/tests/migrate.php +++ /dev/null @@ -1,24 +0,0 @@ -getMethod('get_connection'); - $method->setAccessible(true); - - $tester = new Model_Crud_Tester(); - $write = $method->invokeArgs($tester, array(true)); - $read = $method->invokeArgs($tester, array(false)); - - $this->assertEquals('read', $read); - $this->assertEquals('write', $write); - } -} - -class Model_Crud_Tester extends \Fuel\Core\Model_Crud -{ - static protected $_connection = "read"; - - static protected $_write_connection = "write"; -} diff --git a/fuel/core/tests/num.php b/fuel/core/tests/num.php deleted file mode 100755 index a962ee6..0000000 --- a/fuel/core/tests/num.php +++ /dev/null @@ -1,184 +0,0 @@ -assertEquals($expected, $output); - } - - /** - * @see Num::bytes - * @expectedException Exception - */ - public function test_bytes_exception() - { - $output = Num::bytes('invalid'); - } - - /** - * @see Num::format_bytes - */ - public function test_format_bytes() - { - $output = Num::format_bytes('204800'); - $expected = '200 KB'; - - $this->assertEquals($expected, $output); - - $output = Num::format_bytes('invalid'); - $this->assertFalse($output); - } - - /** - * @see Num::quantity - */ - public function test_quantity() - { - // Return the same - $output = Num::quantity('100'); - $expected = '100'; - - $this->assertEquals($expected, $output); - - $output = Num::quantity('7500'); - $expected = '8K'; - - $this->assertEquals($expected, $output); - - $output = Num::quantity('1500000'); - $expected = '2M'; - - $this->assertEquals($expected, $output); - - $output = Num::quantity('1000000000'); - $expected = '1B'; - - $this->assertEquals($expected, $output); - - // Get current localized decimal separator - $locale_conv = localeconv(); - $decimal_point = isset($locale_conv['decimal_point']) ? $locale_conv['decimal_point'] : '.'; - - $output = Num::quantity('7500', 1); - $expected = '7'.$decimal_point.'5K'; - - $this->assertEquals($expected, $output); - } - - /** - * @see Num::format - */ - public function test_format() - { - $output = Num::format('1234567890', '(000) 000-0000'); - $expected = '(123) 456-7890'; - - $this->assertEquals($expected, $output); - - $output = Num::format(null, '(000) 000-0000'); - $this->assertNull($output); - - $output = Num::format('1234567890', null); - $expected = '1234567890'; - - $this->assertEquals($expected, $output); - } - - /** - * @see Num::mask_string - */ - public function test_mask_string() - { - $output = Num::mask_string('1234567812345678', '**** - **** - **** - 0000', ' -'); - $expected = '**** - **** - **** - 5678'; - - $this->assertEquals($expected, $output); - - // Return the same - $output = Num::mask_string('1234567812345678'); - $expected = '1234567812345678'; - - $this->assertEquals($expected, $output); - } - - /** - * @see Num::format_phone - */ - public function test_format_phone() - { - $output = Num::format_phone('1234567890'); - $expected = '(123) 456-7890'; - - $this->assertEquals($expected, $output); - } - - /** - * @see Num::smart_format_phone - */ - public function test_smart_format_phone() - { - $output = Num::smart_format_phone('1234567'); - $expected = '123-4567'; - - $this->assertEquals($expected, $output); - - // Return the same - $output = Num::smart_format_phone('123456'); - $expected = '123456'; - - $this->assertEquals($expected, $output); - } - - /** - * @see Num::format_exp - */ - public function test_format_exp() - { - $output = Num::format_exp('1234'); - $expected = '12-34'; - - $this->assertEquals($expected, $output); - } - - /** - * @see Num::mask_credit_card - */ - public function test_mask_credit_card() - { - $output = Num::mask_credit_card('1234567812345678'); - $expected = '**** **** **** 5678'; - - $this->assertEquals($expected, $output); - } -} - -/* End of file num.php */ diff --git a/fuel/core/tests/pagination.php b/fuel/core/tests/pagination.php deleted file mode 100755 index 37955b2..0000000 --- a/fuel/core/tests/pagination.php +++ /dev/null @@ -1,758 +0,0 @@ -pathinfo = $_SERVER['PATH_INFO']; - $_SERVER['PATH_INFO'] = '/'.$uri; - - // set Request::$main - $this->request = \Request::forge($uri); - $rp = new \ReflectionProperty($this->request, 'main'); - $rp->setAccessible(true); - $rp->setValue($this->request, $this->request); - - // set Request::$active - $rp = new \ReflectionProperty($this->request, 'active'); - $rp->setAccessible(true); - $rp->setValue($this->request, $this->request); - } - - protected function setUp() - { - $this->old_base_url = Config::get('base_url'); - } - - public function tearDown() - { - // remove the fake uri - if (property_exists($this, 'pathinfo')) - { - $_SERVER['PATH_INFO'] = $this->pathinfo; - } - else - { - unset($_SERVER['PATH_INFO']); - } - - // reset Request::$main - $request = \Request::forge(); - $rp = new \ReflectionProperty($request, 'main'); - $rp->setAccessible(true); - $rp->setValue($request, false); - - // reset Request::$active - $rp = new \ReflectionProperty($request, 'active'); - $rp->setAccessible(true); - $rp->setValue($request, false); - - // ensure base_url is reset even if an exception occurs - Config::set('base_url', $this->old_base_url); - } - -/********************************** - * Tests for URI Segment Pagination - **********************************/ - - protected function set_uri_segment_config() - { - $this->config = array( - 'uri_segment' => 3, - 'pagination_url' => 'http://docs.fuelphp.com/welcome/index/', - 'total_items' => 100, - 'per_page' => 10, - 'wrapper' => "
    \n\t{pagination}\n
    \n", - - 'first' => "\n\t{link}\n\n", - 'first-marker' => "««", - 'first-link' => "\t\t{page}\n", - - 'first-inactive' => "", - 'first-inactive-link' => "", - - 'previous' => "\n\t{link}\n\n", - 'previous-marker' => "«", - 'previous-link' => "\t\t{page}\n", - - 'previous-inactive' => "\n\t{link}\n\n", - 'previous-inactive-link' => "\t\t{page}\n", - - 'regular' => "\n\t{link}\n\n", - 'regular-link' => "\t\t{page}\n", - - 'active' => "\n\t{link}\n\n", - 'active-link' => "\t\t{page}\n", - - 'next' => "\n\t{link}\n\n", - 'next-marker' => "»", - 'next-link' => "\t\t{page}\n", - - 'next-inactive' => "\n\t{link}\n\n", - 'next-inactive-link' => "\t\t{page}\n", - - 'last' => "\n\t{link}\n\n", - 'last-marker' => "»»", - 'last-link' => "\t\t{page}\n", - - 'last-inactive' => "", - 'last-inactive-link' => "", - ); - } - - public function test_uri_segment_auto_detect_pagination_url() - { - // set base_url - Config::set('base_url', 'http://docs.fuelphp.com/'); - // set Request::$main & $active - $this->set_request('welcome/index/5'); - - $this->set_uri_segment_config(); - $this->config['pagination_url'] = null; - $pagination = Pagination::forge(__METHOD__, $this->config); - - // set _make_link() accessible - $_make_link = new \ReflectionMethod($pagination, '_make_link'); - $_make_link->setAccessible(true); - - $test = $_make_link->invoke($pagination, 1); - $expected = 'http://docs.fuelphp.com/welcome/index/1'; - $this->assertEquals($expected, $test); - } - - public function test_uri_segment_set_pagination_url_after_forging_fail() - { - // set Request::$main & $active - $this->set_request('welcome/index/3'); - - $this->set_uri_segment_config(); - $pagination = Pagination::forge(__METHOD__, $this->config); - $pagination->pagination_url = 'http://example.com/page/'; - - // set _make_link() accessible - $_make_link = new \ReflectionMethod($pagination, '_make_link'); - $_make_link->setAccessible(true); - - // not enough segments in the URI to add the page number - $this->setExpectedException('RunTimeException'); - - $test = $_make_link->invoke($pagination, 1); - } - - public function test_uri_segment_set_pagination_url_after_forging_success() - { - // set Request::$main & $active - $this->set_request('welcome/index/3'); - - $this->set_uri_segment_config(); - $pagination = Pagination::forge(__METHOD__, $this->config); - $pagination->pagination_url = 'http://example.com/this/page/'; - - // set _make_link() accessible - $_make_link = new \ReflectionMethod($pagination, '_make_link'); - $_make_link->setAccessible(true); - - $test = $_make_link->invoke($pagination, 1); - $expected = 'http://example.com/this/page/1'; - $this->assertEquals($expected, $test); - } - - public function test_uri_segment_get_total_pages() - { - // set Request::$main & $active - $this->set_request('welcome/index/'); - - $this->set_uri_segment_config(); - $pagination = Pagination::forge(__METHOD__, $this->config); - $test = $pagination->total_pages; - $expected = 10; - $this->assertEquals($expected, $test); - } - - public function test_current_page_calculation_from_link() - { - // set Request::$main & $active - $this->set_request('welcome/index/4'); - - $this->set_uri_segment_config(); - - $config = array( - 'total_items' => 12, - 'per_page' => 3, - 'uri_segment' => 3, - ); - - $pagination = Pagination::forge(__METHOD__.'-1', $config); - $test = $pagination->current_page; - $expected = 4; - $this->assertEquals($expected, $test); - } - - public function test_current_page_calculation_from_config() - { - $this->set_request('welcome/index/6'); - - $config = array( - 'per_page' => 3, - 'total_items' => 12, - 'uri_segment' => 3, - 'current_page' => 4, - ); - - $pagination = Pagination::forge(__METHOD__.'-2', $config); - $test = $pagination->current_page; - $expected = 4; - $this->assertEquals($expected, $test); - } - - /** - * raw render - * - */ - public function test_pagination_raw_render() - { - // set Request::$main & $active - $this->set_request('welcome/index/5'); - - $this->set_uri_segment_config(); - $pagination = Pagination::forge(__METHOD__, $this->config); - - $expected = array( - 'previous' => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/4", - 'title' => "«", - 'type' => "previous", - ), - 0 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/3", - 'title' => 3, - 'type' => "regular", - ), - 1 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/4", - 'title' => 4, - 'type' => "regular", - ), - 2 => array( - 'uri' => "#", - 'title' => 5, - 'type' => "active", - ), - 3 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/6", - 'title' => 6, - 'type' => "regular", - ), - 4 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/7", - 'title' => 7, - 'type' => "regular", - ), - 'next' => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/6", - 'title' => "»", - 'type' => "next", - ), - ); - - // default link offset of 50%, active is the middle link - $test = $pagination->render(true); - $this->assertEquals($expected, $test); - - $expected = array( - 'previous' => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/4", - 'title' => "«", - 'type' => "previous", - ), - 0 => array( - 'uri' => "#", - 'title' => 5, - 'type' => "active", - ), - 1 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/6", - 'title' => 6, - 'type' => "regular", - ), - 2 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/7", - 'title' => 7, - 'type' => "regular", - ), - 3 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/8", - 'title' => 8, - 'type' => "regular", - ), - 4 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/9", - 'title' => 9, - 'type' => "regular", - ), - 'next' => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/6", - 'title' => "»", - 'type' => "next", - ), - ); - - $pagination->link_offset = 0; // 0%, active is the first link - $test = $pagination->render(true); - $this->assertEquals($expected, $test); - - $expected = array( - 'previous' => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/4", - 'title' => "«", - 'type' => "previous", - ), - 0 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/1", - 'title' => 1, - 'type' => "regular", - ), - 1 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/2", - 'title' => 2, - 'type' => "regular", - ), - 2 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/3", - 'title' => 3, - 'type' => "regular", - ), - 3 => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/4", - 'title' => 4, - 'type' => "regular", - ), - 4 => array( - 'uri' => "#", - 'title' => 5, - 'type' => "active", - ), - 'next' => array( - 'uri' => "http://docs.fuelphp.com/welcome/index/6", - 'title' => "»", - 'type' => "next", - ), - ); - - $pagination->link_offset = 100; // 100%, active is the last link - $test = $pagination->render(true); - $this->assertEquals($expected, $test); - } - - /** - * first page - * - */ - public function test_uri_segment_first_page() - { - // set Request::$main & $active - $this->set_request('welcome/index/'); - - $this->set_uri_segment_config(); - $pagination = Pagination::forge(__METHOD__, $this->config); - - $output = $pagination->previous(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = $pagination->pages_render(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = '12345'; - $this->assertEquals($expected, $output); - - $output = $pagination->next(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = $pagination->render(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - } - - /** - * last page - * - */ - public function test_uri_segment_nextlink_inactive() - { - // set Request::$main & $active - $this->set_request('welcome/index/11'); - - $this->set_uri_segment_config(); - $pagination = Pagination::forge(__METHOD__, $this->config); - - $output = $pagination->next(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - - $this->set_request('welcome/index/10'); - - $output = $pagination->pages_render(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = '678910'; - $this->assertEquals($expected, $output); - - $output = $pagination->previous(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = $pagination->render(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - } - - /** - * total page is 1 - * - */ - public function test_uri_segment_total_page_is_one() - { - // set Request::$main & $active - $this->set_request('welcome/index/10'); - - $this->set_uri_segment_config(); - $this->config['per_page'] = 1000; - - $pagination = Pagination::forge(__METHOD__, $this->config); - - $output = $pagination->pages_render(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = $pagination->render(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - } - - public function test_uri_segment_make_link_with_no_query_string_ending_page_number() - { - // set Request::$main & $active - $this->set_request('welcome/index/10'); - $this->set_uri_segment_config(); - $this->config['pagination_url'] = 'http://docs.fuelphp.com/welcome/index/55'; - - $pagination = Pagination::forge(__METHOD__, $this->config); - - // set _make_link() accessible - $_make_link = new \ReflectionMethod($pagination, '_make_link'); - $_make_link->setAccessible(true); - - $test = $_make_link->invoke($pagination, 1); - $expected = 'http://docs.fuelphp.com/welcome/index/1'; - $this->assertEquals($expected, $test); - - $test = $_make_link->invoke($pagination, 99); - $expected = 'http://docs.fuelphp.com/welcome/index/99'; - $this->assertEquals($expected, $test); - } - - public function test_uri_segment_make_link_with_no_query_string_ending_slash() - { - // set Request::$main & $active - $this->set_request('welcome/index/'); - $this->set_uri_segment_config(); - $this->config['pagination_url'] = 'http://docs.fuelphp.com/welcome/index/'; - - $pagination = Pagination::forge(__METHOD__, $this->config); - - // set _make_link() accessible - $_make_link = new \ReflectionMethod($pagination, '_make_link'); - $_make_link->setAccessible(true); - - $test = $_make_link->invoke($pagination, 1); - $expected = 'http://docs.fuelphp.com/welcome/index/1'; - $this->assertEquals($expected, $test); - - $test = $_make_link->invoke($pagination, 99); - $expected = 'http://docs.fuelphp.com/welcome/index/99'; - $this->assertEquals($expected, $test); - } - - public function test_uri_segment_make_link_with_query_string_ending_page_number() - { - // set Request::$main & $active - $this->set_request('welcome/index/55?foo=bar&fuel[]=php1&fuel[]=php2&'); - $this->set_uri_segment_config(); - - // no define pagination_url - $this->config['pagination_url'] = null; - - $pagination = Pagination::forge(__METHOD__, $this->config); - - // set _make_link() accessible - $_make_link = new \ReflectionMethod($pagination, '_make_link'); - $_make_link->setAccessible(true); - - $test = $_make_link->invoke($pagination, 1); - $expected = '/welcome/index/1?foo=bar&fuel%5B0%5D=php1&fuel%5B1%5D=php2'; - $this->assertEquals($expected, $test); - - $test = $_make_link->invoke($pagination, 99); - $expected = '/welcome/index/99?foo=bar&fuel%5B0%5D=php1&fuel%5B1%5D=php2'; - $this->assertEquals($expected, $test); - } - - public function test_uri_segment_make_link_with_query_string_ending_slash() - { - // set Request::$main & $active - $this->set_request('welcome/index/?foo=bar&fuel[]=php1&fuel[]=php2&'); - $this->set_uri_segment_config(); - - // no define pagination_url - $this->config['pagination_url'] = null; - - $pagination = Pagination::forge(__METHOD__, $this->config); - - // set _make_link() accessible - $_make_link = new \ReflectionMethod($pagination, '_make_link'); - $_make_link->setAccessible(true); - - $test = $_make_link->invoke($pagination, 1); - $expected = '/welcome/index/1?foo=bar&fuel%5B0%5D=php1&fuel%5B1%5D=php2'; - $this->assertEquals($expected, $test); - - $test = $_make_link->invoke($pagination, 99); - $expected = '/welcome/index/99?foo=bar&fuel%5B0%5D=php1&fuel%5B1%5D=php2'; - $this->assertEquals($expected, $test); - } - -/*********************************** - * Tests for Query String Pagination - ***********************************/ - - protected function set_query_string_config() - { - $this->config = array( - 'uri_segment' => 'p', - 'pagination_url' => 'http://docs.fuelphp.com/', - 'total_items' => 100, - 'per_page' => 10, - 'wrapper' => "
    \n\t{pagination}\n
    \n", - - 'first' => "\n\t{link}\n\n", - 'first-marker' => "««", - 'first-link' => "\t\t{page}\n", - - 'first-inactive' => "", - 'first-inactive-link' => "", - - 'previous' => "\n\t{link}\n\n", - 'previous-marker' => "«", - 'previous-link' => "\t\t{page}\n", - - 'previous-inactive' => "\n\t{link}\n\n", - 'previous-inactive-link' => "\t\t{page}\n", - - 'regular' => "\n\t{link}\n\n", - 'regular-link' => "\t\t{page}\n", - - 'active' => "\n\t{link}\n\n", - 'active-link' => "\t\t{page}\n", - - 'next' => "\n\t{link}\n\n", - 'next-marker' => "»", - 'next-link' => "\t\t{page}\n", - - 'next-inactive' => "\n\t{link}\n\n", - 'next-inactive-link' => "\t\t{page}\n", - - 'last' => "\n\t{link}\n\n", - 'last-marker' => "»»", - 'last-link' => "\t\t{page}\n", - - 'last-inactive' => "", - 'last-inactive-link' => "", - ); - } - - public function test_query_string_auto_detect_pagination_url() - { - // set base_url - Config::set('base_url', 'http://docs.fuelphp.com/'); - // set Request::$main & $active - $this->set_request('/'); - - $this->set_query_string_config(); - $this->config['pagination_url'] = null; - $pagination = Pagination::forge(__METHOD__, $this->config); - - // set _make_link() accessible - $_make_link = new \ReflectionMethod($pagination, '_make_link'); - $_make_link->setAccessible(true); - - $test = $_make_link->invoke($pagination, 1); - $expected = 'http://docs.fuelphp.com/?p=1'; - $this->assertEquals($expected, $test); - } - - public function test_query_string_get_total_pages() - { - // set Request::$main & $active - $this->set_request('/'); - - $this->set_query_string_config(); - $pagination = Pagination::forge(__METHOD__, $this->config); - $test = $pagination->total_pages; - $expected = 10; - $this->assertEquals($expected, $test); - } - - /** - * first page - * - */ - public function test_query_string_first_page() - { - // set Request::$main & $active - $this->set_request('/'); - - $this->set_query_string_config(); - $pagination = Pagination::forge(__METHOD__, $this->config); - $pagination->current_page = 1; - - $output = $pagination->previous(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = $pagination->pages_render(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = '12345'; - $this->assertEquals($expected, $output); - - $output = $pagination->next(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - } - - /** - * last page - * - */ - public function test_query_string_nextlink_inactive() - { - // set Request::$main & $active - $this->set_request('/'); - - $this->set_query_string_config(); - $pagination = Pagination::forge(__METHOD__, $this->config); - $pagination->current_page = 10; - - $output = $pagination->next(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - - $output = $pagination->pages_render(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = '678910'; - $this->assertEquals($expected, $output); - - $output = $pagination->previous(); - $output = str_replace(array("\n", "\t"), "", $output); - $expected = ''; - $this->assertEquals($expected, $output); - } - - public function test_query_string_make_link_by_request() - { - // set Request::$main & $active - $this->set_request('welcome/index/?foo=bar&fuel[]=php1&fuel[]=php2&p=40'); - - $this->set_query_string_config(); - $this->config['pagination_url'] = null; - - $pagination = Pagination::forge(__METHOD__, $this->config); - - // set _make_link() accessible - $_make_link = new \ReflectionMethod($pagination, '_make_link'); - $_make_link->setAccessible(true); - - $test = $_make_link->invoke($pagination, 1); - $expected = 'welcome/index/?foo=bar&fuel%5B0%5D=php1&fuel%5B1%5D=php2&p=1'; - $this->assertEquals($expected, $test); - - $test = $_make_link->invoke($pagination, 99); - $expected = 'welcome/index/?foo=bar&fuel%5B0%5D=php1&fuel%5B1%5D=php2&p=99'; - $this->assertEquals($expected, $test); - } - - public function test_query_string_make_link_by_pagination_url() - { - // set Request::$main & $active - $this->set_request('welcome/index/?foo=bar&fuel[]=php1&fuel[]=php2&p=40'); - - $this->set_query_string_config(); - $this->config['pagination_url'] = 'http://docs.fuelphp.com/?foo=bar&fuel[]=php1&fuel[]=php2'; - - $pagination = Pagination::forge(__METHOD__, $this->config); - - // set _make_link() accessible - $_make_link = new \ReflectionMethod($pagination, '_make_link'); - $_make_link->setAccessible(true); - - $test = $_make_link->invoke($pagination, 1); - $expected = 'http://docs.fuelphp.com/?foo=bar&fuel%5B0%5D=php1&fuel%5B1%5D=php2&p=1'; - $this->assertEquals($expected, $test); - - $test = $_make_link->invoke($pagination, 99); - $expected = 'http://docs.fuelphp.com/?foo=bar&fuel%5B0%5D=php1&fuel%5B1%5D=php2&p=99'; - $this->assertEquals($expected, $test); - } - - public function test_query_string_make_link_by_pagination_url_include_page_number() - { - // set Request::$main & $active - $this->set_request('welcome/index/?foo=bar&fuel[]=php1&fuel[]=php2&p=40'); - - $this->set_query_string_config(); - $this->config['pagination_url'] = 'http://docs.fuelphp.com/?foo=bar&p=123&fuel[]=php1&fuel[]=php2'; - - $pagination = Pagination::forge(__METHOD__, $this->config); - - // set _make_link() accessible - $_make_link = new \ReflectionMethod($pagination, '_make_link'); - $_make_link->setAccessible(true); - - $test = $_make_link->invoke($pagination, 1); - $expected = 'http://docs.fuelphp.com/?foo=bar&p=1&fuel%5B0%5D=php1&fuel%5B1%5D=php2'; - $this->assertEquals($expected, $test); - - $test = $_make_link->invoke($pagination, 99); - $expected = 'http://docs.fuelphp.com/?foo=bar&p=99&fuel%5B0%5D=php1&fuel%5B1%5D=php2'; - $this->assertEquals($expected, $test); - } -} diff --git a/fuel/core/tests/profiler.php b/fuel/core/tests/profiler.php deleted file mode 100755 index 7e58691..0000000 --- a/fuel/core/tests/profiler.php +++ /dev/null @@ -1,24 +0,0 @@ -set_header($name, $value); - $this->assertEquals($value, $response->headers[$name]); - - // update previously added header value - $new_value = 'new header value'; - $response->set_header($name, $new_value); - $this->assertEquals($new_value, $response->headers[$name]); - - // insert name and value array into header values - $response->set_header($name, $value, false); - $this->assertContains(array($name, $value), $response->headers); - } - - /** - * Tests Reponse get_header - * @test - */ - public function test_get_header() { - $response = Response::forge(); - - // execute without parameter - $this->assertEquals($response->headers, $response->get_header()); - - // get not existing header value - $this->assertNull($response->get_header('test')); - - // get existing header value - $name = 'name'; - $value = 'value'; - $response->set_header($name, $value); - $this->assertEquals($value, $response->get_header($name)); - } - - /** - * Test body - * @test - */ - public function test_body() { - $response = Response::forge(); - - // execute without parameter and check initial value - $this->assertNull($response->body()); - - // execute with parameter - $value = 'body value'; - $result = $response->body($value); - $this->assertEquals(get_class($result), get_class($response)); - - // execute without parameter and check updated value - $this->assertEquals($value, $response->body()); - } - - /** - * Test Response __toString - * @test - */ - public function test___toString() { - $response = Response::forge(); - - // check when body is null - $this->assertTrue(is_string($response->__toString())); - $this->assertSame((string) null, $response->__toString()); - // check when body is not null - $value = 12345; - $response->body($value); - $this->assertTrue(is_string($response->__toString())); - $this->assertSame((string) $value, $response->__toString()); - - $value = '54321'; - $response->body($value); - $this->assertTrue(is_string($response->__toString())); - $this->assertSame($value, $response->__toString()); - } -} diff --git a/fuel/core/tests/route.php b/fuel/core/tests/route.php deleted file mode 100755 index dead9d0..0000000 --- a/fuel/core/tests/route.php +++ /dev/null @@ -1,24 +0,0 @@ -assertEquals($controller, $match->controller); - $this->assertEquals($action, $match->action); - $this->assertEquals(array(), $match->method_params); - } - - public function test_add_route_and_router_name() - { - $path = 'testing/route'; - $options = null; - $prepend = false; - $case_sensitive = null; - Router::add($path, $options, $prepend, $case_sensitive); - - $this->assertEquals($path, Router::$routes[$path]->path); - $this->assertEquals($path, Router::$routes[$path]->name); - - Router::delete($path); - } - - public function test_add_route_and_router_option_name() - { - $path = 'testing/route'; - $name = 'option_name'; - $options = array('name' => $name); - $prepend = false; - $case_sensitive = null; - Router::add($path, $options, $prepend, $case_sensitive); - - $this->assertEquals($path, Router::$routes[$name]->path); - $this->assertEquals($name, Router::$routes[$name]->name); - - Router::delete($name); - } -} diff --git a/fuel/core/tests/router/mock.php b/fuel/core/tests/router/mock.php deleted file mode 100755 index 1c0077a..0000000 --- a/fuel/core/tests/router/mock.php +++ /dev/null @@ -1,48 +0,0 @@ -assertEquals($expected, $output); - } - - /** - * Tests Security::htmlentities() - * - * @test - */ - public function test_htmlentities_singlequote() - { - $output = Security::htmlentities("'"); - $expected = '''; - $this->assertEquals($expected, $output); - } - - /** - * Tests Security::htmlentities() - * - * @test - */ - public function test_htmlentities_charactor_references_no_double_encode() - { - $output = Security::htmlentities('You must write & as &'); - $expected = 'You must write & as &'; - $this->assertEquals($expected, $output); - } - - /** - * Tests Security::htmlentities() - * - * @test - */ - public function test_htmlentities_charactor_references_double_encode() - { - $config = \Config::get('security.htmlentities_double_encode'); - \Config::set('security.htmlentities_double_encode', true); - - $output = Security::htmlentities('You must write & as &'); - $expected = 'You must write & as &amp;'; - $this->assertEquals($expected, $output); - - \Config::set('security.htmlentities_double_encode', $config); - } - - /** - * Tests Security::htmlentities() - * - * @test - */ - public function test_htmlentities_double_encode() - { - $output = Security::htmlentities('"H&M"'); - $output = Security::htmlentities($output); - $expected = '"H&M"'; - $this->assertEquals($expected, $output); - } - - /** - * Tests Security::clean() - * - * @test - */ - public function test_clean() - { - // test correct recursive cleaning - $input = array( - array(' level1 '), - array( - array(' level2 '), - array( - array(' level3 '), - array( - array(' level4 '), - ), - ), - ), - ); - - $expected = array( - array('level1'), - array( - array('level2'), - array( - array('level3'), - array( - array('level4'), - ), - ), - ), - ); - - $output = Security::clean($input, array('trim')); - $this->assertEquals($expected, $output); - } - -} diff --git a/fuel/core/tests/session.php b/fuel/core/tests/session.php deleted file mode 100755 index 36ccf97..0000000 --- a/fuel/core/tests/session.php +++ /dev/null @@ -1,24 +0,0 @@ -assertEquals($expected, $output); - } - - /** - * Test for Str::truncate() - * - * @test - * @dataProvider truncate_provider - */ - public function test_truncate_custom_continuation($limit, $string) - { - $output = Str::truncate($string, $limit, '..'); - $expected = 'Lorem ipsum dol..'; - $this->assertEquals($expected, $output); - } - - /** - * Test for Str::truncate() - * - * @test - * @dataProvider truncate_provider - */ - public function test_truncate_not_html($limit, $string) - { - $string = '

    '.$string.'

    '; - - $output = Str::truncate($string, $limit, '...', false); - $expected = '

    Lorem ipsum...'; - $this->assertEquals($expected, $output); - } - - /** - * Test for Str::truncate() - * - * @test - * @dataProvider truncate_provider - */ - public function test_truncate_is_html($limit, $string) - { - $string = '

    '.$string.'

    '; - - $output = Str::truncate($string, $limit, '...', true); - $expected = '

    Lorem ipsum dol...

    '; - $this->assertEquals($expected, $output); - } - - /** - * Test for Str::truncate() - * - * @test - * @dataProvider truncate_provider - */ - public function test_truncate_multiple_tags($limit, $string) - { - $limit = 400; - $string = '

    '.$string.'

    '; - - $output = Str::truncate($string, $limit, '...', true); - $this->assertEquals($string, $output); - } - - /** - * Test for Str::increment() - * - * @test - */ - public function test_increment() - { - $values = array('valueA', 'valueB', 'valueC'); - - for ($i = 0; $i < count($values); $i ++) - { - $output = Str::increment($values[$i], $i); - $expected = $values[$i].'_'.$i; - - $this->assertEquals($expected, $output); - } - } - - /** - * Test for Str::lower() - * - * @test - */ - public function test_lower() - { - $output = Str::lower('HELLO WORLD'); - $expected = "hello world"; - - $this->assertEquals($expected, $output); - } - - /** - * Test for Str::upper() - * - * @test - */ - public function test_upper() - { - $output = Str::upper('hello world'); - $expected = "HELLO WORLD"; - - $this->assertEquals($expected, $output); - } - - /** - * Test for Str::lcfirst() - * - * @test - */ - public function test_lcfirst() - { - $output = Str::lcfirst('Hello World'); - $expected = "hello World"; - - $this->assertEquals($expected, $output); - } - - /** - * Test for Str::ucfirst() - * - * @test - */ - public function test_ucfirst() - { - $output = Str::ucfirst('hello world'); - $expected = "Hello world"; - - $this->assertEquals($expected, $output); - } - - /** - * Test for Str::ucwords() - * - * @test - */ - public function test_ucwords() - { - $output = Str::ucwords('hello world'); - $expected = "Hello World"; - - $this->assertEquals($expected, $output); - } - - /** - * Test for Str::random() - * - * @test - */ - public function test_random() - { - // testing length - $output = Str::random('alnum', 34); - $this->assertEquals(34, strlen($output)); - - // testing alnum - $output = Str::random('alnum', 15); - $this->assertTrue(ctype_alnum($output)); - - // testing numeric - $output = Str::random('numeric', 20); - $this->assertTrue(ctype_digit($output)); - - // testing alpha - $output = Str::random('alpha', 35); - $this->assertTrue(ctype_alpha($output)); - - // testing nozero - $output = Str::random('nozero', 22); - $this->assertFalse(strpos($output, '0')); - } - - /** - * Test for Str::is_json() - * - * @test - */ - public function test_is_json() - { - $values = array('fuelphp','is' => array('awesome' => true)); - - $string = json_encode($values); - $this->assertTrue(Str::is_json($string)); - - $string = serialize($values); - $this->assertFalse(Str::is_json($string)); - } - - /** - * Test for Str::is_xml() - * - * @test - * @requires extension libxml - */ - public function test_is_xml() - { - $valid_xml = ' - - - - - - - - '; - - $invalid_xml = ' - - - - - - - '; - - $this->assertTrue(Str::is_xml($valid_xml)); - $this->assertFalse(Str::is_xml($invalid_xml)); - } - - /** - * Test for Str::is_serialized() - * - * @test - */ - public function test_is_serialized() - { - $values = array('fuelphp','is' => array('awesome' => true)); - - $string = json_encode($values); - $this->assertFalse(Str::is_serialized($string)); - - $string = serialize($values); - $this->assertTrue(Str::is_serialized($string)); - } - - /** - * Test for Str::is_html() - * - * @test - */ - public function test_is_html() - { - $html = '
    FuelPHP is a simple, flexible, community driven PHP 5.3 web framework based on the best ideas of other frameworks with a fresh start.

    '; - $simple_string = strip_tags($html); - - $this->assertTrue(Str::is_html($html)); - $this->assertFalse(Str::is_html($simple_string)); - } - - /** - * Test for Str::starts_with() - * - * @test - */ - public function test_starts_with() - { - $string = 'HELLO WORLD'; - - $output = Str::starts_with($string, 'HELLO'); - $this->assertTrue($output); - - $output = Str::starts_with($string, 'hello'); - $this->assertFalse($output); - - $output = Str::starts_with($string, 'hello', true); - $this->assertTrue($output); - } - - /** - * Test for Str::ends_with() - * - * @test - */ - public function test_ends_with() - { - $string = 'HELLO WORLD'; - - $output = Str::ends_with($string, 'WORLD'); - $this->assertTrue($output); - - $output = Str::ends_with($string, 'world'); - $this->assertFalse($output); - - $output = Str::ends_with($string, 'world', true); - $this->assertTrue($output); - } - - /** - * Test for Str::alternator() - * - * @test - */ - public function test_alternator() - { - $alt = Str::alternator('one', 'two', 'three'); - - $output = $alt(); - $expected = 'one'; - $this->assertEquals($output, $expected); - - $output = $alt(false); - $expected = 'two'; - $this->assertEquals($output, $expected); - - $output = $alt(); - $expected = 'two'; - $this->assertEquals($output, $expected); - - $output = $alt(); - $expected = 'three'; - $this->assertEquals($output, $expected); - - $output = $alt(); - $expected = 'one'; - $this->assertEquals($output, $expected); - } - -} diff --git a/fuel/core/tests/testcase.php b/fuel/core/tests/testcase.php deleted file mode 100755 index 91e8387..0000000 --- a/fuel/core/tests/testcase.php +++ /dev/null @@ -1,24 +0,0 @@ -old_url_suffix = Config::get('url_suffix'); - $this->old_index_file = Config::get('index_file'); - $this->old_base_url = Config::get('base_url'); - } - - public function tearDown() - { - Config::set('url_suffix', $this->old_url_suffix); - Config::set('index_file', $this->old_index_file); - Config::set('base_url', $this->old_base_url); - } - - /** - * Tests Uri::create() - * - * @test - */ - public function test_create() - { - Config::set('url_suffix', ''); - - $prefix = Uri::create(''); - - Config::set('index_file', 'index.php'); - $output = Uri::create('controller/method'); - $expected = $prefix."index.php/controller/method"; - $this->assertEquals($expected, $output); - - Config::set('index_file', ''); - - $output = Uri::create('controller/method'); - $expected = $prefix."controller/method"; - $this->assertEquals($expected, $output); - - $output = Uri::create('controller/:some', array('some' => 'thing', 'and' => 'more'), array('what' => ':and')); - $expected = $prefix."controller/thing?what=more"; - $this->assertEquals($expected, $output); - - Config::set('url_suffix', '.html'); - - $output = Uri::create('controller/method'); - $expected = $prefix."controller/method.html"; - $this->assertEquals($expected, $output); - - $output = Uri::create('controller/:some', array('some' => 'thing', 'and' => 'more'), array('what' => ':and')); - $expected = $prefix."controller/thing.html?what=more"; - $this->assertEquals($expected, $output); - - $output = Uri::create('http://example.com/controller/:some', array('some' => 'thing', 'and' => 'more'), array('what' => ':and')); - $expected = "http://example.com/controller/thing.html?what=more"; - $this->assertEquals($expected, $output); - - $output = Uri::create('http://example.com/controller/:some', array('some' => 'thing', 'and' => 'more'), array('what' => ':and'), true); - $expected = "https://example.com/controller/thing.html?what=more"; - $this->assertEquals($expected, $output); - - $output = Uri::create('https://example.com/controller/:some', array('some' => 'thing', 'and' => 'more'), array('what' => ':and'), false); - $expected = "http://example.com/controller/thing.html?what=more"; - $this->assertEquals($expected, $output); - - } - - /** - * Tests Uri::base() - * - * @test - */ - public function test_base() - { - Config::set('base_url', null); - Config::set('index_file', false); - - $output = Uri::base(); - $expected = null; - $this->assertEquals($expected, $output); - - Config::set('base_url', 'http://example.com/'); - Config::set('index_file', 'index.php'); - - $output = Uri::base(); - $expected = 'http://example.com/index.php/'; - $this->assertEquals($expected, $output); - - $output = Uri::base(false); - $expected = 'http://example.com/'; - $this->assertEquals($expected, $output); - } - - /** - * Tests Uri::current() - * - * @test - */ - public function test_current() - { - $output = Uri::current(); - $expected = Uri::create(); - $this->assertEquals($expected, $output); - } - - /** - * Tests Uri::build_query_string() - * - * @test - */ - public function test_build_query_string() - { - $output = Uri::build_query_string(array('varA' => 'varA'), 'varB', array('varC' => 'varC')); - $expected = "varA=varA&varB=1&varC=varC"; - $this->assertEquals($expected, $output); - } - - /** - * Tests Uri::update_query_string() - * - * @test - */ - public function test_update_query_string() - { - Config::set('base_url', 'http://example.com/test'); - Config::set('index_file', null); - Config::set('url_suffix', ''); - $_GET = array('one' => 1, 'two' => 2); - - $output = Uri::update_query_string(array('three' => 3)); - $expected = 'http://example.com/test?one=1&two=2&three=3'; - $this->assertEquals($expected, $output); - - $output = Uri::update_query_string(array('two' => 3)); - $expected = 'http://example.com/test?one=1&two=3'; - $this->assertEquals($expected, $output); - - $output = Uri::update_query_string(array('four' => 4), 'http://localhost/controller'); - $expected = 'http://localhost/controller?four=4'; - $this->assertEquals($expected, $output); - - $output = Uri::update_query_string('three', 3, true); - $expected = 'https://example.com/test?one=1&two=2&three=3'; - $this->assertEquals($expected, $output); - } -} diff --git a/fuel/core/tests/validation.php b/fuel/core/tests/validation.php deleted file mode 100755 index 7ad8094..0000000 --- a/fuel/core/tests/validation.php +++ /dev/null @@ -1,911 +0,0 @@ - 'bar', - 'bar' => 'foo', - 'boo' => 'bar', - 'cat' => '', - 'dog' => '245abc', - 'php' => 1, - 'sky' => 'blue', - 'one' => 'john@doe.com', - 'two' => 'john@doe.com, jane@doe.com', - 'owt' => 'john@doe.com; jane@doe.com', - 'six' => 6, - 'ten' => 10, - 'dns' => '127.0.0.1', - 'snd' => '127.0.0', - 'url' => 'http://www.google.com', - 'gender' => 'M', - ), - ), - ); - } - - /** - * Validation: required - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_required_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('foo', 'Foo', 'required'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: required - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_required_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('cat', 'Cat', 'required'); - $val->run($input); - - $output = $val->error('cat', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_value - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_match_value_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('foo', 'Foo', 'match_value[bar]'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_value - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_match_value_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('foo', 'Foo', "match_value['foo']"); - $val->run($input); - - $output = $val->error('foo', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_value (strict) - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_match_value_strict_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('php', 'PHP', '')->add_rule('match_value', 1, 1); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_value (strict) - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_match_value_strict_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('php', 'PHP', '')->add_rule('match_value', '1', 1); - $val->run($input); - - $output = $val->error('php', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_collection - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_match_collection_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('gender', 'Gender', 'match_collection[M,F]'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_collection - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_match_collection_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('gender', 'Gender', 'match_collection["M,F"]'); - $val->run($input); - - $output = $val->error('gender', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_collection (strict) - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_match_collection_strict_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('gender', 'Gender', '')->add_rule('match_collection', array('M', 'F'), true); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_collection (strict) - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_match_collection_strict_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('gender', 'Gender', '')->add_rule('match_collection', array('m', 'f'), true); - $val->run($input); - - $output = $val->error('gender', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_pattern - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_match_pattern_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('dog', 'Dog', '')->add_rule('match_pattern', '/\d{3}\w{3}/'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_pattern - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_match_pattern_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('dog', 'Dog', '')->add_rule('match_pattern', '/^\d{2}[abc]{3}/'); - $val->run($input); - - $output = $val->error('dog', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_field - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_match_field_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('foo', 'Foo', 'valid_string'); - $val->add_field('boo', 'Boo', 'match_field[foo]'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: match_field - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_match_field_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('bar', 'Bar', 'valid_string'); - $val->add_field('boo', 'Boo', 'match_field[bar]'); - $val->run($input); - - $output = $val->error('boo', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: min_length - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_min_length_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('boo', 'Boo', 'min_length[2]'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: min_length - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_min_length_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('boo', 'Boo', 'min_length[4]'); - $val->run($input); - - $output = $val->error('boo', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: max_length - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_max_length_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('boo', 'Boo', 'max_length[4]'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: max_length - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_max_length_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('boo', 'Boo', 'max_length[2]'); - $val->run($input); - - $output = $val->error('boo', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: exact_length - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_exact_length_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('boo', 'Boo', 'exact_length[3]'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: exact_length - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_exact_length_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('boo', 'Boo', 'max_length[2]'); - $val->run($input); - - $output = $val->error('boo', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: valid_email - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_valid_email_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('one', 'Email', 'valid_email'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: valid_email - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_valid_email_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('boo', 'Email', 'valid_email'); - $val->run($input); - - $output = $val->error('boo', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: valid_emails - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_valid_emails_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('two', 'Emails', 'valid_emails'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: valid_emails (different separator) - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_valid_emails_separator_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add('owt', 'Emails')->add_rule('valid_emails', ';'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: valid_emails - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_valid_emails_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('boo', 'Email', 'valid_emails'); - $val->run($input); - - $output = $val->error('boo', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: valid_url - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_valid_url_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('url', 'Url', 'valid_url'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: valid_url - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_valid_url_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('boo', 'Url', 'valid_url'); - $val->run($input); - - $output = $val->error('boo', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: valid_ip - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_valid_ip_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('dns', 'IP', 'valid_ip'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: valid_ip - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_valid_ip_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('snd', 'IP', 'valid_ip'); - $val->run($input); - - $output = $val->error('snd', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: numeric_min - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_numeric_min_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('six', 'Number', 'numeric_min[4]'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: numeric_min - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_numeric_min_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('six', 'Number', 'numeric_min[8]'); - $val->run($input); - - $output = $val->error('six', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: numeric_max - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_numeric_max_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('ten', 'Number', 'numeric_max[11]'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: numeric_max - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_numeric_max_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('ten', 'Number', 'numeric_max[8]'); - $val->run($input); - - $output = $val->error('ten', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: numeric_between - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_numeric_between_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('ten', 'Number', 'numeric_between[9,11]'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: numeric_between - * Expecting: failure - * - * @dataProvider form_provider - */ - public function test_validation_numeric_between_failure($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('ten', 'Number', 'numeric_between[7,8]'); - $val->run($input); - - $output = $val->error('ten', false) ? true : false; - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: required_with - * Expecting: success - * - * @dataProvider form_provider - */ - public function test_validation_required_with_success($input) - { - $val = Validation::forge(__FUNCTION__); - $val->add_field('foo', 'Foo', 'valid_string'); - $val->add_field('bar', 'Bar', 'required_with[foo]'); - - $output = $val->run($input); - $expected = true; - - $this->assertEquals($expected, $output); - } - - /** - * Validation: valid_string numeric - * Expecting: success - */ - public function test_validation_valid_string_numeric_success() - { - $post = array( - 'f1' => '123456', - ); - - $val = Validation::forge(__FUNCTION__); - $val->add('f1', 'F1')->add_rule('valid_string', 'numeric'); - $test = $val->run($post); - $expected = true; - - $this->assertEquals($expected, $test); - } - - /** - * Validation: valid_string numeric - * Expecting: failure - */ - public function test_validation_valid_string_numeric_failure() - { - $post = array( - 'f1' => 'a123456', - ); - - $val = Validation::forge(__FUNCTION__); - $val->add('f1', 'F1')->add_rule('valid_string', 'numeric'); - $test = $val->run($post); - $expected = false; - - $this->assertEquals($expected, $test); - } - - /** - * Validation: valid_string alpha,numeric - * Expecting: failure - */ - public function test_validation_valid_string_multiple_flags_error_message_add_rule() { - $post = array( - 'f1' => '123 abc', - ); - - $val = Validation::forge(__FUNCTION__); - $val->add('f1', 'F1')->add_rule('valid_string', array('alpha', 'numeric')); - $val->set_message('valid_string', 'The valid string rule :rule(:param:1) failed for field :label'); - $val->run($post); - - $test = $val->error('f1')->get_message(); - $expected = 'The valid string rule valid_string(alpha, numeric) failed for field F1'; - - $this->assertEquals($expected, $test); - } - - /** - * Validation: valid_string alpha,numeric - * Expecting: failure - */ - public function test_validation_valid_string_multiple_flags_error_message_add_field() { - $post = array( - 'f1' => '123 abc', - ); - - $val = Validation::forge(__FUNCTION__); - $val->add_field('f1', 'F1', 'valid_string[alpha,numeric]'); - $val->set_message('valid_string', 'The valid string rule :rule(:param:1) failed for field :label'); - $val->run($post); - - $test = $val->error('f1')->get_message(); - $expected = 'The valid string rule valid_string(alpha, numeric) failed for field F1'; - - $this->assertEquals($expected, $test); - } - - /** - * Validation: valid_date - * Expecting: success - */ - public function test_validation_valid_date_none_arguments() { - $post = array( - 'f1' => '2013/02/26', - 'f2' => '2013-02-26', - 'f3' => '2013/2/26 12:0:33', - 'f4' => '19 Jan 2038 03:14:07', - 'f5' => 'Sat Mar 10 17:16:18 MST 2001', - 'f6' => '', - ); - - $val = Validation::forge(__FUNCTION__); - $val->add_field('f1', 'F1', 'valid_date'); - $val->add_field('f2', 'F2', 'valid_date'); - $val->add_field('f3', 'F3', 'valid_date'); - $val->add_field('f4', 'F4', 'valid_date'); - $val->add_field('f5', 'F5', 'valid_date'); - $val->add_field('f6', 'F6', 'valid_date'); - $test = $val->run($post); - $expected = true; - - $this->assertEquals($expected, $test); - } - - /** - * Validation: valid_date - * Expecting: failure - */ - public function test_validation_valid_date_none_arguments_error() { - $post = array( - 'f1' => 'test', - ); - - $val = Validation::forge(__FUNCTION__); - $val->add_field('f1', 'F1', 'valid_date'); - $test = $val->run($post); - $expected = false; - - $this->assertEquals($expected, $test); - } - - /** - * Validation: valid_date - * Expecting: failure - */ - public function test_validation_valid_date_none_arguments_strict_error() { - $post = array( - 'f1' => '2013/02/29', - ); - - $val = Validation::forge(__FUNCTION__); - $val->add_field('f1', 'F1', 'valid_date'); - $test = $val->run($post); - $expected = false; - - $this->assertEquals($expected, $test); - } - - /** - * Validation: valid_date - * Expecting: success - */ - public function test_validation_valid_date_format() { - $post = array( - 'f1' => '2013/02/26', - 'f2' => '2013-02-26', - 'f3' => '2013/2/26 12:00:33', - 'f4' => '19 Jan 2038 03:14:07', - 'f5' => 'Sat Mar 10 17:16:18 MST 2001', - 'f6' => '', - ); - - $val = Validation::forge(__FUNCTION__); - $val->add_field('f1', 'F1', 'valid_date[Y/m/d]'); - $val->add_field('f2', 'F2', 'valid_date[Y-m-d]'); - $val->add_field('f3', 'F3', 'valid_date[Y/m/d H:i:s]'); - $val->add_field('f4', 'F4', 'valid_date[d M Y H:i:s]'); - $val->add_field('f5', 'F5', 'valid_date[D M d H:i:s T Y]'); - $val->add_field('f6', 'F6', 'valid_date[Y/m/d]'); - - $test = $val->run($post); - $expected = true; - - $this->assertEquals($expected, $test); - } - - /** - * Validation: valid_date - * Expecting: failure - */ - public function test_validation_valid_date_format_error() { - $post = array( - 'f1' => '2013/02/26', - ); - - $val = Validation::forge(__FUNCTION__); - $val->add_field('f1', 'F1', 'valid_date[Y/m/d H:i:s]'); - - $test = $val->run($post); - $expected = false; - - $this->assertEquals($expected, $test); - } - - /** - * Validation: valid_date - * Expecting: success - */ - public function test_validation_valid_date_not_strict() { - $post = array( - 'f1' => '2013/02/29', - ); - - $val = Validation::forge(__FUNCTION__); - $val->add_field('f1', 'F1', 'valid_date[Y/m/d,0]'); - - $test = $val->run($post); - $expected = true; - - $this->assertEquals($expected, $test); - } - - /** - * Test for $validation->error_message() - * - * @test - */ - public function test_error_message() { - $post = array( - 'title' => '', - 'number' => 'ABC', - ); - - $val = Validation::forge(__FUNCTION__); - $val->add_field('title', 'Title', 'required'); - $val->add_field('number', 'Number', 'required|valid_string[numeric]'); - - $val->run($post); - - $expected = 'The field Title is required and must contain a value.'; - $this->assertEquals($expected, $val->error_message('title')); - - $expected = 'The valid string rule valid_string(numeric) failed for field Number'; - $this->assertEquals($expected, $val->error_message('number')); - - $expected = 'The field Title is required and must contain a value.'; - $this->assertEquals($expected, current($val->error_message())); - - $expected = 'No error'; - $this->assertEquals($expected, $val->error_message('content', 'No error')); - } -} diff --git a/fuel/core/tests/validation/error.php b/fuel/core/tests/validation/error.php deleted file mode 100755 index 6a1a276..0000000 --- a/fuel/core/tests/validation/error.php +++ /dev/null @@ -1,24 +0,0 @@ -1, 'abbr'=>1, 'acronym'=>1, 'address'=>1, 'applet'=>1, 'area'=>1, 'b'=>1, 'bdo'=>1, 'big'=>1, 'blockquote'=>1, 'br'=>1, 'button'=>1, 'caption'=>1, 'center'=>1, 'cite'=>1, 'code'=>1, 'col'=>1, 'colgroup'=>1, 'dd'=>1, 'del'=>1, 'dfn'=>1, 'dir'=>1, 'div'=>1, 'dl'=>1, 'dt'=>1, 'em'=>1, 'embed'=>1, 'fieldset'=>1, 'font'=>1, 'form'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'hr'=>1, 'i'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'ins'=>1, 'isindex'=>1, 'kbd'=>1, 'label'=>1, 'legend'=>1, 'li'=>1, 'map'=>1, 'menu'=>1, 'noscript'=>1, 'object'=>1, 'ol'=>1, 'optgroup'=>1, 'option'=>1, 'p'=>1, 'param'=>1, 'pre'=>1, 'q'=>1, 'rb'=>1, 'rbc'=>1, 'rp'=>1, 'rt'=>1, 'rtc'=>1, 'ruby'=>1, 's'=>1, 'samp'=>1, 'script'=>1, 'select'=>1, 'small'=>1, 'span'=>1, 'strike'=>1, 'strong'=>1, 'sub'=>1, 'sup'=>1, 'table'=>1, 'tbody'=>1, 'td'=>1, 'textarea'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1, 'tt'=>1, 'u'=>1, 'ul'=>1, 'var'=>1); // 86/deprecated+embed+ruby -if(!empty($C['safe'])){ - unset($e['applet'], $e['embed'], $e['iframe'], $e['object'], $e['script']); -} -$x = !empty($C['elements']) ? str_replace(array("\n", "\r", "\t", ' '), '', $C['elements']) : '*'; -if($x == '-*'){$e = array();} -elseif(strpos($x, '*') === false){$e = array_flip(explode(',', $x));} -else{ - if(isset($x[1])){ - preg_match_all('`(?:^|-|\+)[^\-+]+?(?=-|\+|$)`', $x, $m, PREG_SET_ORDER); - for($i=count($m); --$i>=0;){$m[$i] = $m[$i][0];} - foreach($m as $v){ - if($v[0] == '+'){$e[substr($v, 1)] = 1;} - if($v[0] == '-' && isset($e[($v = substr($v, 1))]) && !in_array('+'. $v, $m)){unset($e[$v]);} - } - } -} -$C['elements'] =& $e; -// config attrs -$x = !empty($C['deny_attribute']) ? str_replace(array("\n", "\r", "\t", ' '), '', $C['deny_attribute']) : ''; -$x = array_flip((isset($x[0]) && $x[0] == '*') ? explode('-', $x) : explode(',', $x. (!empty($C['safe']) ? ',on*' : ''))); -if(isset($x['on*'])){ - unset($x['on*']); - $x += array('onblur'=>1, 'onchange'=>1, 'onclick'=>1, 'ondblclick'=>1, 'onfocus'=>1, 'onkeydown'=>1, 'onkeypress'=>1, 'onkeyup'=>1, 'onmousedown'=>1, 'onmousemove'=>1, 'onmouseout'=>1, 'onmouseover'=>1, 'onmouseup'=>1, 'onreset'=>1, 'onselect'=>1, 'onsubmit'=>1); -} -$C['deny_attribute'] = $x; -// config URL -$x = (isset($C['schemes'][2]) && strpos($C['schemes'], ':')) ? strtolower($C['schemes']) : 'href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; *:file, http, https'; -$C['schemes'] = array(); -foreach(explode(';', str_replace(array(' ', "\t", "\r", "\n"), '', $x)) as $v){ - $x = $x2 = null; list($x, $x2) = explode(':', $v, 2); - if($x2){$C['schemes'][$x] = array_flip(explode(',', $x2));} -} -if(!isset($C['schemes']['*'])){$C['schemes']['*'] = array('file'=>1, 'http'=>1, 'https'=>1,);} -if(!empty($C['safe']) && empty($C['schemes']['style'])){$C['schemes']['style'] = array('!'=>1);} -$C['abs_url'] = isset($C['abs_url']) ? $C['abs_url'] : 0; -if(!isset($C['base_url']) or !preg_match('`^[a-zA-Z\d.+\-]+://[^/]+/(.+?/)?$`', $C['base_url'])){ - $C['base_url'] = $C['abs_url'] = 0; -} -// config rest -$C['and_mark'] = empty($C['and_mark']) ? 0 : 1; -$C['anti_link_spam'] = (isset($C['anti_link_spam']) && is_array($C['anti_link_spam']) && count($C['anti_link_spam']) == 2 && (empty($C['anti_link_spam'][0]) or hl_regex($C['anti_link_spam'][0])) && (empty($C['anti_link_spam'][1]) or hl_regex($C['anti_link_spam'][1]))) ? $C['anti_link_spam'] : 0; -$C['anti_mail_spam'] = isset($C['anti_mail_spam']) ? $C['anti_mail_spam'] : 0; -$C['balance'] = isset($C['balance']) ? (bool)$C['balance'] : 1; -$C['cdata'] = isset($C['cdata']) ? $C['cdata'] : (empty($C['safe']) ? 3 : 0); -$C['clean_ms_char'] = empty($C['clean_ms_char']) ? 0 : $C['clean_ms_char']; -$C['comment'] = isset($C['comment']) ? $C['comment'] : (empty($C['safe']) ? 3 : 0); -$C['css_expression'] = empty($C['css_expression']) ? 0 : 1; -$C['direct_list_nest'] = empty($C['direct_list_nest']) ? 0 : 1; -$C['hexdec_entity'] = isset($C['hexdec_entity']) ? $C['hexdec_entity'] : 1; -$C['hook'] = (!empty($C['hook']) && function_exists($C['hook'])) ? $C['hook'] : 0; -$C['hook_tag'] = (!empty($C['hook_tag']) && function_exists($C['hook_tag'])) ? $C['hook_tag'] : 0; -$C['keep_bad'] = isset($C['keep_bad']) ? $C['keep_bad'] : 6; -$C['lc_std_val'] = isset($C['lc_std_val']) ? (bool)$C['lc_std_val'] : 1; -$C['make_tag_strict'] = isset($C['make_tag_strict']) ? $C['make_tag_strict'] : 1; -$C['named_entity'] = isset($C['named_entity']) ? (bool)$C['named_entity'] : 1; -$C['no_deprecated_attr'] = isset($C['no_deprecated_attr']) ? $C['no_deprecated_attr'] : 1; -$C['parent'] = isset($C['parent'][0]) ? strtolower($C['parent']) : 'body'; -$C['show_setting'] = !empty($C['show_setting']) ? $C['show_setting'] : 0; -$C['style_pass'] = empty($C['style_pass']) ? 0 : 1; -$C['tidy'] = empty($C['tidy']) ? 0 : $C['tidy']; -$C['unique_ids'] = isset($C['unique_ids']) ? $C['unique_ids'] : 1; -$C['xml:lang'] = isset($C['xml:lang']) ? $C['xml:lang'] : 0; - -if(isset($GLOBALS['C'])){$reC = $GLOBALS['C'];} -$GLOBALS['C'] = $C; -$S = is_array($S) ? $S : hl_spec($S); -if(isset($GLOBALS['S'])){$reS = $GLOBALS['S'];} -$GLOBALS['S'] = $S; - -$t = preg_replace('`[\x00-\x08\x0b-\x0c\x0e-\x1f]`', '', $t); -//Clean out any microsoft characters -if ($C['clean_ms_char']) { - /** - * Note: CHANGED: This diverges from the htmLawed standard method to prevent breaking UTF-8 - */ - - //Convert Microsoft smarty quotes to boring quotes - $quotes = array( - "\xC2\xAB" => '"', // (U+00AB) in UTF-8 - "\xC2\xBB" => '"', // (U+00BB) in UTF-8 - "\xE2\x80\x83" => " ", // (U+2003) in UTF-8 - "\xE2\x80\x98" => "'", // (U+2018) in UTF-8 - "\xE2\x80\x99" => "'", // (U+2019) in UTF-8 - "\xE2\x80\x9A" => "'", // (U+201A) in UTF-8 - "\xE2\x80\x9B" => "'", // (U+201B) in UTF-8 - "\xE2\x80\x9C" => '"', // (U+201C) in UTF-8 - "\xE2\x80\x9D" => '"', // (U+201D) in UTF-8 - "\xE2\x80\x9E" => '"', // (U+201E) in UTF-8 - "\xE2\x80\x9F" => '"', // (U+201F) in UTF-8 - "\xE2\x80\xB9" => "'", // (U+2039) in UTF-8 - "\xE2\x80\xBA" => "'", // (U+203A) in UTF-8 - ); - $t = strtr($t, $quotes); - - //Taken from http://www.php.net/manual/en/function.strtr.php#40253 - $badlatin1_cp1252_to_htmlent = array( - '\x80'=>'€', '\x81'=>'?', '\x82'=>'‚', '\x83'=>'ƒ', - '\x84'=>'„', '\x85'=>'…', '\x86'=>'†', '\x87'=>'‡', - '\x88'=>'ˆ', '\x89'=>'‰', '\x8A'=>'Š', '\x8B'=>'‹', - '\x8C'=>'Œ', '\x8D'=>'?', '\x8E'=>'Ž', '\x8F'=>'?', - '\x90'=>'?', '\x91'=>'‘', '\x92'=>'’', '\x93'=>'“', - '\x94'=>'”', '\x95'=>'•', '\x96'=>'–', '\x97'=>'—', - '\x98'=>'˜', '\x99'=>'™', '\x9A'=>'š', '\x9B'=>'›', - '\x9C'=>'œ', '\x9D'=>'?', '\x9E'=>'ž', '\x9F'=>'Ÿ' - ); - $t = strtr($t, $badlatin1_cp1252_to_htmlent); -} -if($C['clean_ms_char']){ - $x = array("\x7f"=>'', "\x80"=>'€', "\x81"=>'', "\x83"=>'ƒ', "\x85"=>'…', "\x86"=>'†', "\x87"=>'‡', "\x88"=>'ˆ', "\x89"=>'‰', "\x8a"=>'Š', "\x8b"=>'‹', "\x8c"=>'Œ', "\x8d"=>'', "\x8e"=>'Ž', "\x8f"=>'', "\x90"=>'', "\x95"=>'•', "\x96"=>'–', "\x97"=>'—', "\x98"=>'˜', "\x99"=>'™', "\x9a"=>'š', "\x9b"=>'›', "\x9c"=>'œ', "\x9d"=>'', "\x9e"=>'ž', "\x9f"=>'Ÿ'); - $x = $x + ($C['clean_ms_char'] == 1 ? array("\x82"=>'‚', "\x84"=>'„', "\x91"=>'‘', "\x92"=>'’', "\x93"=>'“', "\x94"=>'”') : array("\x82"=>'\'', "\x84"=>'"', "\x91"=>'\'', "\x92"=>'\'', "\x93"=>'"', "\x94"=>'"')); - $t = strtr($t, $x); -} -if($C['cdata'] or $C['comment']){$t = preg_replace_callback('``sm', 'hl_cmtcd', $t);} -$t = preg_replace_callback('`&([A-Za-z][A-Za-z0-9]{1,30}|#(?:[0-9]{1,8}|[Xx][0-9A-Fa-f]{1,7}));`', 'hl_ent', str_replace('&', '&', $t)); -if($C['unique_ids'] && !isset($GLOBALS['hl_Ids'])){$GLOBALS['hl_Ids'] = array();} -if($C['hook']){$t = $C['hook']($t, $C, $S);} -if($C['show_setting'] && preg_match('`^[a-z][a-z0-9_]*$`i', $C['show_setting'])){ - $GLOBALS[$C['show_setting']] = array('config'=>$C, 'spec'=>$S, 'time'=>microtime()); -} -// main -$t = preg_replace_callback('`<(?:(?:\s|$)|(?:[^>]*(?:>|$)))|>`m', 'hl_tag', $t); -$t = $C['balance'] ? hl_bal($t, $C['keep_bad'], $C['parent']) : $t; -$t = (($C['cdata'] or $C['comment']) && strpos($t, "\x01") !== false) ? str_replace(array("\x01", "\x02", "\x03", "\x04", "\x05"), array('', '', '&', '<', '>'), $t) : $t; -$t = $C['tidy'] ? hl_tidy($t, $C['tidy'], $C['parent']) : $t; -unset($C, $e); -if(isset($reC)){$GLOBALS['C'] = $reC;} -if(isset($reS)){$GLOBALS['S'] = $reS;} -return $t; -// eof -} - -function hl_attrval($t, $p){ -// check attr val against $S -$o = 1; $l = strlen($t); -foreach($p as $k=>$v){ - switch($k){ - case 'maxlen':if($l > $v){$o = 0;} - break; case 'minlen': if($l < $v){$o = 0;} - break; case 'maxval': if((float)($t) > $v){$o = 0;} - break; case 'minval': if((float)($t) < $v){$o = 0;} - break; case 'match': if(!preg_match($v, $t)){$o = 0;} - break; case 'nomatch': if(preg_match($v, $t)){$o = 0;} - break; case 'oneof': - $m = 0; - foreach(explode('|', $v) as $n){if($t == $n){$m = 1; break;}} - $o = $m; - break; case 'noneof': - $m = 1; - foreach(explode('|', $v) as $n){if($t == $n){$m = 0; break;}} - $o = $m; - break; default: - break; - } - if(!$o){break;} -} -return ($o ? $t : (isset($p['default']) ? $p['default'] : 0)); -// eof -} - -function hl_bal($t, $do=1, $in='div'){ -// balance tags -// by content -$cB = array('blockquote'=>1, 'form'=>1, 'map'=>1, 'noscript'=>1); // Block -$cE = array('area'=>1, 'br'=>1, 'col'=>1, 'embed'=>1, 'hr'=>1, 'img'=>1, 'input'=>1, 'isindex'=>1, 'param'=>1); // Empty -$cF = array('button'=>1, 'del'=>1, 'div'=>1, 'dd'=>1, 'fieldset'=>1, 'iframe'=>1, 'ins'=>1, 'li'=>1, 'noscript'=>1, 'object'=>1, 'td'=>1, 'th'=>1); // Flow; later context-wise dynamic move of ins & del to $cI -$cI = array('a'=>1, 'abbr'=>1, 'acronym'=>1, 'address'=>1, 'b'=>1, 'bdo'=>1, 'big'=>1, 'caption'=>1, 'cite'=>1, 'code'=>1, 'dfn'=>1, 'dt'=>1, 'em'=>1, 'font'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'i'=>1, 'kbd'=>1, 'label'=>1, 'legend'=>1, 'p'=>1, 'pre'=>1, 'q'=>1, 'rb'=>1, 'rt'=>1, 's'=>1, 'samp'=>1, 'small'=>1, 'span'=>1, 'strike'=>1, 'strong'=>1, 'sub'=>1, 'sup'=>1, 'tt'=>1, 'u'=>1, 'var'=>1); // Inline -$cN = array('a'=>array('a'=>1), 'button'=>array('a'=>1, 'button'=>1, 'fieldset'=>1, 'form'=>1, 'iframe'=>1, 'input'=>1, 'label'=>1, 'select'=>1, 'textarea'=>1), 'fieldset'=>array('fieldset'=>1), 'form'=>array('form'=>1), 'label'=>array('label'=>1), 'noscript'=>array('script'=>1), 'pre'=>array('big'=>1, 'font'=>1, 'img'=>1, 'object'=>1, 'script'=>1, 'small'=>1, 'sub'=>1, 'sup'=>1), 'rb'=>array('ruby'=>1), 'rt'=>array('ruby'=>1)); // Illegal -$cN2 = array_keys($cN); -$cR = array('blockquote'=>1, 'dir'=>1, 'dl'=>1, 'form'=>1, 'map'=>1, 'menu'=>1, 'noscript'=>1, 'ol'=>1, 'optgroup'=>1, 'rbc'=>1, 'rtc'=>1, 'ruby'=>1, 'select'=>1, 'table'=>1, 'tbody'=>1, 'tfoot'=>1, 'thead'=>1, 'tr'=>1, 'ul'=>1); -$cS = array('colgroup'=>array('col'=>1), 'dir'=>array('li'=>1), 'dl'=>array('dd'=>1, 'dt'=>1), 'menu'=>array('li'=>1), 'ol'=>array('li'=>1), 'optgroup'=>array('option'=>1), 'option'=>array('#pcdata'=>1), 'rbc'=>array('rb'=>1), 'rp'=>array('#pcdata'=>1), 'rtc'=>array('rt'=>1), 'ruby'=>array('rb'=>1, 'rbc'=>1, 'rp'=>1, 'rt'=>1, 'rtc'=>1), 'select'=>array('optgroup'=>1, 'option'=>1), 'script'=>array('#pcdata'=>1), 'table'=>array('caption'=>1, 'col'=>1, 'colgroup'=>1, 'tfoot'=>1, 'tbody'=>1, 'tr'=>1, 'thead'=>1), 'tbody'=>array('tr'=>1), 'tfoot'=>array('tr'=>1), 'textarea'=>array('#pcdata'=>1), 'thead'=>array('tr'=>1), 'tr'=>array('td'=>1, 'th'=>1), 'ul'=>array('li'=>1)); // Specific - immediate parent-child -if($GLOBALS['C']['direct_list_nest']){$cS['ol'] = $cS['ul'] += array('ol'=>1, 'ul'=>1);} -$cO = array('address'=>array('p'=>1), 'applet'=>array('param'=>1), 'blockquote'=>array('script'=>1), 'fieldset'=>array('legend'=>1, '#pcdata'=>1), 'form'=>array('script'=>1), 'map'=>array('area'=>1), 'object'=>array('param'=>1, 'embed'=>1)); // Other -$cT = array('colgroup'=>1, 'dd'=>1, 'dt'=>1, 'li'=>1, 'option'=>1, 'p'=>1, 'td'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1); // Omitable closing -// block/inline type; ins & del both type; #pcdata: text -$eB = array('address'=>1, 'blockquote'=>1, 'center'=>1, 'del'=>1, 'dir'=>1, 'dl'=>1, 'div'=>1, 'fieldset'=>1, 'form'=>1, 'ins'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'hr'=>1, 'isindex'=>1, 'menu'=>1, 'noscript'=>1, 'ol'=>1, 'p'=>1, 'pre'=>1, 'table'=>1, 'ul'=>1); -$eI = array('#pcdata'=>1, 'a'=>1, 'abbr'=>1, 'acronym'=>1, 'applet'=>1, 'b'=>1, 'bdo'=>1, 'big'=>1, 'br'=>1, 'button'=>1, 'cite'=>1, 'code'=>1, 'del'=>1, 'dfn'=>1, 'em'=>1, 'embed'=>1, 'font'=>1, 'i'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'ins'=>1, 'kbd'=>1, 'label'=>1, 'map'=>1, 'object'=>1, 'q'=>1, 'ruby'=>1, 's'=>1, 'samp'=>1, 'select'=>1, 'script'=>1, 'small'=>1, 'span'=>1, 'strike'=>1, 'strong'=>1, 'sub'=>1, 'sup'=>1, 'textarea'=>1, 'tt'=>1, 'u'=>1, 'var'=>1); -$eN = array('a'=>1, 'big'=>1, 'button'=>1, 'fieldset'=>1, 'font'=>1, 'form'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'label'=>1, 'object'=>1, 'ruby'=>1, 'script'=>1, 'select'=>1, 'small'=>1, 'sub'=>1, 'sup'=>1, 'textarea'=>1); // Exclude from specific ele; $cN values -$eO = array('area'=>1, 'caption'=>1, 'col'=>1, 'colgroup'=>1, 'dd'=>1, 'dt'=>1, 'legend'=>1, 'li'=>1, 'optgroup'=>1, 'option'=>1, 'param'=>1, 'rb'=>1, 'rbc'=>1, 'rp'=>1, 'rt'=>1, 'rtc'=>1, 'script'=>1, 'tbody'=>1, 'td'=>1, 'tfoot'=>1, 'thead'=>1, 'th'=>1, 'tr'=>1); // Missing in $eB & $eI -$eF = $eB + $eI; - -// $in sets allowed child -$in = ((isset($eF[$in]) && $in != '#pcdata') or isset($eO[$in])) ? $in : 'div'; -if(isset($cE[$in])){ - return (!$do ? '' : str_replace(array('<', '>'), array('<', '>'), $t)); -} -if(isset($cS[$in])){$inOk = $cS[$in];} -elseif(isset($cI[$in])){$inOk = $eI; $cI['del'] = 1; $cI['ins'] = 1;} -elseif(isset($cF[$in])){$inOk = $eF; unset($cI['del'], $cI['ins']);} -elseif(isset($cB[$in])){$inOk = $eB; unset($cI['del'], $cI['ins']);} -if(isset($cO[$in])){$inOk = $inOk + $cO[$in];} -if(isset($cN[$in])){$inOk = array_diff_assoc($inOk, $cN[$in]);} - -$t = explode('<', $t); -$ok = $q = array(); // $q seq list of open non-empty ele -ob_start(); - -for($i=-1, $ci=count($t); ++$i<$ci;){ - // allowed $ok in parent $p - if($ql = count($q)){ - $p = array_pop($q); - $q[] = $p; - if(isset($cS[$p])){$ok = $cS[$p];} - elseif(isset($cI[$p])){$ok = $eI; $cI['del'] = 1; $cI['ins'] = 1;} - elseif(isset($cF[$p])){$ok = $eF; unset($cI['del'], $cI['ins']);} - elseif(isset($cB[$p])){$ok = $eB; unset($cI['del'], $cI['ins']);} - if(isset($cO[$p])){$ok = $ok + $cO[$p];} - if(isset($cN[$p])){$ok = array_diff_assoc($ok, $cN[$p]);} - }else{$ok = $inOk; unset($cI['del'], $cI['ins']);} - // bad tags, & ele content - if(isset($e) && ($do == 1 or (isset($ok['#pcdata']) && ($do == 3 or $do == 5)))){ - echo '<', $s, $e, $a, '>'; - } - if(isset($x[0])){ - if(strlen(trim($x)) && (($ql && isset($cB[$p])) or (isset($cB[$in]) && !$ql))){ - echo '
    ', $x, '
    '; - } - elseif($do < 3 or isset($ok['#pcdata'])){echo $x;} - elseif(strpos($x, "\x02\x04")){ - foreach(preg_split('`(\x01\x02[^\x01\x02]+\x02\x01)`', $x, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY) as $v){ - echo (substr($v, 0, 2) == "\x01\x02" ? $v : ($do > 4 ? preg_replace('`\S`', '', $v) : '')); - } - }elseif($do > 4){echo preg_replace('`\S`', '', $x);} - } - // get markup - if(!preg_match('`^(/?)([a-z1-6]+)([^>]*)>(.*)`sm', $t[$i], $r)){$x = $t[$i]; continue;} - $s = null; $e = null; $a = null; $x = null; list($all, $s, $e, $a, $x) = $r; - // close tag - if($s){ - if(isset($cE[$e]) or !in_array($e, $q)){continue;} // Empty/unopen - if($p == $e){array_pop($q); echo ''; unset($e); continue;} // Last open - $add = ''; // Nesting - close open tags that need to be - for($j=-1, $cj=count($q); ++$j<$cj;){ - if(($d = array_pop($q)) == $e){break;} - else{$add .= "";} - } - echo $add, ''; unset($e); continue; - } - // open tag - // $cB ele needs $eB ele as child - if(isset($cB[$e]) && strlen(trim($x))){ - $t[$i] = "{$e}{$a}>"; - array_splice($t, $i+1, 0, 'div>'. $x); unset($e, $x); ++$ci; --$i; continue; - } - if((($ql && isset($cB[$p])) or (isset($cB[$in]) && !$ql)) && !isset($eB[$e]) && !isset($ok[$e])){ - array_splice($t, $i, 0, 'div>'); unset($e, $x); ++$ci; --$i; continue; - } - // if no open ele, $in = parent; mostly immediate parent-child relation should hold - if(!$ql or !isset($eN[$e]) or !array_intersect($q, $cN2)){ - if(!isset($ok[$e])){ - if($ql && isset($cT[$p])){echo ''; unset($e, $x); --$i;} - continue; - } - if(!isset($cE[$e])){$q[] = $e;} - echo '<', $e, $a, '>'; unset($e); continue; - } - // specific parent-child - if(isset($cS[$p][$e])){ - if(!isset($cE[$e])){$q[] = $e;} - echo '<', $e, $a, '>'; unset($e); continue; - } - // nesting - $add = ''; - $q2 = array(); - for($k=-1, $kc=count($q); ++$k<$kc;){ - $d = $q[$k]; - $ok2 = array(); - if(isset($cS[$d])){$q2[] = $d; continue;} - $ok2 = isset($cI[$d]) ? $eI : $eF; - if(isset($cO[$d])){$ok2 = $ok2 + $cO[$d];} - if(isset($cN[$d])){$ok2 = array_diff_assoc($ok2, $cN[$d]);} - if(!isset($ok2[$e])){ - if(!$k && !isset($inOk[$e])){continue 2;} - $add = ""; - for(;++$k<$kc;){$add = "{$add}";} - break; - } - else{$q2[] = $d;} - } - $q = $q2; - if(!isset($cE[$e])){$q[] = $e;} - echo $add, '<', $e, $a, '>'; unset($e); continue; -} - -// end -if($ql = count($q)){ - $p = array_pop($q); - $q[] = $p; - if(isset($cS[$p])){$ok = $cS[$p];} - elseif(isset($cI[$p])){$ok = $eI; $cI['del'] = 1; $cI['ins'] = 1;} - elseif(isset($cF[$p])){$ok = $eF; unset($cI['del'], $cI['ins']);} - elseif(isset($cB[$p])){$ok = $eB; unset($cI['del'], $cI['ins']);} - if(isset($cO[$p])){$ok = $ok + $cO[$p];} - if(isset($cN[$p])){$ok = array_diff_assoc($ok, $cN[$p]);} -}else{$ok = $inOk; unset($cI['del'], $cI['ins']);} -if(isset($e) && ($do == 1 or (isset($ok['#pcdata']) && ($do == 3 or $do == 5)))){ - echo '<', $s, $e, $a, '>'; -} -if(isset($x[0])){ - if(strlen(trim($x)) && (($ql && isset($cB[$p])) or (isset($cB[$in]) && !$ql))){ - echo '
    ', $x, '
    '; - } - elseif($do < 3 or isset($ok['#pcdata'])){echo $x;} - elseif(strpos($x, "\x02\x04")){ - foreach(preg_split('`(\x01\x02[^\x01\x02]+\x02\x01)`', $x, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY) as $v){ - echo (substr($v, 0, 2) == "\x01\x02" ? $v : ($do > 4 ? preg_replace('`\S`', '', $v) : '')); - } - }elseif($do > 4){echo preg_replace('`\S`', '', $x);} -} -while(!empty($q) && ($e = array_pop($q))){echo '';} -$o = ob_get_contents(); -ob_end_clean(); -return $o; -// eof -} - -function hl_cmtcd($t){ -// comment/CDATA sec handler -$t = $t[0]; -global $C; -if(!($v = $C[$n = $t[3] == '-' ? 'comment' : 'cdata'])){return $t;} -if($v == 1){return '';} -if($n == 'comment'){ - if(substr(($t = preg_replace('`--+`', '-', substr($t, 4, -3))), -1) != ' '){$t .= ' ';} -} -else{$t = substr($t, 1, -1);} -$t = $v == 2 ? str_replace(array('&', '<', '>'), array('&', '<', '>'), $t) : $t; -return str_replace(array('&', '<', '>'), array("\x03", "\x04", "\x05"), ($n == 'comment' ? "\x01\x02\x04!--$t--\x05\x02\x01" : "\x01\x01\x04$t\x05\x01\x01")); -// eof -} - -function hl_ent($t){ -// entitity handler -global $C; -$t = $t[1]; -static $U = array('quot'=>1,'amp'=>1,'lt'=>1,'gt'=>1); -static $N = array('fnof'=>'402', 'Alpha'=>'913', 'Beta'=>'914', 'Gamma'=>'915', 'Delta'=>'916', 'Epsilon'=>'917', 'Zeta'=>'918', 'Eta'=>'919', 'Theta'=>'920', 'Iota'=>'921', 'Kappa'=>'922', 'Lambda'=>'923', 'Mu'=>'924', 'Nu'=>'925', 'Xi'=>'926', 'Omicron'=>'927', 'Pi'=>'928', 'Rho'=>'929', 'Sigma'=>'931', 'Tau'=>'932', 'Upsilon'=>'933', 'Phi'=>'934', 'Chi'=>'935', 'Psi'=>'936', 'Omega'=>'937', 'alpha'=>'945', 'beta'=>'946', 'gamma'=>'947', 'delta'=>'948', 'epsilon'=>'949', 'zeta'=>'950', 'eta'=>'951', 'theta'=>'952', 'iota'=>'953', 'kappa'=>'954', 'lambda'=>'955', 'mu'=>'956', 'nu'=>'957', 'xi'=>'958', 'omicron'=>'959', 'pi'=>'960', 'rho'=>'961', 'sigmaf'=>'962', 'sigma'=>'963', 'tau'=>'964', 'upsilon'=>'965', 'phi'=>'966', 'chi'=>'967', 'psi'=>'968', 'omega'=>'969', 'thetasym'=>'977', 'upsih'=>'978', 'piv'=>'982', 'bull'=>'8226', 'hellip'=>'8230', 'prime'=>'8242', 'Prime'=>'8243', 'oline'=>'8254', 'frasl'=>'8260', 'weierp'=>'8472', 'image'=>'8465', 'real'=>'8476', 'trade'=>'8482', 'alefsym'=>'8501', 'larr'=>'8592', 'uarr'=>'8593', 'rarr'=>'8594', 'darr'=>'8595', 'harr'=>'8596', 'crarr'=>'8629', 'lArr'=>'8656', 'uArr'=>'8657', 'rArr'=>'8658', 'dArr'=>'8659', 'hArr'=>'8660', 'forall'=>'8704', 'part'=>'8706', 'exist'=>'8707', 'empty'=>'8709', 'nabla'=>'8711', 'isin'=>'8712', 'notin'=>'8713', 'ni'=>'8715', 'prod'=>'8719', 'sum'=>'8721', 'minus'=>'8722', 'lowast'=>'8727', 'radic'=>'8730', 'prop'=>'8733', 'infin'=>'8734', 'ang'=>'8736', 'and'=>'8743', 'or'=>'8744', 'cap'=>'8745', 'cup'=>'8746', 'int'=>'8747', 'there4'=>'8756', 'sim'=>'8764', 'cong'=>'8773', 'asymp'=>'8776', 'ne'=>'8800', 'equiv'=>'8801', 'le'=>'8804', 'ge'=>'8805', 'sub'=>'8834', 'sup'=>'8835', 'nsub'=>'8836', 'sube'=>'8838', 'supe'=>'8839', 'oplus'=>'8853', 'otimes'=>'8855', 'perp'=>'8869', 'sdot'=>'8901', 'lceil'=>'8968', 'rceil'=>'8969', 'lfloor'=>'8970', 'rfloor'=>'8971', 'lang'=>'9001', 'rang'=>'9002', 'loz'=>'9674', 'spades'=>'9824', 'clubs'=>'9827', 'hearts'=>'9829', 'diams'=>'9830', 'apos'=>'39', 'OElig'=>'338', 'oelig'=>'339', 'Scaron'=>'352', 'scaron'=>'353', 'Yuml'=>'376', 'circ'=>'710', 'tilde'=>'732', 'ensp'=>'8194', 'emsp'=>'8195', 'thinsp'=>'8201', 'zwnj'=>'8204', 'zwj'=>'8205', 'lrm'=>'8206', 'rlm'=>'8207', 'ndash'=>'8211', 'mdash'=>'8212', 'lsquo'=>'8216', 'rsquo'=>'8217', 'sbquo'=>'8218', 'ldquo'=>'8220', 'rdquo'=>'8221', 'bdquo'=>'8222', 'dagger'=>'8224', 'Dagger'=>'8225', 'permil'=>'8240', 'lsaquo'=>'8249', 'rsaquo'=>'8250', 'euro'=>'8364', 'nbsp'=>'160', 'iexcl'=>'161', 'cent'=>'162', 'pound'=>'163', 'curren'=>'164', 'yen'=>'165', 'brvbar'=>'166', 'sect'=>'167', 'uml'=>'168', 'copy'=>'169', 'ordf'=>'170', 'laquo'=>'171', 'not'=>'172', 'shy'=>'173', 'reg'=>'174', 'macr'=>'175', 'deg'=>'176', 'plusmn'=>'177', 'sup2'=>'178', 'sup3'=>'179', 'acute'=>'180', 'micro'=>'181', 'para'=>'182', 'middot'=>'183', 'cedil'=>'184', 'sup1'=>'185', 'ordm'=>'186', 'raquo'=>'187', 'frac14'=>'188', 'frac12'=>'189', 'frac34'=>'190', 'iquest'=>'191', 'Agrave'=>'192', 'Aacute'=>'193', 'Acirc'=>'194', 'Atilde'=>'195', 'Auml'=>'196', 'Aring'=>'197', 'AElig'=>'198', 'Ccedil'=>'199', 'Egrave'=>'200', 'Eacute'=>'201', 'Ecirc'=>'202', 'Euml'=>'203', 'Igrave'=>'204', 'Iacute'=>'205', 'Icirc'=>'206', 'Iuml'=>'207', 'ETH'=>'208', 'Ntilde'=>'209', 'Ograve'=>'210', 'Oacute'=>'211', 'Ocirc'=>'212', 'Otilde'=>'213', 'Ouml'=>'214', 'times'=>'215', 'Oslash'=>'216', 'Ugrave'=>'217', 'Uacute'=>'218', 'Ucirc'=>'219', 'Uuml'=>'220', 'Yacute'=>'221', 'THORN'=>'222', 'szlig'=>'223', 'agrave'=>'224', 'aacute'=>'225', 'acirc'=>'226', 'atilde'=>'227', 'auml'=>'228', 'aring'=>'229', 'aelig'=>'230', 'ccedil'=>'231', 'egrave'=>'232', 'eacute'=>'233', 'ecirc'=>'234', 'euml'=>'235', 'igrave'=>'236', 'iacute'=>'237', 'icirc'=>'238', 'iuml'=>'239', 'eth'=>'240', 'ntilde'=>'241', 'ograve'=>'242', 'oacute'=>'243', 'ocirc'=>'244', 'otilde'=>'245', 'ouml'=>'246', 'divide'=>'247', 'oslash'=>'248', 'ugrave'=>'249', 'uacute'=>'250', 'ucirc'=>'251', 'uuml'=>'252', 'yacute'=>'253', 'thorn'=>'254', 'yuml'=>'255'); -if($t[0] != '#'){ - return ($C['and_mark'] ? "\x06" : '&'). (isset($U[$t]) ? $t : (isset($N[$t]) ? (!$C['named_entity'] ? '#'. ($C['hexdec_entity'] > 1 ? 'x'. dechex($N[$t]) : $N[$t]) : $t) : 'amp;'. $t)). ';'; -} -if(($n = ctype_digit($t = substr($t, 1)) ? intval($t) : hexdec(substr($t, 1))) < 9 or ($n > 13 && $n < 32) or $n == 11 or $n == 12 or ($n > 126 && $n < 160 && $n != 133) or ($n > 55295 && ($n < 57344 or ($n > 64975 && $n < 64992) or $n == 65534 or $n == 65535 or $n > 1114111))){ - return ($C['and_mark'] ? "\x06" : '&'). "amp;#{$t};"; -} -return ($C['and_mark'] ? "\x06" : '&'). '#'. (((ctype_digit($t) && $C['hexdec_entity'] < 2) or !$C['hexdec_entity']) ? $n : 'x'. dechex($n)). ';'; -// eof -} - -function hl_prot($p, $c=null){ -// check URL scheme -global $C; -$b = $a = ''; -if($c == null){$c = 'style'; $b = $p[1]; $a = $p[3]; $p = trim($p[2]);} -$c = isset($C['schemes'][$c]) ? $C['schemes'][$c] : $C['schemes']['*']; -static $d = 'denied:'; -if(isset($c['!']) && substr($p, 0, 7) != $d){$p = "$d$p";} -if(isset($c['*']) or !strcspn($p, '#?;') or (substr($p, 0, 7) == $d)){return "{$b}{$p}{$a}";} // All ok, frag, query, param -if(preg_match('`^([^:?[@!$()*,=/\'\]]+?)(:|&#(58|x3a);|%3a|\\\\0{0,4}3a).`i', $p, $m) && !isset($c[strtolower($m[1])])){ // Denied prot - return "{$b}{$d}{$p}{$a}"; -} -if($C['abs_url']){ - if($C['abs_url'] == -1 && strpos($p, $C['base_url']) === 0){ // Make url rel - $p = substr($p, strlen($C['base_url'])); - }elseif(empty($m[1])){ // Make URL abs - if(substr($p, 0, 2) == '//'){$p = substr($C['base_url'], 0, strpos($C['base_url'], ':')+1). $p;} - elseif($p[0] == '/'){$p = preg_replace('`(^.+?://[^/]+)(.*)`', '$1', $C['base_url']). $p;} - elseif(strcspn($p, './')){$p = $C['base_url']. $p;} - else{ - preg_match('`^([a-zA-Z\d\-+.]+://[^/]+)(.*)`', $C['base_url'], $m); - $p = preg_replace('`(?<=/)\./`', '', $m[2]. $p); - while(preg_match('`(?<=/)([^/]{3,}|[^/.]+?|\.[^/.]|[^/.]\.)/\.\./`', $p)){ - $p = preg_replace('`(?<=/)([^/]{3,}|[^/.]+?|\.[^/.]|[^/.]\.)/\.\./`', '', $p); - } - $p = $m[1]. $p; - } - } -} -return "{$b}{$p}{$a}"; -// eof -} - -function hl_regex($p){ -// ?regex -if(empty($p)){return 0;} -if($t = ini_get('track_errors')){$o = isset($php_errormsg) ? $php_errormsg : null;} -else{ini_set('track_errors', 1);} -unset($php_errormsg); -if(($d = ini_get('display_errors'))){ini_set('display_errors', 0);} -preg_match($p, ''); -if($d){ini_set('display_errors', 1);} -$r = isset($php_errormsg) ? 0 : 1; -if($t){$php_errormsg = isset($o) ? $o : null;} -else{ini_set('track_errors', 0);} -return $r; -// eof -} - -function hl_spec($t){ -// final $spec -$s = array(); -$t = str_replace(array("\t", "\r", "\n", ' '), '', preg_replace_callback('/"(?>(`.|[^"])*)"/sm', create_function('$m', 'return substr(str_replace(array(";", "|", "~", " ", ",", "/", "(", ")", \'`"\'), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\""), $m[0]), 1, -1);'), trim($t))); -for($i = count(($t = explode(';', $t))); --$i>=0;){ - $w = $t[$i]; - if(empty($w) or ($e = strpos($w, '=')) === false or !strlen(($a = substr($w, $e+1)))){continue;} - $y = $n = array(); - foreach(explode(',', $a) as $v){ - if(!preg_match('`^([a-z:\-\*]+)(?:\((.*?)\))?`i', $v, $m)){continue;} - if(($x = strtolower($m[1])) == '-*'){$n['*'] = 1; continue;} - if($x[0] == '-'){$n[substr($x, 1)] = 1; continue;} - if(!isset($m[2])){$y[$x] = 1; continue;} - foreach(explode('/', $m[2]) as $m){ - if(empty($m) or ($p = strpos($m, '=')) == 0 or $p < 5){$y[$x] = 1; continue;} - $y[$x][strtolower(substr($m, 0, $p))] = str_replace(array("\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08"), array(";", "|", "~", " ", ",", "/", "(", ")"), substr($m, $p+1)); - } - if(isset($y[$x]['match']) && !hl_regex($y[$x]['match'])){unset($y[$x]['match']);} - if(isset($y[$x]['nomatch']) && !hl_regex($y[$x]['nomatch'])){unset($y[$x]['nomatch']);} - } - if(!count($y) && !count($n)){continue;} - foreach(explode(',', substr($w, 0, $e)) as $v){ - if(!strlen(($v = strtolower($v)))){continue;} - if(count($y)){$s[$v] = $y;} - if(count($n)){$s[$v]['n'] = $n;} - } -} -return $s; -// eof -} - -function hl_tag($t){ -// tag/attribute handler -global $C; -$t = $t[0]; -// invalid < > -if($t == '< '){return '< ';} -if($t == '>'){return '>';} -if(!preg_match('`^<(/?)([a-zA-Z][a-zA-Z1-6]*)([^>]*?)\s?>$`m', $t, $m)){ - return str_replace(array('<', '>'), array('<', '>'), $t); -}elseif(!isset($C['elements'][($e = strtolower($m[2]))])){ - return (($C['keep_bad']%2) ? str_replace(array('<', '>'), array('<', '>'), $t) : ''); -} -// attr string -$a = str_replace(array("\n", "\r", "\t"), ' ', trim($m[3])); -// tag transform -static $eD = array('applet'=>1, 'center'=>1, 'dir'=>1, 'embed'=>1, 'font'=>1, 'isindex'=>1, 'menu'=>1, 's'=>1, 'strike'=>1, 'u'=>1); // Deprecated -if($C['make_tag_strict'] && isset($eD[$e])){ - $trt = hl_tag2($e, $a, $C['make_tag_strict']); - if(!$e){return (($C['keep_bad']%2) ? str_replace(array('<', '>'), array('<', '>'), $t) : '');} -} -// close tag -static $eE = array('area'=>1, 'br'=>1, 'col'=>1, 'embed'=>1, 'hr'=>1, 'img'=>1, 'input'=>1, 'isindex'=>1, 'param'=>1); // Empty ele -if(!empty($m[1])){ - return (!isset($eE[$e]) ? (empty($C['hook_tag']) ? "" : $C['hook_tag']($e)) : (($C['keep_bad'])%2 ? str_replace(array('<', '>'), array('<', '>'), $t) : '')); -} - -// open tag & attr -static $aN = array('abbr'=>array('td'=>1, 'th'=>1), 'accept-charset'=>array('form'=>1), 'accept'=>array('form'=>1, 'input'=>1), 'accesskey'=>array('a'=>1, 'area'=>1, 'button'=>1, 'input'=>1, 'label'=>1, 'legend'=>1, 'textarea'=>1), 'action'=>array('form'=>1), 'align'=>array('caption'=>1, 'embed'=>1, 'applet'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'object'=>1, 'legend'=>1, 'table'=>1, 'hr'=>1, 'div'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'p'=>1, 'col'=>1, 'colgroup'=>1, 'tbody'=>1, 'td'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1), 'alt'=>array('applet'=>1, 'area'=>1, 'img'=>1, 'input'=>1), 'archive'=>array('applet'=>1, 'object'=>1), 'axis'=>array('td'=>1, 'th'=>1), 'bgcolor'=>array('embed'=>1, 'table'=>1, 'tr'=>1, 'td'=>1, 'th'=>1), 'border'=>array('table'=>1, 'img'=>1, 'object'=>1), 'bordercolor'=>array('table'=>1, 'td'=>1, 'tr'=>1), 'cellpadding'=>array('table'=>1), 'cellspacing'=>array('table'=>1), 'char'=>array('col'=>1, 'colgroup'=>1, 'tbody'=>1, 'td'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1), 'charoff'=>array('col'=>1, 'colgroup'=>1, 'tbody'=>1, 'td'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1), 'charset'=>array('a'=>1, 'script'=>1), 'checked'=>array('input'=>1), 'cite'=>array('blockquote'=>1, 'q'=>1, 'del'=>1, 'ins'=>1), 'classid'=>array('object'=>1), 'clear'=>array('br'=>1), 'code'=>array('applet'=>1), 'codebase'=>array('object'=>1, 'applet'=>1), 'codetype'=>array('object'=>1), 'color'=>array('font'=>1), 'cols'=>array('textarea'=>1), 'colspan'=>array('td'=>1, 'th'=>1), 'compact'=>array('dir'=>1, 'dl'=>1, 'menu'=>1, 'ol'=>1, 'ul'=>1), 'coords'=>array('area'=>1, 'a'=>1), 'data'=>array('object'=>1), 'datetime'=>array('del'=>1, 'ins'=>1), 'declare'=>array('object'=>1), 'defer'=>array('script'=>1), 'dir'=>array('bdo'=>1), 'disabled'=>array('button'=>1, 'input'=>1, 'optgroup'=>1, 'option'=>1, 'select'=>1, 'textarea'=>1), 'enctype'=>array('form'=>1), 'face'=>array('font'=>1), 'flashvars'=>array('embed'=>1), 'for'=>array('label'=>1), 'frame'=>array('table'=>1), 'frameborder'=>array('iframe'=>1), 'headers'=>array('td'=>1, 'th'=>1), 'height'=>array('embed'=>1, 'iframe'=>1, 'td'=>1, 'th'=>1, 'img'=>1, 'object'=>1, 'applet'=>1), 'href'=>array('a'=>1, 'area'=>1), 'hreflang'=>array('a'=>1), 'hspace'=>array('applet'=>1, 'img'=>1, 'object'=>1), 'ismap'=>array('img'=>1, 'input'=>1), 'label'=>array('option'=>1, 'optgroup'=>1), 'language'=>array('script'=>1), 'longdesc'=>array('img'=>1, 'iframe'=>1), 'marginheight'=>array('iframe'=>1), 'marginwidth'=>array('iframe'=>1), 'maxlength'=>array('input'=>1), 'method'=>array('form'=>1), 'model'=>array('embed'=>1), 'multiple'=>array('select'=>1), 'name'=>array('button'=>1, 'embed'=>1, 'textarea'=>1, 'applet'=>1, 'select'=>1, 'form'=>1, 'iframe'=>1, 'img'=>1, 'a'=>1, 'input'=>1, 'object'=>1, 'map'=>1, 'param'=>1), 'nohref'=>array('area'=>1), 'noshade'=>array('hr'=>1), 'nowrap'=>array('td'=>1, 'th'=>1), 'object'=>array('applet'=>1), 'onblur'=>array('a'=>1, 'area'=>1, 'button'=>1, 'input'=>1, 'label'=>1, 'select'=>1, 'textarea'=>1), 'onchange'=>array('input'=>1, 'select'=>1, 'textarea'=>1), 'onfocus'=>array('a'=>1, 'area'=>1, 'button'=>1, 'input'=>1, 'label'=>1, 'select'=>1, 'textarea'=>1), 'onreset'=>array('form'=>1), 'onselect'=>array('input'=>1, 'textarea'=>1), 'onsubmit'=>array('form'=>1), 'pluginspage'=>array('embed'=>1), 'pluginurl'=>array('embed'=>1), 'prompt'=>array('isindex'=>1), 'readonly'=>array('textarea'=>1, 'input'=>1), 'rel'=>array('a'=>1), 'rev'=>array('a'=>1), 'rows'=>array('textarea'=>1), 'rowspan'=>array('td'=>1, 'th'=>1), 'rules'=>array('table'=>1), 'scope'=>array('td'=>1, 'th'=>1), 'scrolling'=>array('iframe'=>1), 'selected'=>array('option'=>1), 'shape'=>array('area'=>1, 'a'=>1), 'size'=>array('hr'=>1, 'font'=>1, 'input'=>1, 'select'=>1), 'span'=>array('col'=>1, 'colgroup'=>1), 'src'=>array('embed'=>1, 'script'=>1, 'input'=>1, 'iframe'=>1, 'img'=>1), 'standby'=>array('object'=>1), 'start'=>array('ol'=>1), 'summary'=>array('table'=>1), 'tabindex'=>array('a'=>1, 'area'=>1, 'button'=>1, 'input'=>1, 'object'=>1, 'select'=>1, 'textarea'=>1), 'target'=>array('a'=>1, 'area'=>1, 'form'=>1), 'type'=>array('a'=>1, 'embed'=>1, 'object'=>1, 'param'=>1, 'script'=>1, 'input'=>1, 'li'=>1, 'ol'=>1, 'ul'=>1, 'button'=>1), 'usemap'=>array('img'=>1, 'input'=>1, 'object'=>1), 'valign'=>array('col'=>1, 'colgroup'=>1, 'tbody'=>1, 'td'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1), 'value'=>array('input'=>1, 'option'=>1, 'param'=>1, 'button'=>1, 'li'=>1), 'valuetype'=>array('param'=>1), 'vspace'=>array('applet'=>1, 'img'=>1, 'object'=>1), 'width'=>array('embed'=>1, 'hr'=>1, 'iframe'=>1, 'img'=>1, 'object'=>1, 'table'=>1, 'td'=>1, 'th'=>1, 'applet'=>1, 'col'=>1, 'colgroup'=>1, 'pre'=>1), 'wmode'=>array('embed'=>1), 'xml:space'=>array('pre'=>1, 'script'=>1, 'style'=>1)); // Ele-specific -static $aNE = array('checked'=>1, 'compact'=>1, 'declare'=>1, 'defer'=>1, 'disabled'=>1, 'ismap'=>1, 'multiple'=>1, 'nohref'=>1, 'noresize'=>1, 'noshade'=>1, 'nowrap'=>1, 'readonly'=>1, 'selected'=>1); // Empty -static $aNP = array('action'=>1, 'cite'=>1, 'classid'=>1, 'codebase'=>1, 'data'=>1, 'href'=>1, 'longdesc'=>1, 'model'=>1, 'pluginspage'=>1, 'pluginurl'=>1, 'usemap'=>1); // Need scheme check; excludes style, on* & src -static $aNU = array('class'=>array('param'=>1, 'script'=>1), 'dir'=>array('applet'=>1, 'bdo'=>1, 'br'=>1, 'iframe'=>1, 'param'=>1, 'script'=>1), 'id'=>array('script'=>1), 'lang'=>array('applet'=>1, 'br'=>1, 'iframe'=>1, 'param'=>1, 'script'=>1), 'xml:lang'=>array('applet'=>1, 'br'=>1, 'iframe'=>1, 'param'=>1, 'script'=>1), 'onclick'=>array('applet'=>1, 'bdo'=>1, 'br'=>1, 'font'=>1, 'iframe'=>1, 'isindex'=>1, 'param'=>1, 'script'=>1), 'ondblclick'=>array('applet'=>1, 'bdo'=>1, 'br'=>1, 'font'=>1, 'iframe'=>1, 'isindex'=>1, 'param'=>1, 'script'=>1), 'onkeydown'=>array('applet'=>1, 'bdo'=>1, 'br'=>1, 'font'=>1, 'iframe'=>1, 'isindex'=>1, 'param'=>1, 'script'=>1), 'onkeypress'=>array('applet'=>1, 'bdo'=>1, 'br'=>1, 'font'=>1, 'iframe'=>1, 'isindex'=>1, 'param'=>1, 'script'=>1), 'onkeyup'=>array('applet'=>1, 'bdo'=>1, 'br'=>1, 'font'=>1, 'iframe'=>1, 'isindex'=>1, 'param'=>1, 'script'=>1), 'onmousedown'=>array('applet'=>1, 'bdo'=>1, 'br'=>1, 'font'=>1, 'iframe'=>1, 'isindex'=>1, 'param'=>1, 'script'=>1), 'onmousemove'=>array('applet'=>1, 'bdo'=>1, 'br'=>1, 'font'=>1, 'iframe'=>1, 'isindex'=>1, 'param'=>1, 'script'=>1), 'onmouseout'=>array('applet'=>1, 'bdo'=>1, 'br'=>1, 'font'=>1, 'iframe'=>1, 'isindex'=>1, 'param'=>1, 'script'=>1), 'onmouseover'=>array('applet'=>1, 'bdo'=>1, 'br'=>1, 'font'=>1, 'iframe'=>1, 'isindex'=>1, 'param'=>1, 'script'=>1), 'onmouseup'=>array('applet'=>1, 'bdo'=>1, 'br'=>1, 'font'=>1, 'iframe'=>1, 'isindex'=>1, 'param'=>1, 'script'=>1), 'style'=>array('param'=>1, 'script'=>1), 'title'=>array('param'=>1, 'script'=>1)); // Univ & exceptions - -if($C['lc_std_val']){ - // predef attr vals for $eAL & $aNE ele - static $aNL = array('all'=>1, 'baseline'=>1, 'bottom'=>1, 'button'=>1, 'center'=>1, 'char'=>1, 'checkbox'=>1, 'circle'=>1, 'col'=>1, 'colgroup'=>1, 'cols'=>1, 'data'=>1, 'default'=>1, 'file'=>1, 'get'=>1, 'groups'=>1, 'hidden'=>1, 'image'=>1, 'justify'=>1, 'left'=>1, 'ltr'=>1, 'middle'=>1, 'none'=>1, 'object'=>1, 'password'=>1, 'poly'=>1, 'post'=>1, 'preserve'=>1, 'radio'=>1, 'rect'=>1, 'ref'=>1, 'reset'=>1, 'right'=>1, 'row'=>1, 'rowgroup'=>1, 'rows'=>1, 'rtl'=>1, 'submit'=>1, 'text'=>1, 'top'=>1); - static $eAL = array('a'=>1, 'area'=>1, 'bdo'=>1, 'button'=>1, 'col'=>1, 'form'=>1, 'img'=>1, 'input'=>1, 'object'=>1, 'optgroup'=>1, 'option'=>1, 'param'=>1, 'script'=>1, 'select'=>1, 'table'=>1, 'td'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1, 'xml:space'=>1); - $lcase = isset($eAL[$e]) ? 1 : 0; -} - -$depTr = 0; -if($C['no_deprecated_attr']){ - // dep attr:applicable ele - static $aND = array('align'=>array('caption'=>1, 'div'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'hr'=>1, 'img'=>1, 'input'=>1, 'legend'=>1, 'object'=>1, 'p'=>1, 'table'=>1), 'bgcolor'=>array('table'=>1, 'td'=>1, 'th'=>1, 'tr'=>1), 'border'=>array('img'=>1, 'object'=>1), 'bordercolor'=>array('table'=>1, 'td'=>1, 'tr'=>1), 'clear'=>array('br'=>1), 'compact'=>array('dl'=>1, 'ol'=>1, 'ul'=>1), 'height'=>array('td'=>1, 'th'=>1), 'hspace'=>array('img'=>1, 'object'=>1), 'language'=>array('script'=>1), 'name'=>array('a'=>1, 'form'=>1, 'iframe'=>1, 'img'=>1, 'map'=>1), 'noshade'=>array('hr'=>1), 'nowrap'=>array('td'=>1, 'th'=>1), 'size'=>array('hr'=>1), 'start'=>array('ol'=>1), 'type'=>array('li'=>1, 'ol'=>1, 'ul'=>1), 'value'=>array('li'=>1), 'vspace'=>array('img'=>1, 'object'=>1), 'width'=>array('hr'=>1, 'pre'=>1, 'td'=>1, 'th'=>1)); - static $eAD = array('a'=>1, 'br'=>1, 'caption'=>1, 'div'=>1, 'dl'=>1, 'form'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'hr'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'legend'=>1, 'li'=>1, 'map'=>1, 'object'=>1, 'ol'=>1, 'p'=>1, 'pre'=>1, 'script'=>1, 'table'=>1, 'td'=>1, 'th'=>1, 'tr'=>1, 'ul'=>1); - $depTr = isset($eAD[$e]) ? 1 : 0; -} - -// attr name-vals -if(strpos($a, "\x01") !== false){$a = preg_replace('`\x01[^\x01]*\x01`', '', $a);} // No comment/CDATA sec -$mode = 0; $a = trim($a, ' /'); $aA = array(); -while(strlen($a)){ - $w = 0; - switch($mode){ - case 0: // Name - if(preg_match('`^[a-zA-Z][\-a-zA-Z:]+`', $a, $m)){ - $nm = strtolower($m[0]); - $w = $mode = 1; $a = ltrim(substr_replace($a, '', 0, strlen($m[0]))); - } - break; case 1: - if($a[0] == '='){ // = - $w = 1; $mode = 2; $a = ltrim($a, '= '); - }else{ // No val - $w = 1; $mode = 0; $a = ltrim($a); - $aA[$nm] = ''; - } - break; case 2: // Val - if(preg_match('`^((?:"[^"]*")|(?:\'[^\']*\')|(?:\s*[^\s"\']+))(.*)`', $a, $m)){ - $a = ltrim($m[2]); $m = $m[1]; $w = 1; $mode = 0; - $aA[$nm] = trim(str_replace('<', '<', ($m[0] == '"' or $m[0] == '\'') ? substr($m, 1, -1) : $m)); - } - break; - } - if($w == 0){ // Parse errs, deal with space, " & ' - $a = preg_replace('`^(?:"[^"]*("|$)|\'[^\']*(\'|$)|\S)*\s*`', '', $a); - $mode = 0; - } -} -if($mode == 1){$aA[$nm] = '';} - -// clean attrs -global $S; -$rl = isset($S[$e]) ? $S[$e] : array(); -$a = array(); $nfr = 0; -foreach($aA as $k=>$v){ - if(((isset($C['deny_attribute']['*']) ? isset($C['deny_attribute'][$k]) : !isset($C['deny_attribute'][$k])) && (isset($aN[$k][$e]) or (isset($aNU[$k]) && !isset($aNU[$k][$e]))) && !isset($rl['n'][$k]) && !isset($rl['n']['*'])) or isset($rl[$k])){ - if(isset($aNE[$k])){$v = $k;} - elseif(!empty($lcase) && (($e != 'button' or $e != 'input') or $k == 'type')){ // Rather loose but ?not cause issues - $v = (isset($aNL[($v2 = strtolower($v))])) ? $v2 : $v; - } - if($k == 'style' && !$C['style_pass']){ - if(false !== strpos($v, '&#')){ - static $sC = array(' '=>' ', ' '=>' ', 'E'=>'e', 'E'=>'e', 'e'=>'e', 'e'=>'e', 'X'=>'x', 'X'=>'x', 'x'=>'x', 'x'=>'x', 'P'=>'p', 'P'=>'p', 'p'=>'p', 'p'=>'p', 'S'=>'s', 'S'=>'s', 's'=>'s', 's'=>'s', 'I'=>'i', 'I'=>'i', 'i'=>'i', 'i'=>'i', 'O'=>'o', 'O'=>'o', 'o'=>'o', 'o'=>'o', 'N'=>'n', 'N'=>'n', 'n'=>'n', 'n'=>'n', 'U'=>'u', 'U'=>'u', 'u'=>'u', 'u'=>'u', 'R'=>'r', 'R'=>'r', 'r'=>'r', 'r'=>'r', 'L'=>'l', 'L'=>'l', 'l'=>'l', 'l'=>'l', '('=>'(', '('=>'(', ')'=>')', ')'=>')', ' '=>':', ' '=>':', '"'=>'"', '"'=>'"', '''=>"'", '''=>"'", '/'=>'/', '/'=>'/', '*'=>'*', '*'=>'*', '\'=>'\\', '\'=>'\\'); - $v = strtr($v, $sC); - } - $v = preg_replace_callback('`(url(?:\()(?: )*(?:\'|"|&(?:quot|apos);)?)(.+?)((?:\'|"|&(?:quot|apos);)?(?: )*(?:\)))`iS', 'hl_prot', $v); - $v = !$C['css_expression'] ? preg_replace('`expression`i', ' ', preg_replace('`\\\\\S|(/|(%2f))(\*|(%2a))`i', ' ', $v)) : $v; - }elseif(isset($aNP[$k]) or strpos($k, 'src') !== false or $k[0] == 'o'){ - $v = str_replace("­", ' ', (strpos($v, '&') !== false ? str_replace(array('­', '­', '­'), ' ', $v) : $v)); # double-quoted char is soft-hyphen; appears here as "­" or hyphen or something else depending on viewing software - $v = hl_prot($v, $k); - if($k == 'href'){ // X-spam - if($C['anti_mail_spam'] && strpos($v, 'mailto:') === 0){ - $v = str_replace('@', htmlspecialchars($C['anti_mail_spam']), $v); - }elseif($C['anti_link_spam']){ - $r1 = $C['anti_link_spam'][1]; - if(!empty($r1) && preg_match($r1, $v)){continue;} - $r0 = $C['anti_link_spam'][0]; - if(!empty($r0) && preg_match($r0, $v)){ - if(isset($a['rel'])){ - if(!preg_match('`\bnofollow\b`i', $a['rel'])){$a['rel'] .= ' nofollow';} - }elseif(isset($aA['rel'])){ - if(!preg_match('`\bnofollow\b`i', $aA['rel'])){$nfr = 1;} - }else{$a['rel'] = 'nofollow';} - } - } - } - } - if(isset($rl[$k]) && is_array($rl[$k]) && ($v = hl_attrval($v, $rl[$k])) === 0){continue;} - $a[$k] = str_replace('"', '"', $v); - } -} -if($nfr){$a['rel'] = isset($a['rel']) ? $a['rel']. ' nofollow' : 'nofollow';} - -// rqd attr -static $eAR = array('area'=>array('alt'=>'area'), 'bdo'=>array('dir'=>'ltr'), 'form'=>array('action'=>''), 'img'=>array('src'=>'', 'alt'=>'image'), 'map'=>array('name'=>''), 'optgroup'=>array('label'=>''), 'param'=>array('name'=>''), 'script'=>array('type'=>'text/javascript'), 'textarea'=>array('rows'=>'10', 'cols'=>'50')); -if(isset($eAR[$e])){ - foreach($eAR[$e] as $k=>$v){ - if(!isset($a[$k])){$a[$k] = isset($v[0]) ? $v : $k;} - } -} - -// depr attrs -if($depTr){ - $c = array(); - foreach($a as $k=>$v){ - if($k == 'style' or !isset($aND[$k][$e])){continue;} - if($k == 'align'){ - unset($a['align']); - if($e == 'img' && ($v == 'left' or $v == 'right')){$c[] = 'float: '. $v;} - elseif(($e == 'div' or $e == 'table') && $v == 'center'){$c[] = 'margin: auto';} - else{$c[] = 'text-align: '. $v;} - }elseif($k == 'bgcolor'){ - unset($a['bgcolor']); - $c[] = 'background-color: '. $v; - }elseif($k == 'border'){ - unset($a['border']); $c[] = "border: {$v}px"; - }elseif($k == 'bordercolor'){ - unset($a['bordercolor']); $c[] = 'border-color: '. $v; - }elseif($k == 'clear'){ - unset($a['clear']); $c[] = 'clear: '. ($v != 'all' ? $v : 'both'); - }elseif($k == 'compact'){ - unset($a['compact']); $c[] = 'font-size: 85%'; - }elseif($k == 'height' or $k == 'width'){ - unset($a[$k]); $c[] = $k. ': '. ($v[0] != '*' ? $v. (ctype_digit($v) ? 'px' : '') : 'auto'); - }elseif($k == 'hspace'){ - unset($a['hspace']); $c[] = "margin-left: {$v}px; margin-right: {$v}px"; - }elseif($k == 'language' && !isset($a['type'])){ - unset($a['language']); - $a['type'] = 'text/'. strtolower($v); - }elseif($k == 'name'){ - if($C['no_deprecated_attr'] == 2 or ($e != 'a' && $e != 'map')){unset($a['name']);} - if(!isset($a['id']) && preg_match('`[a-zA-Z][a-zA-Z\d.:_\-]*`', $v)){$a['id'] = $v;} - }elseif($k == 'noshade'){ - unset($a['noshade']); $c[] = 'border-style: none; border: 0; background-color: gray; color: gray'; - }elseif($k == 'nowrap'){ - unset($a['nowrap']); $c[] = 'white-space: nowrap'; - }elseif($k == 'size'){ - unset($a['size']); $c[] = 'size: '. $v. 'px'; - }elseif($k == 'start' or $k == 'value'){ - unset($a[$k]); - }elseif($k == 'type'){ - unset($a['type']); - static $ol_type = array('i'=>'lower-roman', 'I'=>'upper-roman', 'a'=>'lower-latin', 'A'=>'upper-latin', '1'=>'decimal'); - $c[] = 'list-style-type: '. (isset($ol_type[$v]) ? $ol_type[$v] : 'decimal'); - }elseif($k == 'vspace'){ - unset($a['vspace']); $c[] = "margin-top: {$v}px; margin-bottom: {$v}px"; - } - } - if(count($c)){ - $c = implode('; ', $c); - $a['style'] = isset($a['style']) ? rtrim($a['style'], ' ;'). '; '. $c. ';': $c. ';'; - } -} -// unique ID -if($C['unique_ids'] && isset($a['id'])){ - if(!preg_match('`^[A-Za-z][A-Za-z0-9_\-.:]*$`', ($id = $a['id'])) or (isset($GLOBALS['hl_Ids'][$id]) && $C['unique_ids'] == 1)){unset($a['id']); - }else{ - while(isset($GLOBALS['hl_Ids'][$id])){$id = $C['unique_ids']. $id;} - $GLOBALS['hl_Ids'][($a['id'] = $id)] = 1; - } -} -// xml:lang -if($C['xml:lang'] && isset($a['lang'])){ - $a['xml:lang'] = isset($a['xml:lang']) ? $a['xml:lang'] : $a['lang']; - if($C['xml:lang'] == 2){unset($a['lang']);} -} -// for transformed tag -if(!empty($trt)){ - $a['style'] = isset($a['style']) ? rtrim($a['style'], ' ;'). '; '. $trt : $trt; -} -// return with empty ele / -if(empty($C['hook_tag'])){ - $aA = ''; - foreach($a as $k=>$v){$aA .= " {$k}=\"{$v}\"";} - return "<{$e}{$aA}". (isset($eE[$e]) ? ' /' : ''). '>'; -} -else{return $C['hook_tag']($e, $a);} -// eof -} - -function hl_tag2(&$e, &$a, $t=1){ -// transform tag -if($e == 'center'){$e = 'div'; return 'text-align: center;';} -if($e == 'dir' or $e == 'menu'){$e = 'ul'; return '';} -if($e == 's' or $e == 'strike'){$e = 'span'; return 'text-decoration: line-through;';} -if($e == 'u'){$e = 'span'; return 'text-decoration: underline;';} -static $fs = array('0'=>'xx-small', '1'=>'xx-small', '2'=>'small', '3'=>'medium', '4'=>'large', '5'=>'x-large', '6'=>'xx-large', '7'=>'300%', '-1'=>'smaller', '-2'=>'60%', '+1'=>'larger', '+2'=>'150%', '+3'=>'200%', '+4'=>'300%'); -if($e == 'font'){ - $a2 = ''; - if(preg_match('`face\s*=\s*(\'|")([^=]+?)\\1`i', $a, $m) or preg_match('`face\s*=(\s*)(\S+)`i', $a, $m)){ - $a2 .= ' font-family: '. str_replace('"', '\'', trim($m[2])). ';'; - } - if(preg_match('`color\s*=\s*(\'|")?(.+?)(\\1|\s|$)`i', $a, $m)){ - $a2 .= ' color: '. trim($m[2]). ';'; - } - if(preg_match('`size\s*=\s*(\'|")?(.+?)(\\1|\s|$)`i', $a, $m) && isset($fs[($m = trim($m[2]))])){ - $a2 .= ' font-size: '. $fs[$m]. ';'; - } - $e = 'span'; return ltrim($a2); -} -if($t == 2){$e = 0; return 0;} -return ''; -// eof -} - -function hl_tidy($t, $w, $p){ -// Tidy/compact HTM -if(strpos(' pre,script,textarea', "$p,")){return $t;} -$t = preg_replace('`\s+`', ' ', preg_replace_callback(array('`(<(!\[CDATA\[))(.+?)(\]\]>)`sm', '`(<(!--))(.+?)(-->)`sm', '`(<(pre|script|textarea)[^>]*?>)(.+?)()`sm'), create_function('$m', 'return $m[1]. str_replace(array("<", ">", "\n", "\r", "\t", " "), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), $m[3]). $m[4];'), $t)); -if(($w = strtolower($w)) == -1){ - return str_replace(array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), array('<', '>', "\n", "\r", "\t", ' '), $t); -} -$s = strpos(" $w", 't') ? "\t" : ' '; -$s = preg_match('`\d`', $w, $m) ? str_repeat($s, $m[0]) : str_repeat($s, ($s == "\t" ? 1 : 2)); -$N = preg_match('`[ts]([1-9])`', $w, $m) ? $m[1] : 0; -$a = array('br'=>1); -$b = array('button'=>1, 'input'=>1, 'option'=>1, 'param'=>1); -$c = array('caption'=>1, 'dd'=>1, 'dt'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'isindex'=>1, 'label'=>1, 'legend'=>1, 'li'=>1, 'object'=>1, 'p'=>1, 'pre'=>1, 'td'=>1, 'textarea'=>1, 'th'=>1); -$d = array('address'=>1, 'blockquote'=>1, 'center'=>1, 'colgroup'=>1, 'dir'=>1, 'div'=>1, 'dl'=>1, 'fieldset'=>1, 'form'=>1, 'hr'=>1, 'iframe'=>1, 'map'=>1, 'menu'=>1, 'noscript'=>1, 'ol'=>1, 'optgroup'=>1, 'rbc'=>1, 'rtc'=>1, 'ruby'=>1, 'script'=>1, 'select'=>1, 'table'=>1, 'tbody'=>1, 'tfoot'=>1, 'thead'=>1, 'tr'=>1, 'ul'=>1); -$T = explode('<', $t); -$X = 1; -while($X){ - $n = $N; - $t = $T; - ob_start(); - if(isset($d[$p])){echo str_repeat($s, ++$n);} - echo ltrim(array_shift($t)); - for($i=-1, $j=count($t); ++$i<$j;){ - $r = ''; list($e, $r) = explode('>', $t[$i]); - $x = $e[0] == '/' ? 0 : (substr($e, -1) == '/' ? 1 : ($e[0] != '!' ? 2 : -1)); - $y = !$x ? ltrim($e, '/') : ($x > 0 ? substr($e, 0, strcspn($e, ' ')) : 0); - $e = "<$e>"; - if(isset($d[$y])){ - if(!$x){ - if($n){echo "\n", str_repeat($s, --$n), "$e\n", str_repeat($s, $n);} - else{++$N; ob_end_clean(); continue 2;} - } - else{echo "\n", str_repeat($s, $n), "$e\n", str_repeat($s, ($x != 1 ? ++$n : $n));} - echo $r; continue; - } - $f = "\n". str_repeat($s, $n); - if(isset($c[$y])){ - if(!$x){echo $e, $f, $r;} - else{echo $f, $e, $r;} - }elseif(isset($b[$y])){echo $f, $e, $r; - }elseif(isset($a[$y])){echo $e, $f, $r; - }elseif(!$y){echo $f, $e, $f, $r; - }else{echo $e, $r;} - } - $X = 0; -} -$t = str_replace(array("\n ", " \n"), "\n", preg_replace('`[\n]\s*?[\n]+`', "\n", ob_get_contents())); -ob_end_clean(); -if(($l = strpos(" $w", 'r') ? (strpos(" $w", 'n') ? "\r\n" : "\r") : 0)){ - $t = str_replace("\n", $l, $t); -} -return str_replace(array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), array('<', '>', "\n", "\r", "\t", ' '), $t); -// eof -} - -function hl_version(){ -// rel -return '1.1.19'; -// eof -} - -function kses($t, $h, $p=array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'gopher', 'mailto')){ -// kses compat -foreach($h as $k=>$v){ - $h[$k]['n']['*'] = 1; -} -$C['cdata'] = $C['comment'] = $C['make_tag_strict'] = $C['no_deprecated_attr'] = $C['unique_ids'] = 0; -$C['keep_bad'] = 1; -$C['elements'] = count($h) ? strtolower(implode(',', array_keys($h))) : '-*'; -$C['hook'] = 'kses_hook'; -$C['schemes'] = '*:'. implode(',', $p); -return htmLawed($t, $C, $h); -// eof -} - -function kses_hook($t, &$C, &$S){ -// kses compat -return $t; -// eof -} diff --git a/fuel/core/vendor/phpquickprofiler/console.php b/fuel/core/vendor/phpquickprofiler/console.php deleted file mode 100755 index 254e112..0000000 --- a/fuel/core/vendor/phpquickprofiler/console.php +++ /dev/null @@ -1,98 +0,0 @@ - array(), - 'logCount' => 0, - 'memoryCount' => 0, - 'errorCount' => 0, - 'speedCount' => 0); - } - - /*----------------------------------- - LOG A VARIABLE TO CONSOLE - ------------------------------------*/ - - public static function log($data) { - $logItem = array( - "data" => $data, - "type" => 'log' - ); - self::addToConsoleAndIncrement('logCount', $logItem); - } - - /*--------------------------------------------------- - LOG MEMORY USAGE OF VARIABLE OR ENTIRE SCRIPT - -----------------------------------------------------*/ - - public static function logMemory($object = false, $name = 'Memory Usage') { - $memory = ($object and ! $object instanceOf \Controller) ? strlen(serialize($object)) : memory_get_usage(); - $logItem = array( - "data" => $memory, - "type" => 'memory', - "name" => $name, - "dataType" => gettype($object) - ); - self::addToConsoleAndIncrement('memoryCount', $logItem); - } - - /*----------------------------------- - LOG A PHP EXCEPTION OBJECT - ------------------------------------*/ - - public static function logError($exception, $message) { - $logItem = array( - "data" => $message, - "type" => 'error', - "file" => $exception->getFile(), - "line" => $exception->getLine() - ); - self::addToConsoleAndIncrement('errorCount', $logItem); - } - - /*------------------------------------ - POINT IN TIME SPEED SNAPSHOT - -------------------------------------*/ - - public static function logSpeed($name = 'Point in Time') { - $logItem = array( - "data" => PhpQuickProfiler::getMicroTime(), - "type" => 'speed', - "name" => $name - ); - self::addToConsoleAndIncrement('speedCount', $logItem); - } - - /*----------------------------------- - RETURN & MODIFY LOGS - ------------------------------------*/ - - public static function addToConsoleAndIncrement($log, $item) { - if(!isset($GLOBALS['pqp_logs'])) self::init(); - $GLOBALS['pqp_logs']['console'][] = $item; - $GLOBALS['pqp_logs'][$log] += 1; - } - - public static function getLogs() { - if(!isset($GLOBALS['pqp_logs'])) self::init(); - return $GLOBALS['pqp_logs']; - } - -} - -?> diff --git a/fuel/core/vendor/phpquickprofiler/display.php b/fuel/core/vendor/phpquickprofiler/display.php deleted file mode 100755 index 1172ec3..0000000 --- a/fuel/core/vendor/phpquickprofiler/display.php +++ /dev/null @@ -1,686 +0,0 @@ - - - Description : This is a horribly ugly function used to output - the PQP HTML. This is great because it will just work in your project, - but it is hard to maintain and read. See the README file for how to use - the Smarty file we provided with PQP. - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -function displayPqp($output) { - - $css = preg_replace('/[\n\r]/', '', << - -JAVASCRIPT; - -$return_output .='
    '; - - return $return_output; -} diff --git a/fuel/core/vendor/phpquickprofiler/phpquickprofiler.php b/fuel/core/vendor/phpquickprofiler/phpquickprofiler.php deleted file mode 100755 index 8acea42..0000000 --- a/fuel/core/vendor/phpquickprofiler/phpquickprofiler.php +++ /dev/null @@ -1,234 +0,0 @@ -startTime = $startTime; - $this->config = $config; - } - - /*------------------------------------------- - FORMAT THE DIFFERENT TYPES OF LOGS - -------------------------------------------*/ - - public function gatherConsoleData() { - $logs = Console::getLogs(); - if($logs['console']) { - foreach($logs['console'] as $key => $log) { - if($log['type'] == 'log') { - $logs['console'][$key]['data'] = print_r($log['data'], true); - } - elseif($log['type'] == 'memory') { - $logs['console'][$key]['data'] = $this->getReadableFileSize($log['data']); - } - elseif($log['type'] == 'speed') { - $logs['console'][$key]['data'] = $this->getReadableTime(($log['data'] - $this->startTime)*1000); - } - } - } - $this->output['logs'] = $logs; - } - - /*------------------------------------------- - AGGREGATE DATA ON THE PATHS ADDED - -------------------------------------------*/ - - public function gatherPathData() - { - $this->output['paths'] = \Finder::instance()->paths(); - $this->output['pathTotals'] = array( - 'count' => count($this->output['paths']), - ); - } - - /*------------------------------------------- - AGGREGATE DATA ON THE FILES INCLUDED - -------------------------------------------*/ - - public function gatherFileData() { - $files = get_included_files(); - $fileList = array(); - $fileTotals = array( - "count" => count($files), - "size" => 0, - "largest" => 0, - ); - - foreach($files as $key => $file) { - $size = filesize($file); - $fileList[] = array( - 'name' => $file, - 'size' => $this->getReadableFileSize($size) - ); - $fileTotals['size'] += $size; - if($size > $fileTotals['largest']) $fileTotals['largest'] = $size; - } - - $fileTotals['size'] = $this->getReadableFileSize($fileTotals['size']); - $fileTotals['largest'] = $this->getReadableFileSize($fileTotals['largest']); - $this->output['files'] = $fileList; - $this->output['fileTotals'] = $fileTotals; - } - - /*------------------------------------------- - MEMORY USAGE AND MEMORY AVAILABLE - -------------------------------------------*/ - - public function gatherMemoryData() { - $memoryTotals = array(); - $memoryTotals['used'] = $this->getReadableFileSize(memory_get_peak_usage()); - $memoryTotals['total'] = ini_get("memory_limit"); - $this->output['memoryTotals'] = $memoryTotals; - } - - /*-------------------------------------------------------- - QUERY DATA -- DATABASE OBJECT WITH LOGGING REQUIRED - ----------------------------------------------------------*/ - - public function gatherQueryData() { - $queryTotals = array(); - $queryTotals['count'] = 0; - $queryTotals['time'] = 0; - $queryTotals['duplicates'] = 0; - $queries = array(); - $unique_queries = array(); - - if($this->db != '') { - $queryTotals['count'] += $this->db->queryCount; - foreach($this->db->queries as $key => $query) { - $query = $this->attemptToExplainQuery($query); - $queryTotals['time'] += $query['time']; - $query['time'] = $this->getReadableTime($query['time']); - $duplicate = false; - if ( in_array($query['sql'], $unique_queries) ) { - $duplicate = true; - $queryTotals['duplicates']++; - } - else { - $unique_queries[] = $query['sql']; - } - $query['duplicate'] = $duplicate; - $queries[] = $query; - } - } - - $queryTotals['time'] = $this->getReadableTime($queryTotals['time']); - $this->output['queries'] = $queries; - $this->output['queryTotals'] = $queryTotals; - } - - /*-------------------------------------------------------- - CALL SQL EXPLAIN ON THE QUERY TO FIND MORE INFO - ----------------------------------------------------------*/ - - function attemptToExplainQuery($query) { - if (substr($query['sql'],0,6) == 'SELECT') - { - $rs = false; - try { - $sql = 'EXPLAIN '.html_entity_decode($query['sql'], ENT_QUOTES); - $rs = \DB::query($sql, \DB::SELECT)->execute($query['dbname'])->as_array(); - } - catch(Exception $e) - {} - - if($rs) { - $query['explain'] = $rs; - } - } - return $query; - } - - /*------------------------------------------- - SPEED DATA FOR ENTIRE PAGE LOAD - -------------------------------------------*/ - - public function gatherSpeedData() { - $speedTotals = array(); - $speedTotals['total'] = $this->getReadableTime((static::getMicroTime() - $this->startTime)*1000); - $speedTotals['allowed'] = ini_get("max_execution_time"); - $this->output['speedTotals'] = $speedTotals; - } - - /*------------------------------------------- - HELPER FUNCTIONS TO FORMAT DATA - -------------------------------------------*/ - - public static function getMicroTime() { - $time = microtime(); - $time = explode(' ', $time); - return $time[1] + $time[0]; - } - - public function getReadableFileSize($size, $retstring = null) { - // adapted from code at http://aidanlister.com/repos/v/function.size_readable.php - $sizes = array('bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); - - if ($retstring === null) { $retstring = '%01.2f %s'; } - - $lastsizestring = end($sizes); - - foreach ($sizes as $sizestring) { - if ($size < 1024) { break; } - if ($sizestring != $lastsizestring) { $size /= 1024; } - } - if ($sizestring == $sizes[0]) { $retstring = '%01d %s'; } // Bytes aren't normally fractional - return sprintf($retstring, $size, $sizestring); - } - - public function getReadableTime($time) { - $ret = $time; - $formatter = 0; - $formats = array('ms', 's', 'm'); - if($time >= 1000 && $time < 60000) { - $formatter = 1; - $ret = ($time / 1000); - } - if($time >= 60000) { - $formatter = 2; - $ret = ($time / 1000) / 60; - } - $ret = number_format($ret,3,'.','') . ' ' . $formats[$formatter]; - return $ret; - } - - /*--------------------------------------------------------- - DISPLAY TO THE SCREEN -- CALL WHEN CODE TERMINATING - -----------------------------------------------------------*/ - - public function display($db = '') { - $this->db = $db; - $this->gatherConsoleData(); - $this->gatherPathData(); - $this->gatherFileData(); - $this->gatherMemoryData(); - $this->gatherQueryData(); - $this->gatherSpeedData(); - require_once('display.php'); - if (function_exists('displayPqp')) - { - return displayPqp($this->output); - } - } - -} - -?> diff --git a/fuel/core/vendor/spyc/spyc.php b/fuel/core/vendor/spyc/spyc.php deleted file mode 100755 index e19d562..0000000 --- a/fuel/core/vendor/spyc/spyc.php +++ /dev/null @@ -1,1046 +0,0 @@ - - * @author Chris Wanstrath - * @link http://code.google.com/p/spyc/ - * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen - * @license http://www.opensource.org/licenses/mit-license.php MIT License - * @package Spyc - */ - -if (!function_exists('spyc_load')) { - /** - * Parses YAML to array. - * @param string $string YAML string. - * @return array - */ - function spyc_load ($string) { - return Spyc::YAMLLoadString($string); - } -} - -if (!function_exists('spyc_load_file')) { - /** - * Parses YAML to array. - * @param string $file Path to YAML file. - * @return array - */ - function spyc_load_file ($file) { - return Spyc::YAMLLoad($file); - } -} - -/** - * The Simple PHP YAML Class. - * - * This class can be used to read a YAML file and convert its contents - * into a PHP array. It currently supports a very limited subsection of - * the YAML spec. - * - * Usage: - * - * $Spyc = new Spyc; - * $array = $Spyc->load($file); - * - * or: - * - * $array = Spyc::YAMLLoad($file); - * - * or: - * - * $array = spyc_load_file($file); - * - * @package Spyc - */ -class Spyc { - - // SETTINGS - - const REMPTY = "\0\0\0\0\0"; - - /** - * Setting this to true will force YAMLDump to enclose any string value in - * quotes. False by default. - * - * @var bool - */ - public $setting_dump_force_quotes = false; - - /** - * Setting this to true will forse YAMLLoad to use syck_load function when - * possible. False by default. - * @var bool - */ - public $setting_use_syck_is_possible = false; - - - - /**#@+ - * @access private - * @var mixed - */ - private $_dumpIndent; - private $_dumpWordWrap; - private $_containsGroupAnchor = false; - private $_containsGroupAlias = false; - private $path; - private $result; - private $LiteralPlaceHolder = '___YAML_Literal_Block___'; - private $SavedGroups = array(); - private $indent; - /** - * Path modifier that should be applied after adding current element. - * @var array - */ - private $delayedPath = array(); - - /**#@+ - * @access public - * @var mixed - */ - public $_nodeId; - -/** - * Load a valid YAML string to Spyc. - * @param string $input - * @return array - */ - public function load ($input) { - return $this->__loadString($input); - } - - /** - * Load a valid YAML file to Spyc. - * @param string $file - * @return array - */ - public function loadFile ($file) { - return $this->__load($file); - } - - /** - * Load YAML into a PHP array statically - * - * The load method, when supplied with a YAML stream (string or file), - * will do its best to convert YAML in a file into a PHP array. Pretty - * simple. - * Usage: - * - * $array = Spyc::YAMLLoad('lucky.yaml'); - * print_r($array); - * - * @access public - * @return array - * @param string $input Path of YAML file or string containing YAML - */ - public static function YAMLLoad($input) { - $Spyc = new Spyc; - return $Spyc->__load($input); - } - - /** - * Load a string of YAML into a PHP array statically - * - * The load method, when supplied with a YAML string, will do its best - * to convert YAML in a string into a PHP array. Pretty simple. - * - * Note: use this function if you don't want files from the file system - * loaded and processed as YAML. This is of interest to people concerned - * about security whose input is from a string. - * - * Usage: - * - * $array = Spyc::YAMLLoadString("---\n0: hello world\n"); - * print_r($array); - * - * @access public - * @return array - * @param string $input String containing YAML - */ - public static function YAMLLoadString($input) { - $Spyc = new Spyc; - return $Spyc->__loadString($input); - } - - /** - * Dump YAML from PHP array statically - * - * The dump method, when supplied with an array, will do its best - * to convert the array into friendly YAML. Pretty simple. Feel free to - * save the returned string as nothing.yaml and pass it around. - * - * Oh, and you can decide how big the indent is and what the wordwrap - * for folding is. Pretty cool -- just pass in 'false' for either if - * you want to use the default. - * - * Indent's default is 2 spaces, wordwrap's default is 40 characters. And - * you can turn off wordwrap by passing in 0. - * - * @access public - * @return string - * @param array $array PHP array - * @param int $indent Pass in false to use the default, which is 2 - * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) - */ - public static function YAMLDump($array,$indent = false,$wordwrap = false) { - $spyc = new Spyc; - return $spyc->dump($array,$indent,$wordwrap); - } - - - /** - * Dump PHP array to YAML - * - * The dump method, when supplied with an array, will do its best - * to convert the array into friendly YAML. Pretty simple. Feel free to - * save the returned string as tasteful.yaml and pass it around. - * - * Oh, and you can decide how big the indent is and what the wordwrap - * for folding is. Pretty cool -- just pass in 'false' for either if - * you want to use the default. - * - * Indent's default is 2 spaces, wordwrap's default is 40 characters. And - * you can turn off wordwrap by passing in 0. - * - * @access public - * @return string - * @param array $array PHP array - * @param int $indent Pass in false to use the default, which is 2 - * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) - */ - public function dump($array,$indent = false,$wordwrap = false) { - // Dumps to some very clean YAML. We'll have to add some more features - // and options soon. And better support for folding. - - // New features and options. - if ($indent === false or !is_numeric($indent)) { - $this->_dumpIndent = 2; - } else { - $this->_dumpIndent = $indent; - } - - if ($wordwrap === false or !is_numeric($wordwrap)) { - $this->_dumpWordWrap = 40; - } else { - $this->_dumpWordWrap = $wordwrap; - } - - // New YAML document - $string = "---\n"; - - // Start at the base of the array and move through it. - if ($array) { - $array = (array)$array; - $previous_key = -1; - foreach ($array as $key => $value) { - if (!isset($first_key)) $first_key = $key; - $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key, $array); - $previous_key = $key; - } - } - return $string; - } - - /** - * Attempts to convert a key / value array item to YAML - * @access private - * @return string - * @param $key The name of the key - * @param $value The value of the item - * @param $indent The indent of the current node - */ - private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) { - if (is_array($value)) { - if (empty ($value)) - return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array); - // It has children. What to do? - // Make it the right kind of item - $string = $this->_dumpNode($key, self::REMPTY, $indent, $previous_key, $first_key, $source_array); - // Add the indent - $indent += $this->_dumpIndent; - // Yamlize the array - $string .= $this->_yamlizeArray($value,$indent); - } elseif (!is_array($value)) { - // It doesn't have children. Yip. - $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key, $source_array); - } - return $string; - } - - /** - * Attempts to convert an array to YAML - * @access private - * @return string - * @param $array The array you want to convert - * @param $indent The indent of the current level - */ - private function _yamlizeArray($array,$indent) { - if (is_array($array)) { - $string = ''; - $previous_key = -1; - foreach ($array as $key => $value) { - if (!isset($first_key)) $first_key = $key; - $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key, $array); - $previous_key = $key; - } - return $string; - } else { - return false; - } - } - - /** - * Returns YAML from a key and a value - * @access private - * @return string - * @param $key The name of the key - * @param $value The value of the item - * @param $indent The indent of the current node - */ - private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null) { - // do some folding here, for blocks - if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false || - strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false || strpos ($value, ' ') !== false || - strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || strpos($value,"&") !== false || strpos($value, "'") !== false || strpos($value, "!") === 0 || - substr ($value, -1, 1) == ':') - ) { - $value = $this->_doLiteralBlock($value,$indent); - } else { - $value = $this->_doFolding($value,$indent); - } - - if ($value === array()) $value = '[ ]'; - if (in_array ($value, array ('true', 'TRUE', 'false', 'FALSE', 'y', 'Y', 'n', 'N', 'null', 'NULL'), true)) { - $value = $this->_doLiteralBlock($value,$indent); - } - if (trim ($value) != $value) - $value = $this->_doLiteralBlock($value,$indent); - - if (is_bool($value)) { - $value = ($value) ? "true" : "false"; - } - - if ($value === null) $value = 'null'; - if ($value === "'" . self::REMPTY . "'") $value = null; - - $spaces = str_repeat(' ',$indent); - - //if (is_int($key) && $key - 1 == $previous_key && $first_key===0) { - if (is_array ($source_array) && array_keys($source_array) === range(0, count($source_array) - 1)) { - // It's a sequence - $string = $spaces.'- '.$value."\n"; - } else { - // if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"'); - // It's mapped - if (strpos($key, ":") !== false || strpos($key, "#") !== false) { $key = '"' . $key . '"'; } - $string = rtrim ($spaces.$key.': '.$value)."\n"; - } - return $string; - } - - /** - * Creates a literal block for dumping - * @access private - * @return string - * @param $value - * @param $indent int The value of the indent - */ - private function _doLiteralBlock($value,$indent) { - if ($value === "\n") return '\n'; - if (strpos($value, "\n") === false && strpos($value, "'") === false) { - return sprintf ("'%s'", $value); - } - if (strpos($value, "\n") === false && strpos($value, '"') === false) { - return sprintf ('"%s"', $value); - } - $exploded = explode("\n",$value); - $newValue = '|'; - $indent += $this->_dumpIndent; - $spaces = str_repeat(' ',$indent); - foreach ($exploded as $line) { - $newValue .= "\n" . $spaces . ($line); - } - return $newValue; - } - - /** - * Folds a string of text, if necessary - * @access private - * @return string - * @param $value The string you wish to fold - */ - private function _doFolding($value,$indent) { - // Don't do anything if wordwrap is set to 0 - - if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) { - $indent += $this->_dumpIndent; - $indent = str_repeat(' ',$indent); - $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); - $value = ">\n".$indent.$wrapped; - } else { - if ($this->setting_dump_force_quotes && is_string ($value) && $value !== self::REMPTY) - $value = '"' . $value . '"'; - } - - - return $value; - } - -// LOADING FUNCTIONS - - private function __load($input) { - $Source = $this->loadFromSource($input); - return $this->loadWithSource($Source); - } - - private function __loadString($input) { - $Source = $this->loadFromString($input); - return $this->loadWithSource($Source); - } - - private function loadWithSource($Source) { - if (empty ($Source)) return array(); - if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) { - $array = syck_load (implode ('', $Source)); - return is_array($array) ? $array : array(); - } - - $this->path = array(); - $this->result = array(); - - $cnt = count($Source); - for ($i = 0; $i < $cnt; $i++) { - $line = $Source[$i]; - - $this->indent = strlen($line) - strlen(ltrim($line)); - $tempPath = $this->getParentPathByIndent($this->indent); - $line = self::stripIndent($line, $this->indent); - if (self::isComment($line)) continue; - if (self::isEmpty($line)) continue; - $this->path = $tempPath; - - $literalBlockStyle = self::startsLiteralBlock($line); - if ($literalBlockStyle) { - $line = rtrim ($line, $literalBlockStyle . " \n"); - $literalBlock = ''; - $line .= $this->LiteralPlaceHolder; - $literal_block_indent = strlen($Source[$i+1]) - strlen(ltrim($Source[$i+1])); - while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) { - $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle, $literal_block_indent); - } - $i--; - } - - while (++$i < $cnt && self::greedilyNeedNextLine($line)) { - $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t"); - } - $i--; - - - - if (strpos ($line, '#')) { - if (strpos ($line, '"') === false && strpos ($line, "'") === false) - $line = preg_replace('/\s+#(.+)$/','',$line); - } - - $lineArray = $this->_parseLine($line); - - if ($literalBlockStyle) - $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock); - - $this->addArray($lineArray, $this->indent); - - foreach ($this->delayedPath as $indent => $delayedPath) - $this->path[$indent] = $delayedPath; - - $this->delayedPath = array(); - - } - return $this->result; - } - - private function loadFromSource ($input) { - if (!empty($input) && strpos($input, "\n") === false && file_exists($input)) - return file($input); - - return $this->loadFromString($input); - } - - private function loadFromString ($input) { - $lines = explode("\n",$input); - foreach ($lines as $k => $_) { - $lines[$k] = rtrim ($_, "\r"); - } - return $lines; - } - - /** - * Parses YAML code and returns an array for a node - * @access private - * @return array - * @param string $line A line from the YAML file - */ - private function _parseLine($line) { - if (!$line) return array(); - $line = trim($line); - if (!$line) return array(); - - $array = array(); - - $group = $this->nodeContainsGroup($line); - if ($group) { - $this->addGroup($line, $group); - $line = $this->stripGroup ($line, $group); - } - - if ($this->startsMappedSequence($line)) - return $this->returnMappedSequence($line); - - if ($this->startsMappedValue($line)) - return $this->returnMappedValue($line); - - if ($this->isArrayElement($line)) - return $this->returnArrayElement($line); - - if ($this->isPlainArray($line)) - return $this->returnPlainArray($line); - - - return $this->returnKeyValuePair($line); - - } - - /** - * Finds the type of the passed value, returns the value as the new type. - * @access private - * @param string $value - * @return mixed - */ - private function _toType($value) { - if ($value === '') return null; - $first_character = $value[0]; - $last_character = substr($value, -1, 1); - - $is_quoted = false; - do { - if (!$value) break; - if ($first_character != '"' && $first_character != "'") break; - if ($last_character != '"' && $last_character != "'") break; - $is_quoted = true; - } while (0); - - if ($is_quoted) - return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\'\'' => '\'', '\\\'' => '\'')); - - if (strpos($value, ' #') !== false && !$is_quoted) - $value = preg_replace('/\s+#(.+)$/','',$value); - - if (!$is_quoted) $value = str_replace('\n', "\n", $value); - - if ($first_character == '[' && $last_character == ']') { - // Take out strings sequences and mappings - $innerValue = trim(substr ($value, 1, -1)); - if ($innerValue === '') return array(); - $explode = $this->_inlineEscape($innerValue); - // Propagate value array - $value = array(); - foreach ($explode as $v) { - $value[] = $this->_toType($v); - } - return $value; - } - - if (strpos($value,': ')!==false && $first_character != '{') { - $array = explode(': ',$value); - $key = trim($array[0]); - array_shift($array); - $value = trim(implode(': ',$array)); - $value = $this->_toType($value); - return array($key => $value); - } - - if ($first_character == '{' && $last_character == '}') { - $innerValue = trim(substr ($value, 1, -1)); - if ($innerValue === '') return array(); - // Inline Mapping - // Take out strings sequences and mappings - $explode = $this->_inlineEscape($innerValue); - // Propagate value array - $array = array(); - foreach ($explode as $v) { - $SubArr = $this->_toType($v); - if (empty($SubArr)) continue; - if (is_array ($SubArr)) { - $array[key($SubArr)] = $SubArr[key($SubArr)]; continue; - } - $array[] = $SubArr; - } - return $array; - } - - if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') { - return null; - } - - if ( is_numeric($value) && preg_match ('/^(-|)[1-9]+[0-9]*$/', $value) ){ - $intvalue = (int)$value; - if ($intvalue != PHP_INT_MAX) - $value = $intvalue; - return $value; - } - - if (in_array($value, - array('true', 'on', '+', 'yes', 'y', 'True', 'TRUE', 'On', 'ON', 'YES', 'Yes', 'Y'))) { - return true; - } - - if (in_array(strtolower($value), - array('false', 'off', '-', 'no', 'n'))) { - return false; - } - - if (is_numeric($value)) { - if ($value === '0') return 0; - if (rtrim ($value, 0) === $value) - $value = (float)$value; - return $value; - } - - return $value; - } - - /** - * Used in inlines to check for more inlines or quoted strings - * @access private - * @return array - */ - private function _inlineEscape($inline) { - // There's gotta be a cleaner way to do this... - // While pure sequences seem to be nesting just fine, - // pure mappings and mappings with sequences inside can't go very - // deep. This needs to be fixed. - - $seqs = array(); - $maps = array(); - $saved_strings = array(); - - // Check for strings - $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; - if (preg_match_all($regex,$inline,$strings)) { - $saved_strings = $strings[0]; - $inline = preg_replace($regex,'YAMLString',$inline); - } - unset($regex); - - $i = 0; - do { - - // Check for sequences - while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) { - $seqs[] = $matchseqs[0]; - $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1); - } - - // Check for mappings - while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) { - $maps[] = $matchmaps[0]; - $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1); - } - - if ($i++ >= 10) break; - - } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false); - - $explode = explode(', ',$inline); - $stringi = 0; $i = 0; - - while (1) { - - // Re-add the sequences - if (!empty($seqs)) { - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLSeq') !== false) { - foreach ($seqs as $seqk => $seq) { - $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value); - $value = $explode[$key]; - } - } - } - } - - // Re-add the mappings - if (!empty($maps)) { - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLMap') !== false) { - foreach ($maps as $mapk => $map) { - $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value); - $value = $explode[$key]; - } - } - } - } - - - // Re-add the strings - if (!empty($saved_strings)) { - foreach ($explode as $key => $value) { - while (strpos($value,'YAMLString') !== false) { - $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1); - unset($saved_strings[$stringi]); - ++$stringi; - $value = $explode[$key]; - } - } - } - - $finished = true; - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLSeq') !== false) { - $finished = false; break; - } - if (strpos($value,'YAMLMap') !== false) { - $finished = false; break; - } - if (strpos($value,'YAMLString') !== false) { - $finished = false; break; - } - } - if ($finished) break; - - $i++; - if ($i > 10) - break; // Prevent infinite loops. - } - - return $explode; - } - - private function literalBlockContinues ($line, $lineIndent) { - if (!trim($line)) return true; - if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true; - return false; - } - - private function referenceContentsByAlias ($alias) { - do { - if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; } - $groupPath = $this->SavedGroups[$alias]; - $value = $this->result; - foreach ($groupPath as $k) { - $value = $value[$k]; - } - } while (false); - return $value; - } - - private function addArrayInline ($array, $indent) { - $CommonGroupPath = $this->path; - if (empty ($array)) return false; - - foreach ($array as $k => $_) { - $this->addArray(array($k => $_), $indent); - $this->path = $CommonGroupPath; - } - return true; - } - - private function addArray ($incoming_data, $incoming_indent) { - - // print_r ($incoming_data); - - if (count ($incoming_data) > 1) - return $this->addArrayInline ($incoming_data, $incoming_indent); - - $key = key ($incoming_data); - $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null; - if ($key === '__!YAMLZero') $key = '0'; - - if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values. - if ($key || $key === '' || $key === '0') { - $this->result[$key] = $value; - } else { - $this->result[] = $value; end ($this->result); $key = key ($this->result); - } - $this->path[$incoming_indent] = $key; - return; - } - - - - $history = array(); - // Unfolding inner array tree. - $history[] = $_arr = $this->result; - foreach ($this->path as $k) { - $history[] = $_arr = $_arr[$k]; - } - - if ($this->_containsGroupAlias) { - $value = $this->referenceContentsByAlias($this->_containsGroupAlias); - $this->_containsGroupAlias = false; - } - - - // Adding string or numeric key to the innermost level or $this->arr. - if (is_string($key) && $key == '<<') { - if (!is_array ($_arr)) { $_arr = array (); } - - $_arr = array_merge ($_arr, $value); - } else if ($key || $key === '' || $key === '0') { - if (!is_array ($_arr)) - $_arr = array ($key=>$value); - else - $_arr[$key] = $value; - } else { - if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; } - else { $_arr[] = $value; end ($_arr); $key = key ($_arr); } - } - - $reverse_path = array_reverse($this->path); - $reverse_history = array_reverse ($history); - $reverse_history[0] = $_arr; - $cnt = count($reverse_history) - 1; - for ($i = 0; $i < $cnt; $i++) { - $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i]; - } - $this->result = $reverse_history[$cnt]; - - $this->path[$incoming_indent] = $key; - - if ($this->_containsGroupAnchor) { - $this->SavedGroups[$this->_containsGroupAnchor] = $this->path; - if (is_array ($value)) { - $k = key ($value); - if (!is_int ($k)) { - $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k; - } - } - $this->_containsGroupAnchor = false; - } - - } - - private static function startsLiteralBlock ($line) { - $lastChar = substr (trim($line), -1); - if ($lastChar != '>' && $lastChar != '|') return false; - if ($lastChar == '|') return $lastChar; - // HTML tags should not be counted as literal blocks. - if (preg_match ('#<.*?>$#', $line)) return false; - return $lastChar; - } - - private static function greedilyNeedNextLine($line) { - $line = trim ($line); - if (!strlen($line)) return false; - if (substr ($line, -1, 1) == ']') return false; - if ($line[0] == '[') return true; - if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true; - return false; - } - - private function addLiteralLine ($literalBlock, $line, $literalBlockStyle, $indent = -1) { - $line = self::stripIndent($line, $indent); - if ($literalBlockStyle !== '|') { - $line = self::stripIndent($line); - } - $line = rtrim ($line, "\r\n\t ") . "\n"; - if ($literalBlockStyle == '|') { - return $literalBlock . $line; - } - if (strlen($line) == 0) - return rtrim($literalBlock, ' ') . "\n"; - if ($line == "\n" && $literalBlockStyle == '>') { - return rtrim ($literalBlock, " \t") . "\n"; - } - if ($line != "\n") - $line = trim ($line, "\r\n ") . " "; - return $literalBlock . $line; - } - - function revertLiteralPlaceHolder ($lineArray, $literalBlock) { - foreach ($lineArray as $k => $_) { - if (is_array($_)) - $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock); - else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder) - $lineArray[$k] = rtrim ($literalBlock, " \r\n"); - } - return $lineArray; - } - - private static function stripIndent ($line, $indent = -1) { - if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line)); - return substr ($line, $indent); - } - - private function getParentPathByIndent ($indent) { - if ($indent == 0) return array(); - $linePath = $this->path; - do { - end($linePath); $lastIndentInParentPath = key($linePath); - if ($indent <= $lastIndentInParentPath) array_pop ($linePath); - } while ($indent <= $lastIndentInParentPath); - return $linePath; - } - - - private function clearBiggerPathValues ($indent) { - - - if ($indent == 0) $this->path = array(); - if (empty ($this->path)) return true; - - foreach ($this->path as $k => $_) { - if ($k > $indent) unset ($this->path[$k]); - } - - return true; - } - - - private static function isComment ($line) { - if (!$line) return false; - if ($line[0] == '#') return true; - if (trim($line, " \r\n\t") == '---') return true; - return false; - } - - private static function isEmpty ($line) { - return (trim ($line) === ''); - } - - - private function isArrayElement ($line) { - if (!$line) return false; - if ($line[0] != '-') return false; - if (strlen ($line) > 3) - if (substr($line,0,3) == '---') return false; - - return true; - } - - private function isHashElement ($line) { - return strpos($line, ':'); - } - - private function isLiteral ($line) { - if ($this->isArrayElement($line)) return false; - if ($this->isHashElement($line)) return false; - return true; - } - - - private static function unquote ($value) { - if (!$value) return $value; - if (!is_string($value)) return $value; - if ($value[0] == '\'') return trim ($value, '\''); - if ($value[0] == '"') return trim ($value, '"'); - return $value; - } - - private function startsMappedSequence ($line) { - return ($line[0] == '-' && substr ($line, -1, 1) == ':'); - } - - private function returnMappedSequence ($line) { - $array = array(); - $key = self::unquote(trim(substr($line,1,-1))); - $array[$key] = array(); - $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key); - return array($array); - } - - private function returnMappedValue ($line) { - $array = array(); - $key = self::unquote (trim(substr($line,0,-1))); - $array[$key] = ''; - return $array; - } - - private function startsMappedValue ($line) { - return (substr ($line, -1, 1) == ':'); - } - - private function isPlainArray ($line) { - return ($line[0] == '[' && substr ($line, -1, 1) == ']'); - } - - private function returnPlainArray ($line) { - return $this->_toType($line); - } - - private function returnKeyValuePair ($line) { - $array = array(); - $key = ''; - if (strpos ($line, ':')) { - // It's a key/value pair most likely - // If the key is in double quotes pull it out - if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { - $value = trim(str_replace($matches[1],'',$line)); - $key = $matches[2]; - } else { - // Do some guesswork as to the key and the value - $explode = explode(':',$line); - $key = trim($explode[0]); - array_shift($explode); - $value = trim(implode(':',$explode)); - } - // Set the type of the value. Int, string, etc - $value = $this->_toType($value); - if ($key === '0') $key = '__!YAMLZero'; - $array[$key] = $value; - } else { - $array = array ($line); - } - return $array; - - } - - - private function returnArrayElement ($line) { - if (strlen($line) <= 1) return array(array()); // Weird %) - $array = array(); - $value = trim(substr($line,1)); - $value = $this->_toType($value); - $array[] = $value; - return $array; - } - - - private function nodeContainsGroup ($line) { - $symbolsForReference = 'A-z0-9_\-'; - if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-) - if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; - if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; - if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1]; - if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1]; - if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1]; - return false; - - } - - private function addGroup ($line, $group) { - if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1); - if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1); - //print_r ($this->path); - } - - private function stripGroup ($line, $group) { - $line = trim(str_replace($group, '', $line)); - return $line; - } -} - -// Enable use of Spyc from command line -// The syntax is the following: php spyc.php spyc.yaml - -define ('SPYC_FROM_COMMAND_LINE', false); - -do { - if (!SPYC_FROM_COMMAND_LINE) break; - if (empty ($_SERVER['argc']) || $_SERVER['argc'] < 2) break; - if (empty ($_SERVER['PHP_SELF']) || $_SERVER['PHP_SELF'] != 'spyc.php') break; - $file = $argv[1]; - printf ("Spyc loading file: %s\n", $file); - print_r (spyc_load_file ($file)); -} while (0); \ No newline at end of file diff --git a/fuel/core/views/400.php b/fuel/core/views/400.php deleted file mode 100755 index 4447851..0000000 --- a/fuel/core/views/400.php +++ /dev/null @@ -1,49 +0,0 @@ - - - - - 400 - Bad Request - - - -
    - -
    -

    The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).

    -
    -
    - - diff --git a/fuel/core/views/403.php b/fuel/core/views/403.php deleted file mode 100755 index e15df25..0000000 --- a/fuel/core/views/403.php +++ /dev/null @@ -1,49 +0,0 @@ - - - - - 403 - Forbidden - - - -
    - -
    -

    The request was a valid request, but the server is refusing to respond to it.

    -
    -
    - - diff --git a/fuel/core/views/404.php b/fuel/core/views/404.php deleted file mode 100755 index b1005bd..0000000 --- a/fuel/core/views/404.php +++ /dev/null @@ -1,49 +0,0 @@ - - - - - 404 - Page Not Found - - - -
    - -
    -

    You can see this page because the URL you are accessing cannot be found.

    -
    -
    - - diff --git a/fuel/core/views/500.php b/fuel/core/views/500.php deleted file mode 100755 index 9595b3c..0000000 --- a/fuel/core/views/500.php +++ /dev/null @@ -1,49 +0,0 @@ - - - - - 500 - Internal Server Error - - - -
    - -
    -

    Something has gone horribly wrong.

    -
    -
    - - diff --git a/fuel/core/views/errors/crypt_keys.php b/fuel/core/views/errors/crypt_keys.php deleted file mode 100755 index a70f0d7..0000000 --- a/fuel/core/views/errors/crypt_keys.php +++ /dev/null @@ -1,62 +0,0 @@ - - - - - Crypto key error - - - -
    -

    Crypto key error

    - -

    No write access to APPPATH/config/crypt.php.

    - -

    - The FuelPHP crypto functions require a set of unique and truelly random crypto keys. - These keys are automatically generated and written to the crypto configuration - file the first time the application accesses a crypto function. -

    - -

    Please copy the following code into APPPATH/config/crypt.php manually:

    -
    <?php
    -/**
    - * Part of the Fuel framework.
    - *
    - * @package    Fuel
    - * @version    1.8
    - * @author     Fuel Development Team
    - * @license    MIT License
    - * @copyright  2010 - 2016 Fuel Development Team
    - * @link       http://fuelphp.com
    - */
    -
    -return array (
    -	'crypto_key' => '',
    -	'crypto_iv' => '',
    -	'crypto_hmac' => '',
    -);
    -
    -
    -
    -		
    -	
    - - diff --git a/fuel/core/views/errors/php_error.php b/fuel/core/views/errors/php_error.php deleted file mode 100755 index 0a54370..0000000 --- a/fuel/core/views/errors/php_error.php +++ /dev/null @@ -1,12 +0,0 @@ -
    -

    !

    -

    [ ]:

    -

    @ line :

    -
    {$error_line}:\t".e(trim($debug_lines[$error_line]))."\n";
    -	echo ($error_line + 1).":\t".e(trim($debug_lines[$error_line + 1]))."\n";
    -endif;
    -?>
    -
    diff --git a/fuel/core/views/errors/php_fatal_error.php b/fuel/core/views/errors/php_fatal_error.php deleted file mode 100755 index 05c076a..0000000 --- a/fuel/core/views/errors/php_fatal_error.php +++ /dev/null @@ -1,102 +0,0 @@ - - - - - FuelPHP Framework - - - - -
    -

    !

    - -

    [ ]:

    - -

    @ line

    - - -
     $line_content): ?>
    ->
    -
    - -

    Backtrace

    -
      - -
    1. - -
      -
       $line_content): ?>
      ->
      -
      -
      -
    2. - -
    - - 0): ?> -

    Prior Non-Fatal Errors

    -
      - -
    1. - : in @ line -
      -
       $line_content): ?>
      ->
      -
      -
      -
    2. - -
    - - - -

    Prior Contents (show)

    - - - - - - - - - -
    - - diff --git a/fuel/core/views/errors/php_short.php b/fuel/core/views/errors/php_short.php deleted file mode 100755 index 79838b3..0000000 --- a/fuel/core/views/errors/php_short.php +++ /dev/null @@ -1 +0,0 @@ -: in diff --git a/fuel/core/views/errors/production.php b/fuel/core/views/errors/production.php deleted file mode 100755 index d9ce5da..0000000 --- a/fuel/core/views/errors/production.php +++ /dev/null @@ -1,21 +0,0 @@ - - - - - FuelPHP Framework - - - -
    -

    Oops!

    -

    An unexpected error has occurred.

    -
    - - diff --git a/fuel/packages/.gitkeep b/fuel/packages/.gitkeep deleted file mode 100755 index e69de29..0000000 diff --git a/fuel/packages/auth/.gitignore b/fuel/packages/auth/.gitignore deleted file mode 100755 index 5bb4b31..0000000 --- a/fuel/packages/auth/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*~ -*.bak -Thumbs.db -desktop.ini -.DS_Store -.buildpath -.project -.settings -nbproject/ -.idea \ No newline at end of file diff --git a/fuel/packages/auth/bootstrap.php b/fuel/packages/auth/bootstrap.php deleted file mode 100755 index 18dfc29..0000000 --- a/fuel/packages/auth/bootstrap.php +++ /dev/null @@ -1,48 +0,0 @@ - __DIR__.'/classes/auth.php', - 'Auth\\AuthException' => __DIR__.'/classes/auth.php', - - 'Auth\\Auth_Driver' => __DIR__.'/classes/auth/driver.php', - - 'Auth\\Auth_Opauth' => __DIR__.'/classes/auth/opauth.php', - - 'Auth\\Auth_Acl_Driver' => __DIR__.'/classes/auth/acl/driver.php', - 'Auth\\Auth_Acl_Simpleacl' => __DIR__.'/classes/auth/acl/simpleacl.php', - 'Auth\\Auth_Acl_Ormacl' => __DIR__.'/classes/auth/acl/ormacl.php', - - 'Auth\\Auth_Group_Driver' => __DIR__.'/classes/auth/group/driver.php', - 'Auth\\Auth_Group_Simplegroup' => __DIR__.'/classes/auth/group/simplegroup.php', - 'Auth\\Auth_Group_Ormgroup' => __DIR__.'/classes/auth/group/ormgroup.php', - - 'Auth\\Auth_Login_Driver' => __DIR__.'/classes/auth/login/driver.php', - 'Auth\\Auth_Login_Simpleauth' => __DIR__.'/classes/auth/login/simpleauth.php', - 'Auth\\Auth_Login_Ormauth' => __DIR__.'/classes/auth/login/ormauth.php', - - 'Auth\\SimpleUserUpdateException' => __DIR__.'/classes/auth/exceptions.php', - 'Auth\\SimpleUserWrongPassword' => __DIR__.'/classes/auth/exceptions.php', - 'Auth\\OpauthException' => __DIR__.'/classes/auth/exceptions.php', - - 'Auth\\Model\\Auth_User' => __DIR__.'/classes/model/auth/user.php', - 'Auth\\Model\\Auth_Userpermission' => __DIR__.'/classes/model/auth/userpermission.php', - 'Auth\\Model\\Auth_Metadata' => __DIR__.'/classes/model/auth/metadata.php', - 'Auth\\Model\\Auth_Group' => __DIR__.'/classes/model/auth/group.php', - 'Auth\\Model\\Auth_Grouppermission' => __DIR__.'/classes/model/auth/grouppermission.php', - 'Auth\\Model\\Auth_Role' => __DIR__.'/classes/model/auth/role.php', - 'Auth\\Model\\Auth_Rolepermission' => __DIR__.'/classes/model/auth/rolepermission.php', - 'Auth\\Model\\Auth_Permission' => __DIR__.'/classes/model/auth/permission.php', - 'Auth\\Model\\Auth_Provider' => __DIR__.'/classes/model/auth/provider.php', -)); diff --git a/fuel/packages/auth/classes/auth.php b/fuel/packages/auth/classes/auth.php deleted file mode 100755 index 804420b..0000000 --- a/fuel/packages/auth/classes/auth.php +++ /dev/null @@ -1,473 +0,0 @@ - 'member', - 'acl' => 'has_access', - ); - - public static function _init() - { - \Config::load('auth', true); - - foreach((array) \Config::get('auth.driver', array()) as $driver => $config) - { - $config = is_int($driver) - ? array('driver' => $config) - : array_merge($config, array('driver' => $driver)); - static::forge($config); - } - - // Set the first (or only) as the default instance for static usage - if ( ! empty(static::$_instances)) - { - static::$_instance = reset(static::$_instances); - static::check(); - } - } - - /** - * Load a login driver to the array of loaded drivers - * - * @param Array settings for the new driver - * @throws AuthException on driver load failure - */ - public static function forge($custom = array()) - { - // Driver is given as array key or just string in custom - $custom = ! is_array($custom) ? array('driver' => $custom) : $custom; - $config = \Config::get('auth.'.$custom['driver'].'_config', array()); - $config = array_merge($config, $custom); - - // Driver must be set - if (empty($config['driver']) || ! is_string($config['driver'])) - { - throw new \AuthException('No auth driver given.'); - } - - // determine the driver to load - $driver = \Auth_Login_Driver::forge($config); - - // get the driver's cookie name - $id = $driver->get_id(); - - // do we already have a driver instance for this cookie? - if (isset(static::$_instances[$id])) - { - // if so, they must be using the same driver class! - $class = get_class($driver); - if ( ! static::$_instances[$id] instanceof $class) - { - throw new \AuthException('You can not instantiate two different login drivers using the same id "'.$id.'"'); - } - } - else - { - // store this instance - static::$_instances[$id] = $driver; - } - - // If we have more then one driver instance, check if we need concurrency - if (count(static::$_instances) > 1) - { - // Whether to allow multiple drivers of any type, defaults to not allowed - static::$_verify_multiple = \Config::get('auth.verify_multiple_logins', false); - } - - return static::$_instances[$id]; - } - - /** - * Prevent instantiation - */ - final private function __construct() {} - - /** - * Remove individual driver, or all drivers of $type - * - * @param string driver id or null for default driver - * @throws AuthException when $driver_id isn't valid or true - */ - public static function unload($driver_id = null) - { - if ($driver_id === null && ! empty(static::$_instance)) - { - unset(static::$_instances[static::$_instance->get_id()]); - static::$_instance = null; - return true; - } - elseif (array_key_exists($driver_id, static::$_instances)) - { - return false; - } - - unset(static::$_instances[$driver_id]); - return true; - } - - /** - * Return a specific driver, or the default instance (is created if necessary) - * - * @param string driver id - * @return Auth_Login_Driver - */ - public static function instance($instance = null) - { - if ($instance !== null) - { - if ( ! array_key_exists($instance, static::$_instances)) - { - return false; - } - - return static::$_instances[$instance]; - } - - if (static::$_instance === null) - { - static::$_instance = static::forge(); - } - - return static::$_instance; - } - - /** - * Check login drivers for validated login - * - * @param string|Array specific driver or drivers, in this case it will always terminate after first success - * @return bool - */ - public static function check($specific = null) - { - $drivers = $specific === null ? static::$_instances : (array) $specific; - $verified = static::$_verified; - - if ($specific !== null) - { - $verified = array(); - foreach ($drivers as $i) - { - $i = $i instanceof Auth_Login_Driver ? $i : static::instance($i); - $key = $i->get_id(); - if (isset(static::$_verified[$key])) $verified[$key] = static::$_verified[$key]; - } - } - - foreach ($drivers as $i) - { - if ( ! static::$_verify_multiple && ! empty($verified)) - { - return true; - } - - $i = $i instanceof Auth_Login_Driver ? $i : static::instance($i); - if ( ! array_key_exists($i->get_id(), $verified)) - { - $i->check(); - } - - if ($specific) - { - if (array_key_exists($i->get_id(), $verified)) - { - return true; - } - } - } - - return $specific === null && ! empty($verified); - } - - /** - * Get verified driver or all verified drivers - * returns false when specific driver has not validated - * when all were requested and none validated an empty array is returned - * - * @param null|string driver id or null for all verified driver in an array - * @return Array|Auth_Login_Driver|false - */ - public static function verified($driver = null) - { - if ($driver === null) - { - return static::$_verified; - } - - if ( ! array_key_exists($driver, static::$_verified)) - { - return false; - } - - return static::$_verified[$driver]; - } - - /** - * Login user - * - * @param string - * @param string - * @return bool - */ - public static function login($username_or_email = '', $password = '') - { - $loggedin = false; - - foreach (static::$_instances as $i) - { - if ($i instanceof Auth_Login_Driver) - { - if ($i->login($username_or_email, $password)) - { - $loggedin = true; - if ( ! static::$_verify_multiple) - { - break; - } - } - } - } - - return $loggedin; - } - - /** - * Logs out all current logged in drivers - */ - public static function logout() - { - foreach (static::$_verified as $v) - { - $v->logout(); - } - - static::$_verified = array(); - } - - /** - * Register verified Login driver - * - * @param Auth_Login_Driver - */ - public static function _register_verified(Auth_Login_Driver $driver) - { - static::$_verified[$driver->get_id()] = $driver; - } - - /** - * Unregister verified Login driver - * - * @param Auth_Login_Driver - */ - public static function _unregister_verified(Auth_Login_Driver $driver) - { - unset(static::$_verified[$driver->get_id()]); - } - - /** - * Register a new driver type - * - * @param string name of the driver type, may not conflict with class method name - * @param string name of the method to use for checking this type of driver, also cannot conflict with method - * @return bool - */ - public static function register_driver_type($type, $check_method) - { - $driver_exists = ! is_string($type) - || array_key_exists($type, static::$_drivers) - || method_exists(get_called_class(), $check_method) - || in_array($type, array('login', 'group', 'acl')); - $method_exists = ! is_string($type) - || array_search($check_method, static::$_drivers) - || method_exists(get_called_class(), $type); - - if ($driver_exists && static::$_drivers[$type] == $check_method) - { - return true; - } - - if ($driver_exists || $method_exists) - { - \Errorhandler::notice('Cannot add driver type, its name conflicts with another driver or method.'); - return false; - } - - static::$_drivers[$type] = $check_method; - return true; - } - - /** - * Unregister a driver type - * - * @param string name of the driver type - * @return bool - */ - public static function unregister_driver_type($type) - { - if (in_array($type, array('login', 'group', 'acl'))) - { - \Errorhandler::notice('Cannot remove driver type, included drivers login, group and acl cannot be removed.'); - return false; - } - - unset(static::$_drivers[$type]); - return true; - } - - /** - * Magic method used to retrieve driver instances and check them for validity - * - * @param string - * @param array - * @return mixed - * @throws BadMethodCallException - */ - public static function __callStatic($method, $args) - { - $args = array_pad($args, 3, null); - if (array_key_exists($method, static::$_drivers)) - { - return static::_driver_instance($method, $args[0]); - } - if ($type = array_search($method, static::$_drivers)) - { - return static::_driver_check($type, $args[0], $args[1], @$args[2]); - } - if (static::$_verify_multiple !== true and method_exists(static::$_instance, $method)) - { - return call_fuel_func_array(array(static::$_instance, $method), $args); - } - - throw new \BadMethodCallException('Invalid method: '.get_called_class().'::'.$method); - } - - /** - * Retrieve a loaded driver instance - * (loading must be done by other driver class) - * - * @param string driver type - * @param string|true driver id or true for an array of all loaded drivers - * @return Auth_Driver|array - */ - protected static function _driver_instance($type, $instance) - { - $class = 'Auth_'.\Str::ucwords($type).'_Driver'; - return $class::instance($instance); - } - - /** - * Check driver - * - * @param string driver type - * @param mixed condition for which the driver is checked - * @param string driver id or null to check all - * @param Array identifier to check, should default to current user or relation therof and be - * in the form of array(driver_id, user_id) - * @return bool - */ - public static function _driver_check($type, $condition, $driver = null, $entity = null) - { - $method = static::$_drivers[$type]; - if ($driver === null) - { - if ($entity === null) - { - if ( ! empty(static::$_verified)) - { - foreach (static::$_verified as $v) - { - if ($v->$method($condition)) - { - return true; - } - } - } - else - { - foreach (static::$_instances as $i) - { - if ($i->guest_login() and $i->$method($condition)) - { - return true; - } - } - } - } - else - { - foreach (static::$_instances as $i) - { - if ($i->$method($condition, null, $entity)) - { - return true; - } - } - } - return false; - } - else - { - if ($entity === null) - { - foreach (static::$_verified as $v) - { - if (static::$type($driver)->$method($condition)) - { - return true; - } - } - } - elseif (static::$type($driver)->$method($condition, $entity)) - { - return true; - } - - return false; - } - } -} - -/* end of file auth.php */ diff --git a/fuel/packages/auth/classes/auth/acl/driver.php b/fuel/packages/auth/classes/auth/acl/driver.php deleted file mode 100755 index b3b2199..0000000 --- a/fuel/packages/auth/classes/auth/acl/driver.php +++ /dev/null @@ -1,101 +0,0 @@ -get_id()] = $driver; - is_null(static::$_instance) and static::$_instance = $driver; - - foreach ($driver->get_config('drivers', array()) as $type => $drivers) - { - foreach ($drivers as $d => $custom) - { - $custom = is_int($d) - ? array('driver' => $custom) - : array_merge($custom, array('driver' => $d)); - $class = 'Auth_'.\Str::ucwords($type).'_Driver'; - $class::forge($custom); - } - } - - return $driver; - } - - /** - * Parses a conditions string into it's array equivalent - * - * @rights mixed conditions array or string - * @return array conditions array formatted as array(area, rights) - * - */ - public static function _parse_conditions($rights) - { - // assime it's already a rights array - if (is_array($rights)) - { - return $rights; - } - - // no clue what this is? - if ( ! is_string($rights)) - { - throw new \InvalidArgumentException('Given rights where not formatted proppery. Formatting should be like area.right or area.[right, other_right]. Received: '.$rights); - } - - // deal with only area passed - elseif (strpos($rights, '.') === false) - { - $rights .= "."; - } - - list($area, $rights) = explode('.', $rights); - - if (substr($rights, 0, 1) == '[' and substr($rights, -1, 1) == ']') - { - $rights = preg_split('#( *)?,( *)?#', trim(substr($rights, 1, -1))); - } - - return array($area, $rights); - } - - // ------------------------------------------------------------------------ - - /** - * Check access rights - * - * @param mixed condition to check for access - * @param mixed user or group identifier in the form of array(driver_id, id) - * @return bool - */ - abstract public function has_access($condition, Array $entity); -} - -/* end of file driver.php */ diff --git a/fuel/packages/auth/classes/auth/acl/ormacl.php b/fuel/packages/auth/classes/auth/acl/ormacl.php deleted file mode 100755 index 3662a47..0000000 --- a/fuel/packages/auth/classes/auth/acl/ormacl.php +++ /dev/null @@ -1,298 +0,0 @@ -id : 0); - try - { - // cache in memory to avoid multiple cache hits for the same cache key - if ( ! isset($this->_acl_cache[$cache_key])) - { - $this->_acl_cache[$cache_key] = \Cache::get($cache_key); - } - list($current_rights, $revoked_rights, $global_access) = $this->_acl_cache[$cache_key]; - } - catch (\CacheNotFoundException $e) - { - $current_roles = array(); - - // if we have a group, add the roles assigned to this group - if ($entity[1]) - { - $current_roles = $entity[1]->roles; - } - - // if we have a user, add the roles directly assigned to the user - if ($user) - { - $current_roles = \Arr::merge($current_roles, $user->roles); - } - - foreach ($current_roles as $role) - { - // role grants all access - if ($role->filter == 'A') - { - $global_access = true; - } - - // role denies all access - elseif ($role->filter == 'D') - { - $global_access = false; - } - - // role defines a permission revocation - elseif ($role->filter == 'R') - { - // fetch the permissions of this role - foreach ($role->permissions as $permission) - { - isset($revoked_rights[$permission->area][$permission->permission]) or $revoked_rights[$permission->area][$permission->permission] = array(); - foreach ($role->rolepermission as $rolepermission) - { - if ($rolepermission->role_id == $role->id and $rolepermission->perms_id == $permission->id) - { - $revoked_rights[$permission->area][$permission->permission] = array_merge( - $revoked_rights[$permission->area][$permission->permission], - array_intersect_key( - $permission->actions ?: array(), - array_flip($rolepermission->actions ?: array()) - ) - ); - break; - } - } - } - } - - // standard role, add it to the current rights set - else - { - // fetch the permissions of this role - foreach ($role->permissions as $permission) - { - isset($current_rights[$permission->area][$permission->permission]) or $current_rights[$permission->area][$permission->permission] = array(); - foreach ($role->rolepermission as $rolepermission) - { - if ($rolepermission->role_id == $role->id and $rolepermission->perms_id == $permission->id) - { - $current_rights[$permission->area][$permission->permission] = array_merge( - $current_rights[$permission->area][$permission->permission], - array_intersect_key( - $permission->actions ?: array(), - array_flip($rolepermission->actions ?: array()) - ) - ); - break; - } - } - } - } - } - - // if this user doesn't have a global filter applied... - if (is_array($current_rights)) - { - if ($user) - { - // add the users group rights - if ($user->group) - { - foreach ($user->group->permissions as $permission) - { - isset($current_rights[$permission->area][$permission->permission]) or $current_rights[$permission->area][$permission->permission] = array(); - foreach ($user->group->grouppermission as $grouppermission) - { - if ($grouppermission->group_id == $user->group_id and $grouppermission->perms_id == $permission->id) - { - $current_rights[$permission->area][$permission->permission] = array_merge( - $current_rights[$permission->area][$permission->permission], - array_intersect_key( - $permission->actions ?: array(), - array_flip($grouppermission->actions ?: array()) - ) - ); - break; - } - } - } - } - - // add the users personal rights - foreach ($user->permissions as $permission) - { - isset($current_rights[$permission->area][$permission->permission]) or $current_rights[$permission->area][$permission->permission] = array(); - foreach ($user->userpermission as $userpermission) - { - if ($userpermission->user_id == $user->id and $userpermission->perms_id == $permission->id) - { - $current_rights[$permission->area][$permission->permission] = array_merge( - $current_rights[$permission->area][$permission->permission], - array_intersect_key( - $permission->actions ?: array(), - array_flip($userpermission->actions ?: array()) - ) - ); - break; - } - } - } - } - } - - // save the rights in the cache - $this->_acl_cache[$cache_key] = array($current_rights, $revoked_rights, $global_access); - \Cache::set($cache_key, $this->_acl_cache[$cache_key]); - } - - // check for a revocation first - foreach ($rights as $right) - { - // check revocation permissions - if ( isset($revoked_rights[$area]) and array_key_exists($right, $revoked_rights[$area])) - { - $revoked = true; - - // need to check any actions? - foreach ($actions as $action) - { - if ( ! in_array($action, $revoked_rights[$area][$right])) - { - $revoked = false; - break; - } - } - - // right revoked? - if ($revoked) - { - return false; - } - } - } - - // was a global filter applied? - if (is_bool($global_access)) - { - // we're done here - return $global_access; - } - - // start checking rights, terminate false when right not found - foreach ($rights as $right) - { - // check basic permissions - if ( ! isset($current_rights[$area]) or ! array_key_exists($right, $current_rights[$area])) - { - return false; - } - - // need to check any actions? - foreach ($actions as $action) - { - if ( ! in_array($action, $current_rights[$area][$right])) - { - return false; - } - } - } - - // all necessary rights were found, return true - return true; - } -} diff --git a/fuel/packages/auth/classes/auth/acl/simpleacl.php b/fuel/packages/auth/classes/auth/acl/simpleacl.php deleted file mode 100755 index f3f14bc..0000000 --- a/fuel/packages/auth/classes/auth/acl/simpleacl.php +++ /dev/null @@ -1,84 +0,0 @@ -get_roles($entity[1]); - $current_rights = array(); - if (is_array($current_roles)) - { - $roles = \Config::get('simpleauth.roles', array()); - array_key_exists('#', $roles) && array_unshift($current_roles, '#'); - foreach ($current_roles as $r_role) - { - // continue if the role wasn't found - if ( ! array_key_exists($r_role, $roles)) - { - continue; - } - $r_rights = $roles[$r_role]; - - // if one of the roles has a negative or positive wildcard return it without question - if (is_bool($r_rights)) - { - return $r_rights; - } - // if there are roles for the current area, merge them with earlier fetched roles - elseif (array_key_exists($area, $r_rights)) - { - $current_rights = array_unique(array_merge($current_rights, $r_rights[$area])); - } - } - } - - // start checking rights, terminate false when right not found - foreach ($rights as $right) - { - if ( ! in_array($right, $current_rights)) - { - return false; - } - } - - // all necessary rights were found, return true - return true; - } -} - -/* end of file simpleacl.php */ diff --git a/fuel/packages/auth/classes/auth/driver.php b/fuel/packages/auth/classes/auth/driver.php deleted file mode 100755 index c7e9fc9..0000000 --- a/fuel/packages/auth/classes/auth/driver.php +++ /dev/null @@ -1,121 +0,0 @@ -id = $config['id']; - $this->config = array_merge($this->config, $config); - } - - /** - * Get driver instance ID - * - * @return string - */ - public function get_id() - { - return (string) $this->id; - } - - /** - * Create or change config value - * - * @param string - * @param mixed - */ - public function set_config($key, $value) - { - $this->config[$key] = $value; - } - - /** - * Retrieve config value - * - * @param string - * @param mixed return when key doesn't exist - * @return mixed - */ - public function get_config($key, $default = null) - { - return array_key_exists($key, $this->config) ? $this->config[$key] : $default; - } - - /** - * Whether this driver supports guest login - * - * @return bool - */ - public function guest_login() - { - return false; - } -} - -/* end of file driver.php */ diff --git a/fuel/packages/auth/classes/auth/exceptions.php b/fuel/packages/auth/classes/auth/exceptions.php deleted file mode 100755 index 7e02c4e..0000000 --- a/fuel/packages/auth/classes/auth/exceptions.php +++ /dev/null @@ -1,19 +0,0 @@ -get_id()] = $driver; - is_null(static::$_instance) and static::$_instance = $driver; - - foreach ($driver->get_config('drivers', array()) as $type => $drivers) - { - foreach ($drivers as $d => $custom) - { - $custom = is_int($d) - ? array('driver' => $custom) - : array_merge($custom, array('driver' => $d)); - $class = 'Auth_'.\Str::ucwords($type).'_Driver'; - $class::forge($custom); - } - } - - return $driver; - } - - // ------------------------------------------------------------------------ - - /** - * Verify Acl access - * - * @param mixed condition to validate - * @param string acl driver id or null to check all - * @param array user identifier to check in form array(driver_id, user_id) - * @return bool - */ - public function has_access($condition, $driver, $group = null) - { - // When group was given just check the group - if (is_array($group)) - { - if ($driver === null) - { - foreach (\Auth::acl(true) as $acl) - { - if ($acl->has_access($condition, $group)) - { - return true; - } - } - - return false; - } - - return \Auth::acl($driver)->has_access($condition, $group); - } - - // When no group was given check all logged in users - foreach (\Auth::verified() as $v) - { - // ... and check all those their groups - $gs = $v->get_groups(); - foreach ($gs as $g_id) - { - // ... and try to validate if its group is this one - if ($this->id = $g_id[0]) - { - if ($this->has_access($condition, $driver, $g_id)) - { - return true; - } - } - } - } - - // when nothing validated yet: it has failed to - return false; - } - - // ------------------------------------------------------------------------ - - /** - * Check membership of given users - * - * @param mixed condition to check for access - * @param array user identifier in the form of array(driver_id, user_id), or null for logged in - * @return bool - */ - abstract public function member($group, $user = null); - - /** - * Fetch the display name of the given group - * - * @param mixed group condition to check - * @return string - */ - abstract public function get_name($group); -} - -/* end of file driver.php */ diff --git a/fuel/packages/auth/classes/auth/group/ormgroup.php b/fuel/packages/auth/classes/auth/group/ormgroup.php deleted file mode 100755 index 5a83dd4..0000000 --- a/fuel/packages/auth/classes/auth/group/ormgroup.php +++ /dev/null @@ -1,172 +0,0 @@ - array('acl' => array('Ormacl')), - ); - - /* - * Return the list of defined groups - */ - public function groups() - { - return static::$_valid_groups; - } - - /* - * check for group membership - */ - public function member($group_id, $user = null) - { - // if it's not a group id, fetch it from the object - if ( ! is_numeric($group_id)) - { - $group_id = $group_id->id; - } - - // do we know this group? - if (isset(static::$_valid_groups[$group_id])) - { - // if no user is given - if ($user === null) - { - // get the groups of the logged-in user - $groups = \Auth::instance()->get_groups(); - } - else - { - // get the groups if the given user instance - $groups = \Auth::instance($user[0])->get_groups(); - } - - // if no group info could be retrieved, the user can't be a member - if ( ! $groups) - { - return false; - } - - // check for membership - foreach($groups as $group) - { - if ($group[0] === $this->id and (int) $group_id === (int) $group[1]->id) - { - return true; - } - } - } - - return false; - } - - /* - * get the name of a specific group, or of the users default group - */ - public function get_name($group = null) - { - // if no group is given - if ($group === null) - { - // try get the the group assigned to the logged-in user - if ( ! $login = \Auth::instance() or ! is_array($groups = $login->get_groups())) - { - return false; - } - $group = isset($groups[0][1]) ? $groups[0][1] : null; - } - - // if it's a group id, find the corresponding object - elseif (is_numeric($group) and isset(static::$_valid_groups[$group])) - { - $group = static::$_valid_groups[$group]; - } - - // if the group was found, return the name - if ($group instanceOf Model\Auth_Group) - { - return $group->name; - } - else - { - // no group found, so no name either - return null; - } - } - - /* - * get the roles assigned to a group, or to the users default group - */ - public function get_roles($group = null) - { - // When group is empty, attempt to get groups from a current login - if ($group === null) - { - if ($login = \Auth::instance() - and is_array($groups = $login->get_groups()) - and isset($groups[0][1])) - { - $group = $groups[0][1]; - } - } - - // if it's a group id, find the corresponding object - elseif (is_numeric($group) and isset(static::$_valid_groups[$group])) - { - $group = static::$_valid_groups[$group]; - } - - // if the group was found, return the roles - if ($group instanceOf Model\Auth_Group) - { - return $group->roles; - } - else - { - // no group found, so no roles either - return array(); - } - } -} diff --git a/fuel/packages/auth/classes/auth/group/simplegroup.php b/fuel/packages/auth/classes/auth/group/simplegroup.php deleted file mode 100755 index 3655891..0000000 --- a/fuel/packages/auth/classes/auth/group/simplegroup.php +++ /dev/null @@ -1,89 +0,0 @@ - array('acl' => array('Simpleacl')), - ); - - public function groups() - { - return static::$_valid_groups; - } - - public function member($group, $user = null) - { - if ($user === null) - { - $groups = \Auth::instance()->get_groups(); - } - else - { - $groups = \Auth::instance($user[0])->get_groups(); - } - - if ( ! $groups || ! in_array((int) $group, static::$_valid_groups)) - { - return false; - } - - return in_array(array($this->id, $group), $groups); - } - - public function get_name($group = null) - { - if ($group === null) - { - if ( ! $login = \Auth::instance() or ! is_array($groups = $login->get_groups())) - { - return false; - } - $group = isset($groups[0][1]) ? $groups[0][1] : null; - } - - return \Config::get('simpleauth.groups.'.$group.'.name', null); - } - - public function get_roles($group = null) - { - // When group is empty, attempt to get groups from a current login - if ($group === null) - { - if ( ! $login = \Auth::instance() - or ! is_array($groups = $login->get_groups()) - or ! isset($groups[0][1])) - { - return array(); - } - $group = $groups[0][1]; - } - elseif ( ! in_array((int) $group, static::$_valid_groups)) - { - return array(); - } - - $groups = \Config::get('simpleauth.groups'); - return $groups[(int) $group]['roles']; - } -} - -/* end of file simplegroup.php */ diff --git a/fuel/packages/auth/classes/auth/login/driver.php b/fuel/packages/auth/classes/auth/login/driver.php deleted file mode 100755 index 3ae24cb..0000000 --- a/fuel/packages/auth/classes/auth/login/driver.php +++ /dev/null @@ -1,319 +0,0 @@ -get_id()] = $driver; - is_null(static::$_instance) and static::$_instance = $driver; - - foreach ($driver->get_config('drivers', array()) as $type => $drivers) - { - foreach ($drivers as $d => $custom) - { - $custom = is_int($d) - ? array('driver' => $custom) - : array_merge($custom, array('driver' => $d)); - $class = 'Auth_'.\Str::ucwords($type).'_Driver'; - $class::forge($custom); - } - } - - return $driver; - } - - // ------------------------------------------------------------------------ - - /** - * @var array config values - */ - protected $config = array(); - - /** - * Check for login - * (final method to (un)register verification, work is done by _check()) - * - * @return bool - */ - final public function check() - { - if ( ! $this->perform_check()) - { - \Auth::_unregister_verified($this); - return false; - } - - \Auth::_register_verified($this); - return true; - } - - /** - * Return user info in an array, always includes email & screen_name - * Additional fields can be requested in the first param or set in config, - * all additional fields must have their own method "get_" + fieldname - * - * @param array additional fields - * @return array - */ - final public function get_user_array(Array $additional_fields = array()) - { - $user = array( - 'email' => $this->get_email(), - 'screen_name' => $this->get_screen_name(), - 'groups' => $this->get_groups(), - ); - - $additional_fields = array_merge($this->config['additional_fields'], $additional_fields); - foreach($additional_fields as $af) - { - // only works if it actually can be fetched through a get_ method - if (is_callable(array($this, $method = 'get_'.$af))) - { - $user[$af] = $this->$method(); - } - } - return $user; - } - - /** - * Verify Group membership - * - * @param mixed group identifier to check for membership - * @param string group driver id or null to check all - * @param array user identifier to check in form array(driver_id, user_id) - * @return bool - */ - public function member($group, $driver = null, $user = null) - { - $user = $user ?: $this->get_user_id(); - - if ($driver === null) - { - foreach (\Auth::group(true) as $g) - { - if ($g->member($group, $user)) - { - return true; - } - } - - return false; - } - - return \Auth::group($driver)->member($group, $user); - } - - /** - * Verify Acl access - * - * @param mixed condition to validate - * @param string acl driver id or null to check all - * @param array user identifier to check in form array(driver_id, user_id) - * @return bool - */ - public function has_access($condition, $driver = null, $entity = null) - { - $entity = $entity ?: $this->get_user_id(); - - if ($driver === null) - { - foreach (\Auth::acl(true) as $acl) - { - if ($acl->has_access($condition, $entity)) - { - return true; - } - } - - return false; - } - - return \Auth::acl($driver)->has_access($condition, $entity); - } - - /** - * Default password hash method - * - * @param string - * @return string - */ - public function hash_password($password) - { - return base64_encode(hash_pbkdf2('sha256', $password, \Config::get('auth.salt'), \Config::get('auth.iterations', 10000), 32, true)); - } - - /** - * Returns the list of defined groups - * - * @return array - */ - public function groups($driver = null) - { - $result = array(); - - if ($driver === null) - { - foreach (\Auth::group(true) as $group) - { - method_exists($group, 'groups') and $result = \Arr::merge($result, $group->groups()); - } - } - else - { - $result = \Auth::group($driver)->groups(); - } - - return $result; - } - - /** - * Returns the list of defined roles - * - * @return array - */ - public function roles($driver = null) - { - $result = array(); - - if ($driver === null) - { - foreach (\Auth::acl(true) as $acl) - { - method_exists($acl, 'roles') and $result = \Arr::merge($result, $acl->roles()); - } - } - else - { - $result = \Auth::acl($driver)->roles(); - } - - return $result; - } - - // ------------------------------------------------------------------------ - - /** - * Set a remember-me cookie for the passed user id, or for the current - * logged-in user if no id was given - * - * @return bool whether or not the cookie was set - */ - public function remember_me($user_id = null) - { - // if no user-id is given, get the current user's id - if ($user_id === null and isset($this->user['id'])) - { - $user_id = $this->user['id']; - } - - // if we have a session and an id, set it - if (static::$remember_me and $user_id) - { - static::$remember_me->set('user_id', $user_id); - return true; - } - - // remember-me not enabled, or no user id available - return false; - } - - /** - * Remove any remember-me cookie stored - */ - public function dont_remember_me() - { - static::$remember_me and static::$remember_me->destroy(); - } - - // ------------------------------------------------------------------------ - - /** - * Perform the actual login check - * - * @return bool - */ - abstract protected function perform_check(); - - /** - * Perform the actual login check - * - * @return bool - */ - abstract public function validate_user(); - - /** - * Login method - * - * @return bool whether login succeeded - */ - abstract public function login(); - - /** - * Logout method - */ - abstract public function logout(); - - /** - * Get User Identifier of the current logged in user - * in the form: array(driver_id, user_id) - * - * @return array - */ - abstract public function get_user_id(); - - /** - * Get User Groups of the current logged in user - * in the form: array(array(driver_id, group_id), array(driver_id, group_id), etc) - * - * @return array - */ - abstract public function get_groups(); - - /** - * Get emailaddress of the current logged in user - * - * @return string - */ - abstract public function get_email(); - - /** - * Get screen name of the current logged in user - * - * @return string - */ - abstract public function get_screen_name(); -} - -/* end of file driver.php */ diff --git a/fuel/packages/auth/classes/auth/login/ormauth.php b/fuel/packages/auth/classes/auth/login/ormauth.php deleted file mode 100755 index 0ebbc08..0000000 --- a/fuel/packages/auth/classes/auth/login/ormauth.php +++ /dev/null @@ -1,703 +0,0 @@ - 'cookie', - 'cookie' => array( - 'cookie_name' => \Config::get('ormauth.remember_me.cookie_name', 'rmcookie'), - ), - 'encrypt_cookie' => true, - 'expire_on_close' => false, - 'expiration_time' => \Config::get('ormauth.remember_me.expiration', 86400 * 31), - )); - } - } - - /** - * @var \Model\Auth_User user object for the current user - */ - protected $user = null; - - /** - * @var array Simpleauth compatible permissions array for the current logged-in user - */ - protected $permissions = array(); - - /** - * @var array Ormauth class config - */ - protected $config = array( - 'drivers' => array('group' => array('Ormgroup')), - 'additional_fields' => array(), - ); - - /** - * Check the user exists - * - * @return bool - */ - public function validate_user($username_or_email = '', $password = '') - { - // get the user identification and password - $username_or_email = trim($username_or_email) ?: trim(\Input::post(\Config::get('ormauth.username_post_key', 'username'))); - $password = trim($password) ?: trim(\Input::post(\Config::get('ormauth.password_post_key', 'password'))); - - // and make sure we have both - if (empty($username_or_email) or empty($password)) - { - return false; - } - - // hash the password - $password = $this->hash_password($password); - - // and do a lookup of this user - $user = \Model\Auth_User::query() - ->select(\Config::get('ormauth.table_columns', array())) - ->related('metadata') - ->where_open() - ->where('username', '=', $username_or_email) - ->or_where('email', '=', $username_or_email) - ->where_close() - ->where('password', '=', $password) - ->get_one(); - - // return the user object, or false if not found - return $user ?: false; - } - - /** - * Login user - * - * @param string - * @param string - * @return bool - */ - public function login($username_or_email = '', $password = '') - { - if ( ! ($this->user = $this->validate_user($username_or_email, $password))) - { - // force a logout - $this->logout(); - - // and signal a failed login - return false; - } - - // register so Auth::logout() can find us - Auth::_register_verified($this); - - // store the logged-in user and it's hash in the session - \Session::set('username', $this->user->username); - \Session::set('login_hash', $this->create_login_hash()); - - // and rotate the session id, we've elevated rights - \Session::instance()->rotate(); - - return true; - } - - /** - * Force login user - * - * @param string - * @return bool - */ - public function force_login($user_id = '') - { - // bail out if we don't have a user - if (empty($user_id)) - { - return false; - } - - // get the user we need to login - if ( ! $user_id instanceOf \Model\Auth_User) - { - $this->user = \Model\Auth_User::query() - ->select(\Config::get('ormauth.table_columns', array())) - ->related('metadata') - ->where('id', '=', $user_id) - ->get_one(); - } - else - { - $this->user = $user_id; - } - - // did we find it - if ($this->user and ! $this->user->is_new()) - { - // store the logged-in user and it's hash in the session - \Session::set('username', $this->user->username); - \Session::set('login_hash', $this->create_login_hash()); - - // and rotate the session id, we've elevated rights - \Session::instance()->rotate(); - - // register so Auth::logout() can find us - Auth::_register_verified($this); - - return true; - } - - // force a logout - $this->logout(); - - // and signal a failed login - return false; - } - - /** - * Logout user - * - * @return bool - */ - public function logout() - { - // reset the current user - if (\Config::get('ormauth.guest_login', true)) - { - $this->user = \Model\Auth_User::query() - ->select(\Config::get('ormauth.table_columns', array())) - ->related('metadata') - ->where('id', '=', 0) - ->get_one(); - } - else - { - $this->user = false; - } - - // delete the session data identifying this user - \Session::delete('username'); - \Session::delete('login_hash'); - - return true; - } - - /** - * Create new user - * - * @param string - * @param string - * @param string must contain valid email address - * @param int group id - * @param Array - * @return bool - */ - public function create_user($username, $password, $email, $group = 1, Array $profile_fields = array()) - { - // prep the password - $password = trim($password); - - // and validate the email address - $email = filter_var(trim($email), FILTER_VALIDATE_EMAIL); - - // bail out if we're missing username, password or email address - if (empty($username) or empty($password) or empty($email)) - { - throw new \SimpleUserUpdateException('Username, password or email address is not given, or email address is invalid', 1); - } - - // check if we already have an account with this email address or username - $duplicate = \Model\Auth_User::query() - ->where('username', '=', $username) - ->or_where('email', '=', $email) - ->get_one(); - - // did we find one? - if ($duplicate) - { - // bail out with an exception - if (strtolower($email) == strtolower($duplicate->email)) - { - throw new \SimpleUserUpdateException('Email address already exists', 2); - } - else - { - throw new \SimpleUserUpdateException('Username already exists', 3); - } - } - - // do we have a logged-in user? - if ($currentuser = \Auth::get_user_id()) - { - $currentuser = $currentuser[1]; - } - else - { - $currentuser = 0; - } - - // create the new user record - $user = \Model\Auth_User::forge(array( - 'username' => (string) $username, - 'password' => $this->hash_password((string) $password), - 'email' => $email, - 'group_id' => (int) $group, - 'last_login' => 0, - 'previous_login' => 0, - 'login_hash' => '', - 'user_id' => $currentuser, - 'created_at' => \Date::forge()->get_timestamp(), - 'updated_at' => 0, - )); - - // load all additional data, passed as profile fields - $user->from_array($profile_fields); - - // save the new user record - try - { - $result = $user->save(); - } - catch (\Exception $e) - { - $result = false; - } - - // and the id of the created user, or false if creation failed - return $result ? $user->id : false; - } - - /** - * Update a user's properties - * Note: Username cannot be updated, to update password the old password must be passed as old_password - * - * @param Array properties to be updated including profile fields - * @param string - * @return bool - */ - public function update_user($values, $username = null) - { - // if no username is given, fetch the current user's namd - $username = $username ?: $this->user->username; - - // get the current user record - $current_values = \Model\Auth_User::query() - ->where('username', '=', $username) - ->get_one(); - - // and bail out if it doesn't exist - if (empty($current_values)) - { - throw new \SimpleUserUpdateException('Username not found', 4); - } - - // validate the values passed and assume the update array - $update = array(); - if (array_key_exists('username', $values)) - { - throw new \SimpleUserUpdateException('Username cannot be changed.', 5); - } - if (array_key_exists('password', $values)) - { - if (empty($values['old_password']) - or $current_values->password != $this->hash_password(trim($values['old_password']))) - { - throw new \SimpleUserWrongPassword('Old password is invalid'); - } - - $password = trim(strval($values['password'])); - if ($password === '') - { - throw new \SimpleUserUpdateException('Password can\'t be empty.', 6); - } - $update['password'] = $this->hash_password($password); - unset($values['password']); - } - if (array_key_exists('old_password', $values)) - { - unset($values['old_password']); - } - if (array_key_exists('email', $values)) - { - $email = filter_var(trim($values['email']), FILTER_VALIDATE_EMAIL); - if ( ! $email) - { - throw new \SimpleUserUpdateException('Email address is not valid', 7); - } - - $matches = \Model\Auth_User::query() - ->where('email', '=', $email) - ->where('id', '!=', $current_values->id) - ->get_one(); - - if ($matches) - { - throw new \SimpleUserUpdateException('Email address is already in use', 11); - } - - $update['email'] = $email; - unset($values['email']); - } - // deal with some simpleauth compatibility - if (array_key_exists('group', $values)) - { - array_key_exists('group_id', $values) or $values['group_id'] = $values['group']; - unset($values['group']); - } - if (array_key_exists('group_id', $values)) - { - if (is_numeric($values['group_id'])) - { - $update['group_id'] = (int) $values['group_id']; - } - unset($values['group_id']); - } - - // load the updated values into the object - $current_values->from_array($update); - - $updated = false; - - // any values remaining? - if ( ! empty($values)) - { - // set them as EAV values - foreach ($values as $key => $value) - { - if ( ! isset($current_values->{$key}) or $current_values->{$key} != $value) - { - if ($value === null) - { - unset($current_values->{$key}); - } - else - { - $current_values->{$key} = $value; - } - - // mark we've updated something - $updated = true; - } - } - } - - // check if this has changed anything - if ($updated or $updated = $current_values->is_changed()) - { - // and only save if it did - $current_values->save(); - } - - // return the updated status - return $updated; - } - - /** - * Change a user's password - * - * @param string - * @param string - * @param string username or null for current user - * @return bool - */ - public function change_password($old_password, $new_password, $username = null) - { - // use the update_user method to change the password - try - { - return (bool) $this->update_user(array('old_password' => $old_password, 'password' => $new_password), $username); - } - // only catch the wrong password exception - catch (SimpleUserWrongPassword $e) - { - return false; - } - } - - /** - * Generates new random password, sets it for the given username and returns the new password. - * To be used for resetting a user's forgotten password, should be emailed afterwards. - * - * @param string $username - * @return string - */ - public function reset_password($username) - { - // get the user object - $user = \Model\Auth_User::query() - ->where('username', '=', $username) - ->get_one(); - - // and bail out if not found - if ( ! $user) - { - throw new \SimpleUserUpdateException('Failed to reset password, user was invalid.', 8); - } - - // generate a new random password - $new_password = \Str::random('alnum', 8); - $user->password = $this->hash_password($new_password); - - // store the updated password hash - $user->save(); - - // and return the new password - return $new_password; - } - - /** - * Deletes a given user - * - * @param string - * @return bool - */ - public function delete_user($username) - { - // make sure we have a user to delete - if (empty($username)) - { - throw new \SimpleUserUpdateException('Cannot delete user with empty username', 9); - } - - // get the user object - $user = \Model\Auth_User::query() - ->related('metadata') - ->related('providers') - ->where('username', '=', $username) - ->get_one(); - - // if it was found, delete it - if ($user) - { - return (bool) $user->delete(); - } - return false; - } - - /** - * Creates a temporary hash that will validate the current login - * - * @return string - */ - public function create_login_hash() - { - // we need a logged-in user to generate a login hash - if (empty($this->user)) - { - throw new \SimpleUserUpdateException('User not logged in, can\'t create login hash.', 10); - } - - // set the previous and current last login - $this->user->previous_login = $this->user->last_login; - $this->user->last_login = \Date::forge()->get_timestamp(); - - // generate the new hash - $this->user->login_hash = sha1(\Config::get('ormauth.login_hash_salt').$this->user->username.$this->user->last_login); - - // store it - $this->user->save(); - - // and return it - return $this->user->login_hash; - } - - /** - * Get the user object - * - * @return mixed Model\Auth_User object, or false if no user is set - */ - public function get_user() - { - return empty($this->user) ? false : $this->user; - } - - /** - * Get the user's ID - * - * @return Array containing this driver's ID & the user's ID - */ - public function get_user_id() - { - // bail out if we don't have a user to return - if (empty($this->user)) - { - return false; - } - - return array($this->id, (int) $this->user->id); - } - - /** - * Get the user's groups - * - * @return Array containing the group driver ID & the user's group ID - */ - public function get_groups() - { - // bail out if we don't have a user group to return - if (empty($this->user)) - { - return false; - } - - return array(array('Ormgroup', $this->user->group)); - } - - /** - * Getter for user data. - * - * @param string name of the user field to return - * @param mixed value to return if the field requested does not exist - * - * @return mixed - */ - public function get($field, $default = null) - { - // if it's an object property, return it, else return the default - return isset($this->user->{$field}) ? $this->user->{$field} : $default; - } - - /** - * Get the user's emailaddress - * - * @return string - */ - public function get_email() - { - return $this->get('email', false); - } - - /** - * Get the user's screen name - * - * @return string - */ - public function get_screen_name() - { - return $this->get('username', false); - } - - /** - * for compatibility, will map to the user metadata - * - * @return Array - */ - public function get_profile_fields($field = null, $default = null) - { - // collect all meta data - $profile_fields = array(); - - foreach ($this->user->metadata as $metadata) - { - if (empty($field)) - { - $profile_fields[$metadata->key] = $metadata->value; - } - elseif ($field == $metadata->key) - { - return $metadata->value; - } - } - - // return the connected data - return empty($profile_fields) ? $default : $profile_fields; - } - - /** - * Extension of base driver method to default to user group instead of user id - */ - public function has_access($condition, $driver = null, $user = null) - { - if (is_null($user)) - { - if ( ! is_array($groups = $this->get_groups())) - { - return false; - } - $user = reset($groups); - } - return parent::has_access($condition, $driver, $user); - } - - /** - * Extension of base driver because this supports a guest login when switched on - */ - public function guest_login() - { - return \Config::get('ormauth.guest_login', true); - } - - /** - * Check for login - * - * @return bool - */ - protected function perform_check() - { - // get the username and login hash from the session - $username = \Session::get('username'); - $login_hash = \Session::get('login_hash'); - - // only worth checking if there's both a username and login-hash - if ( ! empty($username) and ! empty($login_hash)) - { - // if we don't have a user, or we're logging in from guest mode - if (is_null($this->user) or ($this->user->username != $username and $this->user->id == 0)) - { - // find the user - $this->user = \Model\Auth_User::query() - ->select(\Config::get('ormauth.table_columns', array())) - ->related('metadata') - ->where('username', '=', $username) - ->get_one(); - } - - // return true when login was verified, and either the hash matches or multiple logins are allowed - if ($this->user and (\Config::get('ormauth.multiple_logins', false) or $this->user['login_hash'] === $login_hash)) - { - return true; - } - } - - // not logged in, do we have remember-me active and a stored user_id? - elseif (static::$remember_me and $user_id = static::$remember_me->get('user_id', null)) - { - return $this->force_login($user_id); - } - - // force a logout - $this->logout(); - - return false; - } -} diff --git a/fuel/packages/auth/classes/auth/login/simpleauth.php b/fuel/packages/auth/classes/auth/login/simpleauth.php deleted file mode 100755 index 386d6b3..0000000 --- a/fuel/packages/auth/classes/auth/login/simpleauth.php +++ /dev/null @@ -1,598 +0,0 @@ - 'cookie', - 'cookie' => array( - 'cookie_name' => \Config::get('simpleauth.remember_me.cookie_name', 'rmcookie'), - ), - 'encrypt_cookie' => true, - 'expire_on_close' => false, - 'expiration_time' => \Config::get('simpleauth.remember_me.expiration', 86400 * 31), - )); - } - } - - /** - * @var Database_Result when login succeeded - */ - protected $user = null; - - /** - * @var array value for guest login - */ - protected static $guest_login = array( - 'id' => 0, - 'username' => 'guest', - 'group' => '0', - 'login_hash' => false, - 'email' => false, - ); - - /** - * @var array SimpleAuth class config - */ - protected $config = array( - 'drivers' => array('group' => array('Simplegroup')), - 'additional_fields' => array('profile_fields'), - ); - - /** - * Check for login - * - * @return bool - */ - protected function perform_check() - { - // fetch the username and login hash from the session - $username = \Session::get('username'); - $login_hash = \Session::get('login_hash'); - - // only worth checking if there's both a username and login-hash - if ( ! empty($username) and ! empty($login_hash)) - { - if (is_null($this->user) or ($this->user['username'] != $username and $this->user != static::$guest_login)) - { - $this->user = \DB::select_array(\Config::get('simpleauth.table_columns', array('*'))) - ->where('username', '=', $username) - ->from(\Config::get('simpleauth.table_name')) - ->execute(\Config::get('simpleauth.db_connection'))->current(); - } - - // return true when login was verified, and either the hash matches or multiple logins are allowed - if ($this->user and (\Config::get('simpleauth.multiple_logins', false) or $this->user['login_hash'] === $login_hash)) - { - return true; - } - } - - // not logged in, do we have remember-me active and a stored user_id? - elseif (static::$remember_me and $user_id = static::$remember_me->get('user_id', null)) - { - return $this->force_login($user_id); - } - - // no valid login when still here, ensure empty session and optionally set guest_login - $this->user = \Config::get('simpleauth.guest_login', true) ? static::$guest_login : false; - \Session::delete('username'); - \Session::delete('login_hash'); - - return false; - } - - /** - * Check the user exists - * - * @return bool - */ - public function validate_user($username_or_email = '', $password = '') - { - $username_or_email = trim($username_or_email) ?: trim(\Input::post(\Config::get('simpleauth.username_post_key', 'username'))); - $password = trim($password) ?: trim(\Input::post(\Config::get('simpleauth.password_post_key', 'password'))); - - if (empty($username_or_email) or empty($password)) - { - return false; - } - - $password = $this->hash_password($password); - $user = \DB::select_array(\Config::get('simpleauth.table_columns', array('*'))) - ->where_open() - ->where('username', '=', $username_or_email) - ->or_where('email', '=', $username_or_email) - ->where_close() - ->where('password', '=', $password) - ->from(\Config::get('simpleauth.table_name')) - ->execute(\Config::get('simpleauth.db_connection'))->current(); - - return $user ?: false; - } - - /** - * Login user - * - * @param string - * @param string - * @return bool - */ - public function login($username_or_email = '', $password = '') - { - if ( ! ($this->user = $this->validate_user($username_or_email, $password))) - { - $this->user = \Config::get('simpleauth.guest_login', true) ? static::$guest_login : false; - \Session::delete('username'); - \Session::delete('login_hash'); - return false; - } - - // register so Auth::logout() can find us - Auth::_register_verified($this); - - \Session::set('username', $this->user['username']); - \Session::set('login_hash', $this->create_login_hash()); - \Session::instance()->rotate(); - return true; - } - - /** - * Force login user - * - * @param string - * @return bool - */ - public function force_login($user_id = '') - { - if (empty($user_id)) - { - return false; - } - - $this->user = \DB::select_array(\Config::get('simpleauth.table_columns', array('*'))) - ->where_open() - ->where('id', '=', $user_id) - ->where_close() - ->from(\Config::get('simpleauth.table_name')) - ->execute(\Config::get('simpleauth.db_connection')) - ->current(); - - if ($this->user == false) - { - $this->user = \Config::get('simpleauth.guest_login', true) ? static::$guest_login : false; - \Session::delete('username'); - \Session::delete('login_hash'); - return false; - } - - \Session::set('username', $this->user['username']); - \Session::set('login_hash', $this->create_login_hash()); - - // and rotate the session id, we've elevated rights - \Session::instance()->rotate(); - - // register so Auth::logout() can find us - Auth::_register_verified($this); - - return true; - } - - /** - * Logout user - * - * @return bool - */ - public function logout() - { - $this->user = \Config::get('simpleauth.guest_login', true) ? static::$guest_login : false; - \Session::delete('username'); - \Session::delete('login_hash'); - return true; - } - - /** - * Create new user - * - * @param string - * @param string - * @param string must contain valid email address - * @param int group id - * @param Array - * @return bool - */ - public function create_user($username, $password, $email, $group = 1, Array $profile_fields = array()) - { - $password = trim($password); - $email = filter_var(trim($email), FILTER_VALIDATE_EMAIL); - - if (empty($username) or empty($password) or empty($email)) - { - throw new \SimpleUserUpdateException('Username, password or email address is not given, or email address is invalid', 1); - } - - $same_users = \DB::select_array(\Config::get('simpleauth.table_columns', array('*'))) - ->where('username', '=', $username) - ->or_where('email', '=', $email) - ->from(\Config::get('simpleauth.table_name')) - ->execute(\Config::get('simpleauth.db_connection')); - - if ($same_users->count() > 0) - { - if (in_array(strtolower($email), array_map('strtolower', $same_users->current()))) - { - throw new \SimpleUserUpdateException('Email address already exists', 2); - } - else - { - throw new \SimpleUserUpdateException('Username already exists', 3); - } - } - - $user = array( - 'username' => (string) $username, - 'password' => $this->hash_password((string) $password), - 'email' => $email, - 'group' => (int) $group, - 'profile_fields' => serialize($profile_fields), - 'last_login' => 0, - 'login_hash' => '', - 'created_at' => \Date::forge()->get_timestamp(), - ); - $result = \DB::insert(\Config::get('simpleauth.table_name')) - ->set($user) - ->execute(\Config::get('simpleauth.db_connection')); - - return ($result[1] > 0) ? $result[0] : false; - } - - /** - * Update a user's properties - * Note: Username cannot be updated, to update password the old password must be passed as old_password - * - * @param Array properties to be updated including profile fields - * @param string - * @return bool - */ - public function update_user($values, $username = null) - { - $username = $username ?: $this->user['username']; - $current_values = \DB::select_array(\Config::get('simpleauth.table_columns', array('*'))) - ->where('username', '=', $username) - ->from(\Config::get('simpleauth.table_name')) - ->execute(\Config::get('simpleauth.db_connection')); - - if (empty($current_values)) - { - throw new \SimpleUserUpdateException('Username not found', 4); - } - - $update = array(); - if (array_key_exists('username', $values)) - { - throw new \SimpleUserUpdateException('Username cannot be changed.', 5); - } - if (array_key_exists('password', $values)) - { - if (empty($values['old_password']) - or $current_values->get('password') != $this->hash_password(trim($values['old_password']))) - { - throw new \SimpleUserWrongPassword('Old password is invalid'); - } - - $password = trim(strval($values['password'])); - if ($password === '') - { - throw new \SimpleUserUpdateException('Password can\'t be empty.', 6); - } - $update['password'] = $this->hash_password($password); - unset($values['password']); - } - if (array_key_exists('old_password', $values)) - { - unset($values['old_password']); - } - if (array_key_exists('email', $values)) - { - $email = filter_var(trim($values['email']), FILTER_VALIDATE_EMAIL); - if ( ! $email) - { - throw new \SimpleUserUpdateException('Email address is not valid', 7); - } - $matches = \DB::select() - ->where('email', '=', $email) - ->where('id', '!=', $current_values[0]['id']) - ->from(\Config::get('simpleauth.table_name')) - ->execute(\Config::get('simpleauth.db_connection')); - if (count($matches)) - { - throw new \SimpleUserUpdateException('Email address is already in use', 11); - } - $update['email'] = $email; - unset($values['email']); - } - if (array_key_exists('group', $values)) - { - if (is_numeric($values['group'])) - { - $update['group'] = (int) $values['group']; - } - unset($values['group']); - } - if ( ! empty($values)) - { - $profile_fields = @unserialize($current_values->get('profile_fields')) ?: array(); - foreach ($values as $key => $val) - { - if ($val === null) - { - unset($profile_fields[$key]); - } - else - { - $profile_fields[$key] = $val; - } - } - $update['profile_fields'] = serialize($profile_fields); - } - - $update['updated_at'] = \Date::forge()->get_timestamp(); - - $affected_rows = \DB::update(\Config::get('simpleauth.table_name')) - ->set($update) - ->where('username', '=', $username) - ->execute(\Config::get('simpleauth.db_connection')); - - // Refresh user - if ($this->user['username'] == $username) - { - $this->user = \DB::select_array(\Config::get('simpleauth.table_columns', array('*'))) - ->where('username', '=', $username) - ->from(\Config::get('simpleauth.table_name')) - ->execute(\Config::get('simpleauth.db_connection'))->current(); - } - - return $affected_rows > 0; - } - - /** - * Change a user's password - * - * @param string - * @param string - * @param string username or null for current user - * @return bool - */ - public function change_password($old_password, $new_password, $username = null) - { - try - { - return (bool) $this->update_user(array('old_password' => $old_password, 'password' => $new_password), $username); - } - // Only catch the wrong password exception - catch (SimpleUserWrongPassword $e) - { - return false; - } - } - - /** - * Generates new random password, sets it for the given username and returns the new password. - * To be used for resetting a user's forgotten password, should be emailed afterwards. - * - * @param string $username - * @return string - */ - public function reset_password($username) - { - $new_password = \Str::random('alnum', 8); - $password_hash = $this->hash_password($new_password); - - $affected_rows = \DB::update(\Config::get('simpleauth.table_name')) - ->set(array('password' => $password_hash)) - ->where('username', '=', $username) - ->execute(\Config::get('simpleauth.db_connection')); - - if ( ! $affected_rows) - { - throw new \SimpleUserUpdateException('Failed to reset password, user was invalid.', 8); - } - - return $new_password; - } - - /** - * Deletes a given user - * - * @param string - * @return bool - */ - public function delete_user($username) - { - if (empty($username)) - { - throw new \SimpleUserUpdateException('Cannot delete user with empty username', 9); - } - - $affected_rows = \DB::delete(\Config::get('simpleauth.table_name')) - ->where('username', '=', $username) - ->execute(\Config::get('simpleauth.db_connection')); - - return $affected_rows > 0; - } - - /** - * Creates a temporary hash that will validate the current login - * - * @return string - */ - public function create_login_hash() - { - if (empty($this->user)) - { - throw new \SimpleUserUpdateException('User not logged in, can\'t create login hash.', 10); - } - - $last_login = \Date::forge()->get_timestamp(); - $login_hash = sha1(\Config::get('simpleauth.login_hash_salt').$this->user['username'].$last_login); - - \DB::update(\Config::get('simpleauth.table_name')) - ->set(array('last_login' => $last_login, 'login_hash' => $login_hash)) - ->where('username', '=', $this->user['username']) - ->execute(\Config::get('simpleauth.db_connection')); - - $this->user['login_hash'] = $login_hash; - - return $login_hash; - } - - /** - * Get the user's ID - * - * @return Array containing this driver's ID & the user's ID - */ - public function get_user_id() - { - if (empty($this->user)) - { - return false; - } - - return array($this->id, (int) $this->user['id']); - } - - /** - * Get the user's groups - * - * @return Array containing the group driver ID & the user's group ID - */ - public function get_groups() - { - if (empty($this->user)) - { - return false; - } - - return array(array('Simplegroup', $this->user['group'])); - } - - /** - * Getter for user data - * - * @param string name of the user field to return - * @param mixed value to return if the field requested does not exist - * - * @return mixed - */ - public function get($field, $default = null) - { - if (isset($this->user[$field])) - { - return $this->user[$field]; - } - elseif (isset($this->user['profile_fields'])) - { - return $this->get_profile_fields($field, $default); - } - - return $default; - } - - /** - * Get the user's emailaddress - * - * @return string - */ - public function get_email() - { - return $this->get('email', false); - } - - /** - * Get the user's screen name - * - * @return string - */ - public function get_screen_name() - { - if (empty($this->user)) - { - return false; - } - - return $this->user['username']; - } - - /** - * Get the user's profile fields - * - * @return Array - */ - public function get_profile_fields($field = null, $default = null) - { - if (empty($this->user)) - { - return false; - } - - if (isset($this->user['profile_fields'])) - { - is_array($this->user['profile_fields']) or $this->user['profile_fields'] = (@unserialize($this->user['profile_fields']) ?: array()); - } - else - { - $this->user['profile_fields'] = array(); - } - - return is_null($field) ? $this->user['profile_fields'] : \Arr::get($this->user['profile_fields'], $field, $default); - } - - /** - * Extension of base driver method to default to user group instead of user id - */ - public function has_access($condition, $driver = null, $user = null) - { - if (is_null($user)) - { - $groups = $this->get_groups(); - $user = reset($groups); - } - return parent::has_access($condition, $driver, $user); - } - - /** - * Extension of base driver because this supports a guest login when switched on - */ - public function guest_login() - { - return \Config::get('simpleauth.guest_login', true); - } -} - -// end of file simpleauth.php diff --git a/fuel/packages/auth/classes/auth/opauth.php b/fuel/packages/auth/classes/auth/opauth.php deleted file mode 100755 index f84a839..0000000 --- a/fuel/packages/auth/classes/auth/opauth.php +++ /dev/null @@ -1,438 +0,0 @@ -uri->get()); - $path = explode('/', trim($parsed_url['path'], '/')); - - // construct the path if needed -// $path = \Request::main()->uri->get_segments(); - $params = count(\Request::active()->route->method_params); - - while ($params-- > 0) - { - array_pop($path); - } - $config['path'] = '/'.(implode('/', $path)).'/'; - } - - // and construct the callback URL if needed - if (empty($config['callback_url'])) - { - // pop the method name from the path - $path = explode('/', trim($config['path'], '/')); - array_pop($path); - - // and add 'callback' as the controller callback action - $config['callback_url'] = (empty($path)?'':'/'.implode('/', $path)).'/callback/'; - } - - // determine the name of the provider we want to call - if ( ! $autorun) - { - // we're processing a callback - $config['provider'] = 'Callback'; - } - else - { - if (empty($config['provider'])) - { - $parsed_url = parse_url(\Uri::base().\Request::main()->uri->get()); - $provider = explode('/', substr($parsed_url['path'], strlen($config['path']))); - $config['provider'] = ucfirst($provider[0]); - } - - // check if we have a strategy defined for this provider - $strategies = \Config::get('opauth.Strategy', array()); - if ( ! array_key_exists(strtolower($config['provider']), array_change_key_case($strategies))) - { - throw new \OpauthException('Opauth strategy "'.$config['provider'].'" is not supported'); - } - } - - // return the created Auth_Opauth object - return new static($config, $autorun); - } - - // ------------------------------------------------------------------------- - - /** - * Opauth configuration - */ - protected $config = array(); - - /** - * Opauth instance - */ - protected $opauth = null; - - /** - * Opauth response - */ - protected $response = array(); - - /** - * Construct the Auth_Opauth object - */ - public function __construct(Array $config, $autorun = true) - { - // store the config - $this->config = $config; - - // construct the Opauth object - $this->opauth = new \Opauth($config, $autorun); - } - - /** - * New Opauth login. If we know this user, we can perform a login, if - * not, we need to register the user first - */ - public function login_or_register() - { - // process the callback data - $this->callback(); - - // if there is no UID we don't know who this is - if ($this->get('auth.uid', null) === null) - { - throw new \OpauthException('No uid in response from the provider, so we have no idea who you are.'); - } - - // we have a UID and logged in? Just attach this authentication to a user - if (\Auth::check()) - { - list(, $user_id) = \Auth::instance()->get_user_id(); - - $result = \DB::select(\DB::expr('COUNT(*) as count'))->from($this->config['table'])->where('parent_id', '=', $user_id)->execute(static::$db_connection); - $num_linked = ($result and $result = $result->current()) ? (int) $result['count'] : 0; - - // allowed multiple providers, or not authed yet? - if ($num_linked === 0 or \Config::get('opauth.link_multiple_providers') === true) - { - // attach this account to the logged in user - $this->link_provider(array( - 'parent_id' => $user_id, - 'provider' => $this->get('auth.provider'), - 'uid' => $this->get('auth.uid'), - 'access_token' => $this->get('auth.credentials.token', null), - 'secret' => $this->get('auth.credentials.secret', null), - 'expires' => $this->get('auth.credentials.expires', null), - 'refresh_token' => $this->get('auth.credentials.refresh_token', null), - 'created_at' => time(), - )); - - // attachment went ok so we'll redirect - return 'linked'; - } - - else - { - $result = \DB::select()->from($this->config['table'])->where('parent_id', '=', $user_id)->limit(1)->as_object()->execute(static::$db_connection); - $auth = $result ? $result->current() : null; - throw new \OpauthException(sprintf('This user is already linked to "%s" and can\'t be linked to another provider.', $auth->provider)); - } - } - - // the user exists, so send him on his merry way as a user - elseif ($authentication = \DB::select()->from($this->config['table'])->where('uid', '=', $this->get('auth.uid'))->where('provider', '=', $this->get('auth.provider'))->as_object()->execute(static::$db_connection) and $authentication->count()) - { - // force a login with this username - $authentication = $authentication->current(); - if (\Auth::instance()->force_login((int) $authentication->parent_id)) - { - // credentials ok, go right in - return 'logged_in'; - } - - throw new \OpauthException('This user could not be logged in.'); - } - - // not an existing user of any type, so we need to create a user somehow - else - { - // generate a dummy password if we don't have one, and want auto registration for this user - if ($this->config['auto_registration']) - { - $this->get('auth.info.password') or $this->response['auth']['info']['password'] = \Str::random('sha1'); - } - - // did the provider return enough information to log the user in? - if (($this->get('auth.info.nickname') or $this->get('auth.info.email')) and $this->get('auth.info.password')) - { - // make sure we have a nickname, if not, use the email address - if (empty($this->response['auth']['info']['nickname'])) - { - $this->response['auth']['info']['nickname'] = $this->response['auth']['info']['email']; - } - - // make a user with what we have - $user_id = $this->create_user($this->response['auth']['info']); - - // attach this authentication to the new user - $insert_id = $this->link_provider(array( - 'parent_id' => $user_id, - 'provider' => $this->get('auth.provider'), - 'uid' => $this->get('auth.uid'), - 'access_token' => $this->get('auth.credentials.token', null), - 'secret' => $this->get('auth.credentials.secret', null), - 'expires' => $this->get('auth.credentials.expires', null), - 'refresh_token' => $this->get('auth.credentials.refresh_token', null), - 'created_at' => time(), - )); - - // force a login with this users id - if ($insert_id and \Auth::instance()->force_login((int) $user_id)) - { - // credentials ok, go right in - return 'registered'; - } - - throw new \OpauthException('We tried automatically creating a user but that just really did not work. Not sure why...'); - } - - // they aren't a user and cant be automatically registerd, so redirect to registration page - else - { - \Session::set('auth-strategy', array( - 'user' => $this->get('auth.info'), - 'authentication' => array( - 'provider' => $this->get('auth.provider'), - 'uid' => $this->get('auth.uid'), - 'access_token' => $this->get('auth.credentials.token', null), - 'secret' => $this->get('auth.credentials.secret', null), - 'expires' => $this->get('auth.credentials.expires', null), - 'refresh_token' => $this->get('auth.credentials.refresh_token', null), - ), - )); - - return 'register'; - } - } - } - - /** - * create a remote entry for this login - */ - public function link_provider(array $data) - { - // do some validation - if ( ! is_numeric($data['expires'])) - { - if ($date = \DateTime::createFromFormat(\DateTime::ISO8601, $data['expires'])) - { - $data['expires'] = $date->getTimestamp(); - } - elseif ($date = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expires'])) - { - $data['expires'] = $date->getTimestamp(); - } - else - { - $data['expires'] = time(); - } - } - - // get rid of old registrations to prevent duplicates - \DB::delete($this->config['table'])->where('uid', '=', $data['uid'])->where('provider', '=', $data['provider'])->execute(static::$db_connection); - - // insert the new provider UID - list($insert_id, $rows_affected) = \DB::insert($this->config['table'])->set($data)->execute(static::$db_connection); - return $rows_affected ? $insert_id : false; - } - - /** - * Get a response value - */ - public function get($key, $default = null) - { - return is_array($this->response) ? \Arr::get($this->response, $key, $default) : $default; - } - - /** - * fetch the callback response - */ - protected function callback() - { - // fetch the response and decode it - if ($this->response = \Input::get('opauth', false)) - { - $this->response = base64_decode($this->response); - $this->response = \Str::is_json($this->response) ? json_decode($this->response, true) : unserialize($this->response); - } - - // did we receive a response at all? - if ( ! $this->response) - { - throw new \OpauthException('no valid response received in the callback'); - } - - // did we receive one, but was it an error - if (array_key_exists('error', $this->response)) - { - throw new \OpauthException('Authentication error: the callback returned an error auth response'); - } - - // validate the response - if ($this->get('auth') === null or $this->get('timestamp') === null or - $this->get('signature') === null or $this->get('auth.provider') === null or $this->get('auth.uid') === null) - { - throw new \OpauthException('Invalid auth response: Missing key auth response components'); - } - elseif ( ! $this->opauth->validate(sha1(print_r($this->get('auth'), true)), $this->get('timestamp'), $this->get('signature'), $reason)) - { - throw new \OpauthException('Invalid auth response: '.$reason); - } - } - - /** - * use Auth to create a new user, in case we've received enough information to do so - * - * @param array array with the raw Opauth response user fields - * - * @return mixed id of the user record created, or false if the create failed - */ - protected function create_user(array $user) - { - $user_id = \Auth::create_user( - - // username - isset($user['nickname']) ? $user['nickname'] : null, - - // password (random string will do if none provided) - isset($user['password']) ? $user['password'] : \Str::random(), - - // email address - isset($user['email']) ? $user['email'] : null, - - // which group are they in? - isset($user['group_id']) ? $user['group_id'] : \Config::get('opauth.default_group', -1), - - // extra information - array( - - // got their name? full name? or first and last to make up a full name? - 'fullname' => isset($user['name']) ? $user['name'] : ( - isset($user['full_name']) ? $user['full_name'] : ( - isset($user['first_name'], $user['last_name']) ? $user['first_name'].' '.$user['last_name'] : null - ) - ), - ) - ); - - return $user_id ?: false; - } - - /** - * Returns the Opauth instance for interaction with the core library. - * - * @return \Opauth - */ - public function get_instance() - { - return $this->opauth; - } - -} diff --git a/fuel/packages/auth/classes/model/auth/group.php b/fuel/packages/auth/classes/model/auth/group.php deleted file mode 100755 index 442f5e1..0000000 --- a/fuel/packages/auth/classes/model/auth/group.php +++ /dev/null @@ -1,171 +0,0 @@ - array(), - 'name' => array( - 'label' => 'auth_model_group.name', - 'default' => '', - 'null' => false, - 'validation' => array('required', 'max_length' => array(255)), - ), - 'user_id' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - 'created_at' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - 'updated_at' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - ); - - /** - * @var array defined observers - */ - protected static $_observers = array( - 'Orm\\Observer_CreatedAt' => array( - 'events' => array('before_insert'), - 'property' => 'created_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_UpdatedAt' => array( - 'events' => array('before_update'), - 'property' => 'updated_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_Typing' => array( - 'events' => array('after_load', 'before_save', 'after_save'), - ), - 'Orm\\Observer_Self' => array( - 'events' => array('before_insert', 'before_update'), - 'property' => 'user_id', - ), - ); - - /** - * @var array has_many relationships - */ - protected static $_has_many = array( - 'users' => array( - 'model_to' => 'Model\\Auth_User', - 'key_from' => 'id', - 'key_to' => 'group_id', - ), - 'grouppermission' => array( - 'model_to' => 'Model\\Auth_Grouppermission', - 'key_from' => 'id', - 'key_to' => 'group_id', - 'cascade_delete' => false, - ), - ); - - /** - * @var array many_many relationships - */ - protected static $_many_many = array( - 'roles' => array( - 'key_from' => 'id', - 'model_to' => 'Model\\Auth_Role', - 'key_to' => 'id', - 'table_through' => null, - 'key_through_from' => 'group_id', - 'key_through_to' => 'role_id', - ), - 'permissions' => array( - 'key_from' => 'id', - 'model_to' => 'Model\\Auth_Permission', - 'key_to' => 'id', - 'table_through' => null, - 'key_through_from' => 'group_id', - 'key_through_to' => 'perms_id', - ), - ); - - /** - * init the class - */ - public static function _init() - { - // auth config - \Config::load('ormauth', true); - - // set the connection this model should use - static::$_connection = \Config::get('ormauth.db_connection'); - - // set the write connection this model should use - static::$_write_connection = \Config::get('ormauth.db_write_connection') ?: static::$_connection; - - // set the models table name - static::$_table_name = \Config::get('ormauth.table_name', 'users').'_groups'; - - // set the relations through table names - static::$_many_many['roles']['table_through'] = \Config::get('ormauth.table_name', 'users').'_group_roles'; - static::$_many_many['permissions']['table_through'] = \Config::get('ormauth.table_name', 'users').'_group_permissions'; - - // model language file - \Lang::load('auth_model_group', true); - } - - /** - * before_insert observer event method - */ - public function _event_before_insert() - { - // assign the user id that lasted updated this record - $this->user_id = 0; - foreach (\Auth::verified() as $driver) - { - if (($id = $driver->get_user_id()) !== false) - { - $this->user_id = $id[1]; - break; - } - } - } - - /** - * before_update observer event method - */ - public function _event_before_update() - { - $this->_event_before_insert(); - } -} diff --git a/fuel/packages/auth/classes/model/auth/grouppermission.php b/fuel/packages/auth/classes/model/auth/grouppermission.php deleted file mode 100755 index e7b7574..0000000 --- a/fuel/packages/auth/classes/model/auth/grouppermission.php +++ /dev/null @@ -1,94 +0,0 @@ - array(), - 'group_id' => array(), - 'perms_id' => array(), - 'actions' => array( - 'data_type' => 'serialize', - 'default' => array(), - 'null' => false, - 'form' => array('type' => false), - ), - ); - - /** - * @var array defined observers - */ - protected static $_observers = array( - 'Orm\\Observer_Typing' => array( - 'events' => array('after_load', 'before_save', 'after_save'), - ), - ); - - /** - * @var array belongs_to relationships - */ - protected static $_belongs_to = array( - 'group' => array( - 'key_from' => 'group_id', - 'model_to' => 'Model\\Auth_Group', - 'key_to' => 'id', - ), - 'permission' => array( - 'key_from' => 'perms_id', - 'model_to' => 'Model\\Auth_Permission', - 'key_to' => 'id', - ), - ); - - /** - * init the class - */ - public static function _init() - { - // auth config - \Config::load('ormauth', true); - - // set the connection this model should use - static::$_connection = \Config::get('ormauth.db_connection'); - - // set the write connection this model should use - static::$_write_connection = \Config::get('ormauth.db_write_connection') ?: static::$_connection; - - // set the models table name - static::$_table_name = \Config::get('ormauth.table_name', 'users').'_group_permissions'; - } -} diff --git a/fuel/packages/auth/classes/model/auth/metadata.php b/fuel/packages/auth/classes/model/auth/metadata.php deleted file mode 100755 index ff6c1f7..0000000 --- a/fuel/packages/auth/classes/model/auth/metadata.php +++ /dev/null @@ -1,133 +0,0 @@ - array(), - 'parent_id' => array(), - 'key' => array(), - 'value' => array(), - 'user_id' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - 'created_at' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - 'updated_at' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - ); - - /** - * @var array defined observers - */ - protected static $_observers = array( - 'Orm\\Observer_CreatedAt' => array( - 'events' => array('before_insert'), - 'property' => 'created_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_UpdatedAt' => array( - 'events' => array('before_update'), - 'property' => 'updated_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_Typing' => array( - 'events' => array('after_load', 'before_save', 'after_save'), - ), - 'Orm\\Observer_Self' => array( - 'events' => array('before_insert', 'before_update'), - 'property' => 'user_id', - ), - ); - - /** - * @var array belongs_to relationships - */ - protected static $_belongs_to = array( - 'user' => array( - 'model_to' => 'Model\\Auth_User', - 'key_from' => 'parent_id', - 'key_to' => 'id', - ), - ); - - /** - * init the class - */ - public static function _init() - { - // auth config - \Config::load('ormauth', true); - - // set the connection this model should use - static::$_connection = \Config::get('ormauth.db_connection'); - - // set the write connection this model should use - static::$_write_connection = \Config::get('ormauth.db_write_connection') ?: static::$_connection; - - // set the models table name - static::$_table_name = \Config::get('ormauth.table_name', 'users').'_metadata'; - } - - /** - * before_insert observer event method - */ - public function _event_before_insert() - { - // assign the user id that lasted updated this record - $this->user_id = 0; - foreach (\Auth::verified() as $driver) - { - if (($id = $driver->get_user_id()) !== false) - { - $this->user_id = $id[1]; - break; - } - } - } - - /** - * before_update observer event method - */ - public function _event_before_update() - { - $this->_event_before_insert(); - } -} diff --git a/fuel/packages/auth/classes/model/auth/permission.php b/fuel/packages/auth/classes/model/auth/permission.php deleted file mode 100755 index cebc7b3..0000000 --- a/fuel/packages/auth/classes/model/auth/permission.php +++ /dev/null @@ -1,178 +0,0 @@ - array(), - 'area' => array( - 'label' => 'auth_model_permission.area', - 'null' => false, - 'validation' => array('required', 'max_length' => array(25)), - ), - 'permission' => array( - 'label' => 'auth_model_permission.permission', - 'null' => false, - 'validation' => array('required', 'max_length' => array(25)), - ), - 'description' => array( - 'label' => 'auth_model_permission.description', - 'null' => false, - 'validation' => array('required', 'max_length' => array(255)), - ), - 'actions' => array( - 'data_type' => 'serialize', - 'default' => array(), - 'null' => false, - 'form' => array('type' => false), - ), - 'user_id' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - 'created_at' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - 'updated_at' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - ); - - /** - * @var array defined observers - */ - protected static $_observers = array( - 'Orm\\Observer_CreatedAt' => array( - 'events' => array('before_insert'), - 'property' => 'created_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_UpdatedAt' => array( - 'events' => array('before_update'), - 'property' => 'updated_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_Typing' => array( - 'events' => array('after_load', 'before_save', 'after_save'), - ), - 'Orm\\Observer_Self' => array( - 'events' => array('before_insert', 'before_update'), - 'property' => 'user_id', - ), - ); - - /** - * @var array many_many relationships - */ - protected static $_many_many = array( - 'users' => array( - 'key_from' => 'id', - 'model_to' => 'Model\\Auth_User', - 'key_to' => 'id', - 'table_through' => null, - 'key_through_from' => 'perms_id', - 'key_through_to' => 'user_id', - ), - 'groups' => array( - 'key_from' => 'id', - 'model_to' => 'Model\\Auth_Group', - 'key_to' => 'id', - 'table_through' => null, - 'key_through_from' => 'perms_id', - 'key_through_to' => 'group_id', - ), - 'roles' => array( - 'key_from' => 'id', - 'model_to' => 'Model\\Auth_Role', - 'key_to' => 'id', - 'table_through' => null, - 'key_through_from' => 'perms_id', - 'key_through_to' => 'role_id', - ), - ); - - /** - * init the class - */ - public static function _init() - { - // auth config - \Config::load('ormauth', true); - - // set the connection this model should use - static::$_connection = \Config::get('ormauth.db_connection'); - - // set the write connection this model should use - static::$_write_connection = \Config::get('ormauth.db_write_connection') ?: static::$_connection; - - // set the models table name - static::$_table_name = \Config::get('ormauth.table_name', 'users').'_permissions'; - - // set the relations through table names - static::$_many_many['users']['table_through'] = \Config::get('ormauth.table_name', 'users').'_user_permissions'; - static::$_many_many['groups']['table_through'] = \Config::get('ormauth.table_name', 'users').'_group_permissions'; - static::$_many_many['roles']['table_through'] = \Config::get('ormauth.table_name', 'users').'_role_permissions'; - - // model language file - \Lang::load('auth_model_permission', true); - } - - /** - * before_insert observer event method - */ - public function _event_before_insert() - { - // assign the user id that lasted updated this record - $this->user_id = 0; - foreach (\Auth::verified() as $driver) - { - if (($id = $driver->get_user_id()) !== false) - { - $this->user_id = $id[1]; - break; - } - } - } - - /** - * before_update observer event method - */ - public function _event_before_update() - { - $this->_event_before_insert(); - } -} diff --git a/fuel/packages/auth/classes/model/auth/provider.php b/fuel/packages/auth/classes/model/auth/provider.php deleted file mode 100755 index cd3d802..0000000 --- a/fuel/packages/auth/classes/model/auth/provider.php +++ /dev/null @@ -1,106 +0,0 @@ - array(), - 'parent_id' => array(), - 'provider' => array(), - 'uid' => array(), - 'secret' => array(), - 'access_token' => array(), - 'expires' => array(), - 'refresh_token' => array(), - 'user_id' => array(), - 'created_at' => array(), - 'updated_at' => array(), - ); - - /** - * @var array defined observers - */ - protected static $_observers = array( - 'Orm\\Observer_CreatedAt' => array( - 'events' => array('before_insert'), - 'property' => 'created_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_UpdatedAt' => array( - 'events' => array('before_update'), - 'property' => 'updated_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_Typing' => array( - 'events' => array('after_load', 'before_save', 'after_save'), - ), - ); - - /** - * @var array belongs_to relationships - */ - protected static $_belongs_to = array( - 'user' => array( - 'key_from' => 'parent_id', - 'model_to' => 'Model\\Auth_User', - 'key_to' => 'id', - ), - 'createdby' => array( - 'key_from' => 'user_id', - 'model_to' => 'Model\\Auth_User', - 'key_to' => 'id', - ), - ); - - /** - * init the class - */ - public static function _init() - { - // auth config - \Config::load('ormauth', true); - - // set the connection this model should use - static::$_connection = \Config::get('ormauth.db_connection'); - - // set the write connection this model should use - static::$_write_connection = \Config::get('ormauth.db_write_connection') ?: static::$_connection; - - // set the models table name - static::$_table_name = \Config::get('ormauth.table_name', 'users').'_providers'; - } -} diff --git a/fuel/packages/auth/classes/model/auth/role.php b/fuel/packages/auth/classes/model/auth/role.php deleted file mode 100755 index 9fe5f35..0000000 --- a/fuel/packages/auth/classes/model/auth/role.php +++ /dev/null @@ -1,188 +0,0 @@ - array(), - 'name' => array( - 'label' => 'auth_model_role.name', - 'default' => 0, - 'null' => false, - 'validation' => array('required', 'max_length' => array(255)), - ), - 'filter' => array( - 'label' => 'auth_model_role.filter', - 'data_type' => 'enum', - 'options' => array('', 'A', 'D', 'R'), - 'default' => 0, - 'null' => false, - 'form' => array('type' => 'select'), - 'validation' => array(), - 'default' => '', - ), - 'user_id' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - 'created_at' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - 'updated_at' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - ); - - /** - * @var array defined observers - */ - protected static $_observers = array( - 'Orm\\Observer_CreatedAt' => array( - 'events' => array('before_insert'), - 'property' => 'created_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_UpdatedAt' => array( - 'events' => array('before_update'), - 'property' => 'updated_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_Typing' => array( - 'events' => array('after_load', 'before_save', 'after_save'), - ), - 'Orm\\Observer_Self' => array( - 'events' => array('before_insert', 'before_update'), - 'property' => 'user_id', - ), - ); - - /** - * @var array has_many relationships - */ - protected static $_has_many = array( - 'rolepermission' => array( - 'model_to' => 'Model\\Auth_Rolepermission', - 'key_from' => 'id', - 'key_to' => 'role_id', - 'cascade_delete' => false, - ), - ); - - /** - * @var array many_many relationships - */ - protected static $_many_many = array( - 'users' => array( - 'key_from' => 'id', - 'model_to' => 'Model\\Auth_User', - 'key_to' => 'id', - 'table_through' => null, - 'key_through_from' => 'role_id', - 'key_through_to' => 'user_id', - ), - 'groups' => array( - 'key_from' => 'id', - 'model_to' => 'Model\\Auth_Group', - 'key_to' => 'id', - 'table_through' => null, - 'key_through_from' => 'role_id', - 'key_through_to' => 'group_id', - ), - 'permissions' => array( - 'key_from' => 'id', - 'model_to' => 'Model\\Auth_Permission', - 'key_to' => 'id', - 'table_through' => null, - 'key_through_from' => 'role_id', - 'key_through_to' => 'perms_id', - ), - ); - - /** - * init the class - */ - public static function _init() - { - // auth config - \Config::load('ormauth', true); - - // set the connection this model should use - static::$_connection = \Config::get('ormauth.db_connection'); - - // set the write connection this model should use - static::$_write_connection = \Config::get('ormauth.db_write_connection') ?: static::$_connection; - - // set the models table name - static::$_table_name = \Config::get('ormauth.table_name', 'users').'_roles'; - - // set the relations through table names - static::$_many_many['users']['table_through'] = \Config::get('ormauth.table_name', 'users').'_user_roles'; - static::$_many_many['groups']['table_through'] = \Config::get('ormauth.table_name', 'users').'_group_roles'; - static::$_many_many['permissions']['table_through'] = \Config::get('ormauth.table_name', 'users').'_role_permissions'; - - // model language file - \Lang::load('auth_model_role', true); - - // set the filter options from the language file - static::$_properties['filter']['form']['options'] = \Lang::get('auth_model_role.permissions'); - } - - /** - * before_insert observer event method - */ - public function _event_before_insert() - { - // assign the user id that lasted updated this record - $this->user_id = 0; - foreach (\Auth::verified() as $driver) - { - if (($id = $driver->get_user_id()) !== false) - { - $this->user_id = $id[1]; - break; - } - } - } - - /** - * before_update observer event method - */ - public function _event_before_update() - { - $this->_event_before_insert(); - } -} diff --git a/fuel/packages/auth/classes/model/auth/rolepermission.php b/fuel/packages/auth/classes/model/auth/rolepermission.php deleted file mode 100755 index be139ba..0000000 --- a/fuel/packages/auth/classes/model/auth/rolepermission.php +++ /dev/null @@ -1,94 +0,0 @@ - array(), - 'role_id' => array(), - 'perms_id' => array(), - 'actions' => array( - 'data_type' => 'serialize', - 'default' => array(), - 'null' => false, - 'form' => array('type' => false), - ), - ); - - /** - * @var array defined observers - */ - protected static $_observers = array( - 'Orm\\Observer_Typing' => array( - 'events' => array('after_load', 'before_save', 'after_save'), - ), - ); - - /** - * @var array belongs_to relationships - */ - protected static $_belongs_to = array( - 'role' => array( - 'key_from' => 'role_id', - 'model_to' => 'Model\\Auth_Role', - 'key_to' => 'id', - ), - 'permission' => array( - 'key_from' => 'perms_id', - 'model_to' => 'Model\\Auth_Permission', - 'key_to' => 'id', - ), - ); - - /** - * init the class - */ - public static function _init() - { - // auth config - \Config::load('ormauth', true); - - // set the connection this model should use - static::$_connection = \Config::get('ormauth.db_connection'); - - // set the write connection this model should use - static::$_write_connection = \Config::get('ormauth.db_write_connection') ?: static::$_connection; - - // set the models table name - static::$_table_name = \Config::get('ormauth.table_name', 'users').'_role_permissions'; - } -} diff --git a/fuel/packages/auth/classes/model/auth/user.php b/fuel/packages/auth/classes/model/auth/user.php deleted file mode 100755 index b9bc3eb..0000000 --- a/fuel/packages/auth/classes/model/auth/user.php +++ /dev/null @@ -1,284 +0,0 @@ - array(), - 'username' => array( - 'label' => 'auth_model_user.name', - 'default' => 0, - 'null' => false, - 'validation' => array('required', 'max_length' => array(255)), - ), - 'email' => array( - 'label' => 'auth_model_user.email', - 'default' => 0, - 'null' => false, - 'validation' => array('required', 'valid_email'), - ), - 'group' => array( - 'label' => 'auth_model_user.group_id', - 'default' => 0, - 'null' => false, - 'form' => array('type' => 'select'), - 'validation' => array('required', 'match_pattern' => array('/^[1-9]\d*$/')), - ), - 'group_id' => array( - 'label' => 'auth_model_user.group_id', - 'default' => null, - 'null' => true, - 'form' => array('type' => 'select'), - 'validation' => array('match_pattern' => array('/^[1-9]\d*$/')), - ), - 'password' => array( - 'label' => 'auth_model_user.password', - 'default' => 0, - 'null' => false, - 'form' => array('type' => 'password'), - 'validation' => array('min_length' => array(8), 'match_field' => array('confirm')), - ), - 'profile_fields' => array( - 'default' => array(), - 'data_type' => 'serialize', - 'form' => array('type' => false), - ), - 'last_login' => array( - 'form' => array('type' => false), - ), - 'previous_login' => array( - 'form' => array('type' => false), - ), - 'login_hash' => array( - 'form' => array('type' => false), - ), - 'user_id' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - 'created_at' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - 'updated_at' => array( - 'default' => 0, - 'null' => false, - 'form' => array('type' => false), - ), - ); - - /** - * @var array defined observers - */ - protected static $_observers = array( - 'Orm\\Observer_CreatedAt' => array( - 'events' => array('before_insert'), - 'property' => 'created_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_UpdatedAt' => array( - 'events' => array('before_update'), - 'property' => 'updated_at', - 'mysql_timestamp' => false, - ), - 'Orm\\Observer_Typing' => array( - 'events' => array('after_load', 'before_save', 'after_save'), - ), - 'Orm\\Observer_Self' => array( - 'events' => array('before_insert', 'before_update'), - 'property' => 'user_id', - ), - ); - - // EAV container for user metadata - protected static $_eav = array( - 'metadata' => array( - 'attribute' => 'key', - 'value' => 'value', - ), - ); - - /** - * @var array belongs_to relationships - */ - protected static $_belongs_to = array( - 'group' => array( - 'model_to' => 'Model\\Auth_Group', - 'key_from' => 'group_id', - 'key_to' => 'id', - 'cascade_delete' => false, - ), - ); - - /** - * @var array has_many relationships - */ - protected static $_has_many = array( - 'metadata' => array( - 'model_to' => 'Model\\Auth_Metadata', - 'key_from' => 'id', - 'key_to' => 'parent_id', - 'cascade_delete' => true, - ), - 'userpermission' => array( - 'model_to' => 'Model\\Auth_Userpermission', - 'key_from' => 'id', - 'key_to' => 'user_id', - 'cascade_delete' => false, - ), - 'providers' => array( - 'model_to' => 'Model\\Auth_Provider', - 'key_from' => 'id', - 'key_to' => 'parent_id', - 'cascade_delete' => true, - ), - ); - - /** - * @var array many_many relationships - */ - protected static $_many_many = array( - 'roles' => array( - 'key_from' => 'id', - 'model_to' => 'Model\\Auth_Role', - 'key_to' => 'id', - 'table_through' => null, - 'key_through_from' => 'user_id', - 'key_through_to' => 'role_id', - ), - 'permissions' => array( - 'key_from' => 'id', - 'model_to' => 'Model\\Auth_Permission', - 'key_to' => 'id', - 'table_through' => null, - 'key_through_from' => 'user_id', - 'key_through_to' => 'perms_id', - ), - ); - - /** - * init the class - */ - public static function _init() - { - // auth config - \Config::load('auth', true); - - // get the auth driver in use - $drivers = normalize_driver_types(); - - // modify the model definition based on the driver used - if (in_array('Simpleauth', $drivers)) - { - // remove properties not in use - unset(static::$_properties['group_id']); - unset(static::$_properties['previous_login']); - unset(static::$_properties['user_id']); - - // remove relations - static::$_eav = array(); - static::$_belongs_to = array(); - static::$_has_many = array(); - static::$_many_many = array(); - - // remove observers - unset(static::$_observers['Orm\\Observer_Self']); - - // simpleauth config - \Config::load('simpleauth', true); - - // set the connection this model should use - static::$_connection = \Config::get('simpleauth.db_connection'); - - // set the write connection this model should use - static::$_write_connection = \Config::get('simpleauth.db_write_connection') ?: static::$_connection; - - // set the models table name - static::$_table_name = \Config::get('simpleauth.table_name', 'users'); - } - - elseif (in_array('Ormauth', $drivers)) - { - // remove properties not in use - unset(static::$_properties['group']); - unset(static::$_properties['profile_fields']); - - // ormauth config - \Config::load('ormauth', true); - - // set the connection this model should use - static::$_connection = \Config::get('ormauth.db_connection'); - - // set the write connection this model should use - static::$_write_connection = \Config::get('ormauth.db_write_connection') ?: static::$_connection; - - // set the models table name - static::$_table_name = \Config::get('ormauth.table_name', 'users'); - - // set the relations through table names - static::$_many_many['roles']['table_through'] = \Config::get('ormauth.table_name', 'users').'_user_roles'; - static::$_many_many['permissions']['table_through'] = \Config::get('ormauth.table_name', 'users').'_user_permissions'; - } - - // model language file - \Lang::load('auth_model_user', true); - } - - /** - * before_insert observer event method - */ - public function _event_before_insert() - { - // assign the user id that lasted updated this record - $this->user_id = 0; - foreach (\Auth::verified() as $driver) - { - if (($id = $driver->get_user_id()) !== false) - { - $this->user_id = $id[1]; - break; - } - } - } - - /** - * before_update observer event method - */ - public function _event_before_update() - { - $this->_event_before_insert(); - } -} diff --git a/fuel/packages/auth/classes/model/auth/userpermission.php b/fuel/packages/auth/classes/model/auth/userpermission.php deleted file mode 100755 index b133343..0000000 --- a/fuel/packages/auth/classes/model/auth/userpermission.php +++ /dev/null @@ -1,94 +0,0 @@ - array(), - 'user_id' => array(), - 'perms_id' => array(), - 'actions' => array( - 'data_type' => 'serialize', - 'default' => array(), - 'null' => false, - 'form' => array('type' => false), - ), - ); - - /** - * @var array defined observers - */ - protected static $_observers = array( - 'Orm\\Observer_Typing' => array( - 'events' => array('after_load', 'before_save', 'after_save'), - ), - ); - - /** - * @var array belongs_to relationships - */ - protected static $_belongs_to = array( - 'user' => array( - 'key_from' => 'user_id', - 'model_to' => 'Model\\Auth_User', - 'key_to' => 'id', - ), - 'permission' => array( - 'key_from' => 'perms_id', - 'model_to' => 'Model\\Auth_Permission', - 'key_to' => 'id', - ), - ); - - /** - * init the class - */ - public static function _init() - { - // auth config - \Config::load('ormauth', true); - - // set the connection this model should use - static::$_connection = \Config::get('ormauth.db_connection'); - - // set the write connection this model should use - static::$_write_connection = \Config::get('ormauth.db_write_connection') ?: static::$_connection; - - // set the models table name - static::$_table_name = \Config::get('ormauth.table_name', 'users').'_user_permissions'; - } -} diff --git a/fuel/packages/auth/composer.json b/fuel/packages/auth/composer.json deleted file mode 100755 index fa098d1..0000000 --- a/fuel/packages/auth/composer.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "fuel/auth", - "description" : "FuelPHP 1.x Auth Package", - "type": "fuel-package", - "homepage": "https://github.com/fuel/auth", - "license": "MIT", - "authors": [ - { - "name": "FuelPHP Development Team", - "email": "team@fuelphp.com" - } - ], - "require": { - "composer/installers": "~1.0" - } -} diff --git a/fuel/packages/auth/config/auth.php b/fuel/packages/auth/config/auth.php deleted file mode 100755 index bf29044..0000000 --- a/fuel/packages/auth/config/auth.php +++ /dev/null @@ -1,27 +0,0 @@ - 'Simpleauth', - 'verify_multiple_logins' => false, - 'salt' => 'put_your_salt_here', - 'iterations' => 10000, -); diff --git a/fuel/packages/auth/config/opauth.php b/fuel/packages/auth/config/opauth.php deleted file mode 100755 index 22ea337..0000000 --- a/fuel/packages/auth/config/opauth.php +++ /dev/null @@ -1,86 +0,0 @@ - true, - - /** - * auto_registration - * - * If true, a login via a provider will automatically create a dummy - * local user account with a random password, if a nickname and an - * email address is present - */ - 'auto_registration' => false, - - /** - * default_group - * - * Group id to be assigned to newly created users - */ - 'default_group' => 1, - - /** - * debug - * - * Uncomment if you would like to view debug messages - */ - 'debug' => false, - - /** - * A random string used for signing of auth response. - * - * You HAVE to set this value in your application config file! - */ - 'security_salt' => null, - - /** - * Higher value, better security, slower hashing; - * Lower value, lower security, faster hashing. - */ - 'security_iteration' => 300, - - /** - * Time limit for valid $auth response, starting from $auth response generation to validation. - */ - 'security_timeout' => '2 minutes', - - /** - * Strategy - * Refer to individual strategy's documentation on configuration requirements. - */ - 'Strategy' => array( - - /** - * 'Facebook' => array( - * 'app_id' => 'APP ID', - * 'app_secret' => 'APP_SECRET' - * ), - */ - - ), -); diff --git a/fuel/packages/auth/config/ormauth.php b/fuel/packages/auth/config/ormauth.php deleted file mode 100755 index 62cd484..0000000 --- a/fuel/packages/auth/config/ormauth.php +++ /dev/null @@ -1,98 +0,0 @@ - null, - - /** - * DB write connection, leave null to use same value as db_connection - */ - 'db_write_connection' => null, - - /** - * DB table name for the user table - */ - 'table_name' => 'users', - - /** - * Array, choose which columns from the users table are selected. - * must include: username, password, email, last_login, - * login_hash, group & profile_fields - */ - 'table_columns' => null, - - /** - * prefix to use for the cache - */ - 'cache_prefix' => 'auth', - - /** - * This will allow you to use the group & acl driver for non-logged in users - */ - 'guest_login' => true, - - /** - * Remember-me functionality - */ - 'remember_me' => array( - /** - * Whether or not remember me functionality is enabled - */ - 'enabled' => false, - - /** - * Name of the cookie used to record this functionality - */ - 'cookie_name' => 'rmcookie', - - /** - * Remember me expiration (default: 31 days) - */ - 'expiration' => 86400 * 31, - ), - - /** - * This will allow the same user to be logged in multiple times. - * - * Note that this is less secure, as session hijacking countermeasures have to - * be disabled for this to work! - */ - 'multiple_logins' => false, - - /** - * Salt for the login hash - */ - 'login_hash_salt' => 'put_some_salt_in_here', - - /** - * $_POST key for login username - */ - 'username_post_key' => 'username', - - /** - * $_POST key for login password - */ - 'password_post_key' => 'password', -); diff --git a/fuel/packages/auth/config/simpleauth.php b/fuel/packages/auth/config/simpleauth.php deleted file mode 100755 index 1c07f43..0000000 --- a/fuel/packages/auth/config/simpleauth.php +++ /dev/null @@ -1,133 +0,0 @@ - null, - - /** - * DB write connection, leave null to use same value as db_connection - */ - 'db_write_connection' => null, - - /** - * DB table name for the user table - */ - 'table_name' => 'users', - - /** - * Array, choose which columns from the users table are selected. - * must include: username, password, email, last_login, - * login_hash, group & profile_fields - */ - 'table_columns' => null, - - /** - * This will allow you to use the group & acl driver for non-logged in users - */ - 'guest_login' => true, - - /** - * This will allow the same user to be logged in multiple times. - * - * Note that this is less secure, as session hijacking countermeasures have to - * be disabled for this to work! - */ - 'multiple_logins' => false, - - /** - * Remember-me functionality - */ - 'remember_me' => array( - /** - * Whether or not remember me functionality is enabled - */ - 'enabled' => false, - - /** - * Name of the cookie used to record this functionality - */ - 'cookie_name' => 'rmcookie', - - /** - * Remember me expiration (default: 31 days) - */ - 'expiration' => 86400 * 31, - ), - - /** - * Groups as id => array(name => , roles => ) - */ - 'groups' => array( - /** - * Examples - * --- - * - * -1 => array('name' => 'Banned', 'roles' => array('banned')), - * 0 => array('name' => 'Guests', 'roles' => array()), - * 1 => array('name' => 'Users', 'roles' => array('user')), - * 50 => array('name' => 'Moderators', 'roles' => array('user', 'moderator')), - * 100 => array('name' => 'Administrators', 'roles' => array('user', 'moderator', 'admin')), - */ - ), - - /** - * Roles as name => array(location => rights) - */ - 'roles' => array( - /** - * Examples - * --- - * - * Regular example with role "user" given create & read rights on "comments": - * 'user' => array('comments' => array('create', 'read')), - * And similar additional rights for moderators: - * 'moderator' => array('comments' => array('update', 'delete')), - * - * Wildcard # role (auto assigned to all groups): - * '#' => array('website' => array('read')) - * - * Global disallow by assigning false to a role: - * 'banned' => false, - * - * Global allow by assigning true to a role (use with care!): - * 'super' => true, - */ - ), - - /** - * Salt for the login hash - */ - 'login_hash_salt' => 'put_some_salt_in_here', - - /** - * $_POST key for login username - */ - 'username_post_key' => 'username', - - /** - * $_POST key for login password - */ - 'password_post_key' => 'password', -); diff --git a/fuel/packages/auth/lang/en/auth_model_group.php b/fuel/packages/auth/lang/en/auth_model_group.php deleted file mode 100755 index 508a2f2..0000000 --- a/fuel/packages/auth/lang/en/auth_model_group.php +++ /dev/null @@ -1,5 +0,0 @@ - 'Group name', -); diff --git a/fuel/packages/auth/lang/en/auth_model_permission.php b/fuel/packages/auth/lang/en/auth_model_permission.php deleted file mode 100755 index 9143ac7..0000000 --- a/fuel/packages/auth/lang/en/auth_model_permission.php +++ /dev/null @@ -1,7 +0,0 @@ - 'Area name', - 'permission' => 'Permission name', - 'description' => 'Description', -); diff --git a/fuel/packages/auth/lang/en/auth_model_role.php b/fuel/packages/auth/lang/en/auth_model_role.php deleted file mode 100755 index d2f756b..0000000 --- a/fuel/packages/auth/lang/en/auth_model_role.php +++ /dev/null @@ -1,13 +0,0 @@ - 'Role name', - 'filter' => 'Special permissions', - - 'permissions' => array( - '' => 'None', - 'A' => 'Allow all access', - 'D' => 'Deny all access', - 'R' => 'Revoke assigned permissions', - ), -); diff --git a/fuel/packages/auth/lang/en/auth_model_user.php b/fuel/packages/auth/lang/en/auth_model_user.php deleted file mode 100755 index f195cce..0000000 --- a/fuel/packages/auth/lang/en/auth_model_user.php +++ /dev/null @@ -1,8 +0,0 @@ - 'User name', - 'email' => 'Email address', - 'password' => 'Password', - 'group_id' => 'Group', -); diff --git a/fuel/packages/auth/migrations/001_auth_create_usertables.php b/fuel/packages/auth/migrations/001_auth_create_usertables.php deleted file mode 100755 index c55d698..0000000 --- a/fuel/packages/auth/migrations/001_auth_create_usertables.php +++ /dev/null @@ -1,264 +0,0 @@ -dbconnection('simpleauth'); - - // only do this if it doesn't exist yet - if ( ! \DBUtil::table_exists($table)) - { - // table users - \DBUtil::create_table($table, array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'username' => array('type' => 'varchar', 'constraint' => 50), - 'password' => array('type' => 'varchar', 'constraint' => 255), - 'group' => array('type' => 'int', 'constraint' => 11, 'default' => 1), - 'email' => array('type' => 'varchar', 'constraint' => 255), - 'last_login' => array('type' => 'varchar', 'constraint' => 25), - 'login_hash' => array('type' => 'varchar', 'constraint' => 255), - 'profile_fields' => array('type' => 'text'), - 'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - ), array('id')); - - // add a unique index on username and email - \DBUtil::create_index($table, array('username', 'email'), 'username', 'UNIQUE'); - } - } - - elseif (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $table = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - - if ( ! \DBUtil::table_exists($table)) - { - // get the simpleauth tablename, maybe that exists - \Config::load('simpleauth', true); - $simpletable = \Config::get('simpleauth.table_name', 'users'); - - if ( ! \DBUtil::table_exists($simpletable)) - { - // table users - \DBUtil::create_table($table, array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'username' => array('type' => 'varchar', 'constraint' => 50), - 'password' => array('type' => 'varchar', 'constraint' => 255), - 'group_id' => array('type' => 'int', 'constraint' => 11, 'default' => 1), - 'email' => array('type' => 'varchar', 'constraint' => 255), - 'last_login' => array('type' => 'varchar', 'constraint' => 25), - 'previous_login' => array('type' => 'varchar', 'constraint' => 25, 'default' => 0), - 'login_hash' => array('type' => 'varchar', 'constraint' => 255), - 'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - ), array('id')); - - // add a unique index on username and email - \DBUtil::create_index($table, array('username', 'email'), 'username', 'UNIQUE'); - } - else - { - \DBUtil::rename_table($simpletable, $table); - } - } - - // run a check on required fields, and deal with missing ones. we might be migrating from simpleauth - if (\DBUtil::field_exists($table, 'group')) - { - \DBUtil::modify_fields($table, array( - 'group' => array('name' => 'group_id', 'type' => 'int', 'constraint' => 11), - )); - } - if ( ! \DBUtil::field_exists($table, 'group_id')) - { - \DBUtil::add_fields($table, array( - 'group_id' => array('type' => 'int', 'constraint' => 11, 'default' => 1, 'after' => 'password'), - )); - } - if ( ! \DBUtil::field_exists($table, 'previous_login')) - { - \DBUtil::add_fields($table, array( - 'previous_login' => array('type' => 'varchar', 'constraint' => 25, 'default' => 0, 'after' => 'last_login'), - )); - } - if ( ! \DBUtil::field_exists($table, 'user_id')) - { - \DBUtil::add_fields($table, array( - 'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'login_hash'), - )); - } - if (\DBUtil::field_exists($table, 'created')) - { - \DBUtil::modify_fields($table, array( - 'created' => array('name' => 'created_at', 'type' => 'int', 'constraint' => 11), - )); - } - if ( ! \DBUtil::field_exists($table, 'created_at')) - { - \DBUtil::add_fields($table, array( - 'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'user_id'), - )); - } - if (\DBUtil::field_exists($table, 'updated')) - { - \DBUtil::modify_fields($table, array( - 'updated' => array('name' => 'updated_at', 'type' => 'int', 'constraint' => 11), - )); - } - if ( ! \DBUtil::field_exists($table, 'updated_at')) - { - \DBUtil::add_fields($table, array( - 'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'created_at'), - )); - } - - // table users_meta - \DBUtil::create_table($table.'_metadata', array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'parent_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'key' => array('type' => 'varchar', 'constraint' => 20), - 'value' => array('type' => 'varchar', 'constraint' => 100), - 'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - ), array('id')); - - // convert profile fields to metadata, and drop the column - if (\DBUtil::field_exists($table, 'profile_fields')) - { - $result = \DB::select('id', 'profile_fields')->from($table)->execute(\Config::get('ormauth.db_connection', null)); - foreach ($result as $row) - { - $profile_fields = empty($row['profile_fields']) ? array() : unserialize($row['profile_fields']); - foreach ($profile_fields as $field => $value) - { - if ( ! is_numeric($field)) - { - \DB::insert($table.'_metadata')->set( - array( - 'parent_id' => $row['id'], - 'key' => $field, - 'value' => $value, - ) - )->execute(\Config::get('ormauth.db_connection', null)); - } - } - } - \DBUtil::drop_fields($table, array( - 'profile_fields', - )); - } - - // table users_user_role - \DBUtil::create_table($table.'_user_roles', array( - 'user_id' => array('type' => 'int', 'constraint' => 11), - 'role_id' => array('type' => 'int', 'constraint' => 11), - ), array('user_id', 'role_id')); - - // table users_user_perms - \DBUtil::create_table($table.'_user_permissions', array( - 'user_id' => array('type' => 'int', 'constraint' => 11), - 'perms_id' => array('type' => 'int', 'constraint' => 11), - ), array('user_id', 'perms_id')); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - function down() - { - // get the drivers defined - $drivers = normalize_driver_types(); - - if (in_array('Simpleauth', $drivers)) - { - // get the tablename - \Config::load('simpleauth', true); - $table = \Config::get('simpleauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('simpleauth'); - - // drop the admin_users table - \DBUtil::drop_table($table); - } - - elseif (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $table = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - - // drop the admin_users table - \DBUtil::drop_table($table); - - // drop the admin_users_meta table - \DBUtil::drop_table($table.'_metadata'); - - // drop the admin_users_user_role table - \DBUtil::drop_table($table.'_user_roles'); - - // drop the admin_users_user_perms table - \DBUtil::drop_table($table.'_user_permissions'); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - /** - * check if we need to override the db connection for auth tables - */ - protected function dbconnection($type = null) - { - static $connection; - - switch ($type) - { - // switch to the override connection - case 'simpleauth': - case 'ormauth': - if ($connection = \Config::get($type.'.db_connection', null)) - { - \DBUtil::set_connection($connection); - } - break; - - // switch back to the configured migration connection, or the default one - case false: - if ($connection) - { - \DBUtil::set_connection(\Config::get('migrations.connection', null)); - } - break; - - default: - // noop - } - } -} diff --git a/fuel/packages/auth/migrations/002_auth_create_grouptables.php b/fuel/packages/auth/migrations/002_auth_create_grouptables.php deleted file mode 100755 index e8b6869..0000000 --- a/fuel/packages/auth/migrations/002_auth_create_grouptables.php +++ /dev/null @@ -1,107 +0,0 @@ -dbconnection('ormauth'); - - // table users_group - \DBUtil::create_table($table.'_groups', array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'name' => array('type' => 'varchar', 'constraint' => 255), - 'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - ), array('id')); - - // table users_group_role - \DBUtil::create_table($table.'_group_roles', array( - 'group_id' => array('type' => 'int', 'constraint' => 11), - 'role_id' => array('type' => 'int', 'constraint' => 11), - ), array('group_id', 'role_id')); - - // table users_group_perms - \DBUtil::create_table($table.'_group_permissions', array( - 'group_id' => array('type' => 'int', 'constraint' => 11), - 'perms_id' => array('type' => 'int', 'constraint' => 11), - ), array('group_id', 'perms_id')); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - function down() - { - // get the drivers defined - $drivers = normalize_driver_types(); - - if (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $table = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - - // drop the admin_users_group table - \DBUtil::drop_table($table.'_groups'); - - // drop the admin_users_group_role table - \DBUtil::drop_table($table.'_group_roles'); - - // drop the admin_users_group_perms table - \DBUtil::drop_table($table.'_group_permissions'); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - /** - * check if we need to override the db connection for auth tables - */ - protected function dbconnection($type = null) - { - static $connection; - - switch ($type) - { - // switch to the override connection - case 'simpleauth': - case 'ormauth': - if ($connection = \Config::get($type.'.db_connection', null)) - { - \DBUtil::set_connection($connection); - } - break; - - // switch back to the configured migration connection, or the default one - case false: - if ($connection) - { - \DBUtil::set_connection(\Config::get('migrations.connection', null)); - } - break; - - default: - // noop - } - } -} diff --git a/fuel/packages/auth/migrations/003_auth_create_roletables.php b/fuel/packages/auth/migrations/003_auth_create_roletables.php deleted file mode 100755 index fecc6a1..0000000 --- a/fuel/packages/auth/migrations/003_auth_create_roletables.php +++ /dev/null @@ -1,99 +0,0 @@ -dbconnection('ormauth'); - - // table users_role - \DBUtil::create_table($table.'_roles', array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'name' => array('type' => 'varchar', 'constraint' => 255), - 'filter' => array('type' => 'enum', 'constraint' => "'', 'A', 'D'", 'default' => ''), - 'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - ), array('id')); - - // table users_role_perms - \DBUtil::create_table($table.'_role_permissions', array( - 'role_id' => array('type' => 'int', 'constraint' => 11), - 'perms_id' => array('type' => 'int', 'constraint' => 11), - ), array('role_id', 'perms_id')); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - function down() - { - // get the drivers defined - $drivers = normalize_driver_types(); - - if (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $table = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - - // drop the admin_users_role table - \DBUtil::drop_table($table.'_roles'); - - // drop the admin_users_role_perms table - \DBUtil::drop_table($table.'_role_permissions'); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - /** - * check if we need to override the db connection for auth tables - */ - protected function dbconnection($type = null) - { - static $connection; - - switch ($type) - { - // switch to the override connection - case 'simpleauth': - case 'ormauth': - if ($connection = \Config::get($type.'.db_connection', null)) - { - \DBUtil::set_connection($connection); - } - break; - - // switch back to the configured migration connection, or the default one - case false: - if ($connection) - { - \DBUtil::set_connection(\Config::get('migrations.connection', null)); - } - break; - - default: - // noop - } - } -} diff --git a/fuel/packages/auth/migrations/004_auth_create_permissiontables.php b/fuel/packages/auth/migrations/004_auth_create_permissiontables.php deleted file mode 100755 index 783bc4c..0000000 --- a/fuel/packages/auth/migrations/004_auth_create_permissiontables.php +++ /dev/null @@ -1,94 +0,0 @@ -dbconnection('ormauth'); - - // table users_perms - \DBUtil::create_table($table.'_permissions', array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'area' => array('type' => 'varchar', 'constraint' => 25), - 'permission' => array('type' => 'varchar', 'constraint' => 25), - 'description' => array('type' => 'varchar', 'constraint' => 255), - 'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - ), array('id')); - - // add a unique index on group and permission - \DBUtil::create_index($table.'_permissions', array('area', 'permission'), 'permission', 'UNIQUE'); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - function down() - { - // get the drivers defined - $drivers = normalize_driver_types(); - - if (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $table = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - - // drop the admin_users_perms table - \DBUtil::drop_table($table.'_permissions'); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - /** - * check if we need to override the db connection for auth tables - */ - protected function dbconnection($type = null) - { - static $connection; - - switch ($type) - { - // switch to the override connection - case 'simpleauth': - case 'ormauth': - if ($connection = \Config::get($type.'.db_connection', null)) - { - \DBUtil::set_connection($connection); - } - break; - - // switch back to the configured migration connection, or the default one - case false: - if ($connection) - { - \DBUtil::set_connection(\Config::get('migrations.connection', null)); - } - break; - - default: - // noop - } - } -} diff --git a/fuel/packages/auth/migrations/005_auth_create_authdefaults.php b/fuel/packages/auth/migrations/005_auth_create_authdefaults.php deleted file mode 100755 index e673f93..0000000 --- a/fuel/packages/auth/migrations/005_auth_create_authdefaults.php +++ /dev/null @@ -1,161 +0,0 @@ -dbconnection('ormauth'); - - /* - * create the default Groups and roles, to be compatible with standard Auth - */ - - // create the 'Banned' group, 'banned' role - list($group_id, $rows_affected) = \DB::insert($table.'_groups')->set(array('name' => 'Banned'))->execute($connection); - list($role_id, $rows_affected) = \DB::insert($table.'_roles')->set(array('name' => 'banned', 'filter' => 'D'))->execute($connection); - \DB::insert($table.'_group_roles')->set(array('group_id' => $group_id, 'role_id' => $role_id))->execute($connection); - - // create the 'Guests' group - list($group_id_guest, $rows_affected) = \DB::insert($table.'_groups')->set(array('name' => 'Guests'))->execute($connection); - list($role_id_guest, $rows_affected) = \DB::insert($table.'_roles')->set(array('name' => 'public'))->execute($connection); - \DB::insert($table.'_group_roles')->set(array('group_id' => $group_id_guest, 'role_id' => $role_id_guest))->execute($connection); - - // create the 'Users' group - list($group_id, $rows_affected) = \DB::insert($table.'_groups')->set(array('name' => 'Users'))->execute($connection); - list($role_id_user, $rows_affected) = \DB::insert($table.'_roles')->set(array('name' => 'user'))->execute($connection); - \DB::insert($table.'_group_roles')->set(array('group_id' => $group_id, 'role_id' => $role_id_user))->execute($connection); - - // create the 'Moderators' group - list($group_id, $rows_affected) = \DB::insert($table.'_groups')->set(array('name' => 'Moderators'))->execute($connection); - list($role_id_mod, $rows_affected) = \DB::insert($table.'_roles')->set(array('name' => 'moderator'))->execute($connection); - \DB::insert($table.'_group_roles')->set(array('group_id' => $group_id, 'role_id' => $role_id_user))->execute($connection); - \DB::insert($table.'_group_roles')->set(array('group_id' => $group_id, 'role_id' => $role_id_mod))->execute($connection); - - // create the 'Administrators' group - list($group_id, $rows_affected) = \DB::insert($table.'_groups')->set(array('name' => 'Administrators'))->execute($connection); - list($role_id, $rows_affected) = \DB::insert($table.'_roles')->set(array('name' => 'administrator'))->execute($connection); - \DB::insert($table.'_group_roles')->set(array('group_id' => $group_id, 'role_id' => $role_id_user))->execute($connection); - \DB::insert($table.'_group_roles')->set(array('group_id' => $group_id, 'role_id' => $role_id_mod))->execute($connection); - \DB::insert($table.'_group_roles')->set(array('group_id' => $group_id, 'role_id' => $role_id))->execute($connection); - - // create the 'Superadmins' group - list($group_id_admin, $rows_affected) = \DB::insert($table.'_groups')->set(array('name' => 'Super Admins'))->execute($connection); - list($role_id_admin, $rows_affected) = \DB::insert($table.'_roles')->set(array('name' => 'superadmin', 'filter' => 'A'))->execute($connection); - \DB::insert($table.'_group_roles')->set(array('group_id' => $group_id_admin, 'role_id' => $role_id_admin))->execute($connection); - - /* - * create the default admin user, so we have initial access - */ - - // create the administrator account if needed, and assign it the superadmin group so it has all access - $result = \DB::select('id')->from($table)->where('username', '=', 'admin')->execute($connection); - if (count($result) == 0) - { - \Auth::instance()->create_user('admin', 'admin', 'admin@example.org', $group_id_admin, array('fullname' => 'System administrator')); - } - - // create the guest account - list($guest_id, $affected) = \DB::insert($table)->set( - array( - 'username' => 'guest', - 'password' => 'YOU CAN NOT USE THIS TO LOGIN', - 'email' => '', - 'group_id' => $group_id_guest, - 'last_login' => 0, - 'previous_login' => 0, - 'login_hash' => '', - 'user_id' => 0, - 'created_at' => time(), - 'updated_at' => 0, - ) - )->execute($connection); - - // adjust the id's, auto_increment doesn't want to create a key with value 0 - \DB::update($table)->set(array('id' => 0))->where('id', '=', $guest_id)->execute($connection); - - // add guests full name to the metadata - \DB::insert($table.'_metadata')->set( - array( - 'parent_id' => 0, - 'key' => 'fullname', - 'value' => 'Guest', - ) - )->execute($connection); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - function down() - { - // get the drivers defined - $drivers = normalize_driver_types(); - - if (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $table = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - - // empty the user, group and role tables - \DBUtil::truncate_table($table); - \DBUtil::truncate_table($table.'_groups'); - \DBUtil::truncate_table($table.'_roles'); - \DBUtil::truncate_table($table.'_group_roles'); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - /** - * check if we need to override the db connection for auth tables - */ - protected function dbconnection($type = null) - { - static $connection; - - switch ($type) - { - // switch to the override connection - case 'simpleauth': - case 'ormauth': - if ($connection = \Config::get($type.'.db_connection', null)) - { - \DBUtil::set_connection($connection); - } - break; - - // switch back to the configured migration connection, or the default one - case false: - if ($connection) - { - \DBUtil::set_connection(\Config::get('migrations.connection', null)); - } - break; - - default: - // noop - } - - return $connection; - } -} diff --git a/fuel/packages/auth/migrations/006_auth_add_authactions.php b/fuel/packages/auth/migrations/006_auth_add_authactions.php deleted file mode 100755 index 140b366..0000000 --- a/fuel/packages/auth/migrations/006_auth_add_authactions.php +++ /dev/null @@ -1,104 +0,0 @@ -dbconnection('ormauth'); - - // add the actions field to the permission and permission through tables - \DBUtil::add_fields($table.'_permissions', array( - 'actions' => array('type' => 'text', 'null' => true, 'after' => 'description'), - )); - \DBUtil::add_fields($table.'_user_permissions', array( - 'actions' => array('type' => 'text', 'null' => true, 'after' => 'perms_id'), - )); - \DBUtil::add_fields($table.'_group_permissions', array( - 'actions' => array('type' => 'text', 'null' => true, 'after' => 'perms_id'), - )); - \DBUtil::add_fields($table.'_role_permissions', array( - 'actions' => array('type' => 'text', 'null' => true, 'after' => 'perms_id'), - )); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - function down() - { - // get the drivers defined - $drivers = normalize_driver_types(); - - if (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $table = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - - \DBUtil::drop_fields($table.'_permissions', array( - 'actions', - )); - \DBUtil::drop_fields($table.'_user_permissions', array( - 'actions', - )); - \DBUtil::drop_fields($table.'_group_permissions', array( - 'actions', - )); - \DBUtil::drop_fields($table.'_role_permissions', array( - 'actions', - )); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - /** - * check if we need to override the db connection for auth tables - */ - protected function dbconnection($type = null) - { - static $connection; - - switch ($type) - { - // switch to the override connection - case 'simpleauth': - case 'ormauth': - if ($connection = \Config::get($type.'.db_connection', null)) - { - \DBUtil::set_connection($connection); - } - break; - - // switch back to the configured migration connection, or the default one - case false: - if ($connection) - { - \DBUtil::set_connection(\Config::get('migrations.connection', null)); - } - break; - - default: - // noop - } - } -} diff --git a/fuel/packages/auth/migrations/007_auth_add_permissionsfilter.php b/fuel/packages/auth/migrations/007_auth_add_permissionsfilter.php deleted file mode 100755 index f7f2751..0000000 --- a/fuel/packages/auth/migrations/007_auth_add_permissionsfilter.php +++ /dev/null @@ -1,91 +0,0 @@ -dbconnection('ormauth'); - - // modify the filter field to add the 'remove' filter - \DBUtil::modify_fields($table.'_roles', array( - 'filter' => array('type' => 'enum', 'constraint' => "'', 'A', 'D', 'R'", 'default' => ''), - )); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - function down() - { - // get the drivers defined - $drivers = normalize_driver_types(); - - if (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $table = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $connection = $this->dbconnection('ormauth'); - - // modify the filter field to add the 'remove' filter - \DB::update($table.'_roles')->set(array('filter' => 'D'))->where('filter', '=', 'R')->execute($connection); - - \DBUtil::modify_fields($table.'_roles', array( - 'filter' => array('type' => 'enum', 'constraint' => "'', 'A', 'D'", 'default' => ''), - )); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - /** - * check if we need to override the db connection for auth tables - */ - protected function dbconnection($type = null) - { - static $connection; - - switch ($type) - { - // switch to the override connection - case 'simpleauth': - case 'ormauth': - if ($connection = \Config::get($type.'.db_connection', null)) - { - \DBUtil::set_connection($connection); - } - break; - - // switch back to the configured migration connection, or the default one - case false: - if ($connection) - { - \DBUtil::set_connection(\Config::get('migrations.connection', null)); - } - break; - - default: - // noop - } - - return $connection; - } -} diff --git a/fuel/packages/auth/migrations/008_auth_create_providers.php b/fuel/packages/auth/migrations/008_auth_create_providers.php deleted file mode 100755 index 2e23e2e..0000000 --- a/fuel/packages/auth/migrations/008_auth_create_providers.php +++ /dev/null @@ -1,122 +0,0 @@ -dbconnection('simpleauth'); - } - - elseif (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $table = \Config::get('ormauth.table_name', 'users').'_providers'; - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - } - - if (isset($table)) - { - \DBUtil::create_table($table, array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'parent_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'provider' => array('type' => 'varchar', 'constraint' => 50), - 'uid' => array('type' => 'varchar', 'constraint' => 255), - 'secret' => array('type' => 'varchar', 'constraint' => 255, 'null' => true), - 'access_token' => array('type' => 'varchar', 'constraint' => 255, 'null' => true), - 'expires' => array( 'type' => 'int', 'constraint' => 12, 'default' => 0, 'null' => true), - 'refresh_token' => array('type' => 'varchar', 'constraint' => 255, 'null' => true), - 'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - ), array('id')); - - \DBUtil::create_index($table, 'parent_id', 'parent_id'); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - function down() - { - // get the drivers defined - $drivers = normalize_driver_types(); - - if (in_array('Simpleauth', $drivers)) - { - // get the tablename - \Config::load('simpleauth', true); - $table = \Config::get('simpleauth.table_name', 'users').'_providers'; - - // make sure the correct connection is used - $this->dbconnection('simpleauth'); - } - - elseif (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $table = \Config::get('ormauth.table_name', 'users').'_providers'; - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - } - - if (isset($table)) - { - // drop the users remote table - \DBUtil::drop_table($table); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - /** - * check if we need to override the db connection for auth tables - */ - protected function dbconnection($type = null) - { - static $connection; - - switch ($type) - { - // switch to the override connection - case 'simpleauth': - case 'ormauth': - if ($connection = \Config::get($type.'.db_connection', null)) - { - \DBUtil::set_connection($connection); - } - break; - - // switch back to the configured migration connection, or the default one - case false: - if ($connection) - { - \DBUtil::set_connection(\Config::get('migrations.connection', null)); - } - break; - - default: - // noop - } - } -} diff --git a/fuel/packages/auth/migrations/009_auth_create_oauth2tables.php b/fuel/packages/auth/migrations/009_auth_create_oauth2tables.php deleted file mode 100755 index 5903622..0000000 --- a/fuel/packages/auth/migrations/009_auth_create_oauth2tables.php +++ /dev/null @@ -1,200 +0,0 @@ -dbconnection('simpleauth'); - } - - elseif (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $basetable = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - } - - else - { - $basetable = 'users'; - } - - \DBUtil::create_table($basetable.'_clients', array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'name' => array('type' => 'varchar', 'constraint' => 32, 'default' => ''), - 'client_id' => array('type' => 'varchar', 'constraint' => 32, 'default' => ''), - 'client_secret' => array('type' => 'varchar', 'constraint' => 32, 'default' => ''), - 'redirect_uri' => array('type' => 'varchar', 'constraint' => 255, 'default' => ''), - 'auto_approve' => array( 'type' => 'tinyint', 'constraint' => 1, 'default' => 0), - 'autonomous' => array( 'type' => 'tinyint', 'constraint' => 1, 'default' => 0), - 'status' => array( 'type' => 'enum', 'constraint' => '"development","pending","approved","rejected"', 'default' => 'development'), - 'suspended' => array( 'type' => 'tinyint', 'constraint' => 1, 'default' => 0), - 'notes' => array('type' => 'tinytext'), - ), array('id')); - \DBUtil::create_index($basetable.'_clients', 'client_id', 'client_id', 'UNIQUE'); - - \DBUtil::create_table($basetable.'_sessions', - array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'client_id' => array('type' => 'varchar', 'constraint' => 32, 'default' => ''), - 'redirect_uri' => array('type' => 'varchar', 'constraint' => 255, 'default' => ''), - 'type_id' => array('type' => 'varchar', 'constraint' => 64), - 'type' => array( 'type' => 'enum', 'constraint' => '"user","auto"', 'default' => 'user'), - 'code' => array('type' => 'text'), - 'access_token' => array('type' => 'varchar', 'constraint' => 50, 'default' => ''), - 'stage' => array( 'type' => 'enum', 'constraint' => '"request","granted"', 'default' => 'request'), - 'first_requested' => array( 'type' => 'int', 'constraint' => 11), - 'last_updated' => array( 'type' => 'int', 'constraint' => 11), - 'limited_access' => array( 'type' => 'tinyint', 'constraint' => 1, 'default' => 0), - ), - array('id'), - true, - false, - null, - array( - array( - 'constraint' => 'oauth_sessions_ibfk_1', - 'key' => 'client_id', - 'reference' => array( - 'table' => $basetable.'_clients', - 'column' => 'client_id', - ), - 'on_delete' => 'CASCADE', - ), - ) - ); - - \DBUtil::create_table($basetable.'_scopes', array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'scope' => array('type' => 'varchar', 'constraint' => 64, 'default' => ''), - 'name' => array('type' => 'varchar', 'constraint' => 64, 'default' => ''), - 'description' => array('type' => 'varchar', 'constraint' => 255, 'default' => ''), - ), array('id')); - \DBUtil::create_index($basetable.'_scopes', 'scope', 'scope', 'UNIQUE'); - - \DBUtil::create_table($basetable.'_sessionscopes', - array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'session_id' => array('type' => 'int', 'constraint' => 11), - 'access_token' => array('type' => 'varchar', 'constraint' => 50, 'default' => ''), - 'scope' => array('type' => 'varchar', 'constraint' => 64, 'default' => ''), - ), - array('id'), - true, - false, - null, - array( - array( - 'constraint' => 'oauth_sessionscopes_ibfk_1', - 'key' => 'scope', - 'reference' => array( - 'table' => $basetable.'_scopes', - 'column' => 'scope', - ), - ), - array( - 'constraint' => 'oauth_sessionscopes_ibfk_2', - 'key' => 'session_id', - 'reference' => array( - 'table' => $basetable.'_sessions', - 'column' => 'id', - ), - 'on_delete' => 'CASCADE', - ), - ) - ); - \DBUtil::create_index($basetable.'_sessionscopes', 'session_id', 'session_id'); - \DBUtil::create_index($basetable.'_sessionscopes', 'access_token', 'access_token'); - \DBUtil::create_index($basetable.'_sessionscopes', 'scope', 'scope'); - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - function down() - { - // get the drivers defined - $drivers = normalize_driver_types(); - - if (in_array('Simpleauth', $drivers)) - { - // get the tablename - \Config::load('simpleauth', true); - $basetable = \Config::get('simpleauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('simpleauth'); - } - - elseif (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $basetable = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - } - - else - { - $basetable = 'users'; - } - - \DBUtil::drop_table($basetable.'_sessionscopes'); - \DBUtil::drop_table($basetable.'_sessions'); - \DBUtil::drop_table($basetable.'_scopes'); - \DBUtil::drop_table($basetable.'_clients'); - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - /** - * check if we need to override the db connection for auth tables - */ - protected function dbconnection($type = null) - { - static $connection; - - switch ($type) - { - // switch to the override connection - case 'simpleauth': - case 'ormauth': - if ($connection = \Config::get($type.'.db_connection', null)) - { - \DBUtil::set_connection($connection); - } - break; - - // switch back to the configured migration connection, or the default one - case false: - if ($connection) - { - \DBUtil::set_connection(\Config::get('migrations.connection', null)); - } - break; - - default: - // noop - } - } -} diff --git a/fuel/packages/auth/migrations/010_auth_fix_jointables.php b/fuel/packages/auth/migrations/010_auth_fix_jointables.php deleted file mode 100755 index ffc2d35..0000000 --- a/fuel/packages/auth/migrations/010_auth_fix_jointables.php +++ /dev/null @@ -1,107 +0,0 @@ -dbconnection('ormauth'); - - \DBUtil::drop_index($basetable.'_user_permissions', 'primary'); - \DBUtil::add_fields($basetable.'_user_permissions', array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true, 'primary_key' => true, 'first' => true), - )); - - \DBUtil::drop_index($basetable.'_group_permissions', 'primary'); - \DBUtil::add_fields($basetable.'_group_permissions', array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true, 'primary_key' => true, 'first' => true), - )); - - \DBUtil::drop_index($basetable.'_role_permissions', 'primary'); - \DBUtil::add_fields($basetable.'_role_permissions', array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true, 'primary_key' => true, 'first' => true), - )); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - function down() - { - // get the drivers defined - $drivers = normalize_driver_types(); - - if (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $basetable = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - - \DBUtil::drop_fields($basetable.'_user_permissions', array( - 'id', - )); - \DBUtil::create_index($basetable.'_user_permissions', array('user_id', 'perms_id'), '', 'PRIMARY'); - - \DBUtil::drop_fields($basetable.'_group_permissions', array( - 'id', - )); - \DBUtil::create_index($basetable.'_group_permissions', array('group_id', 'perms_id'), '', 'PRIMARY'); - - \DBUtil::drop_fields($basetable.'_role_permissions', array( - 'id', - )); - \DBUtil::create_index($basetable.'_role_permissions', array('role_id', 'perms_id'), '', 'PRIMARY'); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - /** - * check if we need to override the db connection for auth tables - */ - protected function dbconnection($type = null) - { - static $connection; - - switch ($type) - { - // switch to the override connection - case 'simpleauth': - case 'ormauth': - if ($connection = \Config::get($type.'.db_connection', null)) - { - \DBUtil::set_connection($connection); - } - break; - - // switch back to the configured migration connection, or the default one - case false: - if ($connection) - { - \DBUtil::set_connection(\Config::get('migrations.connection', null)); - } - break; - - default: - // noop - } - } -} diff --git a/fuel/packages/auth/migrations/011_auth_group_optional.php b/fuel/packages/auth/migrations/011_auth_group_optional.php deleted file mode 100644 index 58c2672..0000000 --- a/fuel/packages/auth/migrations/011_auth_group_optional.php +++ /dev/null @@ -1,87 +0,0 @@ -dbconnection('ormauth'); - - // make the group_id optional - \DBUtil::modify_fields($table, array( - 'group_id' => array('type' => 'int', 'constraint' => 11, 'null' => true, 'default' => null), - )); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - function down() - { - // get the drivers defined - $drivers = normalize_driver_types(); - - if (in_array('Ormauth', $drivers)) - { - // get the tablename - \Config::load('ormauth', true); - $table = \Config::get('ormauth.table_name', 'users'); - - // make sure the correct connection is used - $this->dbconnection('ormauth'); - - // make the group_id optional - \DBUtil::modify_fields($table, array( - 'group_id' => array('type' => 'int', 'constraint' => 11, 'null' => true, 'default' => null), - )); - } - - // reset any DBUtil connection set - $this->dbconnection(false); - } - - /** - * check if we need to override the db connection for auth tables - */ - protected function dbconnection($type = null) - { - static $connection; - - switch ($type) - { - // switch to the override connection - case 'simpleauth': - case 'ormauth': - if ($connection = \Config::get($type.'.db_connection', null)) - { - \DBUtil::set_connection($connection); - } - break; - - // switch back to the configured migration connection, or the default one - case false: - if ($connection) - { - \DBUtil::set_connection(\Config::get('migrations.connection', null)); - } - break; - - default: - // noop - } - } -} diff --git a/fuel/packages/auth/normalizedrivertypes.php b/fuel/packages/auth/normalizedrivertypes.php deleted file mode 100755 index 36ae47c..0000000 --- a/fuel/packages/auth/normalizedrivertypes.php +++ /dev/null @@ -1,57 +0,0 @@ -from($migrations['table'])->where('type', '=', 'package')->where('name', '=', 'auth')->execute(); - if (count($result) < 7) - { - $errors[] = 'Auth database migrations haven\'t run (succesfully).'; - $errors[] = 'There is a discrepancy between your migration configuration file and the migration table.'; - } - } - - // check the fields of the users table - $usertable = array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'username' => array('type' => 'varchar', 'constraint' => 50, 'after' => 'id'), - 'password' => array('type' => 'varchar', 'constraint' => 255, 'after' => 'username'), - 'group_id' => array('type' => 'int', 'constraint' => 11, 'default' => 1, 'after' => 'password'), - 'email' => array('type' => 'varchar', 'constraint' => 255, 'after' => 'group_id'), - 'last_login' => array('type' => 'varchar', 'constraint' => 25, 'after' => 'email'), - 'previous_login' => array('type' => 'varchar', 'constraint' => 25, 'default' => 0, 'after' => 'last_login'), - 'login_hash' => array('type' => 'varchar', 'constraint' => 255, 'after' => 'previous_login'), - 'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'login_hash'), - 'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'user_id'), - 'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'created_at'), - ); - - foreach ($usertable as $field => $value) - { - if (\DBUtil::field_exists(static::$data['ormauth_table'], $field)) - { - unset($usertable[$field]); - } - } - if ( ! empty($usertable)) - { - $errors[] = 'User table "'.static::$data['ormauth_table'].'" is missing the field(s): '.implode(', ', array_keys($usertable)); - } - - // process the results of the validation - if ($errors) - { - // display all errors - \Cli::write('You environment did not validate:', 'light_red'); - - foreach ($errors as $error) - { - \Cli::write('* '.$error); - } - - return false; - } - - // inform the user we're good to go - \Cli::write('Environment validated', 'light_green'); - return true; - } - - /** - * Run the actual migration - */ - protected static function run_migration() - { - // make sure we've got a usertable we can work with - static::usertable(); - - // get the simpleauth config - \Config::load('simpleauth', true); - $simpleauth = \Config::get('simpleauth', array()); - - // process the defined roles - foreach (\Config::get('simpleauth.roles', array()) as $role => $config) - { - // skip all non-standard roles - if ($role == '#' or ! is_array($config)) - { - continue; - } - - // do we already have this role? - $result = \DB::select('id')->from(static::$data['ormauth_table'].'_roles')->where('name', '=', $role)->execute(); - if (count($result)) - { - $role_id = $result[0]['id']; - } - - // no, add it - else - { - \Cli::write('- creating role: '.$role, 'light_green'); - list($role_id, $rows_affected) = \DB::insert(static::$data['ormauth_table'].'_roles')->set(array('name' => $role))->execute(); - } - - // fetch the role as an ORM object, and assign the defined permissions to it - $role = \Model\Auth_Role::find($role_id); - if ($role) - { - foreach ($config as $area => $permissions) - { - foreach ($permissions as $permission) - { - $perm = \Model\Auth_Permission::query()->where('area', '=', $area)->where('permission', '=', $permission)->get_one(); - if ( ! $perm) - { - \Cli::write('- creating permission: '.$area.'.'.$permission, 'light_green'); - $perm = \Model\Auth_Permission::forge(array('area' => $area, 'permission' => $permission, 'description' => $area.'.'.$permission, 'actions' => serialize(array()))); - } - $role->permissions[] = $perm; - } - } - - // update the role and save the permissions - $role->save(); - } - } - - // process the defined groups - foreach (\Config::get('simpleauth.groups', array()) as $group => $config) - { - // ignore invalid entries - if ( ! isset($config['name']) or ! isset($config['roles'])) - { - continue; - } - - // do we already have this group? - $result = \DB::select('id')->from(static::$data['ormauth_table'].'_groups')->where('name', '=', $config['name'])->execute(); - if (count($result)) - { - $group_id = $result[0]['id']; - } - - // no, add it - else - { - \Cli::write('- creating group: '.$config['name'], 'light_green'); - list($group_id, $rows_affected) = \DB::insert(static::$data['ormauth_table'].'_groups')->set(array('name' => $config['name']))->execute(); - } - - // update the user group entries - \DB::update(static::$data['ormauth_table'])->set(array('group_id' => $group_id))->where('group_id', '=', $group)->execute(); - - // fetch the group as an ORM object, and assign the defined roles to it - $group = \Model\Auth_Group::find($group_id); - - if ($group) - { - foreach ($config['roles'] as $role) - { - $role = \Model\Auth_Role::query()->where('name', '=', $role)->get_one(); - if ( ! $role) - { - $role = \Model\Auth_Role::forge(array('name' => $role)); - \Cli::write('- creating role: '.$role, 'light_green'); - } - $group->roles[] = $role; - } - - // update the group and save the roles - $group->save(); - } - } - - return true; - } - - /* - * Deal with potential changes in users table layout between simpleauth and ormauth - */ - protected static function usertable() - { - if ( ! \DBUtil::table_exists(static::$data['ormauth_table'])) - { - if ( ! \DBUtil::table_exists(static::$data['simpleauth_table'])) - { - // table users - \DBUtil::create_table(static::$data['ormauth_table'], array( - 'id' => array('type' => 'int', 'constraint' => 11, 'auto_increment' => true), - 'username' => array('type' => 'varchar', 'constraint' => 50), - 'password' => array('type' => 'varchar', 'constraint' => 255), - 'group_id' => array('type' => 'int', 'constraint' => 11, 'default' => 1), - 'email' => array('type' => 'varchar', 'constraint' => 255), - 'last_login' => array('type' => 'varchar', 'constraint' => 25), - 'previous_login' => array('type' => 'varchar', 'constraint' => 25, 'default' => 0), - 'login_hash' => array('type' => 'varchar', 'constraint' => 255), - 'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - 'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0), - ), array('id')); - - // add a unique index on username and email - \DBUtil::create_index(static::$data['ormauth_table'], array('username', 'email'), 'username', 'UNIQUE'); - } - else - { - \DBUtil::rename_table(static::$data['simpleauth_table'], static::$data['ormauth_table']); - } - } - - // run a check on required fields, and deal with missing ones. we might be migrating from simpleauth - if (\DBUtil::field_exists(static::$data['ormauth_table'], 'group')) - { - \DBUtil::modify_fields(static::$data['ormauth_table'], array( - 'group' => array('name' => 'group_id', 'type' => 'int', 'constraint' => 11), - )); - } - if ( ! \DBUtil::field_exists(static::$data['ormauth_table'], 'group_id')) - { - \DBUtil::add_fields(static::$data['ormauth_table'], array( - 'group_id' => array('type' => 'int', 'constraint' => 11, 'default' => 1, 'after' => 'password'), - )); - } - if ( ! \DBUtil::field_exists(static::$data['ormauth_table'], 'previous_login')) - { - \DBUtil::add_fields(static::$data['ormauth_table'], array( - 'previous_login' => array('type' => 'varchar', 'constraint' => 25, 'default' => 0, 'after' => 'last_login'), - )); - } - if ( ! \DBUtil::field_exists(static::$data['ormauth_table'], 'user_id')) - { - \DBUtil::add_fields(static::$data['ormauth_table'], array( - 'user_id' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'login_hash'), - )); - } - if (\DBUtil::field_exists(static::$data['ormauth_table'], 'created')) - { - \DBUtil::modify_fields(static::$data['ormauth_table'], array( - 'created' => array('name' => 'created_at', 'type' => 'int', 'constraint' => 11), - )); - } - if ( ! \DBUtil::field_exists(static::$data['ormauth_table'], 'created_at')) - { - \DBUtil::add_fields(static::$data['ormauth_table'], array( - 'created_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'user_id'), - )); - } - if (\DBUtil::field_exists(static::$data['ormauth_table'], 'updated')) - { - \DBUtil::modify_fields(static::$data['ormauth_table'], array( - 'updated' => array('name' => 'updated_at', 'type' => 'int', 'constraint' => 11), - )); - } - if ( ! \DBUtil::field_exists(static::$data['ormauth_table'], 'updated_at')) - { - \DBUtil::add_fields(static::$data['ormauth_table'], array( - 'updated_at' => array('type' => 'int', 'constraint' => 11, 'default' => 0, 'after' => 'created_at'), - )); - } - } -} diff --git a/fuel/packages/email/bootstrap.php b/fuel/packages/email/bootstrap.php deleted file mode 100755 index e36b297..0000000 --- a/fuel/packages/email/bootstrap.php +++ /dev/null @@ -1,50 +0,0 @@ - __DIR__.'/classes/email.php', - 'Email\\Email_Driver' => __DIR__.'/classes/email/driver.php', - 'Email\\Email_Driver_Mail' => __DIR__.'/classes/email/driver/mail.php', - 'Email\\Email_Driver_Smtp' => __DIR__.'/classes/email/driver/smtp.php', - 'Email\\Email_Driver_Sendmail' => __DIR__.'/classes/email/driver/sendmail.php', - 'Email\\Email_Driver_Noop' => __DIR__.'/classes/email/driver/noop.php', - 'Email\\Email_Driver_Mailgun' => __DIR__.'/classes/email/driver/mailgun.php', - 'Email\\Email_Driver_Mandrill' => __DIR__.'/classes/email/driver/mandrill.php', - - /** - * Email exceptions. - */ - 'Email\\AttachmentNotFoundException' => __DIR__.'/classes/email.php', - 'Email\\InvalidAttachmentsException' => __DIR__.'/classes/email.php', - 'Email\\InvalidEmailStringEncoding' => __DIR__.'/classes/email.php', - 'Email\\EmailSendingFailedException' => __DIR__.'/classes/email.php', - 'Email\\EmailValidationFailedException' => __DIR__.'/classes/email.php', - - /** - * Smtp exceptions - */ - 'Email\\SmtpTimeoutException' => __DIR__.'/classes/email/driver/smtp.php', - 'Email\\SmtpConnectionException' => __DIR__.'/classes/email/driver/smtp.php', - 'Email\\SmtpCommandFailureException' => __DIR__.'/classes/email/driver/smtp.php', - 'Email\\SmtpAuthenticationFailedException' => __DIR__.'/classes/email/driver/smtp.php', - - /** - * Sendmail exceptions - */ - 'Email\\SendmailFailedException' => __DIR__.'/classes/email/driver/sendmail.php', - 'Email\\SendmailConnectionException' => __DIR__.'/classes/email/driver/sendmail.php', -)); diff --git a/fuel/packages/email/classes/email.php b/fuel/packages/email/classes/email.php deleted file mode 100755 index a41a670..0000000 --- a/fuel/packages/email/classes/email.php +++ /dev/null @@ -1,111 +0,0 @@ - array(), - 'attachment' => array(), - ); - - /** - * Message body - */ - protected $body = ''; - - /** - * Message alt body - */ - protected $alt_body = ''; - - /** - * Message subject - */ - protected $subject = ''; - - /** - * Invalid addresses - */ - protected $invalid_addresses = array(); - - /** - * Message boundaries - */ - protected $boundaries = array(); - - /** - * Message headers - */ - protected $headers = array(); - - /** - * Custom headers - */ - protected $extra_headers = array(); - - /** - * Pipelining enabled? - */ - protected $pipelining = false; - - /** - * Mail type - */ - protected $type = 'plain'; - - /** - * Driver constructor - * - * @param array $config driver config - */ - public function __construct(array $config) - { - $this->config = $config; - } - - /** - * Get a driver config setting. - * - * @param string $key Config key - * @param string $default Default value - * - * @return mixed the config setting value - */ - public function get_config($key, $default = null) - { - return \Arr::get($this->config, $key, $default); - } - - /** - * Set a driver config setting. - * - * @param string $key the config key - * @param mixed $value the new config value - * @return object $this - */ - public function set_config($key, $value) - { - \Arr::set($this->config, $key, $value); - - return $this; - } - - /** - * Enables or disables driver pipelining. - * - * @param bool $pipelining Whether or not to enable pipelining - * - * @return $this - */ - public function pipelining($pipelining = true) - { - $this->pipelining = (bool) $pipelining; - - return $this; - } - - /** - * Gets the body - * - * @return string the message body - */ - public function get_body() - { - return $this->body; - } - - /** - * Sets the body - * - * @param string $body The message body - * - * @return $this - */ - public function body($body) - { - $this->body = (string) $body; - - return $this; - } - - /** - * Sets the alt body - * - * @param string $alt_body The message alt body - * - * @return $this - */ - public function alt_body($alt_body) - { - $this->alt_body = (string) $alt_body; - - return $this; - } - - /** - * Sets the mail priority - * - * @param string $priority The message priority - * - * @return $this - */ - public function priority($priority) - { - $this->config['priority'] = $priority; - - return $this; - } - - /** - * Sets the html body and optionally a generated alt body. - * - * @param string $html The body html - * @param bool $generate_alt Whether to generate the alt body, will set is html to true - * @param bool $auto_attach Whether to auto attach inline files - * - * @return $this - */ - public function html_body($html, $generate_alt = null, $auto_attach = null) - { - $this->config['is_html'] = true; - - // Check settings - $generate_alt = is_bool($generate_alt) ? $generate_alt : $this->config['generate_alt']; - $auto_attach = is_bool($auto_attach) ? $auto_attach : $this->config['auto_attach']; - $remove_html_comments = ! empty($this->config['remove_html_comments']) ? $this->config['remove_html_comments'] : true; - - // Remove html comments - if ($remove_html_comments) - { - $html = preg_replace('//', '', (string) $html); - } - - if ($auto_attach) - { - // Auto attach all images - preg_match_all("/(src|background)=\"(.*)\"/Ui", $html, $images); - if ( ! empty($images[2])) - { - foreach ($images[2] as $i => $image_url) - { - // Don't attach absolute urls - if ( ! preg_match('/(^http\:\/\/|^https\:\/\/|^\/\/|^cid\:|^data\:|^#)/Ui', $image_url)) - { - $cid = 'cid:'.md5(pathinfo($image_url, PATHINFO_BASENAME)); - if ( ! isset($this->attachments['inline'][$cid])) - { - $this->attach($image_url, true, $cid); - } - $html = preg_replace("/".$images[1][$i]."=\"".preg_quote($image_url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $html); - } - - // Deal with relative protocol URI's if needed - elseif ($scheme = $this->get_config('relative_protocol_replacement', false) and strpos($image_url, '//') === 0) - { - $html = preg_replace("/".$images[1][$i]."=\"".preg_quote($image_url, '/')."\"/Ui", $images[1][$i]."=\"".$scheme.substr($image_url, 2)."\"", $html); - } - } - } - } - - $this->body = $html; - - $generate_alt and $this->alt_body = static::generate_alt($html, $this->config['wordwrap'], $this->config['newline']); - - return $this; - } - - /** - * Gets the message subject - * - * @return string the message subject - */ - public function get_subject() - { - return $this->subject; - } - - /** - * Sets the message subject - * - * @param string $subject The message subject - * - * @return $this - */ - public function subject($subject) - { - if ($this->config['encode_headers']) - { - $subject = $this->encode_mimeheader((string) $subject); - } - $this->subject = (string) $subject; - - return $this; - } - - /** - * Gets from address and name - * - * @return array from address and name - */ - public function get_from() - { - return $this->config['from']; - } - - /** - * Sets the from address and name - * - * @param string $email The from email address - * @param bool|string $name The optional from name - * - * @return $this - */ - public function from($email, $name = false) - { - $this->config['from']['email'] = (string) $email; - $this->config['from']['name'] = (is_string($name)) ? $name : false; - - if ($this->config['encode_headers'] and $this->config['from']['name']) - { - $this->config['from']['name'] = $this->encode_mimeheader((string) $this->config['from']['name']); - } - - return $this; - } - - /** - * Gets to recipients list. - * - * @return array to recipients list - */ - public function get_to() - { - return $this->to; - } - - /** - * Add to the to recipients list. - * - * @param string|array $email Email address or list of email addresses, array(email => name, email) - * @param string|bool $name Recipient name, false, null or empty for no name - * - * @return $this - */ - public function to($email, $name = false) - { - static::add_to_list('to', $email, $name); - - return $this; - } - - /** - * Gets to cc recipients list. - * - * @return array to cc recipients list - */ - public function get_cc() - { - return $this->cc; - } - - /** - * Add to the cc recipients list. - * - * @param string|array $email Email address or list of email addresses, array(email => name, email) - * @param string|bool $name Recipient name, false, null or empty for no name - * - * @return $this - */ - public function cc($email, $name = false) - { - static::add_to_list('cc', $email, $name); - - return $this; - } - - /** - * Gets to bcc recipients list. - * - * @return array to bcc recipients list - */ - public function get_bcc() - { - return $this->bcc; - } - - /** - * Add to the bcc recipients list. - * - * @param string|array $email Email address or list of email addresses, array(email => name, email) - * @param string|bool $name Recipient name, false, null or empty for no name - * - * @return $this - */ - public function bcc($email, $name = false) - { - static::add_to_list('bcc', $email, $name); - - return $this; - } - - /** - * Gets to 'reply to' recipients list. - * - * @return array to 'reply to' recipients list - */ - public function get_reply_to() - { - return $this->reply_to; - } - - /** - * Add to the 'reply to' list. - * - * @param string|array $email Email address or list of email addresses, array(email => name, email) - * @param string|bool $name The name, false, null or empty for no name - * - * @return $this - */ - public function reply_to($email, $name = false) - { - static::add_to_list('reply_to', $email, $name); - - return $this; - } - - /** - * Sets the return-path address - * - * @param string $email The return-path email address - * - * @return $this - */ - public function return_path($email) - { - $this->config['return_path'] = (string) $email; - - return $this; - } - - /** - * Add to a recipients list. - * - * @param string $list List to add to (to, cc, bcc) - * @param string|array $email Email address or list of email addresses, array(email => name, email) - * @param string|bool $name Recipient name, false, null or empty for no name - * - * @return void - */ - protected function add_to_list($list, $email, $name = false) - { - if ( ! is_array($email)) - { - $email = (is_string($name)) ? array($email => $name) : array($email); - } - - foreach ($email as $_email => $name) - { - if (is_numeric($_email)) - { - $_email = $name; - $name = false; - } - - if ($this->config['encode_headers'] and $name) - { - $name = $this->encode_mimeheader($name); - } - - $this->{$list}[$_email] = array( - 'name' => $name, - 'email' => $_email, - ); - } - } - - /** - * Clear the a recipient list. - * - * @param string|array $list List or array of lists - * - * @return void - */ - protected function clear_list($list) - { - is_array($list) or $list = array($list); - - foreach ($list as $_list) - { - $this->{$_list} = array(); - } - } - - /** - * Clear all recipient lists. - * - * @return $this - */ - public function clear_recipients() - { - static::clear_list(array('to', 'cc', 'bcc')); - - return $this; - } - - /** - * Clear all address lists. - * - * @return $this - */ - public function clear_addresses() - { - static::clear_list(array('to', 'cc', 'bcc', 'reply_to')); - - return $this; - } - - /** - * Clear the 'to' recipient list. - * - * @return $this - */ - public function clear_to() - { - static::clear_list('to'); - - return $this; - } - - /** - * Clear the 'cc' recipient list. - * - * @return $this - */ - public function clear_cc() - { - static::clear_list('cc'); - - return $this; - } - - /** - * Clear the 'bcc' recipient list. - * - * @return $this - */ - public function clear_bcc() - { - static::clear_list('bcc'); - - return $this; - } - - /** - * Clear the 'reply to' recipient list. - * - * @return $this - */ - public function clear_reply_to() - { - static::clear_list('reply_to'); - - return $this; - } - - /** - * Sets custom headers. - * - * @param string|array $header Header type or array of headers - * @param string $value Header value - * @return $this - */ - public function header($header, $value = null) - { - if(is_array($header)) - { - foreach($header as $_header => $_value) - { - empty($_value) or $this->extra_headers[$_header] = $_value; - } - } - else - { - empty($value) or $this->extra_headers[$header] = $value; - } - - return $this; - } - - /** - * Attaches a file to the email. This method will search for the file in the attachment paths set (config/email.php) in the attach_paths array - * - * @param string $file The file to attach - * @param bool $inline Whether to include the file inline - * @param string $cid The content identifier. Used when attaching inline images - * @param string $mime The file's mime-type - * @param string $name The attachment's name - * - * @throws \InvalidAttachmentsException Could not read attachment or attachment is empty - * - * @return $this - */ - public function attach($file, $inline = false, $cid = null, $mime = null, $name = null) - { - $file = (array) $file; - - // Ensure the attachment name - if ( ! isset($file[1])) - { - $name or $name = pathinfo($file[0], PATHINFO_BASENAME); - $file[1] = $name; - } - - // Find the attachment. - $file[0] = $this->find_attachment($file[0]); - - if (($contents = file_get_contents($file[0])) === false or empty($contents)) - { - throw new \InvalidAttachmentsException('Could not read attachment or attachment is empty: '.$file[0]); - } - - $disp = ($inline) ? 'inline' : 'attachment'; - - $cid = empty($cid) ? 'cid:'.md5($file[1]) : trim($cid); - $cid = strpos($cid, 'cid:') === 0 ? $cid : 'cid:'.$cid; - - // Fetch the file mime type. - $mime or $mime = static::attachment_mime($file[0]); - - $this->attachments[$disp][$cid] = array( - 'file' => $file, - 'contents' => chunk_split(base64_encode($contents), 76, $this->config['newline']), - 'mime' => $mime, - 'disp' => $disp, - 'cid' => $cid, - ); - - return $this; - } - - /** - * Finds an attachment. - * - * @param $file - * - * @throws \AttachmentNotFoundException Email attachment not found - * - * @return string path of the first found attachment - */ - protected function find_attachment($file) - { - foreach($this->get_config('attach_paths') as $path) - { - if(is_file($path.$file)) - { - return $path.$file; - } - } - - // No file found? - throw new \AttachmentNotFoundException('Email attachment not found: '.$file); - } - - /** - * Attach a file using string input - * - * @param string $contents File contents - * @param string $filename The files name - * @param string $cid The content identifier. Used when attaching inline images - * @param bool $inline Whether it's an inline attachment - * @param string $mime The file's mime-type - * - * @return $this - */ - public function string_attach($contents, $filename, $cid = null, $inline = false, $mime = null) - { - $disp = ($inline) ? 'inline' : 'attachment'; - $cid = empty($cid) ? 'cid:'.md5($filename) : trim($cid); - $cid = strpos($cid, 'cid:') === 0 ? $cid : 'cid:'.$cid; - $mime or $mime = static::attachment_mime($filename); - - $this->attachments[$disp][$cid] = array( - 'file' => array(0 => $filename, 1 => pathinfo($filename, PATHINFO_BASENAME)), - 'contents' => static::encode_string($contents, 'base64', $this->config['newline']), - 'mime' => $mime, - 'disp' => $disp, - 'cid' => $cid, - ); - - return $this; - } - - /** - * Clear the attachments list. - * - * @return $this - */ - public function clear_attachments() - { - $this->attachments = array( - 'inline' => array(), - 'attachment' => array(), - ); - - return $this; - } - - /** - * Get the mimetype for an attachment - * - * @param string $file The path to the attachment - * - * @return $this - */ - protected static function attachment_mime($file) - { - static $mimes = false; - - if ( ! $mimes) - { - $mimes = \Config::load('mimes'); - } - - $ext = pathinfo($file, PATHINFO_EXTENSION); - - $mime = \Arr::get($mimes, $ext, 'application/octet-stream'); - is_array($mime) and $mime = reset($mime); - - return $mime; - } - - /** - * Validates all the email addresses. - * - * @return bool|array True if all are valid or an array of recipients which failed validation. - */ - protected function validate_addresses() - { - $failed = array(); - - foreach (array('to', 'cc', 'bcc') as $list) - { - foreach ($this->{$list} as $recipient) - { - if ( ! filter_var($recipient['email'], FILTER_VALIDATE_EMAIL)) - { - $failed[$list][] = $recipient; - } - } - } - - if (count($failed) === 0) - { - return true; - } - - return $failed; - } - - /** - * Sets unique message boundaries - */ - protected function set_boundaries() - { - $uniq_id = md5(uniqid(microtime(true))); - - // Message part boundary, (separates message and attachments). - $this->boundaries[0] = 'B1_'.$uniq_id; - - // Message body boundary (separates message, alt message) - $this->boundaries[1] = 'B2_'.$uniq_id; - - $this->boundaries[2] = 'B3_'.$uniq_id; - } - - /** - * Initiates the sending process. - * - * @param bool Whether to validate the addresses, falls back to config setting - * - * @throws \EmailValidationFailedException One or more email addresses did not pass validation - * @throws \FuelException Cannot send without from address/Cannot send without recipients - * - * @return bool - */ - public function send($validate = null) - { - if (empty($this->to) and empty($this->cc) and empty($this->bcc)) - { - throw new \FuelException('Cannot send email without recipients.'); - } - - if (($from = $this->config['from']['email']) === false or empty($from)) - { - throw new \FuelException('Cannot send without from address.'); - } - - // Check which validation bool to use - is_bool($validate) or $validate = $this->config['validate']; - - // Validate the email addresses if specified - if ($validate and ($failed = $this->validate_addresses()) !== true) - { - $this->invalid_addresses = $failed; - - $error_str = ''; - foreach($failed as $_list => $_contents) - { - $error_str .= $_list.': '.htmlentities(static::format_addresses($_contents)).'.'.PHP_EOL; - } - - throw new \EmailValidationFailedException('One or more email addresses did not pass validation: '.$error_str); - } - - // Reset the headers - $this->headers = array(); - - // Set the email boundaries - $this->set_boundaries(); - - // Set RFC 822 formatted date - $this->set_header('Date', date('r')); - - // Set return path - if ($this->config['return_path'] !== false) - { - $this->set_header('Return-Path', $this->config['return_path']); - } - else - { - $this->set_header('Return-Path', $this->config['from']['email']); - } - - if (($this instanceof Email_Driver_Mail) !== true) - { - if ( ! empty($this->to)) - { - // Set from - $this->set_header('To', static::format_addresses($this->to)); - } - - // Set subject - $this->set_header('Subject', $this->subject); - } - - $this->set_header('From', static::format_addresses(array($this->config['from']))); - - foreach (array('cc' => 'Cc', 'bcc' => 'Bcc', 'reply_to' => 'Reply-To') as $list => $header) - { - if (count($this->{$list}) > 0) - { - $this->set_header($header, static::format_addresses($this->{$list})); - } - } - - // Set message id - $this->set_header('Message-ID', $this->get_message_id()); - - // Set mime version - $this->set_header('MIME-Version', '1.0'); - - // Set priority - $this->set_header('X-Priority', $this->config['priority']); - - // Set mailer useragent - $this->set_header('X-Mailer', $this->config['useragent']); - - $newline = $this->config['newline']; - - $this->type = $this->get_mail_type(); - - $encoding = $this->config['encoding']; - $charset = $this->config['charset']; - - if ($this->type !== 'plain' and $this->type !== 'html') - { - $this->set_header('Content-Type', $this->get_content_type($this->type, $newline."\tboundary=\"".$this->boundaries[0].'"')); - } - else - { - $this->set_header('Content-Transfer-Encoding', $encoding); - $this->set_header('Content-Type', 'text/'.$this->type.'; charset="'.$this->config['charset'].'"'); - } - - // Encode messages - $this->body = static::encode_string($this->body, $encoding, $newline); - $this->alt_body = static::encode_string($this->alt_body, $encoding, $newline); - - // Set wordwrapping - $wrapping = $this->config['wordwrap']; - $qp_mode = $encoding === 'quoted-printable'; - - $is_html = (stripos($this->type, 'html') !== false); - - // Don't wrap the text when using quoted-printable - if ($wrapping and ! $qp_mode) - { - $this->body = static::wrap_text($this->body, $wrapping, $newline, $is_html); - $this->alt_body = static::wrap_text($this->alt_body, $wrapping, $newline, false); - } - - // Send - $this->_send(); - - return true; - } - - /** - * Get the invalid addresses - * - * @return array An array of invalid email addresses - */ - public function get_invalid_addresses() - { - return $this->invalid_addresses; - } - - /** - * Sets the message headers - * - * @param string $header The header type - * @param string $value The header value - */ - protected function set_header($header, $value) - { - empty($value) or $this->headers[$header] = $value; - } - - /** - * Gets the header - * - * @param string $header The header name. Will return all headers, if not specified - * @param bool $formatted Adds newline as suffix and colon as prefix, if true - * - * @return string|array Mail header or array of headers - */ - protected function get_header($header = null, $formatted = true) - { - if ($header === null) - { - return $this->headers; - } - - if (array_key_exists($header, $this->headers)) - { - $prefix = ($formatted) ? $header.': ' : ''; - $suffix = ($formatted) ? $this->config['newline'] : ''; - return $prefix.$this->headers[$header].$suffix; - } - - return ''; - } - - /** - * Encodes a mimeheader. - * - * @param string $header Header to encode - * - * @return string Mimeheader encoded string - */ - protected function encode_mimeheader($header) - { - // we need mbstring for this - if ( ! MBSTRING) - { - throw new \RuntimeException('Email requires the multibyte ("mbstring") package to be installed!'); - } - - // determine the transfer encoding to be used - $transfer_encoding = ($this->config['encoding'] === 'quoted-printable') ? 'Q' : 'B' ; - - // encode - $header = mb_encode_mimeheader($header, $this->config['charset'], $transfer_encoding, $this->config['newline']); - - // and return it - return $header; - } - - /** - * Get the attachment headers - * - */ - protected function get_attachment_headers($type, $boundary) - { - $return = ''; - - $newline = $this->config['newline']; - - foreach ($this->attachments[$type] as $attachment) - { - $return .= '--'.$boundary.$newline; - $return .= 'Content-Type: '.$attachment['mime'].'; name="'.$attachment['file'][1].'"'.$newline; - $return .= 'Content-Transfer-Encoding: base64'.$newline; - $type === 'inline' and $return .= 'Content-ID: <'.substr($attachment['cid'], 4).'>'.$newline; - $return .= 'Content-Disposition: '.$type.'; filename="'.$attachment['file'][1].'"'.$newline.$newline; - $return .= $attachment['contents'].$newline.$newline; - } - - return $return; - } - - /** - * Get a unique message id - * - * @return string The message id - */ - protected function get_message_id() - { - $from = $this->config['from']['email']; - return "<".uniqid('').strstr($from, '@').">"; - } - - /** - * Returns the mail's type - * - * @return string Mail type - */ - protected function get_mail_type() - { - $return = $this->config['is_html'] ? 'html' : 'plain' ; - $alt = trim($this->alt_body); - $return .= ($this->config['is_html'] and ! empty($alt)) ? '_alt' : ''; - $return .= ($this->config['is_html'] and count($this->attachments['inline'])) ? '_inline' : ''; - $return .= (count($this->attachments['attachment'])) ? '_attach' : ''; - return $return; - } - - /** - * Returns the content type - * - * @param string $mail_type Type of email (plain, html, html_inline, etc…) - * @param $boundary - * - * @throws \FuelException Invalid content-type - * - * @return string Mail content type - */ - protected function get_content_type($mail_type, $boundary) - { - $related = $this->config['force_mixed'] ? 'multipart/mixed; ' : 'multipart/related; '; - - switch ($mail_type) - { - case 'plain': - return 'text/plain'; - case 'plain_attach': - case 'html_attach': - return $related.$boundary; - case 'html': - return 'text/html'; - case 'html_alt_attach': - case 'html_alt_inline_attach': - return 'multipart/mixed; '.$boundary; - case 'html_alt_inline': - case 'html_alt': - case 'html_inline': - return 'multipart/alternative; '.$boundary; - default: - throw new \FuelException('Invalid content-type'.$mail_type); - } - } - - /** - * Builds the headers and body - * - * @param bool $no_bcc Whether to exclude Bcc headers. - * - * @return array An array containing the headers and the body - */ - protected function build_message($no_bcc = false) - { - $newline = $this->config['newline']; - $charset = $this->config['charset']; - $encoding = $this->config['encoding']; - - $headers = ''; - $parts = array('Date', 'Return-Path', 'From', 'To', 'Cc', 'Bcc', 'Reply-To', 'Subject', 'Message-ID', 'X-Priority', 'X-Mailer', 'MIME-Version', 'Content-Type'); - $no_bcc and array_splice($parts, 5, 1); - - foreach ($parts as $part) - { - $headers .= $this->get_header($part); - } - - foreach ($this->extra_headers as $header => $value) - { - $headers .= $header.': '.$value.$newline; - } - - $headers .= $newline; - - $body = ''; - - if ($this->type === 'plain' or $this->type === 'html') - { - $body = $this->body; - } - else - { - switch ($this->type) - { - case 'html_alt': - $body .= '--'.$this->boundaries[0].$newline; - $body .= 'Content-Type: text/plain; charset="'.$charset.'"'.$newline; - $body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline; - $body .= $this->alt_body.$newline.$newline; - $body .= '--'.$this->boundaries[0].$newline; - $body .= 'Content-Type: text/html; charset="'.$charset.'"'.$newline; - $body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline; - $body .= $this->body.$newline.$newline; - $body .= '--'.$this->boundaries[0].'--'; - break; - case 'plain_attach': - case 'html_attach': - case 'html_inline': - $body .= '--'.$this->boundaries[0].$newline; - $text_type = (stripos($this->type, 'html') !== false) ? 'html' : 'plain'; - $body .= 'Content-Type: text/'.$text_type.'; charset="'.$charset.'"'.$newline; - $body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline; - $body .= $this->body.$newline.$newline; - $attach_type = (stripos($this->type, 'attach') !== false) ? 'attachment' : 'inline'; - $body .= $this->get_attachment_headers($attach_type, $this->boundaries[0]); - $body .= '--'.$this->boundaries[0].'--'; - break; - case 'html_alt_inline': - $body .= '--'.$this->boundaries[0].$newline; - $body .= 'Content-Type: text/plain'.'; charset="'.$charset.'"'.$newline; - $body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline; - $body .= $this->alt_body.$newline.$newline; - $body .= '--'.$this->boundaries[0].$newline; - $body .= 'Content-Type: multipart/related;'.$newline."\tboundary=\"{$this->boundaries[1]}\"".$newline.$newline; - $body .= '--'.$this->boundaries[1].$newline; - $body .= 'Content-Type: text/html; charset="'.$charset.'"'.$newline; - $body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline; - $body .= $this->body.$newline.$newline; - $body .= $this->get_attachment_headers('inline', $this->boundaries[1]); - $body .= '--'.$this->boundaries[1].'--'.$newline.$newline; - $body .= '--'.$this->boundaries[0].'--'; - break; - case 'html_alt_attach': - case 'html_inline_attach': - $body .= '--'.$this->boundaries[0].$newline; - $body .= 'Content-Type: multipart/alternative;'.$newline."\t boundary=\"{$this->boundaries[1]}\"".$newline.$newline; - if (stripos($this->type, 'alt') !== false) - { - $body .= '--'.$this->boundaries[1].$newline; - $body .= 'Content-Type: text/plain; charset="'.$charset.'"'.$newline; - $body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline; - $body .= $this->alt_body.$newline.$newline; - } - $body .= '--'.$this->boundaries[1].$newline; - $body .= 'Content-Type: text/html; charset="'.$charset.'"'.$newline; - $body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline; - $body .= $this->body.$newline.$newline; - if (stripos($this->type, 'inline') !== false) - { - $body .= $this->get_attachment_headers('inline', $this->boundaries[1]); - $body .= $this->alt_body.$newline.$newline; - } - $body .= '--'.$this->boundaries[1].'--'.$newline.$newline; - $body .= $this->get_attachment_headers('attachment', $this->boundaries[0]); - $body .= '--'.$this->boundaries[0].'--'; - break; - case 'html_alt_inline_attach': - $body .= '--'.$this->boundaries[0].$newline; - $body .= 'Content-Type: multipart/alternative;'.$newline."\t boundary=\"{$this->boundaries[1]}\"".$newline.$newline; - $body .= '--'.$this->boundaries[1].$newline; - $body .= 'Content-Type: text/plain; charset="'.$charset.'"'.$newline; - $body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline; - $body .= $this->alt_body.$newline.$newline; - $body .= '--'.$this->boundaries[1].$newline; - $body .= 'Content-Type: multipart/related;'.$newline."\t boundary=\"{$this->boundaries[2]}\"".$newline.$newline; - $body .= '--'.$this->boundaries[2].$newline; - $body .= 'Content-Type: text/html; charset="'.$charset.'"'.$newline; - $body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline; - $body .= $this->body.$newline.$newline; - $body .= $this->get_attachment_headers('inline', $this->boundaries[2]); - $body .= $this->alt_body.$newline.$newline; - $body .= '--'.$this->boundaries[2].'--'.$newline.$newline; - $body .= '--'.$this->boundaries[1].'--'.$newline.$newline; - $body .= $this->get_attachment_headers('attachment', $this->boundaries[0]); - $body .= '--'.$this->boundaries[0].'--'; - break; - } - - } - - return array( - 'header' => $headers, - 'body' => $body, - ); - } - - /** - * Wraps the body or alt text - * - * @param string $message The text to wrap - * @param int $length The max line length - * @param string $newline The newline delimiter - * @param bool $is_html - * - * @internal param string $charset the text charset - * @internal param bool $qp_mode whether the text is quoted printable encoded - * - * @return string - */ - protected static function wrap_text($message, $length, $newline, $is_html = true) - { - $length = ($length > 76) ? 76 : $length; - $is_html and $message = preg_replace('/[\r\n\t ]+/m', ' ', $message); - $message = wordwrap($message, $length, $newline, false); - - return $message; - } - - /** - * Standardize newlines. - * - * @param string $string String to prep - * @param string $newline The newline delimiter - * - * @return string String with standardized newlines - */ - protected static function prep_newlines($string, $newline = null) - { - $newline or $newline = \Config::get('email.defaults.newline', "\n"); - - $replace = array( - "\r\n" => "\n", - "\n\r" => "\n", - "\r" => "\n", - "\n" => $newline, - ); - - foreach ($replace as $from => $to) - { - $string = str_replace($from, $to, $string); - } - - return $string; - } - - /** - * Encodes a string in the given encoding. - * - * @param string $string String to encode - * @param string $encoding The charset - * @param string $newline Newline delimeter - * - * @throws \InvalidEmailStringEncoding Encoding is not a supported by encoding method - * - * @return string Encoded string - */ - protected static function encode_string($string, $encoding, $newline = null) - { - $newline or $newline = \Config::get('email.defaults.newline', "\n"); - - switch ($encoding) - { - case 'quoted-printable': - return quoted_printable_encode($string); - case '7bit': - case '8bit': - return static::prep_newlines(rtrim($string, $newline), $newline); - case 'base64': - return chunk_split(base64_encode($string), 76, $newline); - default: - throw new \InvalidEmailStringEncoding($encoding.' is not a supported encoding method.'); - } - } - - /** - * Returns a formatted string of email addresses. - * - * @param array $addresses Array of adresses array(array(name=>name, email=>email)); - * - * @return string Correctly formatted email addresses - */ - protected static function format_addresses($addresses) - { - $return = array(); - - foreach ($addresses as $recipient) - { - $recipient['name'] and $recipient['email'] = '"'.$recipient['name'].'" <'.$recipient['email'].'>'; - $return[] = $recipient['email']; - } - - return join(', ', $return); - } - - /** - * Generates an alt body - * - * @param string $html html Body to al body generate from - * @param int $wordwrap Wordwrap length - * @param string $newline Line separator to use - * - * @return string The generated alt body - */ - protected static function generate_alt($html, $wordwrap, $newline) - { - $html = preg_replace('/[ | ]{2,}/m', ' ', $html); - $html = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s', '', $html))); - $lines = explode($newline, $html); - $result = array(); - $first_newline = true; - foreach ($lines as $line) - { - $line = trim($line); - if ( ! empty($line) or $first_newline) - { - $first_newline = false; - $result[] = $line; - } - else - { - $first_newline = true; - } - } - - $html = join($newline, $result); - - if ( ! $wordwrap) - { - return $html; - } - - return wordwrap($html, $wordwrap, $newline, true); - } - - /** - * Initiates the sending process. - * - * @return bool success boolean - */ - abstract protected function _send(); - -} diff --git a/fuel/packages/email/classes/email/driver/mail.php b/fuel/packages/email/classes/email/driver/mail.php deleted file mode 100755 index 24e7065..0000000 --- a/fuel/packages/email/classes/email/driver/mail.php +++ /dev/null @@ -1,35 +0,0 @@ -build_message(); - $return_path = ($this->config['return_path'] !== false) ? $this->config['return_path'] : $this->config['from']['email']; - if ( ! @mail(static::format_addresses($this->to), $this->subject, $message['body'], $message['header'], '-oi -f '.$return_path)) - { - throw new \EmailSendingFailedException('Failed sending email'); - } - return true; - } - -} diff --git a/fuel/packages/email/classes/email/driver/mailgun.php b/fuel/packages/email/classes/email/driver/mailgun.php deleted file mode 100755 index 5826f7c..0000000 --- a/fuel/packages/email/classes/email/driver/mailgun.php +++ /dev/null @@ -1,74 +0,0 @@ -type = 'html'; - - $message = $this->build_message(); - - $mg = new \Mailgun\Mailgun($this->config['mailgun']['key']); - - // Mailgun does not consider these "arbitrary headers" - $exclude = array('From'=>'From', 'To'=>'To', 'Cc'=>'Cc', 'Bcc'=>'Bcc', 'Subject'=>'Subject', 'Content-Type'=>'Content-Type', 'Content-Transfer-Encoding' => 'Content-Transfer-Encoding'); - $headers = array_diff_key($this->headers, $exclude); - - foreach ($this->extra_headers as $header => $value) - { - $headers[$header] = $value; - } - - // Standard required fields - $post_data = array( - 'from' => static::format_addresses(array(array('email' => $this->config['from']['email'], 'name' => $this->config['from']['name']))), - 'to' => static::format_addresses($this->to), - 'subject' => $this->subject, - 'html' => $message['body'], - ); - - // Optionally cc, bcc and alt_body - $this->cc and $post_data['cc'] = static::format_addresses($this->cc); - $this->bcc and $post_data['bcc'] = static::format_addresses($this->bcc); - $this->alt_body and $post_data['text'] = $this->alt_body; - - // Mailgun's "arbitrary headers" are h: prefixed - foreach ($headers as $name => $value) - { - $post_data["h:{$name}"] = $value; - } - - // Add the attachments - $post_body = array( - 'attachment' => array(), - 'inline' => array(), - ); - - foreach ($this->attachments['attachment'] as $cid => $file) - { - $post_body['attachment'][] = array('filePath' => $file['file'][0], 'remoteName' => $file['file'][1]); - } - - foreach ($this->attachments['inline'] as $cid => $file) - { - $post_body['inline'][] = array('filePath' => $file['file'][0], 'remoteName' => substr($cid, 4)); - } - - // And send the message out - $mg->sendMessage($this->config['mailgun']['domain'], $post_data, $post_body); - - return true; - } -} diff --git a/fuel/packages/email/classes/email/driver/mandrill.php b/fuel/packages/email/classes/email/driver/mandrill.php deleted file mode 100755 index f971612..0000000 --- a/fuel/packages/email/classes/email/driver/mandrill.php +++ /dev/null @@ -1,350 +0,0 @@ -config['mandrill']['key']); - - $message = new Mandrill_Messages($mandrill); - - $headers = $this->extra_headers; - - // Get recipients - $to = $this->build_rcpt(); - $cc = $this->build_rcpt('cc'); - $bcc = $this->build_rcpt('bcc'); - - $to = array_merge($bcc, $cc, $to); - - // Get recipient merge vars - $merge_vars = array(); - - foreach ($this->rcpt_merge_vars as $rcpt => $_merge_vars) - { - $merge_vars[] = array( - 'rcpt' => $rcpt, - 'vars' => \Arr::keyval_to_assoc($_merge_vars, 'name', 'content'), - ); - } - - // Get recipient meta data - $metadata = array(); - - foreach ($this->rcpt_metadata as $rcpt => $_metadata) - { - $metadata[] = array( - 'rcpt' => $rcpt, - 'values' => $_metadata, - ); - } - - // Get attachments - $attachments = array(); - - foreach ($this->attachments['attachment'] as $cid => $attachment) - { - $attachments[] = array( - 'type' => $attachment['mime'], - 'name' => $attachment['file'][1], - 'content' => $attachment['contents'], - ); - } - - // Get inline images - $images = array(); - - foreach ($this->attachments['inline'] as $cid => $attachment) - { - if (\Str::starts_with($attachment['mime'], 'image/')) - { - $name = substr($cid, 4); // remove cid: - - $images[] = array( - 'type' => $attachment['mime'], - 'name' => $name, - 'content' => $attachment['contents'], - ); - } - } - - // Get reply-to addresses - if ( ! empty($this->reply_to)) - { - $headers['Reply-To'] = static::format_addresses($this->reply_to); - } - - $important = false; - - if (in_array($this->config['priority'], array(\Email::P_HIGH, \Email::P_HIGHEST))) - { - $important = true; - } - - $message_data = array( - 'html' => $this->body, - 'text' => isset($this->alt_body) ? $this->alt_body : '', - 'subject' => $this->subject, - 'from_email' => $this->config['from']['email'], - 'from_name' => $this->config['from']['name'], - 'to' => $to, - 'headers' => $headers, - 'global_merge_vars' => \Arr::keyval_to_assoc($this->merge_vars, 'name', 'content'), - 'merge_vars' => $merge_vars, - 'metadata' => $this->metadata, - 'recipient_metadata' => $metadata, - 'attachments' => $attachments, - 'images' => $images, - 'important' => $important, - ); - - $message_options = \Arr::filter_keys($this->get_config('mandrill.message_options', array()), array_keys($message_data), true); - - $message_data = \Arr::merge($message_data, $message_options); - - $send_options = extract($this->config['mandrill']['send_options'], EXTR_SKIP); - - $message->send($message_data, $async, $ip_pool, $send_at); - - return true; - } - - /** - * {@inheritdoc} - */ - public function attach($file, $inline = false, $cid = null, $mime = null, $name = null) - { - parent::attach($file, $inline, $cid, $mime, $name); - - if ($inline === true) - { - // Check the last attachment - $attachment = end($this->attachments['inline']); - - if ( ! \Str::starts_with($attachment['mime'], 'image/')) - { - throw new \InvalidAttachmentsException('Non-image inline attachments are not supported by this driver.'); - } - } - } - - /** - * Add type to recipient list - * - * @param string $list to, cc, bcc - * @return array - */ - protected function build_rcpt($list = 'to') - { - return array_map(function ($item) use ($list) - { - $item['type'] = $list; - - return $item; - }, $this->{$list}); - } - - /** - * {@inheritdoc} - */ - protected function clear_list($list) - { - is_array($list) or $list = array($list); - - foreach ($list as $_list) - { - $rcpt = array_keys($this->{$_list}); - \Arr::delete($this->rcpt_merge_vars, $rcpt); - \Arr::delete($this->rcpt_metadata, $rcpt); - } - - return parent::clear_list($list); - } - - /** - * Get merge vars - * - * @param mixed $key Null for all, string for specific - * @param mixed $rcpt Null for global, string for recipient - * @return array - */ - public function get_merge_vars($key = null, $rcpt = null) - { - if (is_null($rcpt)) - { - return \Arr::get($this->merge_vars, $key); - } - elseif (isset($this->rcpt_merge_vars[$rcpt])) - { - return \Arr::get($this->rcpt_merge_vars[$rcpt], $key); - } - } - - /** - * Add merge vars - * - * @param array $merge_vars Key-value pairs - * @param mixed $rcpt Null for global, string for recipient - * @return array - */ - public function add_merge_vars(array $merge_vars, $rcpt = null) - { - if (is_null($rcpt)) - { - $this->merge_vars = $merge_vars; - } - else - { - $this->rcpt_merge_vars[$rcpt] = $merge_vars; - } - - return $this; - } - - /** - * Set one or several merge vars - * - * @param mixed $key Array for many vars, string for one - * @param mixed $value In case of many vars it is ommited - * @param mixed $rcpt Null for global, string for recipient - * @return object $this - */ - public function set_merge_var($key, $value = null, $rcpt = null) - { - is_array($key) or $key = array($key => $value); - - if (is_null($rcpt)) - { - $this->merge_vars = \Arr::merge($this->merge_vars, $key); - } - else - { - $merge_vars = \Arr::get($this->rcpt_merge_vars, $rcpt, array()); - $this->rcpt_merge_vars[$rcpt] = \Arr::merge($merge_vars, $key); - } - - return $this; - } - - /** - * Get metadata - * - * @param mixed $key Null for all, string for specific - * @param mixed $rcpt Null for global, string for recipient - * @return array - */ - public function get_metadata($key = null, $rcpt = null) - { - if (is_null($rcpt)) - { - return \Arr::get($this->metadata, $key); - } - elseif (isset($this->rcpt_metadata[$rcpt])) - { - return \Arr::get($this->rcpt_metadata[$rcpt], $key); - } - } - - /** - * Add metadata - * - * @param array $metadata Key-value pairs - * @param mixed $rcpt Null for global, string for recipient - * @return array - */ - public function add_metadata(array $metadata, $rcpt = null) - { - if (is_null($rcpt)) - { - $this->metadata = $metadata; - } - else - { - $this->rcpt_metadata[$rcpt] = $metadata; - } - - return $this; - } - - /** - * Set one or several metadata - * - * @param mixed $key Array for many, string for one - * @param mixed $value In case of many it is ommited - * @param mixed $rcpt Null for global, string for recipient - * @return object $this - */ - public function set_metadata($key, $value = null, $rcpt = null) - { - is_array($key) or $key = array($key => $value); - - if (is_null($rcpt)) - { - $this->metadata = \Arr::merge($this->metadata, $key); - } - else - { - $metadata = \Arr::get($this->rcpt_metadata, $rcpt, array()); - $this->rcpt_metadata[$rcpt] = \Arr::merge($metadata, $key); - } - - return $this; - } -} diff --git a/fuel/packages/email/classes/email/driver/noop.php b/fuel/packages/email/classes/email/driver/noop.php deleted file mode 100755 index 0900022..0000000 --- a/fuel/packages/email/classes/email/driver/noop.php +++ /dev/null @@ -1,34 +0,0 @@ -build_message(); - - logger(\Fuel::L_INFO, 'To: '.static::format_addresses($this->to), 'Email NoOp driver'); - logger(\Fuel::L_INFO, 'Subject: '.$this->subject, 'Email NoOp driver'); - logger(\Fuel::L_INFO, 'Header: '.$message['header'], 'Email NoOp driver'); - logger(\Fuel::L_INFO, 'Body: '.$message['body'], 'Email NoOp driver'); - - return true; - } - -} diff --git a/fuel/packages/email/classes/email/driver/sendmail.php b/fuel/packages/email/classes/email/driver/sendmail.php deleted file mode 100755 index 2c9749a..0000000 --- a/fuel/packages/email/classes/email/driver/sendmail.php +++ /dev/null @@ -1,58 +0,0 @@ -build_message(); - - // Open a connection - $return_path = ($this->config['return_path'] !== false) ? $this->config['return_path'] : $this->config['from']['email']; - $handle = @popen($this->config['sendmail_path'] . " -oi -f ".$return_path." -t", 'w'); - - // No connection? - if(! is_resource($handle)) - { - throw new \SendmailConnectionException('Could not open a sendmail connection at: '.$this->config['sendmail_path']); - } - - // Send the headers - fputs($handle, $message['header']); - - // Send the body - fputs($handle, $message['body']); - - if(pclose($handle) === -1) - { - throw new \SendmailFailedException('Failed sending email through sendmail.'); - } - - return true; - } - -} diff --git a/fuel/packages/email/classes/email/driver/smtp.php b/fuel/packages/email/classes/email/driver/smtp.php deleted file mode 100755 index 2bc74d1..0000000 --- a/fuel/packages/email/classes/email/driver/smtp.php +++ /dev/null @@ -1,342 +0,0 @@ -smtp_connection) - { - $this->smtp_disconnect(); - } - } - - /** - * The SMTP connection - */ - protected $smtp_connection = null; - - /** - * Initiates the sending process. - * - * @return bool success boolean - */ - protected function _send() - { - // send the email - try - { - return $this->_send_email(); - } - - // something failed - catch (\Exception $e) - { - // disconnect if needed - if ($this->smtp_connection) - { - if ($e instanceOf SmtpTimeoutException) - { - // simply close the connection - fclose($this->smtp_connection); - $this->smtp_connection = null; - } - else - { - // proper close, with a QUIT - $this->smtp_disconnect(); - } - } - - // rethrow the exception - throw $e; - } - } - - /** - * Sends the actual email - * - * @return bool success boolean - */ - protected function _send_email() - { - $message = $this->build_message(true); - - if(empty($this->config['smtp']['host']) or empty($this->config['smtp']['port'])) - { - throw new \FuelException('Must supply a SMTP host and port, none given.'); - } - - // Use authentication? - $authenticate = (empty($this->smtp_connection) and ! empty($this->config['smtp']['username']) and ! empty($this->config['smtp']['password'])); - - // Connect - $this->smtp_connect(); - - // Authenticate when needed - $authenticate and $this->smtp_authenticate(); - - // Set return path - $return_path = empty($this->config['return_path']) ? $this->config['from']['email'] : $this->config['return_path']; - $this->smtp_send('MAIL FROM:<' . $return_path .'>', 250); - - foreach(array('to', 'cc', 'bcc') as $list) - { - foreach($this->{$list} as $recipient) - { - $this->smtp_send('RCPT TO:<'.$recipient['email'].'>', array(250, 251)); - } - } - - // Prepare for data sending - $this->smtp_send('DATA', 354); - - $lines = explode($this->config['newline'], $message['header'].preg_replace('/^\./m', '..$1', $message['body'])); - - foreach($lines as $line) - { - if(substr($line, 0, 1) === '.') - { - $line = '.'.$line; - } - - fputs($this->smtp_connection, $line.$this->config['newline']); - } - - // Finish the message - $this->smtp_send('.', 250); - - // Close the connection if we're not using pipelining - $this->pipelining or $this->smtp_disconnect(); - - return true; - } - - /** - * Connects to the given smtp and says hello to the other server. - */ - protected function smtp_connect() - { - // re-use the existing connection - if ( ! empty($this->smtp_connection)) - { - return; - } - - // add a transport if not given - if (strpos($this->config['smtp']['host'], '://') === false) - { - $this->config['smtp']['host'] = 'tcp://'.$this->config['smtp']['host']; - } - - $this->smtp_connection = stream_socket_client( - $this->config['smtp']['host'].':'.$this->config['smtp']['port'], - $error_number, - $error_string, - $this->config['smtp']['timeout'] - ); - - if(empty($this->smtp_connection)) - { - throw new SmtpConnectionException('Could not connect to SMTP: ('.$error_number.') '.$error_string); - } - - // Clear the smtp response - $this->smtp_get_response(); - - // Just say hello! - try - { - $this->smtp_send('EHLO'.' '.\Input::server('SERVER_NAME', 'localhost.local'), 250); - } - catch(SmtpCommandFailureException $e) - { - // Didn't work? Try HELO - $this->smtp_send('HELO'.' '.\Input::server('SERVER_NAME', 'localhost.local'), 250); - } - - // Enable TLS encryption if needed, and we're connecting using TCP - if (\Arr::get($this->config, 'smtp.starttls', false) and strpos($this->config['smtp']['host'], 'tcp://') === 0) - { - try - { - $this->smtp_send('STARTTLS', 220); - if ( ! stream_socket_enable_crypto($this->smtp_connection, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) - { - throw new SmtpConnectionException('STARTTLS failed, Crypto client can not be enabled.'); - } - } - catch(SmtpCommandFailureException $e) - { - throw new SmtpConnectionException('STARTTLS failed, invalid return code received from server.'); - } - - // Say hello again, the service list might be updated (see RFC 3207 section 4.2) - try - { - $this->smtp_send('EHLO'.' '.\Input::server('SERVER_NAME', 'localhost.local'), 250); - } - catch(SmtpCommandFailureException $e) - { - // Didn't work? Try HELO - $this->smtp_send('HELO'.' '.\Input::server('SERVER_NAME', 'localhost.local'), 250); - } - } - - try - { - $this->smtp_send('HELP', 214); - } - catch(SmtpCommandFailureException $e) - { - // Let this pass as some servers don't support this. - } - } - - /** - * Close SMTP connection - */ - protected function smtp_disconnect() - { - $this->smtp_send('QUIT', false); - fclose($this->smtp_connection); - $this->smtp_connection = null; - } - - /** - * Performs authentication with the SMTP host - */ - protected function smtp_authenticate() - { - // Encode login data - $username = base64_encode($this->config['smtp']['username']); - $password = base64_encode($this->config['smtp']['password']); - - try - { - // Prepare login - $this->smtp_send('AUTH LOGIN', 334); - - // Send username - $this->smtp_send($username, 334); - - // Send password - $this->smtp_send($password, 235); - - } - catch(SmtpCommandFailureException $e) - { - throw new SmtpAuthenticationFailedException('Failed authentication.'); - } - - } - - /** - * Sends data to the SMTP host - * - * @param string $data The SMTP command - * @param string|bool|string $expecting The expected response - * @param bool $return_number Set to true to return the status number - * - * @throws \SmtpCommandFailureException When the command failed an expecting is not set to false. - * @throws \SmtpTimeoutException SMTP connection timed out - * - * @return mixed Result or result number, false when expecting is false - */ - protected function smtp_send($data, $expecting, $return_number = false) - { - ! is_array($expecting) and $expecting !== false and $expecting = array($expecting); - - stream_set_timeout($this->smtp_connection, $this->config['smtp']['timeout']); - if ( ! fputs($this->smtp_connection, $data . $this->config['newline'])) - { - if($expecting === false) - { - return false; - } - throw new SmtpCommandFailureException('Failed executing command: '. $data); - } - - $info = stream_get_meta_data($this->smtp_connection); - if($info['timed_out']) - { - throw new SmtpTimeoutException('SMTP connection timed out.'); - } - - // Get the reponse - $response = $this->smtp_get_response(); - - // Get the reponse number - $number = (int) substr(trim($response), 0, 3); - - // Check against expected result - if($expecting !== false and ! in_array($number, $expecting)) - { - throw new SmtpCommandFailureException('Got an unexpected response from host on command: ['.$data.'] expecting: '.join(' or ', $expecting).' received: '.$response); - } - - if($return_number) - { - return $number; - } - - return $response; - } - - /** - * Get SMTP response - * - * @throws \SmtpTimeoutException - * - * @return string SMTP response - */ - protected function smtp_get_response() - { - $data = ''; - - // set the timeout. - stream_set_timeout($this->smtp_connection, $this->config['smtp']['timeout']); - - while($str = fgets($this->smtp_connection, 512)) - { - $info = stream_get_meta_data($this->smtp_connection); - if($info['timed_out']) - { - throw new SmtpTimeoutException('SMTP connection timed out.'); - } - - $data .= $str; - - if (substr($str, 3, 1) === ' ') - { - break; - } - } - - return $data; - } - -} diff --git a/fuel/packages/email/composer.json b/fuel/packages/email/composer.json deleted file mode 100755 index 4fa3372..0000000 --- a/fuel/packages/email/composer.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "fuel/email", - "description" : "FuelPHP 1.x Email Package", - "type": "fuel-package", - "homepage": "https://github.com/fuel/email", - "license": "MIT", - "authors": [ - { - "name": "FuelPHP Development Team", - "email": "team@fuelphp.com" - } - ], - "require": { - "composer/installers": "~1.0" - } -} diff --git a/fuel/packages/email/config/email.php b/fuel/packages/email/config/email.php deleted file mode 100755 index 4f8b885..0000000 --- a/fuel/packages/email/config/email.php +++ /dev/null @@ -1,179 +0,0 @@ - 'default', - - /** - * Default setup groups - */ - 'setups' => array( - 'default' => array(), - ), - - /** - * Default settings - */ - 'defaults' => array( - - /** - * Mail useragent string - */ - 'useragent' => 'FuelPHP, PHP 5.3 Framework', - - /** - * Mail driver (mail, smtp, sendmail, noop) - */ - 'driver' => 'mail', - - /** - * Whether to send as html, set to null for autodetection. - */ - 'is_html' => null, - - /** - * Email charset - */ - 'charset' => 'utf-8', - - /** - * Whether to encode subject and recipient names. - * Requires the mbstring extension: http://www.php.net/manual/en/ref.mbstring.php - */ - 'encode_headers' => true, - - /** - * Ecoding (8bit, base64 or quoted-printable) - */ - 'encoding' => '8bit', - - /** - * Email priority - */ - 'priority' => \Email::P_NORMAL, - - /** - * Default sender details - */ - 'from' => array( - 'email' => false, - 'name' => false, - ), - - /** - * Whether to validate email addresses - */ - 'validate' => true, - - /** - * Auto attach inline files - */ - 'auto_attach' => true, - - /** - * Auto generate alt body from html body - */ - 'generate_alt' => true, - - /** - * Forces content type multipart/related to be set as multipart/mixed. - */ - 'force_mixed' => false, - - /** - * Wordwrap size, set to null, 0 or false to disable wordwrapping - */ - 'wordwrap' => 76, - - /** - * Path to sendmail - */ - 'sendmail_path' => '/usr/sbin/sendmail', - - /** - * SMTP settings - */ - 'smtp' => array( - 'host' => '', - 'port' => 25, - 'username' => '', - 'password' => '', - 'timeout' => 5, - 'starttls' => false, - ), - - /** - * Newline - */ - 'newline' => "\n", - - /** - * Attachment paths - */ - 'attach_paths' => array( - '', // absolute path - DOCROOT, // relative to docroot. - ), - - /** - * Default return path - */ - 'return_path' => false, - - /** - * Remove html comments - */ - 'remove_html_comments' => true, - - /** - * Mandrill settings, see http://mandrill.com/ - */ - 'mandrill' => array( - 'key' => 'api_key', - 'message_options' => array(), - 'send_options' => array( - 'async' => false, - 'ip_pool' => null, - 'send_at' => null, - ), - ), - - /** - * Mailgun settings, see http://www.mailgun.com/ - */ - 'mailgun' => array( - 'key' => 'api_key', - 'domain' => 'domain', - ), - - /** - * When relative protocol uri's ("//uri") are used in the email body, - * you can specify here what you want them to be replaced with. Options - * are "http://", "https://" or \Input::protocol() if you want to use - * whatever was used to request the controller. - */ - 'relative_protocol_replacement' => false, - ), -); diff --git a/fuel/packages/email/readme.md b/fuel/packages/email/readme.md deleted file mode 100755 index ca93935..0000000 --- a/fuel/packages/email/readme.md +++ /dev/null @@ -1,151 +0,0 @@ -# Fuel Email Package. - -A full fledged email class for Fuel. Send mails using php's mail function, sendmail or SMTP. - -# Summary - -* Send plain/text or html with (optional) alternative plain/text bodies using mail, sendmail or SMTP. -* Add attachments, normal or inline and string or file. -* Automatic inline file attachments for html bodies. -* Configurable attachment paths. - -# Usage - - $mail = Email::forge(); - $mail->from('me@domain.com', 'Your Name Here'); - - // Set to - $mail->to('mail@domain.com'); - - // Set with name - $mail->to('mail@domain.com', 'His/Her Name'); - - // Set as array - $mail->to(array( - // Without name - 'mail@domain.com', - - // With name - 'mail@domain.com' => 'His/Her Name', - )); - - // Work the same for ->cc and ->bcc and ->reply_to - - - // Set a body message - $email->body('My email body'); - - // Set a html body message - $email->html_body(\View::forge('email/template', $email_data)); - - /** - - By default this will also generate an alt body from the html, - and attach any inline files (not paths like http://...) - - **/ - - // Set an alt body - $email->alt_body('This is my alt body, for non-html viewers.'); - - // Set a subject - $email->subject('This is the subject'); - - // Change the priority - $email->priority(\Email::P_HIGH); - - // And send it - $result = $email->send(); - -# Exceptions - - + \EmailValidationFailedException, thrown when one or more email addresses doesn't pass validation - + \EmailSendingFailedException, thrown when the driver failed to send the exception - -Example: - - // Use the default config and change the driver - $email = \Email::forge('default', array('driver' => 'smtp')); - $email->subject('My Subject'); - $email->html_body(\View::forge('email/template', $email_data)); - $email->from('me@example.com', 'It's Me!'); - $email->to('other@example.com', 'It's the Other!'); - - try - { - $email->send(); - } - catch(\EmailValidationFailedException $e) - { - // The validation failed - } - catch(\EmailSendingFailedException $e) - { - // The driver could not send the email - } - -# Priorities - -These can me one of the following: - - + \Email::P_LOWEST - 1 (lowest) - + \Email::P_LOW - 2 (low) - + \Email::P_NORMAL - 3 (normal) - this is the default - + \Email::P_HIGH - 4 (high) - + \Email::P_HIGHEST - 5 (highest) - -# Attachments - -There are multiple ways to add attachments: - - $email = Email::forge(); - - // Add an attachment - $email->attach(DOCROOT.'dir/my_img.png'); - - // Add an inline attachment - // Add a cid here to point to the html - $email->attach(DOCROOT.'dir/my_img.png', true, 'cid:my_conten_id'); - - -You can also add string attachments - - $contents = file_get_contents($my_file); - $email->string_attach($contents, $filename); - -By default html images are auto included, but it only includes local files. -Look at the following html to see how it works. - - // This is included - - - // This is not included - - - -Drivers -======= -The drivers allow the use of this library with mostly anything that can send mails. - -### Mailgun -Mailgun is an online service by Rackspace (http://www.mailgun.com/) that allows you to send emails by demand. You will need to install the mailgun library (https://github.com/mailgun/mailgun-php) with composer in your FuelPHP. - -Once you have installed the package you will have to set up the config for your App: - -```php - array( - 'driver' => 'mailgun', - 'mailgun' => array( - 'key' => 'YOUR KEY', - 'domain' => 'YOUR DOMAIN' - ), - ), -); -``` - -# That's it. Questions? diff --git a/fuel/packages/oil/.gitignore b/fuel/packages/oil/.gitignore deleted file mode 100755 index 5bb4b31..0000000 --- a/fuel/packages/oil/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*~ -*.bak -Thumbs.db -desktop.ini -.DS_Store -.buildpath -.project -.settings -nbproject/ -.idea \ No newline at end of file diff --git a/fuel/packages/oil/bootstrap.php b/fuel/packages/oil/bootstrap.php deleted file mode 100755 index 171909c..0000000 --- a/fuel/packages/oil/bootstrap.php +++ /dev/null @@ -1,24 +0,0 @@ - __DIR__.'/classes/cell.php', - 'Oil\\Command' => __DIR__.'/classes/command.php', - 'Oil\\Console' => __DIR__.'/classes/console.php', - 'Oil\\Exception' => __DIR__.'/classes/exception.php', - 'Oil\\Generate' => __DIR__.'/classes/generate.php', - 'Oil\\Generate_Migration_Actions' => __DIR__.'/classes/generate/migration/actions.php', - 'Oil\\Generate_Admin' => __DIR__.'/classes/generate/admin.php', - 'Oil\\Generate_Scaffold' => __DIR__.'/classes/generate/scaffold.php', - 'Oil\\Package' => __DIR__.'/classes/package.php', - 'Oil\\Refine' => __DIR__.'/classes/refine.php', -)); diff --git a/fuel/packages/oil/classes/cell.php b/fuel/packages/oil/classes/cell.php deleted file mode 100755 index 035d36b..0000000 --- a/fuel/packages/oil/classes/cell.php +++ /dev/null @@ -1,280 +0,0 @@ - - -Description: - Packages containing extra functionality can be downloaded (or git cloned) simply with - the following commands. - -Runtime options: - --via-zip # Download a ZIP file instead of using Git or Hg. - -Examples: - oil cell list - oil cell search - oil cell show - oil cell install - oil cell uninstall - -Documentation: - http://docs.fuelphp.com/packages/oil/cell.html -HELP; - \Cli::write($output); - - } - - protected static function _use_git() - { - exec('which git', $output); - - // If this is a valid path to git, use it instead of just "git" - if (file_exists($line = trim(current($output)))) - { - static::$git = $line; - } - - unset($output); - - // Double check git is installed (windows will fail step 1) - exec(static::$git . ' --version', $output); - - preg_match('#^(git version)#', current($output), $matches); - - // If we have a match, use Git! - return ! empty($matches[0]); - } - - protected static function _download_package_zip($zip_url, $package, $version) - { - // get the list of configured package paths - $paths = \Config::get('package_paths', array(PKGPATH)); - - // and make sure we have at least one - if (empty($paths)) - { - throw new \FuelException('There are no package paths defined in your configuration file. Don\'t know where to install the package.'); - } - - // we'll install in the first path defined - $package_folder = reset($paths); - - // Make the folder so we can extract the ZIP to it - mkdir($tmp_folder = APPPATH . 'tmp' . DS . $package . '-' . time()); - - $zip_file = $tmp_folder . '.zip'; - @copy($zip_url, $zip_file); - - $unzip = new \Unzip; - $files = $unzip->extract($zip_file, $tmp_folder); - - // Grab the first folder out of it (we dont know what it's called) - foreach(new \GlobIterator($tmp_folder.DS.'*') as $pkgfolder) - { - if ($pkgfolder->isDir()) - { - $tmp_package_folder = $tmp_folder.DS.$pkgfolder->getFilename(); - break; - } - } - - if (empty($tmp_package_folder)) - { - throw new \FuelException('The package zip file doesn\'t contain any install directory.'); - } - - // Move that folder into the packages folder - rename($tmp_package_folder, $package_folder); - - unlink($zip_file); - rmdir($tmp_folder); - - foreach ($files as $file) - { - $path = str_replace($tmp_package_folder, $package_folder, $file); - chmod($path, octdec(755)); - \Cli::write("\t" . $path); - } - } - - public static function _clone_package_repo($repo_url, $package, $version) - { - // get the list of configured package paths - $paths = \Config::get('package_paths', array(PKGPATH)); - - // and make sure we have at least one - if (empty($paths)) - { - throw new \FuelException('There are no package paths defined in your configuration file. Don\'t know where to install the package.'); - } - - // we'll install in the first path defined - $package_folder = reset($paths); - - // Clone to the package path - passthru(static::$_git_binary.' submodule add '.$repo_url.' '.$package_folder); - passthru(static::$_git_binary.' submodule update'); - - \Cli::write(''); - } -} diff --git a/fuel/packages/oil/classes/command.php b/fuel/packages/oil/classes/command.php deleted file mode 100755 index 89c5d68..0000000 --- a/fuel/packages/oil/classes/command.php +++ /dev/null @@ -1,406 +0,0 @@ - # Run a test on a specific file only. - --group= # Only runs tests from the specified group(s). - --exclude-group= # Exclude tests from the specified group(s). - --testsuite= # Only runs tests from the specified testsuite(s). - --coverage-clover= # Generate code coverage report in Clover XML format. - --coverage-html= # Generate code coverage report in HTML format. - --coverage-php= # Serialize PHP_CodeCoverage object to file. - --coverage-text= # Generate code coverage report in text format. - --log-junit= # Generate report of test execution in JUnit XML format to file. - --debug # Display debugging information during test execution. - -Description: - Run phpunit on all or a subset of tests defined for the current application. - -Examples: - php oil test - -Documentation: - http://fuelphp.com/docs/packages/oil/test.html -HELP; - \Cli::write($output); - } - else - { - $phpunit_command = \Config::get('oil.phpunit.binary_path', 'phpunit'); - - // Check if we might be using the phar library - $is_phar = false; - foreach(explode(':', getenv('PATH')) as $path) - { - if (is_file($path.DS.$phpunit_command)) - { - $handle = fopen($path.DS.$phpunit_command, 'r'); - $is_phar = fread($handle, 18) == '#!/usr/bin/env php'; - fclose($handle); - if ($is_phar) - { - break; - } - } - } - - // Suppressing this because if the file does not exist... well thats a bad thing and we can't really check - // I know that supressing errors is bad, but if you're going to complain: shut up. - Phil - $phpunit_autoload_path = \Config::get('oil.phpunit.autoload_path', 'PHPUnit/Autoload.php' ); - @include_once $phpunit_autoload_path; - - // Attempt to load PHUnit. If it fails, we are done. - if ( ! $is_phar and ! class_exists('PHPUnit_Framework_TestCase')) - { - throw new Exception('PHPUnit does not appear to be installed.'.PHP_EOL.PHP_EOL."\tPlease visit http://phpunit.de and install."); - } - - // Check for a custom phpunit config, but default to the one from core - if (is_file(APPPATH.'phpunit.xml')) - { - $phpunit_config = APPPATH.'phpunit.xml'; - } - else - { - $phpunit_config = COREPATH.'phpunit.xml'; - } - - // CD to the root of Fuel and call up phpunit with the path to our config - $command = 'cd '.DOCROOT.'; '.$phpunit_command.' -c "'.$phpunit_config.'"'; - - // Respect the group options - \Cli::option('group') and $command .= ' --group '.\Cli::option('group'); - \Cli::option('exclude-group') and $command .= ' --exclude-group '.\Cli::option('exclude-group'); - - // Respect the testsuite options - \Cli::option('testsuite') and $command .= ' --testsuite '.\Cli::option('testsuite'); - - // Respect the debug options - \Cli::option('debug') and $command .= ' --debug'; - - // Respect the coverage-html option - \Cli::option('coverage-html') and $command .= ' --coverage-html '.\Cli::option('coverage-html'); - \Cli::option('coverage-clover') and $command .= ' --coverage-clover '.\Cli::option('coverage-clover'); - \Cli::option('coverage-text') and $command .= ' --coverage-text='.\Cli::option('coverage-text'); - \Cli::option('coverage-php') and $command .= ' --coverage-php '.\Cli::option('coverage-php'); - \Cli::option('log-junit') and $command .= ' --log-junit '.\Cli::option('log-junit'); - \Cli::option('file') and $command .= ' '.\Cli::option('file'); - - \Cli::write('Tests Running...This may take a few moments.', 'green'); - - $return_code = 0; - foreach(explode(';', $command) as $c) - { - passthru($c, $return_code_task); - // Return failure if any subtask fails - $return_code |= $return_code_task; - } - exit($return_code); - } - - break; - - case 's': - case 'server': - - if (isset($args[2]) and $args[2] == 'help') - { - $output = << # The full pathname of your PHP-CLI binary if it's not in the path. - --port= # TCP port number the webserver should listen too. Defaults to 8000. - --host= # Hostname the webserver should run at. Defaults to "localhost". - --docroot= # Your FuelPHP docroot. Defaults to "public". - --router= # PHP router script. Defaults to "fuel/packages/oil/phpserver.php". - -Description: - Starts a local webserver to run your FuelPHP application, using PHP 5.4+ internal webserver. - -Examples: - php oil server -p=8080 - -Documentation: - http://fuelphp.com/docs/packages/oil/server.html -HELP; - \Cli::write($output); - } - else - { - if (version_compare(PHP_VERSION, '5.4.0') < 0) - { - \Cli::write('The PHP built-in webserver is only available on PHP 5.4+', 'red'); - break; - } - - $php = \Cli::option('php', 'php'); - $port = \Cli::option('p', \Cli::option('port', '8000')); - $host = \Cli::option('h', \Cli::option('host', 'localhost')); - $docroot = \Cli::option('d', \Cli::option('docroot', 'public')); - $router = \Cli::option('r', \Cli::option('router', __DIR__.DS.'..'.DS.'phpserver.php')); - - \Cli::write("Listening on http://$host:$port"); - \Cli::write("Document root is $docroot"); - \Cli::write("Press Ctrl-C to quit."); - passthru("$php -S $host:$port -t $docroot $router"); - } - break; - - case 'create': - \Cli::write('You can not use "oil create", a valid FuelPHP installation already exists in this directory', 'red'); - break; - - default: - - static::help(); - } - } - - catch (\Exception $e) - { - static::print_exception($e); - exit(1); - } - } - - protected static function print_exception(\Exception $ex) - { - // create the error message, log and display it - $msg = $ex->getCode().' - '.$ex->getMessage().' in '.$ex->getFile().' on line '.$ex->getLine(); - logger(\Fuel::L_ERROR, $msg); - \Cli::error('Uncaught exception '.get_class($ex).': '.$msg); - - // print a trace if not in production, don't want to spoil external logging - if (\Fuel::$env != \Fuel::PRODUCTION) - { - \Cli::error('Callstack: '); - \Cli::error($ex->getTraceAsString()); - } - \Cli::beep(); - \Cli::option('speak') and `say --voice="Trinoids" "{$ex->getMessage()}"`; - - // print any previous exception(s) too... - if (($previous = $ex->getPrevious()) != null) - { - \Cli::error(''); - \Cli::error('Previous exception: '); - static::print_exception($previous); - } - } - - public static function help() - { - echo << - -More information: - You can pass the parameter "help" to each of the defined command to get information - about that specific command: php oil package help - -Documentation: - http://docs.fuelphp.com/packages/oil/intro.html - -HELP; - - } - - protected static function _clear_args($actions = array()) - { - foreach ($actions as $key => $action) - { - if (substr($action, 0, 1) === '-') - { - unset($actions[$key]); - } - - // get rid of any junk added by Powershell on Windows... - isset($actions[$key]) and $actions[$key] = trim($actions[$key]); - } - - return $actions; - } -} - -/* End of file oil/classes/command.php */ diff --git a/fuel/packages/oil/classes/console.php b/fuel/packages/oil/classes/console.php deleted file mode 100755 index 627df94..0000000 --- a/fuel/packages/oil/classes/console.php +++ /dev/null @@ -1,257 +0,0 @@ ->> ')), PHP_EOL), ';')) - { - continue; - } - - if ($__line == 'quit') - { - break; - } - - // Add this line to history - //$this->history[] = array_slice($this->history, 0, -99) + array($line); - if (\Cli::$readline_support) - { - readline_add_history($__line); - } - - if (self::is_immediate($__line)) - { - $__line = "return ($__line)"; - } - - ob_start(); - - // Unset the previous line and execute the new one - $random_ret = \Str::random(); - try - { - $ret = eval("unset(\$__line); $__line;"); - } - catch(\Exception $e) - { - $ret = $random_ret; - $__line = $e->getMessage(); - } - - // Error was returned - if ($ret === $random_ret) - { - \Cli::error('Parse Error - ' . $__line); - \Cli::beep(); - } - - if (ob_get_length() == 0) - { - if (is_bool($ret)) - { - echo $ret ? 'true' : 'false'; - } - elseif (is_string($ret)) - { - echo addcslashes($ret, "\0..\11\13\14\16..\37\177..\377"); - } - elseif ( ! is_null($ret)) - { - print_r($ret); - } - } - - unset($ret); - $out = ob_get_contents(); - ob_end_clean(); - - if ((strlen($out) > 0) && (substr($out, -1) != PHP_EOL)) - { - $out .= PHP_EOL; - } - - echo $out; - unset($out); - } - } - - private static function is_immediate($line) - { - $skip = array( - 'class', 'declare', 'die', 'echo', 'exit', 'for', - 'foreach', 'function', 'global', 'if', 'include', - 'include_once', 'print', 'require', 'require_once', - 'return', 'static', 'switch', 'unset', 'while', - ); - - $okeq = array('===', '!==', '==', '!=', '<=', '>='); - - $code = ''; - $sq = false; - $dq = false; - - for ($i = 0; $i < strlen($line); $i++) - { - $c = $line{$i}; - if ($c == "'") - { - $sq = !$sq; - } - elseif ($c == '"') - { - $dq = !$dq; - } - - elseif ( ($sq) || ($dq) && $c == "\\") - { - ++$i; - } - else - { - $code .= $c; - } - } - - $code = str_replace($okeq, '', $code); - if (strcspn($code, ';{=') != strlen($code)) - { - return false; - } - - $kw = preg_split("/[^a-z0-9_]/i", $code); - foreach ($kw as $i) - { - if (in_array($i, $skip)) - { - return false; - } - } - - return true; - } - - public static function tab_complete($line, $pos, $cursor) - { - $const = array_keys(get_defined_constants()); - $var = array_keys($GLOBALS); - $func = get_defined_functions(); - - foreach ($func["user"] as $i) - { - $func["internal"][] = $i; - } - $func = $func["internal"]; - - return array_merge($const, $var, $func); - } - - private static function build_date() - { - ob_start(); - phpinfo(INFO_GENERAL); - - $x = ob_get_contents(); - ob_end_clean(); - - $x = strip_tags($x); - $x = explode("\n", $x); // PHP_EOL doesn't work on Windows - $s = array('Build Date => ', 'Build Date '); - - foreach ($x as $i) - { - foreach ($s as $j) - { - if (substr($i, 0, strlen($j)) == $j) - { - return trim(substr($i, strlen($j))); - } - } - } - - return '???'; - } - -} - -/* End of file oil/classes/console.php */ diff --git a/fuel/packages/oil/classes/exception.php b/fuel/packages/oil/classes/exception.php deleted file mode 100755 index 2271c22..0000000 --- a/fuel/packages/oil/classes/exception.php +++ /dev/null @@ -1,32 +0,0 @@ -message); -// } - -} - -/* End of file oil/classes/exception.php */ diff --git a/fuel/packages/oil/classes/generate.php b/fuel/packages/oil/classes/generate.php deleted file mode 100755 index 331e858..0000000 --- a/fuel/packages/oil/classes/generate.php +++ /dev/null @@ -1,2089 +0,0 @@ - array( - 'null' => false, - 'key' => NULL, - ), - 'varchar' => array( - 'constraint' => '255', - ), - 'char' => array( - 'constraint' => '255', - ), - 'int' => array( - 'constraint' => '11', - ), - 'decimal' => array( - 'constraint' => '10,2', - ), - 'float' => array( - 'constraint' => '10,2', - ), - ); - - /** - * - */ - public static function config($args) - { - $file = strtolower(array_shift($args)); - - if (empty($file)) - { - throw new Exception('No config filename has been provided.'); - } - - $config = array(); - - // load the config - if ($paths = \Finder::search('config', $file, '.php', true)) - { - // Reverse the file list so that we load the core configs first and - // the app can override anything. - $paths = array_reverse($paths); - foreach ($paths as $path) - { - $config = \Fuel::load($path) + $config; - } - } - unset($path); - - // We always pass in fields to a config, so lets sort them out here. - foreach ($args as $conf) - { - // Each paramater for a config is seperated by the : character - $parts = explode(":", $conf); - - // We must have the 'name:value' if nothing else! - if (count($parts) >= 2) - { - $config[$parts[0]] = $parts[1]; - } - } - - $overwrite = (\Cli::option('o') or \Cli::option('overwrite')); - - // strip whitespace and add tab - $export = str_replace(array(' ', 'array ('), array("\t", 'array('), var_export($config, true)); - - $content = ' \'active\' ); - $this->template->title = \'' . \Inflector::humanize($name) .' » ' . \Inflector::humanize($action) . '\'; - $this->template->content = View::forge(\''.$filename.'/' . $action .'\', $data); - }'.PHP_EOL; - } - - $extends = \Cli::option('extends', 'Controller_Template'); - $prefix = \Config::get('controller_prefix', 'Controller_'); - - // Build Controller - $controller = <<content = "{$class_name} » {$action}"; - } -} -PRESENTER; - - // Write presenter - static::create($presenter_filepath.DS.$action.'.php', $presenter, 'presenter'); - } - } - - // Generate with test? - $with_test = \Cli::option('with-test'); - if ($with_presenter and $with_test) { - static::_create_test('Presenter', $class_name, $base_path); - } - - $build and static::build(); - } - - /** - * - */ - public static function model($args, $build = true) - { - $singular = \Inflector::singularize(\Str::lower(array_shift($args))); - - $args = static::normalize_args($args); - - if (empty($singular) or strpos($singular, ':')) - { - throw new Exception("Command is invalid.".PHP_EOL."\tphp oil g model [: |: |..]"); - } - - if (empty($args)) - { - throw new Exception('No fields have been provided, the model will not know how to build the table.'); - } - - $plural = (\Cli::option('singular') or \Cli::option('no-standardisation')) ? $singular : \Inflector::pluralize($singular); - - $filename = trim(str_replace(array('_', '-'), DS, $singular), DS); - $base_path = APPPATH; - - if ($module = \Cli::option('module')) - { - if ( ! ($base_path = \Module::exists($module)) ) - { - throw new Exception('Module '.$module.' was not found within any of the defined module paths'); - } - - $module_namespace = ucwords($module); - } - - $filepath = $base_path.'classes'.DS.'model'.DS.$filename.'.php'; - - // Uppercase each part of the class name and remove hyphens - $class_name = \Inflector::classify(str_replace(array('\\', '/'), '_', $singular), false); - - // Generate with test? - if ($with_test = \Cli::option('with-test')) - { - static::_create_test('Model', $class_name, $base_path); - } - - // storage for the generated contents - $contents = ''; - - // deal with Model_Crud models first - if (\Cli::option('crud')) - { - // model properties - if ( ! \Cli::option('no-properties')) - { - $contents = << array("; - $contents .= PHP_EOL."\t\t\t\"label\" => \"".\Inflector::humanize($arg['name'])."\","; - $contents .= PHP_EOL."\t\t\t\"data_type\" => \"".$arg['data_type']."\","; - if (isset($arg['default'])) - { - $contents .= PHP_EOL."\t\t\t\"default\" => \"".$arg['default']."\","; - } - if ($arg['data_type'] == 'enum' and isset($arg['options'])) - { - $contents .= PHP_EOL."\t\t\t\"options\" => array(".$arg['constraint']."),"; - } - - $contents .= PHP_EOL."\t\t),"; - } - $contents .= << array( - 'events' => array('before_insert'), - 'property' => '$created_at', - 'mysql_timestamp' => $mysql_timestamp, - ), - 'Orm\Observer_UpdatedAt' => array( - 'events' => array('before_update'), - 'property' => '$updated_at', - 'mysql_timestamp' => $mysql_timestamp, - ), -CONTENTS; - } - - $contents .= << $mysql_timestamp, - 'deleted_field' => '{$deleted_at}', - ); - -CONTENTS; - } - - // add fields required for temporal models - elseif (\Cli::option('temporal')) - { - $temporal_start = \Cli::option('temporal-start', 'temporal_start'); - is_string($temporal_start) or $temporal_start = 'temporal_start'; - - $temporal_end = \Cli::option('temporal-end', 'temporal_end'); - is_string($temporal_end) or $temporal_end = 'temporal_end'; - - $contents .= << $mysql_timestamp, - 'start_column' => '{$temporal_start}', - 'end_column' => '{$temporal_end}', - - ); -CONTENTS; - } - - // add fields required for nestedset models - elseif (\Cli::option('nestedset')) - { - $contents .= << '{$title}', - -CONTENTS; - } - - if ($tree_id = \Cli::option('tree-id', false)) - { - is_string($tree_id) or $tree_id = 'tree_id'; - $contents .= << '{$tree_id}', - -CONTENTS; - } - - $left_id = \Cli::option('left-id', 'left_id'); - is_string($left_id) or $left_id = 'left_id'; - $contents .= << '{$left_id}', - -CONTENTS; - - - $right_id = \Cli::option('right-id', 'right_id'); - is_string($right_id) or $right_id = 'right_id'; - $contents .= << '{$right_id}', - -CONTENTS; - - if($read_only = \Cli::option('read-only') and is_string($read_only)) - { - $read_only = explode(',', $read_only); - $read_only = "'" . implode("', '", $read_only) . "'"; - $read_only = << array($read_only), - -CONTENTS; - } - - $contents .= << 1) - { - \Cli::write('Your app has multiple module paths defined. Please choose the appropriate path from the list below', 'yellow', 'blue'); - - $options = array(); - foreach ($module_paths as $key => $path) - { - $idx = $key+1; - \Cli::write('['.$idx.'] '.$path); - $options[] = $idx; - } - - $path_idx = \Cli::prompt('Please choose the desired module path', $options); - - $base = $module_paths[$path_idx - 1]; - } - - $module_path = $base.$module_name.DS; - - static::$create_folders[] = $module_path; - static::$create_folders[] = $module_path.'classes/'; - - if ( ($folders = \Cli::option('folders')) !== true ) - { - $folders = explode(',', $folders); - - foreach ($folders as $folder) - { - static::$create_folders[] = $module_path.$folder; - } - } - - static::$create_folders && static::build(); - } - - /** - * - */ - public static function views($args, $subfolder, $build = true) - { - $controller = strtolower(array_shift($args)); - $controller_title = \Inflector::humanize($controller); - - $base_path = APPPATH; - if ($module = \Cli::option('module')) - { - if ( ! ($base_path = \Module::exists($module)) ) - { - throw new Exception('Module '.$module.' was not found within any of the defined module paths'); - } - } - - $view_dir = $base_path.'views/'.trim(str_replace(array('_', '-'), DS, $controller), DS).DS; - - $args or $args = array('index'); - - // Make the directory for these views to be store in - is_dir($view_dir) or static::$create_folders[] = $view_dir; - - // Add the default template if it doesn't exist - if ( ! is_file($app_template = $base_path.'views/template.php') ) - { - static::create($app_template, file_get_contents(\Package::exists('oil').'views/scaffolding/template.php'), 'view'); - } - - $subnav = ''; - foreach($args as $nav_item) - { - $subnav .= "\t
  • ".PHP_EOL; - } - - foreach ($args as $action) - { - $view_title = (\Cli::option('with-presenter') or \Cli::option('with-viewmodel')) ? '' : \Inflector::humanize($action); - - $view = << -{$subnav} - -

    {$view_title}

    -VIEW; - - // Generate with test? - $with_test = \Cli::option('with-test'); - if ($with_test) { - static::_create_test('View', $controller, $base_path, $nav_item); - } - - // Create this view - static::create($view_dir.$action.'.php', $view, 'view'); - } - - $build and static::build(); - } - - /** - * - */ - public static function migration($args, $build = true) - { - // Get the migration name - $migration_name = \Str::lower(str_replace(array('-', '/'), '_', array_shift($args))); - - // what type of migration do we have? - $type = explode('_', $migration_name); - - // tell the generator not to standardize the fieldlist for these types - if (in_array($type[0], array('add', 'delete', 'rename', 'drop'))) - { - \Cli::set_option('no-standardisation', true); - } - - // normalize the arguments if needed - if ( ! empty($args)) - { - $args = static::normalize_args($args); - } - - if (empty($migration_name) or strpos($migration_name, ':')) - { - throw new Exception("Command is invalid.".PHP_EOL."\tphp oil g migration [: |: |..]"); - } - - $base_path = APPPATH; - - // Check if a migration with this name already exists - if ($module = \Cli::option('module')) - { - if ( ! ($base_path = \Module::exists($module)) ) - { - throw new Exception('Module '.$module.' was not found within any of the defined module paths'); - } - } - - $duplicates = array(); - foreach($migrations = new \GlobIterator($base_path.'migrations/*_'.$migration_name.'*') as $migration) - { - // check if it's really a duplicate - $part = explode('_', basename($migration->getFilename(), '.php'), 2); - if ($part[1] != $migration_name) - { - $part = substr($part[1], strlen($migration_name)+1); - if ( ! is_numeric($part)) - { - // not a numbered suffix, but the same base classname - continue; - } - } - - $duplicates[] = $migration->getPathname(); - } - - // save the migration name, it's also used as table name - $table_name = $migration_name; - - // deal with duplicates to make sure the migration name is unique - if (count($duplicates) > 0) - { - // Don't override a file - if (\Cli::option('s', \Cli::option('skip')) === true) - { - return; - } - - // Tear up the file path and name to get the last duplicate - $file_name = pathinfo(end($duplicates), PATHINFO_FILENAME); - - // Override the (most recent) migration with the same name by using its number - if (\Cli::option('f', \Cli::option('force')) === true) - { - list($number) = explode('_', $file_name); - } - - // Name clashes but this is done by hand. Assume they know what they're doing and just increment the file - elseif (static::$scaffolding === false) - { - // Increment the name of this - $migration_name = \Str::increment(substr($file_name, 4), 2); - } - } - - // See if the action exists - $methods = get_class_methods(__NAMESPACE__ . '\Generate_Migration_Actions'); - - // For empty migrations that dont have actions - $migration = array('', ''); - - // Loop through the actions and act on a matching action appropriately - foreach ($methods as $method_name) - { - // If the miration name starts with the name of the action method - if (substr($table_name, 0, strlen($method_name)) === $method_name) - { - /** - * Create an array of the subject the migration is about - * - * - In a migration named 'create_users' the subject is 'users' since thats what we want to create - * So it would be the second object in the array - * array(false, 'users') - * - * - In a migration named 'add_name_to_users' the object is 'name' and the subject is 'users'. - * So again 'users' would be the second object, but 'name' would be the first - * array('name', 'users') - * - */ - $subjects = array(false, false); - $matches = explode('_', str_replace($method_name . '_', '', $table_name)); - - // create_{table} - if (count($matches) == 1) - { - $subjects = array(false, $matches[0]); - } - - // add_{field}_to_{table} - elseif (count($matches) == 3 && $matches[1] == 'to') - { - $subjects = array($matches[0], $matches[2]); - } - - // delete_{field}_from_{table} - elseif (count($matches) == 3 && $matches[1] == 'from') - { - $subjects = array($matches[0], $matches[2]); - } - - // rename_field_{field}_to_{field}_in_{table} (with underscores in field names) - elseif (count($matches) >= 5 && in_array('to', $matches) && in_array('in', $matches)) - { - $subjects = array( - implode('_', array_slice($matches, 0, array_search('to', $matches))), - implode('_', array_slice($matches, array_search('to', $matches)+1, array_search('in', $matches)-array_search('to', $matches)-1)), - implode('_', array_slice($matches, array_search('in', $matches)+1)), - ); - } - - // rename_table - elseif ($method_name == 'rename_table') - { - $subjects = array( - implode('_', array_slice($matches, 0, array_search('to', $matches))), - implode('_', array_slice($matches, array_search('to', $matches)+1)), - ); - } - - // create_{table} or drop_{table} (with underscores in table name) - elseif (count($matches) !== 0) - { - $name = str_replace(array('create_', 'add_', 'drop_', '_to_'), array('create-', 'add-', 'drop-', '-to-'), $table_name); - - if (preg_match('/^(create|drop|add)\-([a-z0-9\_]*)(\-to\-)?([a-z0-9\_]*)?$/i', $name, $deep_matches)) - { - switch ($deep_matches[1]) - { - case 'create' : - case 'drop' : - $subjects = array(false, $deep_matches[2]); - break; - - case 'add' : - $subjects = array($deep_matches[2], $deep_matches[4]); - break; - } - } - } - - // There is no subject here so just carry on with a normal empty migration - else - { - break; - } - - // Call the magic action which returns an array($up, $down) for the migration - $migration = call_user_func(__NAMESPACE__ . "\Generate_Migration_Actions::{$method_name}", $subjects, $args); - } - } - - // Build the migration - list($up, $down) = $migration; - - // If we don't have any, bail out - if (empty($up) and empty($down)) - { - throw new \Exception('No migration could be generated. Please verify your command syntax.'); - exit; - } - - $migration_name = ucfirst(strtolower($migration_name)); - - $migration = << [ | |..] - php oil g model [: |: |..] - php oil g migration [: |: |..] - php oil g scaffold [: |: |..] - php oil g scaffold/template_subfolder [: |: |..] - php oil g config [: |: |..] - php oil g task [ | |..] - php oil g package - -Note that the next two lines are equivalent: - php oil g scaffold ... - php oil g scaffold/orm ... - -Documentation: - http://docs.fuelphp.com/packages/oil/generate.html -HELP; - - \Cli::write($output); - } - - /** - * - */ - public static function package($args, $build = true) - { - $name = str_replace(array('/', '_', '-'), '', \Str::lower(array_shift($args))); - $class_name = ucfirst($name); - $vcs = \Cli::option('vcs', \Cli::option('v', false)); - $path = \Cli::option('path', \Cli::option('p', PKGPATH)); - $drivers = \Cli::option('drivers', \Cli::option('d', '')); - - if (empty($name)) - { - throw new \Exception('No package name has been provided.'); - } - - if ( ! in_array($path, \Config::get('package_paths')) and ! in_array(realpath($path), \Config::get('package_paths')) ) - { - throw new \Exception('Given path is not a valid package path.'); - } - - \Str::ends_with($path, DS) or $path .= DS; - $path .= $name . DS; - - if (is_dir($path)) - { - throw new \Exception('Package already exists.'); - } - - if ($vcs) - { - $output = << \$config); - - \$config = \Arr::merge(static::\$_defaults, \Config::get('{$name}', array()), \$config); - - \$class = '\\{$class_name}\\{$class_name}_' . ucfirst(strtolower(\$config['driver'])); - - if( ! class_exists(\$class, true)) - { - throw new \FuelException('Could not find {$class_name} driver: ' . ucfirst(strtolower(\$config['driver']))); - } - - \$driver = new \$class(\$config); - - static::\$_instances[\$instance] = \$driver; - - return \$driver; - } - - /** - * Return a specific driver, or the default instance (is created if necessary) - * - * @param string \$instance - * @return {$class_name} instance - */ - public static function instance(\$instance = null) - { - if (\$instance !== null) - { - if ( ! array_key_exists(\$instance, static::\$_instances)) - { - return false; - } - - return static::\$_instances[\$instance]; - } - - if (static::\$_instance === null) - { - static::\$_instance = static::forge(); - } - - return static::\$_instance; - } -} - -CLASS; - - static::create($path . 'classes' . DS . $name . '.php', $output); - - $output = <<config = \$config; - } - - /** - * Get a driver config setting. - * - * @param string \$key the config key - * @param mixed \$default the default value - * @return mixed the config setting value - */ - public function get_config(\$key, \$default = null) - { - return \Arr::get(\$this->config, \$key, \$default); - } - - /** - * Set a driver config setting. - * - * @param string \$key the config key - * @param mixed \$value the new config value - * @return object \$this for chaining - */ - public function set_config(\$key, \$value) - { - \Arr::set(\$this->config, \$key, \$value); - - return \$this; - } -} - -DRIVER; - - static::create($path . 'classes' . DS . $name . DS . 'driver.php', $output); - - $bootstrap = PHP_EOL."\t'{$class_name}\\\\{$class_name}_Driver' => __DIR__ . '/classes/{$name}/driver.php',"; - if (is_array($drivers)) - { - foreach ($drivers as $driver) - { - $driver = \Str::lower($driver); - $driver_name = ucfirst($driver); - $output = << __DIR__ . '/classes/{$name}/{$driver}.php',"; - static::create($path . 'classes' . DS . $name . DS . $driver . '.php', $output); - } - } - } - else - { - $output = <<config = \$config; - } - - /** - * Get a config setting. - * - * @param string \$key the config key - * @param mixed \$default the default value - * @return mixed the config setting value - */ - public function get_config(\$key, \$default = null) - { - return \Arr::get(\$this->config, \$key, \$default); - } - - /** - * Set a config setting. - * - * @param string \$key the config key - * @param mixed \$value the new config value - * @return object \$this for chaining - */ - public function set_config(\$key, \$value) - { - \Arr::set(\$this->config, \$key, \$value); - - return \$this; - } -} - -CLASS; - - static::create($path . 'classes' . DS . $name . '.php', $output); - - $bootstrap = ""; - } - - $output = << __DIR__ . '/classes/{$name}.php', - '{$class_name}\\\\{$class_name}Exception' => __DIR__ . '/classes/{$name}.php', -{$bootstrap} -)); - -CLASS; - static::create($path . 'bootstrap.php', $output); - - $build and static::build(); - } - - /** - * - */ - public static function create($filepath, $contents, $type = 'file') - { - $directory = dirname($filepath); - is_dir($directory) or static::$create_folders[] = $directory; - - // Check if a file exists then work out how to react - if (is_file($filepath)) - { - // Don't override a file - if (\Cli::option('s', \Cli::option('skip')) === true) - { - // Don't bother trying to make this, carry on camping - return; - } - - // If we aren't skipping it, tell em to use -f - if (\Cli::option('f', \Cli::option('force')) === null) - { - throw new Exception($filepath .' already exists, use -f or --force to override.'); - exit; - } - } - - static::$create_files[] = array( - 'path' => $filepath, - 'contents' => $contents, - 'type' => $type, - ); - } - - /** - * - */ - public static function build() - { - foreach (static::$create_folders as $folder) - { - is_dir($folder) or mkdir($folder, 0755, TRUE); - } - - $result = true; - - foreach (static::$create_files as $file) - { - \Cli::write("\tCreating {$file['type']}: {$file['path']}", 'green'); - - if ( ! $handle = @fopen($file['path'], 'w+')) - { - throw new Exception('Cannot open file: '. $file['path']); - } - - $result = @fwrite($handle, $file['contents']); - - // Write $somecontent to our opened file. - if ($result === false) - { - throw new Exception('Cannot write to file: '. $file['path']); - } - - @fclose($handle); - - @chmod($file['path'], 0666); - } - - return $result; - } - - /** - * - */ - public static function class_name($name) - { - return str_replace(array(' ', '-'), '_', ucwords(str_replace('_', ' ', $name))); - } - - /** - * - */ - public static function normalize_args(array $args) - { - // normalized result - $normalized = array('id' => null); - - // loop over the field names passed - foreach ($args as $field) - { - // check what we got - if (is_array($field)) - { - // make sure we have the correct format - if (isset($field['name'])) - { - // deal with some generics - if ($field['data_type'] === 'string') - { - $field['data_type'] = 'varchar'; - } - elseif ($field['data_type'] === 'integer') - { - $field['data_type'] = 'int'; - } - elseif (strpos($field['data_type'], ' unsigned') !== false) - { - $field['data_type'] = explode(' ', $field['data_type']); - $field['data_type'] = $field['data_type'][0]; - $field['unsigned'] = true; - } - - // deal with some constraint quirks - if (empty($field['constraint'])) - { - if (isset($field['display'])) - { - $field['constraint'] = $field['display']; - } - elseif (isset($field['numeric_precision'])) - { - $field['constraint'] = $field['numeric_precision'].','.$field['numeric_scale']; - } - } - - // deal with the different constraint types - if ($field['data_type'] === 'enum' or $field['data_type'] === 'set' ) - { - // avoid double quoting - if (strpos($field['constraint'], '"') !== 0) - { - $values = explode(',', $field['constraint']); - $field['constraint'] = '"'.implode('","', $values).'"'; - } - } - - // should support field_name:decimal[10,2] - elseif (in_array($field['data_type'], array('decimal', 'float', 'double'))) - { - // leave as-is - } - - // should support any other constraint - elseif (isset($field['constraint'])) - { - $field['constraint'] = (int) $field['constraint']; - } - - // output from list_columns, we're done here! - $normalized[$field['name']] = $field; - } - } - else - { - // we need to split a field string into components - $field_array = array(); - - // Each paramater for a field is seperated by the : character - $parts = explode(":", $field); - - // We must have the 'name:type' if nothing else! - if (count($parts) >= 2) - { - // make sure we have default values - $field_array = static::$_field_defaults['_default_']; - - // extract the field name - $field_array['name'] = array_shift($parts); - - // process the remaining parts - foreach ($parts as $part_i => $part) - { - // split the part - preg_match('/([a-z0-9_-]+)(?:\[([0-9a-z_\-\,\s]+)\])?/i', $part, $part_matches); - array_shift($part_matches); - - if ( ! count($part_matches)) - { - // Move onto the next part, something is wrong here... - continue; - } - - // The first option always has to be the field type - if (empty($field_array['data_type'])) - { - // determine the field datatype - $type = $part_matches[0]; - // deal with some generics - if ($type === 'string') - { - $type = 'varchar'; - } - elseif ($type === 'integer') - { - $type = 'int'; - } - - // add the defaults for this datatype - if (isset(static::$_field_defaults[$type])) - { - $field_array = array_merge(static::$_field_defaults[$type], $field_array); - } - - // deal with any field constraints - if (isset($part_matches[1]) and $part_matches[1]) - { - // should support field_name:enum[value1,value2] and field_name:set[value1,value2] - if ($type === 'enum' or $type === 'set') - { - $values = explode(',', $part_matches[1]); - $part_matches[1] = '"'.implode('","', $values).'"'; - - $field_array['constraint'] = $part_matches[1]; - } - - // should support field_name:decimal[10,2] - elseif (in_array($type, array('decimal', 'float'))) - { - $field_array['constraint'] = $part_matches[1]; - } - - // should support any other constraint - else - { - $field_array['constraint'] = (int) $part_matches[1]; - } - } - - // so we can add this next - $option = 'data_type'; - $part_matches = $type; - } - else - { - // This allows you to put any number of :option or :option[val] into your field and these will... - // ... always be passed through to the action making it really easy to add extra options for a field - $option = array_shift($part_matches); - if (count($part_matches) > 0) - { - $option = $part_matches[0]; - } - else - { - $part_matches = true; - } - } - - // deal with some special cases - switch ($option) - { - case 'auto_increment': - case 'null': - case 'unsigned': - $part_matches = (bool) $part_matches; - break; - } - - $field_array[$option] = $part_matches; - } - - $normalized[$field_array['name']] = $field_array; - } - else - { - // Invalid field passed in - continue; - } - } - } - - // Check if we have a primary key - $pk = false; - foreach ($args as $arg) - { - if (isset($arg['indexes'])) - { - foreach ($arg['indexes'] as $idx) - { - if ($idx['primary']) - { - $pk = true; - break; - } - } - } - } - - // keep track of the primary keys added - $pk_counter = 0; - - // add a PK if none are present - if ( ! $pk and ! \Cli::option('no-standardisation')) - { - // define the default key column - $normalized['id'] = array('name' => 'id', 'data_type' => 'int', 'unsigned' => true, 'null' => false, 'auto_increment' => true, 'constraint' => '11'); - - // and it's primary index - $normalized['id']['indexes'] = array('PRIMARY' => array( - 'name' => 'PRIMARY', 'column' => 'id', 'order' => strval(++$pk_counter), 'type' => 'BTREE', 'primary' => true, 'unique' => true, 'null' => false, 'ascending' => true, - )); - } - elseif ($normalized['id'] === null) - { - // remove the dummy - unset($normalized['id']); - } - - // some other optional columns in case of ORM - if ( ! \Cli::option('crud')) - { - $time_type = (\Cli::option('mysql-timestamp')) ? 'timestamp' : 'int'; - $no_timestamp_default = false; - - // closure used to add a new field - $add_field = function($args, $name, $type, $options = array()) use($pk_counter) { - - // create the field - $field = static::$_field_defaults['_default_']; - - // add the defaults for this datatype - if (isset(static::$_field_defaults[$type])) - { - $field = array_merge(static::$_field_defaults[$type], $field); - } - - // add the data - $field['name'] = $name; - $field['type'] = $type; - $field['data_type'] = $type; - - // need to add an index? - if (isset($options['key'])) - { - // add a primary key - if ($options['key'] == 'PRI') - { - $field['indexes'] = array('PRIMARY' => array( - 'name' => 'PRIMARY', 'column' => $name, 'order' => strval(++$pk_counter), 'type' => 'BTREE', 'primary' => true, 'unique' => true, 'null' => false, 'ascending' => true, - )); - } - - unset($options['key']); - } - - // return the result - return array_merge($args, array($name => array_merge($field, $options))); - }; - - - // additional column for soft-delete models - if ( \Cli::option('soft-delete')) - { - $deleted_at = \Cli::option('deleted-at', 'deleted_at'); - is_string($deleted_at) or $deleted_at = 'deleted_at'; - if ( ! isset($normalized[$deleted_at])) - { - $normalized = $add_field($normalized, $deleted_at, $time_type, array('null' => true, 'unsigned' => true)); - } - } - - // additional column for temporal models - elseif (\Cli::option('temporal')) - { - $temporal_start = \Cli::option('temporal-start', 'temporal_start'); - is_string($temporal_start) or $temporal_start = 'temporal_start'; - if ( ! isset($normalized[$temporal_start])) - { - $normalized = $add_field($normalized, $temporal_start, $time_type, array('key' => 'PRI', 'null' => true, 'unsigned' => true)); - } - - $temporal_end = \Cli::option('temporal-end', 'temporal_end'); - is_string($temporal_end) or $temporal_end = 'temporal_end'; - if ( ! isset($normalized[$temporal_end])) - { - $normalized = $add_field($normalized, $temporal_end, $time_type, array('key' => 'PRI', 'null' => true, 'unsigned' => true)); - } - - \Cli::set_option('no-timestamp', true); - } - - // additional columns for nestedset models - elseif (\Cli::option('nestedset')) - { - if ($title = \Cli::option('title', false)) - { - is_string($title) or $title = 'title'; - if ( ! isset($normalized[$title])) - { - $normalized = $add_field($normalized, $title, 'varchar', array('null' => true, 'constraint' => '50')); - } - } - - if ($tree_id = \Cli::option('tree-id', false)) - { - is_string($tree_id) or $tree_id = 'tree_id'; - if ( ! isset($normalized[$tree_id])) - { - $normalized = $add_field($normalized, $tree_id, 'int', array('constraint' => '11', 'unsigned' => true)); - } - } - - $left_id = \Cli::option('left-id', 'left_id'); - is_string($left_id) or $left_id = 'left_id'; - if ( ! isset($normalized[$left_id])) - { - $normalized = $add_field($normalized, $left_id, 'int', array('constraint' => '11', 'unsigned' => true)); - } - - $right_id = \Cli::option('right-id', 'right_id'); - is_string($right_id) or $right_id = 'right_id'; - if ( ! isset($normalized[$right_id])) - { - $normalized = $add_field($normalized, $right_id, 'int', array('constraint' => '11', 'unsigned' => true)); - } - } - - if ( ! \Cli::option('no-timestamp') and ! \Cli::option('no-standardisation')) - { - $created_at = \Cli::option('created-at', 'created_at'); - is_string($created_at) or $created_at = 'created_at'; - if ( ! isset($normalized[$created_at])) - { - $normalized = $add_field($normalized, $created_at, $time_type, array('null' => true, 'unsigned' => true)); - } - - $updated_at = \Cli::option('updated-at', 'updated_at'); - is_string($updated_at) or $updated_at = 'updated_at'; - if ( ! isset($normalized[$updated_at])) - { - $normalized = $add_field($normalized, $updated_at, $time_type, array('null' => true, 'unsigned' => true)); - } - } - } - - // return the normalized result - return $normalized; - } - - // Helper methods - - /** - * - */ - private static function _find_migration_number() - { - $base_path = APPPATH; - - if ($module = \Cli::option('module')) - { - if ( ! ($base_path = \Module::exists($module)) ) - { - throw new Exception('Module ' . $module . ' was not found within any of the defined module paths'); - } - } - - foreach(new \GlobIterator($base_path .'migrations/*_*.php') as $file) - { - $migrations[] = $file->getPathname(); - } - if ( ! empty($migrations)) - { - sort($migrations); - list($last) = explode('_', basename(end($migrations))); - } - else - { - $last = 0; - } - - return str_pad($last + 1, 3, '0', STR_PAD_LEFT); - } - - /** - * - */ - private static function _update_current_version($version) - { - if (is_file($app_path = APPPATH.'config'.DS.'migrations.php')) - { - $contents = file_get_contents($app_path); - } - elseif (is_file($core_path = COREPATH.'config'.DS.'migrations.php')) - { - $contents = file_get_contents($core_path); - } - else - { - throw new \Exception('Config file core/config/migrations.php'); - exit; - } - - $contents = preg_replace("#('version'[ \t]+=>)[ \t]+([0-9]+),#i", "$1 $version,", $contents); - - static::create($app_path, $contents, 'config'); - } - - /** - * - */ - private static function _create_test($type, $class_name, $base_path, $nav_item = '') - { - $filepath = $base_path.strtolower('tests'.DS.$type.DS.ucwords($class_name)); - if ( ! empty($nav_item) and $type === 'View') - { - $filepath = $filepath.DS.strtolower($nav_item); - $class_name = $class_name.'_'.ucwords($nav_item); - } - $output = << $subfolder.'/controllers/base.php', - 'location' => 'classes/controller/base.php', - 'type' => 'controller', - ), - array( - 'source' => $subfolder.'/controllers/admin.php', - 'location' => 'classes/controller/admin.php', - 'type' => 'controller', - ), - array( - 'source' => '/template.php', - 'location' => 'views/admin/template.php', - 'type' => 'views', - ), - array( - 'source' => 'dashboard.php', - 'location' => 'views/admin/dashboard.php', - 'type' => 'views', - ), - array( - 'source' => 'login.php', - 'location' => 'views/admin/login.php', - 'type' => 'views', - ), - ); - - foreach ($default_files as $file) - { - // check if there's a template in app, and if so, use that - if (is_file(APPPATH.'views/'.static::$view_subdir.$file['source'])) - { - Generate::create(APPPATH.$file['location'], file_get_contents(APPPATH.'views/'.static::$view_subdir.$file['source']), $file['type']); - } - else - { - Generate::create(APPPATH.$file['location'], file_get_contents(\Package::exists('oil').'views/'.static::$view_subdir.$file['source']), $file['type']); - } - } - - parent::forge($args, $subfolder); - } -} - -/* End of file oil/classes/generate/admin.php */ diff --git a/fuel/packages/oil/classes/generate/migration/actions.php b/fuel/packages/oil/classes/generate/migration/actions.php deleted file mode 100755 index afaa66b..0000000 --- a/fuel/packages/oil/classes/generate/migration/actions.php +++ /dev/null @@ -1,434 +0,0 @@ - $idxval); - } - else - { - $tidx[$idxval['name']][(int)$idxval['order']] = $idxval; - } - } - - $up .= PHP_EOL; - foreach ($tidx as $name => $idx) - { - $field = array(); - foreach ($idx as $fidx) - { - $fidx['column'] = \DB::quote_identifier($fidx['column']); - if ( ! $fidx['ascending']) - { - $fidx['column'] .= ' DESC'; - } - $field[] = $fidx['column']; - } - $unique = reset($idx); - $unique = $unique['unique'] ? ' UNIQUE' : ''; - $field = implode(', ', $field); - $up .= PHP_EOL."\t\t\\DB::query('CREATE{$unique} INDEX {$name} ON {$table_prefix}{$subjects[1]}({$field})')->execute();"; - $down .= PHP_EOL."\t\t\\DB::query('DROP INDEX {$name} ON {$table_prefix}{$subjects[1]}')->execute();"; - } - $down = ltrim($down, PHP_EOL).PHP_EOL.PHP_EOL; - } - - $down .= << \''.$subjects[0].'\', ', str_replace($subjects[0], $subjects[1], $field_up_str)); - $field_up_str = str_replace('array(', 'array(\'name\' => \''.$subjects[1].'\', ', $field_up_str); - - $up = << $field) - { - // storage for the translated field options - $field_opts = array(); - - // loop over the field options - foreach($field as $option => $val) - { - // deal with index data first - if ($option == 'indexes') - { - foreach ($val as $validx) - { - // deal with primary indexes - if ($validx['primary']) - { - $pks[] = $validx; - } - - // secondary index - else - { - $idx[] = $validx; - } - } - continue; - } - - // skip option data from describe not supported by DBUtil::create_table() - if (in_array($option, array('indexes', 'key', 'max', 'min', 'name', 'type', 'ordinal_position', 'display', 'comment', 'privileges', 'collation_name', 'options', 'character_maximum_length', 'numeric_precision', 'numeric_scale', 'exact'))) - { - continue; - } - - // skip empty constraints - if ($option == 'constraint' and empty($val)) - { - continue; - } - - // rename options if need be - if ($option == 'data_type') - { - $option = 'type'; - } - if ($option == 'extra') - { - if ($val != 'auto_increment') - { - continue; - } - $option = 'auto_increment'; - $val = true; - } - - - // create the options based on the value type - if ($val === true) - { - $field_opts[] = "'$option' => true"; - } - elseif ($val === false) - { - $field_opts[] = "'$option' => false"; - } - elseif (is_null($val)) - { - // skip value - } - elseif (is_int($val)) - { - $field_opts[] = "'$option' => $val"; - } - elseif (is_array($val)) - { - // skip value - } - else - { - $field_opts[] = "'$option' => '$val'"; - } - } - $field_opts = implode(', ', $field_opts); - - $field_up_str .= "\t\t\t'$name' => array({$field_opts}),".PHP_EOL; - $fields_down[] = "\t\t\t'$name'".PHP_EOL; - } - - $field_up_str = rtrim($field_up_str, PHP_EOL); - $field_down_str = rtrim(implode(',', $fields_down), PHP_EOL); - - return array($field_up_str, $field_down_str, $pks, $idx); - } -} diff --git a/fuel/packages/oil/classes/generate/scaffold.php b/fuel/packages/oil/classes/generate/scaffold.php deleted file mode 100755 index 7258a18..0000000 --- a/fuel/packages/oil/classes/generate/scaffold.php +++ /dev/null @@ -1,232 +0,0 @@ - \Str::lower($matches[1]), - 'type' => isset($matches[2]) ? $matches[2] : 'string', - 'constraint' => isset($matches[4]) ? $matches[4] : null, - ); - } - - // argument is an array with a column definition - elseif (is_array($arg)) - { - $data['fields'][] = array( - 'name' => $arg['name'], - 'type' => $arg['type'], - 'constraint' => $arg['constraint'], - ); - } - - // huh? - else - { - // skip it - logger(\Fuel::L_DEBUG, 'Generate_Scaffold::forge(): incorrect argument type passed'); - } - } - - $name = array_shift($args); - - // Replace / with _ and classify the rest. DO NOT singularize - $controller_name = \Inflector::classify(static::$controller_prefix.str_replace(DS, '_', $name), false); - - // Replace / with _ and classify the rest. Singularize - $model_name = \Inflector::classify(static::$model_prefix.str_replace(DS, '_', $name), ! \Cli::option('singular')); - - // Either foo or folder/foo - $controller_path = str_replace( - array('_', '-'), - DS, - \Str::lower($controller_name) - ); - - // uri's and view paths have forward slashes, DS is a backslash on Windows - $uri = $view_path = str_replace(DS, '/', $controller_path); - - // Models are always singular, tough! - $model_path = str_replace( - array('_', '-'), - DS, - \Str::lower($model_name) - ); - - $data['include_timestamps'] = ( ! \Cli::option('no-timestamp', false)); - - // If a folder is used, the entity is the last part - $name_parts = explode(DS, $name); - $data['singular_name'] = \Cli::option('singular') ? end($name_parts) : \Inflector::singularize(end($name_parts)); - $data['plural_name'] = \Cli::option('singular') ? $data['singular_name'] : \Inflector::pluralize($data['singular_name']); - - $data['table'] = \Inflector::tableize($model_name); - $data['controller_parent'] = static::$controller_parent; - - /** Generate the Migration **/ - $migration_args = $args; - - // add timestamps to the table if needded - if ($data['include_timestamps']) - { - if (\Cli::option('mysql-timestamp', false)) - { - $migration_args[] = 'created_at:date:null[1]'; - $migration_args[] = 'updated_at:date:null[1]'; - } - else - { - $migration_args[] = 'created_at:int:null[1]'; - $migration_args[] = 'updated_at:int:null[1]'; - } - } - $migration_name = \Cli::option('singular') ? \Str::lower($name) : \Inflector::pluralize(\Str::lower($name)); - array_unshift($migration_args, 'create_'.$migration_name); - Generate::migration($migration_args, false); - - // Merge some other data in - $data = array_merge(compact(array('controller_name', 'model_name', 'model_path', 'view_path', 'uri')), $data); - - /** Generate the Model **/ - $model = \View::forge(static::$view_subdir.$subfolder.'/model', $data); - - Generate::create( - APPPATH.'classes/model/'.$model_path.'.php', - $model, - 'model' - ); - - /** Generate the Controller **/ - $controller = \View::forge(static::$view_subdir.$subfolder.'/controller', $data); - - $controller->actions = array( - array( - 'name' => 'index', - 'params' => '', - 'code' => \View::forge(static::$view_subdir.$subfolder.'/actions/index', $data), - ), - array( - 'name' => 'view', - 'params' => '$id = null', - 'code' => \View::forge(static::$view_subdir.$subfolder.'/actions/view', $data), - ), - array( - 'name' => 'create', - 'params' => '', - 'code' => \View::forge(static::$view_subdir.$subfolder.'/actions/create', $data), - ), - array( - 'name' => 'edit', - 'params' => '$id = null', - 'code' => \View::forge(static::$view_subdir.$subfolder.'/actions/edit', $data), - ), - array( - 'name' => 'delete', - 'params' => '$id = null', - 'code' => \View::forge(static::$view_subdir.$subfolder.'/actions/delete', $data), - ), - ); - - Generate::create( - APPPATH.'classes'.DS.'controller'.DS.$controller_path.'.php', - $controller, - 'controller' - ); - - // do we want csrf protection in our forms? - $data['csrf'] = \Cli::option('csrf') ? true : false; - - // Create each of the views - foreach (array('index', 'view', 'create', 'edit', '_form') as $view) - { - Generate::create( - APPPATH.'views'.DS.$controller_path.DS.$view.'.php', - \View::forge(static::$view_subdir.$subfolder.'/views/actions/'.$view, $data), - 'view' - ); - } - - // If not generating admin files, add the default template if it doesnt exist - if (static::$view_subdir != 'admin/' and ! is_file($app_template = APPPATH.'views/template.php')) - { - // check if there's a template in app, and if so, use that - if (is_file(APPPATH.'views/'.static::$view_subdir.$subfolder.'/views/template.php')) - { - Generate::create($app_template, file_get_contents(APPPATH.'views/'.static::$view_subdir.$subfolder.'/views/template.php'), 'view'); - } - else - { - Generate::create($app_template, file_get_contents(\Package::exists('oil').'views/'.static::$view_subdir.'template.php'), 'view'); - } - } - - Generate::build(); - } - -} - -/* End of file oil/classes/scaffold.php */ diff --git a/fuel/packages/oil/classes/package.php b/fuel/packages/oil/classes/package.php deleted file mode 100755 index b1f2c2e..0000000 --- a/fuel/packages/oil/classes/package.php +++ /dev/null @@ -1,221 +0,0 @@ - - -Description: - Packages containing extra functionality can be downloaded (or git cloned) simply with - the following commands. - -Runtime options: - --direct # Download direct from ZIP even if Git is installed - -Examples: - php oil package install - php oil package uninstall - -Documentation: - http://fuelphp.com/docs/packages/oil/package.html -HELP; - \Cli::write($output); - - } - - private static function _use_git() - { - exec('which git', $output); - - // If this is a valid path to git, use it instead of just "git" - if (file_exists($line = trim(current($output)))) - { - static::$git = $line; - } - - unset($output); - - // Double check git is installed (windows will fail step 1) - exec(static::$git . ' --version', $output); - - preg_match('#^(git version)#', current($output), $matches); - - // If we have a match, use Git! - return ! empty($matches[0]); - } - - private static function _download_package_zip($zip_url, $package, $version) - { - \Cli::write('Downloading package: ' . $zip_url); - - // Make the folder so we can extract the ZIP to it - mkdir($tmp_folder = APPPATH . 'tmp' . DS . $package . '-' . time()); - - $zip_file = $tmp_folder . '.zip'; - @copy($zip_url, $zip_file); - - if (is_file($zip_file)) - { - $unzip = new \Unzip; - $files = $unzip->extract($zip_file, $tmp_folder); - - // Grab the first folder out of it (we dont know what it's called) - foreach($pkgfolders = new \GlobIterator($tmp_folder.DS.'*') as $pkgfolder) - { - if ($pkgfolder->isDir()) - { - $tmp_package_folder = $tmp_folder.DS.$pkgfolder->getFilename(); - break; - } - } - - if (empty($tmp_package_folder)) - { - throw new \FuelException('The package zip file doesn\'t contain any install directory.'); - } - - $package_folder = PKGPATH . $package; - - // Move that folder into the packages folder - rename($tmp_package_folder, $package_folder); - - unlink($zip_file); - rmdir($tmp_folder); - - foreach ($files as $file) - { - $path = str_replace($tmp_package_folder, $package_folder, $file); - chmod($path, octdec(755)); - \Cli::write("\t" . $path); - } - } - else - { - \Cli::write('Package could not be found', 'red'); - } - } - - public static function _clone_package_repo($source, $package, $version) - { - $repo_url = 'git://' . rtrim($source, '/').'/'.$package . '.git'; - - \Cli::write('Downloading package: ' . $repo_url); - - $package_folder = PKGPATH . $package; - - // Clone to the package path - passthru(static::$git . ' clone ' . $repo_url . ' ' . $package_folder); - - passthru(static::$git .' add ' . $package_folder . '/'); - - \Cli::write(''); - } -} - -/* End of file package.php */ diff --git a/fuel/packages/oil/classes/refine.php b/fuel/packages/oil/classes/refine.php deleted file mode 100755 index d26d97f..0000000 --- a/fuel/packages/oil/classes/refine.php +++ /dev/null @@ -1,213 +0,0 @@ -add_path($path, -1); - } - catch (\FuelException $e) - { - throw new Exception(sprintf('Module "%s" does not exist.', $module)); - } - } - - // Just call and run() or did they have a specific method in mind? - list($task, $method) = array_pad(explode(':', $task), 2, 'run'); - - // Find the task - if ( ! $file = \Finder::search('tasks', $task)) - { - $files = \Finder::instance()->list_files('tasks'); - $possibilities = array(); - foreach($files as $file) - { - $possible_task = pathinfo($file, \PATHINFO_FILENAME); - $difference = levenshtein($possible_task, $task); - $possibilities[$difference] = $possible_task; - } - - ksort($possibilities); - - if ($possibilities and current($possibilities) <= 5) - { - throw new Exception(sprintf('Task "%s" does not exist. Did you mean "%s"?', $task, current($possibilities))); - } - else - { - throw new Exception(sprintf('Task "%s" does not exist.', $task)); - } - - return; - } - - require_once $file; - - $task = '\\Fuel\\Tasks\\'.ucfirst($task); - - $new_task = new $task; - - // The help option has been called, so call help instead - if ((\Cli::option('help') or $method == 'help') and is_callable(array($new_task, 'help'))) - { - $method = 'help'; - } - else - { - // if the task has an init method, call it now - is_callable($task.'::_init') and $task::_init(); - } - - if (is_callable(array($new_task, $method))) - { - if ($return = call_fuel_func_array(array($new_task, $method), $args)) - { - \Cli::write($return); - } - } - else - { - \Cli::write(sprintf('Task "%s" does not have a command called "%s".', $task, $method)); - - \Cli::write("\nDid you mean:\n"); - $reflect = new \ReflectionClass($new_task); - - // Ensure we only pull out the public methods - $methods = $reflect->getMethods(\ReflectionMethod::IS_PUBLIC); - if (count($methods) > 0) - { - foreach ($methods as $method) - { - if (strpos($method->name, '_') !== 0) - { - \Cli::write(sprintf("php oil [r|refine] %s:%s", $reflect->getShortName(), $method->name)); - - } - } - } - } - } - - public static function help() - { - // Build a list of possible tasks for the help output - $tasks = self::_discover_tasks(); - if (count($tasks) > 0) - { - $output_available_tasks = ""; - - foreach ($tasks as $task => $options) - { - foreach ($options as $option) - { - $option = ($option == "run") ? "" : ":$option"; - $output_available_tasks .= " php oil refine $task$option\n"; - } - } - } - - else - { - $output_available_tasks = " (none found)"; - } - - $output = << - -Description: - Tasks are classes that can be run through the command line or set up as a cron job. - -Available tasks: -$output_available_tasks -Documentation: - http://docs.fuelphp.com/packages/oil/refine.html -HELP; - \Cli::write($output); - - } - - /** - * Find all of the task classes in the system and use reflection to discover the - * commands we can call. - * - * @return array $taskname => array($taskmethods) - **/ - protected static function _discover_tasks() - { - $result = array(); - $files = \Finder::instance()->list_files('tasks'); - - if (count($files) > 0) - { - foreach ($files as $file) - { - $task_name = str_replace('.php', '', basename($file)); - $class_name = '\\Fuel\\Tasks\\'.$task_name; - - require $file; - - $reflect = new \ReflectionClass($class_name); - - // Ensure we only pull out the public methods - $methods = $reflect->getMethods(\ReflectionMethod::IS_PUBLIC); - - $result[$task_name] = array(); - - if (count($methods) > 0) - { - foreach ($methods as $method) - { - strpos($method->name, '_') !== 0 and $result[$task_name][] = $method->name; - } - } - } - } - - return $result; - } -} diff --git a/fuel/packages/oil/composer.json b/fuel/packages/oil/composer.json deleted file mode 100755 index 6c387de..0000000 --- a/fuel/packages/oil/composer.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "fuel/oil", - "description" : "FuelPHP 1.x Oil Package", - "type": "fuel-package", - "homepage": "https://github.com/fuel/oil", - "license": "MIT", - "authors": [ - { - "name": "FuelPHP Development Team", - "email": "team@fuelphp.com" - } - ], - "require": { - "composer/installers": "~1.0" - } -} diff --git a/fuel/packages/oil/config/oil.php b/fuel/packages/oil/config/oil.php deleted file mode 100755 index 6a230f8..0000000 --- a/fuel/packages/oil/config/oil.php +++ /dev/null @@ -1,49 +0,0 @@ - array( - - /** - * These phpunit settings allow oil to run your project's phpunit - * tests. If you've installed phpunit as a global install via - * pear, then the defaults don't need to be changed. But if you've - * installed phpunit via some other method such as Composer, - * you'll need to update these settings to reflect that. - * - * autoload_path - the path to PHPUnit's Autoload.php file. - * binary_path - the full path you'd type into the command line - * to run phpunit from an arbitrary directory. - * - * For example, if you've installed phpunit via Composer, your - * autoload_path will probably be something like: - * 'autoload_path' => VENDORPATH.'phpunit/phpunit/PHPUnit/Autoload.php', - * and your binary path will probably be something like: - * 'binary_path' => VENDORPATH.'bin/phpunit', - * - * At present, there is no support for phpunit.phar. - */ - - 'autoload_path' => 'PHPUnit/Autoload.php' , - 'binary_path' => 'phpunit' , - - ), -); diff --git a/fuel/packages/oil/phpserver.php b/fuel/packages/oil/phpserver.php deleted file mode 100755 index 7c9ed44..0000000 --- a/fuel/packages/oil/phpserver.php +++ /dev/null @@ -1,37 +0,0 @@ - # Name of the database to use - -Commands: - php oil refine fromdb:scaffold - php oil refine fromdb:scaffold --all - php oil refine fromdb:migration - php oil refine fromdb:migration --all - php oil refine fromdb:model - php oil refine fromdb:model --all - php oil refine fromdb:help - -HELP; - \Cli::write($output); - } - - /** - * Generate scaffold for a database table. - * - * Usage (from command line): - * - * php oil refine fromdb:scaffold - */ - public static function scaffold($tables = null) - { - // do we have any tables defined? - if (empty($tables)) - { - // fetch them all if possible - $tables = static::fetch_tables('scaffolding'); - } - else - { - // make sure we have an array to work with - is_array($tables) or $tables = explode(',', $tables); - } - - // check what kind of models we need to generate - $subfolder = \Cli::option('crud') ? 'crud' : 'orm'; - - // generate for each table defined - foreach ($tables as $table) - { - // start with an empty list - \Oil\Generate::$create_files = array(); - - // and generate - if (\Cli::option('admin', \Cli::option('a', false))) - { - call_user_func('\\Oil\\Generate_Admin::forge', static::arguments($table), $subfolder); - } - else - { - call_user_func('\\Oil\\Generate_Scaffold::forge', static::arguments($table), $subfolder); - } - } - } - - /** - * Generate model for a database table. - * - * Usage (from command line): - * - * php oil refine fromdb:model - */ - public static function model($tables = '') - { - // do we have any tables defined? - if (empty($tables)) - { - // fetch them all if possible - $tables = static::fetch_tables('a model'); - } - else - { - // make sure we have an array to work with - is_array($tables) or $tables = explode(',', $tables); - } - - // generate for each table defined - foreach ($tables as $table) - { - // start with an empty list - \Oil\Generate::$create_files = array(); - - // and generate - call_user_func('Oil\Generate::model', static::arguments($table)); - } - } - - /** - * Generate migrations for a database table. - * - * Usage (from command line): - * - * php oil refine fromdb:migration - */ - public static function migration($tables = '') - { - // do we have any tables defined? - if (empty($tables)) - { - // fetch them all if possible - $tables = static::fetch_tables('a model'); - } - else - { - // make sure we have an array to work with - is_array($tables) or $tables = explode(',', $tables); - } - - // generate for each table defined - foreach ($tables as $table) - { - // start with an empty list - \Oil\Generate::$create_files = array(); - - // and generate - call_user_func('Oil\Generate::migration', static::arguments($table, 'migration')); - } - } - - /** - * Construct the list of tables - * - * @param string type of action being called, used to display a customized message - * @return array - */ - protected static function fetch_tables($type) - { - // do we want to generate for all tables? - if ( ! \Cli::option('all', false)) - { - \Cli::write('No table names specified to run '.$type.' on.', 'red'); - exit(); - } - - // get the list of all available tables - try - { - $list = \DB::list_tables(null, \Cli::option('db', null)); - } - catch (\sFuelException $e) - { - \Cli::write('The database driver configured does not support listing tables. Please specify them manually.', 'red'); - exit(); - } - - $prefix = \DB::table_prefix(); - $migration = \Config::get('migrations.table', 'migration'); - - $tables = array(); - - // create the table list - foreach ($list as $table) - { - // strip any defined table prefix from the table name - if ( ! empty($prefix) and strpos($table, $prefix) === 0) - { - $table = substr($table, strlen($prefix)); - } - - // skip the migration table - if ($table !== $migration) - { - $tables[] = $table; - } - } - - return $tables; - } - - /** - * Construct the argument list - * - * @param string $table name of the database table we need to create the list for - * @param string $migration type of file we're generating an arguments list for - * @return array - */ - protected static function arguments($table, $type = 'model') - { - // construct the arguments list, starting with the table name - switch ($type) - { - case 'migration': - $arguments = array('create_'.$table); - break; - - case 'model': - default: - $arguments = array(\Inflector::singularize($table)); - } - - // set some switches - $include_timestamps = false; - $timestamp_is_int = true; - - // get the list of columns from the table - try - { - $columns = \DB::list_columns(trim($table), null, \Cli::option('db', null)); - } - catch (\Exception $e) - { - \Cli::write($e->getMessage(), 'red'); - exit(); - } - - // get the list of indexes from the table - try - { - $indexes = \DB::list_indexes(trim($table), null, \Cli::option('db', null)); - } - catch (\Exception $e) - { - \Cli::write($e->getMessage(), 'red'); - exit(); - } - - // process the columns found - foreach ($columns as $column) - { - // do we have a data_type defined? If not, use the generic type - isset($column['data_type']) or $column['data_type'] = $column['type']; - - // detect timestamp columns - if (in_array($column['name'], array('created_at', 'updated_at'))) - { - $include_timestamps = true; - $timestamp_is_int = $column['data_type'] == 'int'; - continue; - } - - // do we need to add constraints? - $constraint = ''; - foreach (array('length', 'character_maximum_length', 'display') as $idx) - { - // check if we have such a column, and filter out some default values - if (isset($column[$idx]) and ! in_array($column[$idx], array('65535', '4294967295'))) - { - $constraint = $column[$idx]; - break; - } - } - // if it's an enum column, list the available options - if (in_array($column['data_type'], array('set', 'enum'))) - { - $constraint = implode(',', $column['options']); - } - - // store the constraint - $column['constraint'] = $constraint; - - // fetch index information - $column['indexes'] = array(); - foreach ($indexes as $index) - { - // check if we have an index on the current column - if ($column['name'] == $index['column']) - { - // add the index details for this field - $column['indexes'][$index['name']] = $index; - } - } - - // store the column in the argument list - $arguments[$column['name']] = $column; - } - - // tell oil not to fiddle with column information - \Cli::set_option('no-standardisation', true); - - // return the generated argument list - return $arguments; - } -} diff --git a/fuel/packages/oil/views/admin/crud/actions/create.php b/fuel/packages/oil/views/admin/crud/actions/create.php deleted file mode 100755 index 525c457..0000000 --- a/fuel/packages/oil/views/admin/crud/actions/create.php +++ /dev/null @@ -1,30 +0,0 @@ - if (Input::method() == 'POST') - { - $val = Model_::validate('create'); - - if ($val->run()) - { - $ = Model_::forge(array( - - '' => Input::post(''), - - )); - - if ($ and $->save()) - { - Session::set_flash('success', e('Added #'.$->id.'.')); - Response::redirect(''); - } - else - { - Session::set_flash('error', e('Could not save .')); - } - } - else - { - Session::set_flash('error', $val->error()); - } - } - - $this->template->title = ""; - $this->template->content = View::forge('/create'); diff --git a/fuel/packages/oil/views/admin/crud/actions/delete.php b/fuel/packages/oil/views/admin/crud/actions/delete.php deleted file mode 100755 index 2da51bd..0000000 --- a/fuel/packages/oil/views/admin/crud/actions/delete.php +++ /dev/null @@ -1,13 +0,0 @@ - if ($ = Model_::find_one_by_id($id)) - { - $->delete(); - - Session::set_flash('success', e('Deleted #'.$id)); - } - - else - { - Session::set_flash('error', e('Could not delete #'.$id)); - } - - Response::redirect(''); diff --git a/fuel/packages/oil/views/admin/crud/actions/edit.php b/fuel/packages/oil/views/admin/crud/actions/edit.php deleted file mode 100755 index 340e923..0000000 --- a/fuel/packages/oil/views/admin/crud/actions/edit.php +++ /dev/null @@ -1,31 +0,0 @@ - $ = Model_::find_one_by_id($id); - - if (Input::method() == 'POST') - { - $val = Model_::validate('edit'); - - if ($val->run()) - { - - $-> = Input::post(''); - - - if ($->save()) - { - Session::set_flash('success', e('Updated #'.$id)); - Response::redirect(''); - } - else - { - Session::set_flash('error', 'Nothing updated.'); - } - } - else - { - Session::set_flash('error', $val->error()); - } - } - - $this->template->set_global('', $, false); - $this->template->title = ""; - $this->template->content = View::forge('/edit'); diff --git a/fuel/packages/oil/views/admin/crud/actions/index.php b/fuel/packages/oil/views/admin/crud/actions/index.php deleted file mode 100755 index 936746a..0000000 --- a/fuel/packages/oil/views/admin/crud/actions/index.php +++ /dev/null @@ -1,3 +0,0 @@ - $data[''] = Model_::find_all(); - $this->template->title = ""; - $this->template->content = View::forge('/index', $data); diff --git a/fuel/packages/oil/views/admin/crud/actions/view.php b/fuel/packages/oil/views/admin/crud/actions/view.php deleted file mode 100755 index fac6fc1..0000000 --- a/fuel/packages/oil/views/admin/crud/actions/view.php +++ /dev/null @@ -1,4 +0,0 @@ - $data[''] = Model_::find_by_pk($id); - - $this->template->title = ""; - $this->template->content = View::forge('/view', $data); diff --git a/fuel/packages/oil/views/admin/crud/controller.php b/fuel/packages/oil/views/admin/crud/controller.php deleted file mode 100755 index 2b7e9d4..0000000 --- a/fuel/packages/oil/views/admin/crud/controller.php +++ /dev/null @@ -1,13 +0,0 @@ - - -class Controller_ extends -{ - - - public function action_() - { - - } - - -} diff --git a/fuel/packages/oil/views/admin/crud/controllers/admin.php b/fuel/packages/oil/views/admin/crud/controllers/admin.php deleted file mode 100755 index 309fa7d..0000000 --- a/fuel/packages/oil/views/admin/crud/controllers/admin.php +++ /dev/null @@ -1,102 +0,0 @@ -controller !== 'Controller_Admin' or ! in_array(Request::active()->action, array('login', 'logout'))) - { - if (Auth::check()) - { - if ( ! Auth::member(100)) - { - Session::set_flash('error', e('You don\'t have access to the admin panel')); - Response::redirect('/'); - } - } - else - { - Response::redirect('admin/login'); - } - } - } - - public function action_login() - { - // Already logged in - Auth::check() and Response::redirect('admin'); - - $val = Validation::forge(); - - if (Input::method() == 'POST') - { - $val->add('email', 'Email or Username') - ->add_rule('required'); - $val->add('password', 'Password') - ->add_rule('required'); - - if ($val->run()) - { - if ( ! Auth::check()) - { - if (Auth::login(Input::post('email'), Input::post('password'))) - { - // assign the user id that lasted updated this record - foreach (\Auth::verified() as $driver) - { - if (($id = $driver->get_user_id()) !== false) - { - // credentials ok, go right in - $current_user = Model_User::find($id[1]); - Session::set_flash('success', e('Welcome, '.$current_user->username)); - Response::redirect('admin'); - } - } - } - else - { - $this->template->set_global('login_error', 'Login failed!'); - } - } - else - { - $this->template->set_global('login_error', 'Already logged in!'); - } - } - } - - $this->template->title = 'Login'; - $this->template->content = View::forge('admin/login', array('val' => $val), false); - } - - /** - * The logout action. - * - * @access public - * @return void - */ - public function action_logout() - { - Auth::logout(); - Response::redirect('admin'); - } - - /** - * The index action. - * - * @access public - * @return void - */ - public function action_index() - { - $this->template->title = 'Dashboard'; - $this->template->content = View::forge('admin/dashboard'); - } - -} - -/* End of file app.php */ diff --git a/fuel/packages/oil/views/admin/crud/controllers/base.php b/fuel/packages/oil/views/admin/crud/controllers/base.php deleted file mode 100755 index b4575bb..0000000 --- a/fuel/packages/oil/views/admin/crud/controllers/base.php +++ /dev/null @@ -1,24 +0,0 @@ -current_user = null; - - foreach (\Auth::verified() as $driver) - { - if (($id = $driver->get_user_id()) !== false) - { - $this->current_user = Model_User::find($id[1]); - } - break; - } - - // Set a global variable so views can use it - View::set_global('current_user', $this->current_user); - } - -} diff --git a/fuel/packages/oil/views/admin/crud/model.php b/fuel/packages/oil/views/admin/crud/model.php deleted file mode 100755 index 98bf358..0000000 --- a/fuel/packages/oil/views/admin/crud/model.php +++ /dev/null @@ -1,34 +0,0 @@ - - -class Model_ extends Model_Crud -{ - protected static $_table_name = ''; - - public static function validate($factory) - { - $val = Validation::forge($factory); - - - $val->add_field('', '', ''); - - - return $val; - } -} diff --git a/fuel/packages/oil/views/admin/crud/views/actions/_form.php b/fuel/packages/oil/views/admin/crud/views/actions/_form.php deleted file mode 100755 index 65f6bfa..0000000 --- a/fuel/packages/oil/views/admin/crud/views/actions/_form.php +++ /dev/null @@ -1,30 +0,0 @@ -"form-horizontal")); ?>' ?> - - -
    - -
    - 'control-label')); ?>\n"; ?> - -{$field['name']} : ''), array('class' => 'col-md-8 form-control', 'rows' => 8, 'placeholder'=>'".\Inflector::humanize($field['name'])."')); ?>\n"; - break; - - default: - echo "\t\t\t\t{$field['name']} : ''), array('class' => 'col-md-4 form-control', 'placeholder'=>'".\Inflector::humanize($field['name'])."')); ?>\n"; - -endswitch; ?> - -
    - -
    - - echo Form::submit('submit', 'Save', array('class' => 'btn btn-primary')); '; ?> -
    -
    - - echo Form::hidden(Config::get('security.csrf_token_key'), Security::fetch_token()); '; ?> - - echo Form::close(); '; ?> diff --git a/fuel/packages/oil/views/admin/crud/views/actions/create.php b/fuel/packages/oil/views/admin/crud/views/actions/create.php deleted file mode 100755 index 9f196c6..0000000 --- a/fuel/packages/oil/views/admin/crud/views/actions/create.php +++ /dev/null @@ -1,7 +0,0 @@ -

    New

    -
    - - echo render('/_form'); ?> - - -

    echo Html::anchor('', 'Back'); '; ?>

    diff --git a/fuel/packages/oil/views/admin/crud/views/actions/edit.php b/fuel/packages/oil/views/admin/crud/views/actions/edit.php deleted file mode 100755 index 6ed74ad..0000000 --- a/fuel/packages/oil/views/admin/crud/views/actions/edit.php +++ /dev/null @@ -1,8 +0,0 @@ -

    Editing

    -
    - - echo render('/_form'); ?> -

    - echo Html::anchor('/view/'.$->id, 'View'); '; ?> | - echo Html::anchor('', 'Back'); '; ?> -

    diff --git a/fuel/packages/oil/views/admin/crud/views/actions/index.php b/fuel/packages/oil/views/admin/crud/views/actions/index.php deleted file mode 100755 index b35864b..0000000 --- a/fuel/packages/oil/views/admin/crud/views/actions/index.php +++ /dev/null @@ -1,42 +0,0 @@ -

    Listing

    -
    -"; ?> - - - - - - - - - - - - foreach ($ as $item): '; ?> - - - - - - - -'; ?> - -
    echo $item'.$field['name']; ?>; '; ?> - echo Html::anchor('/view/'.$item->id, 'View'); '; ?> | - echo Html::anchor('/edit/'.$item->id, 'Edit'); '; ?> | - echo Html::anchor('/delete/'.$item->id, 'Delete', array('onclick' => "return confirm('Are you sure?')")); '; ?> - - -
    - -'; ?> - -

    No .

    - -'; ?> -

    - echo Html::anchor('/create', 'Add new ', array('class' => 'btn btn-success')); '; ?> - - -

    diff --git a/fuel/packages/oil/views/admin/crud/views/actions/view.php b/fuel/packages/oil/views/admin/crud/views/actions/view.php deleted file mode 100755 index c4e9030..0000000 --- a/fuel/packages/oil/views/admin/crud/views/actions/view.php +++ /dev/null @@ -1,11 +0,0 @@ -

    Viewing # echo $->id; '; ?>

    - - -

    - : - echo $'.$field['name']; ?>; '; ?> -

    - - - echo Html::anchor('/edit/'.$->id, 'Edit'); '; ?> | - echo Html::anchor('', 'Back'); '; ?> diff --git a/fuel/packages/oil/views/admin/dashboard.php b/fuel/packages/oil/views/admin/dashboard.php deleted file mode 100755 index 8cc6836..0000000 --- a/fuel/packages/oil/views/admin/dashboard.php +++ /dev/null @@ -1,27 +0,0 @@ -
    -

    Welcome!

    -

    This admin panel has been generated by the FuelPHP Framework.

    -

    Read the Docs

    -
    -
    -
    -

    Get Started

    -

    The controller generating this page is found at APPPATH/classes/controller/admin.php.

    -

    This view can be found at APPPATH/views/admin/dashboard.php.

    -

    You can modify these files to get your application started quickly.

    -
    -
    -

    Learn

    -

    The best way to learn FuelPHP is reading through the Documentation.

    -

    Another good resource is the Forums. They are fairly active, and you can usually get a response quickly.

    -
    -
    -

    Contribute

    -

    FuelPHP wouldn't exist without awesome contributions from the community. Use the links below to get contributing.

    - -
    -
    diff --git a/fuel/packages/oil/views/admin/login.php b/fuel/packages/oil/views/admin/login.php deleted file mode 100755 index a56a37c..0000000 --- a/fuel/packages/oil/views/admin/login.php +++ /dev/null @@ -1,37 +0,0 @@ -
    -
    - - - - - - - -
    - - -
    - - 'form-control', 'placeholder' => 'Email or Username', 'autofocus')); ?> - - error('email')): ?> - error('email')->get_message('You must provide a username or email'); ?> - -
    - -
    - - 'form-control', 'placeholder' => 'Password')); ?> - - error('password')): ?> - error('password')->get_message(':label cannot be blank'); ?> - -
    - -
    - 'Login', 'name'=>'submit', 'class' => 'btn btn-lg btn-primary btn-block')); ?> -
    - - -
    -
    diff --git a/fuel/packages/oil/views/admin/orm/actions/create.php b/fuel/packages/oil/views/admin/orm/actions/create.php deleted file mode 100755 index 1b5bf3c..0000000 --- a/fuel/packages/oil/views/admin/orm/actions/create.php +++ /dev/null @@ -1,32 +0,0 @@ - if (Input::method() == 'POST') - { - $val = Model_::validate('create'); - - if ($val->run()) - { - $ = Model_::forge(array( - - '' => Input::post(''), - - )); - - if ($ and $->save()) - { - Session::set_flash('success', e('Added #'.$->id.'.')); - - Response::redirect(''); - } - - else - { - Session::set_flash('error', e('Could not save .')); - } - } - else - { - Session::set_flash('error', $val->error()); - } - } - - $this->template->title = ""; - $this->template->content = View::forge('/create'); diff --git a/fuel/packages/oil/views/admin/orm/actions/delete.php b/fuel/packages/oil/views/admin/orm/actions/delete.php deleted file mode 100755 index 420fd02..0000000 --- a/fuel/packages/oil/views/admin/orm/actions/delete.php +++ /dev/null @@ -1,13 +0,0 @@ - if ($ = Model_::find($id)) - { - $->delete(); - - Session::set_flash('success', e('Deleted #'.$id)); - } - - else - { - Session::set_flash('error', e('Could not delete #'.$id)); - } - - Response::redirect(''); diff --git a/fuel/packages/oil/views/admin/orm/actions/edit.php b/fuel/packages/oil/views/admin/orm/actions/edit.php deleted file mode 100755 index 84220d1..0000000 --- a/fuel/packages/oil/views/admin/orm/actions/edit.php +++ /dev/null @@ -1,38 +0,0 @@ - $ = Model_::find($id); - $val = Model_::validate('edit'); - - if ($val->run()) - { - - $-> = Input::post(''); - - - if ($->save()) - { - Session::set_flash('success', e('Updated #' . $id)); - - Response::redirect(''); - } - - else - { - Session::set_flash('error', e('Could not update #' . $id)); - } - } - - else - { - if (Input::method() == 'POST') - { - - $-> = $val->validated(''); - - - Session::set_flash('error', $val->error()); - } - - $this->template->set_global('', $, false); - } - - $this->template->title = ""; - $this->template->content = View::forge('/edit'); diff --git a/fuel/packages/oil/views/admin/orm/actions/index.php b/fuel/packages/oil/views/admin/orm/actions/index.php deleted file mode 100755 index c2c3d74..0000000 --- a/fuel/packages/oil/views/admin/orm/actions/index.php +++ /dev/null @@ -1,11 +0,0 @@ - $query = Model_::query(); - $pagination = Pagination::forge(array( - 'total_items' => $query->count(), - 'uri_segment' => 'page', - )); - $data[''] = $query->rows_offset($pagination->offset) - ->rows_limit($pagination->per_page) - ->get(); - $this->template->set_global('pagination',$pagination,true); - $this->template->title = ""; - $this->template->content = View::forge('/index', $data); diff --git a/fuel/packages/oil/views/admin/orm/actions/view.php b/fuel/packages/oil/views/admin/orm/actions/view.php deleted file mode 100755 index b44fc84..0000000 --- a/fuel/packages/oil/views/admin/orm/actions/view.php +++ /dev/null @@ -1,4 +0,0 @@ - $data[''] = Model_::find($id); - - $this->template->title = ""; - $this->template->content = View::forge('/view', $data); diff --git a/fuel/packages/oil/views/admin/orm/controller.php b/fuel/packages/oil/views/admin/orm/controller.php deleted file mode 100755 index 2b7e9d4..0000000 --- a/fuel/packages/oil/views/admin/orm/controller.php +++ /dev/null @@ -1,13 +0,0 @@ - - -class Controller_ extends -{ - - - public function action_() - { - - } - - -} diff --git a/fuel/packages/oil/views/admin/orm/controllers/admin.php b/fuel/packages/oil/views/admin/orm/controllers/admin.php deleted file mode 100755 index 4098052..0000000 --- a/fuel/packages/oil/views/admin/orm/controllers/admin.php +++ /dev/null @@ -1,103 +0,0 @@ -controller !== 'Controller_Admin' or ! in_array(Request::active()->action, array('login', 'logout'))) - { - if (Auth::check()) - { - $admin_group_id = Config::get('auth.driver', 'Simpleauth') == 'Ormauth' ? 6 : 100; - if ( ! Auth::member($admin_group_id)) - { - Session::set_flash('error', e('You don\'t have access to the admin panel')); - Response::redirect('/'); - } - } - else - { - Response::redirect('admin/login'); - } - } - } - - public function action_login() - { - // Already logged in - Auth::check() and Response::redirect('admin'); - - $val = Validation::forge(); - - if (Input::method() == 'POST') - { - $val->add('email', 'Email or Username') - ->add_rule('required'); - $val->add('password', 'Password') - ->add_rule('required'); - - if ($val->run()) - { - if ( ! Auth::check()) - { - if (Auth::login(Input::post('email'), Input::post('password'))) - { - // assign the user id that lasted updated this record - foreach (\Auth::verified() as $driver) - { - if (($id = $driver->get_user_id()) !== false) - { - // credentials ok, go right in - $current_user = Model\Auth_User::find($id[1]); - Session::set_flash('success', e('Welcome, '.$current_user->username)); - Response::redirect('admin'); - } - } - } - else - { - $this->template->set_global('login_error', 'Login failed!'); - } - } - else - { - $this->template->set_global('login_error', 'Already logged in!'); - } - } - } - - $this->template->title = 'Login'; - $this->template->content = View::forge('admin/login', array('val' => $val), false); - } - - /** - * The logout action. - * - * @access public - * @return void - */ - public function action_logout() - { - Auth::logout(); - Response::redirect('admin'); - } - - /** - * The index action. - * - * @access public - * @return void - */ - public function action_index() - { - $this->template->title = 'Dashboard'; - $this->template->content = View::forge('admin/dashboard'); - } - -} - -/* End of file admin.php */ diff --git a/fuel/packages/oil/views/admin/orm/controllers/base.php b/fuel/packages/oil/views/admin/orm/controllers/base.php deleted file mode 100755 index 63a3c1e..0000000 --- a/fuel/packages/oil/views/admin/orm/controllers/base.php +++ /dev/null @@ -1,24 +0,0 @@ -current_user = null; - - foreach (\Auth::verified() as $driver) - { - if (($id = $driver->get_user_id()) !== false) - { - $this->current_user = Model\Auth_User::find($id[1]); - } - break; - } - - // Set a global variable so views can use it - View::set_global('current_user', $this->current_user); - } - -} diff --git a/fuel/packages/oil/views/admin/orm/model.php b/fuel/packages/oil/views/admin/orm/model.php deleted file mode 100755 index b4b7073..0000000 --- a/fuel/packages/oil/views/admin/orm/model.php +++ /dev/null @@ -1,57 +0,0 @@ - - -class Model_ extends \Orm\Model -{ - protected static $_properties = array( - 'id', - - '', - - - 'created_at', - 'updated_at', - - ); - - - protected static $_observers = array( - 'Orm\Observer_CreatedAt' => array( - 'events' => array('before_insert'), - 'mysql_timestamp' => false, - ), - 'Orm\Observer_UpdatedAt' => array( - 'events' => array('before_save'), - 'mysql_timestamp' => false, - ), - ); - - - public static function validate($factory) - { - $val = Validation::forge($factory); - - - $val->add_field('', '', ''); - - - return $val; - } - -} diff --git a/fuel/packages/oil/views/admin/orm/views/actions/_form.php b/fuel/packages/oil/views/admin/orm/views/actions/_form.php deleted file mode 100755 index 65f6bfa..0000000 --- a/fuel/packages/oil/views/admin/orm/views/actions/_form.php +++ /dev/null @@ -1,30 +0,0 @@ -"form-horizontal")); ?>' ?> - - -
    - -
    - 'control-label')); ?>\n"; ?> - -{$field['name']} : ''), array('class' => 'col-md-8 form-control', 'rows' => 8, 'placeholder'=>'".\Inflector::humanize($field['name'])."')); ?>\n"; - break; - - default: - echo "\t\t\t\t{$field['name']} : ''), array('class' => 'col-md-4 form-control', 'placeholder'=>'".\Inflector::humanize($field['name'])."')); ?>\n"; - -endswitch; ?> - -
    - -
    - - echo Form::submit('submit', 'Save', array('class' => 'btn btn-primary')); '; ?> -
    -
    - - echo Form::hidden(Config::get('security.csrf_token_key'), Security::fetch_token()); '; ?> - - echo Form::close(); '; ?> diff --git a/fuel/packages/oil/views/admin/orm/views/actions/create.php b/fuel/packages/oil/views/admin/orm/views/actions/create.php deleted file mode 100755 index 9f196c6..0000000 --- a/fuel/packages/oil/views/admin/orm/views/actions/create.php +++ /dev/null @@ -1,7 +0,0 @@ -

    New

    -
    - - echo render('/_form'); ?> - - -

    echo Html::anchor('', 'Back'); '; ?>

    diff --git a/fuel/packages/oil/views/admin/orm/views/actions/edit.php b/fuel/packages/oil/views/admin/orm/views/actions/edit.php deleted file mode 100755 index 6ed74ad..0000000 --- a/fuel/packages/oil/views/admin/orm/views/actions/edit.php +++ /dev/null @@ -1,8 +0,0 @@ -

    Editing

    -
    - - echo render('/_form'); ?> -

    - echo Html::anchor('/view/'.$->id, 'View'); '; ?> | - echo Html::anchor('', 'Back'); '; ?> -

    diff --git a/fuel/packages/oil/views/admin/orm/views/actions/index.php b/fuel/packages/oil/views/admin/orm/views/actions/index.php deleted file mode 100755 index 33825da..0000000 --- a/fuel/packages/oil/views/admin/orm/views/actions/index.php +++ /dev/null @@ -1,43 +0,0 @@ -

    Listing

    -
    -"; ?> - - - - - - - - - - - - foreach ($ as $item): '; ?> - - - - - - - -'; ?> - - -
    echo $item'.$field['name']; ?>; '; ?> - echo Html::anchor('/view/'.$item->id, 'View'); '; ?> | - echo Html::anchor('/edit/'.$item->id, 'Edit'); '; ?> | - echo Html::anchor('/delete/'.$item->id, 'Delete', array('onclick' => "return confirm('Are you sure?')")); '; ?> - - -
    - -'; ?> - -

    No .

    - -'; ?> -

    - echo Html::anchor('/create', 'Add new ', array('class' => 'btn btn-success')); '; ?> - - -

    diff --git a/fuel/packages/oil/views/admin/orm/views/actions/view.php b/fuel/packages/oil/views/admin/orm/views/actions/view.php deleted file mode 100755 index c4e9030..0000000 --- a/fuel/packages/oil/views/admin/orm/views/actions/view.php +++ /dev/null @@ -1,11 +0,0 @@ -

    Viewing # echo $->id; '; ?>

    - - -

    - : - echo $'.$field['name']; ?>; '; ?> -

    - - - echo Html::anchor('/edit/'.$->id, 'Edit'); '; ?> | - echo Html::anchor('', 'Back'); '; ?> diff --git a/fuel/packages/oil/views/admin/template.php b/fuel/packages/oil/views/admin/template.php deleted file mode 100755 index e572213..0000000 --- a/fuel/packages/oil/views/admin/template.php +++ /dev/null @@ -1,99 +0,0 @@ - - - - - <?php echo $title; ?> - - - - - - - - - - - -
    -
    -
    -

    -
    - -
    - -

    -

    ', (array) Session::get_flash('success')); ?> -

    -
    - - -
    - -

    -

    ', (array) Session::get_flash('error')); ?> -

    -
    - -
    -
    - -
    -
    -
    -
    -

    Page rendered in {exec_time}s using {mem_usage}mb of memory.

    -

    - FuelPHP is released under the MIT license.
    - Version: -

    -
    -
    - - diff --git a/fuel/packages/oil/views/scaffolding/crud/actions/create.php b/fuel/packages/oil/views/scaffolding/crud/actions/create.php deleted file mode 100755 index 5211a68..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/actions/create.php +++ /dev/null @@ -1,30 +0,0 @@ - if (Input::method() == 'POST') - { - $val = Model_::validate('create'); - - if ($val->run()) - { - $ = Model_::forge(array( - - '' => Input::post(''), - - )); - - if ($ and $->save()) - { - Session::set_flash('success', 'Added #'.$->id.'.'); - Response::redirect(''); - } - else - { - Session::set_flash('error', 'Could not save .'); - } - } - else - { - Session::set_flash('error', $val->error()); - } - } - - $this->template->title = ""; - $this->template->content = View::forge('/create'); diff --git a/fuel/packages/oil/views/scaffolding/crud/actions/delete.php b/fuel/packages/oil/views/scaffolding/crud/actions/delete.php deleted file mode 100755 index d203cce..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/actions/delete.php +++ /dev/null @@ -1,13 +0,0 @@ - if ($ = Model_::find_one_by_id($id)) - { - $->delete(); - - Session::set_flash('success', 'Deleted #'.$id); - } - - else - { - Session::set_flash('error', 'Could not delete #'.$id); - } - - Response::redirect(''); diff --git a/fuel/packages/oil/views/scaffolding/crud/actions/edit.php b/fuel/packages/oil/views/scaffolding/crud/actions/edit.php deleted file mode 100755 index be2a582..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/actions/edit.php +++ /dev/null @@ -1,33 +0,0 @@ - is_null($id) and Response::redirect(''); - - $ = Model_::find_one_by_id($id); - - if (Input::method() == 'POST') - { - $val = Model_::validate('edit'); - - if ($val->run()) - { - - $-> = Input::post(''); - - - if ($->save()) - { - Session::set_flash('success', 'Updated #'.$id); - Response::redirect(''); - } - else - { - Session::set_flash('error', 'Nothing updated.'); - } - } - else - { - Session::set_flash('error', $val->error()); - } - } - - $this->template->set_global('', $, false); - $this->template->title = ""; - $this->template->content = View::forge('/edit'); diff --git a/fuel/packages/oil/views/scaffolding/crud/actions/index.php b/fuel/packages/oil/views/scaffolding/crud/actions/index.php deleted file mode 100755 index 936746a..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/actions/index.php +++ /dev/null @@ -1,3 +0,0 @@ - $data[''] = Model_::find_all(); - $this->template->title = ""; - $this->template->content = View::forge('/index', $data); diff --git a/fuel/packages/oil/views/scaffolding/crud/actions/view.php b/fuel/packages/oil/views/scaffolding/crud/actions/view.php deleted file mode 100755 index 93d6ad8..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/actions/view.php +++ /dev/null @@ -1,6 +0,0 @@ - is_null($id) and Response::redirect(''); - - $data[''] = Model_::find_by_pk($id); - - $this->template->title = ""; - $this->template->content = View::forge('/view', $data); diff --git a/fuel/packages/oil/views/scaffolding/crud/controller.php b/fuel/packages/oil/views/scaffolding/crud/controller.php deleted file mode 100755 index 786ddcc..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/controller.php +++ /dev/null @@ -1,13 +0,0 @@ - - -class extends -{ - - - public function action_() - { - - } - - -} diff --git a/fuel/packages/oil/views/scaffolding/crud/controllers/admin.php b/fuel/packages/oil/views/scaffolding/crud/controllers/admin.php deleted file mode 100755 index 8a10c23..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/controllers/admin.php +++ /dev/null @@ -1,91 +0,0 @@ -controller !== 'Controller_Admin' or ! in_array(Request::active()->action, array('login', 'logout'))) - { - if (Auth::check()) - { - if ( ! Auth::member(100)) - { - Session::set_flash('error', e('You don\'t have access to the admin panel')); - Response::redirect('/'); - } - } - else - { - Response::redirect('admin/login'); - } - } - } - - public function action_login() - { - // Already logged in - Auth::check() and Response::redirect('admin'); - - $val = Validation::forge(); - - if (Input::method() == 'POST') - { - $val->add('email', 'Email or Username') - ->add_rule('required'); - $val->add('password', 'Password') - ->add_rule('required'); - - if ($val->run()) - { - $auth = Auth::instance(); - - // check the credentials. This assumes that you have the previous table created - if (Auth::check() or $auth->login(Input::post('email'), Input::post('password'))) - { - // credentials ok, go right in - Session::set_flash('notice', 'Welcome, '.$current_user->username); - Response::redirect('admin'); - } - else - { - $this->template->set_global('login_error', 'Fail'); - } - - } - } - - $this->template->title = 'Login'; - $this->template->content = View::forge('admin/login', array('val' => $val)); - } - - /** - * The logout action. - * - * @access public - * @return void - */ - public function action_logout() - { - Auth::logout(); - Response::redirect('admin'); - } - - /** - * The index action. - * - * @access public - * @return void - */ - public function action_index() - { - $this->template->title = 'Dashboard'; - $this->template->content = View::forge('admin/dashboard'); - } - -} - -/* End of file app.php */ diff --git a/fuel/packages/oil/views/scaffolding/crud/controllers/base.php b/fuel/packages/oil/views/scaffolding/crud/controllers/base.php deleted file mode 100755 index eb5b76a..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/controllers/base.php +++ /dev/null @@ -1,16 +0,0 @@ -current_user = Auth::check() ? Model_User::find_one_by_username(Auth::get_screen_name()) : null; - - // Set a global variable so views can use it - View::set_global('current_user', $this->current_user); - } - -} diff --git a/fuel/packages/oil/views/scaffolding/crud/model.php b/fuel/packages/oil/views/scaffolding/crud/model.php deleted file mode 100755 index 2471835..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/model.php +++ /dev/null @@ -1,35 +0,0 @@ - - -class Model_ extends Model_Crud -{ - protected static $_table_name = ''; - - public static function validate($factory) - { - $val = Validation::forge($factory); - - - $val->add_field('', '', ''); - - - return $val; - } - -} diff --git a/fuel/packages/oil/views/scaffolding/crud/views/actions/_form.php b/fuel/packages/oil/views/scaffolding/crud/views/actions/_form.php deleted file mode 100755 index 65f6bfa..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/views/actions/_form.php +++ /dev/null @@ -1,30 +0,0 @@ -"form-horizontal")); ?>' ?> - - -
    - -
    - 'control-label')); ?>\n"; ?> - -{$field['name']} : ''), array('class' => 'col-md-8 form-control', 'rows' => 8, 'placeholder'=>'".\Inflector::humanize($field['name'])."')); ?>\n"; - break; - - default: - echo "\t\t\t\t{$field['name']} : ''), array('class' => 'col-md-4 form-control', 'placeholder'=>'".\Inflector::humanize($field['name'])."')); ?>\n"; - -endswitch; ?> - -
    - -
    - - echo Form::submit('submit', 'Save', array('class' => 'btn btn-primary')); '; ?> -
    -
    - - echo Form::hidden(Config::get('security.csrf_token_key'), Security::fetch_token()); '; ?> - - echo Form::close(); '; ?> diff --git a/fuel/packages/oil/views/scaffolding/crud/views/actions/create.php b/fuel/packages/oil/views/scaffolding/crud/views/actions/create.php deleted file mode 100755 index 9f196c6..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/views/actions/create.php +++ /dev/null @@ -1,7 +0,0 @@ -

    New

    -
    - - echo render('/_form'); ?> - - -

    echo Html::anchor('', 'Back'); '; ?>

    diff --git a/fuel/packages/oil/views/scaffolding/crud/views/actions/edit.php b/fuel/packages/oil/views/scaffolding/crud/views/actions/edit.php deleted file mode 100755 index 6ed74ad..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/views/actions/edit.php +++ /dev/null @@ -1,8 +0,0 @@ -

    Editing

    -
    - - echo render('/_form'); ?> -

    - echo Html::anchor('/view/'.$->id, 'View'); '; ?> | - echo Html::anchor('', 'Back'); '; ?> -

    diff --git a/fuel/packages/oil/views/scaffolding/crud/views/actions/index.php b/fuel/packages/oil/views/scaffolding/crud/views/actions/index.php deleted file mode 100755 index b35864b..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/views/actions/index.php +++ /dev/null @@ -1,42 +0,0 @@ -

    Listing

    -
    -"; ?> - - - - - - - - - - - - foreach ($ as $item): '; ?> - - - - - - - -'; ?> - -
    echo $item'.$field['name']; ?>; '; ?> - echo Html::anchor('/view/'.$item->id, 'View'); '; ?> | - echo Html::anchor('/edit/'.$item->id, 'Edit'); '; ?> | - echo Html::anchor('/delete/'.$item->id, 'Delete', array('onclick' => "return confirm('Are you sure?')")); '; ?> - - -
    - -'; ?> - -

    No .

    - -'; ?> -

    - echo Html::anchor('/create', 'Add new ', array('class' => 'btn btn-success')); '; ?> - - -

    diff --git a/fuel/packages/oil/views/scaffolding/crud/views/actions/view.php b/fuel/packages/oil/views/scaffolding/crud/views/actions/view.php deleted file mode 100755 index c4e9030..0000000 --- a/fuel/packages/oil/views/scaffolding/crud/views/actions/view.php +++ /dev/null @@ -1,11 +0,0 @@ -

    Viewing # echo $->id; '; ?>

    - - -

    - : - echo $'.$field['name']; ?>; '; ?> -

    - - - echo Html::anchor('/edit/'.$->id, 'Edit'); '; ?> | - echo Html::anchor('', 'Back'); '; ?> diff --git a/fuel/packages/oil/views/scaffolding/orm/actions/create.php b/fuel/packages/oil/views/scaffolding/orm/actions/create.php deleted file mode 100755 index ee67f8c..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/actions/create.php +++ /dev/null @@ -1,32 +0,0 @@ - if (Input::method() == 'POST') - { - $val = Model_::validate('create'); - - if ($val->run()) - { - $ = Model_::forge(array( - - '' => Input::post(''), - - )); - - if ($ and $->save()) - { - Session::set_flash('success', 'Added #'.$->id.'.'); - - Response::redirect(''); - } - - else - { - Session::set_flash('error', 'Could not save .'); - } - } - else - { - Session::set_flash('error', $val->error()); - } - } - - $this->template->title = ""; - $this->template->content = View::forge('/create'); diff --git a/fuel/packages/oil/views/scaffolding/orm/actions/delete.php b/fuel/packages/oil/views/scaffolding/orm/actions/delete.php deleted file mode 100755 index 05b3171..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/actions/delete.php +++ /dev/null @@ -1,15 +0,0 @@ - is_null($id) and Response::redirect(''); - - if ($ = Model_::find($id)) - { - $->delete(); - - Session::set_flash('success', 'Deleted #'.$id); - } - - else - { - Session::set_flash('error', 'Could not delete #'.$id); - } - - Response::redirect(''); diff --git a/fuel/packages/oil/views/scaffolding/orm/actions/edit.php b/fuel/packages/oil/views/scaffolding/orm/actions/edit.php deleted file mode 100755 index 508b4ed..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/actions/edit.php +++ /dev/null @@ -1,45 +0,0 @@ - is_null($id) and Response::redirect(''); - - if ( ! $ = Model_::find($id)) - { - Session::set_flash('error', 'Could not find #'.$id); - Response::redirect(''); - } - - $val = Model_::validate('edit'); - - if ($val->run()) - { - - $-> = Input::post(''); - - - if ($->save()) - { - Session::set_flash('success', 'Updated #' . $id); - - Response::redirect(''); - } - - else - { - Session::set_flash('error', 'Could not update #' . $id); - } - } - - else - { - if (Input::method() == 'POST') - { - - $-> = $val->validated(''); - - - Session::set_flash('error', $val->error()); - } - - $this->template->set_global('', $, false); - } - - $this->template->title = ""; - $this->template->content = View::forge('/edit'); diff --git a/fuel/packages/oil/views/scaffolding/orm/actions/index.php b/fuel/packages/oil/views/scaffolding/orm/actions/index.php deleted file mode 100755 index 0942362..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/actions/index.php +++ /dev/null @@ -1,3 +0,0 @@ - $data[''] = Model_::find('all'); - $this->template->title = ""; - $this->template->content = View::forge('/index', $data); diff --git a/fuel/packages/oil/views/scaffolding/orm/actions/view.php b/fuel/packages/oil/views/scaffolding/orm/actions/view.php deleted file mode 100755 index c58675a..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/actions/view.php +++ /dev/null @@ -1,10 +0,0 @@ - is_null($id) and Response::redirect(''); - - if ( ! $data[''] = Model_::find($id)) - { - Session::set_flash('error', 'Could not find #'.$id); - Response::redirect(''); - } - - $this->template->title = ""; - $this->template->content = View::forge('/view', $data); diff --git a/fuel/packages/oil/views/scaffolding/orm/controller.php b/fuel/packages/oil/views/scaffolding/orm/controller.php deleted file mode 100755 index 786ddcc..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/controller.php +++ /dev/null @@ -1,13 +0,0 @@ - - -class extends -{ - - - public function action_() - { - - } - - -} diff --git a/fuel/packages/oil/views/scaffolding/orm/model.php b/fuel/packages/oil/views/scaffolding/orm/model.php deleted file mode 100755 index 97a7f5a..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/model.php +++ /dev/null @@ -1,59 +0,0 @@ - - -use Orm\Model; - -class Model_ extends Model -{ - protected static $_properties = array( - 'id', - - '', - - - 'created_at', - 'updated_at', - - ); - - - protected static $_observers = array( - 'Orm\Observer_CreatedAt' => array( - 'events' => array('before_insert'), - 'mysql_timestamp' => false, - ), - 'Orm\Observer_UpdatedAt' => array( - 'events' => array('before_save'), - 'mysql_timestamp' => false, - ), - ); - - - public static function validate($factory) - { - $val = Validation::forge($factory); - - - $val->add_field('', '', ''); - - - return $val; - } - -} diff --git a/fuel/packages/oil/views/scaffolding/orm/views/actions/_form.php b/fuel/packages/oil/views/scaffolding/orm/views/actions/_form.php deleted file mode 100755 index 65f6bfa..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/views/actions/_form.php +++ /dev/null @@ -1,30 +0,0 @@ -"form-horizontal")); ?>' ?> - - -
    - -
    - 'control-label')); ?>\n"; ?> - -{$field['name']} : ''), array('class' => 'col-md-8 form-control', 'rows' => 8, 'placeholder'=>'".\Inflector::humanize($field['name'])."')); ?>\n"; - break; - - default: - echo "\t\t\t\t{$field['name']} : ''), array('class' => 'col-md-4 form-control', 'placeholder'=>'".\Inflector::humanize($field['name'])."')); ?>\n"; - -endswitch; ?> - -
    - -
    - - echo Form::submit('submit', 'Save', array('class' => 'btn btn-primary')); '; ?> -
    -
    - - echo Form::hidden(Config::get('security.csrf_token_key'), Security::fetch_token()); '; ?> - - echo Form::close(); '; ?> diff --git a/fuel/packages/oil/views/scaffolding/orm/views/actions/create.php b/fuel/packages/oil/views/scaffolding/orm/views/actions/create.php deleted file mode 100755 index fa4a4a0..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/views/actions/create.php +++ /dev/null @@ -1,7 +0,0 @@ -

    New

    -
    - - echo render('/_form'); ?> - - -

    echo Html::anchor('', 'Back'); '; ?>

    diff --git a/fuel/packages/oil/views/scaffolding/orm/views/actions/edit.php b/fuel/packages/oil/views/scaffolding/orm/views/actions/edit.php deleted file mode 100755 index 491686d..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/views/actions/edit.php +++ /dev/null @@ -1,8 +0,0 @@ -

    Editing

    -
    - - echo render('/_form'); ?> -

    - echo Html::anchor('/view/'.$->id, 'View'); '; ?> | - echo Html::anchor('', 'Back'); '; ?> -

    diff --git a/fuel/packages/oil/views/scaffolding/orm/views/actions/index.php b/fuel/packages/oil/views/scaffolding/orm/views/actions/index.php deleted file mode 100755 index 3bcb9e7..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/views/actions/index.php +++ /dev/null @@ -1,45 +0,0 @@ -

    Listing

    -
    -"; ?> - - - - - - - - - - - - foreach ($ as $item): '; ?> - - - - - - - -'; ?> - -
     
    echo $item'.$field['name']; ?>; '; ?> -
    -
    - echo Html::anchor('/view/'.$item->id, ' View', array('class' => 'btn btn-default btn-sm')); '; ?> - echo Html::anchor('/edit/'.$item->id, ' Edit', array('class' => 'btn btn-default btn-sm')); '; ?> - echo Html::anchor('/delete/'.$item->id, ' Delete', array('class' => 'btn btn-sm btn-danger', 'onclick' => "return confirm('Are you sure?')")); '; ?> -
    -
    - -
    - -'; ?> - -

    No .

    - -'; ?> -

    - echo Html::anchor('/create', 'Add new ', array('class' => 'btn btn-success')); '; ?> - - -

    diff --git a/fuel/packages/oil/views/scaffolding/orm/views/actions/view.php b/fuel/packages/oil/views/scaffolding/orm/views/actions/view.php deleted file mode 100755 index ab45a50..0000000 --- a/fuel/packages/oil/views/scaffolding/orm/views/actions/view.php +++ /dev/null @@ -1,11 +0,0 @@ -

    Viewing # echo $->id; '; ?>

    - - -

    - : - echo $'.$field['name']; ?>; '; ?> -

    - - - echo Html::anchor('/edit/'.$->id, 'Edit'); '; ?> | - echo Html::anchor('', 'Back'); '; ?> diff --git a/fuel/packages/oil/views/scaffolding/template.php b/fuel/packages/oil/views/scaffolding/template.php deleted file mode 100755 index bb80831..0000000 --- a/fuel/packages/oil/views/scaffolding/template.php +++ /dev/null @@ -1,45 +0,0 @@ - - - - - <?php echo $title; ?> - - - - -
    -
    -

    -
    - -
    - Success -

    -

    ', e((array) Session::get_flash('success'))); ?> -

    -
    - - -
    - Error -

    -

    ', e((array) Session::get_flash('error'))); ?> -

    -
    - -
    -
    - -
    -
    -

    Page rendered in {exec_time}s using {mem_usage}mb of memory.

    -

    - FuelPHP is released under the MIT license.
    - Version: -

    -
    -
    - - diff --git a/fuel/packages/orm/.gitignore b/fuel/packages/orm/.gitignore deleted file mode 100755 index b5bf08f..0000000 --- a/fuel/packages/orm/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -*~ -*.bak -Thumbs.db -desktop.ini -.DS_Store -.buildpath -.project -.settings -fuel/app/logs/*/*/* -fuel/app/cache/*/* -nbproject/ -.idea \ No newline at end of file diff --git a/fuel/packages/orm/bootstrap.php b/fuel/packages/orm/bootstrap.php deleted file mode 100755 index a4ef6bb..0000000 --- a/fuel/packages/orm/bootstrap.php +++ /dev/null @@ -1,47 +0,0 @@ - __DIR__.'/classes/model.php', - 'Orm\\Query' => __DIR__.'/classes/query.php', - 'Orm\\BelongsTo' => __DIR__.'/classes/belongsto.php', - 'Orm\\HasMany' => __DIR__.'/classes/hasmany.php', - 'Orm\\HasOne' => __DIR__.'/classes/hasone.php', - 'Orm\\ManyMany' => __DIR__.'/classes/manymany.php', - 'Orm\\Relation' => __DIR__.'/classes/relation.php', - - //Speclised models - 'Orm\\Model_Soft' => __DIR__.'/classes/model/soft.php', - 'Orm\\Query_Soft' => __DIR__.'/classes/query/soft.php', - 'Orm\\Model_Temporal' => __DIR__.'/classes/model/temporal.php', - 'Orm\\Query_Temporal' => __DIR__.'/classes/query/temporal.php', - 'Orm\\Model_Nestedset' => __DIR__.'/classes/model/nestedset.php', - - // Observers - 'Orm\\Observer' => __DIR__.'/classes/observer.php', - 'Orm\\Observer_CreatedAt' => __DIR__.'/classes/observer/createdat.php', - 'Orm\\Observer_Typing' => __DIR__.'/classes/observer/typing.php', - 'Orm\\Observer_UpdatedAt' => __DIR__.'/classes/observer/updatedat.php', - 'Orm\\Observer_Validation' => __DIR__.'/classes/observer/validation.php', - 'Orm\\Observer_Self' => __DIR__.'/classes/observer/self.php', - 'Orm\\Observer_Slug' => __DIR__.'/classes/observer/slug.php', - - // Exceptions - 'Orm\\RecordNotFound' => __DIR__.'/classes/model.php', - 'Orm\\FrozenObject' => __DIR__.'/classes/model.php', - 'Orm\\InvalidContentType' => __DIR__.'/classes/observer/typing.php', - 'Orm\\ValidationFailed' => __DIR__.'/classes/observer/validation.php', - 'Orm\\RelationNotSoft' => __DIR__.'/classes/model/soft.php', -)); - -// Ensure the orm's config is loaded for Temporal -\Config::load('orm', true); diff --git a/fuel/packages/orm/classes/belongsto.php b/fuel/packages/orm/classes/belongsto.php deleted file mode 100755 index 71ecc9e..0000000 --- a/fuel/packages/orm/classes/belongsto.php +++ /dev/null @@ -1,226 +0,0 @@ -name = $name; - $this->model_from = $from; - $this->model_to = array_key_exists('model_to', $config) - ? $config['model_to'] : \Inflector::get_namespace($from).'Model_'.\Inflector::classify($name); - $this->key_from = array_key_exists('key_from', $config) - ? (array) $config['key_from'] : (array) \Inflector::foreign_key($this->model_to); - $this->key_to = array_key_exists('key_to', $config) - ? (array) $config['key_to'] : $this->key_to; - $this->conditions = array_key_exists('conditions', $config) - ? (array) $config['conditions'] : array(); - - $this->cascade_save = array_key_exists('cascade_save', $config) - ? $config['cascade_save'] : $this->cascade_save; - $this->cascade_delete = array_key_exists('cascade_delete', $config) - ? $config['cascade_delete'] : $this->cascade_delete; - - if ( ! class_exists($this->model_to)) - { - throw new \FuelException('Related model not found by Belongs_To relation "'.$this->name.'": '.$this->model_to); - } - $this->model_to = get_real_class($this->model_to); - } - - public function get(Model $from, array $conditions = array()) - { - $query = call_user_func(array($this->model_to, 'query')); - reset($this->key_to); - foreach ($this->key_from as $key) - { - // no point running a query when a key value is null - if ($from->{$key} === null) - { - return null; - } - $query->where(current($this->key_to), $from->{$key}); - next($this->key_to); - } - - $conditions = \Arr::merge($this->conditions, $conditions); - $query->_parse_where_array(\Arr::get($conditions, 'where', array())); - - return $query->get_one(); - } - - public function join($alias_from, $rel_name, $alias_to_nr, $conditions = array()) - { - $alias_to = 't'.$alias_to_nr; - $model = array( - 'model' => $this->model_to, - 'connection' => call_user_func(array($this->model_to, 'connection')), - 'table' => array(call_user_func(array($this->model_to, 'table')), $alias_to), - 'primary_key' => call_user_func(array($this->model_to, 'primary_key')), - 'join_type' => \Arr::get($conditions, 'join_type') ?: \Arr::get($this->conditions, 'join_type', 'left'), - 'join_on' => array(), - 'columns' => $this->select($alias_to), - 'rel_name' => strpos($rel_name, '.') ? substr($rel_name, strrpos($rel_name, '.') + 1) : $rel_name, - 'relation' => $this, - 'where' => \Arr::get($conditions, 'where', array()), - 'order_by' => \Arr::get($conditions, 'order_by') ?: \Arr::get($this->conditions, 'order_by', array()), - ); - - reset($this->key_to); - foreach ($this->key_from as $key) - { - $model['join_on'][] = array($alias_from.'.'.$key, '=', $alias_to.'.'.current($this->key_to)); - next($this->key_to); - } - foreach (array(\Arr::get($this->conditions, 'where', array()), \Arr::get($conditions, 'join_on', array())) as $c) - { - foreach ($c as $key => $condition) - { - ! is_array($condition) and $condition = array($key, '=', $condition); - if ( ! $condition[0] instanceof \Fuel\Core\Database_Expression and strpos($condition[0], '.') === false) - { - $condition[0] = $alias_to.'.'.$condition[0]; - } - if (count($condition) == 2) // From Query::_where() - { - $condition = array($condition[0], '=', $condition[1]); - } - is_string($condition[2]) and $condition[2] = \Db::quote($condition[2], $model['connection']); - - $model['join_on'][] = $condition; - } - } - - return array($rel_name => $model); - } - - public function save($model_from, $model_to, $original_model_id, $parent_saved, $cascade) - { - if ($parent_saved) - { - return; - } - - if ( ! $model_to instanceof $this->model_to and $model_to !== null) - { - throw new \FuelException('Invalid Model instance added to relations in this model.'); - } - - // Save if it's a yet unsaved object - if ($model_to and $model_to->is_new()) - { - $model_to->save(false); - } - - $current_model_id = $model_to ? $model_to->implode_pk($model_to) : null; - - // Check if there was another model assigned (this supersedes any change to the foreign key(s)) - if ($current_model_id != $original_model_id) - { - // change the foreign keys in the model_from to point to the new relation - reset($this->key_from); - $model_from->unfreeze(); - foreach ($this->key_to as $pk) - { - $model_from->{current($this->key_from)} = $model_to ? $model_to->{$pk} : null; - next($this->key_from); - } - $model_from->freeze(); - } - - // if not check the model_from's foreign_keys against the model_to's primary keys - // because that is how the model stores them - elseif ($current_model_id != null) - { - $foreign_keys = count($this->key_to) == 1 ? array($original_model_id) : explode('][', substr($original_model_id, 1, -1)); - $changed = false; - $new_rel_id = array(); - reset($foreign_keys); - $m = $this->model_to; - foreach ($m::primary_key() as $pk) - { - if (is_null($model_to->{$pk})) - { - $changed = true; - $new_rel_id = null; - break; - } - elseif ($model_to->{$pk} != current($foreign_keys)) - { - $changed = true; - } - $new_rel_id[] = $model_to->{$pk}; - next($foreign_keys); - } - - // if any of the keys changed, reload the relationship - saving the object will save those keys - if ($changed) - { - // Attempt to load the new related object - if ( ! is_null($new_rel_id)) - { - $rel_obj = call_user_func(array($this->model_to, 'find'), $new_rel_id); - if (empty($rel_obj)) - { - throw new \FuelException('New relation set on '.$this->model_from.' object wasn\'t found.'); - } - } - else - { - $rel_obj = null; - } - - // Add the new relation to the model_from - $model_from->unfreeze(); - $rel = $model_from->_relate(); - $rel[$this->name] = $rel_obj; - $model_from->_relate($rel); - $model_from->freeze(); - } - } - - $cascade = is_null($cascade) ? $this->cascade_save : (bool) $cascade; - if ($cascade and ! empty($model_to)) - { - $model_to->save(); - } - } - - public function delete($model_from, $model_to, $parent_deleted, $cascade) - { - if ( ! $parent_deleted) - { - return; - } - - // break current relations - $model_from->unfreeze(); - $rels = $model_from->_relate(); - $rels[$this->name] = null; - $model_from->_relate($rels); - $model_from->freeze(); - - $cascade = is_null($cascade) ? $this->cascade_delete : (bool) $cascade; - if ($cascade and ! empty($model_to)) - { - $model_to->delete(); - } - } -} diff --git a/fuel/packages/orm/classes/hasmany.php b/fuel/packages/orm/classes/hasmany.php deleted file mode 100755 index a3a560a..0000000 --- a/fuel/packages/orm/classes/hasmany.php +++ /dev/null @@ -1,270 +0,0 @@ -name = $name; - $this->model_from = $from; - $this->model_to = array_key_exists('model_to', $config) - ? $config['model_to'] : \Inflector::get_namespace($from).'Model_'.\Inflector::classify($name); - $this->key_from = array_key_exists('key_from', $config) - ? (array) $config['key_from'] : $this->key_from; - $this->key_to = array_key_exists('key_to', $config) - ? (array) $config['key_to'] : (array) \Inflector::foreign_key($this->model_from); - $this->conditions = array_key_exists('conditions', $config) - ? (array) $config['conditions'] : array(); - - $this->cascade_save = array_key_exists('cascade_save', $config) - ? $config['cascade_save'] : $this->cascade_save; - $this->cascade_delete = array_key_exists('cascade_delete', $config) - ? $config['cascade_delete'] : $this->cascade_delete; - - if ( ! class_exists($this->model_to)) - { - throw new \FuelException('Related model not found by Has_Many relation "'.$this->name.'": '.$this->model_to); - } - $this->model_to = get_real_class($this->model_to); - } - - public function get(Model $from, array $conditions = array()) - { - $query = call_user_func(array($this->model_to, 'query')); - reset($this->key_to); - foreach ($this->key_from as $key) - { - // no point running a query when a key value is null - if ($from->{$key} === null) - { - return array(); - } - $query->where(current($this->key_to), $from->{$key}); - next($this->key_to); - } - - $conditions = \Arr::merge($this->conditions, $conditions); - $query->_parse_where_array(\Arr::get($conditions, 'where', array())); - - foreach (\Arr::get($conditions, 'order_by', array()) as $field => $direction) - { - if (is_numeric($field)) - { - $query->order_by($direction); - } - else - { - $query->order_by($field, $direction); - } - } - - return $query->get(); - } - - public function join($alias_from, $rel_name, $alias_to_nr, $conditions = array()) - { - $alias_to = 't'.$alias_to_nr; - $model = array( - 'model' => $this->model_to, - 'connection' => call_user_func(array($this->model_to, 'connection')), - 'table' => array(call_user_func(array($this->model_to, 'table')), $alias_to), - 'primary_key' => call_user_func(array($this->model_to, 'primary_key')), - 'join_type' => \Arr::get($conditions, 'join_type') ?: \Arr::get($this->conditions, 'join_type', 'left'), - 'join_on' => array(), - 'columns' => $this->select($alias_to), - 'rel_name' => strpos($rel_name, '.') ? substr($rel_name, strrpos($rel_name, '.') + 1) : $rel_name, - 'relation' => $this, - 'where' => \Arr::get($conditions, 'where', array()), - 'order_by' => \Arr::get($conditions, 'order_by') ?: \Arr::get($this->conditions, 'order_by', array()), - ); - - reset($this->key_to); - foreach ($this->key_from as $key) - { - $model['join_on'][] = array($alias_from.'.'.$key, '=', $alias_to.'.'.current($this->key_to)); - next($this->key_to); - } - foreach (array(\Arr::get($this->conditions, 'where', array()), \Arr::get($conditions, 'join_on', array())) as $c) - { - foreach ($c as $key => $condition) - { - ! is_array($condition) and $condition = array($key, '=', $condition); - if ( ! $condition[0] instanceof \Fuel\Core\Database_Expression and strpos($condition[0], '.') === false) - { - $condition[0] = $alias_to.'.'.$condition[0]; - } - if (count($condition) == 2) // From Query::_where() - { - $condition = array($condition[0], '=', $condition[1]); - } - is_string($condition[2]) and $condition[2] = \Db::quote($condition[2], $model['connection']); - - $model['join_on'][] = $condition; - } - } - - return array($rel_name => $model); - } - - public function save($model_from, $models_to, $original_model_ids, $parent_saved, $cascade) - { - if ( ! $parent_saved) - { - return; - } - - if ( ! is_array($models_to) and ($models_to = is_null($models_to) ? array() : $models_to) !== array()) - { - throw new \FuelException('Assigned relationships must be an array or null, given relationship value for '. - $this->name.' is invalid.'); - } - $original_model_ids === null and $original_model_ids = array(); - - foreach ($models_to as $key => $model_to) - { - if ( ! $model_to instanceof $this->model_to) - { - throw new \FuelException('Invalid Model instance added to relations in this model.'); - } - - $current_model_id = ($model_to and ! $model_to->is_new()) ? $model_to->implode_pk($model_to) : null; - - // Check if the model was already assigned - if (($model_to and $model_to->is_new()) or ! in_array($current_model_id, $original_model_ids)) - { - // assign this object to the new objects foreign keys - reset($this->key_to); - $frozen = $model_to->frozen(); // only unfreeze/refreeze when it was frozen - $frozen and $model_to->unfreeze(); - foreach ($this->key_from as $pk) - { - $model_to->{current($this->key_to)} = $model_from->{$pk}; - next($this->key_to); - } - $model_to->is_new() and $model_to->save(false); - $frozen and $model_to->freeze(); - } - // check if the model_to's foreign_keys match the model_from's primary keys - else - { - // unset current model from from array - unset($original_model_ids[array_search($current_model_id, $original_model_ids)]); - - // check if model_to still refers to this model_from - $changed = false; - reset($this->key_to); - foreach ($this->key_from as $pk) - { - if ($model_to->{current($this->key_to)} != $model_from->{$pk}) - { - $changed = true; - } - next($this->key_to); - } - - // if any of the keys changed, the relationship was broken - remove model_to from loaded objects - if ($changed) - { - $model_from->unfreeze(); - $rel = $model_from->_relate(); - unset($rel[$this->name][$key]); - $model_from->_relate($rel); - $model_from->freeze(); - - // cascading this change won't work here, save just the object with cascading switched off - $model_from->save(false); - } - } - - // Fix it if key isn't an imploded PK - if ($key != ($current_model_id = $model_to->implode_pk($model_to))) - { - $model_from->unfreeze(); - $rel = $model_from->_relate(); - if ( ! empty($rel[$this->name][$key]) and $rel[$this->name][$key] === $model_to) - { - unset($rel[$this->name][$key]); - } - $rel[$this->name][$current_model_id] = $model_to; - $model_from->_relate($rel); - $model_from->freeze(); - } - } - - // if any original ids are left over in the array, they're no longer related - break them - foreach ($original_model_ids as $original_model_id) - { - // if still loaded set this object's old relation's foreign keys to null - if ($original_model_id and $obj = call_user_func(array($this->model_to, 'find'), - count($this->key_to) == 1 ? array($original_model_id) : explode('][', substr($original_model_id, 1, -1)))) - { - $frozen = $obj->frozen(); // only unfreeze/refreeze when it was frozen - $frozen and $obj->unfreeze(); - foreach ($this->key_to as $fk) - { - $obj->{$fk} = null; - } - $frozen and $obj->freeze(); - - // cascading this change won't work here, save just the object with cascading switched off - $obj->save(false); - } - } - - $cascade = is_null($cascade) ? $this->cascade_save : (bool) $cascade; - if ($cascade and ! empty($models_to)) - { - foreach ($models_to as $m) - { - $m->save(); - } - } - } - - public function delete($model_from, $models_to, $parent_deleted, $cascade) - { - if ( ! $parent_deleted) - { - return; - } - - // break current relations - $model_from->unfreeze(); - $rels = $model_from->_relate(); - $rels[$this->name] = array(); - $model_from->_relate($rels); - $model_from->freeze(); - - if ( ! empty($models_to)) - { - $cascade = is_null($cascade) ? $this->cascade_delete : (bool) $cascade; - - foreach ($models_to as $m) - { - if ($cascade) - { - $m->delete(); - } - elseif ( ! $m->frozen()) - { - foreach ($this->key_to as $fk) - { - $m->{$fk} = null; - } - $m->is_changed() and $m->save(); - } - } - } - } -} diff --git a/fuel/packages/orm/classes/hasone.php b/fuel/packages/orm/classes/hasone.php deleted file mode 100755 index 14be4ed..0000000 --- a/fuel/packages/orm/classes/hasone.php +++ /dev/null @@ -1,238 +0,0 @@ -name = $name; - $this->model_from = $from; - $this->model_to = array_key_exists('model_to', $config) - ? $config['model_to'] : \Inflector::get_namespace($from).'Model_'.\Inflector::classify($name); - $this->key_from = array_key_exists('key_from', $config) - ? (array) $config['key_from'] : $this->key_from; - $this->key_to = array_key_exists('key_to', $config) - ? (array) $config['key_to'] : (array) \Inflector::foreign_key($this->model_from); - $this->conditions = array_key_exists('conditions', $config) - ? (array) $config['conditions'] : array(); - - $this->cascade_save = array_key_exists('cascade_save', $config) - ? $config['cascade_save'] : $this->cascade_save; - $this->cascade_delete = array_key_exists('cascade_delete', $config) - ? $config['cascade_delete'] : $this->cascade_delete; - - if ( ! class_exists($this->model_to)) - { - throw new \FuelException('Related model not found by Has_One relation "'.$this->name.'": '.$this->model_to); - } - $this->model_to = get_real_class($this->model_to); - } - - public function get(Model $from, array $conditions = array()) - { - $query = call_user_func(array($this->model_to, 'query')); - reset($this->key_to); - foreach ($this->key_from as $key) - { - // no point running a query when a key value is null - if ($from->{$key} === null) - { - return null; - } - $query->where(current($this->key_to), $from->{$key}); - next($this->key_to); - } - - $conditions = \Arr::merge($this->conditions, $conditions); - $query->_parse_where_array(\Arr::get($conditions, 'where', array())); - - return $query->get_one(); - } - - public function join($alias_from, $rel_name, $alias_to_nr, $conditions = array()) - { - $alias_to = 't'.$alias_to_nr; - $model = array( - 'model' => $this->model_to, - 'connection' => call_user_func(array($this->model_to, 'connection')), - 'table' => array(call_user_func(array($this->model_to, 'table')), $alias_to), - 'primary_key' => call_user_func(array($this->model_to, 'primary_key')), - 'join_type' => \Arr::get($conditions, 'join_type') ?: \Arr::get($this->conditions, 'join_type', 'left'), - 'join_on' => array(), - 'columns' => $this->select($alias_to), - 'rel_name' => strpos($rel_name, '.') ? substr($rel_name, strrpos($rel_name, '.') + 1) : $rel_name, - 'relation' => $this, - 'where' => \Arr::get($conditions, 'where', array()), - 'order_by' => \Arr::get($conditions, 'order_by') ?: \Arr::get($this->conditions, 'order_by', array()), - ); - - reset($this->key_to); - foreach ($this->key_from as $key) - { - $model['join_on'][] = array($alias_from.'.'.$key, '=', $alias_to.'.'.current($this->key_to)); - next($this->key_to); - } - foreach (array(\Arr::get($this->conditions, 'where', array()), \Arr::get($conditions, 'join_on', array())) as $c) - { - foreach ($c as $key => $condition) - { - ! is_array($condition) and $condition = array($key, '=', $condition); - if ( ! $condition[0] instanceof \Fuel\Core\Database_Expression and strpos($condition[0], '.') === false) - { - $condition[0] = $alias_to.'.'.$condition[0]; - } - if (count($condition) == 2) // From Query::_where() - { - $condition = array($condition[0], '=', $condition[1]); - } - is_string($condition[2]) and $condition[2] = \Db::quote($condition[2], $model['connection']); - - $model['join_on'][] = $condition; - } - } - - return array($rel_name => $model); - } - - public function save($model_from, $model_to, $original_model_id, $parent_saved, $cascade) - { - if ( ! $parent_saved) - { - return; - } - - if ( ! $model_to instanceof $this->model_to and $model_to !== null) - { - throw new \FuelException('Invalid Model instance added to relations in this model.'); - } - - $current_model_id = ($model_to and ! $model_to->is_new()) ? $model_to->implode_pk($model_to) : null; - // Check if there was another model assigned (this supersedes any change to the foreign key(s)) - if (($model_to and $model_to->is_new()) or $current_model_id != $original_model_id) - { - // assign this object to the new objects foreign keys - if ( ! empty($model_to)) - { - reset($this->key_to); - $frozen = $model_to->frozen(); // only unfreeze/refreeze when it was frozen - $frozen and $model_to->unfreeze(); - foreach ($this->key_from as $pk) - { - $model_to->{current($this->key_to)} = $model_from->{$pk}; - next($this->key_to); - } - $frozen and $model_to->freeze(); - } - - // if still loaded set this object's old relation's foreign keys to null - if ($original_model_id and $obj = call_user_func(array($this->model_to, 'find'), - count($this->key_to) == 1 ? array($original_model_id) : explode('][', substr($original_model_id, 1, -1)))) - { - // check whether the object still refers to this model_from - $changed = false; - reset($this->key_to); - foreach ($this->key_from as $pk) - { - if ($obj->{current($this->key_to)} != $model_from->{$pk}) - { - $changed = true; - } - next($this->key_to); - } - - // when it still refers to this object, reset the foreign key(s) - if ( ! $changed) - { - $frozen = $obj->frozen(); // only unfreeze/refreeze when it was frozen - $frozen and $obj->unfreeze(); - foreach ($this->key_to as $fk) - { - $obj->{$fk} = null; - } - $frozen and $obj->freeze(); - - // cascading this change won't work here, save just the object with cascading switched off - $obj->save(false); - } - } - } - // if not empty check the model_to's foreign_keys, when empty nothing changed - elseif ( ! empty($model_to)) - { - // check if model_to still refers to this model_from - $changed = false; - reset($this->key_to); - foreach ($this->key_from as $pk) - { - if ($model_to->{current($this->key_to)} != $model_from->{$pk}) - { - $changed = true; - } - next($this->key_to); - } - - // if any of the keys changed, the relationship was broken - remove model_to from loaded objects - if ($changed) - { - // Remove the model_to from the relationships of model_from - $model_from->unfreeze(); - $rel = $model_from->_relate(); - $rel[$this->name] = null; - $model_from->_relate($rel); - $model_from->freeze(); - } - } - - $cascade = is_null($cascade) ? $this->cascade_save : (bool) $cascade; - if ($cascade and ! empty($model_to)) - { - $model_to->save(); - } - } - - public function delete($model_from, $model_to, $parent_deleted, $cascade) - { - if ( ! $parent_deleted) - { - return; - } - - // break current relations - $model_from->unfreeze(); - $rels = $model_from->_relate(); - $rels[$this->name] = null; - $model_from->_relate($rels); - $model_from->freeze(); - - if ( ! empty($model_to)) - { - $cascade = is_null($cascade) ? $this->cascade_delete : (bool) $cascade; - - if ($cascade) - { - $model_to->delete(); - } - elseif ( ! $model_to->frozen()) - { - foreach ($this->key_to as $fk) - { - $model_to->{$fk} = null; - } - $model_to->is_changed() and $model_to->save(); - } - } - } -} diff --git a/fuel/packages/orm/classes/manymany.php b/fuel/packages/orm/classes/manymany.php deleted file mode 100755 index 072944f..0000000 --- a/fuel/packages/orm/classes/manymany.php +++ /dev/null @@ -1,384 +0,0 @@ -name = $name; - $this->model_from = $from; - $this->model_to = array_key_exists('model_to', $config) - ? $config['model_to'] : \Inflector::get_namespace($from).'Model_'.\Inflector::classify($name); - $this->key_from = array_key_exists('key_from', $config) - ? (array) $config['key_from'] : $this->key_from; - $this->key_to = array_key_exists('key_to', $config) - ? (array) $config['key_to'] : $this->key_to; - $this->conditions = array_key_exists('conditions', $config) - ? (array) $config['conditions'] : array(); - - if ( ! empty($config['table_through'])) - { - $this->table_through = $config['table_through']; - } - else - { - $table_name = array($this->model_from, $this->model_to); - natcasesort($table_name); - $table_name = array_merge($table_name); - $this->table_through = \Inflector::tableize($table_name[0]).'_'.\Inflector::tableize($table_name[1]); - } - $this->key_through_from = ! empty($config['key_through_from']) - ? (array) $config['key_through_from'] : (array) \Inflector::foreign_key($this->model_from); - $this->key_through_to = ! empty($config['key_through_to']) - ? (array) $config['key_through_to'] : (array) \Inflector::foreign_key($this->model_to); - - $this->cascade_save = array_key_exists('cascade_save', $config) - ? $config['cascade_save'] : $this->cascade_save; - $this->cascade_delete = array_key_exists('cascade_delete', $config) - ? $config['cascade_delete'] : $this->cascade_delete; - - if ( ! class_exists($this->model_to)) - { - throw new \FuelException('Related model not found by Many_Many relation "'.$this->name.'": '.$this->model_to); - } - $this->model_to = get_real_class($this->model_to); - } - - public function get(Model $from, array $conditions = array()) - { - // Create the query on the model_through - $query = call_user_func(array($this->model_to, 'query')); - - // set the model_from's keys as where conditions for the model_through - $join = array( - 'table' => array($this->table_through, 't0_through'), - 'join_type' => null, - 'join_on' => array(), - 'columns' => $this->select_through('t0_through'), - ); - - reset($this->key_from); - foreach ($this->key_through_from as $key) - { - if ($from->{current($this->key_from)} === null) - { - return array(); - } - $query->where('t0_through.'.$key, $from->{current($this->key_from)}); - next($this->key_from); - } - - reset($this->key_to); - foreach ($this->key_through_to as $key) - { - $join['join_on'][] = array('t0_through.'.$key, '=', 't0.'.current($this->key_to)); - next($this->key_to); - } - - $conditions = \Arr::merge($this->conditions, $conditions); - $query->_parse_where_array(\Arr::get($conditions, 'where', array())); - - foreach (\Arr::get($conditions, 'order_by', array()) as $field => $direction) - { - if (strpos($field, '.') !== false) - { - $parts = explode('.', $field); - if ($parts[0] == $join['table'][0]) - { - $parts[0] = $join['table'][1]; - $field = implode('.', $parts); - } - } - - if (is_numeric($field)) - { - $query->order_by($direction); - } - else - { - $query->order_by($field, $direction); - } - } - - $query->_join($join); - - return $query->get(); - } - - public function select_through($table) - { - foreach ($this->key_through_to as $to) - { - $properties[] = $table.'.'.$to; - } - foreach ($this->key_through_from as $from) - { - $properties[] = $table.'.'.$from; - } - - return $properties; - } - - public function join($alias_from, $rel_name, $alias_to_nr, $conditions = array()) - { - $alias_to = 't'.$alias_to_nr; - - $alias_through = array($this->table_through, $alias_to.'_through'); - $alias_to_table = array(call_user_func(array($this->model_to, 'table')), $alias_to); - - $models = array( - $rel_name.'_through' => array( - 'model' => null, - 'connection' => call_user_func(array($this->model_to, 'connection')), - 'table' => $alias_through, - 'primary_key' => null, - 'join_type' => \Arr::get($conditions, 'join_type') ?: \Arr::get($this->conditions, 'join_type', 'left'), - 'join_on' => array(), - 'columns' => $this->select_through($alias_to.'_through'), - 'rel_name' => $this->model_through, - 'relation' => $this, - ), - $rel_name => array( - 'model' => $this->model_to, - 'connection' => call_user_func(array($this->model_to, 'connection')), - 'table' => $alias_to_table, - 'primary_key' => call_user_func(array($this->model_to, 'primary_key')), - 'join_type' => \Arr::get($conditions, 'join_type') ?: \Arr::get($this->conditions, 'join_type', 'left'), - 'join_on' => array(), - 'columns' => $this->select($alias_to), - 'rel_name' => strpos($rel_name, '.') ? substr($rel_name, strrpos($rel_name, '.') + 1) : $rel_name, - 'relation' => $this, - 'where' => \Arr::get($conditions, 'where', array()), - ), - ); - - reset($this->key_from); - foreach ($this->key_through_from as $key) - { - $models[$rel_name.'_through']['join_on'][] = array($alias_from.'.'.current($this->key_from), '=', $alias_to.'_through.'.$key); - next($this->key_from); - } - - reset($this->key_to); - foreach ($this->key_through_to as $key) - { - $models[$rel_name]['join_on'][] = array($alias_to.'_through.'.$key, '=', $alias_to.'.'.current($this->key_to)); - next($this->key_to); - } - - foreach (array(\Arr::get($this->conditions, 'where', array()), \Arr::get($conditions, 'join_on', array())) as $c) - { - foreach ($c as $key => $condition) - { - ! is_array($condition) and $condition = array($key, '=', $condition); - if ( ! $condition[0] instanceof \Fuel\Core\Database_Expression and strpos($condition[0], '.') === false) - { - $condition[0] = $alias_to.'.'.$condition[0]; - } - if (count($condition) == 2) // From Query::_where() - { - $condition = array($condition[0], '=', $condition[1]); - } - is_string($condition[2]) and $condition[2] = \Db::quote($condition[2], $models[$rel_name]['connection']); - - $models[$rel_name]['join_on'][] = $condition; - } - } - - $order_by = \Arr::get($conditions, 'order_by') ?: \Arr::get($this->conditions, 'order_by', array()); - foreach ($order_by as $key => $direction) - { - if ( ! $key instanceof \Fuel\Core\Database_Expression and strpos($key, '.') === false) - { - $key = $alias_to.'.'.$key; - } - else - { - $key = str_replace(array($alias_through[0], $alias_to_table[0]), array($alias_through[1], $alias_to_table[1]), $key); - } - $models[$rel_name]['order_by'][$key] = $direction; - } - - return $models; - } - - public function save($model_from, $models_to, $original_model_ids, $parent_saved, $cascade) - { - if ( ! $parent_saved) - { - return; - } - - if ( ! is_array($models_to) and ($models_to = is_null($models_to) ? array() : $models_to) !== array()) - { - throw new \FuelException('Assigned relationships must be an array or null, given relationship value for '. - $this->name.' is invalid.'); - } - $original_model_ids === null and $original_model_ids = array(); - $del_rels = $original_model_ids; - - foreach ($models_to as $key => $model_to) - { - if ( ! $model_to instanceof $this->model_to) - { - throw new \FuelException('Invalid Model instance added to relations in this model.'); - } - - // Save if it's a yet unsaved object - if ($model_to->is_new()) - { - $model_to->save(false); - } - - $current_model_id = $model_to ? $model_to->implode_pk($model_to) : null; - - // Check if the model was already assigned, if not INSERT relationships: - if ( ! in_array($current_model_id, $original_model_ids)) - { - $ids = array(); - reset($this->key_from); - foreach ($this->key_through_from as $pk) - { - $ids[$pk] = $model_from->{current($this->key_from)}; - next($this->key_from); - } - - reset($this->key_to); - foreach ($this->key_through_to as $pk) - { - $ids[$pk] = $model_to->{current($this->key_to)}; - next($this->key_to); - } - - \DB::insert($this->table_through)->set($ids)->execute(call_user_func(array($model_from, 'connection'), true)); - $original_model_ids[] = $current_model_id; // prevents inserting it a second time - } - else - { - // unset current model from from array of new relations - unset($del_rels[array_search($current_model_id, $original_model_ids)]); - } - - // ensure correct pk assignment - if ($key != $current_model_id) - { - $model_from->unfreeze(); - $rel = $model_from->_relate(); - if ( ! empty($rel[$this->name][$key]) and $rel[$this->name][$key] === $model_to) - { - unset($rel[$this->name][$key]); - } - $rel[$this->name][$current_model_id] = $model_to; - $model_from->_relate($rel); - $model_from->freeze(); - } - } - - // If any ids are left in $del_rels they are no longer assigned, DELETE the relationships: - foreach ($del_rels as $original_model_id) - { - $query = \DB::delete($this->table_through); - - reset($this->key_from); - foreach ($this->key_through_from as $key) - { - $query->where($key, '=', $model_from->{current($this->key_from)}); - next($this->key_from); - } - - $to_keys = count($this->key_to) == 1 ? array($original_model_id) : explode('][', substr($original_model_id, 1, -1)); - reset($to_keys); - foreach ($this->key_through_to as $key) - { - $query->where($key, '=', current($to_keys)); - next($to_keys); - } - - $query->execute(call_user_func(array($model_from, 'connection'), true)); - } - - $cascade = is_null($cascade) ? $this->cascade_save : (bool) $cascade; - if ($cascade and ! empty($models_to)) - { - foreach ($models_to as $m) - { - $m->save(); - } - } - } - - public function delete($model_from, $models_to, $parent_deleted, $cascade) - { - if ( ! $parent_deleted) - { - return; - } - - // Remove relations - $model_from->unfreeze(); - $rels = $model_from->_relate(); - $rels[$this->name] = array(); - $model_from->_relate($rels); - $model_from->freeze(); - - // Delete all relationship entries for the model_from - $this->delete_related($model_from); - - $cascade = is_null($cascade) ? $this->cascade_delete : (bool) $cascade; - if ($cascade and ! empty($models_to)) - { - foreach ($models_to as $m) - { - $m->delete(); - } - } - } - - public function delete_related($model_from) - { - // Delete all relationship entries for the model_from - $query = \DB::delete($this->table_through); - reset($this->key_from); - foreach ($this->key_through_from as $key) - { - $query->where($key, '=', $model_from->{current($this->key_from)}); - next($this->key_from); - } - $query->execute(call_user_func(array($model_from, 'connection'), true)); - } -} diff --git a/fuel/packages/orm/classes/model.php b/fuel/packages/orm/classes/model.php deleted file mode 100755 index fd9752c..0000000 --- a/fuel/packages/orm/classes/model.php +++ /dev/null @@ -1,2517 +0,0 @@ - 'Orm\\BelongsTo', - 'has_one' => 'Orm\\HasOne', - 'has_many' => 'Orm\\HasMany', - 'many_many' => 'Orm\\ManyMany', - ); - - /** - * @var array global array to track circular references in to_array() - */ - protected static $to_array_references = array(); - - /** - * Create a new model instance - */ - public static function forge($data = array(), $new = true, $view = null, $cache = true) - { - return new static($data, $new, $view, $cache); - } - - /** - * Fetch the database connection name to use - * - * @param bool if true return the writeable connection (if set) - * @return null|string - */ - public static function connection($writeable = false) - { - $class = get_called_class(); - - if ($writeable and property_exists($class, '_write_connection') && static::$_write_connection !== null) - { - return static::$_write_connection; - } - - return property_exists($class, '_connection') ? static::$_connection : null; - } - - /** - * Sets the connection to use for this model. - * @param string $connection - */ - public static function set_connection($connection) - { - static::$_connection = $connection; - } - - /** - * Sets the write connection to use for this model. - * @param string $connection - */ - public static function set_write_connection($connection) - { - static::$_write_connection = $connection; - } - - /** - * Get the table name for this class - * - * @return string - */ - public static function table() - { - $class = get_called_class(); - - // Table name unknown - if ( ! array_key_exists($class, static::$_table_names_cached)) - { - // Table name set in Model - if (property_exists($class, '_table_name')) - { - static::$_table_names_cached[$class] = static::$_table_name; - } - else - { - static::$_table_names_cached[$class] = \Inflector::tableize($class); - } - } - - return static::$_table_names_cached[$class]; - } - - /** - * Get a defined condition for this class - * - * @param string type of condition to return - * @return array - */ - public static function condition($type = null) - { - $class = get_called_class(); - - // a specific condition requested? - if (property_exists($class, '_conditions')) - { - if ($type !== null) - { - return isset(static::$_conditions[$type]) ? static::$_conditions[$type] : array(); - } - else - { - return static::$_conditions; - } - } - else - { - return array(); - } - } - - /** - * Attempt to retrieve an earlier loaded object - * - * @param array|Model $obj - * @param null|string $class - * @return Model|false - */ - public static function cached_object($obj, $class = null) - { - $class = $class ?: get_called_class(); - - $id = (is_int($obj) or is_string($obj)) ? (string) $obj : $class::implode_pk($obj); - - $result = ( ! empty(static::$_cached_objects[$class][$id])) ? static::$_cached_objects[$class][$id] : false; - - return $result; - } - - /** - * Flush the object cache - * - * @param null|string|object $class - */ - public static function flush_cache($class = null) - { - // determine what to flush - if (func_num_args() == 0) - { - $class = get_called_class(); - } - elseif (is_object($class)) - { - $class = get_class($class); - } - elseif (is_string($class)) - { - $class = ltrim($class, "\\"); - } - - // flush ... - if (is_null($class)) - { - // the entire cache - static::$_cached_objects = array(); - } - elseif (array_key_exists($class, static::$_cached_objects)) - { - // the requested object cache - unset(static::$_cached_objects[$class]); - } - } - - /** - * Get the primary key(s) of this class - * - * @return array - */ - public static function primary_key() - { - return static::$_primary_key; - } - - /** - * Implode the primary keys within the data into a unique string for the runtime - * - * Note: as explained below, it is not possible to use the output to match an item after runtime - * - The format contains no reference to which value is destined for which key - * - The format does not encode the values - * - * @internal Designed for internal use only - * - * @param array - * @return string - */ - public static function implode_pk($data) - { - if (count(static::$_primary_key) == 1) - { - $p = reset(static::$_primary_key); - return (is_object($data) - ? strval($data->{$p}) - : (isset($data[$p]) - ? strval($data[$p]) - : null)); - } - - $pk = ''; - foreach (static::$_primary_key as $p) - { - if (is_null((is_object($data) ? $data->{$p} : (isset($data[$p]) ? $data[$p] : null)))) - { - return null; - } - $pk .= '['.(is_object($data) ? $data->{$p} : $data[$p]).']'; - } - - return $pk; - } - - /** - * Get the class's properties - * - * @throws \FuelException Listing columns failed - * - * @return array - */ - public static function properties() - { - $class = get_called_class(); - - // If already determined - if (array_key_exists($class, static::$_properties_cached)) - { - return static::$_properties_cached[$class]; - } - - // Try to grab the properties from the class... - if (property_exists($class, '_properties')) - { - $properties = static::$_properties; - foreach ($properties as $key => $p) - { - if (is_string($p)) - { - unset($properties[$key]); - $properties[$p] = array(); - } - } - } - - // ...if the above failed, run DB query to fetch properties - if (empty($properties)) - { - try - { - $properties = \DB::list_columns(static::table(), null, static::connection()); - } - catch (\Exception $e) - { - throw new \FuelException('Listing columns failed, you have to set the model properties with a '. - 'static $_properties setting in the model. Original exception: '.$e->getMessage()); - } - } - - // cache the properties for next usage - static::$_properties_cached[$class] = $properties; - - return static::$_properties_cached[$class]; - } - - /** - * Fetches a property description array, or specific data from it - * - * @param string property or property.key - * @param mixed return value when key not present - * @return mixed - */ - public static function property($key, $default = null) - { - $class = get_called_class(); - - // If already determined - if ( ! array_key_exists($class, static::$_properties_cached)) - { - static::properties(); - } - - return \Arr::get(static::$_properties_cached[$class], $key, $default); - } - - /** - * Fetch the model's views - * - * @throws \InvalidArgumentException Database view is defined without columns - * - * @return array - */ - public static function views() - { - $class = get_called_class(); - - if ( ! isset(static::$_views_cached[$class])) - { - static::$_views_cached[$class] = array(); - if (property_exists($class, '_views')) - { - $views = $class::$_views; - foreach ($views as $k => $v) - { - if ( ! isset($v['columns'])) - { - throw new \InvalidArgumentException('Database view '.$k.' is defined without columns.'); - } - $v['columns'] = (array) $v['columns']; - if ( ! isset($v['view'])) - { - $v['view'] = $k; - } - static::$_views_cached[$class][$k] = $v; - } - } - } - - return static::$_views_cached[$class]; - } - - /** - * Get the class's relations - * - * @param bool $specific - * @return HasOne|HasMany|ManyMany|Belongsto|HasOne[]|HasMany[]|ManyMany[]|Belongsto[] - */ - public static function relations($specific = false) - { - $class = get_called_class(); - - if ( ! array_key_exists($class, static::$_relations_cached)) - { - $relations = array(); - foreach (static::$_valid_relations as $rel_name => $rel_class) - { - if (property_exists($class, '_'.$rel_name)) - { - foreach (static::${'_'.$rel_name} as $key => $settings) - { - $name = is_string($settings) ? $settings : $key; - $settings = is_array($settings) ? $settings : array(); - $relations[$name] = new $rel_class($class, $name, $settings); - } - } - } - - static::$_relations_cached[$class] = $relations; - } - - if ($specific === false) - { - return static::$_relations_cached[$class]; - } - else - { - if ( ! array_key_exists($specific, static::$_relations_cached[$class])) - { - return false; - } - - return static::$_relations_cached[$class][$specific]; - } - } - - /** - * Get the name of the class that defines a relation - * - * @param string - * @return array - */ - public static function related_class($relation) - { - $class = get_called_class(); - - foreach (static::$_valid_relations as $rel_name => $rel_class) - { - if (property_exists($class, '_'.$rel_name)) - { - foreach (static::${'_'.$rel_name} as $key => $value) - { - if (is_string($value)) - { - if ($value === $relation) - { - return \Inflector::classify('model_'.$value); - } - } - else - { - if ($key === $relation) - { - return static::${'_'.$rel_name}[$relation]['model_to']; - } - } - } - } - } - - return null; - } - - /** - * Get the class's observers and what they observe - * - * @param string specific observer to retrieve info of, allows direct param access by using dot notation - * @param mixed default return value when specific key wasn't found - * @return array - */ - public static function observers($specific = null, $default = null) - { - $class = get_called_class(); - - if ( ! array_key_exists($class, static::$_observers_cached)) - { - $observers = array(); - if (property_exists($class, '_observers')) - { - foreach (static::$_observers as $obs_k => $obs_v) - { - if (is_int($obs_k)) - { - $observers[$obs_v] = array(); - } - else - { - if (is_string($obs_v) or (is_array($obs_v) and is_int(key($obs_v)))) - { - // @TODO deprecated until v1.4 - logger(\Fuel::L_WARNING, 'Passing observer events as array is deprecated, they must be - inside another array under a key "events". Check the docs for more info.', __METHOD__); - $observers[$obs_k] = array('events' => (array) $obs_v); - } - else - { - $observers[$obs_k] = $obs_v; - } - } - } - } - static::$_observers_cached[$class] = $observers; - } - - if ($specific) - { - return \Arr::get(static::$_observers_cached[$class], $specific, $default); - } - - return static::$_observers_cached[$class]; - } - - /** - * Register an observer - * - * @param string class name of the observer (including namespace) - * @param mixed observer options - * - * @return void - */ - public static function register_observer($name, $options = array()) - { - $class = get_called_class(); - static::$_observers_cached[$class] = static::observers() + array($name => $options); - } - - /** - * Unregister an observer - * - * @param string class name of the observer (including namespace) - * @return void - */ - public static function unregister_observer($name) - { - $class = get_called_class(); - foreach (static::observers() as $key => $value) - { - if ((is_array($value) and $key == $name) or $value == $name) - { - unset(static::$_observers_cached[$class][$key]); - } - } - } - - /** - * Find one or more entries - * - * @param int|null $id - * @param array $options - * - * @throws \FuelException - * - * @return Model|Model[] - */ - public static function find($id = null, array $options = array()) - { - // deal with null valued PK's - if (is_null($id)) - { - // if no options are present, simply return null. a PK with a null value can exist - return func_num_args() === 2 ? static::query($options) : null; - } - - // Return all that match $options array - elseif ($id === 'all') - { - return static::query($options)->get(); - } - - // Return first or last row that matches $options array - elseif ($id === 'first' or $id === 'last') - { - $query = static::query($options); - - foreach(static::primary_key() as $pk) - { - $query->order_by($pk, $id == 'first' ? 'ASC' : 'DESC'); - } - - return $query->get_one(); - } - - // Return specific request row by ID - else - { - $cache_pk = $where = array(); - $id = (array) $id; - foreach (static::primary_key() as $pk) - { - $where[] = array($pk, '=', current($id)); - $cache_pk[$pk] = current($id); - next($id); - } - - if (array_key_exists(get_called_class(), static::$_cached_objects) - and array_key_exists(static::implode_pk($cache_pk), static::$_cached_objects[get_called_class()]) - and (! isset($options['from_cache']) or $options['from_cache'] == true)) - { - return static::$_cached_objects[get_called_class()][static::implode_pk($cache_pk)]; - } - - array_key_exists('where', $options) and $where = array_merge($options['where'], $where); - $options['where'] = $where; - return static::query($options)->get_one(); - } - } - - /** - * Creates a new query with optional settings up front - * - * @param array - * @return Query - */ - public static function query($options = array()) - { - return Query::forge(get_called_class(), array(static::connection(), static::connection(true)), $options); - } - - /** - * Count entries, optionally only those matching the $options - * - * @param array - * @return int - */ - public static function count(array $options = array()) - { - return static::query($options)->count(); - } - - /** - * Find the maximum - * - * @param mixed - * @param array - * @return bool|int Maximum value or false - */ - public static function max($key = null) - { - return static::query()->max($key ?: static::primary_key()); - } - - /** - * Find the minimum - * - * @param mixed - * @param array - * @return object|array - */ - public static function min($key = null) - { - return static::query()->min($key ?: static::primary_key()); - } - - public static function __callStatic($method, $args) - { - // storage for the type of find query - $find_type = false; - - // Start with count_by? Get counting! - if (strpos($method, 'count_by') === 0) - { - $find_type = 'count'; - $fields = substr($method, 9); - } - - // Otherwise, lets find stuff - elseif (strpos($method, 'find_') === 0) - { - if ($method == 'find_by') - { - $find_type = 'all'; - $fields = array_shift($args); - } - else - { - $find_type = strncmp($method, 'find_all_by_', 12) === 0 ? 'all' : (strncmp($method, 'find_by_', 8) === 0 ? 'first' : false); - $fields = $find_type === 'first' ? substr($method, 8) : substr($method, 12); - } - } - - // bail out if an invalid find type is detected - if ( ! $find_type) - { - throw new \FuelException('Invalid method call. Method '.$method.' does not exist.', 0); - } - - $where = $or_where = array(); - - if (($and_parts = explode('_and_', $fields))) - { - foreach ($and_parts as $and_part) - { - $or_parts = explode('_or_', $and_part); - - if (count($or_parts) == 1) - { - $where[] = array($or_parts[0], array_shift($args)); - } - else - { - foreach($or_parts as $or_part) - { - $or_where[] = array($or_part, array_shift($args)); - } - } - } - } - - $options = count($args) > 0 ? array_pop($args) : array(); - - if ( ! empty($where)) - { - if ( ! array_key_exists('where', $options)) - { - $options['where'] = $where; - } - else - { - $options['where'] = array_merge($where, $options['where']); - } - } - - if ( ! empty($or_where)) - { - if ( ! array_key_exists('or_where', $options)) - { - $options['or_where'] = $or_where; - } - else - { - $options['or_where'] = array_merge($or_where, $options['or_where']); - } - } - - if ($find_type == 'count') - { - return static::count($options); - } - - else - { - return static::find($find_type, $options); - } - - // min_...($options) - // max_...($options) - } - - /* --------------------------------------------------------------------------- - * Object usage - * --------------------------------------------------------------------------- */ - - /** - * @var bool keeps track of whether it's a new object - */ - protected $_is_new = true; - - /** - * @var bool keeps to object frozen - */ - protected $_frozen = false; - - /** - * @var bool $_sanitization_enabled If this is a records data will be sanitized on get - */ - protected $_sanitization_enabled = false; - - /** - * @var array keeps the current state of the object - */ - protected $_data = array(); - - /** - * @var array storage for custom properties on this object - */ - protected $_custom_data = array(); - - /** - * @var array keeps a copy of the object as it was retrieved from the database - */ - protected $_original = array(); - - /** - * @var array - */ - protected $_data_relations = array(); - - /** - * @var array keeps a copy of the relation ids that were originally retrieved from the database - */ - protected $_original_relations = array(); - - /** - * @var array keeps track of relations that need to be reset before saving the new ones - */ - protected $_reset_relations = array(); - - /** - * @var array disabled observer events - */ - protected $_disabled_events = array(); - - /** - * @var string view name when used - */ - protected $_view; - - /** - * Constructor - * - * @param array - * @param bool - */ - public function __construct($data = array(), $new = true, $view = null, $cache = true) - { - // Make sure we get the correct dataformat passed - if ( ! is_array($data) and ! $data instanceOf \ArrayAccess) - { - throw new \ErrorException( - 'Argument 1 passed to '.__METHOD__.'() must be of the type array or implement ArrayAccess, '.gettype($data).' given', - 0, E_ERROR, __FILE__, __LINE__-7 // adjust the line to point to the function prototype, not this line! - ); - } - - // This is to deal with PHP's native hydration that happens before constructor is called - // for some weird reason, for example using the DB's as_object() function - if( ! empty($this->_data) or ! empty($this->_custom_data)) - { - // merge the injected data with the passed data - $data = array_merge($this->_custom_data, $this->_data, $data); - - // and reset them - $this->_data = array(); - $this->_custom_data = array(); - - // and mark it as existing data - $new = false; - } - - // move the passed data to the correct container - $properties = $this->properties(); - foreach ($properties as $prop => $settings) - { - // do we have data for this this model property? - if (array_key_exists($prop, $data)) - { - // store it in the data container - $this->_data[$prop] = $data[$prop]; - unset($data[$prop]); - } - - // property not present, do we have a default value? - elseif ($new and array_key_exists('default', $settings)) - { - $this->_data[$prop] = $settings['default']; - } - } - - // store the remainder in the custom data store - $this->_custom_data = $data; - - // store the view, if one was passed - if ($view and array_key_exists($view, $this->views())) - { - $this->_view = $view; - } - - if ($new === false) - { - // update the original datastore and the related datastore - $this->_update_original($this->_data); - - // update the object cache if needed - $cache and static::$_cached_objects[get_class($this)][static::implode_pk($this->_data)] = $this; - - // mark the object as existing - $this->_is_new = false; - - // and fire the after-load observers - $this->observe('after_load'); - } - else - { - // make sure the primary keys are reset - foreach (static::$_primary_key as $pk) - { - $this->_data[$pk] = null; - } - - // new object, fire the after-create observers - $this->observe('after_create'); - } - } - - /** - * Update the original setting for this object - * - * @param array|null $original - */ - public function _update_original($original = null) - { - $original = is_null($original) ? $this->_data : $original; - $this->_original = array_merge($this->_original, $original); - - $this->_update_original_relations(); - } - - /** - * Update the original relations for this object - */ - public function _update_original_relations($relations = null) - { - if (is_null($relations)) - { - $this->_original_relations = array(); - $relations = $this->_data_relations; - } - else - { - foreach ($relations as $key => $rel) - { - // Unload the just fetched relation from the originals - unset($this->_original_relations[$rel]); - - // Unset the numeric key and set the data to update by the relation name - unset($relations[$key]); - $relations[$rel] = $this->_data_relations[$rel]; - } - } - - foreach ($relations as $rel => $data) - { - if (is_array($data)) - { - $this->_original_relations[$rel] = array(); - foreach ($data as $obj) - { - if ($obj and ! $obj->is_new()) - { - $this->_original_relations[$rel][] = $obj->implode_pk($obj); - } - } - } - else - { - $this->_original_relations[$rel] = null; - if ($data and ! $data->is_new()) - { - $this->_original_relations[$rel] = $data->implode_pk($data); - } - } - } - } - - /** - * Fetch or set relations on this object - * To be used only after having fetched them from the database! - * - * @param array|bool|null $rels - * - * @throws \FuelException Invalid input for _relate(), should be an array - * @throws FrozenObject No changes allowed - * - * @return void|array - */ - public function _relate($rels = false) - { - if ($rels === false) - { - return $this->_data_relations; - } - elseif (is_array($rels)) - { - if ($this->_frozen) - { - throw new FrozenObject('No changes allowed.'); - } - $this->_data_relations = $rels; - } - else - { - throw new \FuelException('Invalid input for _relate(), should be an array.'); - } - } - - /** - * Fetch a property or relation - * - * @param string - * @return mixed - */ - public function & __get($property) - { - return $this->get($property); - } - - /** - * Set a property or relation - * - * @param string - * @param mixed - * - * @return Model - */ - public function __set($property, $value) - { - return $this->set($property, $value); - } - - /** - * Check whether a property exists, only return true for table columns, relations, eav and custom data - * - * @param string $property - * @return bool - */ - public function __isset($property) - { - if (array_key_exists($property, $this->_data)) - { - return true; - } - elseif (static::relations($property)) - { - return true; - } - elseif ($this->_get_eav($property, true)) - { - return true; - } - elseif (array_key_exists($property, $this->_custom_data)) - { - return true; - } - - return false; - } - - /** - * Empty a property, relation or custom data - * - * @param string $property - */ - public function __unset($property) - { - if (array_key_exists($property, static::properties())) - { - $this->_data[$property] = null; - } - elseif ($rel = static::relations($property)) - { - $this->_reset_relations[$property] = true; - $this->_data_relations[$property] = $rel->singular ? null : array(); - } - elseif ($this->_get_eav($property, true, true)) - { - // no additional work needed here - } - elseif (array_key_exists($property, $this->_custom_data)) - { - unset($this->_custom_data[$property]); - } - } - - /** - * Allow for getter, setter and unset methods - * - * @param string $method - * @param array $args - * @return mixed - * @throws \BadMethodCallException - */ - public function __call($method, $args) - { - if (substr($method, 0, 4) == 'get_') - { - return $this->get(substr($method, 4)); - } - elseif (substr($method, 0, 4) == 'set_') - { - return $this->set(substr($method, 4), reset($args)); - } - elseif (substr($method, 0, 6) == 'unset_') - { - return $this->__unset(substr($method, 6)); - } - - // Throw an exception - throw new \BadMethodCallException('Call to undefined method '.get_class($this).'::'.$method.'()'); - } - - /** - * Allow object cloning to new object - */ - public function __clone() - { - // Reset primary keys - foreach (static::$_primary_key as $pk) - { - $this->_data[$pk] = null; - } - - // This is a new object - $this->_is_new = true; - $this->_original = array(); - $this->_original_relations = array(); - - // Cleanup relations - foreach ($this->relations() as $name => $rel) - { - // singular relations (hasone, belongsto) can't be copied, neither can HasMany - if ($rel->singular or $rel instanceof HasMany) - { - unset($this->_data_relations[$name]); - } - } - - $this->observe('after_clone'); - } - - /** - * Get - * - * Gets a property or - * relation from the - * object - * - * @access public - * @param string $property - * @param array $conditions - * @return mixed - */ - public function & get($property, array $conditions = array()) - { - // database columns - if (array_key_exists($property, static::properties())) - { - if ( ! array_key_exists($property, $this->_data)) - { - $result = null; - } - elseif ($this->_sanitization_enabled) - { - // use a copy - $result = $this->_data[$property]; - } - else - { - // use a reference - $result =& $this->_data[$property]; - } - } - - // related models - elseif ($rel = static::relations($property)) - { - if ( ! array_key_exists($property, $this->_data_relations)) - { - $this->_data_relations[$property] = $rel->get($this, $conditions); - $this->_update_original_relations(array($property)); - } - - $result =& $this->_data_relations[$property]; - } - - // EAV properties - elseif (($result = $this->_get_eav($property)) !== false) - { - // nothing else to do here - } - - // database view columns - elseif ($this->_view and in_array($property, static::$_views_cached[get_class($this)][$this->_view]['columns'])) - { - if ($this->_sanitization_enabled) - { - // use a copy - $result = $this->_data[$property]; - } - else - { - // use a reference - $result =& $this->_data[$property]; - } - } - - // stored custom data - elseif (array_key_exists($property, $this->_custom_data)) - { - if ($this->_sanitization_enabled) - { - // use a copy - $result = $this->_custom_data[$property]; - } - else - { - // use a reference - $result =& $this->_custom_data[$property]; - } - } - else - { - throw new \OutOfBoundsException('Property "'.$property.'" not found for '.get_class($this).'.'); - } - - // do we need to clean before returning the result? - if ($this->_sanitization_enabled) - { - $result = $this->_sanitize($property, $result); - } - - return $result; - } - - /** - * Set - * - * Sets a property or - * relation of the - * object - * - * @access public - * @param string|array $property - * @param string $value in case $property is a string - * - * @throws \FuelException Primary key on model cannot be changed - * @throws \InvalidArgumentException You need to pass both a property name and a value to set() - * @throws FrozenObject No changes allowed - * - * @return Model - */ - public function set($property, $value = null) - { - if ($this->_frozen) - { - throw new FrozenObject('No changes allowed.'); - } - - if (is_array($property)) - { - foreach ($property as $p => $v) - { - $this->set($p, $v); - } - } - else - { - if (func_num_args() < 2) - { - throw new \InvalidArgumentException('You need to pass both a property name and a value to set().'); - } - - // is it a primary key we're updating? - if (in_array($property, static::primary_key()) and $this->{$property} !== null and $this->{$property} != $value) - { - throw new \FuelException('Primary key on model '.get_class($this).' cannot be changed.'); - } - - // is it a model property we're updating? - if (array_key_exists($property, static::properties())) - { - $this->_data[$property] = $value; - } - - // or perhaps a related model? - elseif ($rel = static::relations($property)) - { - $this->is_fetched($property) or $this->_reset_relations[$property] = true; - if (isset($this->_data_relations[$property]) and ($this->_data_relations[$property] instanceof self) and is_array($value)) - { - $this->_data_relations[$property]->set($value); - } - elseif ($value === null or $value === array()) - { - $this->_reset_relations[$property] = true; - $this->_data_relations[$property] = $rel->singular ? null : array(); - } - else - { - $this->_data_relations[$property] = $value; - } - } - - // none of the above, assume its custom data - elseif ( ! $this->_set_eav($property, $value)) - { - $this->_custom_data[$property] = $value; - } - } - - return $this; - } - - /** - * Save the object and it's relations, create when necessary - * - * @param mixed $cascade - * null = use default config, - * bool = force/prevent cascade, - * array cascades only the relations that are in the array - * - * @return bool - */ - public function save($cascade = null, $use_transaction = false) - { - if ($this->frozen()) - { - return false; - } - - if ($use_transaction) - { - $db = \Database_Connection::instance(static::connection(true)); - $db->start_transaction(); - } - - try - { - $this->observe('before_save'); - - $this->freeze(); - foreach($this->relations() as $rel_name => $rel) - { - if (array_key_exists($rel_name, $this->_reset_relations)) - { - if (method_exists($rel, 'delete_related')) - { - $rel->delete_related($this); - $this->_original_relations[$rel_name] = $rel->singular ? null : array(); - } - else - { - if (empty($this->_original_relations[$rel_name])) - { - $data = $rel->get($this); - if (is_array($data)) - { - $this->_original_relations[$rel_name] = array(); - foreach ($data as $obj) - { - $this->_original_relations[$rel_name][] = $obj ? $obj->implode_pk($obj) : null; - } - } - else - { - $this->_original_relations[$rel_name] = $data ? $data->implode_pk($data) : null; - } - } - } - unset($this->_reset_relations[$rel_name]); - } - if (array_key_exists($rel_name, $this->_data_relations)) - { - $rel->save($this, $this->{$rel_name}, - array_key_exists($rel_name, $this->_original_relations) ? $this->_original_relations[$rel_name] : null, - false, is_array($cascade) ? in_array($rel_name, $cascade) : $cascade - ); - } - } - $this->unfreeze(); - - // Insert or update - $return = $this->_is_new ? $this->create() : $this->update(); - - $this->freeze(); - foreach($this->relations() as $rel_name => $rel) - { - if (array_key_exists($rel_name, $this->_data_relations)) - { - $rel->save($this, $this->{$rel_name}, - array_key_exists($rel_name, $this->_original_relations) ? $this->_original_relations[$rel_name] : null, - true, is_array($cascade) ? in_array($rel_name, $cascade) : $cascade - ); - } - } - $this->unfreeze(); - - // update the original datastore and the related datastore - $this->_update_original(); - - $this->observe('after_save'); - - $use_transaction and $db->commit_transaction(); - } - catch (\Exception $e) - { - $use_transaction and $db->rollback_transaction(); - throw $e; - } - - return $return; - } - - /** - * Save using INSERT - */ - protected function create() - { - // Only allow creation with new object, otherwise: clone first, create later - if ( ! $this->is_new()) - { - return false; - } - - $this->observe('before_insert'); - - // Set all current values - $query = Query::forge(get_called_class(), static::connection(true)); - $primary_key = static::primary_key(); - $properties = array_keys(static::properties()); - foreach ($properties as $p) - { - if ( ! (in_array($p, $primary_key) and is_null($this->{$p}))) - { - $query->set($p, $this->{$p}); - } - } - - // Insert! - $id = $query->insert(); - - // when there's one PK it might be auto-incremented, get it and set it - if (count($primary_key) == 1 and $id !== false) - { - $pk = reset($primary_key); - // only set it if it hasn't been set manually - is_null($this->{$pk}) and $this->{$pk} = $id; - } - - // update the original properties on creation and cache object for future retrieval in this request - $this->_is_new = false; - - $this->_original = $this->_data; - static::$_cached_objects[get_class($this)][static::implode_pk($this)] = $this; - - $this->observe('after_insert'); - - return $id !== false; - } - - /** - * Save using UPDATE - */ - protected function update() - { - // New objects can't be updated, neither can frozen - if ($this->is_new()) - { - return false; - } - - // Non changed objects don't have to be saved, but return true anyway (no reason to fail) - if ( ! $this->is_changed(array_keys(static::properties()))) - { - return true; - } - - $this->observe('before_update'); - - // Create the query and limit to primary key(s) - $query = Query::forge(get_called_class(), static::connection(true)); - $primary_key = static::primary_key(); - $properties = static::properties(); - $properties_keys = array_keys($properties); - //Add the primary keys to the where - $this->add_primary_keys_to_where($query); - - // Set all current values - foreach ($properties_keys as $p) - { - if ( ! in_array($p, $primary_key) ) - { - if (array_key_exists($p, $this->_original)) - { - if ((array_key_exists('type', $properties[$p]) and $properties[$p]['type'] == 'int') or - (array_key_exists('data_type', $properties[$p]) and $properties[$p]['data_type'] == 'int')) - { - if ($this->{$p} != $this->_original[$p]) - { - $query->set($p, isset($this->_data[$p]) ? $this->_data[$p] : null); - } - } - elseif ($this->{$p} !== $this->_original[$p]) - { - $query->set($p, isset($this->_data[$p]) ? $this->_data[$p] : null); - } - } - else - { - array_key_exists($p, $this->_data) and $query->set($p, $this->_data[$p]); - } - } - } - - // Return false when update fails - if ( ! $query->update()) - { - return false; - } - - $this->_original = $this->_data; - static::$_cached_objects[get_class($this)][static::implode_pk($this)] = $this; - - // update the original property on success - $this->observe('after_update'); - - return true; - } - - /** - * Adds the primary keys in where clauses to the given query. - * - * @param Query $query - */ - protected function add_primary_keys_to_where($query) - { - $primary_key = static::primary_key(); - foreach ($primary_key as $pk) - { - $query->where($pk, '=', $this->_original[$pk]); - } - } - - /** - * Delete current object - * - * @param mixed $cascade - * null = use default config, - * bool = force/prevent cascade, - * array cascades only the relations that are in the array - * @param bool $use_transaction - * - * @throws \Exception - * - * @return Model this instance as a new object without primary key(s) - */ - public function delete($cascade = null, $use_transaction = false) - { - // New objects can't be deleted, neither can frozen - if ($this->is_new() or $this->frozen()) - { - return false; - } - - if ($use_transaction) - { - $db = \Database_Connection::instance(static::connection(true)); - $db->start_transaction(); - } - - try - { - $this->observe('before_delete'); - - $this->freeze(); - foreach($this->relations() as $rel_name => $rel) - { - $should_cascade = is_array($cascade) ? in_array($rel_name, $cascade) : $rel->cascade_delete; - - // Give model subclasses a chance to chip in. - if ($should_cascade && ! $this->should_cascade_delete($rel)) - { - // The function returned false so something does not want this relation to be cascade deleted - $should_cascade = false; - } - - $rel->delete($this, $this->{$rel_name}, false, $should_cascade); - } - $this->unfreeze(); - - // Delete the model in question - if ( ! $this->delete_self()) - { - return false; - } - - $this->freeze(); - foreach($this->relations() as $rel_name => $rel) - { - $should_cascade = is_array($cascade) ? in_array($rel_name, $cascade) : $rel->cascade_delete; - - // Give model subclasses a chance to chip in. - if ($should_cascade && ! $this->should_cascade_delete($rel)) - { - // The function returned false so something does not want this relation to be cascade deleted - $should_cascade = false; - } - - $rel->delete($this, $this->{$rel_name}, true, $should_cascade); - } - $this->unfreeze(); - - // Perform cleanup: - // remove from internal object cache, remove PK's, set to non saved object, remove db original values - if (array_key_exists(get_called_class(), static::$_cached_objects) - and array_key_exists(static::implode_pk($this), static::$_cached_objects[get_called_class()])) - { - unset(static::$_cached_objects[get_called_class()][static::implode_pk($this)]); - } - foreach ($this->primary_key() as $pk) - { - unset($this->_data[$pk]); - } - // remove original relations too - foreach($this->relations() as $rel_name => $rel) - { - $this->_original_relations[$rel_name] = $rel->singular ? null : array(); - } - - $this->_is_new = true; - $this->_original = array(); - - $this->observe('after_delete'); - - $use_transaction and $db->commit_transaction(); - } - catch (\Exception $e) - { - $use_transaction and $db->rollback_transaction(); - throw $e; - } - - return $this; - } - - /** - * Deletes this model instance from the database. - * - * @return bool - */ - protected function delete_self() - { - // Create the query and limit to primary key(s) - $query = Query::forge(get_called_class(), static::connection(true))->limit(1); - $primary_key = static::primary_key(); - foreach ($primary_key as $pk) - { - $query->where($pk, '=', $this->{$pk}); - } - - // Return success of update operation - return $query->delete(); - } - - /** - * Allows subclasses to more easily define if a relation can be cascade deleted or not. - * - * @param array $rel - * - * @return bool False to stop the relation from being deleted. Works the same as the cascade_delete property - */ - protected function should_cascade_delete($rel) - { - return true; - } - - /** - * Reset values to those gotten from the database - */ - public function reset() - { - foreach ($this->_original as $p => $val) - { - $this->_data[$p] = $val; - } - } - - /** - * Disable an observer event - * - * @param string event to disable - * @return void - */ - public function disable_event($event) - { - $this->_disabled_events[$event] = true; - } - - /** - * Enable a defined observer - * - * @param string class name of the observer (including namespace) - * @param string event to enable, or null for all events - * @return void - */ - public function enable_event($event) - { - unset($this->_disabled_events[$event]); - } - - /** - * Calls all observers for the current event - * - * @param string - */ - public function observe($event) - { - foreach ($this->observers() as $observer => $settings) - { - $events = isset($settings['events']) ? $settings['events'] : array(); - if ((empty($events) or in_array($event, $events)) - and empty($this->_disabled_events[$event])) - { - if ( ! class_exists($observer)) - { - $observer_class = \Inflector::get_namespace($observer).'Observer_'.\Inflector::denamespace($observer); - if ( ! class_exists($observer_class)) - { - throw new \UnexpectedValueException($observer); - } - - // Add the observer with the full classname for next usage - unset(static::$_observers_cached[$observer]); - static::$_observers_cached[$observer_class] = $events; - $observer = $observer_class; - } - - try - { - call_user_func(array($observer, 'orm_notify'), $this, $event); - } - catch (\Exception $e) - { - // Unfreeze before failing - $this->unfreeze(); - - throw $e; - } - } - } - } - - /** - * Compare current state with the retrieved state - * - * @param string|array $property - * - * @throws \OutOfBoundsException - * - * @return bool - */ - public function is_changed($property = null) - { - $properties = static::properties(); - $relations = static::relations(); - $property = (array) $property ?: array_merge(array_keys($properties), array_keys($relations)); - $simple_data_types = array('int','bool'); - - foreach ($property as $p) - { - if (isset($properties[$p])) - { - if (array_key_exists($p, $this->_original)) - { - if ((array_key_exists('type', $properties[$p]) and in_array($properties[$p]['type'], $simple_data_types)) or - (array_key_exists('data_type', $properties[$p]) and in_array($properties[$p]['data_type'], $simple_data_types))) - { - if ($this->{$p} != $this->_original[$p]) - { - return true; - } - } - elseif ($this->{$p} !== $this->_original[$p]) - { - return true; - } - } - else - { - if (array_key_exists($p, $this->_data)) - { - return true; - } - } - } - elseif (isset($relations[$p])) - { - if ($relations[$p]->singular) - { - if (empty($this->_original_relations[$p]) !== empty($this->_data_relations[$p]) - or ( ! empty($this->_original_relations[$p]) - and $this->_original_relations[$p] !== $this->_data_relations[$p]->implode_pk($this->{$p}))) - { - return true; - } - } - else - { - if (empty($this->_original_relations[$p])) - { - if ( ! empty($this->_data_relations[$p])) - { - return true; - } - continue; - } - - $orig_rels = $this->_original_relations[$p]; - foreach ($this->{$p} as $rk => $r) - { - if ( ! in_array($r->implode_pk($r), $orig_rels)) - { - return true; - } - unset($orig_rels[array_search($rk, $orig_rels)]); - } - if ( ! empty($orig_rels)) - { - return true; - } - } - } - else - { - throw new \OutOfBoundsException('Unknown property or relation: '.$p); - } - } - - return false; - } - - /** - * Generates an array with keys new & old that contain ONLY the values that differ between the original and - * the current unsaved model. - * Note: relations are given as single or array of imploded pks - * - * @return array - */ - public function get_diff() - { - $diff = array(0 => array(), 1 => array()); - foreach ($this->_data as $key => $val) - { - if ($this->is_changed($key)) - { - $diff[0][$key] = array_key_exists($key, $this->_original) ? $this->_original[$key] : null; - $diff[1][$key] = $val; - } - } - foreach ($this->_data_relations as $key => $val) - { - $rel = static::relations($key); - if ($rel->singular) - { - $new_pk = empty($val) ? null : $val->implode_pk($val); - if (empty($this->_original_relations[$key]) !== empty($val) - or ( ! empty($this->_original_relations[$key]) and ! empty($val) - and $this->_original_relations[$key] !== $new_pk - )) - { - - $diff[0][$key] = isset($this->_original_relations[$key]) ? $this->_original_relations[$key] : null; - $diff[1][$key] = isset($val) ? $new_pk : null; - } - } - else - { - $original_pks = empty($this->_original_relations[$key]) ? array() : $this->_original_relations[$key]; - $new_pks = array(); - if ($val) - { - foreach ($val as $v) - { - if ( ! in_array(($new_pk = $v->implode_pk($v)), $original_pks)) - { - $new_pks[] = $new_pk; - } - else - { - $original_pks = array_diff($original_pks, array($new_pk)); - } - } - } - if ( ! empty($original_pks) or ! empty($new_pks)) { - $diff[0][$key] = empty($original_pks) ? null : $original_pks; - $diff[1][$key] = empty($new_pks) ? null : $new_pks; - } - } - } - - return $diff; - } - - /*** - * Returns whether the given relation is fetched. If no relation is - * - * @param string $relation Name of relation - * - * @return bool - */ - public function is_fetched($relation) - { - if (static::relations($relation)) - { - return array_key_exists($relation, $this->_data_relations); - } - - return false; - } - - /*** - * Returns whether this is a saved or a new object - * - * @return bool - */ - public function is_new() - { - return $this->_is_new; - } - - /** - * Check whether the object was frozen - * - * @return boolean - */ - public function frozen() - { - return $this->_frozen; - } - - /** - * Freeze the object to disallow changing it or saving it - */ - public function freeze() - { - $this->_frozen = true; - } - - /** - * Unfreeze the object to allow changing it or saving it again - */ - public function unfreeze() - { - $this->_frozen = false; - } - - /** - * Enable sanitization mode in the object - * - * @return $this - */ - public function sanitize() - { - $this->_sanitization_enabled = true; - - return $this; - } - - /** - * Disable sanitization mode in the object - * - * @return $this - */ - public function unsanitize() - { - $this->_sanitization_enabled = false; - - return $this; - } - - /** - * Returns the current sanitization state of the object - * - * @return bool - */ - public function sanitized() - { - return $this->_sanitization_enabled; - } - - /** - * Sanitizatize a data value - * - * @param string $field Name of the property that is being sanitized - * @param mixed $value Value to sanitize - * - * @return mixed - */ - protected function _sanitize($field, $value) - { - return \Security::clean($value, null, 'security.output_filter'); - } - - /** - * Method for use with Fieldset::add_model() - * - * @param Fieldset Fieldset instance to add fields to - * @param array|Model Model instance or array for use to repopulate - */ - public static function set_form_fields($form, $instance = null) - { - Observer_Validation::set_fields($instance instanceof static ? $instance : get_called_class(), $form); - $instance and $form->populate($instance, true); - } - - /** - * Allow populating this object from an array, and any related objects - * - * @param array assoc array with named values to store in the object - * - * @return Model this instance as a new object without primary key(s) - */ - public function from_array(array $values) - { - foreach($values as $property => $value) - { - if (array_key_exists($property, static::properties()) and ! in_array($property, static::primary_key())) - { - $this->_data[$property] = $value; - } - elseif (array_key_exists($property, static::relations()) and is_array($value)) - { - $rel = static::relations($property); - if ( ! isset($this->_data_relations[$property])) - { - $this->_data_relations[$property] = $rel->singular ? null : array(); - } - foreach($value as $id => $data) - { - if (is_array($data)) - { - if (array_key_exists($id, $this->_data_relations[$property])) - { - foreach($data as $field => $contents) - { - if ($rel->singular) - { - $this->_data_relations[$property]->{$field} = $contents; - } - else - { - $this->_data_relations[$property][$id]->{$field} = $contents; - } - } - } - else - { - if ($rel->singular) - { - $this->_data_relations[$property] = call_user_func(static::relations($property)->model_to.'::forge', $data); - } - else - { - $this->_data_relations[$property][] = call_user_func(static::relations($property)->model_to.'::forge', $data); - } - } - } - } - } - elseif (property_exists($this, '_eav') and ! empty(static::$_eav)) - { - $this->_set_eav($property, $value); - } - else - { - $this->_custom_data[$property] = $value; - } - } - - return $this; - } - - /** - * Allow converting this object to an array - * - * @param bool $custom - * @param bool $recurse - * @param bool $eav - * - * @internal param \Orm\whether $bool or not to include the custom data array - * - * @return array - */ - public function to_array($custom = false, $recurse = false, $eav = false) - { - // storage for the result - $array = array(); - - // reset the references array on first call - $recurse or static::$to_array_references = array(get_class($this)); - - // make sure all data is scalar or array - if ($custom) - { - foreach ($this->_custom_data as $key => $val) - { - if (is_object($val)) - { - if (method_exists($val, '__toString')) - { - $val = (string) $val; - } - else - { - $val = get_object_vars($val); - } - } - $array[$key] = $val; - } - } - - // make sure all data is scalar or array - foreach ($this->_data as $key => $val) - { - if (is_object($val)) - { - if (method_exists($val, '__toString')) - { - $val = (string) $val; - } - else - { - $val = get_object_vars($val); - } - } - $array[$key] = $val; - } - - // convert relations - foreach ($this->_data_relations as $name => $rel) - { - if (empty($rel)) - { - $array[$name] = null; - } - elseif (is_array($rel)) - { - $array[$name] = array(); - if ( ! in_array(get_class(reset($rel)), static::$to_array_references)) - { - static::$to_array_references[] = get_class(reset($rel)); - foreach ($rel as $id => $r) - { - $array[$name][$id] = $r->to_array($custom, true, $eav); - } - array_pop(static::$to_array_references); - } - } - elseif ( ! in_array(get_class($rel), static::$to_array_references)) - { - static::$to_array_references[] = get_class($rel); - $array[$name] = $rel->to_array($custom, true, $eav); - array_pop(static::$to_array_references); - } - } - - // get eav relations - if ($eav and property_exists(get_called_class(), '_eav')) - { - // loop through the defined EAV containers - foreach (static::$_eav as $rel => $settings) - { - // normalize the container definition, could be string or array - if (is_string($settings)) - { - $rel = $settings; - $settings = array(); - } - - // determine attribute and value column names - $attr = \Arr::get($settings, 'attribute', 'attribute'); - $val = \Arr::get($settings, 'value', 'value'); - - // check if relation is present - if (array_key_exists($rel, $array)) - { - // get eav properties - $container = \Arr::assoc_to_keyval($array[$rel], $attr, $val); - - // merge eav properties to array without overwritting anything - $array = array_merge($container, $array); - - // we don't need this relation anymore - unset($array[$rel]); - } - } - } - - // strip any excluded values from the array - foreach (static::get_to_array_exclude() as $key) - { - if (array_key_exists($key, $array)) - { - unset($array[$key]); - } - } - - return $array; - } - - /** - * Provide the identifying details in the form of an array - * - * @return array - */ - public function get_pk_assoc() - { - $array = array_flip(static::primary_key()); - - foreach ($array as $key => &$value) - { - $value = $this->get($key); - } - - return $array; - } - - /** - * Allow converting this object to a real object - * - * @return object - */ - public function to_object($custom = false, $recurse = false) - { - return (object) $this->to_array($custom, $recurse); - } - - /** - * EAV attribute getter. Also deals with isset() and unset() - * - * @param string $attribute, the attribute value to get - * @param bool $isset, if true, do an exists check instead of returning the value - * @param bool $unset, if true, delete the EAV attribute if it exists - * - * @throws \OutOfBoundsException if the defined EAV relation does not exist or of the wrong type - * - * @return mixed - */ - protected function _get_eav($attribute, $isset = false, $unset = false) - { - // get the current class name - $class = get_called_class(); - - // don't do anything unless we actually have an EAV container - if (property_exists($class, '_eav')) - { - // loop through the defined EAV containers - foreach (static::$_eav as $rel => $settings) - { - // normalize the container definition, could be string or array - if (is_string($settings)) - { - $rel = $settings; - $settings = array(); - } - - // fetch the relation object for this EAV container - if ( ! $rel = static::relations($rel)) - { - throw new \OutOfBoundsException('EAV container defines a relation that does not exist in '.get_class($this).'.'); - } - - // EAV containers must be of the "Many type" - if ($rel instanceOf \Orm\HasOne or $rel instanceOf \Orm\BelongsTo ) - { - throw new \OutOfBoundsException('EAV containers can only be defined on "HasMany" or "ManyMany" relations in '.get_class($this).'.'); - } - - // determine attribute and value column names - $attr = isset($settings['attribute']) ? $settings['attribute'] : 'attribute'; - $val = isset($settings['value']) ? $settings['value'] : 'value'; - - // see if we have a result - if ($result = $this->{$rel->name}) - { - // loop over the resultset - foreach ($result as $key => $record) - { - // check if this is the attribute we need - if ($record->{$attr} === $attribute) - { - if ($unset) - { - // delete the related object if we need to unset - unset($this->{$rel->name}[$key]); - $record->delete(); - return true; - } - else - { - // else return its existence or its value - return $isset ? true : $record->{$val}; - } - } - } - } - } - } - - return false; - } - - /** - * EAV attribute setter - * - * @param string $attribute - * @param string $value - * - * @throws \OutOfBoundsException - * - * @return mixed - */ - protected function _set_eav($attribute, $value) - { - // get the current class name - $class = get_called_class(); - - // don't do anything unless we actually have an EAV container - if (property_exists($class, '_eav')) - { - // loop through the defined EAV containers - foreach (static::$_eav as $rel => $settings) - { - // normalize the container definition, could be string or array - if (is_string($settings)) - { - $rel = $settings; - $settings = array(); - } - - // fetch the relation object for this EAV container - if ( ! $relation = static::relations($rel)) - { - throw new \OutOfBoundsException('EAV container defines a relation that does not exist in '.get_class($this).'.'); - } - - // EAV containers must be of the "Many type" - if ($relation instanceOf \Orm\HasOne or $relation instanceOf \Orm\BelongsTo) - { - throw new \OutOfBoundsException('EAV containers can only be defined on "HasMany" or "ManyMany" relations in '.get_class($this).'.'); - } - - // determine attribute and value column names - $attr = isset($settings['attribute']) ? $settings['attribute'] : 'attribute'; - $val = isset($settings['value']) ? $settings['value'] : 'value'; - - // loop over the resultset - foreach ($this->{$relation->name} as $key => $record) - { - if ($record->{$attr} === $attribute) - { - $record->{$val} = $value; - return true; - } - } - - // not found, we've got outselfs a new attribute, so add it - if ($rel = static::related_class($rel)) - { - $this->{$relation->name}[] = $rel::forge(array( - $attr => $attribute, - $val => $value, - )); - return true; - } - } - } - - return false; - } - - /*************************************************************************** - * Implementation of ArrayAccess - **************************************************************************/ - - public function offsetSet($offset, $value) - { - try - { - $this->__set($offset, $value); - } - catch (\Exception $e) - { - return false; - } - } - - public function offsetExists($offset) - { - return $this->__isset($offset); - } - - public function offsetUnset($offset) - { - $this->__unset($offset); - } - - public function offsetGet($offset) - { - try - { - return $this->__get($offset); - } - catch (\Exception $e) - { - return false; - } - } - - /*************************************************************************** - * Implementation of Iterable - **************************************************************************/ - - protected $_iterable = array(); - - public function rewind() - { - $this->_iterable = array_merge($this->_custom_data, $this->_data, $this->_data_relations); - reset($this->_iterable); - } - - public function current() - { - return current($this->_iterable); - } - - public function key() - { - return key($this->_iterable); - } - - public function next() - { - return next($this->_iterable); - } - - public function valid() - { - return key($this->_iterable) !== null; - } - - /** - * Returns a list of properties that will be excluded when to_array() is used. - * @return array - */ - public static function get_to_array_exclude() - { - return static::$_to_array_exclude; - } - - /** - * Returns a list of properties and their information with _to_array_exclude - * properties removed. - * - * @return array - */ - public static function get_filtered_properties() - { - $array = static::properties(); - - // strip any excluded values from the array - foreach (static::get_to_array_exclude() as $key) - { - if (array_key_exists($key, $array)) - { - unset($array[$key]); - } - } - - return $array; - } -} diff --git a/fuel/packages/orm/classes/model/nestedset.php b/fuel/packages/orm/classes/model/nestedset.php deleted file mode 100755 index d856b5f..0000000 --- a/fuel/packages/orm/classes/model/nestedset.php +++ /dev/null @@ -1,1855 +0,0 @@ - 'left_id', // name of the tree node left index field - 'right_field' => 'right_id', // name of the tree node right index field - 'tree_field' => null, // name of the tree node tree index field - 'title_field' => null, // value of the tree node title field - 'read-only' => array(), // list of properties to protect against direct updates - ); - - // ------------------------------------------------------------------------- - // tree configuration - // ------------------------------------------------------------------------- - - /** - * Get a tree configuration parameter - * - * @param string name of the parameter to get - * @return mixed parameter value, or null if the parameter does not exist - */ - public static function tree_config($name = null) - { - $class = get_called_class(); - - // configuration not loaded yet - if ( ! array_key_exists($class, static::$_tree_cached)) - { - // do we have a custom config for this model? - if (property_exists($class, '_tree')) - { - static::$_tree_cached[$class] = array_merge(static::$_defaults, static::$_tree); - } - else - { - static::$_tree_cached[$class] = static::$_defaults; - } - - // array of read-only column names, the can not be set manually - foreach(array('left_field', 'right_field', 'tree_field') as $field) - { - $column = static::tree_config($field) and static::$_tree_cached[$class]['read-only'][] = $column; - } - } - - if (func_num_args() == 0) - { - return static::$_tree_cached[$class]; - } - else - { - return array_key_exists($name, static::$_tree_cached[$class]) ? static::$_tree_cached[$class][$name] : null; - } - } - - // ------------------------------------------------------------------------- - // updated constructor, capture un-supported compound PK's - // ------------------------------------------------------------------------- - - /** - * @var array store the node operation we need to execute on save() or get() - */ - protected $_node_operation = array(); - - /** - * @var mixed id value of the current tree in multi-tree models - */ - protected $_current_tree_id = null; - - /* - * Initialize the nestedset model instance - * - * @param array any data passed to this model - * @param bool whether or not this is a new model instance - * @param string name of a database view to use instead of a table - * @param bool whether or not to cache this object - * - * @throws OutOfBoundsException if the model has a compound primary key defined - */ - public function __construct(array $data = array(), $new = true, $view = null, $cache = true) - { - // check for a compound key, we don't do that (yet) - if (count(static::$_primary_key) > 1) - { - throw new \OutOfBoundsException('The Nestedset ORM model doesn\'t support compound primary keys.'); - } - - // call the ORM base model constructor - parent::__construct($data, $new, $view, $cache); - } - - // ------------------------------------------------------------------------- - // multi-tree select - // ------------------------------------------------------------------------- - - /** - * Select a specific tree if the table contains multiple trees - * - * @param mixed type depends on the field type of the tree_field - * @return Model_Nestedset this object, for chaining - * - * @throws BadMethodCallException if the model is not multi-tree - */ - public function set_tree_id($tree = null) - { - // is this a multi-tree model? - if (static::tree_config('tree_field') === null) - { - throw new \BadMethodCallException('This is not a multi-tree model, set_tree_id() can not be used.'); - } - - // set the tree filter value to select a specific tree - $this->_current_tree_id = $tree; - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Select a specific tree if the table contains multiple trees - * - * @return mixed current tree id value - * - * @throws OutOfRangeException if no tree id has been set - */ - public function get_tree_id() - { - // check if the current object is part of a tree - if (($value = $this->{static::tree_config('tree_field')}) !== null) - { - return $value; - } - - // check if there is a default tree id value set - if ($this->_current_tree_id !== null) - { - return $this->_current_tree_id; - } - - // we needed a tree id, but there isn't one defined - throw new \OutOfRangeException('tree id required, but none is defined.'); - } - - // ------------------------------------------------------------------------- - // tree queries - // ------------------------------------------------------------------------- - - /** - * Returns a query object on the selected tree - * - * @param bool whether or not to include related models - * - * @return Query the constructed query object - */ - public function build_query($include_related = true) - { - // create a new query object - $query = $this->query(); - - // get params to avoid excessive method calls - $tree_field = static::tree_config('tree_field'); - - // add the tree id if needed - if ( ! is_null($tree_field)) - { - $query->where($tree_field, $this->get_tree_id()); - } - - // add any relations if needed - if ($include_related and isset($this->_node_operation['related'])) - { - foreach ($this->_node_operation['related'] as $relation => $conditions) - { - $query->related($relation, $conditions); - } - } - - // return the query object - return $query; - } - - // ------------------------------------------------------------------------- - - /** - * Returns the root of the tree the current node belongs to - * - * @return Model_Nestedset this object, for chaining - */ - public function root() - { - $this->_node_operation = array( - 'related' => array(), - 'single' => true, - 'action' => 'root', - 'to' => null, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Returns the roots of all trees - * - * @return Model_Nestedset this object, for chaining - */ - public function roots() - { - $this->_node_operation = array( - 'related' => array(), - 'single' => false, - 'action' => 'roots', - 'to' => null, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Returns the parent of the current node - * - * @return Model_Nestedset this object, for chaining - */ - public function parent() - { - $this->_node_operation = array( - 'related' => array(), - 'single' => true, - 'action' => 'parent', - 'to' => null, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Returns the children of the current node - * - * @return Model_Nestedset this object, for chaining - */ - public function children() - { - $this->_node_operation = array( - 'related' => array(), - 'single' => false, - 'action' => 'children', - 'to' => null, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Returns all ancestors of the current node - * - * @return Model_Nestedset this object, for chaining - */ - public function ancestors() - { - $this->_node_operation = array( - 'related' => array(), - 'single' => false, - 'action' => 'ancestors', - 'to' => null, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Returns all descendants of the current node - * - * @return Model_Nestedset this object, for chaining - */ - public function descendants() - { - $this->_node_operation = array( - 'related' => array(), - 'single' => false, - 'action' => 'descendants', - 'to' => null, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Returns all leafs of the current node - * - * @return Model_Nestedset this object, for chaining - */ - public function leaf_descendants() - { - $this->_node_operation = array( - 'related' => array(), - 'single' => false, - 'action' => 'leaf_descendants', - 'to' => null, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Returns the siblings of the current node (includes the node itself!) - * - * @return Model_Nestedset this object, for chaining - */ - public function siblings() - { - $this->_node_operation = array( - 'related' => array(), - 'single' => false, - 'action' => 'siblings', - 'to' => null, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Returns the path to the current node - * - * @return Model_Nestedset this object, for chaining - */ - public function path($addroot = true) - { - $this->_node_operation = array( - 'related' => array(), - 'single' => false, - 'action' => 'path', - 'to' => null, - 'addroot' => $addroot, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - // node manipulation methods - // ------------------------------------------------------------------------- - - /** - * Alias for last_child() - * - * @param Model_Nestedset, or PK of the parent object, or null - * @return Model_Nestedset this object, for chaining - */ - public function child($to = null) - { - return $this->last_child($to); - } - - // ------------------------------------------------------------------------- - - /** - * Gets or sets the first child of a node - * - * @param Model_Nestedset, or PK of the parent object, or null - * @return Model_Nestedset this object, for chaining - */ - public function first_child($to = null) - { - $this->_node_operation = array( - 'related' => array(), - 'single' => true, - 'action' => 'first_child', - 'to' => $to, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Gets or sets the last child of a node - * - * @param Model_Nestedset, or PK of the parent object, or null - * @return Model_Nestedset this object, for chaining - */ - public function last_child($to = null) - { - $this->_node_operation = array( - 'related' => array(), - 'single' => true, - 'action' => 'last_child', - 'to' => $to, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Alias for next_sibling() - * - * @param Model_Nestedset, or PK of the parent object, or null - * @return Model_Nestedset this object, for chaining - */ - public function sibling($to = null) - { - return $this->next_sibling($to); - } - - // ------------------------------------------------------------------------- - - /** - * Gets or sets the previous sibling of a node - * - * @param Model_Nestedset, or PK of the parent object, or null - * @return Model_Nestedset this object, for chaining - */ - public function previous_sibling($to = null) - { - $this->_node_operation = array( - 'related' => array(), - 'single' => true, - 'action' => 'previous_sibling', - 'to' => $to, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - - /** - * Gets or sets the next sibling of a node - * - * @param Model_Nestedset, or PK of the parent object, or null - * @return Model_Nestedset this object, for chaining - */ - public function next_sibling($to = null) - { - $this->_node_operation = array( - 'related' => array(), - 'single' => true, - 'action' => 'next_sibling', - 'to' => $to, - ); - - // return the object for chaining - return $this; - } - - // ------------------------------------------------------------------------- - // boolean tree functions - // ------------------------------------------------------------------------- - - /** - * Check if the object is a tree root - * - * @return bool - */ - public function is_root() - { - return $this->{static::tree_config('left_field')} == 1; - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object is a tree leaf (node with no children) - * - * @return bool - */ - public function is_leaf() - { - return $this->{static::tree_config('right_field')} - $this->{static::tree_config('left_field')} == 1; - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object is a child node (not a root node) - * - * @return bool - */ - public function is_child() - { - return ! $this->is_root($this); - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object is a child of node - * - * @param Model_Nestedset of the parent to check - * @return bool - */ - public function is_child_of(Model_Nestedset $parent) - { - // get our parent - $our_parent = $this->parent()->get_one(); - - // and check if the parents match - return $parent == $our_parent; - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object is a direct descendant of node - * - * @param Model_Nestedset of the parent to check - * @return bool - */ - public function is_descendant_of(Model_Nestedset $parent) - { - // get params to avoid excessive method calls - $left_field = static::tree_config('left_field'); - $right_field = static::tree_config('right_field'); - - return $this->{$left_field} > $parent->{$left_field} and - $this->{$right_field} < $parent->{$right_field}; - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object is the parent of node - * - * @param Model_Nestedset of the child to check - * @return bool - */ - public function is_parent_of(Model_Nestedset $child) - { - return $this == $child->parent()->get_one(); - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object is the ancestor of node - * - * @param Model_Nestedset of the child to check - * @return bool - */ - public function is_ancestor_of(Model_Nestedset $child) - { - // get params to avoid excessive method calls - $left_field = static::tree_config('left_field'); - $right_field = static::tree_config('right_field'); - - return $child->{$left_field} > $this->{$left_field} and - $child->{$right_field} < $this->{$right_field}; - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object is the same model - * - * @param Model_Nestedset object to verify against - * @return bool - */ - public function is_same_model_as(Model_Nestedset $object) - { - return (get_class($object) == get_class($this)); - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object is the same model and the same tree - * - * @param Model_Nestedset object to verify against - * @return bool - */ - public function is_same_tree_as(Model_Nestedset $object) - { - // make sure they're the same model - if ($this->is_same_model_as($object)) - { - // get params to avoid excessive method calls - $tree_field = static::tree_config('tree_field'); - - if (empty($this->{$tree_field}) or $this->{$tree_field} === $object->{$tree_field}) - { - // same tree, or not a multi-tree model - return true; - } - } - - // not the same tree - return false; - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object has a parent - * - * Note: this is an alias for is_child() - * - * @return bool - */ - public function has_parent() - { - return $this->is_child($this); - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object has children - * - * @return bool - */ - public function has_children() - { - return $this->is_leaf($this) ? false : true; - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object has a previous sibling - * - * @return bool - */ - public function has_previous_sibling() - { - return ! is_null($this->previous_sibling()->get_one()); - } - - // ------------------------------------------------------------------------- - - /** - * Check if the object has a next sibling - * - * @return bool - */ - public function has_next_sibling() - { - return ! is_null($this->next_sibling()->get_one()); - } - - // ------------------------------------------------------------------------- - // integer tree methods - // ------------------------------------------------------------------------- - - /** - * Return the count of the objects children - * - * @return mixed integer, or false in case no valid object was passed - */ - public function count_children() - { - $result = $this->children()->get(); - return $result ? count($result) : 0; - } - - // ------------------------------------------------------------------------- - - /** - * Return the count of the objects descendants - * - * @return mixed integer, or false in case no valid object was passed - */ - public function count_descendants() - { - return ($this->{static::tree_config('right_field')} - $this->{static::tree_config('left_field')} - 1) / 2; - } - - // ------------------------------------------------------------------------- - - /** - * Return the depth of the object in the tree, where the root = 0 - * - * @return mixed integer, of false in case no valid object was found - */ - public function depth() - { - // get params to avoid excessive method calls - $left_field = static::tree_config('left_field'); - $right_field = static::tree_config('right_field'); - - // we need a valid object for this to work - if ($this->is_new()) - { - return false; - } - else - { - // if we have a valid object, run the query to calculate the depth - $query = $this->build_query(false) - ->where($left_field, '<', $this->{$left_field}) - ->where($right_field, '>', $this->{$right_field}); - - // return the result count - return $query->count(); - } - } - - // ------------------------------------------------------------------------- - - /** - * Return the tree, with the current node as root, as a nested array structure - * - * @param bool whether or not to return an array of objects - * @param string property name to store the node's children - * @param string property name to store the node's display path - * @param string property name to store the node's uri path - * @return array - */ - public function dump_tree($as_object = false, $children = 'children', $path = 'path', $pathuri = null) - { - // get the PK - $pk = reset(static::$_primary_key); - - // and the tree pointers - $left_field = static::tree_config('left_field'); - $right_field = static::tree_config('right_field'); - $title_field = static::tree_config('title_field'); - - // storage for the result, start with the current node - if ($as_object) - { - $this->_custom_data[$children] = array(); - $tree = array($this->{$pk} => $this); - } - else - { - $this[$children] = array(); - $tree = array($this->{$pk} => $this->to_array(true)); - } - - if ( ! empty($title_field) and isset($this->{$title_field})) - { - if ($as_object) - { - $this->_custom_data[$path] = '/'; - $pathuri and $this->_custom_data['path_'.$pathuri] = '/'; - } - else - { - $tree[$this->{$pk}][$path] = '/'; - $pathuri and $tree[$this->{$pk}]['path_'.$pathuri] = '/'; - } - } - - // parent tracker - $tracker = array(); - $index = 0; - $tracker[$index] =& $tree[$this->{$pk}]; - - // loop over the descendants - foreach ($this->descendants()->get() as $treenode) - { - // get the data for this node and make sure we have a place to store child information - if ($as_object) - { - $node = $treenode; - $node->_custom_data[$children] = array(); - } - else - { - $node = $treenode->to_array(true); - $node[$children] = array(); - } - - // is this node a child of the current parent? - while ($treenode->{$left_field} > $tracker[$index][$right_field]) - { - // no, so pop the last parent and move a level back up - $index--; - } - - // add the path to this node - if ( ! empty($title_field) and isset($treenode->{$title_field})) - { - if ($as_object) - { - $node->_custom_data[$path] = rtrim($tracker[$index][$path], '/').'/'.$node->{$title_field}; - $pathuri and $node->_custom_data['path_'.$pathuri] = rtrim($tracker[$index]['path_'.$pathuri], '/').'/'.$node->{$pathuri}; - } - else - { - $node[$path] = rtrim($tracker[$index][$path], '/').'/'.$node[$title_field]; - $pathuri and $node['path_'.$pathuri] = rtrim($tracker[$index]['path_'.$pathuri], '/').'/'.$node[$pathuri]; - } - } - - // add it as a child to the current parent - if ($as_object) - { - $tracker[$index]->_custom_data[$children][$treenode->{$pk}] = $node; - } - else - { - $tracker[$index][$children][$treenode->{$pk}] = $node; - } - - // does this node have children? - if ($treenode->{$right_field} - $treenode->{$left_field} > 1) - { - // create a new parent level - if ($as_object) - { - $tracker[$index+1] =& $tracker[$index]->_custom_data[$children][$treenode->{$pk}]; - } - else - { - $tracker[$index+1] =& $tracker[$index][$children][$treenode->{$pk}]; - } - $index++; - } - } - - return $as_object ? $this : $tree; - } - - // ------------------------------------------------------------------------- - - /** - * Capture __unset() to make sure no read-only properties are erased - * - * @param string $property - */ - public function __unset($property) - { - // make sure we're not unsetting a read-only value - if (in_array($property, static::tree_config('read-only'))) - { - throw new \InvalidArgumentException('Property "'.$property.'" is read-only and can not be changed'); - } - - parent::__unset($property); - } - - // ------------------------------------------------------------------------- - - /** - * Capture set() to make sure no read-only properties are overwritten - * - * @param string|array $property - * @param string $value in case $property is a string - * @return Model - */ - public function set($property, $value = null) - { - // check if we're in a frozen state - if ($this->_frozen) - { - throw new FrozenObject('No changes allowed.'); - } - - // make sure we're not setting a read-only value - if (in_array($property, static::tree_config('read-only')) and $this->{$property} !== $value) - { - throw new \InvalidArgumentException('Property "'.$property.'" is read-only and can not be changed'); - } - - return parent::set($property, $value); - } - - // ------------------------------------------------------------------------- - - /** - * Capture calls to save(), to make sure no new record is inserted - * directly which would seriously break the tree... - */ - public function save($cascade = null, $use_transaction = false) - { - // get params to avoid excessive method calls - $tree_field = static::tree_config('tree_field'); - $left_field = static::tree_config('left_field'); - $right_field = static::tree_config('right_field'); - - // deal with new objects - if ($this->_is_new) - { - // was a relocation of this node asked? - if ( ! empty($this->_node_operation)) - { - if ($this->_node_operation['to']) - { - // do we have a model? if not, try to autoload it - if ( ! $this->_node_operation['to'] instanceOf Model_Nestedset) - { - $this->_node_operation['to'] = static::find($this->_node_operation['to']); - } - - // verify that both objects are from the same model - $this->_same_model_as($this->_node_operation['to'], __METHOD__); - - // set the tree id if needed - if ( ! is_null($tree_field)) - { - $this->_data[$tree_field] = $this->_node_operation['to']->get_tree_id(); - } - } - - // add the left- and right pointers to the current object, and make room for it - if ($use_transaction) - { - $db = \Database_Connection::instance(static::connection(true)); - $db->start_transaction(); - } - try - { - switch ($this->_node_operation['action']) - { - case 'next_sibling': - // set the left- and right pointers for the new node - $this->_data[$left_field] = $this->_node_operation['to']->{$right_field} + 1; - $this->_data[$right_field] = $this->_node_operation['to']->{$right_field} + 2; - - // create room for this new node - $this->_shift_rl_values($this->{$left_field}, 2); - break; - - case 'previous_sibling': - // set the left- and right pointers for the new node - $this->_data[$left_field] = $this->_node_operation['to']->{$left_field}; - $this->_data[$right_field] = $this->_node_operation['to']->{$left_field} + 1; - - // create room for this new node - $this->_shift_rl_values($this->{$left_field}, 2); - break; - - case 'first_child': - // set the left- and right pointers for the new node - $this->_data[$left_field] = $this->_node_operation['to']->{$left_field} + 1; - $this->_data[$right_field] = $this->_node_operation['to']->{$left_field} + 2; - - // create room for this new node - $this->_shift_rl_values($this->{$left_field}, 2); - break; - - case 'last_child': - // set the left- and right pointers for the new node - $this->_data[$left_field] = $this->_node_operation['to']->{$right_field}; - $this->_data[$right_field] = $this->_node_operation['to']->{$right_field} + 1; - - // create room for this new node - $this->_shift_rl_values($this->{$left_field}, 2); - break; - - default: - throw new \OutOfBoundsException('You can not define a '.$this->_node_operation['action'].'() action before a save().'); - break; - } - } - catch (\Exception $e) - { - $use_transaction and $db->rollback_transaction(); - throw $e; - } - } - - // assume we want a new root node - else - { - // set the left- and right pointers for the new root - $this->_data[$left_field] = 1; - $this->_data[$right_field] = 2; - $pk = reset(static::$_primary_key); - - // we need to check if we don't already have this root - $query = \DB::select($pk) - ->from(static::table()) - ->where($left_field, '=', 1); - - // multi-root tree? And no new tree id defined? - if ( ! is_null($tree_field) and empty($this->{$tree_field})) - { - // get the next free tree id, and hope it's numeric... - $this->_data[$tree_field] = $this->max($tree_field) + 1; - - // and set it as the default tree id for this node - $this->set_tree_id($this->_data[$tree_field]); - } - - // add the tree_id to the query if present - if ( ! empty($this->{$tree_field})) - { - $query->where($tree_field, '=', $this->_data[$tree_field]); - } - - // run the check - $result = $query->execute(static::connection()); - - // any hits? - if (count($result)) - { - throw new \OutOfBoundsException('You can not add this new tree root, it already exists.'); - } - } - } - - // and with existing objects - else - { - // get the classname of this model - $class = get_called_class(); - - // readonly fields may not be changed - foreach (static::$_tree_cached[$class]['read-only'] as $column) - { - // so reset them if they were changed - $this->_data[$column] = $this->_original[$column]; - } - - // was a relocation of this node asked - if ( ! empty($this->_node_operation)) - { - if ($this->_node_operation['to']) - { - // do we have a model? if not, try to autoload it - if ( ! $this->_node_operation['to'] instanceOf Model_Nestedset) - { - $this->_node_operation['to'] = static::find($this->_node_operation['to']); - } - - // verify that both objects are from the same model - $this->_same_model_as($this->_node_operation['to'], __METHOD__); - - // and from the same tree (if we have multi-tree support for this object) - if ( ! is_null($tree_field)) - { - if ($this->{$tree_field} !== $this->_node_operation['to']->{$tree_field}) - { - throw new \OutOfBoundsException('When moving nodes, nodes must be part of the same tree.'); - } - } - } - - // move the node - if ($use_transaction) - { - $db = \Database_Connection::instance(static::connection(true)); - $db->start_transaction(); - } - try - { - switch ($this->_node_operation['action']) - { - case 'next_sibling': - $this->_move_subtree($this->_node_operation['to']->{static::tree_config('right_field')} + 1); - break; - - case 'previous_sibling': - $this->_move_subtree($this->_node_operation['to']->{static::tree_config('left_field')}); - break; - - case 'first_child': - $this->_move_subtree($this->_node_operation['to']->{static::tree_config('left_field')} + 1); - break; - - case 'last_child': - $this->_move_subtree($this->_node_operation['to']->{static::tree_config('right_field')}); - break; - - default: - throw new \OutOfBoundsException('You can not define a '.$this->_node_operation['action'].'() action before a save().'); - break; - } - } - catch (\Exception $e) - { - $use_transaction and $db->rollback_transaction(); - throw $e; - } - } - } - - // reset the node operation store to make sure nothings pending... - $this->_node_operation = array(); - - // save the current node and return the result - return parent::save($cascade, $use_transaction); - } - - // ------------------------------------------------------------------------- - - /** - * Capture calls to delete(), to make sure no delete happens without reindexing - * - * @param mixed $cascade - * null = use default config, - * bool = force/prevent cascade, - * array cascades only the relations that are in the array - * @return Model this instance as a new object without primary key(s) - * - * @throws DomainException if you try to delete a root node with multiple children - */ - public function delete($cascade = null, $use_transaction = false) - { - if ($use_transaction) - { - $db = \Database_Connection::instance(static::connection(true)); - $db->start_transaction(); - } - - // get params to avoid excessive method calls - $left_field = static::tree_config('left_field'); - $right_field = static::tree_config('right_field'); - - // if this is a root node with multiple children, bail out - if ($this->is_root() and $this->count_children() > 1) - { - throw new \DomainException('You can not delete a tree root with multiple children.'); - } - - // put the entire operation in a try/catch, so we can rollback if needed - try - { - // delete the node itself - $result = parent::delete($cascade); - - // check if the delete was succesful - if ($result !== false) - { - // re-index the tree - $this->_shift_rl_range($this->{$left_field} + 1, $this->{$right_field} - 1, -1); - $this->_shift_rl_values($this->{$right_field} + 1, -2); - } - } - catch (\Exception $e) - { - $use_transaction and $db->rollback_transaction(); - throw $e; - } - - // reset the node operation store to make sure nothings pending... - $this->_node_operation = array(); - - // and return the result - return $result; - } - - // ------------------------------------------------------------------------- - // tree destructors - // ------------------------------------------------------------------------- - - /** - * Deletes the entire tree structure using the current node as starting point - * - * @param mixed $cascade - * null = use default config, - * bool = force/prevent cascade, - * array cascades only the relations that are in the array - * @return Model this instance as a new object without primary key(s) - */ - public function delete_tree($cascade = null, $use_transaction = false) - { - if ($use_transaction) - { - $db = \Database_Connection::instance(static::connection(true)); - $db->start_transaction(); - } - - // get params to avoid excessive method calls - $left_field = static::tree_config('left_field'); - $right_field = static::tree_config('right_field'); - $pk = reset(static::$_primary_key); - - // put the entire operation in a try/catch, so we can rollback if needed - try - { - // check if the node has children - if ($this->has_children()) - { - // get them - $children = $this->children()->get(); - - // and delete them to - foreach ($children as $child) - { - if ($child->delete_tree($cascade) === false) - { - throw new \UnexpectedValueException('delete of child node with PK "'.$child->{$pk}.'" failed.'); - } - } - } - - // delete the node itself - $result = parent::delete($cascade); - - // check if the delete was succesful - if ($result !== false) - { - // re-index the tree - $this->_shift_rl_values($this->{$right_field} + 1, $this->{$left_field} - $this->{$right_field} - 1); - } - } - catch (\Exception $e) - { - $use_transaction and $db->rollback_transaction(); - throw $e; - } - - // reset the node operation store to make sure nothings pending... - $this->_node_operation = array(); - - // and return the result - return $result; - } - - // ------------------------------------------------------------------------- - // get methods - // ------------------------------------------------------------------------- - - /** - * Creates a new query with optional settings up front, or return a pre-build - * query to further chain upon - * - * @param array - * @return Query - */ - public function get_query() - { - // make sure there's a node operation defined - if (empty($this->_node_operation)) - { - // assume a get-all operation - $this->_node_operation = array( - 'related' => array(), - 'single' => false, - 'action' => 'all', - 'to' => null, - ); - } - - return $this->_fetch_nodes('query'); - } - - // ------------------------------------------------------------------------- - - /** - * Get one or more tree nodes, and provide fallback for - * the original model getter - * - * @param mixed - * - * @returns mixed - * @throws BadMethodCallException if called without a parameter and without a node to fetch - */ - public function & get($query = null, array $conditions = array()) - { - // do we have any parameters passed? - if (func_num_args()) - { - // capture normal getter calls - if ($query instanceOf Query) - { - // run a get() on the query - return $query->get(); - } - else - { - // assume it's a model getter call - return parent::get($query, $conditions); - } - } - - // make sure there's a node operation defined - if (empty($this->_node_operation)) - { - // assume a get-all operation - $this->_node_operation = array( - 'related' => array(), - 'single' => false, - 'action' => 'all', - 'to' => null, - ); - } - - // no parameters, so we need to fetch something - $result = $this->_fetch_nodes('multiple'); - return $result; - } - - // ------------------------------------------------------------------------- - - /* - * Get a single tree node - * - * @param Query - * - * @returns mixed - * @throws BadMethodCallException if called without a parameter and without a node to fetch - */ - public function get_one(Query $query = null) - { - // do we have a query object passed? - if (func_num_args()) - { - // return the query result - return $query->get_one(); - } - - // make sure there's a node operation defined - if (empty($this->_node_operation)) - { - // assume a get-all operation - $this->_node_operation = array( - 'related' => array(), - 'single' => true, - 'action' => 'all', - 'to' => null, - ); - } - - // so we need to fetch something - return $this->_fetch_nodes('single'); - } - - /** - * Set a relation to include - * - * @param string $relation - * @param array $conditions Optionally - * - * @return $this - */ - public function related($relation, $conditions = array()) - { - // make sure there's a node operation defined - if (empty($this->_node_operation)) - { - // assume a get-all operation - $this->_node_operation = array( - 'related' => array(), - 'single' => false, - 'action' => 'all', - 'to' => null, - ); - } - - // store the relation to include - $this->_node_operation['related'][$relation] = $conditions; - - return $this; - } - - // ------------------------------------------------------------------------- - // protected class functions - // ------------------------------------------------------------------------- - - /** - * Check if the object passed is an instance of the current model - * - * @param Model_Nestedset - * @param string optional method name to display in the exception message - * @return bool - * - * @throws OutOfBoundsException in case the two objects are not part of the same model - */ - protected function _same_model_as($object, $method = 'unknown') - { - if ( ! $this->is_same_model_as($object)) - { - throw new \OutOfBoundsException('Model object passed to '.$method.'() is not an instance of '.get_class($this).'.'); - } - } - - // ------------------------------------------------------------------------- - - /* - * Fetch a node or nodes, and return the result - * - * @param string action, either 'single' or 'multiple' - * @return mixed Model_Nestedset or an array of Model_Nestedset, or null if none found - * - * @throws \UnexpectedValueException Relation was not found in the model - */ - protected function _fetch_nodes($action) - { - // get params to avoid excessive method calls - $left_field = static::tree_config('left_field'); - $right_field = static::tree_config('right_field'); - $tree_field = static::tree_config('tree_field'); - - // construct the query - switch ($this->_node_operation['action']) - { - case 'all': - $query = $this->build_query(); - break; - - case 'root': - $query = $this->build_query() - ->where($left_field, '=', 1); - break; - - case 'roots': - $query = $this->query() - ->where($left_field, '=', 1); - break; - - case 'parent': - $query = $this->build_query() - ->where($left_field, '<', $this->{$left_field}) - ->where($right_field, '>', $this->{$right_field}) - ->order_by($right_field, 'ASC'); - break; - - case 'first_child': - $query = $this->build_query() - ->where($left_field, $this->{$left_field} + 1); - break; - - case 'last_child': - $query = $this->build_query() - ->where($right_field, $this->{$right_field} - 1); - break; - - case 'children': - // get the PK's of all child objects - $pk = reset(static::$_primary_key); - $left = $this->{$left_field}; - $right = $this->{$right_field}; - - // if we're multitree, add the tree filter to the query - if (is_null($tree_field)) - { - $query = \DB::select('child.'.$pk) - ->from(array(static::table(), 'child')) - ->join(array(static::table(), 'ancestor'), 'left') - ->on(\DB::identifier('ancestor.' . $left_field), 'BETWEEN', \DB::expr(($left + 1) . ' AND ' . ($right - 1))) - ->on(\DB::identifier('child.' . $left_field), 'BETWEEN', \DB::expr(\DB::identifier('ancestor.'.$left_field).' + 1 AND '.\DB::identifier('ancestor.'.$right_field).' - 1')) - ->where(\DB::identifier('child.' . $left_field), 'BETWEEN', \DB::expr(($left + 1) . ' AND ' . ($right - 1))) - ->and_where('ancestor.'.$pk, null); - } - else - { - $query = \DB::select('child.'.$pk) - ->from(array(static::table(), 'child')) - ->join(array(static::table(), 'ancestor'), 'left') - ->on(\DB::identifier('ancestor.' . $left_field), 'BETWEEN', \DB::expr(($left + 1) . ' AND ' . ($right - 1) . ' AND '.\DB::identifier('ancestor.'.$tree_field).' = '.$this->get_tree_id())) - ->on(\DB::identifier('child.' . $left_field), 'BETWEEN', \DB::expr(\DB::identifier('ancestor.'.$left_field).' + 1 AND '.\DB::identifier('ancestor.'.$right_field).' - 1')) - ->where(\DB::identifier('child.' . $left_field), 'BETWEEN', \DB::expr(($left + 1) . ' AND ' . ($right - 1))) - ->and_where('ancestor.'.$pk, null) - ->and_where('child.'.$tree_field, '=', $this->get_tree_id()); - - } - - // extract the PK's, and bail out if no children found - if ( ! $pks = $query->execute(static::connection())->as_array()) - { - return null; - } - - // construct the query to find all child objects - $query = $this->build_query() - ->where($pk, 'IN', $pks) - ->order_by($left_field, 'ASC'); - break; - - case 'ancestors': - // storage for the result - $result = array(); - - // new objects don't have a parent - if ( ! $this->is_new()) - { - $parent = $this; - $pk = reset(static::$_primary_key); - - while (($parent = $parent->parent()->get_one()) !== null) - { - $result[$parent->{$pk}] = $parent; - } - } - - // reverse the result - $result = array_reverse($result, true); - - // return the result - return $result; - break; - - case 'descendants': - $query = $this->build_query() - ->where($left_field, '>', $this->{$left_field}) - ->where($right_field, '<', $this->{$right_field}) - ->order_by($left_field, 'ASC'); - break; - - case 'leaf_descendants': - $query = $this->build_query() - ->where($left_field, '>', $this->{$left_field}) - ->where($right_field, '<', $this->{$right_field}) - ->where(\DB::expr(\DB::quote_identifier($right_field) . ' - ' . \DB::quote_identifier($left_field)), '=', 1) - ->order_by($left_field, 'ASC'); - break; - - case 'previous_sibling': - $query = $this->build_query() - ->where(static::tree_config('right_field'), $this->{static::tree_config('left_field')} - 1); - break; - - case 'next_sibling': - $query = $this->build_query() - ->where(static::tree_config('left_field'), $this->{static::tree_config('right_field')} + 1); - break; - - case 'siblings': - // if we have a parent object - if ($parent = $this->parent()->get_one()) - { - // get the children of that parent - return $parent->children()->get(); - } - else - { - // no siblings - return null; - } - break; - - case 'path': - // do we have a title field defined? - if ($title_field = static::tree_config('title_field')) - { - // storage for the path - $path = ''; - - // do we need to add the root? - $addroot = $this->_node_operation['addroot']; - - // get all parents - $result = $this->ancestors()->get(); - - // construct the path - foreach($result as $object) - { - if ($addroot or $object->{$left_field} > 1) - { - $path .= $object->{$title_field}.'/'; - } - } - $path .= $this->{$title_field}; - - // and return it - return $path; - } - else - { - throw new \OutOfBoundsException('You can call path(), the "'.get_class($this).'" model does not define a title field.'); - } - break; - - default: - throw new \OutOfBoundsException('You can not set a '.$this->_node_operation['action'].'() operation on a get() or get_one().'); - break; - } - - // reset the node operation store to make sure nothings pending... - $this->_node_operation = array(); - - if ($action == 'query') - { - // return the query object for further chaining - return $query; - } - else - { - // return the query result based on the action type - return $action == 'single' ? $query->get_one() : $query->get(); - } - } - - // ------------------------------------------------------------------------- - - /** - * Interal tree operation. Shift left-right pointers to make room for - * one or mode nodes, or to re-order the pointers after a delete - * operation. - * - * @param integer left pointer of the first node to shift - * @param integer number of positions to shift (if negative the shift will be to the left) - */ - protected function _shift_rl_values($first, $delta) - { - // get params to avoid excessive method calls - $tree_field = static::tree_config('tree_field'); - $left_field = static::tree_config('left_field'); - $right_field = static::tree_config('right_field'); - - $query = \DB::update(static::table()); - - // if we have multiple roots - if ( ! is_null($tree_field)) - { - $query->where($tree_field, $this->get_tree_id()); - } - - $query->where($left_field, '>=', $first); - - // correct the delta - $sqldelta = ($delta < 0) ? (' - '.abs($delta)) : (' + '.$delta); - - // set clause - $query->set(array( - $left_field => \DB::expr(\DB::quote_identifier($left_field).$sqldelta), - )); - - // update in the correct order to avoid constraint conflicts - $query->order_by($left_field, ($delta < 0 ? 'ASC' : 'DESC')); - - // execute it - $query->execute(static::connection(true)); - - $query = \DB::update(static::table()); - - // if we have multiple roots - if ( ! is_null($tree_field)) - { - $query->where($tree_field, $this->get_tree_id()); - } - - $query->where($right_field, '>=', $first); - - // set clause - $query->set(array( - $right_field => \DB::expr(\DB::quote_identifier($right_field).$sqldelta), - )); - - // update in the correct order to avoid constraint conflicts - $query->order_by($right_field, ($delta < 0 ? 'ASC' : 'DESC')); - - // execute it - $query->execute(static::connection(true)); - - // update cached objects, we've modified pointers - $class = get_called_class(); - if (array_key_exists($class, static::$_cached_objects)) - { - foreach (static::$_cached_objects[$class] as $object) - { - if (is_null($tree_field) or $object->{$tree_field} == $this->{$tree_field}) - { - if ($object->{$left_field} >= $first) - { - if ($delta < 0) - { - $object->_data[$left_field] -= abs($delta); - $object->_original[$left_field] -= abs($delta); - } - else - { - $object->_data[$left_field] += $delta; - $object->_original[$left_field] += $delta; - } - } - if ($object->{$right_field} >= $first) - { - if ($delta < 0) - { - $object->_data[$right_field] -= abs($delta); - $object->_original[$right_field] -= abs($delta); - } - else - { - $object->_data[$right_field] += $delta; - $object->_original[$right_field] += $delta; - } - } - } - } - } - } - - // ------------------------------------------------------------------------- - - /** - * Interal tree operation. Shift left-right pointers to make room for - * one or mode nodes, or to re-order the pointers after a delete - * operation, in the given range - * - * @param integer left pointer of the first node to shift - * @param integer right pointer of the last node to shift - * @param integer number of positions to shift (if negative the shift will be to the left) - */ - protected function _shift_rl_range($first, $last, $delta) - { - // get params to avoid excessive method calls - $tree_field = static::tree_config('tree_field'); - $left_field = static::tree_config('left_field'); - $right_field = static::tree_config('right_field'); - - $query = \DB::update(static::table()); - - // if we have multiple roots - if ( ! is_null($tree_field)) - { - $query->where($tree_field, $this->get_tree_id()); - } - - // select the range - $query->where($left_field, '>=', $first); - $query->where($right_field, '<=', $last); - - // correct the delta - $sqldelta = ($delta < 0) ? (' - '.abs($delta)) : (' + '.$delta); - - // set clause - $query->set(array( - $left_field => \DB::expr(\DB::quote_identifier($left_field).$sqldelta), - $right_field => \DB::expr(\DB::quote_identifier($right_field).$sqldelta), - )); - - // update in the correct order to avoid constraint conflicts - $query->order_by($right_field, ($delta < 0 ? 'ASC' : 'DESC')); - - // execute it - $query->execute(static::connection(true)); - - // update cached objects, we've modified pointers - $class = get_called_class(); - if (array_key_exists($class, static::$_cached_objects)) - { - foreach (static::$_cached_objects[$class] as $object) - { - if (is_null($tree_field) or $object->{$tree_field} == $this->{$tree_field}) - { - if ($object->{$left_field} >= $first and $object->{$right_field} <= $last) - { - if ($delta < 0) - { - $object->_data[$left_field] -= abs($delta); - $object->_data[$right_field] -= abs($delta); - $object->_original[$left_field] -= abs($delta); - $object->_original[$right_field] -= abs($delta); - } - else - { - $object->_data[$left_field] += $delta; - $object->_data[$right_field] += $delta; - $object->_original[$left_field] += $delta; - $object->_original[$right_field] += $delta; - } - } - } - } - } - } - - // ------------------------------------------------------------------------- - - /** - * Interal tree operation. Move the current node and all children - * to a new position in the tree - * - * @param integer new left pointer location to move to - */ - protected function _move_subtree($destination_id) - { - // get params to avoid excessive method calls - $tree_field = static::tree_config('tree_field'); - $left_field = static::tree_config('left_field'); - $right_field = static::tree_config('right_field'); - - // catch a move into the subtree - if ( $destination_id >= $this->{$left_field} and $destination_id <= $this->{$right_field} ) - { - // it would make no change to the tree - return $this; - } - - // determine the size of the tree to move - $treesize = $this->{$right_field} - $this->{$left_field} + 1; - - // get the objects left- and right pointers - $left_id = $this->{$left_field}; - $right_id = $this->{$right_field}; - - // shift to make some space - $this->_shift_rl_values($destination_id, $treesize); - - // correct pointers if there were shifted to - if ($this->{$left_field} >= $destination_id) - { - $left_id += $treesize; - $right_id += $treesize; - } - - // enough room now, start the move - $this->_shift_rl_range($left_id, $right_id, $destination_id - $left_id); - - // and correct index values after the source - $this->_shift_rl_values(++$right_id, (-1 * $treesize)); - - // return the moved object - return $this; - } -} diff --git a/fuel/packages/orm/classes/model/soft.php b/fuel/packages/orm/classes/model/soft.php deleted file mode 100755 index 3181719..0000000 --- a/fuel/packages/orm/classes/model/soft.php +++ /dev/null @@ -1,303 +0,0 @@ - 0 ? array_shift($temp_args) : 'all'; - $options = count($temp_args) > 0 ? array_shift($temp_args) : array(); - - return static::deleted($find_type, $options); - } - - return parent::__callStatic($method, $args); - } - - protected function delete_self() - { - // If soft deleting has been disabled then just call the parent's delete - if ($this->_disable_soft_delete) - { - return parent::delete_self(); - } - - $deleted_column = static::soft_delete_property('deleted_field', static::$_default_field_name); - $mysql_timestamp = static::soft_delete_property('mysql_timestamp', static::$_default_mysql_timestamp); - - // Generate the correct timestamp and save it - $this->{$deleted_column} = $mysql_timestamp ? \Date::forge()->format('mysql') : \Date::forge()->get_timestamp(); - $result = $this->save(false); - - return $result; - } - - /** - * Permanently deletes records using the parent Model delete function - * - * @param $cascade boolean - * @param $use_transaction boolean - * - * @return boolean - */ - public function purge($cascade = null, $use_transaction = false) - { - $this->observe('before_purge'); - - $this->_disable_soft_delete = true; - $result = parent::delete($cascade, $use_transaction); - $this->_disable_soft_delete = false; - - $this->observe('after_purge'); - - return $result; - } - - /** - * Returns true unless the related model is not soft or temporal - */ - protected function should_cascade_delete($rel) - { - // Because temporal includes soft delete functionality it can be deleted too - if ( ! is_subclass_of($rel->model_to, 'Orm\Model_Soft') && ! is_subclass_of($rel->model_to, 'Orm\Model_Temporal')) - { - // Throw if other is not soft - throw new RelationNotSoft('Both sides of the relation must be subclasses of Model_Soft or Model_Temporal if cascade delete is true. '.$rel->model_to.' was found instead.'); - } - - return true; - } - - /** - * Allows a soft deleted entry to be restored. - */ - public function restore($cascade_restore = null) - { - $deleted_column = static::soft_delete_property('deleted_field', static::$_default_field_name); - $this->{$deleted_column} = null; - - //Loop through all relations and restore if we are cascading. - $this->freeze(); - foreach ($this->relations() as $rel_name => $rel) - { - //get the cascade delete status - $rel_cascade = is_null($cascade_restore) ? $rel->cascade_delete : (bool) $cascade_restore; - - //Make sure that the other model is soft delete too - if ($rel_cascade) - { - if (! is_subclass_of($rel->model_to, 'Orm\Model_Soft')) - { - //Throw if other is not soft - throw new RelationNotSoft('Both sides of the relation must be subclasses of Model_Soft if cascade delete is true'); - } - - if (get_class($rel) != 'Orm\ManyMany') - { - $model_to = $rel->model_to; - $model_to::disable_filter(); - - //Loop through and call restore on all the models - $models = $rel->get($this); - - // for hasmany/manymany relations - if (is_array($models)) - { - foreach ($models as $model) - { - $model->restore($cascade_restore); - } - } - // for hasone/belongsto relations - else - { - $models->restore($cascade_restore); - } - - $model_to::enable_filter(); - } - } - } - $this->unfreeze(); - - return $this->save(); - } - - /** - * Alias of restore() - */ - public function undelete() - { - return $this->restore(); - } - - /** - * Overrides the query method to allow soft delete items to be filtered out. - */ - public static function query($options = array()) - { - $query = Query_Soft::forge(get_called_class(), static::connection(), $options); - - if (static::get_filter_status()) - { - //Make sure we are filtering out soft deleted items - $query->set_soft_filter(static::soft_delete_property('deleted_field', static::$_default_field_name)); - } - - return $query; - } - - /** - * Alisas of find() but selects only deleted entries rather than non-deleted - * ones. - */ - public static function deleted($id = null, array $options = array()) - { - //Make sure we are not filtering out soft deleted items - $deleted_column = static::soft_delete_property('deleted_field', static::$_default_field_name); - $options['where'][] = array($deleted_column, 'IS NOT', null); - - static::disable_filter(); - $result = parent::find($id, $options); - static::enable_filter(); - - return $result; - } - -} diff --git a/fuel/packages/orm/classes/model/temporal.php b/fuel/packages/orm/classes/model/temporal.php deleted file mode 100755 index 8fc7251..0000000 --- a/fuel/packages/orm/classes/model/temporal.php +++ /dev/null @@ -1,674 +0,0 @@ -where('id', $id) - ->where($timestamp_start_name, '<=', $timestamp) - ->where($timestamp_end_name, '>', $timestamp); - self::enable_primary_key_check(); - - //Make sure the temporal stuff is activated - $query->set_temporal_properties($timestamp, $timestamp_end_name, $timestamp_start_name); - - foreach ($relations as $relation) - { - $query->related($relation); - } - - $query_result = $query->get_one(); - - // If the query did not return a result but null, then we cannot call - // set_lazy_timestamp on it without throwing errors - if ( $query_result !== null ) - { - $query_result->set_lazy_timestamp($timestamp); - } - return $query_result; - } - - private function set_lazy_timestamp($timestamp) - { - $this->_lazy_timestamp = $timestamp; - } - - /** - * Overrides Model::get() to allow lazy loaded relations to be filtered - * temporaly. - * - * @param string $property - * @return mixed - */ - public function & get($property, array $conditions = array()) - { - // if a timestamp is set and that we have a temporal relation - $rel = static::relations($property); - if ($rel && is_subclass_of($rel->model_to, 'Orm\Model_Temporal')) - { - // find a specific revision or the newest if lazy timestamp is null - $lazy_timestamp = $this->_lazy_timestamp ?: static::temporal_property('max_timestamp') - 1; - //add the filtering and continue with the parent's behavour - $class_name = $rel->model_to; - - $class_name::make_query_temporal($lazy_timestamp); - $result =& parent::get($property, $conditions); - $class_name::make_query_temporal(null); - - return $result; - } - - return parent::get($property, $conditions); - } - - /** - * When a timestamp is set any query objects produced by this temporal model - * will behave the same as find_revision() - * - * @param array $timestamp - */ - private static function make_query_temporal($timestamp) - { - $class = get_called_class(); - static::$_lazy_filtered_classes[$class] = $timestamp; - } - - /** - * Overrides Model::query to provide a Temporal_Query - * - * @param array $options - * @return Query_Temporal - */ - public static function query($options = array()) - { - $timestamp_start_name = static::temporal_property('start_column'); - $timestamp_end_name = static::temporal_property('end_column'); - $max_timestamp = static::temporal_property('max_timestamp'); - - $query = Query_Temporal::forge(get_called_class(), static::connection(), $options) - ->set_temporal_properties($max_timestamp, $timestamp_end_name, $timestamp_start_name); - - //Check if we need to add filtering - $class = get_called_class(); - $timestamp = \Arr::get(static::$_lazy_filtered_classes, $class, null); - - if( ! is_null($timestamp)) - { - $query->where($timestamp_start_name, '<=', $timestamp) - ->where($timestamp_end_name, '>', $timestamp); - } - elseif(static::get_primary_key_status() and ! static::get_primary_key_id_only_status()) - { - $query->where($timestamp_end_name, $max_timestamp); - } - - return $query; - } - - /** - * Returns a list of revisions between the given times with the most recent - * first. This does not load relations. - * - * @param int|string $id - * @param timestamp $earliestTime - * @param timestamp $latestTime - */ - public static function find_revisions_between($id, $earliestTime = null, $latestTime = null) - { - $timestamp_start_name = static::temporal_property('start_column'); - $max_timestamp = static::temporal_property('max_timestamp'); - - if ($earliestTime == null) - { - $earliestTime = 0; - } - - if($latestTime == null) - { - $latestTime = $max_timestamp; - } - - static::disable_primary_key_check(); - //Select all revisions within the given range. - $query = static::query() - ->where('id', $id) - ->where($timestamp_start_name, '>=', $earliestTime) - ->where($timestamp_start_name, '<=', $latestTime); - static::enable_primary_key_check(); - - $revisions = $query->get(); - return $revisions; - } - - /** - * Overrides the default find method to allow the latest revision to be found - * by default. - * - * If any new options to find are added the switch statement will have to be - * updated too. - * - * @param type $id - * @param array $options - * @return type - */ - public static function find($id = null, array $options = array()) - { - $timestamp_end_name = static::temporal_property('end_column'); - $max_timestamp = static::temporal_property('max_timestamp'); - - switch ($id) - { - case 'all': - case 'first': - case 'last': - break; - default: - $id = (array) $id; - $count = 0; - foreach(static::getNonTimestampPks() as $key) - { - $options['where'][] = array($key, $id[$count]); - - $count++; - } - break; - } - - $options['where'][] = array($timestamp_end_name, $max_timestamp); - - static::enable_id_only_primary_key(); - $result = parent::find($id, $options); - static::disable_id_only_primary_key(); - - return $result; - } - - /** - * Returns an array of the primary keys that are not related to temporal - * timestamp information. - */ - public static function getNonTimestampPks() - { - $timestamp_start_name = static::temporal_property('start_column'); - $timestamp_end_name = static::temporal_property('end_column'); - - $pks = array(); - foreach(parent::primary_key() as $key) - { - if ($key != $timestamp_start_name && $key != $timestamp_end_name) - { - $pks[] = $key; - } - } - - return $pks; - } - - /** - * Overrides the save method to allow temporal models to be - * @param boolean $cascade - * @param boolean $use_transaction - * @param boolean $skip_temporal Skips temporal filtering on initial inserts. Should not be used! - * @return boolean - */ - public function save($cascade = null, $use_transaction = false) - { - // Load temporal properties. - $timestamp_start_name = static::temporal_property('start_column'); - $timestamp_end_name = static::temporal_property('end_column'); - $mysql_timestamp = static::temporal_property('mysql_timestamp'); - - $max_timestamp = static::temporal_property('max_timestamp'); - $current_timestamp = $mysql_timestamp ? - \Date::forge()->format('mysql') : - \Date::forge()->get_timestamp(); - - // If this is new then just call the parent and let everything happen as normal - if ($this->is_new()) - { - static::disable_primary_key_check(); - $this->{$timestamp_start_name} = $current_timestamp; - $this->{$timestamp_end_name} = $max_timestamp; - static::enable_primary_key_check(); - - // Make sure save will populate the PK - static::enable_id_only_primary_key(); - $result = parent::save($cascade, $use_transaction); - static::disable_id_only_primary_key(); - - return $result; - } - // If this is an update then set a new PK, save and then insert a new row - else - { - // run the before save observers before checking the diff - $this->observe('before_save'); - - // then disable it so it doesn't get executed by parent::save() - $this->disable_event('before_save'); - - $diff = $this->get_diff(); - - if (count($diff[0]) > 0) - { - // Take a copy of this model - $revision = clone $this; - - // Give that new model an end time of the current time after resetting back to the old data - $revision->set($this->_original); - - self::disable_primary_key_check(); - $revision->{$timestamp_end_name} = $current_timestamp; - self::enable_primary_key_check(); - - // Make sure relations stay the same - $revision->_original_relations = $this->_data_relations; - - // save that, now we have our archive - self::enable_id_only_primary_key(); - $revision_result = $revision->overwrite(false, $use_transaction); - self::disable_id_only_primary_key(); - - if ( ! $revision_result) - { - // If the revision did not save then stop the process so the user can do something. - return false; - } - - // Now that the old data is saved update the current object so its end timestamp is now - self::disable_primary_key_check(); - $this->{$timestamp_start_name} = $current_timestamp; - self::enable_primary_key_check(); - - $result = parent::save($cascade, $use_transaction); - } - else - { - // If nothing has changed call parent::save() to insure relations are saved too - $result = parent::save($cascade, $use_transaction); - } - - // make sure the before save event is enabled again - $this->enable_event('before_save'); - - return $result; - } - } - - /** - * ALlows an entry to be updated without having to insert a new row. - * This will not record any changed data as a new revision. - * - * Takes the same options as Model::save() - */ - public function overwrite($cascade = null, $use_transaction = false) - { - return parent::save($cascade, $use_transaction); - } - - /** - * Restores the entity to this state. - * - * @return boolean - */ - public function restore() - { - $timestamp_end_name = static::temporal_property('end_column'); - $max_timestamp = static::temporal_property('max_timestamp'); - - // check to see if there is a currently active row, if so then don't - // restore anything. - $activeRow = static::find('first', array( - 'where' => array( - array('id', $this->id), - array($timestamp_end_name, $max_timestamp), - ), - )); - - if(is_null($activeRow)) - { - // No active row was found so we are ok to go and restore the this - // revision - $timestamp_start_name = static::temporal_property('start_column'); - $mysql_timestamp = static::temporal_property('mysql_timestamp'); - - $max_timestamp = static::temporal_property('max_timestamp'); - $current_timestamp = $mysql_timestamp ? - \Date::forge()->format('mysql') : - \Date::forge()->get_timestamp(); - - // Make sure this is saved as a new entry - $this->_is_new = true; - - // Update timestamps - static::disable_primary_key_check(); - $this->{$timestamp_start_name} = $current_timestamp; - $this->{$timestamp_end_name} = $max_timestamp; - - // Save - $result = parent::save(); - static::enable_primary_key_check(); - - return $result; - } - - return false; - } - - /** - * Deletes all revisions of this entity permantly. - */ - public function purge() - { - // Get a clean query object so there's no temporal filtering - $query = parent::query(); - // Then select and delete - return $query->where('id', $this->id) - ->delete(); - } - - /** - * Overrides update to remove PK checking when performing an update. - */ - public function update() - { - static::disable_primary_key_check(); - $result = parent::update(); - static::enable_primary_key_check(); - - return $result; - } - - /** - * Allows correct PKs to be added when performing updates - * - * @param Query $query - */ - protected function add_primary_keys_to_where($query) - { - $primary_key = static::$_primary_key; - - foreach ($primary_key as $pk) - { - $query->where($pk, '=', $this->_original[$pk]); - } - } - - /** - * Overrides the parent primary_key method to allow primaray key enforcement - * to be turned off when updating a temporal model. - */ - public static function primary_key() - { - $id_only = static::get_primary_key_id_only_status(); - $pk_status = static::get_primary_key_status(); - - if ($id_only) - { - return static::getNonTimestampPks(); - } - - if ($pk_status && ! $id_only) - { - return static::$_primary_key; - } - - return array(); - } - - public function delete($cascade = null, $use_transaction = false) - { - // If we are using a transcation then make sure it's started - if ($use_transaction) - { - $db = \Database_Connection::instance(static::connection(true)); - $db->start_transaction(); - } - - // Call the observers - $this->observe('before_delete'); - - // Load temporal properties. - $timestamp_end_name = static::temporal_property('end_column'); - $mysql_timestamp = static::temporal_property('mysql_timestamp'); - - // Generate the correct timestamp and save it - $current_timestamp = $mysql_timestamp ? - \Date::forge()->format('mysql') : - \Date::forge()->get_timestamp(); - - static::disable_primary_key_check(); - $this->{$timestamp_end_name} = $current_timestamp; - static::enable_primary_key_check(); - - // Loop through all relations and delete if we are cascading. - $this->freeze(); - foreach ($this->relations() as $rel_name => $rel) - { - // get the cascade delete status - $relCascade = is_null($cascade) ? $rel->cascade_delete : (bool) $cascade; - - if ($relCascade) - { - if(get_class($rel) != 'Orm\ManyMany') - { - // Loop through and call delete on all the models - foreach($rel->get($this) as $model) - { - $model->delete($cascade); - } - } - } - } - $this->unfreeze(); - - parent::save(); - - $this->observe('after_delete'); - - // Make sure the transaction is committed if needed - $use_transaction and $db->commit_transaction(); - - return $this; - } - - /** - * Disables PK checking - */ - private static function disable_primary_key_check() - { - $class = get_called_class(); - self::$_pk_check_disabled[$class] = false; - } - - /** - * Enables PK checking - */ - private static function enable_primary_key_check() - { - $class = get_called_class(); - self::$_pk_check_disabled[$class] = true; - } - - /** - * Returns true if the PK checking should be performed. Defaults to true - */ - private static function get_primary_key_status() - { - $class = get_called_class(); - return \Arr::get(self::$_pk_check_disabled, $class, true); - } - - /** - * Returns true if the PK should only contain the ID. Defaults to false - */ - private static function get_primary_key_id_only_status() - { - $class = get_called_class(); - return \Arr::get(self::$_pk_id_only, $class, false); - } - - /** - * Makes all PKs returned - */ - private static function disable_id_only_primary_key() - { - $class = get_called_class(); - self::$_pk_id_only[$class] = false; - } - - /** - * Makes only id returned as PK - */ - private static function enable_id_only_primary_key() - { - $class = get_called_class(); - self::$_pk_id_only[$class] = true; - } - -} diff --git a/fuel/packages/orm/classes/observer.php b/fuel/packages/orm/classes/observer.php deleted file mode 100755 index 152d28e..0000000 --- a/fuel/packages/orm/classes/observer.php +++ /dev/null @@ -1,55 +0,0 @@ -{$event}($instance); - } - } - - /** - * Create an instance of this observer - * - * @param string name of the model class - */ - public static function instance($model_class) - { - $observer = get_called_class(); - if (empty(static::$_instances[$observer][$model_class])) - { - static::$_instances[$observer][$model_class] = new static($model_class); - } - - return static::$_instances[$observer][$model_class]; - } -} diff --git a/fuel/packages/orm/classes/observer/createdat.php b/fuel/packages/orm/classes/observer/createdat.php deleted file mode 100755 index 171af5c..0000000 --- a/fuel/packages/orm/classes/observer/createdat.php +++ /dev/null @@ -1,72 +0,0 @@ -_mysql_timestamp = isset($props['mysql_timestamp']) ? $props['mysql_timestamp'] : static::$mysql_timestamp; - $this->_property = isset($props['property']) ? $props['property'] : static::$property; - $this->_overwrite = isset($props['overwrite']) ? $props['overwrite'] : true; - } - - /** - * Set the CreatedAt property to the current time. - * - * @param Model Model object subject of this observer method - */ - public function before_insert(Model $obj) - { - if ($this->_overwrite or empty($obj->{$this->_property})) - { - $obj->{$this->_property} = $this->_mysql_timestamp ? \Date::time()->format('mysql') : \Date::time()->get_timestamp(); - } - } -} diff --git a/fuel/packages/orm/classes/observer/self.php b/fuel/packages/orm/classes/observer/self.php deleted file mode 100755 index 2d636e1..0000000 --- a/fuel/packages/orm/classes/observer/self.php +++ /dev/null @@ -1,34 +0,0 @@ -_source = isset($props['source']) ? $props['source'] : static::$source; - $this->_property = isset($props['property']) ? $props['property'] : static::$property; - $this->_separator = isset($props['separator']) ? $props['separator'] : static::$separator; - $this->_unique = isset($props['unique']) ? (bool) $props['unique'] : static::$unique; - $this->_overwrite = isset($props['overwrite']) ? (bool) $props['overwrite'] : static::$overwrite; - } - - /** - * Creates a slug (unique by default) and adds it to the object - * - * @param Model Model object subject of this observer method - */ - public function before_insert(Model $obj) - { - // slug should be overwritten if it is enabled to be or there is no manually assigned value - $overwrite = $this->_overwrite === true || empty($obj->{$this->_property}); - $slug = $obj->{$this->_property}; - - // is this a soft model? - if ($obj instanceof Model_Soft) - { - $class = get_class($obj); - - $class::disable_filter(); - } - - // query to check for existence of this slug - $query = $obj->query(); - - // only determine the slug if it should be overwritten - // fill the query with appropriate where condition - if ($overwrite === true) - { - $properties = (array) $this->_source; - $source = ''; - foreach ($properties as $property) - { - $source .= $this->_separator.$obj->{$property}; - } - $slug = \Inflector::friendly_title(substr($source, 1), $this->_separator, true); - - $query->where($this->_property, 'like', $slug.'%'); - } - else - { - $query->where($this->_property, $slug); - } - - if($this->_unique === true) - { - // query to check for existence of this slug - $query = $obj->query()->where($this->_property, 'like', $slug.'%'); - - // is this a temporal model? - if ($obj instanceof Model_Temporal) - { - // add a filter to only check current revisions excluding the current object - $class = get_class($obj); - $query->where($class::temporal_property('end_column'), '=', $class::temporal_property('max_timestamp')); - foreach($class::getNonTimestampPks() as $key) - { - $query->where($key, '!=', $obj->{$key}); - } - } - - // do we have records with this slug? - $same = $query->get(); - - // is this a soft model? - if ($obj instanceof Model_Soft) - { - $class::enable_filter(); - } - - // make sure our slug is unique - if ( ! empty($same)) - { - if ($overwrite === false) - { - throw new \FuelException('Slug ' . $slug . ' already exists.'); - } - - $max = -1; - - foreach ($same as $record) - { - if (preg_match('/^'.$slug.'(?:-([0-9]+))?$/', $record->{$this->_property}, $matches)) - { - $index = isset($matches[1]) ? (int) $matches[1] : 0; - $max < $index and $max = $index; - } - } - - $max < 0 or $slug .= $this->_separator.($max + 1); - } - } - - $obj->{$this->_property} = $slug; - } - - /** - * Creates a new slug (unique by default) and update the object - * - * @param Model Model object subject of this observer method - */ - public function before_update(Model $obj) - { - // determine the slug - $properties = (array) $this->_source; - $source = ''; - foreach ($properties as $property) - { - $source .= $this->_separator.$obj->{$property}; - } - $slug = \Inflector::friendly_title(substr($source, 1), $this->_separator, true); - - // update it if it's different from the current one - // and is not manually assigned - if ($obj->{$this->_property} !== $slug) - { - $overwrite = $this->_overwrite; - - if ($overwrite === false and ! $obj->is_changed($this->_property)) - { - $this->_overwrite = true; - } - - $this->before_insert($obj); - - $this->_overwrite = $overwrite; - } - } -} diff --git a/fuel/packages/orm/classes/observer/typing.php b/fuel/packages/orm/classes/observer/typing.php deleted file mode 100755 index a85093f..0000000 --- a/fuel/packages/orm/classes/observer/typing.php +++ /dev/null @@ -1,666 +0,0 @@ - 'before', - 'after_save' => 'after', - 'after_load' => 'after', - ); - - /** - * @var array db type mappings - */ - public static $type_mappings = array( - 'tinyint' => 'int', - 'smallint' => 'int', - 'mediumint' => 'int', - 'bigint' => 'int', - 'integer' => 'int', - 'double' => 'float', - 'decimal' => 'float', - 'tinytext' => 'text', - 'mediumtext' => 'text', - 'longtext' => 'text', - 'boolean' => 'bool', - 'time_unix' => 'time', - 'time_mysql' => 'time', - ); - - /** - * @var array db data types with the method(s) to use, optionally pre- or post-database - */ - public static $type_methods = array( - 'varchar' => array( - 'before' => 'Orm\\Observer_Typing::type_string', - ), - 'int' => array( - 'before' => 'Orm\\Observer_Typing::type_integer', - 'after' => 'Orm\\Observer_Typing::type_integer', - ), - 'float' => array( - 'before' => 'Orm\\Observer_Typing::type_float_before', - 'after' => 'Orm\\Observer_Typing::type_float_after', - ), - 'text' => array( - 'before' => 'Orm\\Observer_Typing::type_string', - ), - 'set' => array( - 'before' => 'Orm\\Observer_Typing::type_set_before', - 'after' => 'Orm\\Observer_Typing::type_set_after', - ), - 'enum' => array( - 'before' => 'Orm\\Observer_Typing::type_set_before', - ), - 'bool' => array( - 'before' => 'Orm\\Observer_Typing::type_bool_to_int', - 'after' => 'Orm\\Observer_Typing::type_bool_from_int', - ), - 'serialize' => array( - 'before' => 'Orm\\Observer_Typing::type_serialize', - 'after' => 'Orm\\Observer_Typing::type_unserialize', - ), - 'encrypt' => array( - 'before' => 'Orm\\Observer_Typing::type_encrypt', - 'after' => 'Orm\\Observer_Typing::type_decrypt', - ), - 'json' => array( - 'before' => 'Orm\\Observer_Typing::type_json_encode', - 'after' => 'Orm\\Observer_Typing::type_json_decode', - ), - 'time' => array( - 'before' => 'Orm\\Observer_Typing::type_time_encode', - 'after' => 'Orm\\Observer_Typing::type_time_decode', - ), - ); - - /** - * @var array regexes for db types with the method(s) to use, optionally pre- or post-database - */ - public static $regex_methods = array( - '/^decimal:([0-9])/uiD' => array( - 'before' => 'Orm\\Observer_Typing::type_decimal_before', - 'after' => 'Orm\\Observer_Typing::type_decimal_after', - ), - ); - - /** - */ - public static $use_locale = true; - - /** - * Make sure the orm config is loaded - */ - public static function _init() - { - \Config::load('orm', true); - - static::$use_locale = \Config::get('orm.use_locale', static::$use_locale); - } - - /** - * Get notified of an event - * - * @param Model $instance - * @param string $event - */ - public static function orm_notify(Model $instance, $event) - { - // if we don't serve this event, bail out immediately - if (array_key_exists($event, static::$events)) - { - // get the event type of the event that triggered us - $event_type = static::$events[$event]; - - // fetch the model's properties - $properties = $instance->properties(); - - // and check if we need to do any datatype conversions - foreach ($properties as $p => $settings) - { - // the property is part of the primary key, skip it - if (in_array($p, $instance->primary_key())) - { - continue; - } - - $instance->{$p} = static::typecast($p, $instance->{$p}, $settings, $event_type); - } - } - } - - /** - * Typecast a single column value based on the model properties for that column - * - * @param string $column name of the column - * @param string $value value - * @param string $settings column settings from the model - * - * @throws InvalidContentType - * - * @return mixed - */ - public static function typecast($column, $value, $settings, $event_type = 'before') - { - // only on before_save, check if null is allowed - if ($value === null) - { - // only on before_save - if ($event_type == 'before') - { - if (array_key_exists('null', $settings) and $settings['null'] === false) - { - // if a default is defined, return that instead - if (array_key_exists('default', $settings)) - { - return $settings['default']; - } - - throw new InvalidContentType('The property "'.$column.'" cannot be NULL.'); - } - } - return $value; - } - - // no datatype given - if (empty($settings['data_type'])) - { - return $value; - } - - // get the data type for this column - $data_type = $settings['data_type']; - - // is this a base data type? - if ( ! isset(static::$type_methods[$data_type])) - { - // no, can we map it to one? - if (isset(static::$type_mappings[$data_type])) - { - // yes, so swap it for a base data type - $data_type = static::$type_mappings[$data_type]; - } - else - { - // can't be mapped, check the regexes - foreach (static::$regex_methods as $match => $methods) - { - // fetch the method - $method = ! empty($methods[$event_type]) ? $methods[$event_type] : false; - - if ($method) - { - if (preg_match_all($match, $data_type, $matches) > 0) - { - $value = call_user_func($method, $value, $settings, $matches); - } - } - } - return $value; - } - } - - // fetch the method - $method = ! empty(static::$type_methods[$data_type][$event_type]) ? static::$type_methods[$data_type][$event_type] : false; - - // if one was found, call it - if ($method) - { - $value = call_user_func($method, $value, $settings); - } - - return $value; - } - - /** - * Casts to string when necessary and checks if within max length - * - * @param mixed value to typecast - * @param array any options to be passed - * - * @throws InvalidContentType - * - * @return string - */ - public static function type_string($var, array $settings) - { - if (is_array($var) or (is_object($var) and ! method_exists($var, '__toString'))) - { - throw new InvalidContentType('Array or object could not be converted to varchar.'); - } - - $var = strval($var); - - if (array_key_exists('character_maximum_length', $settings)) - { - $length = intval($settings['character_maximum_length']); - if ($length > 0 and strlen($var) > $length) - { - $var = substr($var, 0, $length); - } - } - - return $var; - } - - /** - * Casts to int when necessary and checks if within max values - * - * @param mixed value to typecast - * @param array any options to be passed - * - * @throws InvalidContentType - * - * @return int - */ - public static function type_integer($var, array $settings) - { - if (is_array($var) or is_object($var)) - { - throw new InvalidContentType('Array or object could not be converted to integer.'); - } - - if ((array_key_exists('min', $settings) and $var < intval($settings['min'])) - or (array_key_exists('max', $settings) and $var > intval($settings['max']))) - { - throw new InvalidContentType('Integer value outside of range: '.$var); - } - - return intval($var); - } - - /** - * Casts float to string when necessary - * - * @param mixed value to typecast - * - * @throws InvalidContentType - * - * @return float - */ - public static function type_float_before($var, $settings = null) - { - if (is_array($var) or is_object($var)) - { - throw new InvalidContentType('Array or object could not be converted to float.'); - } - - // do we need to do locale conversion? - if (is_string($var) and static::$use_locale) - { - $locale_info = localeconv(); - $var = str_replace($locale_info["mon_thousands_sep"], "", $var); - $var = str_replace($locale_info["mon_decimal_point"], ".", $var); - } - - // was a specific float format specified? - if (isset($settings['db_decimals'])) - { - return sprintf('%.'.$settings['db_decimals'].'F', (float) $var); - } - if (isset($settings['data_type']) and strpos($settings['data_type'], 'decimal:') === 0) - { - $decimal = explode(':', $settings['data_type']); - return sprintf('%.'.$decimal[1].'F', (float) $var); - } - - return sprintf('%F', (float) $var); - } - - /** - * Casts to float when necessary - * - * @param mixed value to typecast - * - * @throws InvalidContentType - * - * @return float - */ - public static function type_float_after($var) - { - if (is_array($var) or is_object($var)) - { - throw new InvalidContentType('Array or object could not be converted to float.'); - } - - return floatval($var); - } - - /** - * Decimal pre-treater, converts a decimal representation to a float - * - * @param mixed value to typecast - * - * @throws InvalidContentType - * - * @return float - */ - public static function type_decimal_before($var, $settings = null) - { - if (is_array($var) or is_object($var)) - { - throw new InvalidContentType('Array or object could not be converted to decimal.'); - } - - return static::type_float_before($var, $settings); - } - - /** - * Decimal post-treater, converts any number to a decimal representation - * - * @param mixed value to typecast - * - * @throws InvalidContentType - * - * @return float - */ - public static function type_decimal_after($var, array $settings, array $matches) - { - if (is_array($var) or is_object($var)) - { - throw new InvalidContentType('Array or object could not be converted to decimal.'); - } - - if ( ! is_numeric($var)) - { - throw new InvalidContentType('Value '.$var.' is not numeric and can not be converted to decimal.'); - } - - $dec = empty($matches[1][0]) ? 2 : $matches[1][0]; - - // do we need to do locale aware conversion? - if (static::$use_locale) - { - return sprintf("%.".$dec."f", static::type_float_after($var)); - } - - return sprintf("%.".$dec."F", static::type_float_after($var)); - } - - /** - * Value pre-treater, deals with array values, and handles the enum type - * - * @param mixed value - * @param array any options to be passed - * - * @throws InvalidContentType - * - * @return string - */ - public static function type_set_before($var, array $settings) - { - $var = is_array($var) ? implode(',', $var) : strval($var); - $values = array_filter(explode(',', trim($var))); - - if ($settings['data_type'] == 'enum' and count($values) > 1) - { - throw new InvalidContentType('Enum cannot have more than 1 value.'); - } - - foreach ($values as $val) - { - if ( ! in_array($val, $settings['options'])) - { - throw new InvalidContentType('Invalid value given for '.ucfirst($settings['data_type']). - ', value "'.$var.'" not in available options: "'.implode(', ', $settings['options']).'".'); - } - } - - return $var; - } - - /** - * Value post-treater, converts a comma-delimited string into an array - * - * @param mixed value - * - * @return array - */ - public static function type_set_after($var) - { - return explode(',', $var); - } - - /** - * Converts boolean input to 1 or 0 for the DB - * - * @param bool value - * - * @return int - */ - public static function type_bool_to_int($var) - { - return $var ? 1 : 0; - } - - /** - * Converts DB bool values to PHP bool value - * - * @param bool value - * - * @return int - */ - public static function type_bool_from_int($var) - { - return $var == '1' ? true : false; - } - - /** - * Returns the serialized input - * - * @param mixed value - * @param array any options to be passed - * - * @throws InvalidContentType - * - * @return string - */ - public static function type_serialize($var, array $settings) - { - $var = serialize($var); - - if (array_key_exists('character_maximum_length', $settings)) - { - $length = intval($settings['character_maximum_length']); - if ($length > 0 and strlen($var) > $length) - { - throw new InvalidContentType('Value could not be serialized, result exceeds max string length for field.'); - } - } - - return $var; - } - - /** - * Unserializes the input - * - * @param string value - * - * @return mixed - */ - public static function type_unserialize($var) - { - return empty($var) ? array() : unserialize($var); - } - - /** - * Returns the encrypted input - * - * @param mixed value - * @param array any options to be passed - * - * @throws InvalidContentType - * - * @return string - */ - public static function type_encrypt($var, array $settings) - { - // make the variable serialized, we need to be able to encrypt any variable type - $var = static::type_serialize($var, $settings); - - // and encrypt it - if (array_key_exists('encryption_key', $settings)) - { - $var = \Crypt::encode($var, $settings['encryption_key']); - } - else - { - $var = \Crypt::encode($var); - } - - // do a length check if needed - if (array_key_exists('character_maximum_length', $settings)) - { - $length = intval($settings['character_maximum_length']); - if ($length > 0 and strlen($var) > $length) - { - throw new InvalidContentType('Value could not be encrypted, result exceeds max string length for field.'); - } - } - - return $var; - } - - /** - * decrypt the input - * - * @param string value - * - * @return mixed - */ - public static function type_decrypt($var) - { - // decrypt it - if (array_key_exists('encryption_key', $settings)) - { - $var = \Crypt::decode($var, $settings['encryption_key']); - } - else - { - $var = \Crypt::decode($var); - } - - return $var; - } - - /** - * JSON encodes the input - * - * @param mixed value - * @param array any options to be passed - * - * @throws InvalidContentType - * - * @return string - */ - public static function type_json_encode($var, array $settings) - { - $var = json_encode($var); - - if (array_key_exists('character_maximum_length', $settings)) - { - $length = intval($settings['character_maximum_length']); - if ($length > 0 and strlen($var) > $length) - { - throw new InvalidContentType('Value could not be JSON encoded, exceeds max string length for field.'); - } - } - - return $var; - } - - /** - * Decodes the JSON - * - * @param string value - * - * @return mixed - */ - public static function type_json_decode($var, $settings) - { - $assoc = false; - if (array_key_exists('json_assoc', $settings)) - { - $assoc = (bool) $settings['json_assoc']; - } - return json_decode($var, $assoc); - } - - /** - * Takes a Date instance and transforms it into a DB timestamp - * - * @param \Fuel\Core\Date value - * @param array any options to be passed - * - * @throws InvalidContentType - * - * @return int|string - */ - public static function type_time_encode(\Fuel\Core\Date $var, array $settings) - { - if ( ! $var instanceof \Fuel\Core\Date) - { - throw new InvalidContentType('Value must be an instance of the Date class.'); - } - - if ($settings['data_type'] == 'time_mysql') - { - return $var->format('mysql'); - } - - return $var->get_timestamp(); - } - - /** - * Takes a DB timestamp and converts it into a Date object - * - * @param string value - * @param array any options to be passed - * - * @return \Fuel\Core\Date - */ - public static function type_time_decode($var, array $settings) - { - if ($settings['data_type'] == 'time_mysql') - { - // deal with a 'nulled' date, which according to MySQL is a valid enough to store? - if ($var == '0000-00-00 00:00:00') - { - if (array_key_exists('null', $settings) and $settings['null'] === false) - { - throw new InvalidContentType('Value '.$var.' is not a valid date and can not be converted to a Date object.'); - } - return null; - } - - return \Date::create_from_string($var, 'mysql'); - } - - return \Date::forge($var); - } -} diff --git a/fuel/packages/orm/classes/observer/updatedat.php b/fuel/packages/orm/classes/observer/updatedat.php deleted file mode 100755 index 10410e4..0000000 --- a/fuel/packages/orm/classes/observer/updatedat.php +++ /dev/null @@ -1,140 +0,0 @@ -_mysql_timestamp = isset($props['mysql_timestamp']) ? $props['mysql_timestamp'] : static::$mysql_timestamp; - $this->_property = isset($props['property']) ? $props['property'] : static::$property; - $this->_relations = isset($props['relations']) ? $props['relations'] : array(); - } - - /** - * Set the UpdatedAt property to the current time. - * - * @param Model Model object subject of this observer method - */ - public function before_save(Model $obj) - { - $this->before_update($obj); - } - - /** - * Set the UpdatedAt property to the current time. - * - * @param Model Model object subject of this observer method - */ - public function before_update(Model $obj) - { - // If there are any relations loop through and check if any of them have been changed - $relation_changed = false; - foreach ( $this->_relations as $relation) - { - if ($this->relation_changed($obj, $relation)) - { - $relation_changed = true; - break; - } - } - - $objClassName = get_class($obj); - $objProperties = $objClassName::properties(); - - if ($obj->is_changed(array_keys($objProperties)) or $relation_changed) - { - $obj->{$this->_property} = $this->_mysql_timestamp ? \Date::time()->format('mysql') : \Date::time()->get_timestamp(); - } - } - - /** - * Checks to see if any models in the given relation are changed. This function is lazy so will return true as soon - * as it finds something that has changed. - * - * @param Model $obj - * @param string $relation - * - * @return bool - */ - protected function relation_changed(Model $obj, $relation) - { - // Check that the relation exists - if ($obj->relations($relation) === false) - { - throw new \InvalidArgumentException('Unknown relation '.$relation); - } - - // If the relation is not loaded then ignore it. - if ( ! $obj->is_fetched($relation)) - { - return false; - } - - $relation_object = $obj->relations($relation); - - // Check if whe have a singular relation - if ($relation_object->is_singular()) - { - // If so check that one model - return $obj->{$relation}->is_changed(); - } - - // Else we have an array of related objects so start checking them all - foreach ($obj->{$relation} as $related_model) - { - if ($related_model->is_changed()) - { - return true; - } - } - - return false; - } -} diff --git a/fuel/packages/orm/classes/observer/validation.php b/fuel/packages/orm/classes/observer/validation.php deleted file mode 100755 index a8e5e24..0000000 --- a/fuel/packages/orm/classes/observer/validation.php +++ /dev/null @@ -1,244 +0,0 @@ -fieldset = $fieldset; - } - - /** - * Gets the Fieldset from this exception - * - * @return Fieldset - */ - public function get_fieldset() - { - return $this->fieldset; - } -} - -/** - * Observer class to validate the properties of the model before save. - * - * It is also used in Fieldset generation based on a model, to populate the fields - * and field validation rules of the Fieldset. - */ -class Observer_Validation extends Observer -{ - /** - * Set a Model's properties as fields on a Fieldset, which will be created with the Model's - * classname if none is provided. - * - * @param string - * @param \Fieldset|null - * @return \Fieldset - */ - public static function set_fields($obj, $fieldset = null) - { - static $_generated = array(); - static $_tabular_rows = array(); - - $class = is_object($obj) ? get_class($obj) : $obj; - if (is_null($fieldset)) - { - $fieldset = \Fieldset::instance($class); - if ( ! $fieldset) - { - $fieldset = \Fieldset::forge($class); - } - } - - // is our parent fieldset a tabular form set? - $tabular_form = is_object($fieldset->parent()) ? $fieldset->parent()->get_tabular_form() : false; - - // don't cache tabular form fieldsets - if ( ! $tabular_form) - { - ! array_key_exists($class, $_generated) and $_generated[$class] = array(); - if (in_array($fieldset, $_generated[$class], true)) - { - return $fieldset; - } - $_generated[$class][] = $fieldset; - } - - $primary_keys = is_object($obj) ? $obj->primary_key() : $class::primary_key(); - $primary_key = count($primary_keys) === 1 ? reset($primary_keys) : false; - $properties = is_object($obj) ? $obj->properties() : $class::properties(); - - if ($tabular_form and $primary_key and ! is_object($obj)) - { - isset($_tabular_rows[$class]) or $_tabular_rows[$class] = 0; - } - - foreach ($properties as $p => $settings) - { - if (\Arr::get($settings, 'skip', in_array($p, $primary_keys))) - { - continue; - } - - if (isset($settings['form']['options'])) - { - foreach ($settings['form']['options'] as $key => $value) - { - is_array($value) or $settings['form']['options'][$key] = \Lang::get($value, array(), false) ?: $value; - } - } - - // field attributes can be passed in form key - $attributes = isset($settings['form']) ? $settings['form'] : array(); - // label is either set in property setting, as part of form attributes or defaults to fieldname - $label = isset($settings['label']) ? $settings['label'] : (isset($attributes['label']) ? $attributes['label'] : $p); - $label = \Lang::get($label, array(), false) ?: $label; - - // change the fieldname and label for tabular form fieldset children - if ($tabular_form and $primary_key) - { - if (is_object($obj)) - { - $p = $tabular_form.'['.$obj->{$primary_key}.']['.$p.']'; - } - else - { - $p = $tabular_form.'_new['.$_tabular_rows[$class].']['.$p.']'; - } - $label = ''; - } - - // create the field and add validation rules - $field = $fieldset->add($p, $label, $attributes); - if ( ! empty($settings['validation'])) - { - foreach ($settings['validation'] as $rule => $args) - { - if (is_int($rule) and is_string($args)) - { - $args = array($args); - } - else - { - array_unshift($args, $rule); - } - - call_fuel_func_array(array($field, 'add_rule'), $args); - } - } - } - - // increase the row counter for tabular row fieldsets - if ($tabular_form and $primary_key and ! is_object($obj)) - { - $_tabular_rows[$class]++; - } - - return $fieldset; - } - - /** - * Execute before saving the Model - * - * @param Model the model object to validate - * - * @throws ValidationFailed - */ - public function before_save(Model $obj) - { - $this->validate($obj); - } - - /** - * Execute before inserting the row in the database - * - * @param Model the model object to validate - * - * @throws ValidationFailed - */ - public function before_insert(Model $obj) - { - $this->validate($obj); - } - - /** - * Execute before updating the row in the database - * - * @param Model the model object to validate - * - * @throws ValidationFailed - */ - public function before_update(Model $obj) - { - $this->validate($obj); - } - - /** - * Validate the model - * - * @param Model the model object to validate - * - * @throws ValidationFailed - */ - public function validate(Model $obj) - { - $fieldset = static::set_fields($obj); - $val = $fieldset->validation(); - - $is_new = $obj->is_new(); - - // only allow partial validation on updates, specify the fields for updates to allow null - $allow_partial = $is_new ? false : array(); - - $input = array(); - foreach (array_keys($obj->properties()) as $p) - { - if ( ! in_array($p, $obj->primary_key()) and ($is_new or $obj->is_changed($p))) - { - $input[$p] = $obj->{$p}; - is_array($allow_partial) and $allow_partial[] = $p; - } - } - - if ( ! empty($input) and $val->run($input, $allow_partial, array($obj)) === false) - { - throw new ValidationFailed($val->show_errors(), 0, null, $fieldset); - } - else - { - foreach ($input as $k => $v) - { - $obj->{$k} = $val->validated($k); - } - } - } -} diff --git a/fuel/packages/orm/classes/query.php b/fuel/packages/orm/classes/query.php deleted file mode 100755 index a1b6cfd..0000000 --- a/fuel/packages/orm/classes/query.php +++ /dev/null @@ -1,1822 +0,0 @@ -from_cache = (bool) static::$caching; - } - - $this->model = $model; - - if (is_array($connection)) - { - list($this->connection, $this->write_connection) = $connection; - } - else - { - $this->connection = $connection; - $this->write_connection = $connection; - } - - foreach ($options as $opt => $val) - { - switch ($opt) - { - case 'select': - $val = (array) $val; - call_fuel_func_array(array($this, 'select'), $val); - break; - case 'related': - $val = (array) $val; - $this->related($val); - break; - case 'use_view': - $this->use_view($val); - break; - case 'or_where': - $this->and_where_open(); - foreach ($val as $where) - { - call_fuel_func_array(array($this, '_where'), array($where, 'or_where')); - } - $this->and_where_close(); - break; - case 'where': - $this->_parse_where_array($val); - break; - case 'order_by': - $val = (array) $val; - $this->order_by($val); - break; - case 'group_by': - call_fuel_func_array(array($this, 'group_by'), $val); - break; - case 'limit': - $this->limit($val); - break; - case 'offset': - $this->offset($val); - break; - case 'rows_limit': - $this->rows_limit($val); - break; - case 'rows_offset': - $this->rows_offset($val); - break; - case 'from_cache': - $this->from_cache($val); - break; - } - } - } - - /** - * Does the work for where() and or_where() - * - * @param array $condition - * @param string $type - * - * @throws \FuelException - * - * @return $this - */ - public function _where($condition, $type = 'and_where') - { - if (is_array(reset($condition)) or is_string(key($condition))) - { - foreach ($condition as $k_c => $v_c) - { - is_string($k_c) and $v_c = array($k_c, $v_c); - $this->_where($v_c, $type); - } - return $this; - } - - // prefix table alias when not yet prefixed and not a DB expression object - if (strpos($condition[0], '.') === false and ! $condition[0] instanceof \Fuel\Core\Database_Expression) - { - $condition[0] = $this->alias.'.'.$condition[0]; - } - - if (count($condition) == 2) - { - $this->where[] = array($type, array($condition[0], '=', $condition[1])); - } - elseif (count($condition) == 3 or $condition[0] instanceof \Fuel\Core\Database_Expression) - { - $this->where[] = array($type, $condition); - } - else - { - throw new \FuelException('Invalid param count for where condition.'); - } - - return $this; - } - - /** - * Does the work for having() and or_having() - * - * @param array $condition - * @param string $type - * - * @throws \FuelException - * - * @return $this - */ - public function _having($condition, $type = 'and_having') - { - if (is_array(reset($condition)) or is_string(key($condition))) - { - foreach ($condition as $k_c => $v_c) - { - is_string($k_c) and $v_c = array($k_c, $v_c); - $this->_having($v_c, $type); - } - return $this; - } - - // prefix table alias when not yet prefixed and not a DB expression object - if (strpos($condition[0], '.') === false and ! $condition[0] instanceof \Fuel\Core\Database_Expression) - { - $condition[0] = $this->alias.'.'.$condition[0]; - } - - if (count($condition) == 2) - { - $this->having[] = array($type, array($condition[0], '=', $condition[1])); - } - elseif (count($condition) == 3 or $condition[0] instanceof \Fuel\Core\Database_Expression) - { - $this->having[] = array($type, $condition); - } - else - { - throw new \FuelException('Invalid param count for having condition.'); - } - - return $this; - } - - /** - * Parses an array of where conditions into the query - * - * @param array $val - * @param string $base - * @param bool $or - */ - public function _parse_where_array(array $val, $base = '', $or = false) - { - $or and $this->or_where_open(); - foreach ($val as $k_w => $v_w) - { - if (is_array($v_w) and ! empty($v_w[0]) and (is_string($v_w[0]) or $v_w[0] instanceof \Database_Expression)) - { - ! $v_w[0] instanceof \Database_Expression and strpos($v_w[0], '.') === false and $v_w[0] = $base.$v_w[0]; - call_fuel_func_array(array($this, ($k_w === 'or' ? 'or_' : '').'where'), $v_w); - } - elseif (is_int($k_w) or $k_w == 'or') - { - $k_w === 'or' ? $this->or_where_open() : $this->where_open(); - $this->_parse_where_array($v_w, $base, $k_w === 'or'); - $k_w === 'or' ? $this->or_where_close() : $this->where_close(); - } - else - { - ! $k_w instanceof \Database_Expression and strpos($k_w, '.') === false and $k_w = $base.$k_w; - $this->where($k_w, $v_w); - } - } - $or and $this->or_where_close(); - } - - /** - /* normalize the select fields passed - * - * @param array list of columns to select - * @param int counter of the number of selected columnss - */ - protected function _normalize($fields, &$i) - { - $select = array(); - - // for BC reasons, deal with the odd array(DB::expr, 'name') syntax first - if (($value = reset($fields)) instanceOf \Fuel\Core\Database_Expression and is_string($index = next($fields))) - { - $select[$this->alias.'_c'.$i++] = $fields; - } - - // otherwise iterate - else - { - foreach ($fields as $index => $value) - { - // an array of field definitions is passed - if (is_array($value)) - { - // recurse and add them individually - $select = array_merge($select, $this->_normalize($value, $i)); - } - - // a "field -> include" value pair is passed - elseif (is_bool($value)) - { - if ($value) - { - // if include is true, add the field - $select[$this->alias.'_c'.$i++] = (strpos($index, '.') === false ? $this->alias.'.' : '').$index; - } - else - { - // if not, add it to the filter list - if ( ! in_array($index, $this->select_filter)) - { - $this->select_filter[] = $index; - } - } - } - - // attempted a "SELECT *"? - elseif ($value === '*') - { - // recurse and add all model properties - $select = array_merge($select, $this->_normalize(array_keys(call_user_func($this->model.'::properties')), $i)); - } - - // DB::expr() passed? - elseif ($value instanceOf \Fuel\Core\Database_Expression) - { - // no column name given for the result? - if (is_numeric($index)) - { - $select[$this->alias.'_c'.$i++] = array($value); - } - - // add the index as the column name - else - { - $select[$this->alias.'_c'.$i++] = array($value, $index); - } - } - - // must be a regular field - else - { - $select[$this->alias.'_c'.$i++] = (strpos($value, '.') === false ? $this->alias.'.' : '').$value; - } - } - } - - return $select; - } - - /** - * Returns target table (or view, if specified). - */ - protected function _table() - { - return $this->view ? $this->view['view'] : call_user_func($this->model.'::table'); - } - - /** - * Sets the name of the connection to use for this query. Set to null to use the default DB connection - * - * @param string $name - */ - public function connection($name) - { - $this->connection = $name; - return $this; - } - - /** - * Enables or disables the object cache for this query - * - * @param bool $cache Whether or not to use the object cache on this query - * - * @return Query - */ - public function from_cache($cache = true) - { - $this->from_cache = (bool) $cache; - - return $this; - } - - /** - * Select which properties are included, each as its own param. Or don't give input to retrieve - * the current selection. - * - * @param bool $add_pks Whether or not to add the Primary Keys to the list of selected columns - * @param string|array $fields Optionally. Which field/fields must be retrieved - * - * @throws \FuelException No properties found in model - * - * @return void|array - */ - public function select($add_pks = true) - { - $fields = func_get_args(); - - if (empty($fields) or is_bool($add_pks)) - { - if (empty($this->select)) - { - $fields = array_keys(call_user_func($this->model.'::properties')); - - if (empty($fields)) - { - throw new \FuelException('No properties found in model.'); - } - foreach ($fields as $field) - { - in_array($field, $this->select_filter) or $this->select($field); - } - - if ($this->view) - { - foreach ($this->view['columns'] as $field) - { - $this->select($field); - } - } - } - - // backup select before adding PKs - $select = $this->select; - - // ensure all PKs are being selected - if ($add_pks) - { - $pks = call_user_func($this->model.'::primary_key'); - foreach($pks as $pk) - { - if ( ! in_array($this->alias.'.'.$pk, $this->select)) - { - $this->select($pk); - } - } - } - - // convert selection array for DB class - $out = array(); - foreach($this->select as $k => $v) - { - $out[] = is_array($v) ? array($v[0], $k) : array($v, $k); - } - - // set select back to before the PKs were added - $this->select = $select; - - return $out; - } - - // get the current select count - $i = count($this->select); - - // parse the passed fields list - $this->select = array_merge($this->select, $this->_normalize($fields, $i)); - - return $this; - } - - /** - * Set a view to use instead of the table - * - * @param string $view Name of view which you want to use - * - * @throws \OutOfBoundsException Cannot use undefined database view, must be defined with Model - * - * @return Query - */ - public function use_view($view) - { - $views = call_user_func(array($this->model, 'views')); - if ( ! array_key_exists($view, $views)) - { - throw new \OutOfBoundsException('Cannot use undefined database view, must be defined with Model.'); - } - - $this->view = $views[$view]; - $this->view['_name'] = $view; - return $this; - } - - /** - * Creates a "GROUP BY ..." filter. - * - * @param mixed $coulmns Column name or array($column, $alias) or object - * @return $this - */ - public function group_by() - { - $columns = func_get_args(); - - $this->group_by = array_merge($this->group_by, $columns); - - return $this; - } - - /** - * Set the limit - * - * @param int $limit - * - * @return $this - */ - public function limit($limit) - { - $this->limit = intval($limit); - - return $this; - } - - /** - * Set the offset - * - * @param int $offset - * - * @return $this - */ - public function offset($offset) - { - $this->offset = intval($offset); - - return $this; - } - - /** - * Set the limit of rows requested - * - * @param int $limit - * - * @return $this - */ - public function rows_limit($limit) - { - $this->rows_limit = intval($limit); - - return $this; - } - - /** - * Set the offset of rows requested - * - * @param int $offset - * - * @return $this - */ - public function rows_offset($offset) - { - $this->rows_offset = intval($offset); - - return $this; - } - - /** - * Set where condition - * - * @param string Property - * @param string Comparison type (can be omitted) - * @param string Comparison value - * - * @return $this - */ - public function where() - { - $condition = func_get_args(); - is_array(reset($condition)) and $condition = reset($condition); - - return $this->_where($condition); - } - - /** - * Set or_where condition - * - * @param string Property - * @param string Comparison type (can be omitted) - * @param string Comparison value - * - * @return $this - */ - public function or_where() - { - $condition = func_get_args(); - is_array(reset($condition)) and $condition = reset($condition); - - return $this->_where($condition, 'or_where'); - } - - /** - * Open a nested and_where condition - * - * @return $this - */ - public function and_where_open() - { - $this->where[] = array('and_where_open', array()); - - return $this; - } - - /** - * Close a nested and_where condition - * - * @return $this - */ - public function and_where_close() - { - $this->where[] = array('and_where_close', array()); - - return $this; - } - - /** - * Alias to and_where_open() - * - * @return $this - */ - public function where_open() - { - $this->where[] = array('and_where_open', array()); - - return $this; - } - - /** - * Alias to and_where_close() - * - * @return $this - */ - public function where_close() - { - $this->where[] = array('and_where_close', array()); - - return $this; - } - - /** - * Open a nested or_where condition - * - * @return $this - */ - public function or_where_open() - { - $this->where[] = array('or_where_open', array()); - - return $this; - } - - /** - * Close a nested or_where condition - * - * @return $this - */ - public function or_where_close() - { - $this->where[] = array('or_where_close', array()); - - return $this; - } - - /** - * Set having condition - * - * @param string Property - * @param string Comparison type (can be omitted) - * @param string Comparison value - * - * @return $this - */ - public function having() - { - $condition = func_get_args(); - is_array(reset($condition)) and $condition = reset($condition); - - return $this->_having($condition); - } - - /** - * Set or_having condition - * - * @param string Property - * @param string Comparison type (can be omitted) - * @param string Comparison value - * - * @return $this - */ - public function or_having() - { - $condition = func_get_args(); - is_array(reset($condition)) and $condition = reset($condition); - - return $this->_having($condition, 'or_having'); - } - - /** - * Open a nested and_having condition - * - * @return $this - */ - public function and_having_open() - { - $this->having[] = array('and_having_open', array()); - - return $this; - } - - /** - * Close a nested and_where condition - * - * @return $this - */ - public function and_having_close() - { - $this->having[] = array('and_having_close', array()); - - return $this; - } - - /** - * Alias to and_having_open() - * - * @return $this - */ - public function having_open() - { - $this->having[] = array('and_having_open', array()); - - return $this; - } - - /** - * Alias to and_having_close() - * - * @return $this - */ - public function having_close() - { - $this->having[] = array('and_having_close', array()); - - return $this; - } - - /** - * Open a nested or_having condition - * - * @return $this - */ - public function or_having_open() - { - $this->having[] = array('or_having_open', array()); - - return $this; - } - - /** - * Close a nested or_where condition - * - * @return $this - */ - public function or_having_close() - { - $this->having[] = array('or_having_close', array()); - - return $this; - } - - /** - * Set the order_by - * - * @param string|array $property - * @param string $direction - * - * @return $this - */ - public function order_by($property, $direction = 'ASC') - { - if (is_array($property)) - { - foreach ($property as $p => $d) - { - if (is_int($p)) - { - is_array($d) ? $this->order_by($d[0], $d[1]) : $this->order_by($d, $direction); - } - else - { - $this->order_by($p, $d); - } - } - return $this; - } - - // prefix table alias when not yet prefixed and not a DB expression object - if ( ! $property instanceof \Fuel\Core\Database_Expression and strpos($property, '.') === false) - { - $property = $this->alias.'.'.$property; - } - - $this->order_by[] = array($property, $direction); - - return $this; - } - - /** - * Set a relation to include - * - * @param string $relation - * @param array $conditions Optionally - * - * @throws \UnexpectedValueException Relation was not found in the model - * - * @return $this - */ - public function related($relation, $conditions = array()) - { - if (is_array($relation)) - { - foreach ($relation as $k_r => $v_r) - { - is_array($v_r) ? $this->related($k_r, $v_r) : $this->related($v_r); - } - return $this; - } - - if (strpos($relation, '.')) - { - $rels = explode('.', $relation); - $model = $this->model; - foreach ($rels as $r) - { - $rel = call_user_func(array($model, 'relations'), $r); - if (empty($rel)) - { - throw new \UnexpectedValueException('Relation "'.$r.'" was not found in the model "'.$model.'".'); - } - $model = $rel->model_to; - } - } - else - { - $rel = call_user_func(array($this->model, 'relations'), $relation); - if (empty($rel)) - { - throw new \UnexpectedValueException('Relation "'.$relation.'" was not found in the model.'); - } - } - - $this->relations[$relation] = array($rel, $conditions); - - if ( ! empty($conditions['related'])) - { - $conditions['related'] = (array) $conditions['related']; - foreach ($conditions['related'] as $k_r => $v_r) - { - is_array($v_r) ? $this->related($relation.'.'.$k_r, $v_r) : $this->related($relation.'.'.$v_r); - } - - unset($conditions['related']); - } - - return $this; - } - - /** - * Add a table to join, consider this a protect method only for Orm package usage - * - * @param array $join - * - * @return $this - */ - public function _join(array $join) - { - $this->joins[] = $join; - - return $this; - } - - /** - * Set any properties for insert or update - * - * @param string|array $property - * @param mixed $value Optionally - * - * @return $this - */ - public function set($property, $value = null) - { - if (is_array($property)) - { - foreach ($property as $p => $v) - { - $this->set($p, $v); - } - return $this; - } - - $this->values[$property] = $value; - - return $this; - } - - /** - * Build a select, delete or update query - * - * @param \Fuel\Core\Database_Query_Builder_Where DB where() query object - * @param array $columns Optionally - * @param string $type Type of query to build (count/select/update/delete/insert) - * - * @throws \FuelException Models cannot be related between different database connections - * @throws \UnexpectedValueException Trying to get the relation of an unloaded relation - * - * @return array with keys query and relations - */ - public function build_query(\Fuel\Core\Database_Query_Builder_Where $query, $columns = array(), $type = 'select') - { - // Are we generating a read or a write query? - $read_query = ! in_array($type, array('insert', 'update', 'delete')); - - // Get the limit - if ( ! is_null($this->limit)) - { - $query->limit($this->limit); - } - - // Get the offset - if ( ! is_null($this->offset)) - { - $query->offset($this->offset); - } - - $where_conditions = call_user_func($this->model.'::condition', 'where'); - empty($where_conditions) or $this->_parse_where_array($where_conditions); - - $where_backup = $this->where; - if ( ! empty($this->where)) - { - $open_nests = 0; - $where_nested = array(); - $include_nested = true; - foreach ($this->where as $key => $w) - { - list($method, $conditional) = $w; - - if ($read_query and (empty($conditional) or $open_nests > 0)) - { - $include_nested and $where_nested[$key] = $w; - if ( ! empty($conditional) and strpos($conditional[0], $this->alias.'.') !== 0) - { - $include_nested = false; - } - strpos($method, '_open') and $open_nests++; - strpos($method, '_close') and $open_nests--; - continue; - } - - if (empty($conditional) - or strpos($conditional[0], $this->alias.'.') === 0 - or ( ! $read_query and $conditional[0] instanceof \Fuel\Core\Database_Expression)) - { - if ( ! $read_query and ! empty($conditional) - and ! $conditional[0] instanceof \Fuel\Core\Database_Expression) - { - $conditional[0] = substr($conditional[0], strlen($this->alias.'.')); - } - call_fuel_func_array(array($query, $method), $conditional); - unset($this->where[$key]); - } - } - - if ($include_nested and ! empty($where_nested)) - { - foreach ($where_nested as $key => $w) - { - list($method, $conditional) = $w; - - if (empty($conditional) - or strpos($conditional[0], $this->alias.'.') === 0 - or ( ! $read_query and $conditional[0] instanceof \Fuel\Core\Database_Expression)) - { - if ( ! $read_query and ! empty($conditional) - and ! $conditional[0] instanceof \Fuel\Core\Database_Expression) - { - $conditional[0] = substr($conditional[0], strlen($this->alias.'.')); - } - call_fuel_func_array(array($query, $method), $conditional); - unset($this->where[$key]); - } - } - } - } - - // If it's a write query, we're done - if ( ! $read_query) - { - return array('query' => $query, 'models' => array()); - } - - // Alias number counter - $i = 1; - - // Add defined relations - $models = array(); - foreach ($this->relations as $name => $rel) - { - // when there's a dot it must be a nested relation - if ($pos = strrpos($name, '.')) - { - if (empty($models[substr($name, 0, $pos)]['table'][1])) - { - throw new \UnexpectedValueException('Trying to get the relation of an unloaded relation, make sure you load the parent relation before any of its children.'); - } - - $alias = $models[substr($name, 0, $pos)]['table'][1]; - } - else - { - $alias = $this->alias; - } - - $join = $rel[0]->join($alias, $name, $i++, $rel[1]); - $models = array_merge($models, $this->modify_join_result($join, $name)); - } - - // if no order_by was given, see if a default was defined in the model - empty($this->order_by) and $this->order_by(call_user_func($this->model.'::condition', 'order_by')); - - if ($this->use_subquery()) - { - // Count queries should not select on anything besides the count - if ($type != 'count') - { - // Get the columns for final select - foreach ($models as $m) - { - foreach ($m['columns'] as $c) - { - $columns[] = $c; - } - } - } - - // do we need to add order_by clauses on the subquery? - foreach ($this->order_by as $idx => $ob) - { - if ( ! $ob[0] instanceof \Fuel\Core\Database_Expression) - { - if (strpos($ob[0], $this->alias.'.') === 0) - { - // order by on the current model - $query->order_by($ob[0], $ob[1]); - } - } - } - - // make current query subquery of ultimate query - $new_query = call_fuel_func_array('DB::select', $columns); - $query = $new_query->from(array($query, $this->alias)); - } - else - { - // Count queries should not select on anything besides the count - if ($type != 'count') - { - // add additional selected columns - foreach ($models as $m) - { - foreach ($m['columns'] as $c) - { - $query->select($c); - } - } - } - } - - // join tables - foreach ($this->joins as $j) - { - $join_query = $query->join($j['table'], $j['join_type']); - foreach ($j['join_on'] as $on) - { - $join_query->on($on[0], $on[1], $on[2]); - } - } - foreach ($models as $m) - { - if ($m['connection'] != $this->connection) - { - throw new \FuelException('Models cannot be related between different database connections.'); - } - - $join_query = $query->join($m['table'], $m['join_type']); - foreach ($m['join_on'] as $on) - { - $join_query->on($on[0], $on[1], $on[2]); - } - } - - // Get the order, if none set see if we have an order_by condition set - $order_by = $order_by_backup = $this->order_by; - - // Add any additional order_by and where clauses from the relations - foreach ($models as $m_name => $m) - { - if ( ! empty($m['order_by'])) - { - foreach ((array) $m['order_by'] as $k_ob => $v_ob) - { - if (is_int($k_ob)) - { - $v_dir = is_array($v_ob) ? $v_ob[1] : 'ASC'; - $v_ob = is_array($v_ob) ? $v_ob[0] : $v_ob; - if ( ! $v_ob instanceof \Fuel\Core\Database_Expression and strpos($v_ob, '.') === false) - { - $v_ob = $m_name.'.'.$v_ob; - } - - $order_by[] = array($v_ob, $v_dir); - } - else - { - strpos($k_ob, '.') === false and $k_ob = $m_name.'.'.$k_ob; - $order_by[] = array($k_ob, $v_ob); - } - } - } - if ( ! empty($m['where'])) - { - $this->_parse_where_array($m['where'], $m_name.'.'); - } - } - - // Get the order - if ( ! empty($order_by)) - { - foreach ($order_by as $ob) - { - if ( ! $ob[0] instanceof \Fuel\Core\Database_Expression) - { - if (strpos($ob[0], $this->alias.'.') === 0) - { - // get the field name - $fn = substr($ob[0], strlen($this->alias.'.')); - - // if not a a model property? - if ( ! call_fuel_func_array(array($this->model, 'property'), array($fn))) - { - // and it's not an alias? - foreach ($this->select as $salias => $sdef) - { - // if the fieldname matches - if (is_array($sdef) and $sdef[1] == $fn) - { - // order on it's alias instead - $ob[0] = $salias; - break; - } - } - } - } - else - { - // try to rewrite conditions on the relations to their table alias - $dotpos = strrpos($ob[0], '.'); - $relation = substr($ob[0], 0, $dotpos); - if ($dotpos > 0 and array_key_exists($relation, $models)) - { - $ob[0] = $models[$relation]['table'][1].substr($ob[0], $dotpos); - } - } - } - $query->order_by($ob[0], $ob[1]); - } - } - - // Get the grouping - if ( ! empty($this->group_by)) - { - foreach ($this->group_by as $gb) - { - if ( ! $gb instanceof \Fuel\Core\Database_Expression) - { - if (strpos($gb, $this->alias.'.') === false) - { - // try to rewrite on the relations to their table alias - $dotpos = strrpos($gb, '.'); - $relation = substr($gb, 0, $dotpos); - if ($dotpos > 0) - { - if(array_key_exists($relation, $models)) - { - $gb = $models[$relation]['table'][1].substr($gb, $dotpos); - } - } - else - { - $gb = $this->alias.'.'.$gb; - } - } - } - $query->group_by($gb); - } - } - - // Add any having filters - if ( ! empty($this->having)) - { - foreach ($this->having as $h) - { - list($method, $conditional) = $h; - - // try to rewrite conditions on the relations to their table alias - if ( ! empty($conditional) and is_array($conditional)) - { - $dotpos = strrpos($conditional[0], '.'); - $relation = substr($conditional[0], 0, $dotpos); - if ($dotpos > 0 and array_key_exists($relation, $models)) - { - $conditional[0] = $models[$relation]['table'][1].substr($conditional[0], $dotpos); - } - } - - call_fuel_func_array(array($query, $method), $conditional); - } - } - - // put omitted where conditions back - if ( ! empty($this->where)) - { - foreach ($this->where as $w) - { - list($method, $conditional) = $w; - - // try to rewrite conditions on the relations to their table alias - if ( ! empty($conditional) and is_array($conditional)) - { - $dotpos = strrpos($conditional[0], '.'); - $relation = substr($conditional[0], 0, $dotpos); - if ($dotpos > 0 and array_key_exists($relation, $models)) - { - $conditional[0] = $models[$relation]['table'][1].substr($conditional[0], $dotpos); - } - } - - call_fuel_func_array(array($query, $method), $conditional); - } - } - - $this->where = $where_backup; - $this->order_by = $order_by_backup; - - // Set the row limit and offset, these are applied to the outer query when a subquery - // is used or overwrite limit/offset when it's a normal query - ! is_null($this->rows_limit) and $query->limit($this->rows_limit); - ! is_null($this->rows_offset) and $query->offset($this->rows_offset); - - return array('query' => $query, 'models' => $models); - } - - /** - * Allows subclasses to make changes to the join information before it is used - */ - protected function modify_join_result($join_result, $name) - { - return $join_result; - } - - /** - * Determines whether a subquery is needed, is the case if there was a limit/offset on a join - * - * @return bool - */ - public function use_subquery() - { - return ( ! empty($this->relations) and ( ! empty($this->limit) or ! empty($this->offset))); - } - - /** - * Hydrate model instances with retrieved data - * - * @param array &$row Row from the database - * @param array $models Relations to be expected - * @param \stdClass $result An object containing current result array - * @param string $model Optionally. Model classname to hydrate - * @param array $select Optionally. Columns to use - * @param array $primary_key Optionally. Primary key(s) for this model - * - * @return Model - */ - public function hydrate(&$row, $models, \stdClass $result, $model = null, $select = null, $primary_key = null) - { - // First check the PKs, if null it's an empty row - foreach($select as $column) - { - if (is_string($column[0])) - { - $r1c1 = $column; - break; - } - } - $prefix = substr($r1c1[0], 0, strpos($r1c1[0], '.') + 1); - $obj = array(); - foreach ($primary_key as $pk) - { - $pk_c = null; - foreach ($select as $s) - { - $s[0] === $prefix.$pk and $pk_c = $s[1]; - } - - if (is_null($row[$pk_c])) - { - return false; - } - $obj[$pk] = $row[$pk_c]; - } - - // Check for cached object - $pk = count($primary_key) == 1 ? reset($obj) : '['.implode('][', $obj).']'; - $obj = $this->from_cache ? Model::cached_object($pk, $model) : false; - - // Create the object when it wasn't found - if ( ! $obj) - { - // Retrieve the object array from the row - $obj = array(); - foreach ($select as $s) - { - if ($s[0] instanceOf \Fuel\Core\Database_Expression) - { - $f = isset($this->select[$s[1]][1]) ? $this->select[$s[1]][1] : $s[1]; - } - else - { - $f = substr($s[0], strpos($s[0], '.') + 1); - } - $obj[$f] = $row[$s[1]]; - if (in_array($f, $primary_key)) - { - $obj[$f] = \Orm\Observer_Typing::typecast($f, $obj[$f], call_user_func($model.'::property', $f)); - } - unset($row[$s[1]]); - } - $obj = $model::forge($obj, false, $this->view ? $this->view['_name'] : null, $this->from_cache); - } - else - { - // add fields not present in the already cached version - $new = array(); - foreach ($select as $s) - { - if ($s[0] instanceOf \Fuel\Core\Database_Expression) - { - $f = isset($this->select[$s[1]][1]) ? $this->select[$s[1]][1] : $s[1]; - } - else - { - $f = substr($s[0], strpos($s[0], '.') + 1); - } - $new[$f] = $row[$s[1]]; - if ( ! isset($obj->{$f})) - { - $obj->{$f} = $new[$f]; - } - } - if ($new) - { - $obj->_update_original($new); - } - } - - // if the result to be generated is an array and the current object is not yet in there - if (is_array($result->data)) { - if (! array_key_exists($pk, $result->data)) - { - $result->data[$pk] = $obj; - } - else - { - $obj = $result->data[$pk]; - } - } - // if the result to be generated is a single object and empty - elseif ( ! is_array($result->data) and empty($result->data)) - { - $result->data = $obj; - } - - // start fetching relationships - $rel_objs = $obj->_relate(); - $relations_updated = array(); - $relation_result_wrapper = new \stdClass; - foreach ($models as $m) - { - // when the expected model is empty, there's nothing to be done - if (empty($m['model'])) - { - continue; - } - $relations_updated[] = $m['rel_name']; - - // when not yet set, create the relation result var with null or array - if ( ! array_key_exists($m['rel_name'], $rel_objs)) - { - $rel_objs[$m['rel_name']] = $m['relation']->singular ? null : array(); - } - - $relation_result_wrapper->data = $rel_objs[$m['rel_name']]; - - // when result is array or singular empty, try to fetch the new relation from the row - $this->hydrate( - $row, - ! empty($m['models']) ? $m['models'] : array(), - $relation_result_wrapper, - $m['model'], - $m['columns'], - $m['primary_key'] - ); - - $rel_objs[$m['rel_name']] = $relation_result_wrapper->data; - } - - // attach the retrieved relations to the object and update its original DB values - $obj->_relate($rel_objs); - $obj->_update_original_relations($relations_updated); - - return $obj; - } - - /** - * Build the query and return hydrated results - * - * @return array - */ - public function get() - { - // Get the columns - $columns = $this->select(); - - // Start building the query - $select = $columns; - if ($this->use_subquery()) - { - $select = array(); - foreach ($columns as $c) - { - $select[] = $c[0]; - } - } - - $query = call_fuel_func_array('DB::select', $select); - - // Set from view/table - $query->from(array($this->_table(), $this->alias)); - - // Build the query further - $tmp = $this->build_query($query, $columns); - $query = $tmp['query']; - $models = $tmp['models']; - - // Make models hierarchical - foreach ($models as $name => $values) - { - if (strpos($name, '.')) - { - unset($models[$name]); - $rels = explode('.', $name); - $ref =& $models[array_shift($rels)]; - foreach ($rels as $rel) - { - empty($ref['models']) and $ref['models'] = array(); - empty($ref['models'][$rel]) and $ref['models'][$rel] = array(); - $ref =& $ref['models'][$rel]; - } - $ref = $values; - } - } - - $rows = $query->execute($this->connection)->as_array(); - - // To workaround the PHP 5.x performance issue at pulling a large number of records, - // we shouldn't use passing array by reference directly here. - $result = new \stdClass; - $result->data = array(); - - $model = $this->model; - $select = $this->select(); - $primary_key = $model::primary_key(); - foreach ($rows as $id => $row) - { - $this->hydrate($row, $models, $result, $model, $select, $primary_key); - unset($rows[$id]); - } - - // It's all built, now lets execute and start hydration - return $result->data; - } - - /** - * Get the Query as it's been build up to this point and return it as an object - * - * @return Database_Query - */ - public function get_query() - { - // Get the columns - $columns = $this->select(false); - - // Start building the query - $select = $columns; - if ($this->use_subquery()) - { - $select = array(); - foreach ($columns as $c) - { - $select[] = $c[0]; - } - } - $query = call_fuel_func_array('DB::select', $select); - - // Set the defined connection on the query - $query->set_connection($this->connection); - - // Set from table - $query->from(array($this->_table(), $this->alias)); - - // Build the query further - $tmp = $this->build_query($query, $columns); - - return $tmp['query']; - } - - /** - * Build the query and return single object hydrated - * - * @return Model - */ - public function get_one() - { - // save the current limits - $limit = $this->limit; - $rows_limit = $this->rows_limit; - - if ($this->rows_limit !== null) - { - $this->limit = null; - $this->rows_limit = 1; - } - else - { - $this->limit = 1; - $this->rows_limit = null; - } - - // get the result using normal find - $result = $this->get(); - - // put back the old limits - $this->limit = $limit; - $this->rows_limit = $rows_limit; - - return $result ? reset($result) : null; - } - - /** - * Count the result of a query - * - * @param bool $column False for random selected column or specific column, only works for main model currently - * @param bool $distinct True if DISTINCT has to be aded to the query - * - * @return mixed number of rows OR false - */ - public function count($column = null, $distinct = true) - { - $select = $column ?: \Arr::get(call_user_func($this->model.'::primary_key'), 0); - $select = (strpos($select, '.') === false ? $this->alias.'.'.$select : $select); - - // Get the columns - $columns = \DB::expr('COUNT('.($distinct ? 'DISTINCT ' : ''). - \Database_Connection::instance($this->connection)->quote_identifier($select). - ') AS count_result'); - - // Remove the current select and - $query = \DB::select($columns); - - // Set from view or table - $query->from(array($this->_table(), $this->alias)); - - $tmp = $this->build_query($query, $columns, 'count'); - $query = $tmp['query']; - $count = $query->execute($this->connection)->get('count_result'); - - // Database_Result::get('count_result') returns a string | null - if ($count === null) - { - return false; - } - - return (int) $count; - } - - /** - * Get the maximum of a column for the current query - * - * @param string $column Column - * @return bool|int maximum value OR false - */ - public function max($column) - { - is_array($column) and $column = array_shift($column); - - // Get the columns - $columns = \DB::expr('MAX('. - \Database_Connection::instance($this->connection)->quote_identifier($this->alias.'.'.$column). - ') AS max_result'); - - // Remove the current select and - $query = \DB::select($columns); - - // Set from table - $query->from(array($this->_table(), $this->alias)); - - $tmp = $this->build_query($query, $columns, 'max'); - $query = $tmp['query']; - $max = $query->execute($this->connection)->get('max_result'); - - // Database_Result::get('max_result') returns a string | null - if ($max === null) - { - return false; - } - - return $max; - } - - /** - * Get the minimum of a column for the current query - * - * @param string $column Column which min value you want to get - * - * @return bool|int minimum value OR false - */ - public function min($column) - { - is_array($column) and $column = array_shift($column); - - // Get the columns - $columns = \DB::expr('MIN('. - \Database_Connection::instance($this->connection)->quote_identifier($this->alias.'.'.$column). - ') AS min_result'); - - // Remove the current select and - $query = \DB::select($columns); - - // Set from table - $query->from(array($this->_table(), $this->alias)); - - $tmp = $this->build_query($query, $columns, 'min'); - $query = $tmp['query']; - $min = $query->execute($this->connection)->get('min_result'); - - // Database_Result::get('min_result') returns a string | null - if ($min === null) - { - return false; - } - - return $min; - } - - /** - * Run INSERT with the current values - * - * @return bool|int Last inserted ID (if present) or false on failure - */ - public function insert() - { - $res = \DB::insert(call_user_func($this->model.'::table'), array_keys($this->values)) - ->values(array_values($this->values)) - ->execute($this->write_connection); - - // Failed to save the new record - if ($res[1] === 0) - { - return false; - } - - return $res[0]; - } - - /** - * Run UPDATE with the current values - * - * @return bool success of update operation - */ - public function update() - { - // temporary disable relations - $tmp_relations = $this->relations; - $this->relations = array(); - - // Build query and execute update - $query = \DB::update(call_user_func($this->model.'::table')); - $tmp = $this->build_query($query, array(), 'update'); - $query = $tmp['query']; - $res = $query->set($this->values)->execute($this->write_connection); - - // put back any relations settings - $this->relations = $tmp_relations; - - // Update can affect 0 rows when input types are different but outcome stays the same - return $res >= 0; - } - - /** - * Run DELETE with the current values - * - * @return bool success of delete operation - */ - public function delete() - { - // temporary disable relations - $tmp_relations = $this->relations; - $this->relations = array(); - - // Build query and execute update - $query = \DB::delete(call_user_func($this->model.'::table')); - $tmp = $this->build_query($query, array(), 'delete'); - $query = $tmp['query']; - $res = $query->execute($this->write_connection); - - // put back any relations settings - $this->relations = $tmp_relations; - - return $res > 0; - } -} diff --git a/fuel/packages/orm/classes/query/soft.php b/fuel/packages/orm/classes/query/soft.php deleted file mode 100755 index f7f2f12..0000000 --- a/fuel/packages/orm/classes/query/soft.php +++ /dev/null @@ -1,114 +0,0 @@ -_col_name = $col_name; - return $this; - } - - /** - * Make sure the soft-filter is added to get() calls - */ - public function get() - { - $this->add_soft_filter(); - return parent::get(); - } - - /** - * Make sure the soft-filter is added to count() calls - */ - public function count($column = null, $distinct = true) - { - $this->add_soft_filter(); - return parent::count($column, $distinct); - } - - /** - * Make sure the soft-filter is added to min() calls - */ - public function min($column) - { - $this->add_soft_filter(); - return parent::min($column); - } - - /** - * Make sure the soft-filter is added to max() calls - */ - public function max($column) - { - $this->add_soft_filter(); - return parent::max($column); - } - - protected function modify_join_result($join_result, $name) - { - if ( ! is_null($this->_col_name) and is_subclass_of($join_result[$name]['model'], '\Orm\Model_Soft')) - { - $table = $join_result[$name]['table'][1]; - $join_result[$name]['join_on'][] = array("$table.$this->_col_name", 'IS', \DB::expr('NULL')); - } - - return parent::modify_join_result($join_result, $name); - } - - /** - * Add an additional where clause if needed to execute the soft-filter - */ - protected function add_soft_filter() - { - if ($this->_col_name !== null) - { - // Capture any filtering that has already been added - $current_where = $this->where; - - // If there is no filtering then we don't need to add any special organization - if ( ! empty($current_where)) - { - $this->where = array(); - - // Make sure the existing filtering is wrapped safely - $this->and_where_open(); - $this->where = array_merge($this->where, $current_where); - $this->and_where_close(); - } - - // Finally add the soft delete filtering - $this->where($this->_col_name, null); - } - } - -} diff --git a/fuel/packages/orm/classes/query/temporal.php b/fuel/packages/orm/classes/query/temporal.php deleted file mode 100755 index 423416d..0000000 --- a/fuel/packages/orm/classes/query/temporal.php +++ /dev/null @@ -1,79 +0,0 @@ -timestamp = $stamp; - $this->timestamp_end_col = $timestamp_end_col; - $this->timestamp_start_col = $timestamp_start_col; - - return $this; - } - - /** - * Adds extra where conditions when temporal filtering is needed. - * - * @param array $join_result - * @param string $name - * @return array - */ - protected function modify_join_result($join_result, $name) - { - if ( ! is_null($this->timestamp) and is_subclass_of($join_result[$name]['model'], '\Orm\Model_Temporal')) - { - //Add the needed conditions to allow for temporal-ness - $table = $join_result[$name]['table'][1]; - $query_time = \DB::escape($this->timestamp); - $join_result[$name]['join_on'][] = array("$table.$this->timestamp_start_col", '<=', $query_time); - $join_result[$name]['join_on'][] = array("$table.$this->timestamp_end_col", '>=', $query_time); - } - - return $join_result; - } - - public function hydrate(&$row, $models, \stdClass $result, $model = null, $select = null, $primary_key = null) - { - if( is_subclass_of($model, '\Orm\Model_Temporal')) - { - $primary_key[] = $this->timestamp_start_col; - $primary_key[] = $this->timestamp_end_col; - } - parent::hydrate($row, $models, $result, $model, $select, $primary_key); - } - -} diff --git a/fuel/packages/orm/classes/relation.php b/fuel/packages/orm/classes/relation.php deleted file mode 100755 index 0adc6f0..0000000 --- a/fuel/packages/orm/classes/relation.php +++ /dev/null @@ -1,164 +0,0 @@ - property, the table alias is - * given to be included with the property - * - * @param string - * @return array - */ - public function select($table) - { - $props = call_user_func(array($this->model_to, 'properties')); - $i = 0; - $properties = array(); - foreach ($props as $pk => $pv) - { - $properties[] = array($table.'.'.$pk, $table.'_c'.$i); - $i++; - } - - return $properties; - } - - /** - * Returns tables to join and fields to select with optional additional settings like order/where - * - * @param $alias_from - * @param $rel_name - * @param $alias_to - * - * @return array - */ - abstract public function join($alias_from, $rel_name, $alias_to); - - /** - * Saves the current relationships and may cascade saving to model_to instances - * - * @param Model $model_from - * @param Model $model_to - * @param $original_model_id - * @param $parent_saved - * @param bool|null $cascade - * @internal param \Orm\instance $Model of model_from - * @internal param array|\Orm\Model $single or multiple model instances to save - * @internal param \Orm\whether $bool the model_from has been saved already - * @internal param bool|null $either uses default setting (null) or forces when true or prevents when false - * - * @return - */ - abstract public function save($model_from, $model_to, $original_model_id, $parent_saved, $cascade); - - /** - * Takes the current relations and attempts to delete them when cascading is allowed or forced - * - * @param Model $model_from instance of model_from - * @param array|Model $model_to single or multiple model instances to delete - * @param bool $parent_deleted whether the model_from has been saved already - * @param null|bool $cascade either uses default setting (null) or forces when true or prevents when false - */ - abstract public function delete($model_from, $model_to, $parent_deleted, $cascade); - - /** - * Allow outside access to protected properties - * - * @param $property - * @throws \FuelException Invalid relation property - * @return - */ - public function __get($property) - { - if (strncmp($property, '_', 1) == 0 or ! property_exists($this, $property)) - { - throw new \FuelException('Invalid relation property: '.$property); - } - - return $this->{$property}; - } - - /** - * Returns true if this relation is a singular relation. Eg, has_one not has_many - * - * @return bool - */ - public function is_singular() - { - return $this->singular; - } -} diff --git a/fuel/packages/orm/composer.json b/fuel/packages/orm/composer.json deleted file mode 100755 index 50b79c9..0000000 --- a/fuel/packages/orm/composer.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "fuel/orm", - "description" : "FuelPHP 1.x ORM Package", - "type": "fuel-package", - "homepage": "https://github.com/fuel/orm", - "license": "MIT", - "authors": [ - { - "name": "FuelPHP Development Team", - "email": "team@fuelphp.com" - } - ], - "require": { - "composer/installers": "~1.0" - } -} diff --git a/fuel/packages/orm/config/orm.php b/fuel/packages/orm/config/orm.php deleted file mode 100755 index 65a085f..0000000 --- a/fuel/packages/orm/config/orm.php +++ /dev/null @@ -1,9 +0,0 @@ - true, - - // temporal model settings - 'sql_max_timestamp_mysql' => '2038-01-18 22:14:08', - 'sql_max_timestamp_unix' => 2147483647, -); diff --git a/fuel/packages/parser/.gitignore b/fuel/packages/parser/.gitignore deleted file mode 100755 index 8b0bd70..0000000 --- a/fuel/packages/parser/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -*~ -*.bak -Thumbs.db -desktop.ini -.DS_Store -.buildpath -.project -.settings -fuel/app/logs/*/*/* -fuel/app/cache/*/* -nbproject/ -.idea -*.tmproj -*.sublime-project -*.sublime-workspace \ No newline at end of file diff --git a/fuel/packages/parser/bootstrap.php b/fuel/packages/parser/bootstrap.php deleted file mode 100755 index 08d6f9f..0000000 --- a/fuel/packages/parser/bootstrap.php +++ /dev/null @@ -1,31 +0,0 @@ - __DIR__.'/classes/view.php', - 'Parser\\View_Dwoo' => __DIR__.'/classes/view/dwoo.php', - 'Parser\\View_Mustache' => __DIR__.'/classes/view/mustache.php', - 'Parser\\View_Markdown' => __DIR__.'/classes/view/markdown.php', - 'Parser\\View_Twig' => __DIR__.'/classes/view/twig.php', - 'Parser\\View_HamlTwig' => __DIR__.'/classes/view/hamltwig.php', - 'Parser\\View_Jade' => __DIR__.'/classes/view/jade.php', - 'Parser\\View_Handlebars' => __DIR__.'/classes/view/handlebars.php', - 'Parser\\View_Haml' => __DIR__.'/classes/view/haml.php', - 'Parser\\View_Smarty' => __DIR__.'/classes/view/smarty.php', - 'Parser\\View_Phptal' => __DIR__.'/classes/view/phptal.php', - 'Parser\\View_Lex' => __DIR__.'/classes/view/lex.php', - - 'Parser\\Twig_Fuel_Extension' => __DIR__.'/classes/twig/fuel/extension.php', - 'Parser\\Smarty_Fuel_Extension' => __DIR__.'/classes/smarty/fuel/extension.php', -)); diff --git a/fuel/packages/parser/classes/smarty/fuel/extension.php b/fuel/packages/parser/classes/smarty/fuel/extension.php deleted file mode 100755 index f1ee0b9..0000000 --- a/fuel/packages/parser/classes/smarty/fuel/extension.php +++ /dev/null @@ -1,614 +0,0 @@ -registerPlugin('function', 'fuel_version', array($this, 'fuel_version')); - $smarty->registerPlugin('function', 'url', array($this, 'url')); - $smarty->registerPlugin('function', 'base_url', array('Uri', 'base')); - $smarty->registerPlugin('function', 'current_url', array('Uri', 'current')); - $smarty->registerPlugin('function', 'uri_segment', array($this, 'uri_segment')); - $smarty->registerPlugin('function', 'uri_segments', array('Uri', 'segments')); - $smarty->registerPlugin('function', 'config', array($this, 'config_get')); - $smarty->registerPlugin('function', 'lang', array($this, 'lang_get')); - $smarty->registerPlugin('block', 'form', array($this, 'form')); - $smarty->registerPlugin('function', 'form_input', array($this, 'form_input')); - $smarty->registerPlugin('function', 'form_password', array($this, 'form_password')); - $smarty->registerPlugin('function', 'form_hidden', array($this, 'form_hidden')); - $smarty->registerPlugin('function', 'form_button', array($this, 'form_button')); - $smarty->registerPlugin('function', 'form_reset', array($this, 'form_reset')); - $smarty->registerPlugin('function', 'form_submit', array($this, 'form_submit')); - $smarty->registerPlugin('function', 'form_textarea', array($this, 'form_textarea')); - $smarty->registerPlugin('block', 'form_fieldset', array($this, 'form_fieldset')); - $smarty->registerPlugin('function', 'form_label', array($this, 'form_label')); - $smarty->registerPlugin('function', 'form_checkbox', array($this, 'form_checkbox')); - $smarty->registerPlugin('function', 'form_radio', array($this, 'form_radio')); - $smarty->registerPlugin('function', 'form_file', array($this, 'form_file')); - $smarty->registerPlugin('function', 'form_select', array($this, 'form_select')); - $smarty->registerPlugin('function', 'form_val', array($this, 'form_val')); - $smarty->registerPlugin('function', 'input_get', array($this, 'input_get')); - $smarty->registerPlugin('function', 'input_post', array($this, 'input_post')); - $smarty->registerPlugin('function', 'asset_add_path', array($this, 'asset_add_path')); - $smarty->registerPlugin('function', 'asset_css', array($this, 'asset_css')); - $smarty->registerPlugin('function', 'asset_js', array($this, 'asset_js')); - $smarty->registerPlugin('function', 'asset_img', array($this, 'asset_img')); - $smarty->registerPlugin('function', 'asset_render', array($this, 'asset_render')); - $smarty->registerPlugin('function', 'asset_find_file', array($this, 'asset_find_file')); - $smarty->registerPlugin('function', 'html_anchor', array($this, 'html_anchor')); - $smarty->registerPlugin('function', 'session_get_flash', array($this, 'session_get_flash')); - $smarty->registerPlugin('block', 'markdown', array($this, 'markdown_parse')); - $smarty->registerPlugin('function', 'auth_has_access', array($this, 'auth_has_access')); - $smarty->registerPlugin('function', 'auth_check', array($this, 'auth_check')); - } - - /** - * Return the current Fuel version - */ - public function fuel_version() - { - return \Fuel::VERSION; - } - - /** - * Provides the url() functionality. Generates a full url (including - * domain and index.php). - * - * Usage: {url uri='' params=[name=>$value]} - * - * @return string - */ - public function url($params) - { - $uri = isset($params['uri']) ? $params['uri'] : ''; - $named_params = isset($params['params']) ? $params['params'] : array(); - if ($named_uri = \Router::get($uri, $named_params)) - { - $uri = $named_uri; - } - return \Uri::create($uri); - } - - /** - * Usage: {uri_segment segment=''} - * Required: segment - * - * @return mixed segment string or false - */ - public function uri_segment($params) - { - if (isset($params['segment'])) - { - return \Uri::segment($params['segment']); - } - return false; - } - - /** - * Usage: {config item='' default=''} - * Required: item - * - * @return mixed string or array - */ - public function config_get($params) - { - if (isset($params['item'])) - { - $default = $params['default'] ? null : $params['default']; - return \Config::get($params['item'], $default); - } - return ''; - } - - /** - * Usage: {lang line='id' params=[] default='default value' lang='en'} - * Required: line - * - * @return mixed string or false - */ - public function lang_get($params) - { - if (isset($params['line'])) - { - $parameters = isset($params['params']) ? $params['params'] : array(); - $default = isset($params['default']) ? $params['default'] : null; - $language = isset($params['lang']) ? $params['lang'] : null; - return \Lang::get($params['line'], $parameters, $default, $language); - } - return false; - } - - /** - * Usage: {form attrs=[] hidden=[]}...{/form} - * - * @return string - */ - public function form($params, $content, $smarty, &$repeat) - { - //$content is null when repeat is true and has block content when repeat is false - if ($repeat) - { - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - $hidden = isset($params['hidden']) ? $params['hidden'] : array(); - return \Form::open($attributes, $hidden); - } - else - { - return $content . \Form::close(); - } - } - - /** - * Usage: {form_fieldset attrs=[] legend=''}...{/form} - * - * @return string - */ - public function form_fieldset($params, $content, $smarty, &$repeat) - { - //$content is null when repeat is true and has block content when repeat is false - if ($repeat) - { - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - $legend = isset($params['legend']) ? $params['legend'] : null; - return \Form::fieldset_open($attributes, $legend); - } - else - { - return $content . \Form::fieldset_close(); - } - } - - /** - * Usage: {form_input field='' value='' attrs=[]} - * Required: field - * - * @return string - */ - public function form_input($params) - { - if ( ! isset($params['field'])) - { - throw new \UnexpectedValueException("The field parameter is required."); - } - $value = isset($params['value']) ? $params['value'] : null; - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - return \Form::input($params['field'], $value, $attributes); - } - - /** - * Usage: {form_password field='' value='' attrs=[]} - * Required: field - * - * @return string - */ - public function form_password($params) - { - if ( ! isset($params['field'])) - { - throw new \UnexpectedValueException("The field parameter is required."); - } - $value = isset($params['value']) ? $params['value'] : null; - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - return \Form::password($params['field'], $value, $attributes); - } - - /** - * Usage: {form_hidden field='' value='' attrs=[]} - * Required: field - * - * @return string - */ - public function form_hidden($params) - { - if ( ! isset($params['field'])) - { - throw new \UnexpectedValueException("The field parameter is required."); - } - $value = isset($params['value']) ? $params['value'] : null; - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - return \Form::hidden($params['field'], $value, $attributes); - } - - /** - * Usage: {form_button field='' value='' attrs=[]} - * Required: field - * - * @return string - */ - public function form_button($params) - { - if ( ! isset($params['field'])) - { - throw new \UnexpectedValueException("The field parameter is required."); - } - $value = isset($params['value']) ? $params['value'] : null; - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - return \Form::button($params['field'], $value, $attributes); - } - - /** - * Usage: {form_submit field='' value='' attrs=[]} - * Required: field - * - * @return string - */ - public function form_submit($params) - { - if ( ! isset($params['field'])) - { - throw new \UnexpectedValueException("The field parameter is required."); - } - $value = isset($params['value']) ? $params['value'] : null; - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - return \Form::submit($params['field'], $value, $attributes); - } - - /** - * Usage: {form_reset field='' value='' attrs=[]} - * Required: field - * - * @return string - */ - public function form_reset($params) - { - if ( ! isset($params['field'])) - { - throw new \UnexpectedValueException("The field parameter is required."); - } - $value = isset($params['value']) ? $params['value'] : null; - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - return \Form::reset($params['field'], $value, $attributes); - } - - /** - * Usage: {form_textarea field='' value='' attrs=[]} - * Required: field - * - * @return string - */ - public function form_textarea($params) - { - if ( ! isset($params['field'])) - { - throw new \UnexpectedValueException("The field parameter is required."); - } - $value = isset($params['value']) ? $params['value'] : null; - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - return \Form::textarea($params['field'], $value, $attributes); - } - - /** - * Usage: {form_label text='' id='' attrs=[]} - * Required: text - * - * @return string - */ - public function form_label($params) - { - if ( ! isset($params['text'])) - { - throw new \UnexpectedValueException("The text parameter is required."); - } - $id = isset($params['id']) ? $params['id'] : null; - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - return \Form::label($params['text'], $id, $attributes); - } - - /** - * Usage: {form_checkbox field='' value='' checked=false attrs=[]} - * Required: field - * - * @return string - */ - public function form_checkbox($params) - { - if ( ! isset($params['field'])) - { - throw new \UnexpectedValueException("The field parameter is required."); - } - $value = isset($params['value']) ? $params['value'] : null; - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - $checked = isset($params['checked']) ? $params['checked'] : null; - return \Form::checkbox($params['field'], $value, $checked, $attributes); - } - - /** - * Usage: {form_radio field='' value='' checked=false attrs=[]} - * Required: field - * - * @return string - */ - public function form_radio($params) - { - if ( ! isset($params['field'])) - { - throw new \UnexpectedValueException("The field parameter is required."); - } - $value = isset($params['value']) ? $params['value'] : null; - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - $checked = isset($params['checked']) ? $params['checked'] : null; - return \Form::checkbox($params['field'], $value, $checked, $attributes); - } - - /** - * Usage: {form_select field='' values='' options=[] attrs=[]} - * Required: field - * - * @return string - */ - public function form_select($params) - { - if ( ! isset($params['field'])) - { - throw new \UnexpectedValueException("The field parameter is required."); - } - $values = isset($params['values']) ? $params['values'] : null; - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - $options = isset($params['options']) ? $params['options'] : array(); - return \Form::select($params['field'], $values, $options, $attributes); - } - - /** - * Usage: {form_file field='' attrs=[]} - * Required: field - * - * @return string - */ - public function form_file($params) - { - if ( ! isset($params['field'])) - { - throw new \UnexpectedValueException("The field parameter is required."); - } - $attributes = isset($params['attrs']) ? $params['attrs'] : array(); - return \Form::file($params['field'], $attributes); - } - - /** - * Provide access to Input::param - * Usage: {form_val index='' default=''} - * - * @return string - */ - public function form_val($params) - { - $index = isset($params['index']) ? $params['index'] : null; - $default = isset($params['default']) ? $params['default'] : null; - return \Input::param($index, $default); - } - - /** - * Provide access to Input::get - * Usage: {input_get index='' default=''} - * - * @return string - */ - public function input_get($params) - { - $index = isset($params['index']) ? $params['index'] : null; - $default = isset($params['default']) ? $params['default'] : null; - return \Input::get($index, $default); - } - - /** - * Provide access to Input::post - * Usage: {input_post index='' default=''} - * - * @return string - */ - public function input_post($params) - { - $index = isset($params['index']) ? $params['index'] : null; - $default = isset($params['default']) ? $params['default'] : null; - return \Input::post($index, $default); - } - - /** - * Provide addess to Asset::add_path - * Usage: {form_val path='' type=''} - * Required: path - * - */ - public function asset_add_path($params) - { - if ( ! isset($params['path'])) - { - throw new \UnexpectedValueException('Asset path must be specified'); - } - $type = isset($params['type']) ? $params['type'] : null; - \Asset::add_path($params['path'], $type); - } - - /** - * Usage: {asset_css refs='' attrs=[] group='' raw=false} - * Required: refs - * - * @return mixed string or nothing if group is filled - */ - public function asset_css($params) - { - if ( ! isset($params['refs'])) - { - throw new \UnexpectedValueException("The refs parameter is required."); - } - $group = isset($params['group']) ? $params['group'] : null; - $attrs = isset($params['attrs']) ? $params['attrs'] : array(); - $raw = isset($params['raw']) ? $params['raw'] : false; - return \Asset::css($params['refs'], $attrs, $group, $raw); - } - - /** - * Usage: {asset_js refs='' attrs=[] group='' raw=false} - * Required: refs - * - * @return mixed string or nothing if group is filled - */ - public function asset_js($params) - { - if ( ! isset($params['refs'])) - { - throw new \UnexpectedValueException("The refs parameter is required."); - } - $group = isset($params['group']) ? $params['group'] : null; - $attrs = isset($params['attrs']) ? $params['attrs'] : array(); - $raw = isset($params['raw']) ? $params['raw'] : false; - return \Asset::js($params['refs'], $attrs, $group, $raw); - } - - /** - * Usage: {asset_img refs='' attrs=[] group=''} - * Required: refs - * - * @return mixed string or nothing if group is filled - */ - public function asset_img($params) - { - if ( ! isset($params['refs'])) - { - throw new \UnexpectedValueException("The refs parameter is required."); - } - $group = isset($params['group']) ? $params['group'] : null; - $attrs = isset($params['attrs']) ? $params['attrs'] : array(); - return \Asset::img($params['refs'], $attrs, $group); - } - - /** - * Render a group of assets - * Usage: {asset_render group='' raw=false} - * - * @return string - */ - public function asset_render($params) - { - $group = isset($params['group']) ? $params['group'] : null; - $raw = isset($params['raw']) ? $params['raw'] : false; - return \Asset::render($group, $raw); - } - - /** - * Usage: {asset_find_file file='' type='' folder=''} - * Required: file and type - * - * @return string - */ - public function asset_find_file($params) - { - if ( ! isset($params['file'])) - { - throw new \UnexpectedValueException("The file parameter is required."); - } - if ( ! isset($params['type'])) - { - throw new \UnexpectedValueException("The type parameter is required."); - } - $folder = isset($params['folder']) ? $params['folder'] : ''; - return \Asset::find_file($params['file'], $params['type'], $folder); - } - - /** - * Usage: {html_anchor href='' text='' attrs='' secure=false} - * Required: href and text - * - * @return string - */ - public function html_anchor($params) - { - if ( ! isset($params['href'])) - { - throw new \UnexpectedValueException("The href parameter is required."); - } - if ( ! isset($params['text'])) - { - throw new \UnexpectedValueException("The text parameter is required."); - } - $attrs = isset($params['attrs']) ? $params['attrs'] : array(); - $secure = isset($params['secure']) ? $params['secure'] : null; - return \Html::anchor($params['href'], $params['text'], $attrs, $secure); - } - - /** - * Usage: {session_get_flash var='' default='' expire=false} - * Required: var - * - * @return mixed - */ - public function session_get_flash($params) - { - if ( ! isset($params['var'])) - { - throw new \UnexpectedValueException("The var parameter is required."); - } - $default = isset($params['default']) ? $params['default'] : null; - $expire = isset($params['expire']) ? $params['expire'] : false; - return \Session::get_flash($params['var'], $default, $expire); - } - - /** - * Usage: {markdown}...{/markdown} - * - * @return string - */ - public function markdown_parse($params, $content, $smarty, &$repeat) - { - //only take action when repeat = false as that is the closing tag - if (!$repeat) - { - return \Markdown::parse($content); - } - } - - /** - * Usage: {auth_has_access cond=''} - * Required: cond - * - * @return bool - */ - public function auth_has_access($params) - { - if ( ! isset($params['cond'])) - { - throw new \UnexpectedValueException("The cond parameter is required."); - } - return \Auth::has_access($params['cond']); - } - - /** - * Usage: {auth_check} - * - * @return bool - */ - public function auth_check() - { - return \Auth::check(); - } -} diff --git a/fuel/packages/parser/classes/twig/fuel/extension.php b/fuel/packages/parser/classes/twig/fuel/extension.php deleted file mode 100755 index fa1161f..0000000 --- a/fuel/packages/parser/classes/twig/fuel/extension.php +++ /dev/null @@ -1,212 +0,0 @@ - new Twig_Function_Method($this, 'fuel_version'), - 'url' => new Twig_Function_Method($this, 'url'), - - 'base_url' => new Twig_Function_Function('Uri::base'), - 'current_url' => new Twig_Function_Function('Uri::current'), - 'uri_segment' => new Twig_Function_Function('Uri::segment'), - 'uri_segments' => new Twig_Function_Function('Uri::segments'), - - 'config' => new Twig_Function_Function('Config::get'), - - 'dump' => new Twig_Function_Function('Debug::dump'), - - 'lang' => new Twig_Function_Function('Lang::get'), - - 'form_open' => new Twig_Function_Function('Form::open'), - 'form_close' => new Twig_Function_Function('Form::close'), - 'form_input' => new Twig_Function_Function('Form::input'), - 'form_password' => new Twig_Function_Function('Form::password'), - 'form_hidden' => new Twig_Function_Function('Form::hidden'), - 'form_radio' => new Twig_Function_Function('Form::radio'), - 'form_checkbox' => new Twig_Function_Function('Form::checkbox'), - 'form_textarea' => new Twig_Function_Function('Form::textarea'), - 'form_file' => new Twig_Function_Function('Form::file'), - 'form_button' => new Twig_Function_Function('Form::button'), - 'form_reset' => new Twig_Function_Function('Form::reset'), - 'form_submit' => new Twig_Function_Function('Form::submit'), - 'form_select' => new Twig_Function_Function('Form::select'), - 'form_label' => new Twig_Function_Function('Form::label'), - - 'form_val' => new Twig_Function_Function('Input::param'), - 'input_get' => new Twig_Function_Function('Input::get'), - 'input_post' => new Twig_Function_Function('Input::post'), - - 'asset_add_path' => new Twig_Function_Function('Asset::add_path'), - 'asset_css' => new Twig_Function_Function('Asset::css'), - 'asset_js' => new Twig_Function_Function('Asset::js'), - 'asset_img' => new Twig_Function_Function('Asset::img'), - 'asset_render' => new Twig_Function_Function('Asset::render'), - 'asset_find_file' => new Twig_Function_Function('Asset::find_file'), - - 'theme_asset_css' => new Twig_Function_Method($this, 'theme_asset_css'), - 'theme_asset_js' => new Twig_Function_Method($this, 'theme_asset_js'), - 'theme_asset_img' => new Twig_Function_Method($this, 'theme_asset_img'), - - 'html_anchor' => new Twig_Function_Function('Html::anchor'), - 'html_mail_to_safe' => new Twig_Function_Function('Html::mail_to_safe'), - - 'session_get' => new Twig_Function_Function('Session::get'), - 'session_get_flash' => new Twig_Function_Function('Session::get_flash'), - - 'security_js_fetch_token' => new Twig_Function_Function('Security::js_fetch_token'), - 'security_js_set_token' => new Twig_Function_Function('Security::js_set_token'), - - 'markdown_parse' => new Twig_Function_Function('Markdown::parse'), - - 'auth_has_access' => new Twig_Function_Function('Auth::has_access'), - 'auth_check' => new Twig_Function_Function('Auth::check'), - 'auth_get' => new Twig_Function_Function('Auth::get'), - ); - } - } - - /** - * Provides the url() functionality. Generates a full url (including - * domain and index.php). - * - * @param string URI to make a full URL for (or name of a named route) - * @param array Array of named params for named routes - * @return string - */ - public function url($uri = '', $named_params = array()) - { - if ($named_uri = \Router::get($uri, $named_params)) - { - $uri = $named_uri; - } - - return \Uri::create($uri); - } - - public function fuel_version() - { - return \Fuel::VERSION; - } - - public function theme_asset_css($stylesheets = array(), $attr = array(), $group = null, $raw = false) - { - return \Theme::instance()->asset->css($stylesheets, $attr, $group, $raw); - } - - public function theme_asset_js($scripts = array(), $attr = array(), $group = null, $raw = false) - { - return \Theme::instance()->asset->js($scripts, $attr, $group, $raw); - } - - public function theme_asset_img($images = array(), $attr = array(), $group = null) - { - return \Theme::instance()->asset->img($images, $attr, $group); - } -} diff --git a/fuel/packages/parser/classes/view.php b/fuel/packages/parser/classes/view.php deleted file mode 100755 index aff62fb..0000000 --- a/fuel/packages/parser/classes/view.php +++ /dev/null @@ -1,113 +0,0 @@ -extension = $extension; - - $view->set_filename($file, true); - } - - // and return the view object - return $view; - } -} diff --git a/fuel/packages/parser/classes/view/dwoo.php b/fuel/packages/parser/classes/view/dwoo.php deleted file mode 100755 index 0636825..0000000 --- a/fuel/packages/parser/classes/view/dwoo.php +++ /dev/null @@ -1,86 +0,0 @@ -file_name; - $data = $this->get_data(); - - try - { - $result = static::parser()->get($file, $data); - } - catch (\Exception $e) - { - // Delete the output buffer & re-throw the exception - ob_end_clean(); - throw $e; - } - - $this->unsanitize($data); - return $result; - } - - public $extension = 'tpl'; - - /** - * Returns the Parser lib object - * - * @return Dwoo - */ - public static function parser() - { - if ( ! empty(static::$_parser)) - { - return static::$_parser; - } - - // Parser - static::$_parser = new Dwoo(); - static::$_parser->setCacheTime(\Config::get('parser.View_Dwoo.environment.cache_time', 0)); - static::$_parser->setCacheDir(\Config::get('parser.View_Dwoo.environment.cache_dir', APPPATH.'cache'.DS.'dwoo'.DS)); - static::$_parser->setCompileDir(\Config::get('parser.View_Dwoo.environment.compile_dir', APPPATH.'cache'.DS.'dwoo'.DS.'compiled'.DS)); - - // Compiler - static::$_parser_compiler = new Dwoo_Compiler; - static::$_parser_compiler->setAutoEscape(\Config::get('parser.View_Dwoo.environment.autoescape', false)); - static::$_parser_compiler->setLooseOpeningHandling(\Config::get('parser.View_Dwoo.environment.allow_spaces', false)); - static::$_parser_compiler->setNestedCommentsHandling(\Config::get('parser.View_Dwoo.environment.nested_comments', false)); - static::$_parser_compiler->setDelimiters( - \Config::get('parser.View_Dwoo.delimiters.left', '{'), - \Config::get('parser.View_Dwoo.delimiters.right', '}') - ); - - // Security - static::$_parser_security = new Dwoo_Security_Policy; - static::$_parser_security->setPhpHandling(\Config::get('parser.View_Dwoo.environment.allow_php_tags', 2)); - static::$_parser_security->allowPhpFunction(\Config::get('parser.View_Dwoo.environment.allow_php_func', array())); - - static::$_parser->setSecurityPolicy(static::$_parser_security); - - return static::$_parser; - } -} - -// end of file dwoo.php diff --git a/fuel/packages/parser/classes/view/haml.php b/fuel/packages/parser/classes/view/haml.php deleted file mode 100755 index 7bff1c6..0000000 --- a/fuel/packages/parser/classes/view/haml.php +++ /dev/null @@ -1,72 +0,0 @@ -file_name; - - static::cache_init($file); - $file = static::parser()->parse($file, static::$_cache); - - return parent::process_file($file); - } - - public $extension = 'haml'; - - /** - * Returns the Parser lib object - * - * @return HamlParser - */ - public static function parser() - { - if ( ! empty(static::$_parser)) - { - return static::$_parser; - } - - static::$_parser = new HamlParser(); - - return static::$_parser; - } - - // Jade stores cached templates as the filename in plain text, - // so there is a high chance of name collisions (ex: index.jade). - // This function attempts to create a unique directory for each - // compiled template. - // TODO: Extend Jade's caching class? - public function cache_init($file_path) - { - $cache_key = md5($file_path); - $cache_path = \Config::get('parser.View_Haml.cache_dir', null) - .substr($cache_key, 0, 2).DS.substr($cache_key, 2, 2); - - if ($cache_path !== null AND ! is_dir($cache_path)) - { - mkdir($cache_path, 0777, true); - } - - static::$_cache = $cache_path; - } - -} - -/* end of file haml.php */ diff --git a/fuel/packages/parser/classes/view/hamltwig.php b/fuel/packages/parser/classes/view/hamltwig.php deleted file mode 100755 index 574a195..0000000 --- a/fuel/packages/parser/classes/view/hamltwig.php +++ /dev/null @@ -1,125 +0,0 @@ -file_name; - - $local_data = $this->get_data('local'); - $global_data = $this->get_data('global'); - - // Extract View name/extension (ex. "template.twig") - $view_name = pathinfo($file, PATHINFO_BASENAME); - - // Twig Loader - $views_paths = \Config::get('parser.View_Twig.views_paths', array(APPPATH . 'views')); - array_unshift($views_paths, pathinfo($file, PATHINFO_DIRNAME)); - - if ( ! empty($global_data)) - { - foreach ($global_data as $key => $value) - { - static::parser()->addGlobal($key, $value); - } - } - else - { - // Init the parser if you have no global data - static::parser(); - } - - // Set the HtHaml Twig loader - $filesyst = new Twig_Loader_Filesystem($views_paths); - static::$_parser_loader = new MtHaml\Support\Twig\Loader(static::$_environment, $filesyst); - - $twig_lexer = new Twig_Lexer(static::$_parser, static::$_twig_lexer_conf); - static::$_parser->setLexer($twig_lexer); - //\Debug::dump(static::parser()); exit(); - try - { - $result = static::parser()->render($view_name, $local_data); - } - catch (\Exception $e) - { - // Delete the output buffer & re-throw the exception - ob_end_clean(); - throw $e; - } - - $this->unsanitize($local_data); - $this->unsanitize($global_data); - - return $result; - } - - /** - * @access public - * @static - * @return Twig_Environment - */ - public static function parser() - { - if (empty(static::$_parser)) - { - parent::parser(); - - // Register Haml twig supports - static::$_parser->addExtension(new MtHaml\Support\Twig\Extension()); - // Store MtHaml environment - static::$_environment = new MtHaml\Environment('twig', \Config::get('parser.View_HamlTwig.environment')); - - return static::$_parser; - } - return parent::parser(); - } -} - -// end of file hamltwig.php diff --git a/fuel/packages/parser/classes/view/handlebars.php b/fuel/packages/parser/classes/view/handlebars.php deleted file mode 100644 index acfae4e..0000000 --- a/fuel/packages/parser/classes/view/handlebars.php +++ /dev/null @@ -1,72 +0,0 @@ -file_name; - - // compiled template path - $path = rtrim(\Config::get('parser.View_Handlebars.compile_dir', APPPATH.'tmp'.DS.'handlebars'),DS).DS; - - // construct the compiled filename - $compiled = md5($file); - $compiled = $path.substr($compiled, 0, 1).DS.substr($compiled, 1, 1).DS.substr($compiled, 2).'.'.$this->extension; - - // do we need to compile? - if ( ! is_file($compiled) or filemtime($file) > filemtime($compiled) or \Config::get('parser.View_Handlebars.force_compile', true)) - { - // make sure the directory exists - if ( ! is_dir($compiled_path = dirname($compiled))) - { - \File::create_dir(APPPATH, substr($compiled_path, strlen(APPPATH))); - } - - // write the compiled code - file_put_contents($compiled, ' function($cx, $name) { - $file = \Finder::search('views', $name, '.'.$this->extension, false, false); - return empty($file) ? "[ PARTIAL $name NOT FOUND!]" : file_get_contents($file); - } - ) + \Config::get('parser.View_Handlebars.environment', array()) - )); - } - - // fetch the compiled template and render it - try - { - $data = $this->get_data(); - $result = include($compiled); - $result = $result($data); - } - catch (\Exception $e) - { - // Delete the output buffer & re-throw the exception - ob_end_clean(); - throw $e; - } - - $this->unsanitize($data); - return $result; - } -} diff --git a/fuel/packages/parser/classes/view/jade.php b/fuel/packages/parser/classes/view/jade.php deleted file mode 100755 index add58f1..0000000 --- a/fuel/packages/parser/classes/view/jade.php +++ /dev/null @@ -1,117 +0,0 @@ -registerVisitor('tag', new Everzet\Visitor\AutotagsVisitor()); - $dumper->registerFilter('javascript', new Everzet\Filter\JavaScriptFilter()); - $dumper->registerFilter('cdata', new Everzet\Filter\CDATAFilter()); - $dumper->registerFilter('php', new Everzet\Filter\PHPFilter()); - $dumper->registerFilter('style', new Everzet\Filter\CSSFilter()); - - // return the Jade parser - return new Everzet\Jade($parser, $dumper, $cachepath); - } - - /** - * Returns the Parser lib object - * - * @return Tale\Jade - */ - protected function tale_parser($cachepath) - { - // get the config - $config = \Config::get('parser.View_Jade', array()); - - // add the cache path for this template - $config['cachePath'] = $cachepath; - - // create a renderer instance - return new Tale\Renderer($config); - } - - /** - * @InheritDoc - */ - protected function process_file($file_override = false) - { - // determine the filename - $file = $file_override ?: $this->file_name; - - // render the template using the Everzet implementation - if (class_exists('Everzet\\Jade\\Jade')) - { - // render the template - $file = $this->everzet_parser($this->cache_init($file))->cache($file); - $result = parent::process_file($file); - } - - // render the template using the Tale implementation - elseif (class_exists('Tale\\Jade\\Renderer')) - { - // render the template - $result = $this->jade_parser($this->cache_init($file))->render($file, $data = $this->get_data()); - - // disable sanitization on objects that support it - $this->unsanitize($data); - } - - // no known renderer found - else - { - throw new \FuelException("No supported Jade renderer found. Please check the documentation"); - } - - return $result; - } - - // Jade stores cached templates as the filename in plain text, - // so there is a high chance of name collisions (ex: index.jade). - // This function attempts to create a unique directory for each - // compiled template. - protected function cache_init($file_path) - { - $cache_key = md5($file_path); - $cache_path = \Config::get('parser.View_Jade.cache_dir', null) - .substr($cache_key, 0, 2).DS.substr($cache_key, 2, 2); - - if ($cache_path !== null AND ! is_dir($cache_path)) - { - mkdir($cache_path, 0777, true); - } - - return $cache_path; - } - -} diff --git a/fuel/packages/parser/classes/view/lex.php b/fuel/packages/parser/classes/view/lex.php deleted file mode 100755 index fd9b7d3..0000000 --- a/fuel/packages/parser/classes/view/lex.php +++ /dev/null @@ -1,67 +0,0 @@ -callback = $callback; - - return $this; - } - - protected function process_file($file_override = false) - { - $file = $file_override ?: $this->file_name; - - try - { - $data = $this->get_data(); - static::parser()->scopeGlue(\Config::get('parser.View_Lex.scope_glue', '.')); - $result = static::parser()->parse(file_get_contents($file), $data, $this->callback, \Config::get('parser.View_Lex.allow_php', false)); - } - catch (\Exception $e) - { - // Delete the output buffer & re-throw the exception - ob_end_clean(); - throw $e; - } - - $this->unsanitize($data); - return $result; - } -} diff --git a/fuel/packages/parser/classes/view/markdown.php b/fuel/packages/parser/classes/view/markdown.php deleted file mode 100755 index 9a70d97..0000000 --- a/fuel/packages/parser/classes/view/markdown.php +++ /dev/null @@ -1,84 +0,0 @@ -file_name; - - $contents = ''; - - if (\Config::get('parser.View_Markdown.allow_php', false)) - { - $contents = static::pre_process('php', $file, $data = $this->get_data()); - $this->unsanitize($data); - } - else - { - $contents = file_get_contents($file); - } - - return static::parser()->transform($contents); - } - - protected static function pre_process($_type = 'php', $_view_filename, array $_data = array()) - { - if ($_type == 'php') - { - // Import the view variables to local namespace - $_data AND extract($_data, EXTR_REFS); - - // Capture the view output - ob_start(); - - try - { - // Load the view within the current scope - include $_view_filename; - } - catch (\Exception $e) - { - // Delete the output buffer - ob_end_clean(); - - // Re-throw the exception - throw $e; - } - - // Get the captured output and close the buffer - return ob_get_clean(); - } - } - - public $extension = 'md'; - - /** - * Returns the Parser lib object - * - * @return Markdown_Parser - */ - public static function parser() - { - static $parser = null; - if (is_null($parser)) - { - $parser = new \Michelf\MarkdownExtra(); - } - - return $parser; - } -} diff --git a/fuel/packages/parser/classes/view/mustache.php b/fuel/packages/parser/classes/view/mustache.php deleted file mode 100755 index 27e8ad0..0000000 --- a/fuel/packages/parser/classes/view/mustache.php +++ /dev/null @@ -1,83 +0,0 @@ -file_name; - $data = $this->get_data(); - - try - { - $result = static::parser()->render(file_get_contents($file), $data); - } - catch (\Exception $e) - { - // Delete the output buffer & re-throw the exception - ob_end_clean(); - throw $e; - } - - $this->unsanitize($data); - return $result; - } - - public $extension = 'mustache'; - - /** - * Returns the Parser lib object - * - * @return Mustache_Engine - */ - public static function parser() - { - if ( ! empty(static::$_parser)) - { - return static::$_parser; - } - - $options = array( - // TODO: set 'logger' with Monolog instance. - 'cache' => \Config::get('parser.View_Mustache.environment.cache_dir', APPPATH.'cache'.DS.'mustache'.DS), - 'charset' => \Config::get('parser.View_Mustache.environment.charset', 'UTF-8'), - ); - - if ($partials = \Config::get('parser.View_Mustache.environment.partials', array())) - { - $options['partials'] = $partials; - } - - if ($helpers = \Config::get('parser.View_Mustache.environment.helpers', array())) - { - $options['helpers'] = $helpers; - } - - if ($partials = \Config::get('parser.View_Mustache.environment.partials_loader', array())) - { - $options['partials_loader'] = new Mustache_Loader_FilesystemLoader($partials); - } - - static::$_parser = new Mustache_Engine($options); - - return static::$_parser; - } -} - -// end of file mustache.php diff --git a/fuel/packages/parser/classes/view/phptal.php b/fuel/packages/parser/classes/view/phptal.php deleted file mode 100755 index 04e5fa2..0000000 --- a/fuel/packages/parser/classes/view/phptal.php +++ /dev/null @@ -1,66 +0,0 @@ -file_name; - - try - { - $parser = static::parser(); - $data = $this->get_data(); - foreach($data as $key => $value) - { - $parser->set($key, $value); - } - $parser->setTemplate($file); - $result = $parser->execute(); - } - catch (\Exception $e) - { - // Delete the output buffer & re-throw the exception - ob_end_clean(); - throw $e; - } - - $this->unsanitize($data); - return $result; - } - - public $extension = 'phptal'; - - public static function parser() - { - if ( ! empty(static::$_parser)) - { - return static::$_parser; - } - - static::$_parser = new \PHPTAL(); - static::$_parser->setEncoding(\Config::get('parser.View_Phptal.encoding', 'UTF-8')); - static::$_parser->setOutputMode(constant('\\'.\Config::get('parser.View_Phptal.output_mode', 'PHPTAL::XHTML'))); - static::$_parser->setTemplateRepository(\Config::get('parser.View_Phptal.template_repository', '')); - static::$_parser->setPhpCodeDestination(\Config::get('parser.View_Phptal.cache_dir', APPPATH.'cache'.DS.'PHPTAL'.DS)); - static::$_parser->setCacheLifetime(\Config::get('parser.View_Phptal.cache_lifetime', 0)); - static::$_parser->setForceReparse(\Config::get('parser.View_Phptal.force_reparse', false)); - - return static::$_parser; - } -} - -// end of file phptal.php diff --git a/fuel/packages/parser/classes/view/smarty.php b/fuel/packages/parser/classes/view/smarty.php deleted file mode 100755 index 077f209..0000000 --- a/fuel/packages/parser/classes/view/smarty.php +++ /dev/null @@ -1,84 +0,0 @@ -file_name; - - try - { - // Smarty doesn't support method chaining - $parser = static::parser(); - $parser->assign($data = $this->get_data()); - $result = $parser->fetch($file); - } - catch (\Exception $e) - { - // Delete the output buffer & re-throw the exception - ob_end_clean(); - throw $e; - } - - $this->unsanitize($data); - return $result; - } - - public $extension = 'smarty'; - - /** - * Returns the Parser lib object - * - * @return Smarty - */ - public static function parser() - { - if ( ! empty(static::$_parser)) - { - return static::$_parser; - } - - // Parser - static::$_parser = new Smarty(); - static::$_parser->template_dir = \Config::get('parser.View_Smarty.environment.template_dir', APPPATH.'views'.DS); - static::$_parser->compile_dir = \Config::get('parser.View_Smarty.environment.compile_dir', APPPATH.'tmp'.DS.'Smarty'.DS.'templates_c'.DS); - static::$_parser->config_dir = \Config::get('parser.View_Smarty.environment.config_dir', APPPATH.'tmp'.DS.'Smarty'.DS.'configs'.DS); - static::$_parser->cache_dir = \Config::get('parser.View_Smarty.environment.cache_dir', APPPATH.'cache'.DS.'Smarty'.DS); - $plugins_dir = \Config::get('parser.View_Smarty.environment.plugins_dir', array()); - static::$_parser->addPluginsDir($plugins_dir); - - static::$_parser->caching = \Config::get('parser.View_Smarty.environment.caching', false); - static::$_parser->cache_lifetime = \Config::get('parser.View_Smarty.environment.cache_lifetime', 0); - static::$_parser->force_compile = \Config::get('parser.View_Smarty.environment.force_compile', false); - static::$_parser->compile_check = \Config::get('parser.View_Smarty.environment.compile_check', true); - static::$_parser->debugging = \Config::get('parser.View_Smarty.environment.debugging', false); - - static::$_parser->left_delimiter = \Config::get('parser.View_Smarty.delimiters.left', '{'); - static::$_parser->right_delimiter = \Config::get('parser.View_Smarty.delimiters.right', '}'); - - static::$_parser->autoload_filters = \Config::get('parser.View_Smarty.environment.autoload_filters', array()); - static::$_parser->default_modifiers = \Config::get('parser.View_Smarty.environment.default_modifiers', array()); - foreach (\Config::get('parser.View_Smarty.extensions', array()) as $extension){ - new $extension(static::$_parser); - } - return static::$_parser; - } -} - -// end of file smarty.php diff --git a/fuel/packages/parser/classes/view/twig.php b/fuel/packages/parser/classes/view/twig.php deleted file mode 100755 index c31467d..0000000 --- a/fuel/packages/parser/classes/view/twig.php +++ /dev/null @@ -1,125 +0,0 @@ -file_name; - - $local_data = $this->get_data('local'); - $global_data = $this->get_data('global'); - - // Extract View name/extension (ex. "template.twig") - $view_name = pathinfo($file, PATHINFO_BASENAME); - - // Twig Loader - $views_paths = \Config::get('parser.View_Twig.views_paths', array(APPPATH . 'views')); - array_unshift($views_paths, pathinfo($file, PATHINFO_DIRNAME)); - static::$_parser_loader = new Twig_Loader_Filesystem($views_paths); - - if ( ! empty($global_data)) - { - foreach ($global_data as $key => $value) - { - static::parser()->addGlobal($key, $value); - } - } - else - { - // Init the parser if you have no global data - static::parser(); - } - - $twig_lexer = new Twig_Lexer(static::$_parser, static::$_twig_lexer_conf); - static::$_parser->setLexer($twig_lexer); - - try - { - $result = static::parser()->loadTemplate($view_name)->render($local_data); - } - catch (\Exception $e) - { - // Delete the output buffer & re-throw the exception - ob_end_clean(); - throw $e; - } - - $this->unsanitize($local_data); - $this->unsanitize($global_data); - - return $result; - } - - public $extension = 'twig'; - - /** - * Returns the Parser lib object - * - * @return Twig_Environment - */ - public static function parser() - { - if ( ! empty(static::$_parser)) - { - static::$_parser->setLoader(static::$_parser_loader); - return static::$_parser; - } - - // Twig Environment - $twig_env_conf = \Config::get('parser.View_Twig.environment', array('optimizer' => -1)); - static::$_parser = new Twig_Environment(static::$_parser_loader, $twig_env_conf); - - foreach (\Config::get('parser.View_Twig.extensions') as $ext) - { - static::$_parser->addExtension(new $ext()); - } - - // Twig Lexer - static::$_twig_lexer_conf = \Config::get('parser.View_Twig.delimiters', null); - if (isset(static::$_twig_lexer_conf)) - { - isset(static::$_twig_lexer_conf['tag_block']) - and static::$_twig_lexer_conf['tag_block'] = array_values(static::$_twig_lexer_conf['tag_block']); - isset(static::$_twig_lexer_conf['tag_comment']) - and static::$_twig_lexer_conf['tag_comment'] = array_values(static::$_twig_lexer_conf['tag_comment']); - isset(static::$_twig_lexer_conf['tag_variable']) - and static::$_twig_lexer_conf['tag_variable'] = array_values(static::$_twig_lexer_conf['tag_variable']); - } - - return static::$_parser; - } -} - -// end of file twig.php diff --git a/fuel/packages/parser/composer.json b/fuel/packages/parser/composer.json deleted file mode 100755 index d28f9e7..0000000 --- a/fuel/packages/parser/composer.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "fuel/parser", - "description" : "FuelPHP 1.x Parser Package", - "type": "fuel-package", - "homepage": "https://github.com/fuel/parser", - "license": "MIT", - "authors": [ - { - "name": "FuelPHP Development Team", - "email": "team@fuelphp.com" - } - ], - "require": { - "composer/installers": "~1.0" - } -} diff --git a/fuel/packages/parser/config/parser.php b/fuel/packages/parser/config/parser.php deleted file mode 100755 index ec9d731..0000000 --- a/fuel/packages/parser/config/parser.php +++ /dev/null @@ -1,211 +0,0 @@ - array( - 'php' => 'View', - 'twig' => 'View_Twig', - 'mthaml' => array('class' => 'View_HamlTwig', 'extension' => 'haml'), - 'mustache' => 'View_Mustache', - 'md' => 'View_Markdown', - 'dwoo' => array('class' => 'View_Dwoo', 'extension' => 'tpl'), - 'jade' => 'View_Jade', - 'haml' => 'View_Haml', - 'smarty' => 'View_Smarty', - 'phptal' => 'View_Phptal', - 'lex' => 'View_Lex', - ), - - // ------------------------------------------------------------------------ - // Individual class config by classname - // ------------------------------------------------------------------------ - - - // MARKDOWN ( http://michelf.com/projects/php-markdown/ ) - // ------------------------------------------------------------------------ - 'View_Markdown' => array( - 'auto_encode' => true, - 'allow_php' => true, - ), - - // TWIG ( http://www.twig-project.org/documentation ) - // ------------------------------------------------------------------------ - 'View_Twig' => array( - 'auto_encode' => true, - 'views_paths' => array(APPPATH.'views'), - 'delimiters' => array( - 'tag_block' => array('left' => '{%', 'right' => '%}'), - 'tag_comment' => array('left' => '{#', 'right' => '#}'), - 'tag_variable' => array('left' => '{{', 'right' => '}}'), - ), - 'environment' => array( - 'debug' => false, - 'charset' => 'utf-8', - 'base_template_class' => 'Twig_Template', - 'cache' => APPPATH.'cache'.DS.'twig'.DS, - 'auto_reload' => true, - 'strict_variables' => false, - 'autoescape' => false, - 'optimizations' => -1, - ), - 'extensions' => array( - 'Twig_Fuel_Extension', - ), - ), - - // HamlTwig with MtHaml https://github.com/arnaud-lb/MtHaml - // Twig configuration is grabbed from 'View_Twig' config key - // Packagist url: https://packagist.org/packages/mthaml/mthaml - // Uses > 1.1.1 (Master branch ATM) - // ------------------------------------------------------------------------ - 'View_HamlTwig' => array( - //'include' => APPPATH.'vendor'.DS.'MtHaml'.DS.'Autoloader.php', - 'auto_encode' => true, - 'environment' => array( - 'auto_escaper' => true, - 'escape_html' => true, - 'escape_attrs' => true, - 'charset' => 'UTF-8', - 'format' => 'html5', - ), - ), - - // DWOO ( http://wiki.dwoo.org/ ) - // ------------------------------------------------------------------------ - 'View_Dwoo' => array( - 'include' => APPPATH.'vendor'.DS.'Dwoo'.DS.'dwooAutoload.php', - 'auto_encode' => true, - 'delimiters' => array('left' => '{{', 'right' => '}}'), - 'environment' => array( - 'autoescape' => false, - 'nested_comments' => false, - 'allow_spaces' => false, - 'cache_dir' => APPPATH.'cache'.DS.'dwoo'.DS, - 'compile_dir' => APPPATH.'cache'.DS.'dwoo'.DS.'compiled'.DS, - 'cache_time' => 0, - - // Set what parser should do with PHP tags - // 1 - Encode tags | 2 - Remove tags | 3 - Allow tags - 'allow_php_tags' => 2, - - // Which PHP functions should be accessible through Parser - 'allow_php_func' => array(), - ), - ), - - // MUSTACHE ( https://github.com/bobthecow/mustache.php ) - // ------------------------------------------------------------------------ - 'View_Mustache' => array( - 'auto_encode' => true, - 'environment' => array( - 'cache_dir' => APPPATH.'cache'.DS.'mustache'.DS, - 'partials' => array(), - 'helpers' => array(), - 'charset' => 'UTF-8', - ), - ), - - // JADE PHP ( https://github.com/everzet/jade.php ) - // See notes in /parser/classes/view/jade.php - // ------------------------------------------------------------------------ - 'View_Jade' => array( - // global config - 'cache_dir' => APPPATH.'cache'.DS.'jade'.DS, - - // Everzet config - 'include' => APPPATH.'vendor'.DS.'Jade'.DS.'autoload.php.dist', - 'auto_encode' => true, - - // Tale config - 'lifetime' => 3600, - 'pretty' => false, - ), - - // HAML / PHAMLP ( http://code.google.com/p/phamlp/ ) - // ------------------------------------------------------------------------ - 'View_Haml' => array( - 'include' => APPPATH.'vendor'.DS.'Phamlp'.DS.'haml'.DS.'HamlParser.php', - 'auto_encode' => true, - 'cache_dir' => APPPATH.'cache'.DS.'haml'.DS, - ), - - // SMARTY ( http://www.smarty.net/documentation ) - // ------------------------------------------------------------------------ - 'View_Smarty' => array( - 'auto_encode' => true, - 'delimiters' => array('left' => '{', 'right' => '}'), - 'environment' => array( - 'compile_dir' => APPPATH.'tmp'.DS.'Smarty'.DS.'templates_c'.DS, - 'config_dir' => APPPATH.'tmp'.DS.'Smarty'.DS.'configs'.DS, - 'cache_dir' => APPPATH.'cache'.DS.'Smarty'.DS, - 'plugins_dir' => array(), - 'caching' => false, - 'cache_lifetime' => 0, - 'force_compile' => false, - 'compile_check' => true, - 'debugging' => false, - 'autoload_filters' => array(), - 'default_modifiers' => array(), - ), - 'extensions' => array( - 'Smarty_Fuel_Extension', - ), - ), - - // PHPTAL ( http://phptal.org/manual/en/ ) - // ------------------------------------------------------------------------ - 'View_Phptal' => array( - 'include' => APPPATH.'vendor'.DS.'PHPTAL'.DS.'PHPTAL.php', - 'auto_encode' => true, - 'cache_dir' => APPPATH.'cache'.DS.'PHPTAL'.DS, - 'cache_lifetime' => 0, - 'encoding' => 'UTF-8', - 'output_mode' => 'PHPTAL::XHTML', - 'template_repository' => '', - 'force_reparse' => false, - ), - - // LEX ( http://github.com/pyrocms/lex/ ) - // Packagist url: https://packagist.org/packages/pyrocms/lex - // ------------------------------------------------------------------------ - 'View_Lex' => array( - 'scope_glue' => '.', - 'allow_php' => false, - ), - - // HANDLEBARS ( https://github.com/zordius/lightncandy ) - // Packagist url: https://packagist.org/packages/zordius/lightncandy - // ------------------------------------------------------------------------ - 'View_Handlebars' => array( - 'force_compile' => true, - 'compile_dir' => APPPATH.'tmp'.DS.'handlebars'.DS, - 'environment' => array( - 'flags' => class_exists('LightnCandy\LightnCandy') ? LightnCandy\LightnCandy::FLAG_ERROR_EXCEPTION | LightnCandy\LightnCandy::FLAG_ELSE | LightnCandy\LightnCandy::FLAG_HBESCAPE | LightnCandy\LightnCandy::FLAG_JS : 0, - 'helpers' => array(), - 'helperresolver' => function($cx, $name) { return; }, - ), - ), - -);