Merge branch 'master' of git://github.com/shadowhand/kohana
This commit is contained in:
commit
5e63e8f34f
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1 @@
|
|||
application/logs/*
|
||||
application/cache/*
|
||||
*.DS_Store
|
|
@ -0,0 +1,3 @@
|
|||
# Kohana PHP Framework, version 3.0 (dev)
|
||||
|
||||
This is the current development version of [Kohana](http://kohanaphp.com/).
|
1
application/cache/.gitignore
vendored
Normal file
1
application/cache/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
[^.]*
|
1
application/log/.gitignore
vendored
Normal file
1
application/log/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
[^.]*
|
43
index.php
43
index.php
|
@ -1,32 +1,65 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The directory in which your application specific resources are located.
|
||||
* The application directory must contain the config/kohana.php file.
|
||||
*
|
||||
* @see http://docs.kohanaphp.com/install#application
|
||||
*/
|
||||
$application = 'application';
|
||||
|
||||
/**
|
||||
* The directory in which shared resources are located. Each module must be
|
||||
* contained within its own directory.
|
||||
*
|
||||
* @see http://docs.kohanaphp.com/install#modules
|
||||
*/
|
||||
$modules = 'modules';
|
||||
|
||||
/**
|
||||
* The directory in which the Kohana resources are located. The system
|
||||
* directory must contain the classes/kohana.php file.
|
||||
*
|
||||
* @see http://docs.kohanaphp.com/install#system
|
||||
*/
|
||||
$system = 'system';
|
||||
|
||||
/**
|
||||
* The default extension of resource files. If you change this, all resources
|
||||
* must be renamed to use the new extension.
|
||||
*
|
||||
* @see http://docs.kohanaphp.com/install#ext
|
||||
*/
|
||||
define('EXT', '.php');
|
||||
|
||||
define('DOCROOT', str_replace('\\', '/', pathinfo(__FILE__, PATHINFO_DIRNAME)).'/');
|
||||
//
|
||||
// END OF CONFIGURATION, DO NOT EDIT BELOW!
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
// Define the name of the front controller
|
||||
define('FC_FILE', basename(__FILE__));
|
||||
|
||||
// Define the absolute paths for configured directories
|
||||
define('DOCROOT', str_replace('\\', '/', realpath(getcwd())).'/');
|
||||
define('APPPATH', str_replace('\\', '/', realpath($application)).'/');
|
||||
define('MODPATH', str_replace('\\', '/', realpath($modules)).'/');
|
||||
define('SYSPATH', str_replace('\\', '/', realpath($system)).'/');
|
||||
|
||||
// Clean up the configuration vars
|
||||
unset($application, $modules, $system);
|
||||
|
||||
if (file_exists('install'.EXT))
|
||||
{
|
||||
// Installation check
|
||||
// Load the installation check
|
||||
include 'install'.EXT;
|
||||
}
|
||||
elseif (file_exists(APPPATH.'bootstrap'.EXT))
|
||||
{
|
||||
// Custom boostrap
|
||||
// Load the custom bootstrap
|
||||
include APPPATH.'bootstrap'.EXT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default bootstrap
|
||||
// Load the default bootstrap
|
||||
include SYSPATH.'bootstrap'.EXT;
|
||||
}
|
||||
|
|
17
install.php
17
install.php
|
@ -8,9 +8,9 @@
|
|||
<title>Kohana Installation</title>
|
||||
|
||||
<style type="text/css">
|
||||
body { width: 42em; margin: 0 auto; font-family: sans-serif; }
|
||||
h1 { letter-spacing: -0.05em; }
|
||||
h1 + p { width: 75%; margin: 0 0 2em; color: #666; font-style: italic; font-size:90%; }
|
||||
body { width: 42em; margin: 0 auto; font-family: sans-serif; background: #fff; font-size: 1em; }
|
||||
h1 { letter-spacing: -0.04em; }
|
||||
h1 + p { margin: 0 0 2em; color: #333; font-size: 90%; font-style: italic; }
|
||||
code { font-family: monaco, monospace; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
table th,
|
||||
|
@ -70,6 +70,14 @@
|
|||
<td class="fail">The configured <code>modules</code> directory does not exist or does not contain required files.</td>
|
||||
<?php endif ?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Cache Directory</th>
|
||||
<?php if (is_dir(APPPATH) AND is_dir(APPPATH.'cache') AND is_writable(APPPATH.'cache')): ?>
|
||||
<td class="pass"><?php echo APPPATH.'cache' ?></td>
|
||||
<?php else: $failed = TRUE ?>
|
||||
<td class="fail">The <code><?php echo APPPATH.'cache' ?></code> directory is not writable.</td>
|
||||
<?php endif ?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>PCRE UTF-8</th>
|
||||
<?php if ( ! @preg_match('/^.$/u', 'ñ')): $failed = TRUE ?>
|
||||
|
@ -127,7 +135,8 @@
|
|||
<?php if ($failed === TRUE): ?>
|
||||
<p id="results" class="fail">✘ Kohana may not work correctly with your environment.</p>
|
||||
<?php else: ?>
|
||||
<p id="results" class="pass">✔ Your environment passed all requirements.<br />Remove or rename the <code>install<?php echo EXT ?></code> file now.</p>
|
||||
<p id="results" class="pass">✔ Your environment passed all requirements.<br />
|
||||
Remove or rename the <code>install<?php echo EXT ?></code> file now.</p>
|
||||
<?php endif ?>
|
||||
|
||||
</body>
|
||||
|
|
0
media/css/grid.css
Normal file
0
media/css/grid.css
Normal file
0
media/css/print.css
Normal file
0
media/css/print.css
Normal file
0
media/css/reset.css
Normal file
0
media/css/reset.css
Normal file
0
media/css/web.css
Normal file
0
media/css/web.css
Normal file
BIN
media/img/kohana.png
Normal file
BIN
media/img/kohana.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
|
@ -28,9 +28,6 @@ else
|
|||
define('SERVER_UTF8', FALSE);
|
||||
}
|
||||
|
||||
// Default output type is UTF-8 text/html
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
// Load the main Kohana class
|
||||
require SYSPATH.'classes/kohana'.EXT;
|
||||
|
||||
|
@ -44,15 +41,12 @@ $_COOKIE = utf8::clean($_COOKIE);
|
|||
$_SERVER = utf8::clean($_SERVER);
|
||||
|
||||
|
||||
/*
|
||||
$route = Route::factory('(:controller(/:method(/:id)))')
|
||||
->defaults(array('controller' => 'welcome', 'method' => 'index'));
|
||||
|
||||
|
||||
echo Kohana::debug($route->matches('uploads/doc/foo.xml'));
|
||||
*/
|
||||
$route = Route::factory('(:path/):file(.:format)', array('path' => '.*'));
|
||||
|
||||
$view = View::factory('test');
|
||||
echo Kohana::debug($route->matches('uploads/doc/foo.xml'));
|
||||
|
||||
echo $view->render();
|
||||
// Shutdown the environment
|
||||
Kohana::shutdown();
|
|
@ -16,14 +16,23 @@
|
|||
*/
|
||||
final class Kohana {
|
||||
|
||||
// Command line instance
|
||||
public static $cli_mode = FALSE;
|
||||
|
||||
// Client request method
|
||||
public static $request_method = 'GET';
|
||||
|
||||
// Default charset for all requests
|
||||
public static $charset = 'UTF-8';
|
||||
|
||||
// Has the environment been initialized?
|
||||
private static $init = FALSE;
|
||||
|
||||
// Include paths that are used to find files
|
||||
private static $include_paths = array(APPPATH, SYSPATH);
|
||||
|
||||
// Cache for class methods
|
||||
private static $cache = array();
|
||||
// Cache for resource location
|
||||
private static $file_path;
|
||||
|
||||
/**
|
||||
* Initializes the environment:
|
||||
|
@ -39,12 +48,54 @@ final class Kohana {
|
|||
if (self::$init === TRUE)
|
||||
return;
|
||||
|
||||
// Enable auto-loading of classes
|
||||
spl_autoload_register(array(__CLASS__, 'auto_load'));
|
||||
|
||||
// Load the file path cache
|
||||
self::$file_path = Kohana::cache('kohana_file_paths');
|
||||
|
||||
if (PHP_SAPI === 'cli')
|
||||
{
|
||||
// The current instance is being run via the command line
|
||||
self::$cli_mode = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($_SERVER['REQUEST_METHOD']))
|
||||
{
|
||||
// Let the server determine the request method
|
||||
self::$request_method = strtoupper($_SERVER['REQUEST_METHOD']);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if ($hooks = self::find_file('hooks'))
|
||||
{
|
||||
foreach ($hooks as $hook)
|
||||
{
|
||||
// Load each hook in the order they appear
|
||||
require $hook;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// The system has been initialized
|
||||
self::$init = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* The last method before Kohana stops processing the request:
|
||||
*
|
||||
* - Saves the file path cache
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function shutdown()
|
||||
{
|
||||
Kohana::cache('kohana_file_paths', self::$file_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path of a file by directory, filename, and extension.
|
||||
* If no extension is give, the default EXT extension will be used.
|
||||
|
@ -66,25 +117,41 @@ final class Kohana {
|
|||
// Use the defined extension by default
|
||||
$ext = ($ext === NULL) ? EXT : '.'.$ext;
|
||||
|
||||
// Full (relative) path name
|
||||
// Create a partial path of the filename
|
||||
$file = $dir.'/'.$file.$ext;
|
||||
|
||||
if (isset(self::$cache[__FUNCTION__][$file]))
|
||||
if (isset(self::$file_path[$file]))
|
||||
{
|
||||
return self::$cache[__FUNCTION__][$file];
|
||||
// The path to this file has already been found
|
||||
return self::$file_path[$file];
|
||||
}
|
||||
|
||||
foreach (self::$include_paths as $path)
|
||||
{
|
||||
if (file_exists($path.$file))
|
||||
{
|
||||
return self::$cache[__FUNCTION__][$file] = $path.$file;
|
||||
// Cache and return the path to this file
|
||||
return self::$file_path[$file] = $path.$file;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a file within a totally empty scope and returns the output:
|
||||
*
|
||||
* $foo = Kohana::load_file('foo.php');
|
||||
*
|
||||
* @param string
|
||||
* @return mixed
|
||||
*/
|
||||
public function load_file($file)
|
||||
{
|
||||
// Return the output of the file
|
||||
return include $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides auto-loading support of Kohana classes, as well as transparent
|
||||
* extension of classes that have a _Core suffix.
|
||||
|
@ -93,7 +160,7 @@ final class Kohana {
|
|||
* lowercase and converting underscores to slashes:
|
||||
*
|
||||
* // Loads classes/my/class/name.php
|
||||
* Kohana::auto_load('My_Class_Name')
|
||||
* Kohana::auto_load('My_Class_Name');
|
||||
*
|
||||
* @param string class name
|
||||
* @param string file extensions to use
|
||||
|
@ -101,10 +168,12 @@ final class Kohana {
|
|||
*/
|
||||
public static function auto_load($class)
|
||||
{
|
||||
// Transform the class name into a path
|
||||
$file = str_replace('_', '/', strtolower($class));
|
||||
|
||||
if ($path = self::find_file('classes', $file))
|
||||
{
|
||||
// Load the class file
|
||||
require $path;
|
||||
}
|
||||
else
|
||||
|
@ -114,6 +183,7 @@ final class Kohana {
|
|||
|
||||
if ($path = self::find_file('extensions', $file))
|
||||
{
|
||||
// Load the extension file
|
||||
require $path;
|
||||
}
|
||||
elseif (class_exists($class.'_Core', FALSE))
|
||||
|
@ -131,13 +201,67 @@ final class Kohana {
|
|||
}
|
||||
|
||||
// Transparent class extensions are possible using eval. Not very
|
||||
// clean, but it can be avoided by creating empty extensions.
|
||||
// clean, but it can be avoided by creating empty extension files.
|
||||
eval($extension);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides simple file-based caching. All caches are serialized and
|
||||
* stored as a hash.
|
||||
*
|
||||
* // Set the "foo" cache
|
||||
* Kohana::cache('foo', 'hello, world');
|
||||
*
|
||||
* // Get the "foo" cache
|
||||
* $foo = Kohana::cache('foo');
|
||||
*
|
||||
* @param string name of the cache
|
||||
* @param mixed data to cache
|
||||
* @param integer number of seconds the cache is valid for
|
||||
* @return mixed for getting
|
||||
* @return boolean for setting
|
||||
*/
|
||||
public function cache($name, $data = NULL, $lifetime = 60)
|
||||
{
|
||||
// Cache file is a hash of the name
|
||||
$file = sha1($name);
|
||||
|
||||
// Cache directories are split by keys
|
||||
$dir = APPPATH.'cache/'.$file[0].'/';
|
||||
|
||||
if ($data === NULL)
|
||||
{
|
||||
if (is_file($dir.$file))
|
||||
{
|
||||
if ((time() - filemtime($dir.$file)) < $lifetime)
|
||||
{
|
||||
// Return the cache
|
||||
return unserialize(file_get_contents($dir.$file));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cache has expired
|
||||
unlink($dir.$file);
|
||||
}
|
||||
}
|
||||
|
||||
// Cache not found
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( ! is_dir($dir))
|
||||
{
|
||||
// Create the cache directory
|
||||
mkdir($dir, 0777);
|
||||
}
|
||||
|
||||
// Serialize the data and create the cache
|
||||
return (bool) file_put_contents($dir.$file, serialize($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTML string of debugging information about any number of
|
||||
* variables, each wrapped in a <pre> tag:
|
||||
|
@ -154,13 +278,13 @@ final class Kohana {
|
|||
if (func_num_args() === 0)
|
||||
return;
|
||||
|
||||
// Get params
|
||||
$params = func_get_args();
|
||||
$output = array();
|
||||
// Get all passed variables
|
||||
$variables = func_get_args();
|
||||
|
||||
foreach ($params as $var)
|
||||
$output = array();
|
||||
foreach ($variables as $var)
|
||||
{
|
||||
$output[] = '<pre>('.gettype($var).') '.htmlspecialchars(print_r($var, TRUE)).'</pre>';
|
||||
$output[] = '<pre>('.gettype($var).') '.htmlspecialchars(print_r($var, TRUE), ENT_QUOTES, self::$charset, TRUE).'</pre>';
|
||||
}
|
||||
|
||||
return implode("\n", $output);
|
||||
|
|
|
@ -82,6 +82,13 @@ class Route_Core {
|
|||
{
|
||||
$this->regex = $regex;
|
||||
}
|
||||
|
||||
// Attempt to load the cached regex
|
||||
if (($this->compiled = Kohana::cache('route:'.$uri)) === NULL)
|
||||
{
|
||||
// Compile and cache the compiled regex
|
||||
Kohana::cache('route:'.$uri, $this->compiled = $this->compile());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,10 +139,7 @@ class Route_Core {
|
|||
*/
|
||||
public function matches($uri)
|
||||
{
|
||||
// Get the compiled regex
|
||||
$regex = $this->compile();
|
||||
|
||||
if (preg_match('#'.$regex.'#', $uri, $matches))
|
||||
if (preg_match('#'.$this->compiled.'#', $uri, $matches))
|
||||
{
|
||||
$params = array();
|
||||
foreach ($matches as $key => $value)
|
||||
|
@ -168,19 +172,13 @@ class Route_Core {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the compiled regular expression for the route. The generated
|
||||
* pattern will be cached after it is compiled.
|
||||
* Returns the compiled regular expression for the route. This translates
|
||||
* keys and optional groups to a proper PCRE regular expression.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compile()
|
||||
{
|
||||
if (isset($this->cache[$this->uri]))
|
||||
{
|
||||
// The regex has already been compiled
|
||||
return $this->cache[$this->uri];
|
||||
}
|
||||
|
||||
// The URI should be considered literal except for keys and optional parts
|
||||
// Escape everything preg_quote would escape except for : ( )
|
||||
$this->uri = preg_replace('#'.Route::REGEX_ESCAPE.'#', '\\\\$0', $this->uri);
|
||||
|
@ -205,19 +203,24 @@ class Route_Core {
|
|||
$regex = strtr($regex, $replace);
|
||||
}
|
||||
|
||||
// Add anchors and cache the compiled regex
|
||||
return $this->compiled = '^'.$regex.'$';
|
||||
return '^'.$regex.'$';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a segment keys into a regular expression patterns.
|
||||
*
|
||||
* @param array array of keys
|
||||
* @return array
|
||||
*/
|
||||
protected function compile_keys(array $keys)
|
||||
{
|
||||
$groups = array();
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
// Get the key name
|
||||
// Remove the colon from the key to get the name
|
||||
$name = substr($key, 1);
|
||||
|
||||
// Name the matched segment
|
||||
// Create a named regex match
|
||||
$regex = '(?P<'.$name.'>';
|
||||
|
||||
if (isset($this->regex[$name]))
|
||||
|
|
Loading…
Reference in a new issue