mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merged from 2.3
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@76269 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
7a4320f339
commit
b20b6e0f95
@ -161,6 +161,9 @@ abstract class Object {
|
|||||||
* completely replace the default PHP static when you set $replace = true, and do not define extra data on any child
|
* completely replace the default PHP static when you set $replace = true, and do not define extra data on any child
|
||||||
* classes
|
* classes
|
||||||
*
|
*
|
||||||
|
* Note that from SilverStripe 2.3.2, Object::get_static() can only be used to get public
|
||||||
|
* static variables, not protected ones.
|
||||||
|
*
|
||||||
* @param string $class
|
* @param string $class
|
||||||
* @param string $name the property name
|
* @param string $name the property name
|
||||||
* @param bool $uncached if set to TRUE, force a regeneration of the static cache
|
* @param bool $uncached if set to TRUE, force a regeneration of the static cache
|
||||||
@ -238,6 +241,9 @@ abstract class Object {
|
|||||||
/**
|
/**
|
||||||
* Get an uninherited static variable - a variable that is explicity set in this class, and not in the parent class.
|
* Get an uninherited static variable - a variable that is explicity set in this class, and not in the parent class.
|
||||||
*
|
*
|
||||||
|
* Note that from SilverStripe 2.3.2, Object::uninherited_static() can only be used to get public
|
||||||
|
* static variables, not protected ones.
|
||||||
|
*
|
||||||
* @todo Recursively filter out parent statics, currently only inspects the parent class
|
* @todo Recursively filter out parent statics, currently only inspects the parent class
|
||||||
*
|
*
|
||||||
* @param string $class
|
* @param string $class
|
||||||
|
@ -617,13 +617,12 @@ class Requirements_Backend {
|
|||||||
$jsRequirements = preg_replace('/>\n*/', '>', $jsRequirements);
|
$jsRequirements = preg_replace('/>\n*/', '>', $jsRequirements);
|
||||||
|
|
||||||
// We put script tags into the body, for performance.
|
// We put script tags into the body, for performance.
|
||||||
// If your template already has script tags in the body, then we put our script tags at the top of the body.
|
// If your template already has script tags in the body, then we put our script
|
||||||
// Otherwise, we put it at the bottom.
|
// tags just before those. Otherwise, we put it at the bottom.
|
||||||
$p1 = strripos($content, '<script');
|
$p1 = strripos($content, '<script');
|
||||||
$p2 = stripos($content, '<body');
|
$p2 = stripos($content, '<body');
|
||||||
if($p1 !== false && $p1 > $p2) {
|
if($p1 !== false && $p1 > $p2) {
|
||||||
user_error("You have a script tag in the body, moving requirements to top of <body> for compatibilty. I recommend removing the script tag from your template's body.", E_USER_NOTICE);
|
$content = substr($content,0,$p1) . $jsRequirements . substr($content,$p1);
|
||||||
$content = eregi_replace("(<body[^>]*>)", "\\1" . $jsRequirements, $content);
|
|
||||||
} else {
|
} else {
|
||||||
$content = eregi_replace("(</body[^>]*>)", $jsRequirements . "\\1", $content);
|
$content = eregi_replace("(</body[^>]*>)", $jsRequirements . "\\1", $content);
|
||||||
}
|
}
|
||||||
|
@ -725,9 +725,10 @@ class Translatable extends DataObjectDecorator {
|
|||||||
* @return DataObject
|
* @return DataObject
|
||||||
*/
|
*/
|
||||||
function alternateGetByUrl($urlSegment, $extraFilter, $cache = null, $orderby = null) {
|
function alternateGetByUrl($urlSegment, $extraFilter, $cache = null, $orderby = null) {
|
||||||
$SQL_URLSegment = Convert::raw2sql($urlSegment);
|
$filter = sprintf("\"SiteTree\".\"URLSegment\" = '%s'", Convert::raw2sql($urlSegment));
|
||||||
|
if($extraFilter) $filter .= " AND $extraFilter";
|
||||||
self::$enable_lang_filter = false;
|
self::$enable_lang_filter = false;
|
||||||
$record = DataObject::get_one('SiteTree', "\"URLSegment\" = '{$SQL_URLSegment}'", false);
|
$record = DataObject::get_one('SiteTree', $filter);
|
||||||
self::$enable_lang_filter = true;
|
self::$enable_lang_filter = true;
|
||||||
|
|
||||||
return $record;
|
return $record;
|
||||||
|
@ -26,7 +26,7 @@ abstract class DBField extends ViewableData {
|
|||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected static $default_search_filter_class = 'PartialMatchFilter';
|
public static $default_search_filter_class = 'PartialMatchFilter';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var $default mixed Default-value in the database.
|
* @var $default mixed Default-value in the database.
|
||||||
|
@ -19,7 +19,7 @@ class ForeignKey extends Int {
|
|||||||
*/
|
*/
|
||||||
protected $object;
|
protected $object;
|
||||||
|
|
||||||
protected static $default_search_filter_class = 'ExactMatchMultiFilter';
|
public static $default_search_filter_class = 'ExactMatchMultiFilter';
|
||||||
|
|
||||||
function __construct($name, $object = null) {
|
function __construct($name, $object = null) {
|
||||||
$this->object = $object;
|
$this->object = $object;
|
||||||
|
@ -13,7 +13,7 @@ class PrimaryKey extends Int {
|
|||||||
*/
|
*/
|
||||||
protected $object;
|
protected $object;
|
||||||
|
|
||||||
protected static $default_search_filter_class = 'ExactMatchMultiFilter';
|
public static $default_search_filter_class = 'ExactMatchMultiFilter';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
@ -30,7 +30,10 @@ class CliTestReporter extends SapphireTestReporter {
|
|||||||
echo SSCli::text(" AT LEAST ONE FAILURE ", "white", "red");
|
echo SSCli::text(" AT LEAST ONE FAILURE ", "white", "red");
|
||||||
}
|
}
|
||||||
echo "\n\n$testCount tests run: " . SSCli::text("$passCount passes", null) . ", ". SSCli::text("$failCount fails", null) . ", and 0 exceptions\n";
|
echo "\n\n$testCount tests run: " . SSCli::text("$passCount passes", null) . ", ". SSCli::text("$failCount fails", null) . ", and 0 exceptions\n";
|
||||||
|
|
||||||
|
if(function_exists('memory_get_peak_usage')) {
|
||||||
echo "Maximum memory usage: " . number_format(memory_get_peak_usage()/(1024*1024), 1) . "M\n\n";
|
echo "Maximum memory usage: " . number_format(memory_get_peak_usage()/(1024*1024), 1) . "M\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
$totalTime = array_sum($this->testSpeeds);
|
$totalTime = array_sum($this->testSpeeds);
|
||||||
echo "Total time: " . round($totalTime,3) . " seconds\n";
|
echo "Total time: " . round($totalTime,3) . " seconds\n";
|
||||||
|
@ -253,6 +253,18 @@ class FunctionalTest extends SapphireTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log in as the given member
|
||||||
|
* @param $member The ID, fixture codename, or Member object of the member that you want to log in
|
||||||
|
*/
|
||||||
|
function logInAs($member) {
|
||||||
|
if(is_object($member)) $memberID = $member->ID;
|
||||||
|
elseif(is_numeric($member)) $memberID = $member;
|
||||||
|
else $memberID = $this->idFromFixture('Member', $member);
|
||||||
|
|
||||||
|
$this->session()->inst_set('loggedInAs', $memberID);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the draft (stage) site for testing.
|
* Use the draft (stage) site for testing.
|
||||||
* This is helpful if you're not testing publication functionality and don't want "stage management" cluttering your test.
|
* This is helpful if you're not testing publication functionality and don't want "stage management" cluttering your test.
|
||||||
|
@ -335,6 +335,8 @@ 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) {
|
||||||
|
SSViewer::set_source_file_comments(false);
|
||||||
|
|
||||||
if(!$this->parseVariables_done) {
|
if(!$this->parseVariables_done) {
|
||||||
$this->parseVariables_done = true;
|
$this->parseVariables_done = true;
|
||||||
|
|
||||||
|
@ -1023,6 +1023,7 @@ class ComplexTableField_Popup extends Form {
|
|||||||
$this->dataObject = $dataObject;
|
$this->dataObject = $dataObject;
|
||||||
|
|
||||||
Requirements::clear();
|
Requirements::clear();
|
||||||
|
Requirements::unblock_all();
|
||||||
|
|
||||||
$actions = new FieldSet();
|
$actions = new FieldSet();
|
||||||
if(!$readonly) {
|
if(!$readonly) {
|
||||||
|
@ -206,6 +206,19 @@ class SiteTreeTest extends SapphireTest {
|
|||||||
$this->assertEquals('Page', $requeriedPage->class);
|
$this->assertEquals('Page', $requeriedPage->class);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test SiteTree::get_by_url()
|
||||||
|
*/
|
||||||
|
function testGetByURL() {
|
||||||
|
// Test basic get by url
|
||||||
|
$this->assertEquals($this->idFromFixture('Page', 'home'), SiteTree::get_by_url("home")->ID);
|
||||||
|
|
||||||
|
// Test the extraFilter argument
|
||||||
|
// Note: One day, it would be more appropriate to return null instead of false for queries such as these
|
||||||
|
$this->assertFalse(SiteTree::get_by_url("home", "1 = 2"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We make these extend page since that's what all page types are expected to do
|
// We make these extend page since that's what all page types are expected to do
|
||||||
|
57
tests/model/HierarchyTest.php
Normal file
57
tests/model/HierarchyTest.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class HierarchyTest extends SapphireTest {
|
||||||
|
static $fixture_file = 'sapphire/tests/model/HierarchyTest.yml';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Hierarchy::AllHistoricalChildren().
|
||||||
|
*/
|
||||||
|
function testAllHistoricalChildren() {
|
||||||
|
// Delete some pages
|
||||||
|
$this->objFromFixture('Page', 'page2b')->delete();
|
||||||
|
$this->objFromFixture('Page', 'page3a')->delete();
|
||||||
|
$this->objFromFixture('Page', 'page3')->delete();
|
||||||
|
|
||||||
|
// Check that page1-3 appear at the top level of the AllHistoricalChildren tree
|
||||||
|
$this->assertEquals(array("Page 1", "Page 2", "Page 3"),
|
||||||
|
singleton('Page')->AllHistoricalChildren()->column('Title'));
|
||||||
|
|
||||||
|
// Check that both page 2 children are returned
|
||||||
|
$page2 = $this->objFromFixture('Page', 'page2');
|
||||||
|
$this->assertEquals(array("Page 2a", "Page 2b"),
|
||||||
|
$page2->AllHistoricalChildren()->column('Title'));
|
||||||
|
|
||||||
|
// Page 3 has been deleted; let's bring it back from the grave
|
||||||
|
$page3 = Versioned::get_including_deleted("SiteTree", "Title = 'Page 3'")->First();
|
||||||
|
|
||||||
|
// Check that both page 3 children are returned
|
||||||
|
$this->assertEquals(array("Page 3a", "Page 3b"),
|
||||||
|
$page3->AllHistoricalChildren()->column('Title'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that you can call Hierarchy::markExpanded/Unexpanded/Open() on a page, and that
|
||||||
|
* calling Hierarchy::isMarked() on a different instance of that object will return true.
|
||||||
|
*/
|
||||||
|
function testItemMarkingIsntRestrictedToSpecificInstance() {
|
||||||
|
// Mark a few pages
|
||||||
|
$this->objFromFixture('Page', 'page2')->markExpanded();
|
||||||
|
$this->objFromFixture('Page', 'page2a')->markExpanded();
|
||||||
|
$this->objFromFixture('Page', 'page2b')->markExpanded();
|
||||||
|
$this->objFromFixture('Page', 'page3')->markUnexpanded();
|
||||||
|
|
||||||
|
// Query some pages in a different context and check their m
|
||||||
|
$pages = DataObject::get("Page");
|
||||||
|
$marked = $expanded = array();
|
||||||
|
foreach($pages as $page) {
|
||||||
|
if($page->isMarked()) $marked[] = $page->Title;
|
||||||
|
if($page->isExpanded()) $expanded[] = $page->Title;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertEquals(array('Page 2', 'Page 3', 'Page 2a', 'Page 2b'), $marked);
|
||||||
|
$this->assertEquals(array('Page 2', 'Page 2a', 'Page 2b'), $expanded);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
19
tests/model/HierarchyTest.yml
Normal file
19
tests/model/HierarchyTest.yml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Page:
|
||||||
|
page1:
|
||||||
|
Title: Page 1
|
||||||
|
page2:
|
||||||
|
Title: Page 2
|
||||||
|
page3:
|
||||||
|
Title: Page 3
|
||||||
|
page2a:
|
||||||
|
Parent: =>Page.page2
|
||||||
|
Title: Page 2a
|
||||||
|
page2b:
|
||||||
|
Parent: =>Page.page2
|
||||||
|
Title: Page 2b
|
||||||
|
page3a:
|
||||||
|
Parent: =>Page.page3
|
||||||
|
Title: Page 3a
|
||||||
|
page3b:
|
||||||
|
Parent: =>Page.page3
|
||||||
|
Title: Page 3b
|
30
tests/model/VersionedTest.php
Normal file
30
tests/model/VersionedTest.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class VersionedTest extends SapphireTest {
|
||||||
|
static $fixture_file = 'sapphire/tests/model/VersionedTest.yml';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Versioned::get_including_deleted()
|
||||||
|
*/
|
||||||
|
function testGetIncludingDeleted() {
|
||||||
|
// Delete a page
|
||||||
|
$this->objFromFixture('Page', 'page3')->delete();
|
||||||
|
|
||||||
|
// Get all items, ignoring deleted
|
||||||
|
$remainingPages = DataObject::get("SiteTree", "ParentID = 0");
|
||||||
|
// Check that page 3 has gone
|
||||||
|
$this->assertEquals(array("Page 1", "Page 2"), $remainingPages->column('Title'));
|
||||||
|
|
||||||
|
// Get all including deleted
|
||||||
|
$allPages = Versioned::get_including_deleted("SiteTree", "ParentID = 0");
|
||||||
|
// Check that page 3 is still there
|
||||||
|
$this->assertEquals(array("Page 1", "Page 2", "Page 3"), $allPages->column('Title'));
|
||||||
|
|
||||||
|
// Check that this still works if we switch to reading the other stage
|
||||||
|
Versioned::reading_stage("Live");
|
||||||
|
$allPages = Versioned::get_including_deleted("SiteTree", "ParentID = 0");
|
||||||
|
$this->assertEquals(array("Page 1", "Page 2", "Page 3"), $allPages->column('Title'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
19
tests/model/VersionedTest.yml
Normal file
19
tests/model/VersionedTest.yml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Page:
|
||||||
|
page1:
|
||||||
|
Title: Page 1
|
||||||
|
page2:
|
||||||
|
Title: Page 2
|
||||||
|
page3:
|
||||||
|
Title: Page 3
|
||||||
|
page2a:
|
||||||
|
Parent: =>Page.page2
|
||||||
|
Title: Page 2a
|
||||||
|
page2b:
|
||||||
|
Parent: =>Page.page2
|
||||||
|
Title: Page 2b
|
||||||
|
page3a:
|
||||||
|
Parent: =>Page.page3
|
||||||
|
Title: Page 3a
|
||||||
|
page3b:
|
||||||
|
Parent: =>Page.page3
|
||||||
|
Title: Page 3b
|
Loading…
Reference in New Issue
Block a user