Merge branch 'master' of git://github.com/shadowhand/kohana

This commit is contained in:
Geert De Deckere 2008-12-09 19:50:05 +01:00
commit 5e63e8f34f
14 changed files with 216 additions and 49 deletions

3
.gitignore vendored
View file

@ -1,2 +1 @@
application/logs/*
application/cache/*
*.DS_Store

View file

@ -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
View file

@ -0,0 +1 @@
[^.]*

1
application/log/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
[^.]*

View file

@ -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;
}

View file

@ -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
View file

0
media/css/print.css Normal file
View file

0
media/css/reset.css Normal file
View file

0
media/css/web.css Normal file
View file

BIN
media/img/kohana.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -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();

View file

@ -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);

View file

@ -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]))