mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge branch '3.1'
This commit is contained in:
commit
bfdf14fafa
@ -127,7 +127,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only resume a session if its not started already, and a session identifier exists
|
// Only resume a session if its not started already, and a session identifier exists
|
||||||
if(!isset($_SESSION) && (isset($_COOKIE[session_name()]) || isset($_REQUEST[session_name()]))) {
|
if(!isset($_SESSION) && Session::request_contains_session_id()) {
|
||||||
Session::start();
|
Session::start();
|
||||||
}
|
}
|
||||||
// Initiate an empty session - doesn't initialize an actual PHP session until saved (see belwo)
|
// Initiate an empty session - doesn't initialize an actual PHP session until saved (see belwo)
|
||||||
@ -714,6 +714,26 @@ class Director implements TemplateGlobalProvider {
|
|||||||
return Director::protocol() . $login . $_SERVER['HTTP_HOST'] . Director::baseURL();
|
return Director::protocol() . $login . $_SERVER['HTTP_HOST'] . Director::baseURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip any further processing and immediately respond with a redirect to the passed URL.
|
||||||
|
*
|
||||||
|
* @param string $destURL - The URL to redirect to
|
||||||
|
*/
|
||||||
|
protected static function force_redirect($destURL) {
|
||||||
|
$response = new SS_HTTPResponse(
|
||||||
|
"<h1>Your browser is not accepting header redirects</h1>".
|
||||||
|
"<p>Please <a href=\"$destURL\">click here</a>",
|
||||||
|
301
|
||||||
|
);
|
||||||
|
|
||||||
|
HTTP::add_cache_headers($response);
|
||||||
|
$response->addHeader('Location', $destURL);
|
||||||
|
|
||||||
|
// TODO: Use an exception - ATM we can be called from _config.php, before Director#handleRequest's try block
|
||||||
|
$response->output();
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Force the site to run on SSL.
|
* Force the site to run on SSL.
|
||||||
*
|
*
|
||||||
@ -782,10 +802,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
if(class_exists('SapphireTest', false) && SapphireTest::is_running_test()) {
|
if(class_exists('SapphireTest', false) && SapphireTest::is_running_test()) {
|
||||||
return $destURL;
|
return $destURL;
|
||||||
} else {
|
} else {
|
||||||
if(!headers_sent()) header("Location: $destURL");
|
self::force_redirect($destURL);
|
||||||
|
|
||||||
die("<h1>Your browser is not accepting header redirects</h1>"
|
|
||||||
. "<p>Please <a href=\"$destURL\">click here</a>");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -800,9 +817,7 @@ class Director implements TemplateGlobalProvider {
|
|||||||
$destURL = str_replace(Director::protocol(), Director::protocol() . 'www.',
|
$destURL = str_replace(Director::protocol(), Director::protocol() . 'www.',
|
||||||
Director::absoluteURL($_SERVER['REQUEST_URI']));
|
Director::absoluteURL($_SERVER['REQUEST_URI']));
|
||||||
|
|
||||||
header("Location: $destURL", true, 301);
|
self::force_redirect($destURL);
|
||||||
die("<h1>Your browser is not accepting header redirects</h1>"
|
|
||||||
. "<p>Please <a href=\"$destURL\">click here</a>");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,8 +341,8 @@ class HTTP {
|
|||||||
// To do: User-Agent should only be added in situations where you *are* actually
|
// To do: User-Agent should only be added in situations where you *are* actually
|
||||||
// varying according to user-agent.
|
// varying according to user-agent.
|
||||||
$responseHeaders['Vary'] = 'Cookie, X-Forwarded-Protocol, User-Agent, Accept';
|
$responseHeaders['Vary'] = 'Cookie, X-Forwarded-Protocol, User-Agent, Accept';
|
||||||
|
}
|
||||||
} else {
|
else {
|
||||||
$responseHeaders["Cache-Control"] = "no-cache, max-age=0, must-revalidate, no-transform";
|
$responseHeaders["Cache-Control"] = "no-cache, max-age=0, must-revalidate, no-transform";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +128,14 @@ class Session {
|
|||||||
|
|
||||||
protected $changedData = array();
|
protected $changedData = array();
|
||||||
|
|
||||||
|
protected function userAgent() {
|
||||||
|
if (isset($_SERVER['HTTP_USER_AGENT'])) {
|
||||||
|
return $_SERVER['HTTP_USER_AGENT'];
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start PHP session, then create a new Session object with the given start data.
|
* Start PHP session, then create a new Session object with the given start data.
|
||||||
*
|
*
|
||||||
@ -138,14 +146,8 @@ class Session {
|
|||||||
|
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
|
|
||||||
if (isset($_SERVER['HTTP_USER_AGENT'])) {
|
|
||||||
$ua = $_SERVER['HTTP_USER_AGENT'];
|
|
||||||
} else {
|
|
||||||
$ua = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($this->data['HTTP_USER_AGENT'])) {
|
if (isset($this->data['HTTP_USER_AGENT'])) {
|
||||||
if ($this->data['HTTP_USER_AGENT'] != $ua) {
|
if ($this->data['HTTP_USER_AGENT'] != $this->userAgent()) {
|
||||||
// Funny business detected!
|
// Funny business detected!
|
||||||
$this->inst_clearAll();
|
$this->inst_clearAll();
|
||||||
|
|
||||||
@ -153,8 +155,6 @@ class Session {
|
|||||||
Session::start();
|
Session::start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->inst_set('HTTP_USER_AGENT', $ua);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -461,12 +461,17 @@ class Session {
|
|||||||
return $this->data;
|
return $this->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function inst_finalize() {
|
||||||
|
$this->inst_set('HTTP_USER_AGENT', $this->userAgent());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save data to session
|
* Save data to session
|
||||||
* Only save the changes, so that anyone manipulating $_SESSION directly doesn't get burned.
|
* Only save the changes, so that anyone manipulating $_SESSION directly doesn't get burned.
|
||||||
*/
|
*/
|
||||||
public function inst_save() {
|
public function inst_save() {
|
||||||
if($this->changedData) {
|
if($this->changedData) {
|
||||||
|
$this->inst_finalize();
|
||||||
if(!isset($_SESSION)) Session::start();
|
if(!isset($_SESSION)) Session::start();
|
||||||
$this->recursivelyApply($this->changedData, $_SESSION);
|
$this->recursivelyApply($this->changedData, $_SESSION);
|
||||||
}
|
}
|
||||||
@ -508,6 +513,16 @@ class Session {
|
|||||||
Session::set("FormInfo.$formname.formError.type", $type);
|
Session::set("FormInfo.$formname.formError.type", $type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is there a session ID in the request?
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function request_contains_session_id() {
|
||||||
|
$secure = Director::is_https() && Config::inst()->get('Session', 'cookie_secure');
|
||||||
|
$name = $secure ? 'SECSESSID' : session_name();
|
||||||
|
return isset($_COOKIE[$name]) || isset($_REQUEST[$name]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize session.
|
* Initialize session.
|
||||||
*
|
*
|
||||||
@ -517,7 +532,7 @@ class Session {
|
|||||||
$path = Config::inst()->get('Session', 'cookie_path');
|
$path = Config::inst()->get('Session', 'cookie_path');
|
||||||
if(!$path) $path = Director::baseURL();
|
if(!$path) $path = Director::baseURL();
|
||||||
$domain = Config::inst()->get('Session', 'cookie_domain');
|
$domain = Config::inst()->get('Session', 'cookie_domain');
|
||||||
$secure = Config::inst()->get('Session', 'cookie_secure');
|
$secure = Director::is_https() && Config::inst()->get('Session', 'cookie_secure');
|
||||||
$session_path = Config::inst()->get('Session', 'session_store_path');
|
$session_path = Config::inst()->get('Session', 'session_store_path');
|
||||||
$timeout = Config::inst()->get('Session', 'timeout');
|
$timeout = Config::inst()->get('Session', 'timeout');
|
||||||
|
|
||||||
@ -533,11 +548,14 @@ class Session {
|
|||||||
// Allow storing the session in a non standard location
|
// Allow storing the session in a non standard location
|
||||||
if($session_path) session_save_path($session_path);
|
if($session_path) session_save_path($session_path);
|
||||||
|
|
||||||
|
// If we want a secure cookie for HTTPS, use a seperate session name. This lets us have a
|
||||||
|
// seperate (less secure) session for non-HTTPS requests
|
||||||
|
if($secure) session_name('SECSESSID');
|
||||||
|
|
||||||
// @ is to supress win32 warnings/notices when session wasn't cleaned up properly
|
// @ is to supress win32 warnings/notices when session wasn't cleaned up properly
|
||||||
// There's nothing we can do about this, because it's an operating system function!
|
// There's nothing we can do about this, because it's an operating system function!
|
||||||
if($sid) session_id($sid);
|
if($sid) session_id($sid);
|
||||||
@session_start();
|
@session_start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modify the timeout behaviour so it's the *inactive* time before the session expires.
|
// Modify the timeout behaviour so it's the *inactive* time before the session expires.
|
||||||
|
@ -273,6 +273,15 @@ class SS_ClassManifest {
|
|||||||
return $modules;
|
return $modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to set up files that we want to exclude from parsing for performance reasons.
|
||||||
|
*/
|
||||||
|
protected function setDefaults()
|
||||||
|
{
|
||||||
|
$this->classes['sstemplateparser'] = FRAMEWORK_PATH.'/view/SSTemplateParser.php';
|
||||||
|
$this->classes['sstemplateparseexception'] = FRAMEWORK_PATH.'/view/SSTemplateParser.php';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Completely regenerates the manifest file.
|
* Completely regenerates the manifest file.
|
||||||
*
|
*
|
||||||
@ -289,10 +298,12 @@ class SS_ClassManifest {
|
|||||||
$this->$reset = array();
|
$this->$reset = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->setDefaults();
|
||||||
|
|
||||||
$finder = new ManifestFileFinder();
|
$finder = new ManifestFileFinder();
|
||||||
$finder->setOptions(array(
|
$finder->setOptions(array(
|
||||||
'name_regex' => '/^(_config.php|[^_].*\.php)$/',
|
'name_regex' => '/^(_config.php|[^_].*\.php)$/',
|
||||||
'ignore_files' => array('index.php', 'main.php', 'cli-script.php'),
|
'ignore_files' => array('index.php', 'main.php', 'cli-script.php', 'SSTemplateParser.php'),
|
||||||
'ignore_tests' => !$this->tests,
|
'ignore_tests' => !$this->tests,
|
||||||
'file_callback' => array($this, 'handleFile'),
|
'file_callback' => array($this, 'handleFile'),
|
||||||
'dir_callback' => array($this, 'handleDir')
|
'dir_callback' => array($this, 'handleDir')
|
||||||
|
@ -291,7 +291,7 @@ class SS_ConfigManifest {
|
|||||||
// For each, parse out into module/file#name, and set any missing to "*"
|
// For each, parse out into module/file#name, and set any missing to "*"
|
||||||
$header[$order] = array();
|
$header[$order] = array();
|
||||||
foreach($orderparts as $part) {
|
foreach($orderparts as $part) {
|
||||||
preg_match('! (?P<module>\*|\w+)? (\/ (?P<file>\*|\w+))? (\# (?P<fragment>\*|\w+))? !x',
|
preg_match('! (?P<module>\*|[^\/#]+)? (\/ (?P<file>\*|\w+))? (\# (?P<fragment>\*|\w+))? !x',
|
||||||
$part, $match);
|
$part, $match);
|
||||||
|
|
||||||
$header[$order][] = array(
|
$header[$order][] = array(
|
||||||
|
@ -100,7 +100,7 @@ class SS_ConfigStaticManifest {
|
|||||||
$finder = new ManifestFileFinder();
|
$finder = new ManifestFileFinder();
|
||||||
$finder->setOptions(array(
|
$finder->setOptions(array(
|
||||||
'name_regex' => '/^([^_].*\.php)$/',
|
'name_regex' => '/^([^_].*\.php)$/',
|
||||||
'ignore_files' => array('index.php', 'main.php', 'cli-script.php'),
|
'ignore_files' => array('index.php', 'main.php', 'cli-script.php', 'SSTemplateParser.php'),
|
||||||
'ignore_tests' => !$this->tests,
|
'ignore_tests' => !$this->tests,
|
||||||
'file_callback' => array($this, 'handleFile')
|
'file_callback' => array($this, 'handleFile')
|
||||||
));
|
));
|
||||||
|
@ -349,6 +349,7 @@ class Email extends ViewableData {
|
|||||||
* and it won't be plain email :)
|
* and it won't be plain email :)
|
||||||
*/
|
*/
|
||||||
protected function parseVariables($isPlain = false) {
|
protected function parseVariables($isPlain = false) {
|
||||||
|
$origState = Config::inst()->get('SSViewer', 'source_file_comments');
|
||||||
Config::inst()->update('SSViewer', 'source_file_comments', false);
|
Config::inst()->update('SSViewer', 'source_file_comments', false);
|
||||||
|
|
||||||
if(!$this->parseVariables_done) {
|
if(!$this->parseVariables_done) {
|
||||||
@ -373,6 +374,7 @@ class Email extends ViewableData {
|
|||||||
// Rewrite relative URLs
|
// Rewrite relative URLs
|
||||||
$this->body = HTTP::absoluteURLs($fullBody);
|
$this->body = HTTP::absoluteURLs($fullBody);
|
||||||
}
|
}
|
||||||
|
Config::inst()->update('SSViewer', 'source_file_comments', $origState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,12 +77,40 @@ class TimeField extends TextField {
|
|||||||
return 'time text';
|
return 'time text';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a time into a Zend_Date object
|
||||||
|
*
|
||||||
|
* @param string $value Raw value
|
||||||
|
* @param string $format Format string to check against
|
||||||
|
* @param string $locale Optional locale to parse against
|
||||||
|
* @param boolean $exactMatch Flag indicating that the date must be in this
|
||||||
|
* exact format, and is unchanged after being parsed and written out
|
||||||
|
*
|
||||||
|
* @return Zend_Date Returns the Zend_Date, or null if not in the specified format
|
||||||
|
*/
|
||||||
|
protected function parseTime($value, $format, $locale = null, $exactMatch = false) {
|
||||||
|
// Check if the date is in the correct format
|
||||||
|
if(!Zend_Date::isDate($value, $format)) return null;
|
||||||
|
|
||||||
|
// Parse the value
|
||||||
|
$valueObject = new Zend_Date($value, $format, $locale);
|
||||||
|
|
||||||
|
// For exact matches, ensure the value preserves formatting after conversion
|
||||||
|
if($exactMatch && ($value !== $valueObject->get($format))) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return $valueObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the internal value to ISO date format.
|
* Sets the internal value to ISO date format.
|
||||||
*
|
*
|
||||||
* @param String|Array $val
|
* @param String|Array $val
|
||||||
*/
|
*/
|
||||||
public function setValue($val) {
|
public function setValue($val) {
|
||||||
|
|
||||||
// Fuzzy matching through strtotime() to support a wider range of times,
|
// Fuzzy matching through strtotime() to support a wider range of times,
|
||||||
// e.g. 11am. This means that validate() might not fire.
|
// e.g. 11am. This means that validate() might not fire.
|
||||||
// Note: Time formats are assumed to be less ambiguous than dates across locales.
|
// Note: Time formats are assumed to be less ambiguous than dates across locales.
|
||||||
@ -99,13 +127,12 @@ class TimeField extends TextField {
|
|||||||
$this->valueObj = null;
|
$this->valueObj = null;
|
||||||
}
|
}
|
||||||
// load ISO time from database (usually through Form->loadDataForm())
|
// load ISO time from database (usually through Form->loadDataForm())
|
||||||
else if(Zend_Date::isDate($val, $this->getConfig('datavalueformat'))) {
|
// Requires exact format to prevent false positives from locale specific times
|
||||||
$this->valueObj = new Zend_Date($val, $this->getConfig('datavalueformat'));
|
else if($this->valueObj = $this->parseTime($val, $this->getConfig('datavalueformat'), null, true)) {
|
||||||
$this->value = $this->valueObj->get($this->getConfig('timeformat'));
|
$this->value = $this->valueObj->get($this->getConfig('timeformat'));
|
||||||
}
|
}
|
||||||
// Set in current locale (as string)
|
// Set in current locale (as string)
|
||||||
else if(Zend_Date::isDate($val, $this->getConfig('timeformat'), $this->locale)) {
|
else if($this->valueObj = $this->parseTime($val, $this->getConfig('timeformat'), $this->locale)) {
|
||||||
$this->valueObj = new Zend_Date($val, $this->getConfig('timeformat'), $this->locale);
|
|
||||||
$this->value = $this->valueObj->get($this->getConfig('timeformat'));
|
$this->value = $this->valueObj->get($this->getConfig('timeformat'));
|
||||||
}
|
}
|
||||||
// Fallback: Set incorrect value so validate() can pick it up
|
// Fallback: Set incorrect value so validate() can pick it up
|
||||||
|
@ -383,6 +383,7 @@
|
|||||||
$( 'div.ss-upload:not(.disabled):not(.readonly) .ss-uploadfield-item-edit').entwine({
|
$( 'div.ss-upload:not(.disabled):not(.readonly) .ss-uploadfield-item-edit').entwine({
|
||||||
onclick: function(e) {
|
onclick: function(e) {
|
||||||
var editform = this.closest('.ss-uploadfield-item').find('.ss-uploadfield-item-editform');
|
var editform = this.closest('.ss-uploadfield-item').find('.ss-uploadfield-item-editform');
|
||||||
|
var itemInfo = editform.prev('.ss-uploadfield-item-info');
|
||||||
var disabled;
|
var disabled;
|
||||||
var iframe = editform.find('iframe');
|
var iframe = editform.find('iframe');
|
||||||
|
|
||||||
@ -406,8 +407,15 @@
|
|||||||
disabled=this.find('ss-uploadfield-item-edit').siblings();
|
disabled=this.find('ss-uploadfield-item-edit').siblings();
|
||||||
}
|
}
|
||||||
editform.parent('.ss-uploadfield-item').removeClass('ui-state-warning');
|
editform.parent('.ss-uploadfield-item').removeClass('ui-state-warning');
|
||||||
disabled.toggleClass('ui-state-disabled');
|
|
||||||
editform.toggleEditForm();
|
editform.toggleEditForm();
|
||||||
|
|
||||||
|
if (itemInfo.find('.toggle-details-icon').hasClass('opened')) {
|
||||||
|
disabled.addClass('ui-state-disabled');
|
||||||
|
disabled.attr('disabled', 'disabled');
|
||||||
|
} else {
|
||||||
|
disabled.removeClass('ui-state-disabled');
|
||||||
|
disabled.removeAttr('disabled');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
e.preventDefault(); // Avoid a form submit
|
e.preventDefault(); // Avoid a form submit
|
||||||
return false;
|
return false;
|
||||||
|
@ -99,6 +99,7 @@ class SessionTest extends SapphireTest {
|
|||||||
// Generate our session
|
// Generate our session
|
||||||
$s = new Session(array());
|
$s = new Session(array());
|
||||||
$s->inst_set('val', 123);
|
$s->inst_set('val', 123);
|
||||||
|
$s->inst_finalize();
|
||||||
|
|
||||||
// Change our UA
|
// Change our UA
|
||||||
$_SERVER['HTTP_USER_AGENT'] = 'Fake Agent';
|
$_SERVER['HTTP_USER_AGENT'] = 'Fake Agent';
|
||||||
|
@ -36,17 +36,20 @@ class ClassManifestTest extends SapphireTest {
|
|||||||
|
|
||||||
public function testGetClasses() {
|
public function testGetClasses() {
|
||||||
$expect = array(
|
$expect = array(
|
||||||
'classa' => "{$this->base}/module/classes/ClassA.php",
|
'classb' => "{$this->base}/module/classes/ClassB.php",
|
||||||
'classb' => "{$this->base}/module/classes/ClassB.php",
|
'classa' => "{$this->base}/module/classes/ClassA.php",
|
||||||
'classc' => "{$this->base}/module/classes/ClassC.php",
|
'classb' => "{$this->base}/module/classes/ClassB.php",
|
||||||
'classd' => "{$this->base}/module/classes/ClassD.php"
|
'classc' => "{$this->base}/module/classes/ClassC.php",
|
||||||
|
'classd' => "{$this->base}/module/classes/ClassD.php",
|
||||||
|
'sstemplateparser' => FRAMEWORK_PATH."/view/SSTemplateParser.php",
|
||||||
|
'sstemplateparseexception' => FRAMEWORK_PATH."/view/SSTemplateParser.php"
|
||||||
);
|
);
|
||||||
$this->assertEquals($expect, $this->manifest->getClasses());
|
$this->assertEquals($expect, $this->manifest->getClasses());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetClassNames() {
|
public function testGetClassNames() {
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array('classa', 'classb', 'classc', 'classd'),
|
array('sstemplateparser', 'sstemplateparseexception', 'classa', 'classb', 'classc', 'classd'),
|
||||||
$this->manifest->getClassNames());
|
$this->manifest->getClassNames());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,164 @@ class ConfigManifestTest extends SapphireTest {
|
|||||||
return $manifest->get('ConfigManifestTest', $name);
|
return $manifest->get('ConfigManifestTest', $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a helper method for displaying a relevant message about a parsing failure
|
||||||
|
*/
|
||||||
|
protected function getParsedAsMessage($path) {
|
||||||
|
return sprintf('Reference path "%s" failed to parse correctly', $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test checks the processing of before and after reference paths (module-name/filename#fragment)
|
||||||
|
* This method uses fixture/configmanifest/mysite/_config/addyamlconfigfile.yml as a fixture
|
||||||
|
*/
|
||||||
|
public function testAddYAMLConfigFileReferencePathParsing() {
|
||||||
|
// Use a mock to avoid testing unrelated functionality
|
||||||
|
$manifest = $this->getMockBuilder('SS_ConfigManifest')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->setMethods(array('addModule'))
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
// This tests that the addModule method is called with the correct value
|
||||||
|
$manifest->expects($this->once())
|
||||||
|
->method('addModule')
|
||||||
|
->with($this->equalTo(dirname(__FILE__).'/fixtures/configmanifest/mysite'));
|
||||||
|
|
||||||
|
// Call the method to be tested
|
||||||
|
$manifest->addYAMLConfigFile(
|
||||||
|
'addyamlconfigfile.yml',
|
||||||
|
dirname(__FILE__).'/fixtures/configmanifest/mysite/_config/addyamlconfigfile.yml',
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
// There is no getter for yamlConfigFragments
|
||||||
|
$property = new ReflectionProperty('SS_ConfigManifest', 'yamlConfigFragments');
|
||||||
|
$property->setAccessible(true);
|
||||||
|
|
||||||
|
// Get the result back from the parsing
|
||||||
|
$result = $property->getValue($manifest);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'module' => 'mysite',
|
||||||
|
'file' => 'testfile',
|
||||||
|
'name' => 'fragment',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
@$result[0]['after'],
|
||||||
|
$this->getParsedAsMessage('mysite/testfile#fragment')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'module' => 'test-module',
|
||||||
|
'file' => 'testfile',
|
||||||
|
'name' => 'fragment',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
@$result[1]['after'],
|
||||||
|
$this->getParsedAsMessage('test-module/testfile#fragment')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'module' => '*',
|
||||||
|
'file' => '*',
|
||||||
|
'name' => '*',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
@$result[2]['after'],
|
||||||
|
$this->getParsedAsMessage('*')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'module' => '*',
|
||||||
|
'file' => 'testfile',
|
||||||
|
'name' => '*'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
@$result[3]['after'],
|
||||||
|
$this->getParsedAsMessage('*/testfile')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'module' => '*',
|
||||||
|
'file' => '*',
|
||||||
|
'name' => 'fragment'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
@$result[4]['after'],
|
||||||
|
$this->getParsedAsMessage('*/*#fragment')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'module' => '*',
|
||||||
|
'file' => '*',
|
||||||
|
'name' => 'fragment'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
@$result[5]['after'],
|
||||||
|
$this->getParsedAsMessage('#fragment')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'module' => 'test-module',
|
||||||
|
'file' => '*',
|
||||||
|
'name' => 'fragment'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
@$result[6]['after'],
|
||||||
|
$this->getParsedAsMessage('test-module#fragment')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'module' => 'test-module',
|
||||||
|
'file' => '*',
|
||||||
|
'name' => '*'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
@$result[7]['after'],
|
||||||
|
$this->getParsedAsMessage('test-module')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'module' => 'test-module',
|
||||||
|
'file' => '*',
|
||||||
|
'name' => '*'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
@$result[8]['after'],
|
||||||
|
$this->getParsedAsMessage('test-module/*')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'module' => 'test-module',
|
||||||
|
'file' => '*',
|
||||||
|
'name' => '*'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
@$result[9]['after'],
|
||||||
|
$this->getParsedAsMessage('test-module/*/#*')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testClassRules() {
|
public function testClassRules() {
|
||||||
$config = $this->getConfigFixtureValue('Class');
|
$config = $this->getConfigFixtureValue('Class');
|
||||||
|
|
||||||
|
@ -41,7 +41,9 @@ class NamespacedClassManifestTest extends SapphireTest {
|
|||||||
'silverstripe\test\classe' => "{$this->base}/module/classes/ClassE.php",
|
'silverstripe\test\classe' => "{$this->base}/module/classes/ClassE.php",
|
||||||
'silverstripe\test\classf' => "{$this->base}/module/classes/ClassF.php",
|
'silverstripe\test\classf' => "{$this->base}/module/classes/ClassF.php",
|
||||||
'silverstripe\test\classg' => "{$this->base}/module/classes/ClassG.php",
|
'silverstripe\test\classg' => "{$this->base}/module/classes/ClassG.php",
|
||||||
'silverstripe\test\classh' => "{$this->base}/module/classes/ClassH.php"
|
'silverstripe\test\classh' => "{$this->base}/module/classes/ClassH.php",
|
||||||
|
'sstemplateparser' => FRAMEWORK_PATH."/view/SSTemplateParser.php",
|
||||||
|
'sstemplateparseexception' => FRAMEWORK_PATH."/view/SSTemplateParser.php"
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals($expect, $this->manifest->getClasses());
|
$this->assertEquals($expect, $this->manifest->getClasses());
|
||||||
@ -49,9 +51,10 @@ class NamespacedClassManifestTest extends SapphireTest {
|
|||||||
|
|
||||||
public function testGetClassNames() {
|
public function testGetClassNames() {
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array('silverstripe\test\classa', 'silverstripe\test\classb', 'silverstripe\test\classc',
|
array('sstemplateparser', 'sstemplateparseexception', 'silverstripe\test\classa',
|
||||||
'silverstripe\test\classd', 'silverstripe\test\classe', 'silverstripe\test\classf',
|
'silverstripe\test\classb', 'silverstripe\test\classc', 'silverstripe\test\classd',
|
||||||
'silverstripe\test\classg', 'silverstripe\test\classh'),
|
'silverstripe\test\classe', 'silverstripe\test\classf', 'silverstripe\test\classg',
|
||||||
|
'silverstripe\test\classh'),
|
||||||
$this->manifest->getClassNames());
|
$this->manifest->getClassNames());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
After: 'mysite/testfile#fragment'
|
||||||
|
---
|
||||||
|
ClassManifestTest:
|
||||||
|
testParam: false
|
||||||
|
|
||||||
|
---
|
||||||
|
After: 'test-module/testfile#fragment'
|
||||||
|
---
|
||||||
|
ClassManifestTest:
|
||||||
|
testParam: false
|
||||||
|
|
||||||
|
---
|
||||||
|
After: '*'
|
||||||
|
---
|
||||||
|
ClassManifestTest:
|
||||||
|
testParam: false
|
||||||
|
|
||||||
|
---
|
||||||
|
After: '*/testfile'
|
||||||
|
---
|
||||||
|
ClassManifestTest:
|
||||||
|
testParam: false
|
||||||
|
|
||||||
|
---
|
||||||
|
After: '*/*#fragment'
|
||||||
|
---
|
||||||
|
ClassManifestTest:
|
||||||
|
testParam: false
|
||||||
|
|
||||||
|
---
|
||||||
|
After: '#fragment'
|
||||||
|
---
|
||||||
|
ClassManifestTest:
|
||||||
|
testParam: false
|
||||||
|
|
||||||
|
---
|
||||||
|
After: 'test-module#fragment'
|
||||||
|
---
|
||||||
|
ClassManifestTest:
|
||||||
|
testParam: false
|
||||||
|
|
||||||
|
---
|
||||||
|
After: 'test-module'
|
||||||
|
---
|
||||||
|
ClassManifestTest:
|
||||||
|
testParam: false
|
||||||
|
|
||||||
|
---
|
||||||
|
After: 'test-module/*'
|
||||||
|
---
|
||||||
|
ClassManifestTest:
|
||||||
|
testParam: false
|
||||||
|
|
||||||
|
---
|
||||||
|
After: 'test-module/*#*'
|
||||||
|
---
|
||||||
|
ClassManifestTest:
|
||||||
|
testParam: false
|
@ -100,4 +100,36 @@ class TimeFieldTest extends SapphireTest {
|
|||||||
$field->setValue('');
|
$field->setValue('');
|
||||||
$this->assertEquals($field->dataValue(), '');
|
$this->assertEquals($field->dataValue(), '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that AM/PM is preserved correctly in various situations
|
||||||
|
*/
|
||||||
|
public function testPreserveAMPM() {
|
||||||
|
|
||||||
|
// Test with timeformat that includes hour
|
||||||
|
|
||||||
|
// Check pm
|
||||||
|
$f = new TimeField('Time', 'Time');
|
||||||
|
$f->setConfig('timeformat', 'h:mm:ss a');
|
||||||
|
$f->setValue('3:59 pm');
|
||||||
|
$this->assertEquals($f->dataValue(), '15:59:00');
|
||||||
|
|
||||||
|
// Check am
|
||||||
|
$f = new TimeField('Time', 'Time');
|
||||||
|
$f->setConfig('timeformat', 'h:mm:ss a');
|
||||||
|
$f->setValue('3:59 am');
|
||||||
|
$this->assertEquals($f->dataValue(), '03:59:00');
|
||||||
|
|
||||||
|
// Check with ISO date/time
|
||||||
|
$f = new TimeField('Time', 'Time');
|
||||||
|
$f->setConfig('timeformat', 'h:mm:ss a');
|
||||||
|
$f->setValue('15:59:00');
|
||||||
|
$this->assertEquals($f->dataValue(), '15:59:00');
|
||||||
|
|
||||||
|
// ISO am
|
||||||
|
$f = new TimeField('Time', 'Time');
|
||||||
|
$f->setConfig('timeformat', 'h:mm:ss a');
|
||||||
|
$f->setValue('03:59:00');
|
||||||
|
$this->assertEquals($f->dataValue(), '03:59:00');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
3
tests/templates/SSViewerTestIncludeScopeInheritance.ss
Normal file
3
tests/templates/SSViewerTestIncludeScopeInheritance.ss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<% loop Items %>
|
||||||
|
<% include SSViewerTestIncludeScopeInheritanceInclude %>
|
||||||
|
<% end_loop %>
|
@ -0,0 +1 @@
|
|||||||
|
$Title <% if ArgA %>- $ArgA <% end_if %>- <%if First %>First-<% end_if %><% if Last %>Last-<% end_if %><%if MultipleOf(2) %>EVEN<% else %>ODD<% end_if %> top:$Top.Title
|
@ -0,0 +1,3 @@
|
|||||||
|
<% loop Items %>
|
||||||
|
<% include SSViewerTestIncludeScopeInheritanceInclude ArgA=$Title %>
|
||||||
|
<% end_loop %>
|
@ -30,6 +30,56 @@ class SSViewerTest extends SapphireTest {
|
|||||||
$this->assertEquals('Test partial template: var value', trim(preg_replace("/<!--.*-->/U",'',$result)));
|
$this->assertEquals('Test partial template: var value', trim(preg_replace("/<!--.*-->/U",'',$result)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testIncludeScopeInheritance() {
|
||||||
|
$data = $this->getScopeInheritanceTestData();
|
||||||
|
$expected = array(
|
||||||
|
'Item 1 - First-ODD top:Item 1',
|
||||||
|
'Item 2 - EVEN top:Item 2',
|
||||||
|
'Item 3 - ODD top:Item 3',
|
||||||
|
'Item 4 - EVEN top:Item 4',
|
||||||
|
'Item 5 - ODD top:Item 5',
|
||||||
|
'Item 6 - Last-EVEN top:Item 6',
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $data->renderWith('SSViewerTestIncludeScopeInheritance');
|
||||||
|
$this->assertExpectedStrings($result, $expected);
|
||||||
|
|
||||||
|
// reset results for the tests that include arguments (the title is passed as an arg)
|
||||||
|
$expected = array(
|
||||||
|
'Item 1 - Item 1 - First-ODD top:Item 1',
|
||||||
|
'Item 2 - Item 2 - EVEN top:Item 2',
|
||||||
|
'Item 3 - Item 3 - ODD top:Item 3',
|
||||||
|
'Item 4 - Item 4 - EVEN top:Item 4',
|
||||||
|
'Item 5 - Item 5 - ODD top:Item 5',
|
||||||
|
'Item 6 - Item 6 - Last-EVEN top:Item 6',
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $data->renderWith('SSViewerTestIncludeScopeInheritanceWithArgs');
|
||||||
|
$this->assertExpectedStrings($result, $expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getScopeInheritanceTestData() {
|
||||||
|
return new ArrayData(array(
|
||||||
|
'Title' => 'TopTitleValue',
|
||||||
|
'Items' => new ArrayList(array(
|
||||||
|
new ArrayData(array('Title' => 'Item 1')),
|
||||||
|
new ArrayData(array('Title' => 'Item 2')),
|
||||||
|
new ArrayData(array('Title' => 'Item 3')),
|
||||||
|
new ArrayData(array('Title' => 'Item 4')),
|
||||||
|
new ArrayData(array('Title' => 'Item 5')),
|
||||||
|
new ArrayData(array('Title' => 'Item 6'))
|
||||||
|
))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function assertExpectedStrings($result, $expected) {
|
||||||
|
foreach ($expected as $expectedStr) {
|
||||||
|
$this->assertTrue(
|
||||||
|
(boolean) preg_match("/{$expectedStr}/", $result),
|
||||||
|
"Didn't find '{$expectedStr}' in:\n{$result}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Small helper to render templates from strings
|
* Small helper to render templates from strings
|
||||||
|
@ -3242,7 +3242,7 @@ class SSTemplateParser extends Parser {
|
|||||||
$arguments = $res['arguments'];
|
$arguments = $res['arguments'];
|
||||||
|
|
||||||
$res['php'] = '$val .= SSViewer::execute_template('.$template.', $scope->getItem(), array(' .
|
$res['php'] = '$val .= SSViewer::execute_template('.$template.', $scope->getItem(), array(' .
|
||||||
implode(',', $arguments)."));\n";
|
implode(',', $arguments)."), \$scope);\n";
|
||||||
|
|
||||||
if($this->includeDebuggingComments) { // Add include filename comments on dev sites
|
if($this->includeDebuggingComments) { // Add include filename comments on dev sites
|
||||||
$res['php'] =
|
$res['php'] =
|
||||||
|
@ -701,7 +701,7 @@ class SSTemplateParser extends Parser {
|
|||||||
$arguments = $res['arguments'];
|
$arguments = $res['arguments'];
|
||||||
|
|
||||||
$res['php'] = '$val .= SSViewer::execute_template('.$template.', $scope->getItem(), array(' .
|
$res['php'] = '$val .= SSViewer::execute_template('.$template.', $scope->getItem(), array(' .
|
||||||
implode(',', $arguments)."));\n";
|
implode(',', $arguments)."), \$scope);\n";
|
||||||
|
|
||||||
if($this->includeDebuggingComments) { // Add include filename comments on dev sites
|
if($this->includeDebuggingComments) { // Add include filename comments on dev sites
|
||||||
$res['php'] =
|
$res['php'] =
|
||||||
|
@ -47,11 +47,17 @@ class SSViewer_Scope {
|
|||||||
private $localIndex;
|
private $localIndex;
|
||||||
|
|
||||||
|
|
||||||
public function __construct($item){
|
public function __construct($item, $inheritedScope = null) {
|
||||||
$this->item = $item;
|
$this->item = $item;
|
||||||
$this->localIndex = 0;
|
$this->localIndex = 0;
|
||||||
$this->localStack = array();
|
$this->localStack = array();
|
||||||
$this->itemStack[] = array($this->item, null, 0, null, null, 0);
|
if ($inheritedScope instanceof SSViewer_Scope) {
|
||||||
|
$this->itemIterator = $inheritedScope->itemIterator;
|
||||||
|
$this->itemIteratorTotal = $inheritedScope->itemIteratorTotal;
|
||||||
|
$this->itemStack[] = array($this->item, $this->itemIterator, $this->itemIteratorTotal, null, null, 0);
|
||||||
|
} else {
|
||||||
|
$this->itemStack[] = array($this->item, null, 0, null, null, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getItem(){
|
public function getItem(){
|
||||||
@ -357,8 +363,8 @@ class SSViewer_DataPresenter extends SSViewer_Scope {
|
|||||||
*/
|
*/
|
||||||
protected $underlay;
|
protected $underlay;
|
||||||
|
|
||||||
public function __construct($item, $overlay = null, $underlay = null){
|
public function __construct($item, $overlay = null, $underlay = null, $inheritedScope = null) {
|
||||||
parent::__construct($item);
|
parent::__construct($item, $inheritedScope);
|
||||||
|
|
||||||
// Build up global property providers array only once per request
|
// Build up global property providers array only once per request
|
||||||
if (self::$globalProperties === null) {
|
if (self::$globalProperties === null) {
|
||||||
@ -895,10 +901,11 @@ class SSViewer {
|
|||||||
* @param Object $item - The item to use as the root scope for the template
|
* @param Object $item - The item to use as the root scope for the template
|
||||||
* @param array|null $overlay - Any variables to layer on top of the scope
|
* @param array|null $overlay - Any variables to layer on top of the scope
|
||||||
* @param array|null $underlay - Any variables to layer underneath the scope
|
* @param array|null $underlay - Any variables to layer underneath the scope
|
||||||
|
* @param Object $inheritedScope - the current scope of a parent template including a sub-template
|
||||||
*
|
*
|
||||||
* @return string - The result of executing the template
|
* @return string - The result of executing the template
|
||||||
*/
|
*/
|
||||||
protected function includeGeneratedTemplate($cacheFile, $item, $overlay, $underlay) {
|
protected function includeGeneratedTemplate($cacheFile, $item, $overlay, $underlay, $inheritedScope = null) {
|
||||||
if(isset($_GET['showtemplate']) && $_GET['showtemplate'] && Permission::check('ADMIN')) {
|
if(isset($_GET['showtemplate']) && $_GET['showtemplate'] && Permission::check('ADMIN')) {
|
||||||
$lines = file($cacheFile);
|
$lines = file($cacheFile);
|
||||||
echo "<h2>Template: $cacheFile</h2>";
|
echo "<h2>Template: $cacheFile</h2>";
|
||||||
@ -910,7 +917,7 @@ class SSViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$cache = $this->getPartialCacheStore();
|
$cache = $this->getPartialCacheStore();
|
||||||
$scope = new SSViewer_DataPresenter($item, $overlay, $underlay);
|
$scope = new SSViewer_DataPresenter($item, $overlay, $underlay, $inheritedScope);
|
||||||
$val = '';
|
$val = '';
|
||||||
|
|
||||||
include($cacheFile);
|
include($cacheFile);
|
||||||
@ -930,11 +937,12 @@ class SSViewer {
|
|||||||
* Note: You can call this method indirectly by {@link ViewableData->renderWith()}.
|
* Note: You can call this method indirectly by {@link ViewableData->renderWith()}.
|
||||||
*
|
*
|
||||||
* @param ViewableData $item
|
* @param ViewableData $item
|
||||||
* @param SS_Cache $cache Optional cache backend.
|
* @param array|null $arguments - arguments to an included template
|
||||||
|
* @param Object $inheritedScope - the current scope of a parent template including a sub-template
|
||||||
*
|
*
|
||||||
* @return HTMLText Parsed template output.
|
* @return HTMLText Parsed template output.
|
||||||
*/
|
*/
|
||||||
public function process($item, $arguments = null) {
|
public function process($item, $arguments = null, $inheritedScope = null) {
|
||||||
SSViewer::$topLevel[] = $item;
|
SSViewer::$topLevel[] = $item;
|
||||||
|
|
||||||
if ($arguments && $arguments instanceof Zend_Cache_Core) {
|
if ($arguments && $arguments instanceof Zend_Cache_Core) {
|
||||||
@ -979,7 +987,7 @@ class SSViewer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$output = $this->includeGeneratedTemplate($cacheFile, $item, $arguments, $underlay);
|
$output = $this->includeGeneratedTemplate($cacheFile, $item, $arguments, $underlay, $inheritedScope);
|
||||||
|
|
||||||
if($this->includeRequirements) {
|
if($this->includeRequirements) {
|
||||||
$output = Requirements::includeInHTML($template, $output);
|
$output = Requirements::includeInHTML($template, $output);
|
||||||
@ -1009,11 +1017,11 @@ class SSViewer {
|
|||||||
* Execute the given template, passing it the given data.
|
* Execute the given template, passing it the given data.
|
||||||
* Used by the <% include %> template tag to process templates.
|
* Used by the <% include %> template tag to process templates.
|
||||||
*/
|
*/
|
||||||
public static function execute_template($template, $data, $arguments = null) {
|
public static function execute_template($template, $data, $arguments = null, $scope = null) {
|
||||||
$v = new SSViewer($template);
|
$v = new SSViewer($template);
|
||||||
$v->includeRequirements(false);
|
$v->includeRequirements(false);
|
||||||
|
|
||||||
return $v->process($data, $arguments);
|
return $v->process($data, $arguments, $scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function parseTemplateContent($content, $template="") {
|
public static function parseTemplateContent($content, $template="") {
|
||||||
@ -1071,7 +1079,7 @@ class SSViewer_FromString extends SSViewer {
|
|||||||
$this->content = $content;
|
$this->content = $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function process($item, $arguments = null) {
|
public function process($item, $arguments = null, $scope = null) {
|
||||||
if ($arguments && $arguments instanceof Zend_Cache_Core) {
|
if ($arguments && $arguments instanceof Zend_Cache_Core) {
|
||||||
Deprecation::notice('3.0', 'Use setPartialCacheStore to override the partial cache storage backend, ' .
|
Deprecation::notice('3.0', 'Use setPartialCacheStore to override the partial cache storage backend, ' .
|
||||||
'the second argument to process is now an array of variables.');
|
'the second argument to process is now an array of variables.');
|
||||||
@ -1086,7 +1094,7 @@ class SSViewer_FromString extends SSViewer {
|
|||||||
fwrite($fh, $template);
|
fwrite($fh, $template);
|
||||||
fclose($fh);
|
fclose($fh);
|
||||||
|
|
||||||
$val = $this->includeGeneratedTemplate($tmpFile, $item, $arguments, null);
|
$val = $this->includeGeneratedTemplate($tmpFile, $item, $arguments, null, $scope);
|
||||||
|
|
||||||
unlink($tmpFile);
|
unlink($tmpFile);
|
||||||
return $val;
|
return $val;
|
||||||
|
Loading…
Reference in New Issue
Block a user