Merging fixes and enhancements into trunk.

Revision: [2282]
Fixed caching of content when wrapped with the <cake:nocache> tags </cake:nocache>

Revision: [2281]
Fixing DBO compatibility in AclNode::_resolveID(), adding docblock and fixing code for stripslashes_deep(), and adding request detection helper methods to RequestHandler

Revision: [2280]
Added fix for empty pages being cached

Revision: [2279]
Fixed undefined index in CacheHelper::cache()

Revision: [2278]
Fixed bug in CacheHelper::__parseFile() regex pattern did not match properly

Revision: [2277]
Adding CacheHelper class.
Refactored View::_render() to use new CacheHelper.

git-svn-id: https://svn.cakephp.org/repo/trunk/cake@2283 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
phpnut 2006-03-13 03:48:39 +00:00
parent de46dc7fdc
commit f9197dc7a5
6 changed files with 333 additions and 62 deletions

View file

@ -6,4 +6,4 @@
// +---------------------------------------------------------------------------------------------------+ //
///////////////////////////////////////////////////////////////////////////////////////////////////////////
1.0.0.2276
1.0.0.2283

View file

@ -992,17 +992,21 @@ function clearCache($params = null, $type = 'views', $ext = '.php')
}
/**
* Enter description here...
* Recursively strips slashes from all values in an array
*
* @param unknown_type $value
* @return unknown
*/
function stripslashes_deep($value)
{
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
if (is_array($value))
{
return array_map('stripslashes_deep', $value);
}
else
{
return stripslashes($value);
}
}
/**

View file

@ -247,7 +247,7 @@ class AclNode extends AppModel
function _resolveID($id, $fKey)
{
$key = (is_string($id) ? 'alias' : $fKey);
$val = (is_string($id) ? '"' . addslashes($id) . '"' : $id);
$val = (is_string($id) ? '"' . $this->db->value($id) . '"' : $id);
return "{$key} = {$val}";
}

View file

@ -51,6 +51,35 @@ class RequestHandlerComponent extends Object
var $disableStartup = false;
var $__requestContent = array(
'js' => 'text/javascript',
'css' => 'text/css',
'html' => 'text/html',
'form' => 'application/x-www-form-urlencoded',
'file' => 'multipart/form-data',
'xhtml' => array('application/xhtml+xml', 'application/xhtml', 'text/xhtml'),
'xml' => array('application/xml', 'text/xml'),
'rss' => 'application/rss+xml',
'atom' => 'application/atom+xml'
);
var $__acceptTypes = array();
function __construct()
{
$this->__acceptTypes = explode(',', env('HTTP_ACCEPT'));
foreach ($this->__acceptTypes as $i => $type)
{
if (strpos($type, ';'))
{
$type = explode(';', $type);
$this->__acceptTypes[$i] = $type[0];
}
}
parent::__construct();
}
/**
* Startup
@ -102,6 +131,36 @@ class RequestHandlerComponent extends Object
}
}
/**
* Returns true if the current call accepts an XML response, false otherwise
*
* @return bool True if client accepts an XML response
*/
function isXml()
{
return $this->accepts('xml');
}
/**
* Returns true if the current call accepts an RSS response, false otherwise
*
* @return bool True if client accepts an RSS response
*/
function isRss()
{
return $this->accepts('rss');
}
/**
* Returns true if the current call accepts an RSS response, false otherwise
*
* @return bool True if client accepts an RSS response
*/
function isAtom()
{
return $this->accepts('atom');
}
/**
* Returns true if the current call a POST request
*
@ -132,6 +191,15 @@ class RequestHandlerComponent extends Object
return (low(env('REQUEST_METHOD')) == 'get');
}
/**
* Returns true if the current call a DELETE request
*
* @return bool True if call is a DELETE
*/
function isDelete()
{
return (low(env('REQUEST_METHOD')) == 'delete');
}
/**
* Gets Prototype version if call is Ajax, otherwise empty string.
@ -147,6 +215,18 @@ class RequestHandlerComponent extends Object
return false;
}
/**
* Adds/sets the Content-type(s) for the given name
*
* @param string $name The name of the Content-type, i.e. "html", "xml", "css"
* @param mixed $type The Content-type or array of Content-types assigned to the name
* @return void
*/
function setContent($name, $type)
{
$this->__requestContent[$name] = $type;
}
/**
* Gets the server name from which this request was referred
*
@ -209,7 +289,7 @@ class RequestHandlerComponent extends Object
*/
function isMobile()
{
return (preg_match('/'.REQUEST_MOBILE_UA.'/i', $_SERVER['HTTP_USER_AGENT']) > 0);
return (preg_match('/'.REQUEST_MOBILE_UA.'/i', env('HTTP_USER_AGENT')) > 0);
}
/**
@ -277,6 +357,77 @@ class RequestHandlerComponent extends Object
}
return $str;
}
/**
* Determines which content types the client accepts
*
* @param mixed $type Can be null (or no parameter), a string type name, or an
* array of types
* @returns mixed If null or no parameter is passed, returns an array of content
* types the client accepts. If a string is passed, returns true
* if the client accepts it. If an array is passed, returns true
* if the client accepts one or more elements in the array.
* @access public
*/
function accepts($type = null)
{
if ($type == null)
{
return $this->__acceptTypes;
}
else if (is_array($type))
{
foreach($type as $t)
{
if ($this->accepts($t) == true)
{
return true;
}
}
return false;
}
else if (is_string($type))
{
if (!in_array($type, array_keys($this->__requestContent)))
{
return false;
}
$content = $this->__requestContent[$type];
if (is_array($content))
{
foreach($content as $c)
{
if (in_array($c, $this->__acceptTypes))
{
return true;
}
}
}
else
{
if (in_array($content, $this->__acceptTypes))
{
return true;
}
}
}
}
/**
* Determines which content types the client prefers
*
* @param mixed $type
* @returns mixed
* @access public
*/
function prefers($type = null)
{
if ($type == null)
{
return $this->accepts(null);
}
}
}
?>

View file

@ -0,0 +1,158 @@
<?php
/* SVN FILE: $Id$ */
/**
* Short description for file.
*
* Long description for file
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright (c) 2006, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.cake.libs.view.helpers
* @since CakePHP v 1.0.0.2277
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Short description for file.
*
* Long description for file
*
* @package cake
* @subpackage cake.cake.libs.view.helpers
* @since CakePHP v 1.0.0.2277
*
*/
class CacheHelper extends Helper
{
var $replace = array();
var $match = array();
function cache($file, $out, $cache = false)
{
if(is_array($this->cacheAction))
{
$check = str_replace('/', '_', $this->here);
$replace = str_replace('/', '_', $this->base);
$check = str_replace($replace, '', $check);
$check = str_replace('_'.$this->controllerName.'_', '', $check);
$pos = strpos($check, '_');
$pos1 = strrpos($check, '_');
if($pos1 > 0)
{
$check = substr($check, 0, $pos1);
}
if ($pos !== false)
{
$check = substr($check, 1);
}
$keys = str_replace('/', '_', array_keys($this->cacheAction));
$key = preg_grep("/^$check/", array_values($keys));
if(isset($key['0']))
{
$key = str_replace('_', '/', $key['0']);
}
else
{
$key = 'index';
}
if(isset($this->cacheAction[$key]))
{
$cacheTime = $this->cacheAction[$key];
}
else
{
$cacheTime = 0;
}
}
else
{
$cacheTime = $this->cacheAction;
}
if($cacheTime != '' && $cacheTime > 0)
{
$this->__parseFile($file, $out);
if($cache === true)
{
$cached = $this->__parseOutput($out);
$this->__writeFile($cached, $cacheTime);
}
return $out;
}
else
{
return $out;
}
}
function __parseFile($file, $cache)
{
$file = file_get_contents($file);
preg_match_all('/(?P<found><cake:nocache>(?:.*|(?:[\\S\\s]*[^\\S]))<\/cake:nocache>)/i', $cache, $oresult, PREG_PATTERN_ORDER);
preg_match_all('/<cake:nocache>(?P<replace>(?:.*|(?:[\\S\\s]*[^\\S])))<\/cake:nocache>/i', $file, $result, PREG_PATTERN_ORDER);
if(!empty($result['replace']))
{
$count = 0;
foreach($result['replace'] as $result)
{
$this->replace[] = $result;
$this->match[] = $oresult['found'][$count];
$count++;
}
}
}
function __parseOutput($cache)
{
$count = 0;
if(!empty($this->match))
{
foreach($this->match as $found)
{
$cache = str_replace($found, $this->replace[$count], $cache);
$count++;
}
return $cache;
}
return $cache;
}
function __writeFile($file, $timestamp)
{
$now = time();
if (is_numeric($timestamp))
{
$cacheTime = $now + $timestamp;
}
else
{
$cacheTime = $now + strtotime($timestamp);
}
$result = preg_replace('/\/\//', '/', $this->here);
$cache = str_replace('/', '_', $result.'.php');
$cache = str_replace('favicon.ico', '', $cache);
$file = '<!--cachetime:'.$cacheTime.'-->'.$file;
return cache('views'.DS.$cache, $file, $timestamp);
}
}
?>

View file

@ -458,7 +458,7 @@ class View extends Object
if(substr($layout_fn, -5) === 'thtml')
{
$out = View::_render($layout_fn, $data_for_layout, false);
$out = View::_render($layout_fn, $data_for_layout, false, true);
}
else
{
@ -618,7 +618,7 @@ class View extends Object
* @return string Rendered output
* @access private
*/
function _render($___viewFn, $___dataForView, $loadHelpers = true)
function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false)
{
if ($this->helpers != false && $loadHelpers === true)
{
@ -657,48 +657,24 @@ class View extends Object
{
@include($___viewFn);
}
$out = ob_get_clean();
$out = ob_get_clean();
if($this->controller->cacheAction != false && (defined('CACHE_CHECK') && CACHE_CHECK === true))
{
if(is_array($this->controller->cacheAction))
if (is_a($this->loaded['cache'], 'CacheHelper'))
{
$check = str_replace('/', '_', $this->params['url']['url']);
$check = str_replace('_'.$this->params['controller'].'_', '', $check);
$check = substr_replace($check, '', -1);
$keys = str_replace('/', '_', array_keys($this->controller->cacheAction));
$key = preg_grep("/^$check/", array_values($keys));
$key = str_replace('_', '/', $key['0']);
if(isset($this->controller->cacheAction[$key]))
{
$cacheTime = $this->controller->cacheAction[$key];
}
else
{
$cacheTime = 0;
}
}
else
{
$cacheTime = $this->controller->cacheAction;
}
if($cacheTime != '' && $cacheTime > 0)
{
return $this->cacheView($out, $cacheTime);
}
else
{
return $out;
$cache =& $this->loaded['cache'];
$cache->base = $this->base;
$cache->here = $this->here;
$cache->controllerName = $this->params['controller'];
$cache->cacheAction = $this->controller->cacheAction;
$cache->cache($___viewFn, $out, $cached);
}
}
else
{
return $out;
}
return $out;
}
/**
* Loads helpers, with their dependencies.
*
@ -807,23 +783,5 @@ class View extends Object
'file' => $viewFileName)));
}
}
function cacheView($view, $timestamp)
{
$now = time();
if (is_numeric($timestamp))
{
$cacheTime = $now + $timestamp;
}
else
{
$cacheTime = $now + strtotime($timestamp);
}
$result = preg_replace('/\/\//', '/', $this->here);
$cache = str_replace('/', '_', $result.'.php');
$cache = str_replace('favicon.ico', '', $cache);
$view = '<!--cachetime:'.$cacheTime.'-->'.$view;
return cache('views'.DS.$cache, $view, $timestamp);
}
}
?>