mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge branch '3.6' into 3
This commit is contained in:
commit
bbb250916e
@ -726,16 +726,17 @@ abstract class Object {
|
|||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function __call($method, $arguments) {
|
public function __call($method, $arguments) {
|
||||||
|
$class = get_class($this);
|
||||||
// If the method cache was cleared by an an Object::add_extension() / Object::remove_extension()
|
// If the method cache was cleared by an an Object::add_extension() / Object::remove_extension()
|
||||||
// call, then we should rebuild it.
|
// call, then we should rebuild it.
|
||||||
if(empty(self::$extra_methods[get_class($this)])) {
|
if(empty(self::$extra_methods[$class])) {
|
||||||
$this->defineMethods();
|
$this->defineMethods();
|
||||||
}
|
}
|
||||||
|
|
||||||
$method = strtolower($method);
|
$method = strtolower($method);
|
||||||
|
|
||||||
if(isset(self::$extra_methods[$this->class][$method])) {
|
if(isset(self::$extra_methods[$class][$method])) {
|
||||||
$config = self::$extra_methods[$this->class][$method];
|
$config = self::$extra_methods[$class][$method];
|
||||||
|
|
||||||
switch(true) {
|
switch(true) {
|
||||||
case isset($config['property']) :
|
case isset($config['property']) :
|
||||||
@ -752,11 +753,11 @@ abstract class Object {
|
|||||||
|
|
||||||
if($this->destroyed) {
|
if($this->destroyed) {
|
||||||
throw new Exception (
|
throw new Exception (
|
||||||
"Object->__call(): attempt to call $method on a destroyed $this->class object"
|
"Object->__call(): attempt to call $method on a destroyed $class object"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new Exception (
|
throw new Exception (
|
||||||
"Object->__call(): $this->class cannot pass control to $config[property]($config[index])."
|
"Object->__call(): $class cannot pass control to $config[property]($config[index])."
|
||||||
. ' Perhaps this object was mistakenly destroyed?'
|
. ' Perhaps this object was mistakenly destroyed?'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -770,13 +771,12 @@ abstract class Object {
|
|||||||
|
|
||||||
default :
|
default :
|
||||||
throw new Exception (
|
throw new Exception (
|
||||||
"Object->__call(): extra method $method is invalid on $this->class:"
|
"Object->__call(): extra method $method is invalid on $class:"
|
||||||
. var_export($config, true)
|
. var_export($config, true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Please do not change the exception code number below.
|
// Please do not change the exception code number below.
|
||||||
$class = get_class($this);
|
|
||||||
throw new Exception("Object->__call(): the method '$method' does not exist on '$class', or the method is not public.", 2175);
|
throw new Exception("Object->__call(): the method '$method' does not exist on '$class', or the method is not public.", 2175);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -793,7 +793,7 @@ abstract class Object {
|
|||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function hasMethod($method) {
|
public function hasMethod($method) {
|
||||||
return method_exists($this, $method) || isset(self::$extra_methods[$this->class][strtolower($method)]);
|
return method_exists($this, $method) || isset(self::$extra_methods[get_class($this)][strtolower($method)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -803,14 +803,15 @@ abstract class Object {
|
|||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function allMethodNames($custom = false) {
|
public function allMethodNames($custom = false) {
|
||||||
if(!isset(self::$built_in_methods[$this->class])) {
|
$class = get_class($this);
|
||||||
self::$built_in_methods[$this->class] = array_map('strtolower', get_class_methods($this));
|
if(!isset(self::$built_in_methods[$class])) {
|
||||||
|
self::$built_in_methods[$class] = array_map('strtolower', get_class_methods($this));
|
||||||
}
|
}
|
||||||
|
|
||||||
if($custom && isset(self::$extra_methods[$this->class])) {
|
if($custom && isset(self::$extra_methods[$class])) {
|
||||||
return array_merge(self::$built_in_methods[$this->class], array_keys(self::$extra_methods[$this->class]));
|
return array_merge(self::$built_in_methods[$class], array_keys(self::$extra_methods[$class]));
|
||||||
} else {
|
} else {
|
||||||
return self::$built_in_methods[$this->class];
|
return self::$built_in_methods[$class];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -826,11 +827,12 @@ abstract class Object {
|
|||||||
$this->addMethodsFrom('extension_instances', $key);
|
$this->addMethodsFrom('extension_instances', $key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($_REQUEST['debugmethods']) && isset(self::$built_in_methods[$this->class])) {
|
$class = get_class($this);
|
||||||
|
if(isset($_REQUEST['debugmethods']) && isset(self::$built_in_methods[$class])) {
|
||||||
Debug::require_developer_login();
|
Debug::require_developer_login();
|
||||||
|
|
||||||
echo '<h2>Methods defined on ' . $this->class . '</h2><ul>';
|
echo "<h2>Methods defined on $class</h2><ul>";
|
||||||
foreach(self::$built_in_methods[$this->class] as $method) {
|
foreach(self::$built_in_methods[$class] as $method) {
|
||||||
echo "<li>$method</li>";
|
echo "<li>$method</li>";
|
||||||
}
|
}
|
||||||
echo '</ul>';
|
echo '</ul>';
|
||||||
@ -863,11 +865,12 @@ abstract class Object {
|
|||||||
* @param string|int $index an index to use if the property is an array
|
* @param string|int $index an index to use if the property is an array
|
||||||
*/
|
*/
|
||||||
protected function addMethodsFrom($property, $index = null) {
|
protected function addMethodsFrom($property, $index = null) {
|
||||||
|
$class = get_class($this);
|
||||||
$extension = ($index !== null) ? $this->{$property}[$index] : $this->$property;
|
$extension = ($index !== null) ? $this->{$property}[$index] : $this->$property;
|
||||||
|
|
||||||
if(!$extension) {
|
if(!$extension) {
|
||||||
throw new InvalidArgumentException (
|
throw new InvalidArgumentException (
|
||||||
"Object->addMethodsFrom(): could not add methods from {$this->class}->{$property}[$index]"
|
"Object->addMethodsFrom(): could not add methods from {$class}->{$property}[$index]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -881,11 +884,11 @@ abstract class Object {
|
|||||||
|
|
||||||
$newMethods = array_fill_keys($methods, $methodInfo);
|
$newMethods = array_fill_keys($methods, $methodInfo);
|
||||||
|
|
||||||
if(isset(self::$extra_methods[$this->class])) {
|
if(isset(self::$extra_methods[$class])) {
|
||||||
self::$extra_methods[$this->class] =
|
self::$extra_methods[$class] =
|
||||||
array_merge(self::$extra_methods[$this->class], $newMethods);
|
array_merge(self::$extra_methods[$class], $newMethods);
|
||||||
} else {
|
} else {
|
||||||
self::$extra_methods[$this->class] = $newMethods;
|
self::$extra_methods[$class] = $newMethods;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -929,7 +932,7 @@ abstract class Object {
|
|||||||
* @param string $wrap the method name to wrap to
|
* @param string $wrap the method name to wrap to
|
||||||
*/
|
*/
|
||||||
protected function addWrapperMethod($method, $wrap) {
|
protected function addWrapperMethod($method, $wrap) {
|
||||||
self::$extra_methods[$this->class][strtolower($method)] = array (
|
self::$extra_methods[get_class($this)][strtolower($method)] = array (
|
||||||
'wrap' => $wrap,
|
'wrap' => $wrap,
|
||||||
'method' => $method
|
'method' => $method
|
||||||
);
|
);
|
||||||
@ -944,7 +947,7 @@ abstract class Object {
|
|||||||
* function
|
* function
|
||||||
*/
|
*/
|
||||||
protected function createMethod($method, $code) {
|
protected function createMethod($method, $code) {
|
||||||
self::$extra_methods[$this->class][strtolower($method)] = array (
|
self::$extra_methods[get_class($this)][strtolower($method)] = array (
|
||||||
'function' => create_function('$obj, $args', $code)
|
'function' => create_function('$obj, $args', $code)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ class PaginatedList extends SS_ListDecorator {
|
|||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* @param int $context The number of pages to display around the current
|
* @param int $context The number of pages to display around the current
|
||||||
* page. The number should be event, as half the number of each pages
|
* page. The number should be even, as half the number of each pages
|
||||||
* are displayed on either side of the current one.
|
* are displayed on either side of the current one.
|
||||||
* @return SS_List
|
* @return SS_List
|
||||||
*/
|
*/
|
||||||
|
@ -730,7 +730,7 @@ class Image extends File implements Flushable {
|
|||||||
call_user_func_array(array($this, "generateFormattedImage"), $args);
|
call_user_func_array(array($this, "generateFormattedImage"), $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
$cached = new Image_Cached($cacheFile, false, $this);
|
$cached = Injector::inst()->createWithArgs('Image_Cached', array($cacheFile, false, $this));
|
||||||
return $cached;
|
return $cached;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -869,10 +869,10 @@ class Requirements_Backend {
|
|||||||
|
|
||||||
// Forcefully put the scripts at the bottom of the body instead of before the first
|
// Forcefully put the scripts at the bottom of the body instead of before the first
|
||||||
// script tag.
|
// script tag.
|
||||||
$replacements["/(<\/body[^>]*>)/i"] = $jsRequirements . "\\1";
|
$replacements["/(<\/body[^>]*>)/i"] = $this->escapeReplacement($jsRequirements) . "\\1";
|
||||||
|
|
||||||
// Put CSS at the bottom of the head
|
// Put CSS at the bottom of the head
|
||||||
$replacements["/(<\/head>)/i"] = $requirements . "\\1";
|
$replacements["/(<\/head>)/i"] = $this->escapeReplacement($requirements) . "\\1";
|
||||||
} elseif ($this->write_js_to_body) {
|
} elseif ($this->write_js_to_body) {
|
||||||
$jsRequirements = $this->removeNewlinesFromCode($jsRequirements);
|
$jsRequirements = $this->removeNewlinesFromCode($jsRequirements);
|
||||||
|
|
||||||
@ -894,14 +894,14 @@ class Requirements_Backend {
|
|||||||
if ($canWriteToBody) {
|
if ($canWriteToBody) {
|
||||||
$content = substr($content, 0, $p1) . $jsRequirements . substr($content, $p1);
|
$content = substr($content, 0, $p1) . $jsRequirements . substr($content, $p1);
|
||||||
} else {
|
} else {
|
||||||
$replacements["/(<\/body[^>]*>)/i"] = $jsRequirements . "\\1";
|
$replacements["/(<\/body[^>]*>)/i"] = $this->escapeReplacement($jsRequirements) . "\\1";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put CSS at the bottom of the head
|
// Put CSS at the bottom of the head
|
||||||
$replacements["/(<\/head>)/i"] = $requirements . "\\1";
|
$replacements["/(<\/head>)/i"] = $this->escapeReplacement($requirements) . "\\1";
|
||||||
} else {
|
} else {
|
||||||
// Put CSS and Javascript together before the closing head tag
|
// Put CSS and Javascript together before the closing head tag
|
||||||
$replacements["/(<\/head>)/i"] = $requirements . $jsRequirements. "\\1";
|
$replacements["/(<\/head>)/i"] = $this->escapeReplacement($requirements . $jsRequirements) . "\\1";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($replacements)) {
|
if (!empty($replacements)) {
|
||||||
@ -923,6 +923,16 @@ class Requirements_Backend {
|
|||||||
return preg_replace('/>\n*/', '>', $code);
|
return preg_replace('/>\n*/', '>', $code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely escape a literal string for use in preg_replace replacement
|
||||||
|
*
|
||||||
|
* @param string $replacement
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function escapeReplacement($replacement) {
|
||||||
|
return addcslashes($replacement, '\\$');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach requirements inclusion to X-Include-JS and X-Include-CSS headers on the given
|
* Attach requirements inclusion to X-Include-JS and X-Include-CSS headers on the given
|
||||||
* HTTP Response
|
* HTTP Response
|
||||||
|
Loading…
Reference in New Issue
Block a user